AI・機械学習
上級

Grammar制約(LLM Guided Decoding)(グラマーセイヤク ガイデッドデコーディング)

Grammar制約(Guided Decoding)とは、LLMのトークン生成時に文脈自由文法(CFG)・正規表現・GBNFなどの形式文法でデコーディングを制約し、出力が指定した構造に100%準拠することを保証する技術である。

0 回閲覧
0 いいね

Grammar制約(LLM Guided Decoding)とは

Grammar制約(Guided Decoding / Constrained Decoding)は、LLMがトークンを生成する際に、文法規則に基づいて次のトークンの候補を制限する技術である。通常のLLM推論では語彙全体(例: Llama 3の場合128,256トークン)から次トークンを確率的に選択するが、Grammar制約では文法的に許容されるトークンのみをサンプリング対象とする。これにより、JSONやXMLなどの構造化形式への100%準拠が数学的に保証される。クラウドAPI経由のJSON ModeやFunction Callingとは異なり、主にローカル推論エンジンで使用される技術である。

Grammar制約の仕組み

トークンマスキング方式

Grammar制約の基本原理は「トークンマスキング」である。

  1. 文法規則から現在の状態で許容されるトークン集合を計算
  2. 許容されないトークンの確率を-inf(マスク)に設定
  3. マスク適用後の確率分布からサンプリング

この方式により、文法違反のトークンは絶対に生成されない。計算コストは文法の複雑度とボキャブラリサイズに依存するが、効率的な実装では推論速度への影響を5〜15%程度に抑えられる。

有限状態マシン(FSM)方式

正規表現制約の場合、正規表現をDFA(決定性有限オートマトン)に変換し、各状態で許容されるトークンを事前計算する。Outlinesライブラリがこの方式を採用しており、推論開始前にトークンごとのFSM遷移テーブルをインデックス化することで、実行時のオーバーヘッドを最小化する。

プッシュダウンオートマトン方式

CFG(文脈自由文法)制約の場合、プッシュダウンオートマトン(PDA)を使用する。JSONのようなネスト構造を持つ文法では、スタックベースの状態管理が必要であり、FSM方式では表現できない。llama.cppのGBNF実装がこの方式を採用している。

主要な実装ツール

ツール制約形式対応推論エンジン言語特徴
llama.cpp GBNFGBNF (BNF拡張)llama.cppC/C++JSON/SQL/正規表現/任意文法対応
Outlines正規表現 / JSON Schema / CFGvLLM, TGI, llama.cppPythonFSM方式で高速。JSON Schemaから自動変換
vLLM Guided Decoding正規表現 / JSON SchemavLLMPythonOutlinesベース。guided_json/guided_regexパラメータ
SGLang正規表現 / JSON SchemaSGLangPythonCompressed FSMで高速化。Outlinesの2〜5倍速
XGrammarEBNF / JSON SchemaMLC-LLM, vLLMC++/PythonByteレベルPDA。マルチGPU並列対応
lm-format-enforcer正規表現 / JSON SchemavLLM, TGIPythonCharacter-level enforcement

GBNF(GGML BNF)

llama.cppで使用されるBNF拡張文法記法。

  • 基本構文: root ::= "{" ws members ws "}"のようにBNFルールを定義
  • 文字クラス: [a-zA-Z0-9]などの正規表現的な文字クラスをサポート
  • 繰り返し: *(0回以上)、+(1回以上)、?(0または1回)
  • JSON用定義済みGrammar: llama.cpp/grammars/json.gbnfに標準的なJSONの文法定義が付属

Outlines

Python製のGuided Decodingライブラリ。正規表現・JSON Schema・CFGの3つの制約方式をサポート。

  • 正規表現制約: outlines.generate.regex(model, r"[0-9]{3}-[0-9]{4}-[0-9]{4}")のように正規表現パターンを直接指定
  • JSON Schema制約: outlines.generate.json(model, MyPydanticModel)でPydanticモデルからJSON Schema制約を自動生成
  • CFG制約: outlines.generate.cfg(model, grammar_string)でEBNF文法を指定
  • インデックス事前計算: 初回実行時にFSM/PDAのトークンインデックスを構築し、キャッシュ。2回目以降の実行はオーバーヘッドが大幅に削減される

