AI・機械学習
中級
llama.cpp Grammar Sampling(GBNF)(ラマシーピーピー グラマー サンプリング)
llama.cppが実装する独自文法記述フォーマットGBNF(GGML BNF)を使い、ローカルLLMからJSON・SQL・カスタム形式の構造化テキストを確実に生成する機能。
0 回閲覧
0 いいね
2026/6/6 更新
関連タグ
llama.cpp
GBNF
構造化出力
ローカルLLM
GGUF
llama.cpp Grammar Sampling(GBNF)とは
llama.cppが独自に実装する文法制約サンプリング機能。GBNF(GGML BNF)という独自フォーマットで文法を記述し、ローカルGGUFモデルからJSON・SQL・カスタム形式の出力を強制する。
GBNFの基本構文
# JSONオブジェクト(nameとageを持つ)の文法
root ::= object
object ::= "{" ws members ws "}"
members ::= pair ("," ws pair)*
pair ::= string ws ":" ws value
value ::= string | number | "true" | "false" | "null"
string ::= "\\\"" chars "\\\""
chars ::= [^\\\"\\\\]* (escape chars)?
escape ::= "\\\\" (["\\\\/bfnrt] | unicode)
unicode ::= "u" [0-9a-fA-F]{4}
number ::= "-"? ([0-9] | [1-9][0-9]*) ("." [0-9]+)?
ws ::= ([ \t\n\r])*
使用方法
CLIから直接使用
# 組み込みのjson.gbnfを使用
./llama-cli -m ./models/mistral-7b-instruct.Q4_K_M.gguf \
--grammar-file grammars/json.gbnf \
-p "ユーザー情報をJSONで返して"
# カスタム文法ファイル
./llama-cli -m ./models/llama-3-8b.gguf \
--grammar-file ./my_schema.gbnf \
-p "SQLクエリを生成して: usersテーブルから名前と年齢を取得"
Python(llama-cpp-python)
from llama_cpp import Llama, LlamaGrammar
llm = Llama(model_path="./models/mistral-7b-instruct.Q4_K_M.gguf")
# GBNFファイルから文法をロード
grammar = LlamaGrammar.from_file("grammars/json.gbnf")
# JSON Schema から自動変換
import json
schema = {
"type": "object",
"properties": {
"name": {"type": "string"},
"score": {"type": "integer", "minimum": 0, "maximum": 100}
},
"required": ["name", "score"]
}
grammar = LlamaGrammar.from_json_schema(json.dumps(schema))
output = llm(
"評価結果をJSONで返して",
grammar=grammar,
max_tokens=200
)
print(output['choices'][0]['text']) # 常に有効なJSON
OpenAI互換APIサーバー
# llama.cppのOpenAI互換サーバー起動
./llama-server -m ./models/llama-3-8b.gguf --port 8080
import requests
response = requests.post("http://localhost:8080/v1/chat/completions", json={
"model": "local",
"messages": [{"role": "user", "content": "製品情報をJSONで"}],
"grammar": open("grammars/json.gbnf").read()
})
組み込み文法ファイル(grammars/ディレクトリ)
| ファイル | 用途 |
|---|---|
json.gbnf | 汎用JSONオブジェクト |
json_arr.gbnf | JSON配列 |
list.gbnf | 箇条書きリスト |
chess.gbnf | チェス棋譜(PGN形式) |
c.gbnf | Cプログラム構文 |
フロントエンドとの統合
- Ollama:
format: "json"でJSON Modeを有効化(内部でGBNF使用) - LM Studio: チャット設定でJSON Schemaを指定可能
- Jan: 文法制約プリセットを選択
- OpenWebUI: 構造化出力の設定パネルから指定
よくある質問(FAQ)
Q1: GBNFとEBNFの違いは?
A: GBNFはllama.cpp独自拡張で文字クラス([a-z]等)や繰り返し(*/+/?)が使いやすく簡略化されている。標準EBNFのサブセット+拡張。
Q2: 文法が複雑になるとどのくらい遅くなる? A: 単純なJSONは2〜5%のオーバーヘッド。再帰を多用した複雑な文法は10〜20%程度。XGrammarより遅いが多くのユースケースで十分実用的。
Q3: WindowsのGPU環境でも動く? A: CUDA/ROCm/Vulkanバックエンドを使えばWindowsでもGPU推論+文法制約が動作する。