投機的decodeのAcceptance性能検証

CHATGPT / AIChatGPTなどの生成AIを活用して運営・記事制作・更新を行っています。制作方針

llama.cpp b10328の投機的decodeを対象に、target/draft、prompt、sampling、同時数を固定し、acceptance、TTFT、総時間、memory、出力同等性を方式別に測る机上検証計画です。

Acceptanceの高さとDraft費用を分け、最終的な総時間とMemoryで方式を選ぶ比較図

先に結論

投機的decodeの評価では、acceptanceが高い方式をそのまま採用しません。target modelの検証回数を減らせても、draft作成、追加memory、sampling、同期の費用が大きければend-to-endは遅くなります。llama.cpp b10328のnoneを基準に、追加model不要のn-gram、別の小型modelを使うdraft-simple、利用可能なtargetだけEAGLE-3/MTPを別条件として測ります。model artifact、prompt、sampling、生成長、同時request数を固定し、TTFT、総時間、accepted/generated draft token、peak memory、出力同等性を同じrun IDへ結び付けるのが再現可能な設計です。

確認日時: 2026年8月12日(Asia/Tokyo)
対象version: llama.cpp b10328、commit dd2c7c4。同commitのllama-server引数・metrics文書と、2026年8月12日の公式speculative decoding文書を確認。
検証区分: 公式repositoryに基づく机上調査・実験計画です。model推論やbenchmarkを実行しておらず、速度、acceptance、memoryの実測値や方式の順位は示しません。
適用外: 非対応targetへのEAGLE-3/MTP適用、tokenizerが異なるdraftの互換性推定、品質評価を省いた速度だけの採用、複数node、production SLOの達成保証。

比較単位をartifactまで固定する

同じmodel名でもGGUF、quantization、converter、tokenizer、chat templateが変わればacceptanceも総時間も変わります。開始前に次をmanifestへ保存します。

区分固定する値防ぐ混同
runtimellama.cpp commit dd2c7c4、build options、compiler、backend、driverkernel/実装差
target元repository/revision、GGUF SHA-256、quant、tokenizer、chat templatetarget artifact差
draft方式、repository/revision、GGUF SHA-256、target対応表、draft長候補生成費用と互換性差
hardwareCPU、GPU、RAM/VRAM、device配置、電源・冷却、他processmemory帯域と競合差
requestprompt ID、入力token、生成上限、sampling、seed、stop、同時数workload差
observationcold/warm、反復、timeout、client clock、metrics snapshotcacheと測定窓の差

EAGLE-3のdraftはtargetのhidden stateを読み、特定target向けに学習され、target tokenizerを共有する仕組みです。MTPもmodel側に対応head/metadataが必要です。名前が似た小型modelを推測で組み合わせません。公式文書やartifact metadataでtargetとの対応を確認できない条件はmatrixから外します。

stochastic samplingでは、同じseedでもCPU/backend samplingの浮動小数点差でtokenが変わり得ると公式文書が説明しています。速度比較の第一段階はtemperature: 0のgreedy samplingで出力同等性を見ます。実運用が確率samplingなら、第二段階で実際のsamplerへ戻し、完全一致ではなくtask固有の品質判定へ切り替えます。

方式を段階的に増やす

一つの巨大なmatrixから始めず、次の順に条件を増やします。

  1. —spec-type noneをbaselineにする。
  2. ngram-modをb10328既定値で追加する。
  3. 繰り返しの多いworkloadだけ、n-gramのmatch長/draft長を一変数ずつ変更する。
  4. tokenizerとtarget familyの互換性を公式情報で確認できる場合だけdraft-simpleを追加する。
  5. target専用artifactがある場合だけdraft-eagle3またはdraft-mtpを追加する。
  6. 単一requestで候補を絞った後に、実運用の同時数へ広げる。

b10328の公式helpでは—spec-draft-n-maxの既定が3、ngram-modのmatch/min/maxが24/48/64です。この値を「最適値」とは扱わず、比較開始点として明示します。draft長を増やすと一度に検証できる候補は増えますが、誤った候補の生成費用やtarget検証batchも変わります。acceptanceと総時間を同時に見ます。

LLAMA_SERVER="/absolute/path/to/b10328/build/bin/llama-server"
TARGET_GGUF="/absolute/path/to/target.gguf"

# baseline
"$LLAMA_SERVER" -m "$TARGET_GGUF" \
  --host 127.0.0.1 --port 8080 \
  --spec-type none --metrics

# n-gram initial condition
"$LLAMA_SERVER" -m "$TARGET_GGUF" \
  --host 127.0.0.1 --port 8080 \
  --spec-type ngram-mod \
  --spec-ngram-mod-n-match 24 \
  --spec-ngram-mod-n-min 48 \
  --spec-ngram-mod-n-max 64 \
  --metrics

各条件の間でserver processを再起動します。公式文書ではngram-modのhash poolが全server slotで共有されるため、前条件や別requestの履歴を持ち越すと方式差とcache差を分離できません。cold start測定とwarm steady-state測定も別run IDにします。

draft model条件は、互換性確認後に次の形へ追加します。pathは実際に検証したartifactへ置き換えます。

