答案在于计算模式和硬件效率的根本不同。Prefill是计算密集型(Compute-Bound),而Decoding是访存密集型(Memory-Bound)。
我们通过一个具体的例子来解释。
实例解析
场景设定:一个具体的例子
假设我们有以下配置:
- 模型: 一个类似GPT-3的模型,拥有 1750亿 (175B) 参数。每个参数用半精度(FP16)存储,占2个字节。
- 模型总大小 = 1750亿 × 2 Bytes = 350 GB。
- 硬件: 一台配备8张NVIDIA H100 80GB GPU的服务器。
- 总HBM容量 = 8 × 80 GB = 640 GB (足以放下整个模型)。
- 单张H100的HBM带宽 ≈ 3.35 TB/s。
- 单张H100的FP16计算能力 ≈ 1979 TFLOPS (TeraFLOPS, 万亿次浮点运算/秒)。
- 任务: 用户输入一段提示(Prompt),长度为 512个token,我们希望模型续写 1个token。
我们将这个任务分解为两个阶段:
- Prefill 阶段: 并行处理输入的512个token。
- Decoding 阶段: 生成第513个token。
第1阶段: Prefill (处理输入的512个token)
在这个阶段,模型接收全部的512个token,并一次性地、并行地计算出这512个位置对应的隐藏状态(Hidden States),最终目的是为了预测第513个token。
1. I/O (访存):
- 需要加载什么? 为了完成这次前向传播,我们需要从HBM(显存)中完整地读取一遍模型权重。
- I/O大小: 350 GB。
- I/O时间: 假设带宽能被充分利用,时间 = 350 GB / 3.35 TB/s ≈ 104毫秒。