爆内存带宽不是算力,是数据搬运:推理速度为什么总卡在这儿
内存带宽成了推理的软肋
在手机或 SBC 上跑 LLM,慢归慢,但慢的原因大多不是 CPU 不给力。 autoregressive 模型每次只产出一个 token,batch=1 时意味着要把整个模型权重从内存刷一遍,用 activation 向量点一下乘就丢掉。每个权重参与的算术强度太低,处理器干的事情就是等数据到了——roofline 角度看,这毫无疑问是 memory-bound 而不是 compute-bound。
拿 Jetson Orin Nano 8GB 举例:LPDDR5 总线带宽约 68 GB/s,一 个 4bit 量化的 7B 模型 ≈ 4GB。光读取这 4GB 就得 59 ms,相当于单次内存访问就把你卡在了 <20tok/s 的天花板上。升级算力单位没用,升级内存带宽才行。
speculative decoding 如何打破限制
speculative decoding 靠“批量验证”压榨内存带宽。思路很直接:
1. 用小 draft model 冒 N 个 token(比如 8 个),因为模型小所以快;
2. 用大 target model 做一次 forward pass,同时验证这 N 个位置;
3. 逐位比较,保留 draft 和 target 一致的前缀;
4. 遇到分歧,用 target 自己的采样结果补齐至少一个 token,继续循环。
关键点:target model 的权重只需要从内存读取一次,却验证了多个 token。draft 猜得准就能一次性拿到多个 token;猜得不准,退化到普通解码的速度也没什么损失。
验证是精确,而不是近似
很多人以为 draft 模式是“牺牲精度换速度”,其实不然。speculative decoding 的接受规则是严格设计的,保证最终输出的概率分布和纯 target model 解码一致。换句话说,文本内容是一样的,变的是吞吐。