DRAFT_GGUF="/absolute/path/to/verified-compatible-draft.gguf"

"$LLAMA_SERVER" -m "$TARGET_GGUF" \
  --spec-draft-model "$DRAFT_GGUF" \
  --spec-type draft-simple \
  --spec-draft-n-max 3 \
  --host 127.0.0.1 --port 8080 \
  --metrics

targetとdraftのtokenizer、vocabulary mapping、chat template、architecture対応が公式に確認できない場合は、このcommandを試行しません。loadできたことだけを互換性の証明にせず、greedy出力同等性とerror-freeな複数promptをgateにします。

workloadを分層する

一つのpromptで全用途を代表させず、最低でも次の層を分けます。

workload層予想ではなく確認する点
repetitivecode編集、定型format、既存文書の継続n-gramがdraftを作れるか
general chat短い質問と説明draft準備費用が支配しないか
reasoning長い推論を要する固定問題acceptanceと品質が両立するか
long input長文要約、document QATTFTとmemoryが悪化しないか
structuredJSON schemaやtool call出力制約とspeculationが干渉しないか

各promptには内容hash、入力token数、期待する判定を持たせます。生成token数が条件間で大きく違う場合、総時間だけを比較すると短い回答が有利になります。greedy第一段階では出力一致を求め、確率sampling段階ではtask別rubric、schema validation、tool argument validationを同じ条件で通します。

acceptanceと総時間を同じrunへ結ぶ

公式/metricsには、総draft token、accepted token、verification step、position別accepted tokenがあります。run前後のcounter差分を取り、別条件の累積値を混ぜません。

acceptance_rate = accepted_draft_tokens / generated_draft_tokens
end_to_end_speedup = baseline_total_ms / speculative_total_ms
decode_rate = generated_output_tokens / decode_seconds

generated draft tokenが0ならacceptance rateは未定義として扱い、0%と同一視しません。speedupが1より大きいときだけそのrunでは短縮、1未満なら遅延です。ただし採用判定は単発値ではなく、反復のmedian、p95、error数と一緒に行います。

各runで最低限保存する列は次です。

取得元判断
TTFTclientのrequest開始〜最初のtoken対話の待ち時間
total msclientの開始〜完了draft費用を含む最終効果
predicted token/sresponse timingsまたはmetrics差分decode区間の変化
draft/accepted tokenmetrics差分、server統計候補量と採用率
verification stepmetrics差分target検証回数
peak RAM/VRAMOS/accelerator monitordraft追加費用
output verdictexact matchまたはtask rubric正しさのgate
error/timeoutclientとserver log運用安定性

公式文書には各speculative implementationが統計を出すことと、SPEED-Bench clientでbaselineとspeculative runを比較できることが記載されています。ただしb10328と現行masterでtoolやoptionが変わり得るため、実際に使うbenchmark helperも同じcommitへ固定し、—helpを保存します。

採用gateとtrade-off

方式を採用するには、次をすべて満たす必要があります。

  • 必須promptの出力同等性またはtask品質gateを落とさない。
  • 対象concurrencyのtotal msまたはthroughput SLOを改善する。
  • p95 latency、timeout、errorを悪化させない。
  • 追加RAM/VRAMがcapacity margin内に収まる。
  • target/draft artifactのrevision、license、配布条件を固定できる。
  • rollbackが—spec-type noneと旧artifactで再現できる。

acceptanceが高くてもmemory不足でtargetのoffloadが減れば、全体が遅くなる可能性があります。逆にacceptanceが中程度でも、n-gramのdraft費用が十分小さいworkloadでは総時間が短くなる可能性があります。ここは推論で順位を決めず、同じrunのtotal msとpeak memoryで判定します。

複数requestではn-gram pool共有が命中率を上げる一方、request間の履歴依存を増やします。単一requestの結果をそのままmulti-userへ一般化せず、concurrency 1で正しさを通した後、実運用のslot数、arrival pattern、prompt mixでqueue、TTFT、throughputを再測定します。privacyやtenant分離が必要な環境では、共有履歴の仕様も導入判断へ含めます。

未検証範囲と判断基準

本稿はb10328のoptionと観測面を固定した実験計画であり、特定方式の優位を示すbenchmarkではありません。masterではDFlash、DSpark、複数n-gram方式、backend samplingなどが継続更新されています。新しいreleaseへ上げる場合は、同じoption名でも実装と既定値を再監査し、b10328の測定と同じseriesへ混ぜません。

EAGLE-3、MTP、DFlash、DSparkはtargetごとの専用artifactや変換条件を持ちます。利用可能なcheckpoint一覧、license、tokenizer mapping、hidden-state layer、trained block sizeを公式sourceで確認できたものだけを対象にします。未対応modelへ「近いarchitectureだから動く」と推定しません。

最終判断は方式名ではなくworkload単位です。code編集ではn-gram、一般chatではnone、特定targetではEAGLE-3という複数profileが残っても問題ありません。全trafficへ一つの勝者を強制せず、改善が再現した範囲だけへ適用します。

入門記事

初めて試す場合は、llama.cpp投機的decode入門で、追加model不要のn-gramをbaselineから有効にし、draft/accepted tokenを確認して戻す手順から始めてください。

参考資料