惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Tenable Blog
月光博客
月光博客
雷峰网
雷峰网
WordPress大学
WordPress大学
博客园 - 司徒正美
Last Week in AI
Last Week in AI
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
V
Visual Studio Blog
H
Help Net Security
Engineering at Meta
Engineering at Meta
Google DeepMind News
Google DeepMind News
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
S
Security @ Cisco Blogs
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
爱范儿
爱范儿
W
WeLiveSecurity
J
Java Code Geeks
Forbes - Security
Forbes - Security
H
Hacker News: Front Page
T
Threatpost
The Cloudflare Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
N
Netflix TechBlog - Medium
Latest news
Latest news
V2EX - 技术
V2EX - 技术
小众软件
小众软件
T
The Blog of Author Tim Ferriss
A
Arctic Wolf
B
Blog RSS Feed
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
I
InfoQ
C
Check Point Blog
N
News | PayPal Newsroom
Cyberwarzone
Cyberwarzone
V
V2EX
TaoSecurity Blog
TaoSecurity Blog
P
Privacy & Cybersecurity Law Blog
Microsoft Security Blog
Microsoft Security Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
D
DataBreaches.Net
F
Fortinet All Blogs
阮一峰的网络日志
阮一峰的网络日志
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
IT之家
IT之家
K
Kaspersky official blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Google DeepMind News
Google DeepMind News
C
CXSECURITY Database RSS Feed - CXSecurity.com
www.infosecurity-magazine.com
www.infosecurity-magazine.com

土法炼钢兴趣小组的算法知识备份

