ハクソク

世界を動かす技術を、日本語で。

LLM構造化出力ハンドブック

概要

  • LLMの構造化出力はプログラム利用時に重要な課題
  • 確実な構造化出力を実現する手法とツールの紹介
  • 開発・運用・最適化に関する実践的なガイド
  • 最新動向を反映した包括的なハンドブック
  • Nanonets-OCRdocstrangeの開発者による執筆

LLMの構造化出力と課題

  • LLM(大規模言語モデル)はJSONやXML、コードなど構造化出力を生成可能
  • しかし確率的生成のため、時折構文エラーや不正な出力が発生
  • データ抽出コード生成ツール連携などで構造化出力の信頼性が重要
  • 構造化出力が保証されなければ自動化やエージェント活用は実現困難

構造化出力を保証する方法

  • 決定論的手法による構造化出力の強制
    • 出力テンプレートの利用
    • 構文チェッカーによる検証
    • ツール連携による自動修正
  • ベストプラクティス最新ツールの選定基準
  • システム構築・運用・スケーリングのノウハウ
  • レイテンシやコスト最適化の手法
  • 出力品質向上のための工夫

ハンドブックの特徴と活用方法

  • 構造化生成分野は急速に進化、既存リソースは陳腐化が早い
  • 学術論文、ブログ、GitHubリポジトリなど多様な情報の統合
  • 定期的に更新されるリビングドキュメント
  • 最初から通読、またはリファレンスとしての利用が可能

著者・運営元について

  • Nanonets-OCR(VLMで文書をMarkdownへ変換)開発チーム
  • docstrange(オープンソース文書処理ライブラリ)開発者
  • LLM開発者コミュニティからの知見・最新情報を配信
    • ニュースレターで月2回のアップデート
    • 最新ブレークスルー有用ツールの紹介

まとめ

  • LLMの構造化出力の信頼性・効率化を目指す開発者向けハンドブック
  • 最新技術動向実践手法を一冊に集約
  • 開発・運用・最適化に役立つ必携リソース

Hackerたちの意見

