Openai 异步客户端 支持ChatGPT Dall.E等模型
v1.0.12
版本
2024-06-27
版本更新时间
1191
安装
56
star
简介
传统php-fpm架构调用openai等大模型接口时只能做到阻塞调用,由于大模型接口返回速度很慢,一个php-fpm进程一分钟只能调用几次,几个人一刷系统就会明显的卡顿甚至不可用状态,所以php-fpm不适合做大模型调用,而webman这类的常驻内存类型的框架非常适合大模型应用的开发。
webman/openai是一个异步非阻塞的openai客户端,配合webman可以做到同一时刻支持上万并发调用,使用简单,返回如丝般的顺滑,无卡顿。
安装
composer require webman/openai
使用
Chat流式返回
<?php
namespace app\controller;
use support\Request;
use Webman\Openai\Chat;
use Workerman\Protocols\Http\Chunk;
class ChatController
{
public function completions(Request $request)
{
$connection = $request->connection;
// https://api.openai.com 国内访问不到的话可以用地址 https://api.openai-proxy.com 替代
$chat = new Chat(['apikey' => 'sk-xx', 'api' => 'https://api.openai.com']);
$chat->completions(
[
'model' => 'gpt-3.5-turbo',
'stream' => true,
'messages' => [['role' => 'user', 'content' => 'hello']],
], [
'stream' => function($data) use ($connection) {
// 当openai接口返回数据时转发给浏览器
$connection->send(new Chunk(json_encode($data, JSON_UNESCAPED_UNICODE) . "\n"));
},
'complete' => function($result, $response) use ($connection) {
// 响应结束时检查是否有错误
if (isset($result['error'])) {
$connection->send(new Chunk(json_encode($result, JSON_UNESCAPED_UNICODE) . "\n"));
}
// 返回空的chunk代表响应结束
$connection->send(new Chunk(''));
},
]);
// 先返回一个http头,后面数据异步返回
return response()->withHeaders([
"Transfer-Encoding" => "chunked",
]);
}
}
Chat非流式返回
<?php
namespace app\controller;
use support\Request;
use Webman\Openai\Chat;
use Workerman\Protocols\Http\Chunk;
class ChatController
{
public function completions(Request $request)
{
$connection = $request->connection;
$chat = new Chat(['apikey' => 'sk-xxx', 'api' => 'https://api.openai.com']);
$chat->completions(
[
'model' => 'gpt-3.5-turbo',
'messages' => [['role' => 'user', 'content' => 'hello']],
], [
'complete' => function($result, $response) use ($connection) {
$connection->send(new Chunk(json_encode($result, JSON_UNESCAPED_UNICODE) . "\n"));
$connection->send(new Chunk(''));
},
]);
return response()->withHeaders([
"Transfer-Encoding" => "chunked",
]);
}
}
Dall.E画图
<?php
namespace app\controller;
use support\Request;
use Webman\Openai\Image;
use Workerman\Protocols\Http\Chunk;
class ImageController
{
public function generations(Request $request)
{
$connection = $request->connection;
$image = new Image(['apikey' => 'sk-xxx', 'api' => 'https://api.openai.com']);
$image->generations([
'model' => 'dall-e-3',
'prompt' => 'a dog',
'n' => 1,
'size' => "1024x1024"
], [
'complete' => function($result) use ($connection) {
$connection->send(new Chunk(json_encode($result)));
$connection->send(new Chunk(''));
}
]);
return response()->withHeaders([
"Content-Type" => "application/json",
"Transfer-Encoding" => "chunked",
]);
}
}
TTS语音
<?php
namespace app\controller;
use support\Request;
use Webman\Openai\Audio;
use Workerman\Protocols\Http\Chunk;
class AudioController
{
public function speech(Request $request)
{
$connection = $request->connection;
$audio = new Audio(['apikey' => 'sk-xxx', 'api' => 'https://api.openai.com']);
$audio->speech([
'model' => 'tts-1',
'input' => '你好,有什么可以帮您?',
'voice' => 'echo'
], [
'stream' => function($buffer) use ($connection) {
$connection->send(new Chunk($buffer));
},
'complete' => function($result, $response) use ($connection) {
$connection->send(new Chunk(''));
}
]);
return response()->withHeaders([
"Content-Type" => "audio/mpeg",
"Transfer-Encoding" => "chunked",
]);
}
}
Embeddings
<?php
namespace app\controller;
use support\Request;
use Webman\Openai\Embedding;
use Workerman\Protocols\Http\Chunk;
class EmbeddingController
{
public function create(Request $request)
{
$connection = $request->connection;
$embedding = new Embedding(['apikey' => 'sk-xxx', 'api' => 'https://api.openai.com']);
$embedding->create([
'model' => 'text-embedding-ada-002',
'input' => 'Some words',
'encodding_format' => 'float',
], [
'complete' => function($result) use ($connection) {
$connection->send(new Chunk(json_encode($result)));
$connection->send(new Chunk(''));
}
]);
return response()->withHeaders([
"Content-Type" => "application/json",
"Transfer-Encoding" => "chunked",
]);
}
}
Azure OpenAI
如果是Azure OpenAI
接口,需要额外传入 'isAzure' => true
选项
public function completions(Request $request)
{
$connection = $request->connection;
$chat = new Chat(['api' => 'https://xxx.openai.azure.com', 'apikey' => 'xxx', 'isAzure' => true]);
$chat->completions(
[
'model' => 'gpt-3.5-turbo',
'stream' => true,
'messages' => [['role' => 'user', 'content' => 'hello']],
], [
'stream' => function($data) use ($connection) {
$connection->send(new Chunk(json_encode($data, JSON_UNESCAPED_UNICODE) . "\n"));
},
'complete' => function($result, $response) use ($connection) {
if (isset($result['error'])) {
$connection->send(new Chunk(json_encode($result, JSON_UNESCAPED_UNICODE) . "\n"));
}
$connection->send(new Chunk(''));
},
]);
return response()->withHeaders([
"Transfer-Encoding" => "chunked",
]);
}