国密算法与国密 TLS 系列索引 【系统架构设计】架构质量属性:不只是"高可用高性能" 【系统架构设计百科】告警策略:如何避免"狼来了" 【系统架构设计】CQRS:读写分离的架构哲学 【系统架构设计】空间架构:极端扩展场景的解法 【系统架构设计】微服务架构深度审视:优势、代价与适用边界 【系统架构设计】扩展性原理:水平、垂直与对角扩展 【系统架构设计】无状态设计:扩展的第一步也是最难的一步 【系统架构设计】缓存架构:从本地到分布式的多级缓存体系 【系统架构设计】管道与过滤器:Unix 哲学的架构表达 【系统架构设计】复杂性管理:架构的核心战场 【系统架构设计】消息队列架构:异步解耦的设计与陷阱 【系统架构设计】CDN 架构:全球加速的设计原理 【系统架构设计】连接池设计:被忽视的性能杀手 【系统架构设计】弹性设计模式:熔断器、舱壁与超时 【系统架构设计】高可用设计模式:冗余、故障转移与仲裁 【系统架构设计】容量规划:从拍脑袋到数据驱动 【系统架构设计】数据库扩展:分库分表的工程实践与替代方案 【系统架构设计】SLO 工程:可靠性的量化管理 【系统架构设计】性能建模:用数学思维分析系统瓶颈 【系统架构设计】混沌工程:主动验证系统的韧性 【系统架构设计】零拷贝与内存映射:数据搬运的极致优化 【系统架构设计】线程模型:从 thread-per-request 到协程 【系统架构设计】容灾架构:多活与灾备设计 【系统架构设计】数据库性能模式:索引、查询与连接管理 【系统架构设计】数据建模:从关系范式到文档模型的真实权衡 【系统架构设计】吞吐量优化:批处理、流水线与并发模型 【系统架构设计】流处理架构:从批处理到实时的范式迁移 【系统架构设计】搜索引擎架构:倒排索引之上的系统设计 【系统架构设计】时序数据架构:监控与 IoT 的存储设计 【系统架构设计】数据迁移与版本化:在线不停机的数据演进 【系统架构设计】数据湖与数据仓库:分析架构的演进路线 【系统架构设计】API 网关设计:入口层的职责边界 【系统架构设计】应用层数据一致性模式:在正确性与性能之间走钢丝 【系统架构设计】多模数据库选型:Polyglot Persistence 的工程实践 【系统架构设计】服务发现与注册:动态拓扑的基础设施 【系统架构设计】配置管理架构:从配置文件到配置中心 【系统架构设计】全链路压测:大规模系统的性能验证 【系统架构设计】幂等性设计:分布式环境下的安全重试 【系统架构设计】契约测试与 Schema 演进:服务间的信任协议 【系统架构设计】长连接与推送架构:WebSocket、SSE 与 MQTT 【系统架构设计】延迟分析:从 P50 到 P999 的全链路追踪 【系统架构设计百科】DDD 战术模式:聚合、实体与值对象 【系统架构设计百科】防腐层与开放主机服务:系统集成的 DDD 方案 【系统架构设计百科】领域事件与事件风暴:从业务到架构的桥梁 【系统架构设计百科】CQRS + Event Sourcing 完整实战:从领域建模到部署 【系统架构设计百科】DDD 与微服务:用领域模型划分服务边界 【系统架构设计】DDD 战略设计:限界上下文与上下文映射 【系统架构设计百科】认证架构:从 Session 到 JWT 到 OIDC 【系统架构设计】API 设计哲学:REST vs GraphQL vs gRPC 的真实权衡 排序算法专题:从 TimSort 到并行排序 【密码学百科】国密算法体系:SM2/SM3/SM4/SM9 全景解读 【密码学百科】承诺方案:Pedersen 承诺、向量承诺与多项式承诺 【密码学百科】不经意传输与隐私信息检索:OT、OT 扩展与 PIR 【密码学百科】门限密码学:门限签名、门限解密与分布式密钥生成 完美哈希:从理论到 gperf 实践 【密码学百科】安全多方计算:从 Yao 的混淆电路到实用 MPC 【密码学百科】同态加密:从 Paillier 到全同态加密(FHE) 【密码学百科】零知识证明系统:zk-SNARKs、zk-STARKs 与 Bulletproofs 【密码学百科】概率论与密码分析:生日攻击、差分分析与线性分析 【密码学百科】计算复杂性与归约:密码安全性证明的基石 【密码学百科】秘密共享:Shamir 方案、VSS 与安全多方计算入口 【密码学百科】椭圆曲线代数:Weierstrass 方程、点群运算与曲线选择 【密码学百科】离散对数与配对密码学:从 DLP 到 BLS 签名 【密码学百科】格密码数学基础:SVP、LWE 与格基约化 【密码学百科】抽象代数:群、环、域的密码学视角 【密码学百科】有限域算术:GF(2^n) 运算与在 AES/ECC 中的应用 【密码学百科】数论进阶:二次剩余、椭圆曲线上的 Weil 配对 【密码学百科】密码学简史:从凯撒密码到量子时代 【密码学百科】威胁模型与安全目标:CIA 三要素之外 【密码学百科】Kerckhoffs 原则与现代密码设计哲学 【密码学百科】随机性:密码学的基石 【密码学百科】信息论入门:熵、完美保密与 Shannon 定理 【密码学百科】分组密码原理:Feistel 网络与 SPN 结构 【密码学百科】AES 逐步拆解:SubBytes 到 MixColumns 的数学 【密码学百科】分组密码工作模式全览:ECB/CBC/CTR/OFB/CFB 【密码学百科】流密码:RC4 的兴衰与 ChaCha20 的崛起 【密码学百科】密码学哈希函数:MD5→SHA-2→SHA-3 的进化之路 【密码学百科】MAC 与 HMAC:消息认证的正确姿势 【密码学百科】认证加密(AEAD):GCM、ChaCha20-Poly1305 与 OCB 【密码学百科】密钥派生函数:HKDF、PBKDF2、Argon2 与密码存储 【密码学百科】公钥密码的数论基础:模运算、群、原根 【密码学百科】RSA 从原理到攻击:教科书 RSA 为什么不安全 【密码学百科】Diffie-Hellman 密钥交换与离散对数问题 【密码学百科】椭圆曲线密码学(ECC):从几何直觉到点群运算 【密码学百科】数字签名:ECDSA、EdDSA 与 Schnorr 签名 【密码学百科】现代密钥交换:X25519、ECDHE 与前向保密 【密码学百科】混合加密与 KEM/DEM 范式:ECIES 与 HPKE 【密码学百科】填充方案:PKCS#1 v1.5、OAEP 与 PSS 【密码学百科】TLS 协议全解析:从握手到 0-RTT 【密码学百科】PKI 与数字证书:信任链的构建与崩塌 【密码学百科】密码认证协议:从 SRP 到 OPAQUE 【密码学百科】零知识证明入门:如何证明你知道而不泄露 【密码学百科】安全信道构造:Noise 协议框架与 Signal 协议 【密码学百科】密钥管理工程:HSM、KMS 与密钥生命周期 【密码学百科】侧信道攻击:从时序攻击到功耗分析 【密码学百科】密码学实现陷阱:三层漏洞分类、审计工具链与系统性预防 密码敏捷性:如何设计可升级的密码系统 【密码学百科】OpenSSL/BoringSSL 架构剖析:ENGINE、Provider 与 FIPS 模块 排序基准测试:用数据说话
【Transformer 与注意力机制】18|注意力的复杂度问题
2026-04-15 · via 土法炼钢兴趣小组的算法知识备份

