AI・機械学習
上級

Grammar-Constrained Decoding(グラマー コンストレインド デコーディング)

LLMのトークンサンプリング時にBNF/EBNF等の形式文法を使い、文法的に無効なトークンのlogitを-∞にマスクして構造化テキストのみを生成する推論技術。

0 回閲覧
0 いいね
2026/6/6 更新
関連タグ
構造化出力
LLM推論
形式文法
BNF
トークンマスキング

Grammar-Constrained Decodingとは

LLMのデコード(推論)ステップで形式文法(BNF/EBNF等)を使い、文法違反トークンのlogit(確率スコア)を-∞に設定してサンプリングから排除する技術。これにより「必ずJSONになる」「必ずSQLになる」出力が確実に得られる。

動作原理

生成ステップ t での処理:
1. 現在のパース状態 S_t から「次に来うるトークン集合」T_valid を計算
2. 語彙 V 全体のlogit l を LLM から取得
3. V \ T_valid に含まれるトークンの logit を -∞ にマスク
4. マスク後のlogitでソフトマックス→サンプリング→次トークン決定
5. パース状態を S_{t+1} に更新、繰り返し

文法記述フォーマット

フォーマット使用ツール特徴
GBNFllama.cppllama.cpp独自拡張BNF、JSON/SQL/コード対応
EBNFOutlines, lm-format-enforcer標準的、Python正規表現とも統合
JSON SchemaOutlines, XGrammar, OpenAIJSONに特化、自動変換対応
正規表現Outlines, guidance単純パターン向け

GBNFの例(llama.cpp)

# JSONオブジェクト(name: string, age: number)
root  ::= "{" ws "\"name\":" ws string "," ws "\"age\":" ws number "}"
string ::= "\"" [^""]* "\""
number ::= [0-9]+
ws ::= [ \t\n]*

JSON Schemaからの自動変換

Outlines・XGrammarはJSON Schemaを受け取り内部的に文法へ自動変換する:

from outlines import models, generate

model = models.transformers("mistralai/Mistral-7B-v0.1")

schema = {
    "type": "object",
    "properties": {
        "name": {"type": "string"},
        "score": {"type": "number", "minimum": 0, "maximum": 100}
    },
    "required": ["name", "score"]
}

generator = generate.json(model, schema)
result = generator("製品名とスコアをJSONで返して")
# 常に {"name": "...", "score": XX.X} 形式を返す

パフォーマンスへの影響

実装オーバーヘッド方式
素朴なマスキング10〜50%ステップごとに全文法再評価
XGrammar<1%コンパイル済みオートマトン + GPU並列
Outlines(FSM)1〜5%有限状態機械をキャッシュ
llama.cpp GBNF2〜10%Wasm統合、単スレッド最適化

よくある質問(FAQ)

Q1: Grammar-Constrained DecodingはLLMの品質を落とす? A: 文法的には正しいが意味的に最適でないトークンを選ぶ場合はある。ただし実用上の品質低下はほぼ報告されていない。

Q2: ストリーミング出力との相性は? A: 問題なし。各トークン生成時にリアルタイムでマスクを適用するためストリーミングと完全互換。

Q3: どのLLMでも使える? A: 理論上は任意のLLMに適用可能。llama.cppベースモデルとHugging Face Transformersモデルで広くサポートされている。

この記事について
カテゴリーAI・機械学習
難易度上級
作成日2026/6/6