はじめに
- LLMのモデルを準備・評価し、本番システムに組み込んで運用する際のフローとポイントをまとめました
LLMシステム開発・運用のフローとポイント
フローの全体像
- LLMシステム開発・運用のフロー図
引用元: LLMOps: Deployment and Learning in Production
- (参考)LLM開発・運用のワークフロー
引用元: LLMOps:基盤モデルに基づくアプリケーション開発のワークフロー
タスク個別のポイント
0. 開発の方針決定
- 開発の目的整理
- 背景・課題、ゴール
- 改めて、適切なユースケースかを確認する
- 評価と改善ができるか
- LLMはフォーマッタとしては優秀、etc
- 改めて、適切なユースケースかを確認する
- 背景・課題、ゴール
- 検証のKPI設定
- KPIを設定する
- 精度の最低ラインと目標ライン、処理速度やコスト、etc
- 検証の前提整理
- データ(学習、評価)、評価方法、検証環境
1. データ準備
データ収集
- アノテーションは計画的に実施する。段階的に実施することになることが多い
- アノテーションと評価の工数はきちんと確保しておく
データ管理
- スライスベースの評価をすることになるので、初めから分類しておく
2. モデル開発
ベースモデルの選択
Large Language Modelなので、気軽にモデルをスクラッチで開発するのは難しい。ユースケースごとに検討する必要がある
- 基盤モデルを活用する方法は、大きく3通り
- ①自ら基盤モデルをスクラッチ開発
- (参考)AWSで作る自社用基盤モデル
- ②公開済基盤モデルを活用
- ex. https://twitter.com/hardmaru/status/1660484586277830656?s=20 -> 1000件で65BのLLaMaをfine tuneしたら性能出た?
- ③生成系AI、API、基盤モデル提供ベンダーの活用
- ex. Azure OpenAI Service
- ①自ら基盤モデルをスクラッチ開発
- 基盤モデルも色々ある
- 商用可能なLLMリスト: open-llms
- ユースケースごとに、基盤モデル×活用法を、トレードオフを考慮して考える。観点は例えば以下
- 精度
- 推論速度、レイテンシ
- コスト
- fine-tuneability / 拡張性
- ライセンス
- 入力長
- データセキュリティ
- 学習に使われるか、etc
まずは、(現時点であれば)GPT-4から始めてみるのが良い。GPT-4でできるなら、そこから他の要件をトレードオフで考え始める(コストetc)
精度改善
- プロンプトエンジニアリング vs ファインチューニング
- 例が少ない場合はプロンプトエンジニアリングが始めやすい。一方で、入力トークンの最大長には注意が必要。一般的には、例の数が増えるにつれて、プロンプトエンジニアリングよりもファインチューニング方がモデルのパフォーマンスが向上しやすい
プロンプトエンジニアリング
- プロンプトを改善する
- LLMの持つ汎化性能を十分に引き出せるように、タスクを実行するための指示を適切に設計する
- 関連技術
- few-shot learning(in-context learning): 適切なタスクの回答例を数件〜数十件付加することで性能改善を試みる。重みの更新を伴わない。
- ポイント
- トークン数には注意
- Few Shot Learningはいいが、CoTとかSelf-consistencyは注意、精度とトレードオフで回答が長くなる
- トークン数には注意
モデルのファインチューニング
- モデルを改善する
- 対象タスクのラベル付きデータセットを用意し、事前学習済みのLLMを再学習してタスクに特化させる
- 必要なケース: より小さいモデルが必要、データ量が多く、検索がうまく行っていない
- 関連技術
- PEFT(Parameter-efficient fine-tuning): 全てのパラメータを更新せず、一部あるいは新規かつ少数の重みのみを変更
- LoRA(Low rank adoption): 事前学習済みの重みは固定、低ランク行列で間接的に下流タスクの訓練を行う、重みの行列の更新差分を低ランク近似してfine-tuning
- Instruction Tuning: テンプレート化された大量のタスク(指示と回答のペア)によりLLMの更なる性能向上
- RLHF(Reinforcement Learning from Human Feedback): 人間の嗜好に対してLLMを強化学習で最適化
- ポイント
- 下手にファインチューニングすると精度が下がるケースもあるので注意
- 最新の情報の入力というよりは、出力のトーンや言語の指示にプロンプトの文字数を大量に使っていて、それを大幅に削減したい時等に有用か
- 挙動を変える目安は、400M-1Bクラスで1000件程度か
- コストに注意
- ファインチューニング後のモデルは入出力ともに約8倍のコストがかかったりする
- どこを更新するかを決める(Classifier, fully connected layers, all layers)
- 下手にファインチューニングすると精度が下がるケースもあるので注意
Grounding
- システムが現実にアクセスする手段を提供すること
- 関連技術
- RAG(Retrieval-Augmented Generation): 情報をベクトル化(Embedding)して、プロンプトで検索して、距離が近い文章をプロンプトと一緒に投げる手法。In-Context LearningのIn-Contextを外部からひっぱってくる版
- ReAct: 外部のサービスから必要な情報をLLMが取得する手法
- ポイント
- ベクトル化部分も精度に大きく影響する
実験管理
実験管理対象として、従来のMLモデル開発で管理していた項目に加えて、promptやchainを保存する必要がある。モデルがアップデートされたらpromptの変更が必要であったり、fine-tuningまで絡むとさらに管理が複雑になりがち
- 実験管理が必要な理由
(参考)MLflowで実験管理入門- 昔の実験に立ち返って確認する必要がある(が、古いpromptは時間が経つと失われてしまう)ため
- 実験の再現のため
- チームでの作業の共有のため
- 並行した検証の実行のため(多くの実験を並行して行うことが多い)
- promptの変更とデプロイの分離のため
- 非技術者のステークホルダが関与するため
- ツールとしては、Weights & BiasesやMLflowなど
- 詳しくは、Weights & Biases (wandb) を用いたLLMファインチューニング
3. モデル評価
モデル評価
新しいモデル/promptが古いものより優れているかを測定したい
- 従来のML監視と違う難しさ
- インターネットのデータをもとにトレーニングされており、常にドリフトが発生するしそれはそれほど問題ではない
- ドリフトとタスク性能の間に必ずしも相関が発生するとは限らない
- 定量的な指標を定義することが難しい(生成された文をどう評価するか。従来のMLモデルのようなラベルとの一致をみるような評価はできない)
- 難しさ: インデント分類 < 要約、翻訳 < 雑談生成
- 多様な状況が考えられるので、1つの数字でまとめることが困難(ex. Startupの文脈ならあっているが、Physicsについてだったらダメ、とか)
- インターネットのデータをもとにトレーニングされており、常にドリフトが発生するしそれはそれほど問題ではない
- -> よって、あなたのタスクのための評価データセットを用意する必要がある
- ①段階的にスタートする
- アドホックな評価からスタートする。興味深い(Hard/Different)評価事例を見つけたら、都度小さなデータセットに整理する
- 人の目で見ることも大事。学びになる
- 難易度も段階的に設定することも考える
- ②LLMを活用する
- LLMでテストケースを生成する
- PineappleExpress808/auto-evaluator
- ③ロールアウトしながらデータを追加していく
- Hard data: ユーザにとってHard、アノテーターにとってHard、別のモデルにとってHard
- Different data: 現在の評価セットとの比較で異常値を示すデータ、少数のトピック・インテント・ドキュメント
- ①段階的にスタートする
- LLMの評価指標
- 従来のML同様の評価
- Accuracyなど。テキストでなく数値予測や分類ラベルを生成する場合は従来通り
- 独立したテキストベースの評価
- Perplexityなど。正しい単語を正しく予測していれば小さくなる指標。他、Reading Level, Non-letter Charactersなど
- HDBSCAN, UMAP, K-meansなど。埋め込みをクラスタリングし、3次元にマッピングして分析する、ベクトルの類似度を見る
- 評価データセットによる評価
- ROUGEメトリックなど。一致度を測る指標。グランドトゥルースのラベルを持つデータセットにより、テキスト出力を承認された回答のベースラインと比較する
- LLMによる評価
テストするメトリクスに対してバイナリ分類ラベルを出力するのが良い。数値スコアとランキングは、より多くの作業が必要で、バイナリ・ラベリングほど性能が高くない- Toxicity メトリクス
- モデルの出力がToxicかどうかを判定するEvaluator LLM(Hugging Faceはroberta-hate-speech-dynabench-r4を推奨)
- Reference matching メトリクス
- 他のLLMに「この二つの回答は事実上一致ししているか」と聞くなど
- "Which is better" メトリクス
- 他のLLMに「2つの答えのどちらが良いか」と聞くなど
- "Is feedback incorporated" メトリクス
- 他のLLMに「新しい回答が古い回答に対するフィードバックを取り込んでいるか」と聞くなど
- Static メトリクス
- 出力フォーマットの確認。jsonになっているかなど
- 既知の敵対的なプロンプトの参照セットと比較することで、悪質な行為者にフラグを立てることができる
- Toxicity メトリクス
- 従来のML同様の評価
- ポイント
- 注意すべきは、新しいpromptがいくつかの例でより良く見えるからといって、総合的に良く見えるとは限らない
- 特定の顧客向けの精度だけ下がると心象が悪い
- 注意すべきは、新しいpromptがいくつかの例でより良く見えるからといって、総合的に良く見えるとは限らない
4. デプロイ
アプリケーション開発
- ①自ら基盤モデルをスクラッチ開発or②公開基盤モデルを活用か③生成系AI、API、基盤モデル提供ベンダーの活用かによって異なる
一貫性・クオリティ
- 曖昧性への対応が必要。意図せぬ入出力(Hallucinatnion等)を考慮した設計
- 嘘をつく前提で、適切に設計と運用をする
- バリデーション、生成文はエンドユーザに直接見せないようにすることも考えられる
レイテンシ
LLMは従来のMLモデルと比べても、大量の計算リソースを必要とする。学習も推論も
- 負荷分散方式の検討
- リージョン負荷分散など
- AOAI: デプロイごとにTPM(Token per Minute)上限を設定でき、例えばgpt-3.5-turboなら各リージョンごとに合計で240K TPMまでを割り当てる。1つのデプロイに240K全部割り当てることもできれば、複数のデプロイに分散させることも可能
- クォータ制限に注意。トークン数など
- 入力だけでなく、出力の長さも影響
- イベントストリーム表示の検討
コスト
* APIコストの見積もり: プロビジョニングするか、閉域網か、トークン数(入出力)、冗長構成(リージョン数)、面数
セキュリティ
- ガードレール
- 不適切な応答をブロックする
- MLモデルを活用することもあり(犯罪に関連するものか判定、など)
- コンテンツフィルタリング
- 認証・認可
- 閉域化
- promptログの管理
- データ保存ポリシー
- 意図せぬ入出力を考慮した設計(プロンプトインジェクション)
- プロンプト漏洩対策。距離メトリクスを活用するなど
- 法・規制の遵守はアプリケーション側で実装する
- 利用規約の整備
オーケストレーション
- API部分以外の複雑なprompt/chainをどう実装するか
RAG
- (参考)RAGを活用したシステムのワークフロー例
- ワークフロー構成要素
- LLM
- ワークフローツール: LLMに対する入力と出力のハンドリング、LLMが出力する意図の分類結果ごとの処理を実行する仕組みの提供
- 外部API/データソース: データの提供、LLMが不得意とする処理を担うエンジンの提供
- ワークフロー図
引用元: Step-by-step MLOps v1.2
- ワークフロー構成要素
- ポイント
- RAGの限界は考慮する必要がある
- 外部API/データソースへのアクセス
- ベクトルDBの設計も重要。サイロ化しないように。意外とコストもかかるし複雑になる
- Chunkの設計、サマリのベクトル
- セマンティック検索との組み合わせ
- 関連技術
- GPTCache: LLM応答を保存するセマンティック・キャッシュを構築する
- Nemo-Guardrails: プログラム可能なガードレールを簡単に追加するツールキット。政治的な話をしない、など
- Llamaindex: LLMと外部データを接続するためのインターフェースを提供する
- RAGAS: RAGパイプラインを評価するためのフレームワーク。Faithfulnessなど
- LangSmith: LLM アプリケーションのデバッグ、テスト、評価、監視するプラットフォーム
その他
- データ基盤: データを活用できる形に用意しておく(データの把握、収集、クレンジング)。精度向上には高品質なデータセットが必要
デプロイ
- モデルのアップデートは必須。古いのは古い情報しか持っていない
- 下記のモニタリングとセットで実施する
5. モニタリング
ユーザにとってのボトルネックを特定する
モニタリング
- モニタリングすべき項目
- 精度
- エンドツーエンド、LLM部分、etc
- データの分布
- モデル性能の劣化を引き起こすと考えられる計測可能なメトリック、すなわち入力されるデータの分布を監視する
- ユーザからのフィードバック
- サムズアップ/サムダウンなど
- 代替指標
- 売上、ユーザー離脱率、クリック率などモデルが影響を与えると考えられる複数の間接的な指標を代替指標として使う
-
現実的な落としどころとしては、当面の間は代替指標や Human-in-the-loop による評価値をメインの指標として運用し、その間入力データを蓄積して何らかの入力側分布変化と指標の間に相関が発生していないかを探るというのが良さそうな気がしています
- 成果やエンドユーザの声、実際に何が問題になっているのかを測定する。モデルが対応できていないテーマを探していく
- A/Bテストはおそらく有効
- レイテンシー、コスト、リクエスト数、トークン使用量、エラー率
- レイテンシも種類がある
- ユーザープロンプトンの送信から最初のトークンレンダリングまで
- LLMのRPS(Requests Per Second)
- LLM応答をストリーミング(新しいタブで開く)する際に、1秒間にレンダリングされるトークン
- レイテンシも種類がある
- 精度
- モニタリング手法
- 手動確認(人手で確認)、自動確認(固定で用意したデータセット、自動で取得してくるデータセット)
- モニタリングの仕組み
フィードバックを集められるようにすることが大切- ロギング
- リクエスト/レスポンスBody
- 質問と回答を溜めておく
- 修正ログ
- ロギング
その他
- ethics, fairness, bias, privacy, explainabilityについても十分考慮する。
参考
- LLMOps: Deployment and Learning in Production
- Weights & Biases (wandb) を用いたLLMファインチューニング
- LLMOps を考え始める
- Large Language Models: A Complete Guide
- Understanding LLMOps: Taking MLOps to the Next Level
- Step-by-step MLOps v1.2
- ChatGPT(とその周辺)の技術
- GPT-4登場以降に出てきたChatGPT/LLMに関する論文や技術の振り返り
- LLMシステムの非機能要件対応_現場レポート
- LLMの普及による機械学習の民主化とMLPdMの重要性
- LLMOps:基盤モデルに基づくアプリケーション開発のワークフロー
- プロンプトエンジニアリング テクニックまとめ
- LLM Monitoring and Observability — A Summary of Techniques and Approaches for Responsible AI
- How to Evaluate LLMs: A Complete Metric Framework