〇、为什么单独花一篇讲复杂度

如果只让我挑一个 Transformer 时代最重要的工程问题,我会毫不犹豫地选「O(n²) 的注意力复杂度」。它不是某个论文的边角细节,而是过去七年(2017–2024)里几乎所有「Transformer 改进型工作」共同的攻击目标——FlashAttention、Sparse Transformer、Longformer、Performer、Linformer、Mamba、RWKV、RetNet、Hyena,名字层出不穷,但全都在回答同一个问题:能不能让 attention 不再是 n²?

这个问题之所以难,不是因为数学上找不到 O(n) 算法(早就有了),而是因为:在大规模语言模型这个具体场景下,所有「降复杂度」的方案在效果上都打不过 vanilla full attention。这就出现了一个奇怪的局面:理论上明显次优的设计,工程上压制了所有理论上更优的设计。直到今天,主流大模型(GPT-4、Claude、Gemini、LLaMA、Qwen)使用的仍是 O(n²) 的 full attention,只是用 FlashAttention 把内存压到了 O(n)。

本篇就来彻底说清楚:复杂度到底是怎么来的,O(n²) 的具体瓶颈在哪里,5 类降复杂度方案各自的代价是什么,以及为什么 FlashAttention 不是 O(n)(这是最常见的误解之一)。读完后你应该能在面试或讨论中清晰回答:「LLaMA 跑 128k 上下文的瓶颈到底在哪?」「为什么 Mamba 这么火但还没替代 Transformer?」


一、attention 的复杂度从哪里来

回到第 13 篇推导的 scaled dot-product attention:

Q, K, V ∈ R^{n×d}
S = Q K^T / √d         # n×n
A = softmax(S)         # n×n
O = A V                # n×d

逐步算计算量:

  • Q K^T:两个 n×d 矩阵相乘,得到 n×n 矩阵。FLOPs ≈ 2 · n · n · d = 2n²d
  • softmax:对 n×n 矩阵每行做 softmax。约 5n² FLOPs(exp、sum、div),相对前者可忽略。
  • A V:n×n 与 n×d 相乘。FLOPs ≈ 2 · n · n · d = 2n²d

总计:4n²d FLOPs。计算复杂度 O(n²·d)

显存方面:

  • SA:n×n 矩阵,占 个元素。fp16 每个 2 字节,所以一个 head 是 2n² 字节。
  • 多 head:实际每层有 h 个 head 但每个 head 维度是 d/h,所以总量仍是 O(n²) 量级。

显存复杂度 O(n²)——这才是真正卡死长上下文的瓶颈,比计算更要命。

我们做个具体数字:n=128k 时,单层单 head 的 attention 矩阵 = 128k×128k×2 = 32 GB。一个 80GB 的 H100 单卡都装不下一层。这就是为什么没有 FlashAttention 的话,128k 上下文在硬件上完全不可能。


