Open-Assistant v0.0.3 : アーキテクチャ : 推論 (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 06/29/2023 (v0.0.3-alpha33)
* 本ページは、LAION-AI / Open-Assistant の以下のドキュメントを翻訳した上で適宜、補足説明したものです:
* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
- 人工知能研究開発支援
- 人工知能研修サービス(経営者層向けオンサイト研修)
- テクニカルコンサルティングサービス
- 実証実験(プロトタイプ構築)
- アプリケーションへの実装
- 人工知能研修サービス
- PoC(概念実証)を失敗させないための支援
- お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。
◆ お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。
- 株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション
- sales-info@classcat.com ; Web: www.classcat.com ; ClassCatJP
Open-Assistant v0.0.3 : アーキテクチャ : 推論
テキストクライアントの視点から
開発については、基本的な REPL クライアントはチャット・インターフェイスとして使用され、Typer を軸に構成されています。ロジックの大部分は inference.text-client.text_client_utils.DebugClient にあります。基本的なステップは以下です :
- デバッグクライアントは最初に /auth/callback/debug への GET リクエストで認証を行ない、これは bearer トークンを返し、そしてそれはその後のリクエストヘッダに設定されます。
- 認証後、DebugClient は /chats にポストすることで “chat” を作成します、これはセッション用の chat_id を返します。
- それからスクリプトはユーザプロンプトを収集します。
- DebugClient はエンドポイント “/chats/{chat_id}/messages” にポストします。このリクエストにはメッセージ内容, parent_id:str (もしあれば、前のメッセージへのアシスタントのレスポンスの ID), model_config_name:str, そして推論 sampling_parameters:dict が含まれます。レスポンスでは、サーバは message_id:str を返します。
- クライアントはこの id を {backend_url}/chats/{chat_id}/messages/{message_id}/events への GET リクエストを作成するために使用します。重要なことは、このリクエストの get() メソッドにおいて stream=True が渡されることで、つまりレスポンス・コンテンツは直ちにダウンロードされずにストリーミングされます。更に、実際の GET リクエストは、サーバにイベントストリームを待っていることを知らせるために、ヘッダで “Accept”: “text/event-stream” を持つ必要があります。
- そしてレスポンスは SSEClient をインスタンス化するために使用されます、これはその events() メソッドを通して推論結果を一度に 1 トークンをプリントアウトするために使用できる iterable を返します。
- events iterable を使いきった (つまり推論が完了した) あと、ユーザは新しいメッセージを促されます。
OA 推論サーバの視点から
推論サーバは FastAPI を軸に構築されています。
- クライアントが /chats にポストするとき、UserChatRepository – アプリケーションロジックとチャットメッセージテーブル間のインターフェイス – はチャットテーブル内にチャットを作成します、これは必要なチャット id を割り当ててレスポンスでクライアントに返されます。
- 次に、クライアントは /chats/{chat_id}/prompter_message にポストします、これは以下のために UserChatRepository を使用します :
- POST リクエストに含まれるメッセージコンテンツが configure された設定よりも長いか確認します。
- UserChatRepository のこのインスタンスがインスタンス化されたときに設定された database session と user_id を使用して、この chat_id と user_id の対応するエントリをチャットテーブルで探します。
- チャットの assistant + prompter メッセージの総数が configure された設定よりも多いか確認します。
- これが新しいチャットで (つまりチャットに parent_id が設定されておらず)、チャットテーブルがそのid のチャット用のタイトルを含まない場合、チャットテーブルを初期ユーザプロンプトをタイトルとして更新します。
- メッセージテーブルにユーザプロンプト用のメッセージを作成します。
- 次にクライアントは /chats/{chat_id}/assistant_message に POST します。
- 最初にクライアントのリクエストで指定された model_config_name 用のモデル config をロードします。
- 次に、UserChatRepository を使用して post し、ペンディング状態でメッセージテーブル内にメッセージを作成します。注意してください、チャットの任意の他の現在ペンディング中のメッセージの状態も inference.MessageState.cancelled に更新します。
- メッセージテーブルを更新後、この特定のメッセージ用に RedisQueue を作成してメッセージをキューに入れます。
- 最後に、クライアントに inference.MessageRead (Pydantic モデル) を返します。これは必要な message_id を含むオブジェクトです。
- クライアントが message_id を持てば、/chats/{chat_id}/messages/{message_id}/events に GET リクエストをします。このリクエストを受け取るとき、サーバはメッセージテーブルからメッセージを取得し、メッセージが終了していないこととメッセージのロールがアシスタントであることを確認します。
この後、この特定のメッセージ id の Redis キューを取得します。ここから、dequeue() メソッドを使用してキューをポーリングします。デフォルトではこのメソッドは 1 秒間までブロックしますが、その間にメッセージがキューに追加された場合、それは自動的に返されます。そうでないなら dequeue() は None を返します。
None が返されてこれがキューの作成からキューを最初にポーリングした場合、chat_schema.PendingResponseEvent を yield します。ループはメッセージ項目が返されるまで、(デフォルトで) 1 秒間ブロッキングで継続します。メッセージ項目はタプルで、最初の要素はメッセージ id の文字列で、2 番目の要素はレスポンスです。メッセージレスポンス型の幾つかのチェックの後 (例えば安全性の割り込みやワーカーの内部エラーがあるか)、chat_schema.MessageResponseEvent を yield します。メッセージのポーリングと yielding は EventSourceResponse オブジェクト内でバンドルされています。
EventSourceResponse は Starlette/FastAPI 用の Server Sent Events (SSE) プラグインで、これはコンテンツを受け取りそれを HTTP イベントストリームの一部として返します。これがどのように機能するかの詳細は EventSourceResposethe ライブラリの ソースコード で確認できます。
以上