<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Speculative-Decoding on Tarragon</title><link>https://tarrragon.github.io/blog/tags/speculative-decoding/</link><description>Recent content in Speculative-Decoding on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Tue, 12 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/speculative-decoding/index.xml" rel="self" type="application/rss+xml"/><item><title>Acceptance Rate</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/acceptance-rate/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/acceptance-rate/</guid><description>&lt;p>Acceptance rate（接受率）的核心概念是「&lt;strong>在 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/speculative-decoding/" data-link-title="Speculative Decoding" data-link-desc="用小模型猜未來 token、大模型並行驗證的加速技巧">speculative decoding&lt;/a> 中、&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/drafter-model/" data-link-title="Drafter Model" data-link-desc="speculative decoding 中用來快速猜未來 token 的小模型">drafter&lt;/a> 提出的 token 序列被 target model 驗證後接受的比例&lt;/strong>」。Acceptance rate 直接決定 speculative decoding 的實際加速倍率：高 acceptance rate（如 0.8）能拉出接近理論上限的加速；低 acceptance rate（如 0.3）可能反而比純 target model 慢。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Speculative decoding 一個 step 的流程：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">1. Drafter 一次生 K 個候選 token（如 K=5）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">2. Target model 對「prefix + 這 K 個 token」並行驗證
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">3. 從前往後：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> - drafter token i 跟 target 第 i 個位置 sampling 一致 → 接受
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl"> - 第一個不一致 → 接受到此為止、用 target 的 token 取代第一個不一致
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">4. 若全 K 個都接受、target 再 sample 一個 bonus token&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Acceptance rate 影響：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>場景&lt;/th>
 &lt;th>Acceptance rate&lt;/th>
 &lt;th>實際加速&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Drafter 跟 target 高度同分佈&lt;/td>
 &lt;td>0.8 ~ 0.95&lt;/td>
 &lt;td>接近 K 倍上限&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Drafter / target 一般搭配&lt;/td>
 &lt;td>0.5 ~ 0.7&lt;/td>
 &lt;td>約 1.5 ~ 2× 加速&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Drafter 訓練分佈差很多&lt;/td>
 &lt;td>0.2 ~ 0.4&lt;/td>
 &lt;td>接近 1×（甚至更慢）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Drafter / target tokenizer 不一致&lt;/td>
 &lt;td>不能用&lt;/td>
 &lt;td>概念不成立&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="影響-acceptance-rate-的因素">影響 acceptance rate 的因素&lt;/h2>