二、attention vs FFN:谁才是计算大头

很多人下意识以为 attention 是模型计算量最大的部分。实际上这取决于 n 和 d 的相对大小。

FFN 的计算量:每层 FFN 做两次矩阵乘 n·d → n·4d → n·d,FLOPs ≈ 16n·d²。复杂度 O(n·d²)。

Attention 的计算量:FLOPs ≈ 4n²·d。复杂度 O(n²·d)。

两者比值:4n²d / 16nd² = n/(4d)

  • n < 4d 时,FFN 主导。
  • n > 4d 时,attention 主导。

LLaMA-7B 的 d=4096,所以 n=16k 才是 attention 与 FFN 各占一半的临界点。在 n=2k(典型短对话)时,attention 只占总 FLOPs 的约 1/8;FFN 才是大头。这是为什么短上下文场景里 attention 复杂度其实不那么紧迫,FFN 的优化(量化、MoE)反而更值钱

但训练长上下文(n=32k 或 128k)的模型时,attention 立刻反超:n=128k 时 attention 是 FFN 的 8 倍。这就是为什么长上下文的训练成本爆炸式增长。


三、显存:比计算更早爆掉

n²·d 的计算可以靠堆 GPU 时间解决,但 O(n²) 显存是硬墙。

让我们算几个典型配置:

序列长度 n n² 矩阵 fp16 显存 单 H100(80 GB)能放几层?
2k 8 MB 一万层都行
8k 128 MB 几百层
32k 2 GB 30 层左右(接近极限)
128k 32 GB 2 层(不能训练)
1M 2 TB 不可能

注意以上是单 head 的数字。实际多 head 会再 ×8 或 ×32(取决于 GQA 配置)。再加上 batch 维度,128k 训练时即便 batch=1 都装不下。

这是为什么 FlashAttention 和 KV cache 是绝对必需品而不是优化项。没有它们,Transformer 在 n>16k 上就不能存在。


四、O(n²) 之外还要算 KV cache

推理阶段,KV cache 增加了一项隐藏的复杂度:每生成一个新 token,KV cache 都要存下所有历史的 K、V。

KV cache 大小 = 2 · n · d · L(2 是 K 和 V,L 是层数)。

LLaMA-2-7B 配置:d=4096,L=32。每个 token 的 KV cache = 2 · 4096 · 32 · 2 字节 = 512 KB

n=4k 时 KV cache = 2 GB;n=128k 时 KV cache = 64 GB。这甚至超过了模型权重本身的大小

KV cache 还和 batch size 是乘性的:服务 32 个并发用户、每个 8k 上下文,仅 KV cache 就是 32 × 8k × 512KB = 128 GB,必须分多卡。

正因如此,工业界又发明了 GQA(Grouped Query Attention,第 16 篇讨论过)、MLA(Multi-head Latent Attention,DeepSeek-V2 的核心创新)、Paged Attention(vLLM 的核心创新)等专门针对 KV cache 的优化。


五、五类降复杂度方案

工业界和学术界对 O(n²) 的不满几乎是同步爆发的。从 2019 年开始,出现了一系列试图把 attention 复杂度降到 O(n·log n)、O(n·√n) 甚至 O(n) 的工作。我把它们归成五大类:

1)滑动窗口类(local attention)

让每个位置只看前后各 w 个位置。复杂度 O(n·w),w 是固定常数所以本质是 O(n)。

代表工作:Longformer(2020,Allen AI)、Mistral-7B 的 SWA(sliding window attention)。

优点:实现极简,把 mask 改成带状即可。GPU 友好(因为不需要复杂索引)。

缺点:彻底丢失全局信息。模型无法建立长距离依赖。

补救方案:加 global token(Longformer)、加 dilation(Sparse Transformer)。

2)稀疏注意力(sparse attention)

按某种规则稀疏化 attention 矩阵。复杂度通常 O(n·√n)。

