Open-Assistant v0.0.3 : アーキテクチャ : 推論

Open-Assistant v0.0.3 : アーキテクチャ : 推論 (翻訳/解説)

翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 06/29/2023 (v0.0.3-alpha33)

* 本ページは、LAION-AI / Open-Assistant の以下のドキュメントを翻訳した上で適宜、補足説明したものです:

* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

クラスキャット 人工知能 研究開発支援サービス

クラスキャット は人工知能・テレワークに関する各種サービスを提供しています。お気軽にご相談ください :

◆ 人工知能とビジネスをテーマに WEB セミナーを定期的に開催しています。スケジュール
  • お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。

お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。

  • 株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション
  • sales-info@classcat.com  ;  Web: www.classcat.com  ;   ClassCatJP

 

 

Open-Assistant v0.0.3 : アーキテクチャ : 推論

テキストクライアントの視点から

テキストクライアント・ワークフローの概要

開発については、基本的な REPL クライアントはチャット・インターフェイスとして使用され、Typer を軸に構成されています。ロジックの大部分は inference.text-client.text_client_utils.DebugClient にあります。基本的なステップは以下です :

  1. デバッグクライアントは最初に /auth/callback/debug への GET リクエストで認証を行ない、これは bearer トークンを返し、そしてそれはその後のリクエストヘッダに設定されます。

  2. 認証後、DebugClient は /chats にポストすることで “chat” を作成します、これはセッション用の chat_id を返します。

  3. それからスクリプトはユーザプロンプトを収集します。

  4. DebugClient はエンドポイント “/chats/{chat_id}/messages” にポストします。このリクエストにはメッセージ内容, parent_id:str (もしあれば、前のメッセージへのアシスタントのレスポンスの ID), model_config_name:str, そして推論 sampling_parameters:dict が含まれます。レスポンスでは、サーバは message_id:str を返します。

  5. クライアントはこの id を {backend_url}/chats/{chat_id}/messages/{message_id}/events への GET リクエストを作成するために使用します。重要なことは、このリクエストの get() メソッドにおいて stream=True が渡されることで、つまりレスポンス・コンテンツは直ちにダウンロードされずにストリーミングされます。更に、実際の GET リクエストは、サーバにイベントストリームを待っていることを知らせるために、ヘッダで “Accept”: “text/event-stream” を持つ必要があります。

  6. そしてレスポンスは SSEClient をインスタンス化するために使用されます、これはその events() メソッドを通して推論結果を一度に 1 トークンをプリントアウトするために使用できる iterable を返します。

  7. events iterable を使いきった (つまり推論が完了した) あと、ユーザは新しいメッセージを促されます。

 

OA 推論サーバの視点から

推論サーバは FastAPI を軸に構築されています。

  1. クライアントが /chats にポストするとき、UserChatRepository – アプリケーションロジックとチャットメッセージテーブル間のインターフェイス – はチャットテーブル内にチャットを作成します、これは必要なチャット id を割り当ててレスポンスでクライアントに返されます。

  2. 次に、クライアントは /chats/{chat_id}/prompter_message にポストします、これは以下のために UserChatRepository を使用します :
    1. POST リクエストに含まれるメッセージコンテンツが configure された設定よりも長いか確認します。
    2. UserChatRepository のこのインスタンスがインスタンス化されたときに設定された database session と user_id を使用して、この chat_id と user_id の対応するエントリをチャットテーブルで探します。
    3. チャットの assistant + prompter メッセージの総数が configure された設定よりも多いか確認します。
    4. これが新しいチャットで (つまりチャットに parent_id が設定されておらず)、チャットテーブルがそのid のチャット用のタイトルを含まない場合、チャットテーブルを初期ユーザプロンプトをタイトルとして更新します。
    5. メッセージテーブルにユーザプロンプト用のメッセージを作成します。

  3. 次にクライアントは /chats/{chat_id}/assistant_message に POST します。
    1. 最初にクライアントのリクエストで指定された model_config_name 用のモデル config をロードします。
    2. 次に、UserChatRepository を使用して post し、ペンディング状態でメッセージテーブル内にメッセージを作成します。注意してください、チャットの任意の他の現在ペンディング中のメッセージの状態も inference.MessageState.cancelled に更新します。
    3. メッセージテーブルを更新後、この特定のメッセージ用に RedisQueue を作成してメッセージをキューに入れます。
    4. 最後に、クライアントに inference.MessageRead (Pydantic モデル) を返します。これは必要な message_id を含むオブジェクトです。

  4. クライアントが 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 ライブラリの ソースコード で確認できます。

 

以上