vLLM Guided Decoding

vLLMの組み込みGuided Decoding機能。OpenAI互換APIとして提供される。

  • guided_json: JSON Schemaオブジェクトを指定。Outlinesバックエンドで制約を適用
  • guided_regex: 正規表現パターンを指定
  • guided_choice: 選択肢のリストを指定(enumに相当)
  • guided_grammar: EBNF文法を指定
  • パフォーマンス: Outlinesバックエンドでは10〜15%のスループット低下。XGrammarバックエンドでは5%以下に改善(vLLM 0.6+)

Grammar制約のユースケース

  • 確実なJSON出力: ローカルLLM(Llama 4、Qwen 3、Gemma 4など)でJSON形式の出力を100%保証。クラウドAPIのJSON Modeに依存しない自律的な構造化出力
  • SQL生成: SQLの文法をGBNFで定義し、構文的に正しいSQLクエリのみを生成。Text-to-SQLタスクの精度向上
  • フォームデータ入力: メールアドレス・電話番号・郵便番号などの形式を正規表現で制約し、バリデーションコストを削減
  • コード生成: プログラミング言語の文法をCFGで定義し、構文エラーのないコードを生成
  • 構造化ログ出力: JSON Lines形式のログエントリをLLMに生成させる際、行ごとの形式を保証

パフォーマンス比較

ツールJSON生成速度 (tokens/s)オーバーヘッドメモリ増加初回起動時間
GBNF (llama.cpp)45-655-10%50-100MB< 1秒
Outlines (FSM)40-5510-15%200-500MB5-30秒
vLLM + Outlines80-12010-15%300-600MB10-60秒
SGLang (Compressed FSM)100-1803-5%150-300MB5-15秒
XGrammar90-1603-8%100-200MB2-10秒

※ Llama 3 8B、A100 GPU、JSON出力タスクでの参考値

よくある質問(FAQ)

Q1: Grammar制約とJSON Modeの違いは何ですか? A: JSON Modeはクラウドプロバイダがモデルレベルで提供する機能で、APIパラメータで有効化する。Grammar制約はローカル推論エンジンが提供する機能で、任意の形式文法(JSON以外も含む)でトークン生成を制約する。Grammar制約は数学的に100%の形式準拠を保証するが、JSON Modeはプロバイダの実装に依存する。

Q2: Grammar制約で推論速度はどの程度低下しますか? A: 文法の複雑度と実装方式に依存する。単純なJSON文法で5〜15%、複雑なネスト構造を持つ文法で15〜25%のスループット低下が典型的。SGLangのCompressed FSMやXGrammarでは最適化により3〜8%程度に抑えられる。初回実行時のFSM/PDAインデックス構築に数秒〜数十秒かかる点にも注意が必要。

Q3: GBNFの文法定義を自分で書く必要がありますか? A: JSON出力であればllama.cppに付属のjson.gbnfをそのまま使用できる。特定のJSON Schemaに準拠させたい場合はOutlinesやXGrammarを使えばJSON SchemaやPydanticモデルから自動変換される。SQLや独自フォーマットの場合はGBNF/EBNF文法を手書きする必要がある。

まとめ

  • Grammar制約はトークン生成時に形式文法で出力を制約する技術で、100%の形式準拠を保証
  • GBNF(llama.cpp)、Outlines、vLLM Guided Decoding、SGLang、XGrammarが主要ツール
  • JSON・SQL・正規表現パターンなど多様な構造化出力に対応
  • スループット低下は最新実装で3〜15%程度に抑制可能
  • ローカルLLM活用時のJSON出力保証に特に有効