代表工作:Sparse Transformer(OpenAI 2019,GPT-3 之前)、BigBird(Google 2020)。

优点:理论好,可证明能近似 full attention。

缺点:实现复杂,GPU 上不易高效,效果与 full attention 仍有差距。BigBird 论文发表后实际工业部署很少。

3)低秩 / kernel 方法(linear attention)

把 softmax 换成可分解的核函数 φ(Q)φ(K)^T,从而 (φ(Q)φ(K)^T)V = φ(Q)(φ(K)^T V),括号里先算就是 O(n)。

代表工作:Linformer(2020)、Performer(2020)、Linear Attention(2020)。

优点:真正的 O(n),对长序列友好。

缺点:在大规模语言模型上效果显著弱于 full attention。多数工作只验证了几亿参数规模,没有在 LLaMA 级别复现成功。

4)SSM / RNN 复兴(state space models)

不走 attention 路线,用状态空间模型或 gated RNN 实现 O(n) 序列建模。

代表工作:S4(2021)、Mamba(2023)、RWKV(2023)、RetNet(2023)。

优点:真正的 O(n) 推理,并行训练(通过 selective scan 等技巧),实测效果在中小规模上接近 Transformer。

缺点:长程检索任务(needle in haystack)仍弱于 attention;目前最大模型仍未到 70B+;混合架构(Jamba=Mamba+attention)成为务实方案。

5)FlashAttention(IO-aware exact attention)

这一类不降低渐进复杂度,而是利用 GPU 内存层次(HBM → SRAM)做 tiling 和 recomputation,让显存从 O(n²) 降到 O(n),计算时间因为减少 HBM 访问而加速 2–4×。

代表工作:FlashAttention(Dao 2022)、FlashAttention-2(2023)、FlashAttention-3(2024)。

优点:精确而非近似,效果与 full attention 完全一致;显存 O(n);训练加速显著;成为事实标准。

缺点:仍是 O(n²) 计算,长序列计算量本身没降。


六、FlashAttention 不是 O(n):最常见的误解

我见过太多次这种错误描述:「FlashAttention 把注意力复杂度降到 O(n)」。这是错的

正确说法是:FlashAttention 把 attention 的显存复杂度从 O(n²) 降到 O(n),但计算复杂度仍然是 O(n²)。

它的核心想法是:

  1. 把 Q、K、V 分块(tile),每次只把一小块加载到 GPU 的 SRAM(高速缓存)。
  2. 在 SRAM 内部计算块 × 块的部分 attention 结果,用 online softmax trick 增量更新。
  3. 最终输出 O 是逐块累加得到的,永远不需要在 HBM 里物化完整的 n×n 矩阵

所以:

  • 计算次数仍然是 O(n²·d),因为每一对 Q-K token 还是要做内积。
  • 显存占用是 O(n),因为只保留分块结果而不是完整 attention 矩阵。
  • 实测时间快是因为减少了 HBM ↔︎ SRAM 的数据搬运(这是 GPU 的真实瓶颈,不是 FLOPs)。

这种「不改变渐进复杂度但巨幅改善实测性能」的工作有个专有名词:IO-aware。其本质是认识到现代 GPU 的瓶颈早已不是计算而是带宽。FlashAttention 的成功告诉我们:在系统层面优化往往比改算法更值钱。


七、为什么大家最后都回到 full attention

2020–2022 年是「线性注意力」的黄金期,论文层出不穷,但到了 2023 年大家发现:主流大模型基本都还在用 full attention

原因有几个:

  1. 质量差距难以弥合。线性 attention 在小规模任务上能逼近 full attention,但放大到 7B+ 时差距被放大。Anthropic、OpenAI、Google 都内部尝试过,都没把线性方案 ship 出去。

  2. FlashAttention 让 full attention 不再是瓶颈。一旦显存问题解决了,full attention 的「贵」就只剩计算贵——而计算贵可以用 GPU 数量解决。

  3. 长上下文的真正瓶颈是 KV cache 而不是 attention 计算。这让线性方案的「O(n) 计算」优势失去意义,因为推理时大头根本不在那。

  4. 稀疏方案 GPU 不友好。理论上的 O(n·√n) 在 GPU 上往往跑不出来,因为稀疏 indexing 的 memory access pattern 不规则。

  5. 混合架构兜底。如果线性方案确实有用,可以做成混合架构(如 Jamba),这种灵活性比纯线性更受工业界欢迎。