いいガイドだね。特にこのページのマスクされたデコーディング図が好きだな。https://nanonets.com/cookbooks/structured-llm-outputs/basic-.... 追記:なんかそのリンクがうまくいかない…「制約付きメソッド」のページの図だよ。
ここにいる著者の一人だよ。図のリンクをチェックしてみるね。商業モデルの提供者はみんな構造化された出力を追加してるから、ガイドもどんどん更新していくよ。
これは本当に美しいガイドだね。まとめてくれてありがとう!いろんなページのタブスルーアニメーションが特に好きだし、これまで見た中で一番の説明だと思う。文法制約付き生成については結構理解してるつもりだけど(llama.cppの文法実装にいくつかの貢献を統合したことがある)、それでも君のイラストからいくつかの洞察を得られたよ。ありがとう!もっと多くの人がこの機能を理解できるように手助けしてくれて嬉しい。どう機能するのか、効果的に使う方法もね。構造化された出力はLLMエンジンの中で最も過小評価されている機能の一つだと思うし、もっと使われるべきだよ。制約付き非決定性のおかげで、LLMを大きなパイプラインやプロセスの一部として信頼して使えるし(例えば、ツール呼び出しをするエージェントなど)、文法エラーや「もちろん!これは他のテキストや前置きなしでJSON形式にフォーマットされた出力です」といったメッセージが混ざることもない。君のLLM出力が正しいとは限らないけど、文法があれば少なくとも文法的には正しい出力が保証される。全てではないけど、何もないわけじゃないし。特にクラウドデプロイから離れて効果的なローカルモデルを運用したいなら、文法は非常に価値のある要素だよ。実用的な例としては、JartのRaspberry Pi上で動くシンプルなLLMベースのスパムフィルターの例をよく思い出す。 [0]: > llamafile -m TinyLlama-1.1B-Chat-v1.0.f16.gguf \ > --grammar 'root ::= "yes" | "no"' --temp 0 -c 0 \ > --no-display-prompt --log-disable -p " > このメールがスパムであると確信を持って言えますか? ... すごく小さなハードウェアでも、出力を「yes」か「no」に制約する文法を含めることで、システムが別の結果を出すことは不可能になるから、超小型モデルを超限られたハードウェアで使えるし、それでも役に立つ。スパムを正しく識別できるわけじゃないかもしれないけど、文法的な理由で壊れることはないから、小さくてローカルなモデルの有用性が大きく向上するよ。
モデルが他のものを返したいときはどうなるの?llamafileでやるのと、呼び出しているラッパーでやるのとでは何が良くて何が悪いの?リトライをどう設定するの?JSONと範囲が欲しいときはどうすればいいの?
JSONよりも信頼性が高い(スキーマへの適合が良い、パース可能な出力が得やすい)か、安価(トークン数が少ない)な出力形式ってある?YAMLには独自の問題があるし、TOMLはあまり普及してないけど、どちらも生成しやすそうだよね。みんなは何を試したの?
そう、それがTOONの目的だよ。https://github.com/toon-format/toon
正規表現を使ってXMLスキーマを強制して、その後普通のXMLパーサーでデコードしてるよ。コードにはXMLの方が良いし、特にコード部分ではcdataを強制してるから、LLMはエスケープなしで自由にできるんだ。OpenAI APIは正規表現で構造化された出力を可能にしてて、コードにはJSONよりもずっといいよ。
ちょっとブレインストーミングしてみる。人間はJSONを書くのが難しいんだよね、だってめんどくさいから。厳しすぎるし。私の経験では、人間がTypeScriptを書く方が、JSONを直接書くよりずっと良いよ。コメントも書けるし、可読性を高めるための末尾のカンマも許されるしね。だから、LLMに生成させる面白いファイルは、最終的なファイルの代わりに最終ファイルを作成するプログラムとかかも?もちろん、セキュリティの問題があるけど、LLMが生成するプログラムはちゃんとサンドボックス化されて、DOS攻撃や爆発的な出力サイズを防ぐために時間制限も必要だし、最終結果のCPU使用量も考えないといけないけど、品質的にはどうなんだろう?
自分のケースに特化した評価をするべきだよ。私の評価では、XMLは配布外タスクにおいて全てのモデルでJSONを上回ってる(つまり、データに含まれていたJSONではなく)。
モデルが毎回有効なJSONを出力することを信頼できないなら、エージェントを構築するのは基本的に不可能だと思う。これは、プロダクションシステムのために決定論的な構造を強制するための現在の技術の良いコレクションだね。
とてもよく書かれたガイドだね!著者や読者がガイダンスとllguidanceの最適化に関する技術的な詳細に興味があれば、ここにちょっとした論文を書いたよ。https://guidance-ai.github.io/llguidance/llg-go-brrr
これは素晴らしいガイドだね!博士課程の時に構造化生成についてたくさん研究したよ。他にも興味がある人のためにいくつかのポイントを挙げておくね。いくつかのライブラリ: - Outlines、構造化生成のための素敵なライブラリ - https://github.com/dottxt-ai/outlines - Guidance(このスレッドでFlyingLawnmowerが既に触れてる)、もう一つの素敵なライブラリ - https://github.com/guidance-ai/guidance - XGrammar、機能は少ないけど、制約された生成のために本当に最適化されたライブラリ - https://github.com/mlc-ai/xgrammar - これは面白い技術的な側面がたくさんあって、興味深いプロジェクトだよ。いくつかの論文: - 大規模言語モデルのための効率的なガイド生成 - Outlinesの著者によるもので、おそらく最初の本格的なLLM制約生成の論文 - https://arxiv.org/abs/2307.09702 - 言語モデルデコーディングのためのオートマタベースの制約 - 制約生成と実装についてのもっと技術的な論文 - https://arxiv.org/abs/2407.08103 - オートマタベースのサブワードレベル制約生成における落とし穴、微妙な点、技術 - ちょっと自己宣伝。制約生成がどこで間違えるかを示し、実務者向けのいくつかの技術について話してる - https://openreview.net/pdf?id=DFybOGeGDS いくつかのブログ記事: - 正規表現制約を使った高速・高忠実度のLLMデコーディング - 標準的なトークン化に従うことについて話してる(つまり、単に制約だけでなく、トークナイザーによって生成されるものも) - https://vivien000.github.io/blog/journal/llm-decoding-with-regex-constraints.html - Coalescence: LLM推論を5倍速くする - Outlinesチームからのもの - 制約生成中に有効なトークンが一つだけの時に推論をスキップすることについて - https://blog.dottxt.ai/coalescence.html
なんて素晴らしい情報の宝庫なんだ!オートマタベースの制約は楽しいね。
こんにちは、https://openreview.net/pdf?id=DFybOGeGDSの標準的フィルタリングに関する部分は、プレトークナイゼーションを考慮していないように見えるんだけど。例えば、o200kで「
これらはクールなトリックだけど、なんかミスマッチな感じがするね。なぜ、確定的なテキストが必要な状況で、確率的なテキストのソースであるLLMを使うの?
それは…しないよ。まさに構造化出力のためにあるんだから!形式的に定義された生成を、より適したツールにオフロードして、タスクのあいまいな部分をモデルに任せるんだ。コードは混合ケースの一例だし、モデルから機械的に解析可能な出力を得るのも別の例だよ。生成後にフォーマットを整えることはできるけど、そのためには生成が解析可能である必要があるからね。多くの場合、必要なフォーマットをすぐに使うことで、より良い返答のためのコンテキストも提供されるよ。
これは良いね。人々が使う二つの最も簡単な主要な方法をカバーしてる。彼らが推奨している方法に対する私の主な不満にも触れてるし。ただ、 - 制約生成は、生のLLMが提供するものとは異なる分布を生む。これは病的に悪くなることもある。私の例は、LLMが長い構造化オブジェクトにおいて省略記号を含むことを好むことだよ。制約生成は、スキーマに従ってそのエラーから回復するために閉じる引用符を強制するけど、それでも無効な結果を生むことになる。再サンプリングは、LLMが問題のデータを完全に生成するまで繰り返され、常に有効な結果を生み出し、スキーマにも従う。これより悪化することもあるよ。 - 制約のない「方法」にはいくつかの実装が考えられる。スキーマエラーについて文句を言いながらコンテキストの長さを増やすのは、スキーマが通るまで再試行するよりも、エンドクオリティの観点からほとんど常に悪化する。効果的なコンテキストウィンドウは貴重で、現在のモデルは与えられた初期データに強くバイアスがかかってる。低エラーの状況では、単一のチャットで「もう一度試してみて」っていう反応で済むかもしれないけど、高エラーの状況では、モデルがエラーを引き起こさないまで同じプロンプトを文字通り再送信する方が、より良い結果を低コストで得られるよ。
このスレッドを読んでいる詳しい人たちに質問なんだけど、OpusやGeminiみたいな最先端モデルって、まだ出力スキーマの強制が必要なのかな?それとも、コードやJSONを生成するためのRLVRトレーニングのおかげで、スキーマエラーがほとんど起こらなくなったのかな?実際、これらのモデルを使っていると、JSONやコードを生成する際に文法ミスがほとんどないんだよね。ただ、ツールコールスキーマみたいな「内部」のことには、まだ出力スキーマの強制があるのかもしれないけど。実際にそんなに多くのエラーをキャッチしているとは思えないな。たまにあるかもしれないけど、結局LLMは確率的だからね。(小さいLLMには構造化生成が必要なのは分かるけど、それは納得できる。)
そうだね。最先端モデルで最もよくある失敗パターンは、```json\nを最初に入れちゃうことだけど、実際にはJSONレスポンススキーマでAPIを呼ぶ価値があるくらい、結構失敗することが多いんだよね。
スキーマは結構複雑になりがちだし(LLMはカウントが得意じゃないかもしれないし)、スキーマはLLMの確率性に対する最初の防御手段になることもあるよね。とはいえ、モデル自体は結構うまくやってると思う。
すごいガイドだね、マジで。絶対にみんなにシェアするよ。こんなのが1年前にあったらよかったな。