3.9K Views
September 25, 23
スライド概要
とっとるびー第48回勉強会(https://tottoruby.connpass.com/event/292461/)の発表資料です。
エンジニアです
ChatGPTでマニュアルについて回答するサービス作成 @mechamogera
自己紹介 • mechamogera • 主にQiitaで活動:https://qiita.com/mechamogera • 第2種電気工事士の勉強中 • 夏休みの宿題で子供用にReactで計算カードアプリ作った https://mechamogera.github.io/keisan-card/ 2
今日お話しする内容 作成中のマニュアルに基づいて回答するChatGPTサービスについ て紹介 • 作ってるものの簡単な紹介 • 前提知識としてChatGPTのドメイン学習(Embeddings) • サービスの構成 • マニュアル回答のチャット化(LlamaIndexのchat engine) 3
最近の仕事 • UnrealEngineを使ったVRコミュニケーションサービス作成 4
マニュアルに基づいて回答するサービス • • • • • • VRコミュニケーションサービス内でサービスのことを聞くと答え てくれるサービス 初心者向けのチュートリアルの機能の代わりになるのではと期待 ChatGPTが一気に盛り上がって使ってみたかった ドキュメントが機能全般について書かれた顧客用のマニュアルと Slackのチャットくらいだったのでとりあえずマニュアルでやって みた まだ開発中、完成してない ChatGPTは初学者なのでツッコミがあったらぜひお願いします 5
会話実例 質問: 付箋を表示するのはどうすればいいですか? 回答: 付箋を表示するには、リングメニューから「Items」を選択し、その後 「Note」を選択します。 質問:天候を変えることはできますか? 回答 提供された情報では、天候を変えることに関する情報は含まれていません。 そのため、天候を変えることができるかどうかについてはわかりません。 6
ChatGPTのドメイン学習 • ChatGPTはデフォルトではドメイン知識なし • なんらかの形でドメイン知識を与えてやる必要あり • Fine-tunning • 学習データでトレーニングしてチューニングしたモデルを利用 • Embeddings • ドメイン知識をベクトルデータにして関連する部分をプロンプトに埋 め込む 7
ChatGPTのドメイン学習 • Fine-tunning • 学習データでトレーニングしてチューニングしたモデルを利用 • => 大量の学習データが必要だが手持ちのデータがない • Embeddings • ドメイン知識をベクトルデータにして関連する部分をプロンプトに埋 め込む • => マニュアルくらいの分量なのでこちら 8
Embeddingsのフロー 1. ユーザーが質問入力 2. 入力文字列のベクトル化 3. 2.を利用してあらかじめベクトル化しておいたドメイン知識 から情報を抽出 4. 3.をプロンプト情報に付与してChatGPTに質問し回答取得 5. ユーザーに回答提示 9
Embedggingsのプロンプトの例 一問一答式のquery engineの例 [アプリ名]に関する情報をコンテキスト情報として与えます。 コンテキスト情報 ------------------------{context_str} ------------------------コンテキスト情報を考慮したうえで、以下の[アプリ名]に関する質問に日本語で答えなさい。 質問 ------------------------- {query_str} ------------------------10
Embeddingsを行うllamaindex • 以下のOpenAI公式サンプルにEmbeddingsのコードもあるが結構 大変 • https://github.com/openai/openai-cookbook • llamaindex:https://www.llamaindex.ai/ • カスタム データ ソースをLLMに接続するためのシンプルで柔軟なデー タ フレームワーク、pythonライブラリ • 日本語の情報が多い • がんがんIFが変わる • ネットにある情報がすぐ古くなっていく • デバッグしてライブラリの中のコードを見て対応したりした 11
サービスの全体構成 • VRコミュニケーションアプリ (UnrealEnigine)がクライアント • AWSでAPI Gateway + Lambdaを利用 WebSocketsのAPIを提供 • Lambda上でllamaindexコードを実行 • Azure OpenAI ServiceのChatGPTモデ ルを利用 12
OpenAIとAzure OpenAI Service • ChatGPT提供サービスとしてAzure OpenAI Serviceを利用 • OpenAIはクレカ払いで清算が面倒だったのでAzure OpenAI Serviceに移行(現状はChatGPT Enterpriseができた) • どちらも利用した情報を学習データには使わないとは明言 • マネージメントのAdd Your DataがあるがAzure Cognitive Searchで利用しなくても課金が発生するために不使用 • Azure OpenAI Serivce有効化 • 約5時間半 • GPT-4有効化 • Azure OpenAI Service:約44日 • OpenAI:約55日(7/6から待機リストで待たなくても利用可に) 13
API Gateway + Lambda • API GatewayのWebSocket機能を使って提供 • ChatGPTの返答にあわせて少しずつ回答を返すように • API Gateway HTTP APIの最大統合タイムアウト30秒(緩和不可) のためHTTP APIとしての提供は不可 • API GatewayのAPIキー機能で認証 14
Lambdaが遅い問題 AIの回答が遅い(元々遅いけど)、調査したところLambdaの処理が遅い • Lambdaのメモリ設定を256MBにしていたがLambda Insightsで計測す ると300MBくらいメモリを利用していた • => メモリ設定を1024MBにした • コールドスタートで時間がかかる • 初期化:7秒くらい、クエリ発行まで:13秒くらい (コールドスタート出ない場合はクエリ発行まで2秒ほど) • => コンテナ化してみた、若干速くなった • 初期化:5~6秒くらい、クエリ発行まで:5~6秒くらい • => 何もしないAPIを用意してクライアントでUIを表示した際に利用して暖気し てみた • 初期化でどうしても5~6秒かかるのでその間に質問されるとコールドスタート • 暖気してから時間がたって質問するとコールドスタート • 根本的にはProvisioned Concurrency利用するしかなさそう 15
llamaindexで工夫した点 • streamingを用いて回答を少しづつ返すように • temperatureパラメータを0にして回答が一貫性があるように • デフォルトプロンプトを変更 • たまに英語で返される • => 日本語で返すように明示 • [アプリ名]の主語がいらないようにする • Q:起動方法を教えてください A:何について聞いているのかわかりません • => [アプリ名]の質問について回答するように指示する 16
サービスの料金 • Azure OpenAI Serviceの料金が99%以上で支配的 • トークン単位で料金が発生 • 単語数< トークン数 < 文字数 • トークンを測れるツール:https://platform.openai.com/tokenizer • 質問1回で質問:1.5kトークン、返答0.5kトークンくらい • 上記の前提だと以下のような料金 • gpt3.5-turbo-16K:$0.00815 • gpt4 8K:$0.075 • gpt4 32K:$0.150 17
UnrealEngineからのWebSocket通信 • Engine本体にWebSocketsモジュールがあって利用 18
WebSocketsモジュール利用ではまった • リクエストのJSONを直書きしていたらエラー • => 原因:文字コードの問題でJSON形式が崩れていてAPIでエラー • => 対応:UnrealEngineのJSONライブラリを使ってJSON構築 • パスなしカスタムドメインでアクセスしたら400エラー (デフォルトで提供されるドメインならアクセス可) • 調査:HTTPS(wss)がキャプチャできるfiddlerでパケットキャプチャ • 原因:WebSocketsモジュールでパスがないとパスとして//を追加 WebSocketsの利用しているlibwebsocketsのlws_parse_uri関数がパスがなかった ら/、/hogeパスだったらhogeをパスで返し、WebSockets側で/でジョイン • 対応:APIをパスを付けて提供するように 一応UDN(UnrealEngineDeveloperNetwork)に連絡したがUnrealEngineとしての 対応はしてもらえないということだった 19
1問1答式の限界 • 課題:質問の言葉のブレがあり質問者の意図しない回答をされる • • • • 例:マニュアルでは3Dデータ → モデルで聞くと別の機能がヒット 例:移動方法を教えてください → 自身、アイテムの移動方法? 言葉のブレから質問者が意図しないコンテキストを抽出 意図しないコンテキストに基づいたChatGPTの意図しない回答 • 対策案1:コンテキストの候補数の増加 • マニュアルで関連する箇所を増やすとどれかが引っかかる • 回答は増長に • 対策案2:フォローアップ質問の付与 • プロンプトでフォローアップ質問(前の質問の答えに対して想定される質問)を追 加するように指示 • そもそも意図しないコンテキストに基づいているので意図しない方向のフォロー アップに • 20
1問1答式からチャット形式へ • 意図しない回答はするとして簡単に訂正できるようにしたい • • • • 質問:モデルの表示方法を教えて 回答:モデルの表示方法は...(意図しない回答) 質問:モデルとはglbファイルのようなことです 回答:glbのようなモデルについては... • Llamaindexではquery engineが1問1答式で最近実装されたchat engineがチャット形式に対応しているので利用してみた 21
LLMのチャット • 履歴はLLM側で保持しない • ユーザーがLLM APIで会話の履歴情報を提供する必要がある • ユーザーのプロンプトの内容とLLMの回答情報の時系列順のデータが 履歴となる • システムプロンプト • LLMを定義付ける命令、前提条件の定義 • 役割を与える 22
chat engineのchat mode llama-index 0.8.19時点でいくつかchatの動作が切替可能 • SIMPLE:知識ベースを利用しない • CONDENSE_QUESTION:会話のコンテキストと最後のメッセージから 質問を生成しquery engineに問い合わせる • CONTEXT:ユーザーのメッセージを使用してインデックスからテキ ストを取得し、システムプロンプトでコンテキストを使用して応答 を生成 • REACT:この後説明 • OPENAI:OpenAI関数を使用(関数呼び出しAPIをサポートするOpenAI モデルでのみ動作) • BEST:LLMに応じて最適なエンジンを選択(REACTかOPENAI) デフォルト 23
chat mode BESTのシステムプロンプト llama-index 0.8.19のchat mode デフォルト(BEST)のプロンプト 英語なのを翻訳、意訳、一部省略している -----あなたは質問への回答をするように設計されています。 ## ツール あなたは様々なツールを利用することができます。 タスクを完了するために適切と思われる順序でツールを使用する責任があ ります。 以下のツールを利用できます。 24
> ツール名:query_engine_tool
ツールの説明 知識ベースに対して自然言語クエリを実行し、自
然言語応答を返します。
Tool Args: {'title': 'DefaultToolFnSchema', 'description':
'Default tool function Schema.', 'type': 'object', 'properties':
{'input': {'title': 'Input', 'type': 'string'}}, 'required': ['input']}
25
## 出力形式
質問に答えるには、以下のフォーマットを使用してください。
```
Thought: 質問に答えるためにツールを使いたい。
Action:ツール名({tool_names}のうちの1つ)
Action Input: ツールへの入力。kwargsを表すJSON形式(例:{{"text": "hello world",
"num_beams": 5}})
```
アクションの入力には有効なJSONフォーマットを使用してください。この例を使わないで
ください{{'text': 'hello world', 'num_beams': 5}}.
このフォーマットが使用された場合、ユーザーは以下のフォーマットで応答します:
```
Observation: ツールの応答
```
26
これ以上ツールを使わなくても質問に答えられるだけの情報が得 られるまで、上記のフォーマットを繰り返してください。 その時点で、以下のフォーマットで回答しなければなりません: ``` Thought: これ以上ツールを使わなくても答えられる。 Answer: [あなたの答えをここに] ``` ## 現在の会話 以下は、人間とアシスタントのメッセージを織り交ぜた現在の会 話です。 27
Llamaindexのchat engineの処理フロー 28
Llamaindexのchat engineの対話例 • 質問:移動方法を教えてください • Thought: 移動方法についての情報を取得するために、 query_engine_toolを使用する必要があります。 • Action: query_engine_tool • Action Input: {'input': '[アプリ名]の移動方法'} • Observation: [アプリ名]の移動方法にはいくつかの方法がありま す。... • Response: [アプリ名]の移動方法にはいくつかの方法がありま す。... 29
Llamaindexのchat engineの対話例 • 質問:前進・行進、左右水平回転を行う方法を教えてください • Thought: I need to use a tool to help me answer the question. • Action: query_engine_tool • Action Input: {'input': '[アプリ名]の前進・後進、左右水平回転の 操作方法'} • Observation: ...セクションに記載されています。...そのセクショ ンを参照してください。 • Response: [アプリ名]の前進・後進、左右水平回転の操作方法に ついては、...セクションに記載されています。...そのセクショ ンを参照してください。 30
Llamaindexのchat engineの対話例 • 質問:使用するコントローラーのボタンについて教えてくださ い • Thought: I need to use a tool to help me answer the question. • Action: query_engine_tool • Action Input: {'input': '[アプリ名]の前進・後進、左右水平回転の 操作に使用するコントローラーのボタン'} • Observation: 前進・後進、左右水平回転の操作には... • Response: [アプリ名]の前進・後進、左右水平回転の操作には... 31
chat engineでの問題と対応 • アプリの主語がいる • 例:Q:移動方法を教えてください A:何の移動方法ですか? • ⇒ システムプロンプトでアプリ名についての質問であることを明示 • streamが利用できない • => 調査中、構造的にはどうしても回答は遅くなりそう • たまに会話を省略する • 例:A:操作は以下のようにできます。(以下の部分が省略される) • => llamaindexのバグだった、https://github.com/jerryjliu/llama_index/issues/7690 • マニュアルを参照しろと言い出す • 例:A:その操作はマニュアルの該当部分を参照してください • => query_engine_toolのプロンプトの方でそのような部分を削除させる 32
サービスを作ってみてる感想 • 意外と微調整が必要でサービスとして成立させるの大変 • 急成長中のLlamaindexにあわせていく必要がある • Lambdaのコールドスタートなんとかなってほしい • 聞くだけだとつまらないのでアクションできるようにしたい • アイテムを出したり • 3Dデータの属性情報を検索させたり 33
今日お話しした内容 作成中のマニュアルに基づいて回答するChatGPTサービスについ て紹介 • 作ってるものの簡単な紹介 • 前提知識としてChatGPTのドメイン学習(Embeddings) • サービスの構成 • マニュアル回答のチャット化(LlamaIndexのchat engine) 34