---
tags: [CANN]
doc_type: knowledge-note
返回目录: "[[计算机系/昇腾与CANN/大模型与算子专题学习导航|大模型与算子专题学习导航]]"
上一篇: "[[计算机系/昇腾与CANN/推理框架与KV缓存调度|推理框架与KV缓存调度]]"
下一篇: "[[计算机系/昇腾与CANN/低比特量化优化与AMCT实践|低比特量化优化与AMCT实践]]"
---

# MTP 投机解码与多流预取

投机解码通过减少昂贵目标模型的串行轮次提升生成速度；多流与预取则尝试覆盖计算或数据搬运的等待时间。二者优化的对象不同，可以组合，但必须以完整请求的时延与输出质量判断收益。

## 1. 为什么一次验证多个 Token

普通自回归 Decode 每轮生成一个 Token，然后才能开始下一轮。小批量时，每轮都可能重新读取大量权重，计算单元利用率不高。

投机解码让成本较低的草稿模型或预测模块先提出多个候选 Token，再由目标模型在一次带因果约束的前向中验证这些候选。目标模型仍需根据各候选前缀计算正确的条件分布，不能让候选看到未来信息。

![投机解码与验证流程](.assets/CANN推理专题/speculative-5.png)

一次迭代通常包括提出候选、目标验证、接受连续前缀、生成纠正或额外 Token、更新缓存。拒绝位置之后的候选不属于有效历史，其 KV 和位置状态必须回滚或丢弃。

### 贪心验证与随机采样不同

贪心生成可以比较候选 Token 是否与目标模型的 argmax 一致。随机采样要保持目标分布，则需要正确的接受与纠正算法。

对草稿分布 $q$ 提出的 Token $x$，经典接受概率为：

$$
a(x)=\min\left(1,\frac{p(x)}{q(x)}\right).
$$

拒绝时从归一化后的 $\max(p-q,0)$ 残差分布采样。具体算法还要处理终止与全接受后的额外采样。任意地比较概率阈值或只接受相同 Token，不能自动保证随机生成分布保持不变。

## 2. MTP 是预测结构，投机是执行策略

Multi-Token Prediction 在训练目标或模型结构中引入对多个后续 Token 的预测。它可以采用多个预测头，也可以采用逐级传递隐藏信息的预测模块。DeepSeek 风格的 MTP 与其他多头预测结构在信息流和参数共享方式上并不完全相同。

![多 Token 预测结构](.assets/CANN推理专题/speculative-8.png)

推理时，可以利用 MTP 模块产生草稿，再交给主模型验证。有些实现重复调用一个已训练的 MTP 模块以扩展草稿长度，但不能据此推断所有 MTP 训练结构中的各级模块都共享全部权重。

MTP 预测得越多，潜在接受长度越大，同时草稿开销、验证开销和错误累积也可能增加。因此草稿长度需要随模型、任务和批量调节。

## 3. 用每个有效 Token 的成本比较收益

定义接受率为已接受草稿 Token 数除以提出的草稿 Token 数。若每个验证轮次都额外产生一个纠正或奖励 Token，则平均推进长度可写为：

$$
\bar L=\frac{N_{accepted}+N_{rounds}}{N_{rounds}}.
$$

遇到 EOS、长度限制或不同验证协议时，需要按实际产出的 Token 重新统计。

$$
T_{token}\approx\frac{T_{draft}+T_{verify}+T_{manage}}{\bar L}.
$$

例如，一轮验证与草稿合计 62 ms，平均推进 1.7 个 Token，则平均约为 36.5 ms/Token。只有在同一负载下，普通 Decode 的对应时间确实更大时才构成收益；不能用接受率单独证明加速。

![MTP 推理与性能分析](.assets/CANN推理专题/speculative-12.png)

大批量下，普通 Decode 已经有较高利用率，投机额外计算可能降低吞吐。因此应同时检查低并发时延、高并发吞吐与显存增长。

## 4. 多流的本质是表达可并行的依赖图

同一流内的任务按顺序执行；跨流任务需要事件等机制建立依赖。以 MoE 为例，共同输入就绪后，共享专家与路由专家可以分别执行，最终合并输出前再等待两支完成。

![多流并行与依赖关系](.assets/CANN推理专题/speculative-19.png)

事件解决“消费者何时可以读取结果”；`tensor.record_stream` 等内存生命周期机制解决“分配器何时可以复用存储”。两者不是替代关系：生命周期管理不会自动建立正确的计算先后顺序。

跨流并发还取决于硬件资源。两个任务如果都已占满相同的计算单元或带宽，并行可能只会相互拖慢。部分实现通过限制核资源分配给另一任务留下空间，这属于特定运行时的调度策略，不能无条件照搬。

## 5. 预取：提前把即将读取的数据送入缓存

预取尝试在前序计算进行时，把后续权重从 HBM 搬入 L2。使用相关版本接口时，其调用形式可以是：

```python
torch_npu.npu_prefetch(weight, depend, size, offset)
```

`weight` 指定目标数据，`size` 和 `offset` 描述预取范围；`depend` 表达预取开始前需要满足的依赖。它不是要搬运的数据，也不是自动定义的“可重叠计算窗口”。预取发生在依赖生产者完成之后，需与之后的独立工作形成重叠。

![权重预取的时序与位置](.assets/CANN推理专题/speculative-23.png)

例如，可在满足依赖后预取后续 Gate/Up 或 Down 投影的权重，或为下一层 Q/K/V 投影做准备。具体位置需要由计算图的真实依赖、当前缓存压力和时间线决定。

预取大小应按照 TP/EP 分片后的本地物理权重计算。INT4 的打包格式、量化 Scale 和对齐空间都可能影响实际字节数。按权重的一定比例预取只能作为搜索起点，不能把 50% 当作所有模型的固定最优值。

GE 图模式下的调度管理与 `npugraph_ex` 中显式流和事件的使用方式不同，接口必须与当前执行路径匹配。预取过早可能被后续数据逐出缓存，过晚可能退化为阻塞搬运，过多则可能挤占更有用的缓存内容。

## 6. 以关键路径验证组合优化

比较目标算子、包含它的时间窗口和端到端请求三个层次。目标算子变快但窗口变慢，说明额外搬运或资源争用已抵消收益；窗口变快而请求不变，可能意味着它不在关键路径上。

同步基础见[流水线双向同步原理](流水线双向同步原理.md)，调度与缓存管理见[推理框架与 KV 缓存调度](推理框架与KV缓存调度.md)。