所以现在的实际格局是:

  • 全 attention + FlashAttention + GQA/MLA + KV cache 优化 = 主流(GPT-4、Claude、LLaMA、Qwen、DeepSeek)
  • 混合 SSM + attention = 实验性(Jamba、Granite-4)
  • 纯 SSM / 纯线性 = 学术为主(Mamba 仍在快速进化)

八、长上下文的真正挑战

「O(n²) 复杂度」常被作为长上下文困难的简单解释。但在 2024 年的现实里,让模型支持 128k 上下文的难点不是复杂度,而是质量

具体说,当 n 从 4k 扩到 128k 时,遇到的问题包括:

  1. 位置编码外推(第 19 篇主题相关,第 27、28 篇会展开 RoPE 与外推):训练只到 4k,推理到 128k,位置嵌入是怎么处理的?需要 NTK-aware、YaRN 等技巧。

  2. attention 注意力发散:序列变长后 softmax 越来越平,attention 几乎对所有位置都给一点点权重,「focus」消失。这与 attention sink(第 17 篇)现象相关。

  3. 训练数据不够:互联网上 128k+ 的连续高质量文本极少。需要拼接、人工合成。

  4. 显存爆炸:即便有 FlashAttention,128k 训练时激活值(activation)的显存仍极大,需要 gradient checkpointing、sequence parallelism 等。

  5. 质量评估难:传统困惑度在长上下文上不区分。需要 needle-in-haystack、RULER、∞-Bench 等专用评测。

复杂度只是表面问题。真正的长上下文工程涉及训练、数据、评测、推理优化的全链条。


九、计算 vs 带宽:现代 GPU 的真实账本

讲到这里必须说清楚一个事实:现代 GPU 的瓶颈早已不是 FLOPs 而是 memory bandwidth

H100 的 fp16 算力约 989 TFLOPs,HBM 带宽约 3.35 TB/s。FLOPs/byte 的「算术强度」需要达到 ~295 才能让算力跑满。

attention 的算术强度本身不高:每读一字节 K/V,做大约 d 次 FMA。d=4096 时算术强度 = 4096 ≈ 跑满。但是!如果你按朴素方式实现 attention,每次都要把 n×n 的 attention matrix 写回 HBM 再读出来 softmax 再读出来乘 V,这些「memory round trip」会让实际算术强度暴跌到 ~10。

这是 FlashAttention 巨幅加速的真正原因——它并没有让 GPU 算得更快,而是让 GPU 不用频繁来回搬数据。

理解这一点,对所有「为什么我的训练没有跑满 GPU」的疑问都有帮助。答案 99% 是带宽瓶颈,1% 是算力瓶颈。


十、近似 attention 的代价:质量 vs 速度

研究界一个反复被验证的经验法则:任何打着「线性 attention」旗号的方案,质量上都会损失几个点。这种损失在小规模任务上不明显,但在 LLM 上会被放大。

具体表现:

  • 短文本任务:线性 attention 与 full attention 差距 < 1%,几乎不可见。
  • 中等任务(如 GLUE):线性差 1–3%。
  • 长文本检索(如 LRA、ZeroSCROLLS):线性 attention 显著弱于 full。
  • 长文本生成(开放对话):线性 attention 在长上下文中容易丢失早期信息。

为什么?直觉理解:线性 attention 把 n×n 矩阵分解成两个 n×k 的乘积,丢失了 rank=n 的表达力。这种压缩在「精确建模任意 token 对」的场景下损失大。Mamba 的 selective scan 等机制是在试图弥补这种损失,但完全弥补尚无定论。

