2. 大模型推理基础:Transformer架构回顾,自注意力机制与FFN的计算模式,推理的瓶颈分析

各位同学,今天我们聊聊大模型推理的底子——Transformer。说实话,这玩意儿刚出来的时候,我第一反应是:这不就是Seq2Seq加了个注意力放大镜吗?后来在FPGA上跑了一轮才发现,事情远没那么简单。

Transformer的核心就两块:自注意力机制前馈神经网络。你想想看,大模型动辄几十亿参数,推理时每一步都在反复调用这两个模块。搞明白它们的计算模式,你才能知道FPGA到底该在哪儿使劲。

2.1 自注意力机制:到底在算什么?

自注意力的公式大家都见过:

Attention(Q, K, V) = softmax(Q × K^T / √d_k) × V

说白了,就是让每个词都去“看”一遍序列里的其他词,算出关联度,再加权融合。我在项目中遇到过一个问题:当序列长度从128涨到1024时,Q×K^T这一步的计算量直接翻了64倍。为什么?因为它是O(n²)的复杂度。

具体拆开看,自注意力分三步:

  1. 投影:把输入X分别乘上W_Q、W_K、W_V三个权重矩阵,得到Q、K、V。这一步是矩阵乘,计算密集。
  2. 注意力分数:Q×K^T,再除以√d_k。这一步也是矩阵乘,但结果矩阵是n×n的,访存压力巨大。
  3. 加权求和:softmax后的分数乘上V。又是矩阵乘。

嗯,这里要注意:第二步的中间结果矩阵是推理时的隐形杀手。我见过不少团队在FPGA上优化时,只盯着矩阵乘的吞吐量,却忽略了n×n矩阵的存储和搬运。序列长度一长,片上BRAM直接爆掉。

核心结论:自注意力是典型的访存密集型操作。计算本身并不复杂,但数据搬运量随序列长度平方增长。

2.2 FFN:计算量的大头

前馈神经网络(FFN)的结构更简单:

FFN(x) = max(0, x × W_1 + b_1) × W_2 + b_2

就是一个两层线性变换,中间夹一个ReLU激活。你可能会问:这么简单的结构,有什么好分析的?

我告诉你,FFN才是计算量的真正大头。以GPT-3 175B为例,自注意力只占不到10%的FLOPs,剩下90%全在FFN里。为什么?因为FFN的隐藏层维度通常是输入维度的4倍。比如d_model=4096,那FFN的中间层就是16384。每次推理,都要算一个4096×16384的矩阵乘,再算一个16384×4096的矩阵乘。

我在调优时发现一个有意思的现象:FFN的权重矩阵特别大,但每个token的计算模式完全一样。这意味着什么?意味着我们可以把权重提前加载好,然后批量处理多个token。这就是FPGA做FFN加速的切入点。

个人经验:FFN的权重矩阵通常占模型总参数量的2/3以上。在FPGA上做权重压缩或量化,收益最明显的就是这一块。

2.3 推理瓶颈:访存 vs 计算

好了,我们把两个模块的计算模式理清了。现在来回答一个关键问题:大模型推理到底卡在哪儿?

我习惯把操作分成两类:

类型 特点 典型操作 瓶颈
计算密集型 计算时间远大于访存时间 大矩阵乘(M、N、K都很大) MAC单元利用率
访存密集型 访存时间远大于计算时间 注意力分数矩阵、小批量矩阵乘 带宽、缓存命中率

你想想看,自注意力里的Q×K^T,矩阵维度是n×d_k和d_k×n。当n=1024、d_k=128时,计算量才2×1024×1024×128≈268M FLOPs。但中间结果矩阵是1024×1024=1M个元素,每个元素是FP16就是2MB。这2MB数据要写回去,再读出来做softmax,再写回去,再读出来做加权求和。访存次数远多于计算次数。

反过来看FFN:W_1是4096×16384的矩阵,一次矩阵乘就是4096×16384×4096≈275G FLOPs。计算量是自注意力的1000倍。但权重是提前加载好的,只要计算单元够快,访存不是问题。

避坑指南:我曾经在项目里犯过一个错误——把FPGA的DSP资源全堆给自注意力,结果发现性能提升微乎其微。后来分析才发现,自注意力那块儿根本不是在算,而是在等数据。DSP闲着也是闲着,不如去干FFN的活儿。

2.4 一张图看懂计算模式

下面这张SVG图,我画了Transformer推理时两个核心模块的计算流。红色箭头表示访存密集路径,蓝色箭头表示计算密集路径。你看一眼就明白瓶颈在哪儿了。

Transformer推理计算模式分析 输入序列 X 自注意力机制 ● Q×K^T (O(n²)) ● 中间矩阵 n×n ● softmax + 加权求和 访存密集型 带宽瓶颈,BRAM压力大 前馈神经网络 ● x×W₁ (d×4d) ● ReLU激活 ● ×W₂ (4d×d) 计算密集型 DSP利用率是关键 输出序列 访存密集路径 计算密集路径

2.5 对FPGA设计的启示

搞清楚了瓶颈,FPGA的优化方向就清晰了:

  • 自注意力:重点优化数据流和缓存策略。我建议用分块计算的方法,把n×n矩阵切成小块,让每个块都能塞进BRAM。别想着一次性算完,那是在跟物理定律作对。
  • FFN:重点优化计算单元。把DSP阵列铺满,用脉动阵列做矩阵乘。权重可以提前量化到INT8,FPGA上跑INT8比FP16快一倍,精度损失可以接受。
  • 整体策略:自注意力用访存优化,FFN用计算优化。两条腿走路,缺一不可。

一个小技巧:我在做FPGA加速时,习惯先跑一遍profiling,看看模型在GPU上的计算/访存比。如果比值小于1,说明是访存瓶颈,重点优化数据搬运;如果比值大于10,说明是计算瓶颈,堆DSP就对了。Transformer里,自注意力比值通常在0.5~2之间,FFN在20~50之间。你看,差别就这么大。

好了,这一章我们回顾了Transformer的核心计算模式,也分析了推理瓶颈。说白了,自注意力是“等数据”,FFN是“算数据”。FPGA加速的关键,就是针对这两种模式分别设计架构。下一章我们会深入具体的数据流优化方案,到时候拿实际案例来拆解。


公众号:蓝海资料掘金营,微信deep3321