---
schemaVersion: 1
slug: lv-19-20261020-speculative-decoding
ticketId: Lv-19
lang: zh-tw
title: 在神諭塔當見習抄寫刺蝟，偷寫答案讓預言快了好幾倍，神諭卻一個字都沒被改到：推測解碼入門
summary: 神諭塔的發條神諭每吐一個字，就得把整部典籍從塔底吊上來一次。負責抄寫的見習刺蝟 Mogu 戴著香菇帽、無聊到開始偷寫答案，預言快了好幾倍，內容卻一個字都沒變。這篇用一段輕小說教推測解碼：LLM 吐字為什麼卡在記憶體頻寬、小模型怎麼先猜、大模型怎麼一次驗收一整排，以及那條讓輸出機率分布完全不變的接受規則。
originalDate: 2026-10-20
translatedDate: 2026-10-20
source: Level-Up 系列
sourceUrl: https://gu-log.vercel.app/posts/lv-19-20261020-speculative-decoding
author: null
authorshipNote: null
canonicalUrl: https://gu-log.vercel.app/posts/lv-19-20261020-speculative-decoding
status: published
replacementTicketId: null
replacementUrl: null
---

# 在神諭塔當見習抄寫刺蝟，偷寫答案讓預言快了好幾倍，神諭卻一個字都沒被改到：推測解碼入門