&lt;ol>
&lt;li>&lt;strong>Drafter / target 同 family&lt;/strong>：同訓練分佈、acceptance rate 高（如 Gemma 4 31B + Gemma 4 E4B）&lt;/li>
&lt;li>&lt;strong>任務難度&lt;/strong>：簡單任務（boilerplate、常見 pattern）drafter 容易猜對；困難任務（reasoning、罕見領域）acceptance rate 降&lt;/li>
&lt;li>&lt;strong>Sampling temperature&lt;/strong>：高 temperature 兩邊 sample 分佈都拉平、隨機性增加、acceptance rate 降；T=0（greedy）acceptance rate 最高&lt;/li>
&lt;li>&lt;strong>K 設太大&lt;/strong>：drafter 越往後預測、累積誤差越大、後半段 token acceptance rate 急降；K 通常設 3-5 為甜蜜點&lt;/li>
&lt;/ol>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 speculative decoding 設定 / model card 看到「draft acceptance」「acceptance length」就是這指標。寫 code 場景的判讀：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>挑 drafter 看 family + 大小&lt;/strong>：drafter 跟 target 同 family（如 Gemma 4 31B + Gemma 4 E4B、Qwen3-30B + Qwen3-1.5B）是 acceptance rate 最高的組合&lt;/li>
&lt;li>&lt;strong>&lt;code>llama-bench&lt;/code> 量實際加速比理論 K 倍重要&lt;/strong>：理論加速 = K × acceptance rate、實測才知道 drafter 在自己工作流的真實表現&lt;/li>
&lt;li>&lt;strong>太低的 acceptance rate 是訊號&lt;/strong>：&amp;lt; 0.3 通常表示 drafter / target 不匹配、值得換 drafter；&amp;lt; 0.5 表示甜蜜點以下、可調 K 或 sampling 設定&lt;/li>
&lt;li>&lt;strong>MTP（Multi-Token Prediction）&lt;/strong>：把 drafter 改成 target 內建多預測 head、acceptance rate 通常更高（因為 head 跟 target 完全同分佈）&lt;/li>
&lt;/ol></description><content:encoded><![CDATA[<p>Acceptance rate（接受率）的核心概念是「<strong>在 <a href="/blog/llm/knowledge-cards/speculative-decoding/" data-link-title="Speculative Decoding" data-link-desc="用小模型猜未來 token、大模型並行驗證的加速技巧">speculative decoding</a> 中、<a href="/blog/llm/knowledge-cards/drafter-model/" data-link-title="Drafter Model" data-link-desc="speculative decoding 中用來快速猜未來 token 的小模型">drafter</a> 提出的 token 序列被 target model 驗證後接受的比例</strong>」。Acceptance rate 直接決定 speculative decoding 的實際加速倍率：高 acceptance rate（如 0.8）能拉出接近理論上限的加速；低 acceptance rate（如 0.3）可能反而比純 target model 慢。</p>
<h2 id="概念位置">概念位置</h2>
<p>Speculative decoding 一個 step 的流程：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">1. Drafter 一次生 K 個候選 token（如 K=5）
</span></span><span class="line"><span class="ln">2</span><span class="cl">2. Target model 對「prefix + 這 K 個 token」並行驗證
</span></span><span class="line"><span class="ln">3</span><span class="cl">3. 從前往後：
</span></span><span class="line"><span class="ln">4</span><span class="cl">   - drafter token i 跟 target 第 i 個位置 sampling 一致 → 接受
</span></span><span class="line"><span class="ln">5</span><span class="cl">   - 第一個不一致 → 接受到此為止、用 target 的 token 取代第一個不一致
</span></span><span class="line"><span class="ln">6</span><span class="cl">4. 若全 K 個都接受、target 再 sample 一個 bonus token</span></span></code></pre></div><p>Acceptance rate 影響：</p>
<table>
  <thead>
      <tr>
          <th>場景</th>
          <th>Acceptance rate</th>
          <th>實際加速</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Drafter 跟 target 高度同分佈</td>
          <td>0.8 ~ 0.95</td>
          <td>接近 K 倍上限</td>
      </tr>
      <tr>
          <td>Drafter / target 一般搭配</td>
          <td>0.5 ~ 0.7</td>
          <td>約 1.5 ~ 2× 加速</td>
      </tr>
      <tr>
          <td>Drafter 訓練分佈差很多</td>
          <td>0.2 ~ 0.4</td>
          <td>接近 1×（甚至更慢）</td>
      </tr>
      <tr>
          <td>Drafter / target tokenizer 不一致</td>
          <td>不能用</td>
          <td>概念不成立</td>
      </tr>
  </tbody>
</table>
<h2 id="影響-acceptance-rate-的因素">影響 acceptance rate 的因素</h2>
<ol>
<li><strong>Drafter / target 同 family</strong>：同訓練分佈、acceptance rate 高（如 Gemma 4 31B + Gemma 4 E4B）</li>
<li><strong>任務難度</strong>：簡單任務（boilerplate、常見 pattern）drafter 容易猜對；困難任務（reasoning、罕見領域）acceptance rate 降</li>
<li><strong>Sampling temperature</strong>：高 temperature 兩邊 sample 分佈都拉平、隨機性增加、acceptance rate 降；T=0（greedy）acceptance rate 最高</li>
<li><strong>K 設太大</strong>：drafter 越往後預測、累積誤差越大、後半段 token acceptance rate 急降；K 通常設 3-5 為甜蜜點</li>
</ol>
<h2 id="設計責任">設計責任</h2>
<p>讀 speculative decoding 設定 / model card 看到「draft acceptance」「acceptance length」就是這指標。寫 code 場景的判讀：</p>
<ol>
<li><strong>挑 drafter 看 family + 大小</strong>：drafter 跟 target 同 family（如 Gemma 4 31B + Gemma 4 E4B、Qwen3-30B + Qwen3-1.5B）是 acceptance rate 最高的組合</li>
<li><strong><code>llama-bench</code> 量實際加速比理論 K 倍重要</strong>：理論加速 = K × acceptance rate、實測才知道 drafter 在自己工作流的真實表現</li>
<li><strong>太低的 acceptance rate 是訊號</strong>：&lt; 0.3 通常表示 drafter / target 不匹配、值得換 drafter；&lt; 0.5 表示甜蜜點以下、可調 K 或 sampling 設定</li>
<li><strong>MTP（Multi-Token Prediction）</strong>：把 drafter 改成 target 內建多預測 head、acceptance rate 通常更高（因為 head 跟 target 完全同分佈）</li>
</ol>
]]></content:encoded></item><item><title>3.9 Speculative decoding 內部：drafter / 驗證 / 加速上限</title><link>https://tarrragon.github.io/blog/llm/03-theoretical-foundations/speculative-decoding-internals/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/03-theoretical-foundations/speculative-decoding-internals/</guid><description>&lt;p>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/speculative-decoding/" data-link-title="Speculative Decoding" data-link-desc="用小模型猜未來 token、大模型並行驗證的加速技巧">Speculative decoding&lt;/a> 在多個前面章節被引用作為「LLM 推論加速的主要技術之一」。本章把這個機制完整展開：為什麼能加速、acceptance 怎麼運作、實際加速倍率怎麼算、&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/drafter-model/" data-link-title="Drafter Model" data-link-desc="speculative decoding 中用來快速猜未來 token 的小模型">drafter model&lt;/a> 怎麼選、跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/mtp/" data-link-title="Multi-Token Prediction (MTP)" data-link-desc="Google 為 Gemma 系列釋出的 speculative decoding 工程化實作">MTP&lt;/a> / EAGLE 等變體的關係。&lt;/p>
&lt;p>讀完本章後、看到「speculative decoding 加速 2.5×」這類聲稱時、能判斷可信度、能對自己工作流估算實際收益、能挑對 drafter。&lt;/p>
&lt;h2 id="本章目標">本章目標&lt;/h2>
&lt;ol>
&lt;li>解釋為什麼 speculative decoding 能在「不降品質」前提下加速。&lt;/li>
&lt;li>區分 drafter-based、MTP、EAGLE 三條主流路線。&lt;/li>
&lt;li>用 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/acceptance-rate/" data-link-title="Acceptance Rate" data-link-desc="speculative decoding 中 drafter 提出的 token 被 target model 接受的比例、決定實際加速倍率">acceptance rate&lt;/a> 估算實際加速倍率。&lt;/li>
&lt;li>判斷一個 drafter / target 配對是否值得用。&lt;/li>
&lt;li>看到 &lt;code>llama-bench&lt;/code> 結果時、判讀「speculative speed」對自己場景的意義。&lt;/li>
&lt;/ol>
&lt;h2 id="為什麼能加速memory-bandwidth-bound-的縫隙">為什麼能加速：&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/memory-bandwidth/" data-link-title="Memory Bandwidth" data-link-desc="記憶體每秒能讀寫多少 bytes：決定本地 LLM 生字速度的真正瓶頸">memory bandwidth&lt;/a> bound 的縫隙&lt;/h2>
&lt;p>回顧 LLM 推論的瓶頸：&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/forward-pass/" data-link-title="Forward Pass" data-link-desc="input 經過所有 layer 的計算、得到 output 的單向流程；推論跟訓練都會跑、訓練多一個反向階段">forward pass&lt;/a> 每生一個 token 要把整份模型權重從記憶體讀到處理器一次、所以 memory bandwidth 是上限。每次讀的時候、處理器有大量算力是閒置的（modern GPU / Apple Silicon 算力遠超頻寬）。&lt;/p>
&lt;p>Speculative decoding 攻擊這個閒置：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">單純 autoregressive 推論：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl"> 每 token：讀整份權重 → 算 forward → 出 1 個 token
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl"> 讀權重 N 次、生 N 個 token
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl"> 瓶頸 = memory bandwidth × N
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">Speculative decoding（K=4）：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl"> Drafter 一次生 4 個候選 token（drafter 小、讀它的權重快）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl"> Target 一次驗證 4 個位置（並行算 forward、權重只讀 1 次）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl"> 若全部接受、生 4-5 個 token（含 bonus）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl"> 讀 target 權重次數從 4 降到 1、平均 token 成本顯著降&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>關鍵理解：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Target model 的 forward pass 對 K 個位置是並行的&lt;/strong>：一次讀權重、做矩陣乘法時把 K 個位置同時算（batch dimension 變大）&lt;/li>
&lt;li>&lt;strong>算力是免費資源&lt;/strong>：原本閒置的算力被用來「同時算多個位置」、不增加 memory bandwidth 消耗&lt;/li>
&lt;li>&lt;strong>正確性保證&lt;/strong>：sampling 階段的接受 / 拒絕邏輯確保最終輸出分佈跟「純 target 自回歸生成」一致 — speculative decoding 不降品質、只省時間&lt;/li>
&lt;/ol>
&lt;h2 id="演算法核心sampling-階段的接受邏輯">演算法核心：sampling 階段的接受邏輯&lt;/h2>
&lt;p>詳細的接受機制（簡化版）：&lt;/p></description><content:encoded><![CDATA[<p><a href="/blog/llm/knowledge-cards/speculative-decoding/" data-link-title="Speculative Decoding" data-link-desc="用小模型猜未來 token、大模型並行驗證的加速技巧">Speculative decoding</a> 在多個前面章節被引用作為「LLM 推論加速的主要技術之一」。本章把這個機制完整展開：為什麼能加速、acceptance 怎麼運作、實際加速倍率怎麼算、<a href="/blog/llm/knowledge-cards/drafter-model/" data-link-title="Drafter Model" data-link-desc="speculative decoding 中用來快速猜未來 token 的小模型">drafter model</a> 怎麼選、跟 <a href="/blog/llm/knowledge-cards/mtp/" data-link-title="Multi-Token Prediction (MTP)" data-link-desc="Google 為 Gemma 系列釋出的 speculative decoding 工程化實作">MTP</a> / EAGLE 等變體的關係。</p>
<p>讀完本章後、看到「speculative decoding 加速 2.5×」這類聲稱時、能判斷可信度、能對自己工作流估算實際收益、能挑對 drafter。</p>
<h2 id="本章目標">本章目標</h2>
<ol>
<li>解釋為什麼 speculative decoding 能在「不降品質」前提下加速。</li>
<li>區分 drafter-based、MTP、EAGLE 三條主流路線。</li>
<li>用 <a href="/blog/llm/knowledge-cards/acceptance-rate/" data-link-title="Acceptance Rate" data-link-desc="speculative decoding 中 drafter 提出的 token 被 target model 接受的比例、決定實際加速倍率">acceptance rate</a> 估算實際加速倍率。</li>
<li>判斷一個 drafter / target 配對是否值得用。</li>
<li>看到 <code>llama-bench</code> 結果時、判讀「speculative speed」對自己場景的意義。</li>
</ol>
<h2 id="為什麼能加速memory-bandwidth-bound-的縫隙">為什麼能加速：<a href="/blog/llm/knowledge-cards/memory-bandwidth/" data-link-title="Memory Bandwidth" data-link-desc="記憶體每秒能讀寫多少 bytes：決定本地 LLM 生字速度的真正瓶頸">memory bandwidth</a> bound 的縫隙</h2>
<p>回顧 LLM 推論的瓶頸：<a href="/blog/llm/knowledge-cards/forward-pass/" data-link-title="Forward Pass" data-link-desc="input 經過所有 layer 的計算、得到 output 的單向流程；推論跟訓練都會跑、訓練多一個反向階段">forward pass</a> 每生一個 token 要把整份模型權重從記憶體讀到處理器一次、所以 memory bandwidth 是上限。每次讀的時候、處理器有大量算力是閒置的（modern GPU / Apple Silicon 算力遠超頻寬）。</p>
<p>Speculative decoding 攻擊這個閒置：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">單純 autoregressive 推論：
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">  每 token：讀整份權重 → 算 forward → 出 1 個 token
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">  讀權重 N 次、生 N 個 token
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">  瓶頸 = memory bandwidth × N
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">Speculative decoding（K=4）：
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">  Drafter 一次生 4 個候選 token（drafter 小、讀它的權重快）
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">  Target 一次驗證 4 個位置（並行算 forward、權重只讀 1 次）
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">  若全部接受、生 4-5 個 token（含 bonus）
</span></span><span class="line"><span class="ln">10</span><span class="cl">  讀 target 權重次數從 4 降到 1、平均 token 成本顯著降</span></span></code></pre></div><p>關鍵理解：</p>
<ol>
<li><strong>Target model 的 forward pass 對 K 個位置是並行的</strong>：一次讀權重、做矩陣乘法時把 K 個位置同時算（batch dimension 變大）</li>
<li><strong>算力是免費資源</strong>：原本閒置的算力被用來「同時算多個位置」、不增加 memory bandwidth 消耗</li>
<li><strong>正確性保證</strong>：sampling 階段的接受 / 拒絕邏輯確保最終輸出分佈跟「純 target 自回歸生成」一致 — speculative decoding 不降品質、只省時間</li>
</ol>
<h2 id="演算法核心sampling-階段的接受邏輯">演算法核心：sampling 階段的接受邏輯</h2>
<p>詳細的接受機制（簡化版）：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">給定：drafter D、target T、context prefix x、speculative length K
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">Step 1：D 從 x 生 K 個候選 token：d_1, d_2, ..., d_K
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">        對每個位置算 D(d_i | x, d_1..i-1) 機率
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">Step 2：T 對 (x, d_1, d_2, ..., d_K) 做一次 forward pass、得到每個位置的 T 分佈
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">        T_1 = T(· | x)
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">        T_2 = T(· | x, d_1)
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">        ...
</span></span><span class="line"><span class="ln">10</span><span class="cl">        T_K = T(· | x, d_1..K-1)
</span></span><span class="line"><span class="ln">11</span><span class="cl">        T_{K+1} = T(· | x, d_1..K)   ← bonus token 位置
</span></span><span class="line"><span class="ln">12</span><span class="cl">
</span></span><span class="line"><span class="ln">13</span><span class="cl">Step 3：從前往後處理：
</span></span><span class="line"><span class="ln">14</span><span class="cl">        for i = 1 to K:
</span></span><span class="line"><span class="ln">15</span><span class="cl">          r = uniform random in [0, 1]
</span></span><span class="line"><span class="ln">16</span><span class="cl">          if r &lt; min(1, T_i(d_i) / D(d_i)):
</span></span><span class="line"><span class="ln">17</span><span class="cl">            accept d_i           ← d_i 在 T 下機率 ≥ D 下機率、接受
</span></span><span class="line"><span class="ln">18</span><span class="cl">          else:
</span></span><span class="line"><span class="ln">19</span><span class="cl">            reject、sample 替代 token from (T_i - D)+ normalized
</span></span><span class="line"><span class="ln">20</span><span class="cl">            break
</span></span><span class="line"><span class="ln">21</span><span class="cl">
</span></span><span class="line"><span class="ln">22</span><span class="cl">Step 4：若全 K 個接受、再 sample 一個 bonus token from T_{K+1}</span></span></code></pre></div><p>關鍵性質（數學上可證明）：</p>
<ol>
<li><strong>最終輸出分佈 ≡ 純 target 自回歸</strong>：不管 drafter 多爛、speculative decoding 的輸出在統計上跟「就用 T 從頭生」完全相同 — 不是「近似」、是「等價」</li>
<li><strong>Drafter 越接近 target、acceptance rate 越高</strong>：但即使 drafter 完全亂猜、輸出仍正確、只是沒加速</li>
<li><strong>每 step 至少生 1 個 token</strong>：最差情況第一個就拒絕、用 T 取代、退化成單純 T 自回歸</li>
</ol>
<h2 id="加速倍率--k--acceptance-rate-的限制">加速倍率 = K × acceptance rate 的限制</h2>
<p>理論加速分析：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">Step 平均生 token 數 = E[接受長度] + 1（bonus 若有）
</span></span><span class="line"><span class="ln">2</span><span class="cl">                    ≈ K × acceptance_rate （簡化估算）
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl">每 step 主要成本：
</span></span><span class="line"><span class="ln">5</span><span class="cl">  Drafter K 次小 forward + Target 1 次大 forward
</span></span><span class="line"><span class="ln">6</span><span class="cl">  ≈ K × T_drafter + T_target
</span></span><span class="line"><span class="ln">7</span><span class="cl">  ≈ T_target × (1 + K × C)   where C = T_drafter / T_target
</span></span><span class="line"><span class="ln">8</span><span class="cl">
</span></span><span class="line"><span class="ln">9</span><span class="cl">加速倍率 ≈ K × acceptance_rate / (1 + K × C)</span></span></code></pre></div><p>實際例子（Gemma 4 31B target + Gemma 4 E4B drafter、K=5）：</p>
<ul>
<li>T_drafter / T_target ≈ 4B / 31B ≈ 0.13</li>
<li>K = 5、acceptance rate ≈ 0.7（同 family、estimate）</li>
<li>加速倍率 ≈ 5 × 0.7 / (1 + 5 × 0.13) ≈ 3.5 / 1.65 ≈ <strong>2.1×</strong></li>
</ul>
<p>對照 LM Studio / llama.cpp 實測常見的「2-3×」加速、推導合理。</p>
<p>什麼破壞加速：</p>
<ol>
<li><strong>Drafter 太大</strong>：C 接近 1、(1 + K × C) 爆增、淨收益消失</li>
<li><strong>Acceptance rate 太低</strong>：K × acceptance 達不到 1 + K × C、淨收益負</li>
<li><strong>K 設太大</strong>：drafter 後面 token acceptance rate 急降、且每步成本 K × T_drafter 線性增加</li>
</ol>
<h2 id="三條主流變體">三條主流變體</h2>
<h3 id="drafter-based經典-speculative-decoding">Drafter-based（經典 speculative decoding）</h3>
<p>Leviathan et al. 2022 / Chen et al. 2023 提出：</p>
<ul>
<li><strong>方式</strong>：獨立訓練一個小 drafter model、跟 target 同 family / 同 tokenizer</li>
<li><strong>代表</strong>：Gemma 4 31B + E4B、Llama 3.1 405B + 8B、Qwen3 30B + 1.5B</li>
<li><strong>優點</strong>：相對成熟、各推論伺服器（llama.cpp、vLLM）廣泛支援</li>
<li><strong>缺點</strong>：要訓 / 維護兩個 model；drafter 跟 target 必須完全相容</li>
</ul>
<h3 id="mtpmulti-token-prediction">MTP（Multi-Token Prediction）</h3>
<p>DeepSeek-V3 / Gemma 4 等內建：</p>
<ul>
<li><strong>方式</strong>：訓練 target 時、output 端額外加 K 個 head、每個 head 學「預測 N+1, N+2, &hellip;, N+K」</li>
<li><strong>代表</strong>：DeepSeek-V3（MTP=4）、Gemma 4 coding 變體</li>
<li><strong>優點</strong>：不需獨立 drafter、head 跟 target 完全同分佈、acceptance rate 高（通常 0.7-0.85）</li>
<li><strong>缺點</strong>：需要 target model 訓練時就支援、現存模型不能後加</li>
</ul>
<h3 id="eagleextrapolation-algorithm-for-greater-llm-efficiency">EAGLE（Extrapolation Algorithm for Greater LLM Efficiency）</h3>
<p>Li et al. 2024 / EAGLE-2 / EAGLE-3：</p>
<ul>
<li><strong>方式</strong>：drafter 用 target 內部的 hidden state（不是 token embedding）當輸入、預測下一個位置的 token 機率、逼近 target 的分佈。因為 drafter 看的是 target 已經處理過的 feature、acceptance rate 比純 token-based drafter 高</li>
<li><strong>代表</strong>：EAGLE-2、EAGLE-3 應用在 Llama 系列</li>
<li><strong>優點</strong>：acceptance rate 通常更高（0.8+）、且 drafter 可以很小</li>
<li><strong>缺點</strong>：實作較複雜、需要 access target 的 hidden state、推論伺服器支援度較窄</li>
</ul>
<blockquote>
<p><strong>事實查核註</strong>：MTP / EAGLE 的具體 acceptance rate 跟加速倍率依模型、任務、量化、推論伺服器實作而異、引用前以各推論伺服器 release notes 跟自己 <code>llama-bench</code> 結果為準。</p></blockquote>
<h2 id="怎麼挑-drafter">怎麼挑 drafter</h2>
<p>實務判讀：</p>
<table>
  <thead>
      <tr>
          <th>條件</th>
          <th>選擇</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Target 有內建 MTP（如 Gemma 4 coding-mtp）</td>
          <td>直接用 MTP、不另找 drafter</td>
      </tr>
      <tr>
          <td>Target 沒 MTP、有同 family 小模型</td>
          <td>用 drafter-based、選小一個量級的同 family 模型</td>
      </tr>
      <tr>
          <td>Target 沒 MTP、無同 family 小模型</td>
          <td>多半不值得 speculative、用一般推論</td>
      </tr>
      <tr>
          <td>用 Apple Silicon Mac、target ≤ 30B</td>
          <td>MTP 是首選、見 <a href="/blog/llm/knowledge-cards/mtp/" data-link-title="Multi-Token Prediction (MTP)" data-link-desc="Google 為 Gemma 系列釋出的 speculative decoding 工程化實作">MTP 卡片</a></td>
      </tr>
      <tr>
          <td>用 PC 獨立 GPU、target 較大</td>
          <td>看 llama.cpp 支援度、EAGLE-2 / drafter-based 都可</td>
      </tr>
  </tbody>
</table>
<p>挑 drafter 的反例（不該配）：</p>
<ol>
<li><strong>跨 family</strong>：Llama 3 + Qwen3 — tokenizer 不一致、無法配對</li>
<li><strong>跨 generation</strong>：Llama 2 + Llama 3 — vocab 不同</li>
<li><strong>太大 drafter</strong>：target 8B + drafter 3B — drafter 成本接近 target、淨收益小</li>
<li><strong>量化不對稱</strong>：target Q4 + drafter Q8 — drafter 不必比 target 精度高、浪費記憶體</li>
</ol>
<h2 id="怎麼測自己的加速倍率">怎麼測自己的加速倍率</h2>
<p><code>llama-bench</code> 是 llama.cpp 官方 benchmark 工具：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1"># 純 target 推論</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">llama-bench -m gemma-4-31b-Q4_K_M.gguf -p <span class="m">512</span> -n <span class="m">128</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1"># 加 drafter（speculative decoding）</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">llama-bench -m gemma-4-31b-Q4_K_M.gguf <span class="se">\
</span></span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="se"></span>            --draft-model gemma-4-e4b-Q4_K_M.gguf <span class="se">\
</span></span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="se"></span>            --n-predict <span class="m">128</span> --speculative-draft <span class="m">5</span></span></span></code></pre></div><p>看的指標：</p>
<ul>
<li><strong>tg128 (純 target)</strong>：純自回歸生 128 token 的 tokens/s</li>
<li><strong>tg128 (with draft)</strong>：speculative decoding 模式的 tokens/s</li>
<li><strong>加速倍率</strong>：後者 / 前者</li>
</ul>
<p>實際工作流的 acceptance rate 跟 benchmark 上可能不同（取決於任務）、benchmark 是上限估算。</p>
<h2 id="跟其他加速技巧的關係">跟其他加速技巧的關係</h2>
<table>
  <thead>
      <tr>
          <th>技巧</th>
          <th>攻擊的瓶頸</th>
          <th>跟 speculative decoding 的關係</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/quantization/" data-link-title="Quantization" data-link-desc="用較少 bits 表示模型權重：壓縮記憶體佔用、加快生字速度，代價是少量品質衰減">Quantization</a></td>
          <td>權重大小</td>
          <td>正交、可疊加（兩個都用）</td>
      </tr>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/flash-attention/" data-link-title="Flash Attention" data-link-desc="Attention 計算的記憶體友善實作、減少 GPU memory 讀寫、提升長 context 推論吞吐">Flash Attention</a></td>
          <td>Attention 記憶體佔用</td>
          <td>正交、可疊加</td>
      </tr>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/kv-cache/" data-link-title="KV Cache" data-link-desc="已處理 token 的 attention 中間結果暫存：避免重算、加速後續生成">KV cache 量化</a></td>
          <td>KV cache 大小</td>
          <td>正交、可疊加</td>
      </tr>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/batching/" data-link-title="Batching" data-link-desc="多 request 一起跑、攤平 model load 成本：production LLM inference 的核心優化、決定 throughput vs latency 取捨">Batching</a></td>
          <td>多請求共用權重讀取</td>
          <td>跟 speculative 邏輯衝突（共用 batch dim）</td>
      </tr>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/prefix-cache/" data-link-title="Prefix Cache" data-link-desc="把多個請求共用的前綴 prompt 的 KV cache 重用、省下重複 prefill 算力的優化、production 多用戶服務的常見設計">Prefix cache</a></td>
          <td>Prompt 重複部分</td>
          <td>正交、可疊加</td>
      </tr>
  </tbody>
</table>
<p>關鍵注意：<strong>Speculative decoding + batching 同時開的支援度差</strong> — 推論伺服器多半要選一個。個人 dev 場景 batch size = 1、用 speculative 是合理選擇；高併發 production 場景多半選 batching。</p>
<h2 id="何時不適合用-speculative-decoding">何時不適合用 speculative decoding</h2>
<ol>
<li><strong>Batch size &gt; 1 場景</strong>：跟 batching 衝突、加速可能反向</li>
<li><strong>Reasoning model</strong>：reasoning trace 的 token 多樣化、drafter 很難猜對、acceptance rate 低（多數 reasoning model 不用 speculative）</li>
<li><strong>Drafter 不存在或不合</strong>：勉強配差 family 的 drafter 反而拖慢</li>
<li><strong>記憶體吃緊</strong>：drafter 也要載入、可能擠掉 KV cache budget、其他地方變慢</li>
</ol>
<h2 id="何時過時--何時不過時">何時過時 / 何時不過時</h2>
<p><strong>不會過時的部分</strong>：</p>
<ul>
<li>「Memory bandwidth bound 留下算力閒置」的根本觀察</li>
<li>接受 / 拒絕 sampling 邏輯（數學上等價於純 target）</li>
<li>Acceptance rate × K 是加速倍率主要 driver</li>
<li>Drafter / target 必須 tokenizer 相容</li>
<li>跟 batching 衝突的 trade-off</li>
</ul>
<p><strong>會變的部分</strong>：</p>
<ul>
<li>具體變體（drafter-based / MTP / EAGLE → 未來可能新方法）</li>
<li>各推論伺服器的支援度（llama.cpp、vLLM、TGI 都在演化）</li>
<li>模型廠商是否內建 MTP（目前 Gemma 4、DeepSeek 等先行、未來普及）</li>
<li>Reasoning model 是否會有 reasoning-aware speculative 變體</li>
</ul>
<h2 id="下一步">下一步</h2>
<p>下一步：模組三的內容到此完整、進入 <a href="/blog/llm/04-applications/" data-link-title="模組四：LLM 應用層原理" data-link-desc="Prompt 技術光譜、RAG、tool use、agent、應用層協議、人機協作、multi-agent、workflow 編排、eval 設計：跨工具不變的概念地圖">模組四 應用層原理</a> 看 LLM 作為系統元件的設計取捨。</p>
]]></content:encoded></item></channel></rss>