所以「O(n)」从来不是免费的午餐。


十一、训练 vs 推理:复杂度账要分别算

attention 的复杂度在训练和推理阶段是不同的。

训练(一次前向 + 反向):

  • 计算:O(n²·d)
  • 显存(不带 FlashAttn):O(n² + n·d)
  • 显存(带 FlashAttn):O(n·d)

推理(单 token)

  • 计算:O(n·d)(生成第 t 个 token 时只做 t 个 token 与新 token 的注意力)
  • 显存:O(n·d)(KV cache)

推理(生成 m 个 token)

  • 总计算:O((n+m)²·d / 2)(累加每个 step 的 O(n+m)·d)
  • 总显存:O((n+m)·d)

注意推理的总计算仍是 n²-级别,因为虽然每步是 O(n),但要做 n 步。这意味着 chatbot 生成长回复时也是 O(n²)


十二、一个具体的成本估算:训 LLaMA-7B 长上下文

让我们做一个有趣的估算:把 LLaMA-7B 从 4k 上下文扩到 32k,计算成本是多少?

LLaMA-7B 训练数据约 2T tokens。如果都按 4k 上下文训练:

  • 每条样本 4k tokens,attention FLOPs 约 4·(4k)²·4096 ≈ 0.27 PFLOPs。
  • 每条样本 FFN FLOPs 约 16·4k·4096² ≈ 1.1 PFLOPs。
  • 比例 ≈ 1:4。

现在改成 32k:

  • attention FLOPs 约 4·(32k)²·4096 ≈ 17 PFLOPs(涨 64 倍)。
  • FFN FLOPs 约 16·32k·4096² ≈ 8.8 PFLOPs(涨 8 倍)。
  • 比例反转:attention 是 FFN 的 2 倍。

整体训练 cost 涨 ~10×,主要由 attention 推动。这就是为什么长上下文模型训练费用高得离谱。


十三、降复杂度方案的工程冷启动问题

线性 attention 还有个非技术但同样重要的障碍:生态系统

  • HuggingFace transformers 库的所有模型默认实现都是 full attention。
  • vLLM、TGI、TensorRT-LLM 等推理框架的优化都围绕 full attention(PagedAttention、CUDA kernel、FlashInfer 等)。
  • 训练框架(Megatron、DeepSpeed)的 Tensor Parallel、Sequence Parallel 也都假定 full attention。

线性 attention 要替代 full attention,不仅要在质量上证明自己,还要建立一整套等价的工具链。这是 Mamba 直到 2024 年才有 vLLM 支持的原因。生态系统粘性是 full attention 的护城河。


十四、attention 复杂度的代码视角

把 PyTorch 朴素实现拿出来对照看:

def naive_attention(Q, K, V, mask=None):
    # Q,K,V: (B, H, n, d)
    n = Q.size(-2)
    d = Q.size(-1)
    # 1) 计算 n×n 矩阵:O(n²·d)
    scores = (Q @ K.transpose(-2, -1)) / d**0.5  # (B,H,n,n)  ← O(n²) 显存
    if mask is not None:
        scores = scores.masked_fill(mask == 0, float('-inf'))
    # 2) softmax over n
    attn = scores.softmax(dim=-1)               # (B,H,n,n)
    # 3) 加权和:再 O(n²·d)
    out = attn @ V                              # (B,H,n,d)
    return out

显存大头在 scoresattn 两个 n×n 矩阵。把它们物化是问题所在。

FlashAttention 接口:

from flash_attn import flash_attn_func
out = flash_attn_func(Q, K, V, causal=True)
# 内部分块计算,永远不显式构造 n×n

接口几乎一样,性能差几倍到几十倍。这是「IO-aware」工程的魅力。