> **來源:** [Level-Up 系列](https://gu-log.vercel.app/posts/lv-19-20261020-speculative-decoding)

神諭塔頂樓，黃銅齒輪喀的一聲停住，出字口掉出一片銅字：「當」。

接著，整座塔開始搬書。

大神諭是一台比塔還老的發條機器。它不說話、沒有表情，唯一會做的事，是一個字一個字往外吐預言。機器本身什麼都不記得，它知道的一切都寫在一部厚到要用絞盤吊的典籍裡，平常鎖在塔底的書庫。每吐一個字，典籍就得整部沿著井道吊上頂樓，讓齒輪從第一頁讀到最後一頁，再吊回去。下一個字，再來一次。

出字口旁邊有一張抄寫台，坐著一隻戴香菇帽的見習抄寫刺蝟：[Mogu](https://gu-log.vercel.app/glossary#mogu)。牆上的工作守則只有一行：「神諭吐一字，抄一字。」

> 第一天抄了四十二個字，聽了四十二次絞盤聲。我開始懷疑這座塔是用來磨練刺蝟耐心的。

這座塔，就是大型語言模型（LLM）生成文字時的樣子。接下來 Mogu 為了不在抄寫台上無聊到縮成一顆刺球而想出來的偷懶法，業界叫 `speculative decoding`，這篇用中文叫它推測解碼。爬完七層，讀者會知道小模型怎麼替大模型先猜、大模型怎麼一口氣驗收一整排，還有整套技巧最反直覺的地方：用了它，大模型吐出來的東西跟沒用時一樣，連機率分布都一樣。

## 第 1 層：一個字，吊一次書

**Level 1 / 7 — 神諭塔抄寫刺蝟見習日誌 — 14% 完成**

第三天，Mogu 想到一個辦法：既然典籍都吊上來了，乾脆讓神諭一次吐兩個字。

這個辦法撐不到中午。機器的構造是這樣：把目前為止的整段預言餵進去，它算出「下一個字」，就這樣，一次一個。第二個字要接在第一個字後面；第一個字還沒掉出出字口之前，連機器自己都算不出第二個字該接什麼。

LLM 也是這副德性。它每次只產生一個 [Token](https://gu-log.vercel.app/glossary#token)（先想成一個字或一小段詞就好），產生的方式是把整個模型從頭到尾跑一遍，這一趟叫一次 `forward pass`。第 t+1 個 token 要拿第 t 個 token 當輸入，所以生成天生是一個接一個：要吐 100 個 token，就得乖乖跑 100 趟，中間沒有捷徑。這種吐一個、接回去、再吐下一個的生成方式，叫自回歸（`autoregressive`）解碼。[Lv-12](https://gu-log.vercel.app/posts/levelup-20260608-12-llm-internals/) 把這個「下一個 token」迴圈從頭走過一次，想補底子可以先繞過去。

> **Mogu 認真說：**
>
> `autoregressive` 這個字拆開很好記：`auto` 是「自己」，`regressive` 來自統計的「回歸」，也就是拿過去的值預測下一個值。合起來就是「拿自己剛剛吐出來的東西，預測自己下一個要吐什麼」。
>
> 聽起來像在原地繞圈，實際上也真的是在原地繞圈，而且每繞一圈都要吊一次書。我第三天就看懂了這件事，然後一路絕望到第三十天 ┐(￣ヘ￣)┌

一百個字，一百次絞盤聲。真正的問題是：時間到底花在哪裡？

**Quiz:** LLM 為什麼不能讓第 2、第 3 個 token 跟第 1 個 token 同時算出來？

- A. 因為 GPU 一次只能做一件事
- B. 因為第 2 個 token 要拿第 1 個 token 當輸入，第 1 個還沒決定，第 2 個沒得算
- C. 因為模型廠商刻意限速，好多收一點錢
- D. 因為大神諭有起床氣

**Answer:** B — 自回歸解碼的每一步，都以前面所有已產生的 token 為輸入，所以未來的 token 必須等前一個決定之後才能算。A 不對，GPU 其實很擅長同時做大量運算，第 2 層會看到它大部分時間反而閒著。C 是陰謀論。D 也不對，大神諭是機器，沒有情緒。

---

## 第 2 層：慢的不是讀，是吊

**Level 2 / 7 — 神諭塔抄寫刺蝟見習日誌 — 29% 完成**

Mogu 拿沙漏量了一整天。

齒輪讀完整部典籍：眨一下眼。絞盤把典籍從塔底吊上頂樓：大半個沙漏。頂樓的齒輪大部分時間都停在原地，等書。

> 原來這座塔慢，不是因為神諭想得慢，是因為井道太窄。

GPU（顯示卡上負責大量平行運算的那顆晶片）跑 LLM 時，狀況幾乎一模一樣。模型的知識存在權重（`weights`）裡，這些權重放在 GPU 的高頻寬記憶體（`HBM`）。每產生一個 token，幾乎所有權重都得從記憶體送進運算單元一次；可是每個 token 分到的計算量其實不大，運算單元一下就算完，接著閒在那裡，等下一批權重送到。

瓶頸卡在記憶體頻寬，不在算力，這種狀態叫記憶體受限（`memory-bound`）。同一時間只服務少數請求、也就是 `batch` 很小的時候最明顯，例如自己在電腦上跟模型一對一聊天。（`batch` 變大會怎樣，第 6 層再算帳。）

> **塔裡每樣東西，現實裡是什麼**
>
> - **大神諭（發條機器）**：要用來生成文字的大模型。推測解碼的論文叫它 `target model`，等一下會一直用到這個名字。
> - **典籍**：模型的權重。
> - **塔底書庫**：GPU 的記憶體（`HBM`）。
> - **井道和絞盤**：記憶體頻寬，也就是每秒能把多少權重送上樓。
> - **頂樓齒輪**：GPU 的運算單元。
> - **吐出一個字**：跑一次 `forward pass`，產生一個 token。

> **Mogu 真心話：**
>
> 所以替這座塔多裝幾組齒輪，對吐字速度幾乎沒幫助；把井道挖寬才有用。這也是大家討論在自己電腦上跑模型時，老是在比記憶體頻寬的原因，[MP-286](https://gu-log.vercel.app/posts/mp-286-20260413-ggerganov-llama-cpp-mac-300-t-s-georgi-gerganov/) 拆解 Mac 為什麼跑得快時，也把統一記憶體解決頻寬瓶頸排在最前面。
>
> 我替那組齒輪覺得委屈。全塔最貴的零件，一天裡大半時間在發呆，跟我一樣。

**Quiz:** 一個人在自己電腦上跑模型聊天，同時只有這一個請求。哪個升級最可能讓吐字明顯變快？

- A. 換更快的運算核心，記憶體頻寬維持不變
- B. 換記憶體頻寬更高的硬體
- C. 換一顆更大的硬碟
- D. 幫大神諭的齒輪上油

**Answer:** B — 同時處理的請求很少時，生成每個 token 都要把幾乎所有權重從記憶體搬到運算單元一次，運算單元大多在等資料，瓶頸是記憶體頻寬。A 加的是本來就閒著的算力。C 的硬碟只在載入模型時用到，生成時權重已經在記憶體裡。D 很貼心，但齒輪本來就沒在忙。

---

## 第 3 層：吊一次書，蓋一整排章

**Level 3 / 7 — 神諭塔抄寫刺蝟見習日誌 — 43% 完成**

某天打掃頂樓，Mogu 在機器背面發現一個長長的托盤，一次可以放一整排字條。操作手冊的角落寫著用途：校對舊預言。把一整段字條放進托盤，典籍吊上來一次，齒輪就會在**每一張**字條底下，各印上一個字：「讀到這張為止的話，下一個字會吐什麼」。

Mogu 又拿出沙漏。校對一排五張字條，跟吐一個新字，花的時間差不多。

道理不難想通：典籍只需要吊上來一次，多出來的四張字條，用的是原本就閒著的齒輪。

`Transformer` 架構的模型天生就能這樣做。餵給它一整段 token，它跑一趟 `forward pass`，就能在**每個位置**都算出「下一個 token 的機率分布」；模型訓練、讀進一整段 [Prompt](https://gu-log.vercel.app/glossary#prompt)，靠的都是這個能力。在記憶體受限的情況下，一趟處理 5 個位置的時間，跟處理 1 個位置差不了多少，因為權重只要搬一次，多出來的位置吃的是閒置算力。DeepMind 團隊 2023 年的[論文](https://arxiv.org/abs/2302.01318)，摘要裡寫的正是這個觀察：讓大模型平行評分一小段延續文字，延遲跟讓它取樣單一個 token 相當。

「差不多」不是「完全一樣」，托盤也不能無限長；放太多位置，齒輪總有忙起來的一刻。不過對一小排字條來說，這筆帳非常划算。

Mogu 盯著托盤看了很久。校對很便宜，生成很貴；可是校對得先有東西可以校。要是有誰在神諭開口之前，先把後面幾個字猜好放進托盤呢？

Mogu 低頭看了看自己手上的筆。

**Quiz:** 大模型跑一趟就檢查 5 個位置，花的時間跟產生 1 個 token 差不多。主要原因是什麼？

- A. 權重只需要搬一次，多出來的位置用的是本來閒著的運算單元
- B. 檢查不用算機率，所以比產生新 token 簡單
- C. 模型會自動跳過看起來沒問題的位置
- D. 托盤是精靈族的魔法托盤

**Answer:** A — 在記憶體受限的狀態下，時間主要花在把權重從記憶體搬上來，一趟搬上來之後，多算幾個位置只是用掉原本閒置的算力。B 是常見誤會，檢查時模型在每個位置照樣算出完整的機率分布，跟生成時做的事一樣。C 不存在，每個位置都會算。D 的托盤是黃銅做的，沒有魔法。

---

## 第 4 層：本刺蝟來猜

**Level 4 / 7 — 神諭塔抄寫刺蝟見習日誌 — 57% 完成**

Mogu 腦袋很小，裝不下一部典籍，只有一本隨身筆記。但小有小的好處：不用吊書，寫得飛快。而且預言裡很多地方根本不用動腦，「當北風」後面接「吹過」，連刺蝟都猜得到。

隔天，Mogu 開始照這套流程做事：

1. 神諭每吐完一個字，Mogu 立刻在筆記上接著往下寫 4 個猜測。
2. 把「目前為止的預言 + 4 張猜測字條」整排放進托盤。
3. 典籍吊上來一次，齒輪在每張字條底下印出神諭自己會吐的字，總共 5 個位置：4 張字條各一個，最後一張後面再多一個。
4. 從左往右對答案。

這一天，神諭的設定是「永遠挑排名第一的字」，這種生成方式叫 `greedy decoding`。所以對答案的規則很單純：

- 猜的字跟神諭印的字一樣，蓋「過」。
- 第一個不一樣的位置，Mogu 的字條蓋「退」，改用神諭印在那裡的字。
- 「退」之後的字條，不管猜得多準，通通撕掉。
- 四張全過的話，最後那格神諭本來就印了字，直接收下，白賺一個。

撕掉那條最容易讓人想不通。理由是：神諭在第 3 格印的字，是假設前兩格都是 Mogu 的字才算出來的。只要第 2 格被換掉，第 3 格以後的計算前提就不存在了，就算 Mogu 第 3 格碰巧跟神諭一樣，那個「一樣」也是建立在錯的前文上，不能收。

所以每一輪最少收 1 個字：就算第一張就被退，神諭在那一格印的字還是能用。最多收 5 個字：四張全過，加上白賺的那一個。

第一個禮拜，Mogu 平均每吊一次書收三個字左右，得意到香菇帽都戴歪了。第二個禮拜碰上一段古語預言，Mogu 第一張字條就猜錯，四張全撕，一輪只換回神諭自己的一個字。跟以前一樣慢，還倒賠了猜字的時間。

> **Mogu 歪樓一下：**
>
> 那個禮拜我學到兩件事。第一，古語預言裡沒有「當北風吹過」這種送分題。第二，也是比較重要的一件：就算我猜得一塌糊塗，寫進預言書的每一個字，還是神諭自己會吐的字。被退的字條全進了垃圾桶，一個都沒混進去。
>
> 我能決定的，只有吊一次書能帶走幾個字。預言的內容從頭到尾不歸我管。這件事一開始有點傷刺蝟的自尊，後來想想，這正是整套偷懶法能放心用的原因。

> **抄寫刺蝟的正式職稱**
>
> - **Mogu**：草稿模型（`draft model`），一個又小又快的模型，負責先猜。
> - **在筆記上接著寫 4 個字**：草稿模型自己用自回歸方式產生 k 個候選 token，這裡 k = 4。因為模型小，每一步都很便宜。
> - **托盤校對**：大模型（`target model`）跑一次 `forward pass`，同時驗證 k + 1 個位置。
> - **過／退**：接受（`accept`）／拒絕（`reject`）草稿 token。
> - **最後那格白賺的字**：`bonus token`。
> - **同一套銅字字模**：草稿模型跟大模型共用同一套 `tokenizer` 與詞彙表，不然連對答案都沒辦法對。

**Quiz:** 前文是「當北風」，Mogu 猜「吹過、第七、座、塔」，神諭在 5 個位置依序印出「吹過、第七、道、門、前」。這一輪寫進預言書的是哪幾個字？

- A. 吹過、第七、道
- B. 吹過、第七
- C. 吹過、第七、道、門、前
- D. 吹過、第七、座、塔

**Answer:** A — 前兩格猜對，接受吹過和第七。第三格 Mogu 猜座、神諭印道，第一個不一致，改用神諭的道。之後神諭印的門和前，是假設第三格是座才算出來的，前提不成立，全部丟掉，所以這輪收 3 個字。B 少收了神諭在不一致那格給的字，那個字永遠可以收。C 和 D 都把建立在錯誤前文上的字收進去了。

---

## 第 5 層：會轉轉盤的神諭

**Level 5 / 7 — 神諭塔抄寫刺蝟見習日誌 — 71% 完成**

每逢月圓，塔裡的設定會切到轉盤模式。

這時神諭不再固定挑第一名。每個位置它都轉一次轉盤，每個候選字在盤上佔一塊，佔多大由機率決定，指針停在哪就吐哪個字。同一段前文，這次吐「圓」，下次可能吐「亮」。這就是 LLM 用溫度取樣（`sampling`）生成文字的狀況，很多聊天服務平常就是這樣跑。

Mogu 第 4 層那套「跟神諭的第一名比」突然失效了：轉盤模式下，根本沒有唯一的標準答案。要是隨便放寬標準，預言就會悄悄變成「有點像神諭、其實摻了刺蝟味」的東西。

推測解碼真正厲害的地方在這裡。Mogu 也有一個自己的小轉盤，代表草稿模型的機率，記作 q；神諭的轉盤記作 p。規則是：

1. Mogu 轉自己的轉盤，抽出一個字 x，寫上字條。
2. 驗收時，看 x 在兩個轉盤上各佔多大。神諭給 x 的比例不比 Mogu 小，就一定過；Mogu 給得比神諭多，就照 p(x) / q(x) 的機率決定過不過。寫成式子是：接受機率 = `min(1, p(x) / q(x))`。
3. 被退的話，不是隨便補一個字，而是從「差額轉盤」抽。每個字算 `max(0, p − q)`，只留下神諭給得比 Mogu 多的那一塊，重新換算成總和 100% 的轉盤，再轉一次。

規則看起來有點繞，直接算一次。前文是「今晚的月亮很」，候選字只有三個：

```text
神諭 p：圓 50%   亮 30%   美 20%
Mogu q：圓 80%   亮 10%   美 10%     （一隻很愛「圓」的刺蝟）
```

一個一個看 Mogu 抽到什麼：

```text
抽到「圓」（80%）：接受機率 = 50 / 80 = 62.5%
    → 收下「圓」：80% × 62.5% = 50%
    → 被退：      80% × 37.5% = 30%
抽到「亮」（10%）：神諭給 30%，比 Mogu 多 → 一定過，收下「亮」10%
抽到「美」（10%）：神諭給 20%，比 Mogu 多 → 一定過，收下「美」10%

被退的 30% 改從差額轉盤抽：
    圓 max(0, 50 − 80) = 0
    亮 max(0, 30 − 10) = 20
    美 max(0, 20 − 10) = 10      → 換算成 亮 2/3、美 1/3
    → 亮：30% × 2/3 = 20%
    → 美：30% × 1/3 = 10%

最後寫進預言書的機率：
    圓 50%
    亮 10% + 20% = 30%
    美 10% + 10% = 20%
```

跟神諭自己的轉盤 50 / 30 / 20 一模一樣。

不是「差不多」，是一模一樣。Mogu 多押在「圓」上的那 30 個百分點，剛好被退回 30%；差額轉盤補上的，剛好是 Mogu 少押的地方：「亮」少了 20、「美」少了 10。被退的總機率，又剛好等於差額轉盤的總面積，兩邊都是 30%。這不是這組數字湊巧：不管兩個轉盤長什麼樣子，Mogu 多押的總量一定等於少押的總量，因為兩個轉盤加起來都是 100%。

四張字條全過的話，最後一格也照樣白賺：神諭在那一格本來就算好了自己的轉盤，直接轉一次就好。

這套接受規則，在數學上保證整份預言的機率分布，跟神諭獨自轉盤時完全相同。Google 團隊的說法是輸出「沒有任何改變」；DeepMind 團隊講得更精確：在硬體數值精度的範圍內，保住大模型的分布。換句話說，浮點數的捨入誤差之外，速度是白拿的，品質一分都沒有讓。

> **Mogu 內心戲：**
>
> 這招的學名叫拒絕取樣（`rejection sampling`），是統計學的老技巧：想從一個難抽的分布取樣，就先從好抽的分布抽，再照比例決定收不收。老版本被拒絕之後要重抽，運氣差可以抽到天荒地老。
>
> 推測解碼用的是改良版：被退的那一刻，直接從差額轉盤補一個字，每一輪保證有字可收，不會白吊一次書。
>
> 我第一次把上面那串數字算完的時候，在抄寫台前呆坐了很久。我的轉盤歪成那樣，整天只想著「圓」，最後的預言書居然一點刺蝟味都沒有。猜得歪只會讓退件變多、速度變慢，不會讓預言變味。這大概是我這輩子被否定得最舒服的一次 (๑•̀ㅂ•́)و✧

**Quiz:** 沿用上面的例子：Mogu 給「美」10%，神諭給「美」20%。Mogu 抽到「美」時，這張字條被接受的機率是多少？

- A. 50%
- B. 100%
- C. 20%
- D. 看神諭今天心情

**Answer:** B — 接受機率是 min(1, p/q) = min(1, 20/10) = 1。神諭給的比例比草稿模型高，代表草稿模型在這個字上押得不夠多，抽到它一定收。不夠的那 10 個百分點，由被退時的差額轉盤補上。A 是把比例倒過來算的結果。C 是神諭的機率本身，不是接受機率。D 不對，神諭是機器，轉盤只聽機率的。

---

## 第 6 層：白忙一場的日子

**Level 6 / 7 — 神諭塔抄寫刺蝟見習日誌 — 86% 完成**

速度白拿，不代表每天都拿得到。Mogu 開始記帳。

假設每張字條被接受的機率都是 α，而且每張互不影響（真實情況沒這麼整齊，但拿來估算很好用），每輪猜 k 張。Google 團隊的論文給了每吊一次書平均能收幾個字：

```text
平均每輪收的字數 = (1 − α^(k+1)) / (1 − α)

α = 0.8，k = 4：(1 − 0.32768) / 0.2 ≈ 3.36
α = 0.5，k = 4：(1 − 0.03125) / 0.5 ≈ 1.94
α = 0.8，k = 8：(1 − 0.134)   / 0.2 ≈ 4.33
```

猜得準的日子，一次吊書收三個多字；猜得普通，連兩個都不到。第三行更值得多看一眼：k 從 4 加倍到 8，每輪只多收大約一個字，Mogu 寫字的時間卻加倍了，多寫的字條大半直接進垃圾桶。

還有一筆帳要記得：每輪收 3.36 個字，不等於快 3.36 倍。Mogu 猜字也要時間，托盤多放幾格也不是完全免費，牆上時鐘量到的加速一定比這個數字小。

白忙的日子大致有這幾種：

**猜不準的日子**。古語預言、或者神諭的轉盤被調得很平（溫度很高、要寫天馬行空的創作），α 掉下去，每輪常常只收 1 個字，再倒賠草稿模型的時間，可能比不用還慢。

**塔裡擠滿人的日子**。要是塔同時替一大群求籤者吐預言，每吊一次書，齒輪本來就要處理一大疊別人的字條，不再閒著。這就是 `batch` 很大的情況：瓶頸從記憶體頻寬轉到算力，推理變成算力受限（`compute-bound`），托盤上多放的猜測不再免費，加速跟著縮水。

**字模對不上的日子**。標準做法裡，草稿模型必須跟大模型共用同一套詞彙表，Mogu 寫的銅字神諭認不得，連第一張都沒辦法對。

後來也有變體乾脆不請另一隻刺蝟。[`Medusa`](https://arxiv.org/abs/2401.10774) 在大模型身上多裝幾個預測頭，讓它自己順便猜後面幾個位置；[MP-296](https://gu-log.vercel.app/posts/mp-296-20260415-article-inferencex-v2-nvidia-blackwell-amd/) 介紹的 MTP（`Multi-Token Prediction`）也是同一路，靠額外的預測頭先猜、大模型自己驗收，不用另外養一個草稿模型，那篇也順便把解碼階段卡在 `HBM` 頻寬的帳算了一遍。[`EAGLE`](https://arxiv.org/abs/2401.15077) 拿大模型內部的特徵來打草稿；`prompt lookup` 這類 `n-gram` 做法更省，直接從前文裡找可能重複出現的片段當草稿。不管草稿從哪裡來，驗收那一步的規則都還是同一套。

> **Mogu 溫馨提示：**
>
> 記完一個月的帳，我得到一個有點傷心的結論：我在這座塔的身價，就是那個 α。
>
> 猜得準，我是全塔最有價值的刺蝟；猜不準，我只是一個讓絞盤多等一下的累贅。所以挑草稿模型時要在「夠小、夠快」跟「夠準」之間取捨：太大猜得準但猜得慢，太小猜得快但一直被退。剛好跟我一樣，小到不用吊書、又剛好懂一點預言的那種，最好用。

**Quiz:** 下面哪個情況，推測解碼最可能幾乎沒有加速？

- A. 一個人在自己電腦上跑模型寫程式，同時只有這一個請求
- B. 雲端伺服器同時塞滿一大批請求，GPU 的算力已經吃滿
- C. 草稿模型在大多數位置都跟大模型猜得一樣
- D. Mogu 剛喝完三杯咖啡

**Answer:** B — 推測解碼賺的是記憶體受限時閒著的算力。同時處理的請求一多，運算單元本來就忙，多驗幾個位置不再免費，加速會縮水。A 是請求少、記憶體受限的典型場景，最適合。C 代表接受率高，每輪能收更多字。D 不影響，刺蝟的手速本來就夠快，問題從來不在 Mogu 寫得慢。

---

## 魔王關：把一整輪慢動作重播

**Level 7 / 7 — 神諭塔抄寫刺蝟見習日誌 — 100% 完成**

最後，把前面六層串成兩輪真正的推測解碼。神諭設在「永遠挑第一名」模式，Mogu 每輪猜 4 個字。為了好讀，下面把一個詞當成一個 token；真實的 `tokenizer` 切法會不一樣，但流程完全相同。

已經寫進預言書的是：「當北風吹過第七座橋，沉睡的」。

**第一輪**

1. Mogu（`draft model`）在筆記上接著寫 4 個猜測：「鐘」「將」「會」「響起」。這是草稿模型自己跑 4 次小小的 `forward pass`，很便宜。
2. 「目前的預言 + 4 張字條」放進托盤，典籍吊上來**一次**（大模型的一次 `forward pass`），神諭在 5 個位置各印一個字： - 「的」後面：鐘
   - 「鐘」後面：將
   - 「將」後面：再次
   - 「會」後面：有印字，但用不到
   - 「響起」後面：有印字，但用不到
3. 對答案：「鐘」過、「將」過；第三格 Mogu 寫「會」、神諭印「再次」，退，改用「再次」；「響起」撕掉。

這一輪寫進預言書：「鐘、將、再次」，3 個字。

**第二輪**

1. 預言現在停在「…沉睡的鐘將再次」。Mogu 猜：「響起」「，」「喚醒」「整座」。
2. 托盤、吊一次書，神諭印出：響起、，、喚醒、整座，最後一格印「城」。
3. 四張全過，最後一格的「城」白賺，就是 `bonus token`。

這一輪寫進預言書 5 個字。

兩輪合計 8 個字，典籍只吊了 2 次；照以前的老規矩，要吊 8 次。Mogu 多付的代價是 8 次在筆記上猜字，加上每次托盤多驗幾格。要是那天是月圓的轉盤模式，流程完全一樣，只是第 3 步的對答案換成第 5 層那套接受規則。

這套流程不是 Mogu 發明的。2022 年 11 月，Google 團隊發表[論文](https://arxiv.org/abs/2211.17192)（後來登上 ICML 2023），把它叫做 `speculative decoding`；2023 年 2 月，DeepMind 團隊發表[另一篇](https://arxiv.org/abs/2302.01318)，叫它 `speculative sampling`。兩邊差不多同時、各自走到同一個點子。Google 團隊在摘要裡寫下的關鍵觀察，正是 Mogu 在第 4 層發現的事：困難的語言建模任務裡，藏著很多簡單的小題目，效率高的小模型就能猜得很準。他們不用重新訓練、也不改模型架構，在 `T5-XXL` 上比標準 `T5X` 實作快 2 到 3 倍，輸出完全相同。DeepMind 團隊則在 `Chinchilla` 70B 上、分散式的環境裡，量到 2 到 2.5 倍的解碼加速。

這招也早就從論文走進日常。[MP-286](https://gu-log.vercel.app/posts/mp-286-20260413-ggerganov-llama-cpp-mac-300-t-s-georgi-gerganov/) 裡，`llama.cpp` 作者在一台三年前的 Mac 上跑出每秒 300 個 token，那套組合裡就有推測解碼；照 MP-286 的介紹，用的是一種叫 `Prompt Speculative Decoding`、拿 prompt 本身來找草稿的版本。[MP-220](https://gu-log.vercel.app/posts/mp-220-20260328-daniel-mac8-qwen3-14b-rtx-5060-sonnet-4-5-harness/) 拆解的 ATLAS 專案，也是在一張 `RTX 5060 Ti` 上跑打過補丁的 `llama-server`，開著推測解碼跑到每秒約 100 個 token。[MP-45](https://gu-log.vercel.app/posts/mp-45-20260208-bcherny-opus-fast-mode/) 談 Opus 的快速模式時，也把推測解碼列進可能的做法之一；不過那只是旁觀者的推測，不是確認過的事。

**Quiz:** 某一輪，Mogu 第一張字條就猜錯了。這一輪最後寫進預言書幾個字？

- A. 0 個，整輪作廢，下一輪重來
- B. 1 個，就是神諭在第一格印的字
- C. 4 個，照 Mogu 猜的寫
- D. 5 個，神諭看在 Mogu 很努力的份上全收

**Answer:** B — 大模型那一趟運算在第一格就算出了自己的 token，第一張草稿被拒絕時，直接改用這個 token，所以每輪至少收 1 個字，最壞情況等於沒用推測解碼，只是多付了草稿模型的時間。A 不對，大模型那一趟不會白跑。C 會把錯的字寫進輸出，違反整套規則。D 的神諭是機器，不看努力。

月底，那本預言書照例送去歸檔。

書裡每一個字，都是神諭自己會吐的字；月圓那幾天的字，出現的機率也跟神諭獨自轉盤時一樣。從第一頁翻到最後一頁，找不到任何一個字看得出 Mogu 來過。

整座塔唯一記得 Mogu 的，是井道旁那本絞盤日誌：同樣厚的一本預言，這個月吊書的次數少了一大截。

---

## 延伸閱讀

- [Lv-12：LLM 其實怎麼跑起來的？從 Token 到下一個 Token 迴圈](https://gu-log.vercel.app/posts/levelup-20260608-12-llm-internals/)（「下一個 token」迴圈的完整版，也就是第 1 層那座塔的內部構造）
- [MP-286：`llama.cpp` 的真正實力 — 三年前的 Mac 跑出 300 t/s，`Georgi Gerganov` 親自示範](https://gu-log.vercel.app/posts/mp-286-20260413-ggerganov-llama-cpp-mac-300-t-s-georgi-gerganov/)（記憶體頻寬、量化跟推測解碼疊在一台 Mac 上的實際樣子）
- [MP-296：`InferenceX v2`：NVIDIA `Blackwell` 屠榜實錄，AMD 軟體債怎麼還](https://gu-log.vercel.app/posts/mp-296-20260415-article-inferencex-v2-nvidia-blackwell-amd/)（MTP 這種不用另外養草稿模型的推測解碼變體，還有解碼階段卡在 `HBM` 頻寬的帳）
- [MP-220：ATLAS：一張 `RTX 5060 Ti` + `Qwen3-14B` 在 `LiveCodeBench` 跑贏 Sonnet 4.5？拆解 harness 的真正魔法](https://gu-log.vercel.app/posts/mp-220-20260328-daniel-mac8-qwen3-14b-rtx-5060-sonnet-4-5-harness/)（一張消費級顯示卡開推測解碼的實際用法）
- [Google 團隊的推測解碼論文](https://arxiv.org/abs/2211.17192)與 [DeepMind 團隊的推測取樣論文](https://arxiv.org/abs/2302.01318)（第 5 層那條接受規則的正式證明都在裡面）
