llama.cpp の ngram-mod で、コードの書き直しが 4 倍以上速くなった — n-gram の投機的デコーディングを、エージェントの実際の要求でも測った(RTX 5060 Ti 16GB)
CONTENTS目次(7)
この記事の結論
- ファイル全体を返させる書き直しでは、生成が 80〜82 tok/s(1 秒あたりのトークン数)から 344〜524 tok/s に上がった。初回で 4.3〜5.2 倍、同じファイルの 2 回目は 5.5〜6.6 倍。出力の大半を入力から写せるため。
- コーディングエージェント(opencode)の実際の要求の形で出した 28 問では、66.2 → 66.1 tok/s で変わらなかった。出力が短いツール呼び出し(中央値 55 トークン)が中心で、先読みが出たのは 9 問だけだった。
- 付け方は
--spec-type ngram-modの 1 つだけで、下書き用のモデルも要らず、VRAM も増えない。出力の傾向も変わらない。書き直しのように入力を写す使い方に向き、エージェントのツール呼び出しには向かない。
投機的デコーディング(speculative decoding)は、次の数トークンを安く「下書き」して、本体のモデルがまとめて確かめる仕組みです。下書きが当たった分だけ、1 回の計算で進むトークンが増えます。確かめる工程があるので、出力の傾向(確率の分布)は変わりません。
下書きの作り方には、小さな別のモデルを使う方法と、モデルに付いた先読みの頭(MTP)を使う方法、そして今回の n-gram があります。n-gram は、いま書いているトークンの並びと同じ並びが文脈の中に前にも出てきていれば、その続きをそのまま下書きにします。追加のモデルが要らないので手軽ですが、「同じ並びが前に出てくる」使い方でしか当たりません。その差がどれくらいかを、手元の GPU で測りました。数字は 2026年9月29日時点のものです。
ngram-mod の仕組み
llama.cpp にはいくつかの n-gram の方式があり、ngram-mod はその 1 つです。llama.cpp の説明によると、次のように動きます。
- 文脈のトークンの並び(既定では 24 トークン)ごとにハッシュを取り、その並びの次に来たトークンを覚えておく
- 生成中は、直前の並びのハッシュで表を引いて、次のトークンを続けて下書きにする(下書きの長さは可変)
- 表は約 16MB で、サーバーのすべての要求で共有される。前の要求で覚えた並びが、次の要求でも使われる
llama.cpp の説明では、向く使い方として、文章やコードの塊の書き直し、推論モデルが考えた内容を答えで繰り返す場合、要約が挙げられています。
測った環境
| 項目 | 内容 |
|---|---|
| GPU | GeForce RTX 5060 Ti 16GB(電力の上限 180W) |
| CPU・メモリ | Core i5-12400F・DDR4-3200 32GB |
| OS・ドライバ | Windows 11・NVIDIA ドライバ 610.47 |
| llama.cpp | b11193(公式の Windows 向け CUDA 13.4 版)の llama-server |
| モデル | Qwen3-Coder-30B-A3B の派生モデル(MoE・IQ3_M の量子化・13.5GB) |
| 共通の設定 | -c 32768 -np 1 -fa on -ctk q8_0 -ctv q8_0 -b 512 -ub 512 --jinja。置き場所は自動。サンプリングは Qwen3-Coder の推奨値の温度 0.7・top_p 0.8・top_k 20(repetition_penalty は付けていない) |
| 先読みあり | 上に --spec-type ngram-mod を足しただけ(照合の長さなどは既定値)。VRAM は先読みなしと同じ 14,695MiB |
問い 1: ファイル全体を返させる書き直し
手元の Python のファイル 3 つ(入力 1,098〜1,604 トークン)について、「関数の名前を 1 つ変え、呼び出している箇所もすべて直して、ファイル全体を返して」と頼みました。出力のほとんどは入力の写しになる、n-gram に有利な問いです。各 2 回ずつ測りました。
| ファイル(出力) | 先読みなし | ngram-mod 1 回目 | ngram-mod 2 回目 | 下書きの当たり |
|---|---|---|---|---|
| A(1,511 トークン) | 79.9 | 418.4(×5.2) | 524.0(×6.6) | 93%・97% |
| B(1,016 トークン) | 82.1〜82.2 | 362.6(×4.4) | 448.8(×5.5) | 96%・86% |
| C(1,325 トークン) | 80.7〜80.9 | 344.2(×4.3) | 450.6(×5.6) | 94%・96% |
生成の tok/s。倍率は同じ回の先読みなしとの比。1 回の応答の時間は 12.9〜20.0 秒 → 2.9〜4.6 秒。2026年9月29日に測定。
- 生成は 4.3〜6.6 倍になりました。出力のトークン数と書き出しは、先読みの有無で同じです
- 下書きの当たりは 86〜97% で、出力の 9 割前後を入力から写せています
- 2 回目のほうが速いのは、表がすべての要求で共有されるためとみられます。1 回目の出力の並びも表に入り、2 回目はそれも使えます。はじめて扱うファイルなら、1 回目の 4.3〜5.2 倍が目安です
問い 2: エージェントの実際の要求
次に、コーディングエージェントの opencode が実際にモデルへ送っている要求の形で測りました。システムプロンプト(約 9,400 字)と 9 個の道具(ファイルの読み書き・検索・コマンドの実行など)の定義はそのままで、ツール呼び出しの問題 28 問を載せています。1 手目で正しい道具を呼ぶか、道具の結果を受けて続けられるか、エラーから立て直せるか、といった問題です。
| 28 問 | 先読みなし | ngram-mod |
|---|---|---|
| 生成 tok/s(中央値) | 66.2 | 66.1 |
| 問題ごとの比(中央値・範囲) | — | 1.00(0.96〜1.45) |
| 先読みが出た問題 | — | 9 問(当たりの中央値 28%) |
| 出力の長さ(中央値) | 55 トークン | 46.5 トークン |
入力が長い(システムプロンプトと道具の定義)ので、先読みなしでも問い 1 より遅い。乱数の種を固定していないので、問題ごとの出力は同じではない(先読みなしの 1 問は出力の上限の 8,192 トークンまで書き続けた)。2026年9月29日に測定。
ほとんど変わりませんでした。ツール呼び出しは、道具の名前と引数を組み立てる短い出力が中心です。ファイルを直すときも、ファイル全体ではなく差分だけを渡す道具を使うので、入力から長く写せる並びがほとんどありません。先読みが出た 9 問でも、当たりは 3 割ほどでした。
使い分けの目安
- 向く: ファイル全体の書き直し(名前の変更・整形・一括の置き換え)、長い文章の書き写しや手直し。入力と出力で同じ並びが長く続く使い方
- 向かない: エージェントのツール呼び出し、短い答え、新しく文章を書く使い方
付けても出力の傾向は変わらず、VRAM もほぼ増えないので、書き直しの多い使い方なら付けておいて損はありません。
opencode を llama-server に直接つなぐときの注意
手元では、opencode を Ollama ではなく llama-server に直接つなぐと、1 本目の作業に 400 秒かかりました。修正そのものは正しかったものの、そのあと確認の試みを 40 回ほど繰り返しています。Ollama につないだときの作業 1 本の中央値は 13 秒でした。原因は確かめていません。n-gram を試すために llama-server に切り替えるなら、先にふだんの作業が同じように終わるかを見てください。
測っていないこと
- ほかのモデル(とくに全部が GPU に載る密なモデル)。llama.cpp の説明では、MoE は長い下書きが要り、密なモデルは下書きの長さを縮められるとされています
- 照合の長さなど
ngram-modの設定を変えた場合と、ほかの n-gram の方式(ngram-simple・ngram-map-kなど) - opencode での作業 1 本あたりの時間(上の注意のとおり、llama-server では作業そのものが安定しなかった)
- 要約や、推論モデルが答えで考えた内容を繰り返す場合に、どれくらい速くなるか
まとめ
- llama.cpp の
--spec-type ngram-modは、下書き用のモデルなしで使える投機的デコーディング。出力の傾向は変わらず、VRAM もほぼ増えない - ファイル全体の書き直しでは、生成が 4.3〜6.6 倍になった(80 → 344〜524 tok/s・RTX 5060 Ti・2026年9月29日時点)
- エージェントの実際の要求では変わらなかった(66.2 → 66.1 tok/s)。短いツール呼び出しには、写せる並びがない
- 入力を写す使い方かどうかで、付ける価値が決まる
出典
- llama.cpp の投機的デコーディングの説明(ngram-mod の仕組み・既定値・向く使い方): https://github.com/ggml-org/llama.cpp/blob/master/docs/speculative.md
- Qwen3-Coder-30B-A3B-Instruct(Hugging Face・推奨のサンプリング): https://huggingface.co/Qwen/Qwen3-Coder-30B-A3B-Instruct
- opencode: https://opencode.ai
この記事は、手元の機材で行った測定をもとにした一般的な技術情報の提供を目的としており、特定の製品・ソフトウェアの購入や利用を推奨・勧誘するものではありません。数値は 2026年9月29日時点の測定で、モデル・ソフトの版・設定・機材によって変わることがあります。