🌏 Read this article in English
在固定硬體、負載與取樣設定下,Speculative Decoding 的目標是降低端到端延遲並維持目標模型(Target Model)的輸出分布。其核心機制在於利用一個小型且快速的 Draft Model 自回歸生成 k 個候選 token,再由 Target Model 以一次前向計算並行驗證這些候選位置。透過精確取樣演算法(Exact Sampling),系統能保證最終輸出的機率分布與標準 Target Model 完全一致;若採用 greedy 等確定性條件,則可主張逐 token 的一致性。
這種機制的關鍵在於,雖然 Target Model 仍需進行完整的 Forward Pass,但由於它只需要處理較少的自回歸迭代次數,整體的計算量得以攤提。根據 Leviathan et al. (2022) 的研究,在特定條件下這種方法能實現顯著加速。然而,加速效能高度依賴於 Draft Model 與 Target Model 之間的 Token 預測一致性(Acceptance Rate),而非單純追求 Draft Model 的生成速度。當 Acceptance Rate 過低時,Draft Model 生成的候選 token 會被大量拒絕,系統不僅無法攤提 Target Model 的前向計算成本,反而會因為額外的模型調度開銷與 Draft Model 的生成時間,導致整體延遲增加。
前置條件與環境設定
在開始實作之前,必須確保基礎環境與變數控制已就緒。這不僅是為了建立可靠的基準,也是為了避免後續優化過程中引入不可控的變數。
Global Prerequisites:
- 硬體一致性:確保 Target Model 與 Draft Model 運行在同一 GPU 或同構架構上,以減少跨設備傳輸延遲對測量結果的干擾。
- 版本鎖定:固定 PyTorch/TensorFlow、CUDA/cuDNN、以及推理框架(如 vLLM, TGI)的版本。任何庫的更新都可能改變內存管理或算子實現,影響基準的可重現性。
- 變數控制清單:明確記錄
batch_size、max_new_tokens、temperature、top_p等參數。在比較不同模式時,這些參數必須保持完全一致,除非實作已支援基於機率的校正機制。
實作步驟:建立基準與導入機制
建議優先建立一個可靠的基準(Baseline),以確保後續的加速效果衡量準確無誤,並能識別潛在的變數干擾。
Step 1: 建立 Target-Only 基準
首先,需要建立一個僅使用 Target Model 的推理管道。這個管道將作為後續比較的唯一參考點。
前置條件:已部署 Target Model,並具備完整的推理環境。
操作步驟:
- 固定實驗變數:記錄硬體與軟體版本、暖機輪次、同步方式、固定工作負載。設定固定的
batch_size、max_new_tokens、temperature等參數。 - 準備測試輸入:準備一組代表性的測試輸入 (Prompt),涵蓋不同的長度、領域和複雜度。
- 執行推理與記錄:執行推理,記錄每個輸入的端到端延遲(End-to-End Latency)、吞吐量(Throughput)以及輸出內容。建議記錄 p50/p95/p99 延遲分位數、首 token 延遲 (TTFT)、平均 token 生成時間 (ITL) 與 tokens/s,確保比較可重現。
- 驗證輸出:在 greedy 模式下,使用相同輸入逐 token 比較 Target-Only 的輸出,確認重複執行的一致性。若採隨機取樣,單次答案比較或人工評估只能作為內容品質檢查,不能證明取樣分布等價;分布驗證需限制在固定的小詞彙與固定輸入上,對兩種模式進行重複抽樣,再以事先明定的統計量與容差比較經驗分布。
可觀察檢查:確認所有測試用例都能成功完成推理,且輸出符合預期。記錄平均延遲和每分鐘 token 生成數 (Tokens Per Minute, TPM) 作為基準數據。
停止條件:當所有測試用例都完成並記錄完畢時,停止基準建立。
回退路徑:如果發現基準測試中有任何異常,應檢查模型配置、輸入數據或環境設置,修正後重新執行。
Step 2: 導入 Draft Proposal 與 Target Verification
在建立好基準後,可以開始導入 Speculative Decoding 機制。這需要選擇一個合適的 Draft Model,並將其與 Target Model 整合。
前置條件:已建立 Target-Only 基準,並具備 Draft Model 的部署環境。
操作步驟:
- 選擇 Draft Model:Draft Model 應該比 Target Model 小得多,以便快速生成 tokens,但又足夠準確,能夠預測大部分正確的 tokens。常見的選擇是使用相同架構但參數量較小的模型,或者使用專門訓練的輕量級模型。若使用不同模型家族,需驗證 tokenizer、詞彙表及特殊 token 的相容性。
- 配置 Speculative Decoding 參數:設定 k 值(Draft Model 一次性生成的 token 數量)。精確演算法使用機率比接受規則,若介紹框架特有的信心閾值,需標明實作、用途及是否仍保證分布等價。
- 整合推理管道:修改原有的推理管道,使其支持 Speculative Decoding。這通常涉及在 Target Model 之前插入一個 Draft Model 的推理步驟,並添加驗證邏輯。
以下為簡化的 Python 偽代碼,展示如何實作 Token 驗證與校正(Correction)邏輯。注意:此代碼僅為核心邏輯示意,實際生產環境需處理 Batch size > 1 時的張量對齊、KV Cache 管理以及更複雜的錯誤邊界條件。
def speculative_decoding_step(draft_model, target_model, prompt, k=5):
# Step 1: Draft Model 自回歸產生 k 個候選 token,並回傳每個 token 的完整機率分布
# draft_tokens: LongTensor, shape (k,)
# draft_probs: Tensor, shape (k, vocab_size)
draft_tokens, draft_probs = draft_model.generate_with_probs(
prompt, max_new_tokens=k
)
# Step 2: Target Model 對這 k 個 tokens 進行一次 Forward Pass 驗證
# 輸入為 prompt + draft_tokens,返回對應的 k+1 個位置的 logits
# 包含 k 個驗證位置的分布,以及第 k+1 個 bonus token 的預測
target_logits = target_model.forward(prompt, draft_tokens)
target_probs = torch.softmax(target_logits, dim=-1)
# Step 3: 驗證機制 (Verification Logic)
accepted_count = 0
for i in range(k):
token_id = draft_tokens[i]
# 取得純量機率進行接受率判定
p_scalar = target_probs[i, token_id].item()
q_scalar = draft_probs[i, token_id].item()
u = random.uniform(0, 1)
if u < min(1.0, p_scalar / q_scalar):
accepted_count += 1
else:
break # 候選遭拒,停止驗證
# Step 4: 校正 (Correction) 與後續取樣
if accepted_count < k:
# 從正規化的殘差分布 max(p - q, 0) 取樣
# p_dist、q_dist: Tensor, shape (vocab_size,)
p_dist = target_probs[accepted_count]
q_dist = draft_probs[accepted_count]
residual_probs = torch.clamp(p_dist - q_dist, min=0.0)
sum_r = residual_probs.sum()
if sum_r > 1e-8:
next_token = sample_from_distribution(
residual_probs / sum_r
)
else:
next_token = sample_from_distribution(p_dist)
# next_token 為 scalar LongTensor;回傳 LongTensor, shape (accepted_count + 1,)
return torch.cat(
(draft_tokens[:accepted_count], next_token.reshape(1)),
dim=0,
), False
else:
# 全部接受:從 Target 模型第 k+1 個位置的分布取樣 bonus token
# 索引 [k] 對應第 k+1 個位置(因為從 0 開始算)
bonus_token = sample_from_distribution(target_probs[k])
# 回傳 LongTensor, shape (k + 1,)
return torch.cat(
(draft_tokens, bonus_token.reshape(1)),
dim=0,
), True接受率定義:在指定統計期間內,Acceptance Rate 等於「被 Target Model 接受的 Draft token 總數」除以「Draft Model 提出的 Draft token 總數」。某輪在第一個位置即遭拒時,該輪提出的 k 個 token 全數進入分母、分子增加 0;部分接受時,k 個 token 進入分母,拒絕位置之前被接受的數量進入分子;全部接受時,k 個 token 同時進入分子與分母。校正 token 與 bonus token 都不是 Draft proposal,因此不計入這個比率。
可觀察檢查:確認 Draft Model 能夠正常運行,並生成預期的 tokens。檢查整合後的推理管道是否能夠正確執行 Speculative Decoding 流程,且各輪提出數、接受數、校正 token 與 bonus token 均可追蹤。
停止條件:當整合完成並通過基本功能測試時,停止配置;這只代表功能路徑可執行,不代表分布或效能已通過最終驗證。
回退路徑:如果整合過程中出現執行異常,可以暫時關閉 Speculative Decoding 功能,回到 Target-Only 模式運行,確保系統的基本可用性(此處稱為「功能回退」)。
限制情境與邊界條件剖析
在實作 Speculative Decoding 的過程中,可能會遇到各種效能瓶頸情境。了解這些情況及其處理方法,對於確保系統的穩定性和可靠性至關重要。特別需要注意的是,當機制面臨挑戰時,除了功能性的錯誤,還可能帶來隱形的性能風險。
Tokenizer 差異導致的不一致
一個常見的優化挑戰是 Draft Model 和 Target Model 使用不同的 Tokenizer。即使兩者使用相同的模型架構,如果 Tokenizer 的詞彙表或分詞規則不同,就會導致輸出不一致。這主要適用於本文採用的經典 token-level 實作;若 tokenizer 不同,需使用明確支援重編碼與對齊的變體,不能只稱為額外轉換。
解決方案:確保 Draft Model 和 Target Model 使用完全相同的 Tokenizer。在整合之前,應仔細檢查兩者的 Tokenizer 配置。如果無法使用相同的 Tokenizer,則需要進行額外的轉換處理,但這會增加系統的複雜性並可能影響性能。
取樣設定差異 (Sampling Settings)
除了 Tokenizer,取樣設定也會影響輸出。在 Speculative Decoding 中,需區分 proposal 分布 q 與目標分布 p;精確校正可容許兩者不同,但實作必須取得相應機率並滿足演算法支援條件。若強行要求 Draft Model 和 Target Model 的取樣設定完全一致,可能並非所有場景的最優解。
解決方案:在配置推理管道時,明確指定並鎖定取樣設定。確保 Draft Model 和 Target Model 使用相同的 temperature、top-p 等參數,除非實作已支援基於機率的校正。
接受率過低導致的性能下降與回退開銷
雖然 Speculative Decoding 旨在加速推理,但如果 Draft Model 的預測能力太差,導致接受率過低,反而可能會增加計算負擔。候選遭拒時,該輪仍會輸出拒絕位置之前的已接受 token,以及一個符合 Target 分布的校正 token;因此,不能把整次 Target Forward Pass 視為沒有產生有效輸出。效益下降的來源,是第一次拒絕位置之後的驗證計算無法轉化為本輪輸出,再疊加 Draft 生成、模型排程與同步開銷。
隱形風險分析:當 Acceptance Rate 極低時,系統會經歷頻繁的校正(Correction)。這種校正不僅帶來額外的 GPU 計算負載,還可能導致 GPU 閒置或負載波動。額外成本主要是拒絕位置之後未被利用的候選驗證計算、Draft 開銷及下一輪解碼。這種隱形的開銷在某些延遲敏感場景中,可能比單純使用 Target-Only 模式更為不利。
解決方案:選擇更準確的 Draft Model,或調整 k 值以適應不同的應用場景。如果接受率持續過低,可能需要考慮回退到 Target-Only 模式。
情境取捨:何時不建議導入
Speculative Decoding 的導入並非單純的效能優化,而是在「推理延遲」與「系統複雜度/維運成本」之間進行權衡。以下情境建議重新評估:
- 無法完成分布等價及驗證的場景:實際操作中需完成分布驗證、數值誤差與框架支援檢查。若無法滿足這些嚴格的驗證條件,可能需要更保守的方案。
- 缺乏合適 Draft Model 的場景:如果無法找到準確且輕量的 Draft Model,Speculative Decoding 可能無法帶來預期的加速效果。
- 硬體資源極度受限的場景:它仍然需要同時運行兩個模型(Draft 和 Target)。在顯存或算力極度受限時,額外模型常駐、KV Cache 與排程空間可能縮小可用邊界。採用判準不能只看平均速度;需以同一 workload 比較 Speculative 與 Target-Only 的 p95 延遲、ITL、吞吐量、顯存占用、平均接受長度及維運成本。只要必要資源超出部署邊界,或整體指標未達事先設定的門檻,就保留 Target-Only。
最終驗證與回退判準
整合完成後,需要安排獨立於功能冒煙檢查的最終驗證階段。先固定硬體、軟體版本、Prompt 集合、batch_size、max_new_tokens、取樣設定、暖機輪次與同步方式,再以同一 workload 分別執行 Target-Only 與 Speculative 兩種模式。
在 greedy 模式下,逐 token 比較兩種模式的輸出;在隨機取樣模式下,於固定的小詞彙與固定輸入上重複抽樣,依事先指定的統計量與容差比較經驗分布。效能與資源面則比較 p95 延遲、ITL、吞吐量、顯存占用和平均接受長度,並把額外維運成本納入 decision matrix。
通過判準:分布檢查需落在預先定義的容差內,效能與資源指標也需達到部署前設定的門檻。人工評估可以保留為品質檢查,但不能取代分布等價驗證。
停止與回退條件:若輸出分布不一致、指標未達門檻、顯存超出部署邊界,或結果無法穩定重現,停止擴大部署並關閉 Speculative Decoding,回退至已建立的 Target-Only 路徑。完成原因定位前,不把單次較快的結果視為驗證通過。
本文沒有提供上述 workload 的實測資料,因此目前只能確認驗證流程與回退邊界,不能宣稱特定部署已獲得加速或通過分布驗證。當固定 batch_size 與固定 k 的版本通過全部門檻後,下一個可逆的安全擴充點是另開實驗比較不同 batch,之後再單獨測試動態 k;任何一項未通過,都可回到前一個已驗證設定。