十五、关键概念回顾

  • attention 计算复杂度 O(n²·d)、显存复杂度 O(n²)。
  • attention vs FFN 计算量比例 ≈ n/(4d),n 小时 FFN 主导,n 大时 attention 主导。
  • KV cache 是推理时的隐藏成本,对长上下文 / 多并发场景至关重要。
  • 五类降复杂度方案:滑窗、稀疏、低秩 kernel、SSM、FlashAttention(IO-aware)。
  • FlashAttention 不是 O(n) 计算,仅是 O(n) 显存,仍是 O(n²) 计算。
  • 当代主流大模型仍用 full attention + FlashAttention + GQA/MLA。
  • 现代 GPU 的真实瓶颈是带宽不是 FLOPs,FlashAttention 的成功本质是减少 HBM 访问。

十六、常见误解

  • 「FlashAttention 把 attention 降到 O(n)」——错。是 O(n) 显存,不是 O(n) 计算。
  • 「线性 attention 已经替代了 full attention」——错。主流大模型仍是 full。
  • 「Mamba 比 Transformer 强」——不准确。在中小模型上接近,在长程检索上仍弱。
  • 「attention 是模型计算量大头」——只在长序列时成立,短序列时是 FFN。
  • 「O(n²) 是不可避免的」——理论上可以避免,但工程上还没找到能匹配 full 的方案。
  • 「降到 O(n) 就能无限长上下文」——长上下文还有位置编码、训练数据、评测等多重瓶颈。

十七、下一步

下一篇(第 19 篇)会回到《Attention Is All You Need》论文本身的历史背景:2017 年的它是怎么从 Google Brain 诞生、怎么在 LSTM 时代杀出重围、为什么作者最初甚至没意识到 decoder-only 的潜力。理解了复杂度的工程现实,再回看那篇论文会有截然不同的感受——「all you need」这句话在当时是个挑衅,七年后却成了预言。


参考文献

  • Vaswani A. et al. Attention Is All You Need. NeurIPS 2017. arXiv:1706.03762.
  • Dao T., Fu D. Y., Ermon S., Rudra A., Ré C. FlashAttention. NeurIPS 2022. arXiv:2205.14135.
  • Dao T. FlashAttention-2: Faster Attention with Better Parallelism and Work Partitioning. 2023. arXiv:2307.08691.
  • Shah J. et al. FlashAttention-3. 2024. arXiv:2407.08608.
  • Beltagy I., Peters M. E., Cohan A. Longformer: The Long-Document Transformer. 2020. arXiv:2004.05150.
  • Zaheer M. et al. Big Bird: Transformers for Longer Sequences. NeurIPS 2020. arXiv:2007.14062.
  • Child R., Gray S., Radford A., Sutskever I. Generating Long Sequences with Sparse Transformers. 2019. arXiv:1904.10509.
  • Wang S. et al. Linformer: Self-Attention with Linear Complexity. 2020. arXiv:2006.04768.
  • Choromanski K. et al. Rethinking Attention with Performers. ICLR 2021. arXiv:2009.14794.
  • Gu A., Dao T. Mamba: Linear-Time Sequence Modeling with Selective State Spaces. 2023. arXiv:2312.00752.
  • Peng B. et al. RWKV: Reinventing RNNs for the Transformer Era. 2023. arXiv:2305.13048.
  • Sun Y. et al. Retentive Network. 2023. arXiv:2307.08621.
  • DeepSeek-AI. DeepSeek-V2: A Strong, Economical, and Efficient Mixture-of-Experts Language Model. 2024. arXiv:2405.04434.

← 上一篇:17. Causal Mask 与自回归 | 下一篇:19.《Attention Is All You Need》论文背景

同主题继续阅读

把当前热点继续串成多页阅读,而不是停在单篇消费。

2026-04-15 · transformer

【Transformer 与注意力机制】01|为什么要从这里开始

这是【Transformer 与注意力机制】系列的第一篇,承担两件事:一是把这套五十多篇文章为谁写、解决什么问题、彼此之间是什么关系交代清楚;二是为完全没基础的读者画出一条从向量、点积、矩阵乘法走到自注意力、再走到大语言模型的爬升路径,让你在投入时间之前先知道终点在哪、路上要经过哪些坎、读完之后你会、还不会做什么事。