3、深度学习推理模型:Transformer架构回顾、推理与训练的区别、推理的瓶颈分析

3.1 Transformer架构回顾——我们到底在推什么?

说实话,Transformer 这个架构现在都快成「深度学习界的钢筋混凝土」了。你随便拉一个 NLP 模型,背后大概率都是它。但咱们做推理优化,不能光知道它长什么样,得清楚它运行时到底在干什么。

我习惯把 Transformer 拆成三个核心阶段来看:

  1. Embedding 阶段:把 token 变成向量。说白了就是查表,把「你好」映射成一堆浮点数。
  2. Self-Attention 计算:这是最重头的。Q、K、V 三个矩阵乘,然后 softmax,再加权求和。我当年第一次看这公式时也觉得头大,后来发现其实就是「找关联、算权重、做融合」三步。
  3. FFN(前馈网络):两层线性变换加个激活函数。嗯,这个相对简单,但参数量可不小。

你想想看,一个 7B 参数的模型,光是把参数从显存里搬一遍,就是几十 GB 的数据量。这还没算中间激活值呢。

核心要点:推理时,Transformer 的每一层都要做「矩阵乘法 + 非线性变换 + 残差连接」。其中 Self-Attention 的计算量随序列长度呈平方增长,这是后续所有优化手段的出发点。

3.2 推理 vs 训练——同一个模型,两套逻辑

很多刚入行的同学会问我:「老师,推理不就是训练的前向传播吗?」
嗯,从数学上看确实一样。但从工程角度看,完全是两码事。

维度 训练 推理
目标 更新参数,降低 loss 快速生成结果,延迟要低
显存需求 需要存梯度、优化器状态、中间激活 只需要存参数 + KV Cache
batch size 通常较大(64~1024) 动态变化,甚至 batch=1
精度要求 FP32 / BF16 为主 可以量化到 INT8 / FP8
计算模式 计算密集型,追求吞吐 访存密集型,追求低延迟

我举个例子你就明白了。训练时,你恨不得把 GPU 的每个 CUDA Core 都跑满,算得越快越好。但推理时呢?尤其是做自回归生成,每次只生成一个 token,大部分时间 GPU 都在「等数据从显存搬过来」。说白了,推理的瓶颈往往不在算力,而在带宽。

避坑指南:我曾经犯过一个错误——把训练时的 batch size 策略直接搬到推理服务上。结果显存爆了,延迟也高得离谱。后来才意识到,推理的 batch 调度要结合「请求到达率」和「显存池大小」来动态调整。

3.3 推理的瓶颈分析——到底卡在哪?

好,咱们来点硬核的。推理的瓶颈,我总结为三大类:

3.3.1 访存瓶颈(Memory Bound)

这是最要命的。你看 Transformer 的每一层,都要做:

// 伪代码示意
for each layer:
    load params from HBM to SRAM   // 访存
    compute attention               // 计算
    store activations to HBM        // 访存
    load params again               // 访存
    compute FFN                     // 计算
    store results                   // 访存

你会发现,计算只占了一小部分时间,大部分时间都在搬数据。我做过 profiling,在 A100 上跑 LLaMA-7B,访存操作占了总时间的 70% 以上。

3.3.2 计算瓶颈(Compute Bound)

当 batch size 足够大时,计算才会成为瓶颈。比如你一次推理 64 个请求,矩阵乘法的规模上来了,GPU 的 Tensor Core 才能吃饱。但问题是,很多场景下 batch size 就是上不去——比如对话系统,用户一个一个发消息,你没法攒够 64 个再一起算。

3.3.3 KV Cache 的显存压力

这个我得多说两句。自回归生成时,每生成一个 token,都要把之前所有 token 的 Key 和 Value 缓存下来。序列越长,KV Cache 越大。我算过一笔账:

  • 一个 7B 模型,batch=1,序列长度 2048,KV Cache 大约占 1.5GB
  • 如果 batch=64,序列长度 4096,KV Cache 能吃掉 96GB 显存

你想想看,一张 A100 才 80GB 显存。光 KV Cache 就占满了,模型参数放哪?

注意:KV Cache 是推理优化的「甜蜜点」。很多显存池技术,本质上就是在管理这块缓存——什么时候分配、什么时候复用、什么时候淘汰。我见过有人因为没处理好 KV Cache 的显存碎片问题,导致 40% 的显存被浪费掉。

3.4 一张图看懂推理的瓶颈

下面这张 SVG 图,是我自己画的推理流程与瓶颈分布。你可以看到,数据从显存搬到计算单元的过程,是整个推理的「咽喉」。

Transformer 推理流程与瓶颈分布 输入 Token Embedding(查表) Transformer Layer × N Self-Attention FFN 瓶颈:访存带宽 + KV Cache 输出 Token 三大瓶颈 ① 访存带宽 参数搬运占 70% 时间 ② 计算利用率 小 batch 时 Tensor Core 吃不饱 ③ KV Cache 显存 长序列时显存爆炸 碎片化严重 优化方向 • 显存池复用 • 动态 batch • 量化压缩 • PagedAttention

3.5 我的实战经验总结

做了这么多年推理优化,我最大的感受是:别想着用一个技巧解决所有问题。不同的场景,瓶颈不一样,解法也不一样。

  • 对话场景:延迟敏感,batch size 小。重点优化 KV Cache 和访存。
  • 离线批量推理:吞吐优先,batch size 可以很大。重点优化计算效率和显存复用。
  • 边缘设备:显存和算力都受限。量化 + 模型剪枝是王道。

我曾经在一个项目中,把推理延迟从 200ms 优化到 30ms。你以为我用了什么黑科技?其实就是把 KV Cache 的显存分配策略改了一下,减少了碎片和重复分配的开销。嗯,有时候优化就是这么朴实无华。

一个小技巧:做推理 profiling 时,别只看 GPU 利用率。要看「访存带宽利用率」和「计算利用率」的比值。如果访存利用率高但计算利用率低,说明你的模型是访存瓶颈——这时候加 batch size 或者用显存池,效果立竿见影。

好了,这一章的内容就到这里。Transformer 的推理瓶颈,说白了就是「数据搬不动、显存放不下、计算吃不饱」三个问题。下一章我们会深入讲显存池怎么解决这些问题。


想要更多资料,联系可可