对应 Maps to:CMU 10-423 / 10-623 / 10-723 Generative AI(Matt Gormley),Lecture 19 · Wed 25-Mar · Long Context in LLM(slides:lecture19-long)。 阅读材料:Kamradt (2023), Needle In A Haystack;Chen et al. (2023), Extending Context Window of Large Language Models via Positional Interpolation;Fu et al. (2024), Data Engineering for Scaling Language Models to 128K Context;Bertsch et al. (2024), In-Context Learning with Long-Context Models;Child et al. (2019), Sparse Transformers;Beltagy et al. (2020), Longformer;Ding et al. (2023), LongNet;Liu & Abbeel (2023), Blockwise Parallel Transformer;Liu, Zaharia & Abbeel (2023), Ring Attention;Liu et al. (2024), Large World Model。 依据说明:本讲按原课第 19 讲公开的 slides 展开:一个视频问答的例子撞上”超过 4096 的最大上下文”;2019–2026 年各模型的上下文长度表;大海捞针测试;扩展短上下文模型的两个关键(可扩展的位置编码、挑选长数据)和一般配方;微调 vs 上下文学习(2023 年的看法和长上下文下的新结果);近似注意力(稀疏、滑动窗口的三种实现、空洞);高效的精确注意力(FLOPs 随上下文的增长、序列并行、BPT、环形注意力及其结果、Large World Model)。所有实验是本讲义自己设计的,不代表课堂上讲了什么。 配套代码 Code:
code/lecture19/(4 个脚本 + 1 个模块;02、03 第一次各约 3 分钟,之后几秒到半分钟) 预计阅读时间:2.5 小时(含运行代码)
0. 本讲导航 · How to read this lecture
0.1 学习目标 Learning goals
学完这一讲,你应该能够:
- 说出长上下文贵在哪里:训练的 FLOPs、推理的 KV 缓存、预填充的时间,并算出量级。
- 解释大海捞针测试测什么、不测什么;为什么”找不到”往往是”太远”而不是”太长”。
- 用 RoPE 的频率解释外推为什么失败,说出位置插值(PI)、调大 base(NTK / ABF)各改了什么、代价是什么。
- 说明扩展上下文时”数据要有长距离依赖”的意思。
- 比较稀疏、滑动窗口、空洞注意力的代价与局限,用”两跳之内能不能到”判断一个模式会丢掉什么。
- 描述 BPT 和环形注意力怎样让每块设备的显存和序列长度无关,以及通信被计算藏住的条件 。
0.2 先修与本讲范围 Prerequisites & scope
| 默认你已经会 Assumed | 本讲只给直觉,后面再展开 Previewed only |
|---|---|
| 第 4 讲:RoPE、GQA、滑动窗口(三种实现、感受野、滚动缓存) | 状态空间模型、线性注意力(第 21 讲) |
| 第 18 讲:在线 softmax 的 、FlashAttention | YaRN 等更细的位置编码缩放方法 |
| 第 11 讲:上下文学习;第 17 讲:并行与通信 | 长上下文的评测基准(RULER、LongBench 等)的细节 |
0.3 本讲地图 Map
§1 上下文有多长,贵在哪里 ← 代码 01
§2 大海捞针:一个最小的长上下文测试 ← 代码 02 第 1、2 部分
§3 扩展短上下文模型:位置编码 + 长数据 ← 代码 02 第 3–5 部分
§4 近似注意力:稀疏、滑动窗口、空洞 ← 代码 03
§5 高效的精确注意力:BPT 与环形注意力 ← 代码 04
§6–10 小结、误区、练习、延伸阅读、下一讲
本讲的实验模型在 long_lab.py 里:一个 37 万参数、2 层的 Llama 式小 Transformer(RMSNorm、RoPE、SwiGLU),可以换位置编码和注意力模式;玩具世界是一个”大海捞针”的 token 语言。
1. 上下文有多长,贵在哪里 · How long, and what does it cost
1.1 为什么需要长上下文
slides 从一段代码开始:把一段视频的每一帧用 ViT 编码成 66 个 token,和问题一起喂给 GPT-2 做视频问答。10 帧就是 660 个图像 token;帧数一多——“错误:输入超过了 Transformer 的最大上下文长度 4096 个 token”。长文档、整个代码库、长对话、多张图片、视频,都需要长上下文。
slides 的表(节选):
| 模型 | 年份 | 上下文 |
|---|---|---|
| GPT-2 | 2019 | 1,024 |
| GPT-3 | 2020 | 2,048 |
| LLaMA-2 | 2023 | 4,096 |
| Claude-2.1 | 2023 | 200K |
| Gemini-1.5 | 2024 | 1M |
| LLaMA-3.1 | 2024 | 128K |
| Llama 4 Scout / Maverick | 2025 | 10M |
| GPT-5.4 / Gemini 3.1 Pro / Claude Opus 4.6 | 2026 | 1M |
七年里涨了三个数量级。代价在哪里?
1.2 训练:FLOPs 涨得没有想象的快(代码 01 第 1 部分)
训练时每个 token 的 FLOPs ≈ (参数部分,第 15 讲)+ 注意力部分。注意力每层前向对 个键做 和 ,各 次运算,反向是前向的两倍,因果掩码再省一半(第 18 讲 §4.3):约 。整个序列的注意力是 ,摊到每个 token 只是 :
| 模型 | 4K 时注意力占比 | 1M 时注意力占比 | 每 token 1M 比 4K 贵 |
|---|---|---|---|
| Llama-3 8B | 6% | 94% | 17.0× |
| Llama-3 70B | 4% | 91% | 10.3× |
| Llama-3.1 405B | 2% | 84% | 6.2× |
上下文变长 256 倍,每个 token 只贵 6–17 倍;模型越大( 越大),注意力占比越小、涨得越慢。这就是 slides(引自 Ring Attention 论文)说的”FLOPs 随上下文增长得没有你想象的那么快:除了 的注意力,Transformer 还有很多计算密集的部分”。
1.3 推理:KV 缓存和预填充(代码 01 第 2、3 部分)
一个序列的 KV 缓存(BF16、GQA 8 个 KV 头):
| 模型 | 权重 | 每 token | 128K | 1M | KV = 权重时的长度 |
|---|---|---|---|---|---|
| Llama-3 8B | 15 GiB | 128 KiB | 16 GiB | 128 GiB | 120K |
| Llama-3 70B | 131 GiB | 320 KiB | 40 GiB | 320 GiB | 421K |
| Llama-3.1 405B | 756 GiB | 504 KiB | 63 GiB | 504 GiB | 1,536K |
8B 模型在约 12 万个 token 时 KV 缓存就和权重一样大,100 万 token 的一个请求要 128 GiB——比一块 H100 还大。H100 上的 roofline 估计(批大小 1):8B 模型解码一个 token,4K 时 5.0 ms(读 KV 只占 3%),1M 时 45.8 ms(读 KV 占 90%);预填充一个 1M 的提示,8B 要 5 分钟、70B 要 27 分钟,大部分时间在注意力上。
所以长上下文的瓶颈是显存(训练时的激活值、推理时的 KV 缓存)和预填充时间,而不只是每 token 的 FLOPs。§4 的近似注意力、§5 的环形注意力、第 21 讲的状态空间模型,都是在对付这些。
2. 大海捞针 · Needle in a haystack
2.1 测试是什么
slides:“大海捞针测试是一个极其简单、最低限度的测试,看 LLM 能不能在长上下文里找到信息。“做法:造一个长文档;在某个深度埋一个事实(“针”);问一个答案就是这个事实的问题。把”文档长度 × 针的深度”画成热力图(gkamradt 的仓库),一眼看出模型在哪里找不到。
“最低限度”的意思是:找到一句话和”理解长文档”差得很远——后来的基准(例如 RULER)加入了多根针、多跳、聚合等任务,发现很多模型的”有效上下文”比标称的短得多。但如果连这一关都过不了,长上下文就无从谈起。
2.2 我们的玩具版(代码 02 第 1 部分)
long_lab.NeedleTask:16 个键 k0…k15、16 个值 v0…v15、32 个填充词 f0…f31。草堆是填充词组成的马尔可夫链(像一段有规律、但和问题无关的文字);针是 “N k v”;问题是 “Q k”,要预测 v。键值配对每个序列都不一样,答案只能从针里抄。测试时每个序列放 4 根针(1 根要找、3 根干扰):
<s> f3 f30 f31 … N k10 v1 f6 f19 … N k15 v11 … N k6 v3 … N k2 v2 … Q k10 → v1
这正是第 11 讲 §1.3 提到的”归纳头”(induction head)要做的事:找到前面出现过的同一个 k,把它后面的 token 抄过来。训练长度 128,模型 d = 128、2 层、2 个头。
训练这个模型比想象的难,过程本身就是一课(详见 README 的”计划 vs 实际”):
- 只放 1 根针的测试是假的:模型可以只学”抄 N 后面第二个 token”,不比对键也全对——所以测试加了干扰针。
- 捷径:训练时每根针恰好被问一次,模型学会了排除法(最后一个问题只剩一根没问过的针),准确率卡在 0.55,从不比对键。改成有放回地抽问题。
- 头太窄:每个头 16 维(和第 2 讲的 GPT 一样)时,连最简单的键值检索都学不会;每头 64 维时 600 步就学会了。
- 草堆挡住了学习:一开始就在长草堆里训练,3 个种子都卡在”随便抄一根针”(≈ 0.3)上;先在没有草堆的短序列上训练 600 步,学会检索之后再换成长草堆,就一直保持住了(课程学习)。而且种子 0 在所有设置下都学不会——这种”突然学会”的能力出不出现,和初始化关系很大(和第 11 讲 §1.3 ICL 的”突然出现”是同一类现象)。
最终的模型:前 600 步没有草堆(第 400 步准确率 0.654),换成草堆后第 800 步 0.997、第 1200 步起 1.000。
2.3 拿到更长的草堆上去测(代码 02 第 2 部分)
不做任何修改:
| 长度 | 深度 0%(最远) | 25% | 50% | 75% | 100%(最近) | 平均 |
|---|---|---|---|---|---|---|
| 128(训练长度) | 0.98 | 1.00 | 1.00 | 1.00 | 1.00 | 1.00 |
| 256 | 0.92 | 1.00 | 1.00 | 1.00 | 1.00 | 0.98 |
| 512 | 0.64 | 0.88 | 0.94 | 1.00 | 1.00 | 0.89 |
| 1024 | 0.31 | 0.52 | 0.78 | 0.94 | 1.00 | 0.71 |
(每格 64 个序列;瞎猜 1/16,随便抄一根针 1/4。)1024 个 token 的草堆里,紧挨着问题的针仍然全对,最远的针只剩 0.31。失败的不是”长”本身,而是”远”:针和问题之间的距离超过训练时见过的最大距离(约 120)越多,越找不到——这就是大海捞针热力图上常见的”一角发红”。
3. 扩展一个短上下文模型 · Extending short-context models
slides:“扩展一个短上下文模型有两个关键:① 可扩展的位置编码;② 仔细挑选的长数据。“一般的配方(Fu et al., 2024):先用短上下文(块长 4K)在 1 万亿 token 上预训练;调整位置编码的超参数;再把块长增加到 80K 继续预训练,只用 50 亿 token——不到预训练的 1%。
3.1 为什么 RoPE 外推会失败(代码 02 第 3 部分)
回顾第 4 讲:RoPE 把查询和键的每一对维度按位置旋转,第 对的转速是 ; 只取决于相对距离 对应的角度 。头维度 64、base 10000 时:
| 频率对 | 转一圈要多少 token | 训练时最大角度(距离 127) | 测试时(距离 1023) | |
|---|---|---|---|---|
| 0 | 1.00000 | 6 | 127.00 | 1023.00 |
| 10 | 0.05623 | 112 | 7.14 | 57.53 |
| 11 | 0.04217 | 149 | 5.36(不到 ) | 43.14 |
| 16 | 0.01000 | 628 | 1.27 | 10.23 |
| 31 | 0.00013 | 47,117 | 0.02 | 0.14 |
32 对频率里有 21 对在训练时连一圈都没转满:模型只见过圆周上的一段角度。测试时距离到了 1023,这些维度转到了训练时从未出现的角度, 落到模型没学过的范围里。高频的几对转过很多圈,什么角度都见过,所以只靠高频就能分辨的”近处”不受影响——和 §2.3 的”远处失败、近处没事”正好对上。(第 4 讲 §7.3 看到的”RoPE 外推得最差”是同一类问题的另一面。)
3.2 不训练,只改位置编码(代码 02 第 4 部分)
两种零样本的做法, = 测试长度 / 训练长度:
- 位置插值(PI,Chen et al., 2023):把位置 换成 。长度 的序列被”压”回训练见过的角度范围 。代价是相邻两个 token 的角度差也缩小了 倍——高频的分辨率下降。
- NTK 式缩放:不改位置,改 base:。最高频几乎不变(近处照常外推),最低频被拉长 倍(远处相当于插值)。
| 长度 | 做法 | 深度 0% | 平均 |
|---|---|---|---|
| 1024 | 原样外推 | 0.31 | 0.71 |
| 1024 | PI() | 0.98 | 0.91 |
| 1024 | NTK | 0.89 | 0.96 |
都不需要训练,就把远处的针大部分救了回来。PI 在 1024 时每个深度都略降(相邻 token 的角度差被压缩了 8 倍);NTK 只拉长低频,近处几乎不受影响。真实的大模型里,零样本的 PI 通常不够好,要配合少量微调(PI 论文:把 LLaMA 扩展到 32K 只要 1000 步左右的微调);NTK 的思路后来发展成 YaRN 等方法。
调大 base(ABF) 是更常见的做法:Code Llama 把 base 从 1 万调到 100 万,Llama-3 预训练就用 50 万——slides 配方里的”调整位置编码的超参数”指的主要就是这个,然后再用长数据继续训练。
3.3 继续训练:数据里要有长距离依赖(代码 02 第 5 部分)
从基础模型出发,在 512 个 token 上继续训练 150 步,三种做法:
| 做法 | 512 · 深度 0% | 512 · 平均 | 1024 · 深度 0% | 1024 · 平均 |
|---|---|---|---|---|
| (不训练,原样外推) | 0.64 | 0.89 | 0.31 | 0.71 |
| RoPE + 长依赖的数据(针在整个草堆里均匀分布) | 1.00 | 1.00 | 0.73 | 0.92 |
| RoPE + 短依赖的数据(针只在最后 20%) | 0.61 | 0.88 | 0.22 | 0.68 |
| PI()+ 长依赖的数据 | 1.00 | 1.00 | 1.00 | 0.99 |
序列一样长、步数一样多,差别只在”针离问题有多远”。依赖都很短的长序列几乎没有帮助(0.61,和不训练的 0.64 一样):模型只学会了在长草堆里找近处的针。这就是 slides 说的”仔细挑选长数据”:把很多短网页拼接成长序列,内容仍是局部的,教不会模型用远处的信息;要的是书、长代码文件这类真正有长距离依赖的数据(Fu et al. 还发现要保持各领域的比例、在每个领域内部增加长文档的比例)。调整位置编码(PI)+ 长依赖数据的组合最好,在 2 倍于训练长度的 1024 上也几乎全对。
3.4 长上下文改变了”微调 vs 上下文学习”
slides 回到第 11 讲的问题。2023 年的看法(Mosbach et al., 2023):“即使对很大的语言模型,微调也常常胜过上下文学习”——在 RTE、MNLI 上公平比较,多数规模下微调更好。slides 的批注:“至少 2023 年的普遍看法是这样。到了 2025 年,故事可能不一样了。”
Bertsch et al. (2024) 用长上下文的 LLaMA-2-7B,在两个多分类数据集(Clinic-150 有 151 个标签、Trecfine 有 50 个标签)上比较:LoRA 微调、随机挑例子的 ICL、用 BM25 检索最相似例子的 ICL。上下文能放下成百上千个例子时,ICL 的效果随例子数持续上升,可以接近甚至超过微调;例子越多,“检索相似例子”相对”随机挑”的优势越小。长上下文让”把训练集塞进提示”成为一种可行的适配方式——不用训练,代价是每次推理都要处理很长的提示(§1.3)。
4. 近似注意力 · Approximate attention
slides:“标准注意力需要 的显存和计算。计算也许还能接受,显存通常不行。“(第 18 讲的 FlashAttention 已经把显存降到 ,但计算仍是平方的。)一个办法是近似:稀疏注意力(2019,)、滑动窗口(2020,)、空洞注意力(2023,)。
4.1 三种模式(代码 03 第 1、2 部分)
- 滑动窗口(Longformer 的局部注意力,第 4 讲 §6):只看最近 个 token。slides 再次列出它的三种实现(朴素的掩码、for 循环、滑动分块),第 4 讲已经实现过。
- 跨步稀疏(Sparse Transformer,Child et al., 2019):最近 stride 个,再加上每隔 stride 个取一个;stride ≈ 时每个查询看 个键。
- 空洞注意力(LongNet,Ding et al., 2023):把序列切成长度 的段,段内每隔 个取一个;几种 合起来——近处密、远处疏。slides 的评价:“运行时间很好,但它已经是另一个模型了。“(我们实现的是只抽稀键的简化版;LongNet 原文让不同的头用不同的起点。)
要算的 (查询, 键) 对:
| 完整(因果) | 滑动窗口 | 跨步稀疏 stride = | 空洞 | |
|---|---|---|---|---|
| 1,024 | 524,800 | 43.7% | 9.2% | 5.2% |
| 4,096 | 8,390,656 | 12.1% | 4.6% | 1.6% |
(这些模式要配专门的核函数,只算需要的块,才真正省时间。)
4.2 能从多远的地方传过来(代码 03 第 3 部分)
每一层是一”跳”。,2 层:
| 模式 | 一跳能到的 | 两跳能到的 |
|---|---|---|
| 完整 | 100% | 100% |
| 滑动窗口 | 23.4% | 42.4% |
| 跨步稀疏 stride = 12 | 25.3% | 100% |
| 空洞 (8,1)(32,4)(128,16) | 16.3% | 30.2% |
跨步稀疏的”列”位置像中转站:任何位置都在某个列的局部窗口里,两跳处处可达。但”能到”只说明有路——模型得学会走这条路。
4.3 同样的配方训练四个模型(代码 03 第 4 部分)
训练长度 128(600 步没有草堆 + 900 步有草堆),在 128 个 token 上找针,每格 128 个序列:
| 模式 | 深度 0%(距离 124) | 25%(96) | 50%(68) | 75%(39) | 100%(11) | 平均 |
|---|---|---|---|---|---|---|
| 完整 | 1.00 | 1.00 | 1.00 | 1.00 | 1.00 | 1.00 |
| 跨步稀疏 | 0.98 | 0.98 | 0.95 | 0.95 | 1.00 | 0.97 |
| 空洞(简化版) | 0.10 | 0.05 | 0.16 | 0.35 | 0.98 | 0.33 |
| 滑动窗口 | 0.08 | 0.06 | 0.08 | 0.10 | 1.00 | 0.26 |
- 滑动窗口只能找到窗口附近的针:第二层只看最近 16 个位置,这些位置在第一层也只看再往前 16 个——最远约 30 个 token。窗口之外的信息,在两层之内根本过不来(第 4 讲 §6.5 的主谓一致是同一个现象)。
- 跨步稀疏几乎和完整注意力一样好,只算了约四分之一的对。按它的掩码,远处的针只能先被附近的列位置在第一层”收进来”,第二层再从列上取——模型学会了用这些中转站。
- 空洞(简化版) 的段是对齐的块,块开头附近的位置在第一层看不到多少历史,两跳只能到 30%,中转站很难建立。
教训:省下的计算是有代价的;代价多大,取决于这个模式有没有给远处的信息留一条模型学得会的路。这也是 Longformer、BigBird 额外加几个”全局 token”(能看所有位置、也被所有位置看)的原因,也是 Gemma、gpt-oss 等把滑动窗口层和全局注意力层交替使用的原因(第 4 讲 §6.5)。
5. 高效的精确注意力:BPT 与环形注意力 · Efficient full attention
5.1 序列并行的问题
slides:序列并行(Li et al., 2021)把一个长序列切成几段,每段给一块设备;对仅解码器的 Transformer,前面设备的计算结果要传给后面的设备。“问题:这样扩展得并不高效,因为后面的查询仍然要看 个键和值。”
5.2 BPT:注意力和前馈层都分块(代码 04 第 1 部分)
FlashAttention 把注意力的显存降了下来,但”只在注意力层里做分块计算”。BPT(Blockwise Parallel Transformer,Liu & Abbeel, 2023)对每一块查询 ,遍历所有键值块算完注意力(用第 18 讲的在线 softmax:slides 说”softmax 对平移不变,所以可以分块计算,再根据其他块的充分统计量重新缩放之前的输出”),然后立刻对这一块做前馈层和残差连接——前馈层 4h 宽的中间结果也只存一块。Ring Attention 论文表 1 的每层最大激活值(BF16,、32 个头,块 ):
| 序列长度 | 普通注意力 | FlashAttention(前馈层 最大) | BPT | 环形注意力 (每块设备) |
|---|---|---|---|---|
| 32K | 64 GiB | 1.0 GiB | 256 MiB | 96 MiB |
| 128K | 1.0 TiB | 4.0 GiB | 1.0 GiB | 96 MiB |
| 1M | 64 TiB | 32 GiB | 8 GiB | 96 MiB |
BPT 之后,一层只剩它的输出本身()——但仍和 成正比,一块设备总有放不下的时候。
5.3 环形注意力(代码 04 第 2 部分)
slides 的关键想法:“用 BPT 在很多设备上处理很长的序列;K、V 块在设备之间传递的模式,和它们在注意力计算里被使用的模式完全相同。“结果:“能放进显存的序列长度随设备数线性增长。“(slides 把它叫作”击鼓传花” pass the parcel。)
把 个 token 分给 块设备,第 块持有自己的 。一共 轮:每一轮,每块设备用手上当前的 K、V 块和自己的 算一块注意力,用 合并进累加器;然后把手上的 K、V 块传给环上的下一块设备、从上一块收一块。 轮之后,每块设备都见过了全部的 K、V。
04 真的算了一遍(、、float64):,有无因果掩码,和整段注意力的差都在 量级。每块设备一共发出 个 K/V 块,总量 ——和一次 all-gather(第 17 讲)一样多,但拆成了 次、每次只和邻居通信,正好可以和计算重叠。每块设备只存 6 个块(、当前的 K/V、正在接收的 K/V、输出),和序列长度无关(§5.2 表的最后一列)。
5.4 因果掩码下的负载均衡(代码 04 第 3 部分)
因果掩码让连续切分忙闲不均:设备 0 拿最前面的 token,只需要看自己那一块;设备 7 拿最后的 token,要看全部 8 块。每一轮大家都要等最忙的那块:
| 切分(、) | 各设备的工作量 | 效率 |
|---|---|---|
| 连续 | 2k / 6k / … / 30k | 53% |
| 条带(token → 设备 ) | 16k × 8 | 99% |
条带式切分(Brandon et al., 2023 的 Striped Attention)让每块设备都有早有晚的 token,每一轮的工作量都差不多是半块。
5.5 通信藏得住吗(代码 04 第 4 部分)
一块 对一块 K/V 要 次运算,同时要收发 字节(K、V 各 ,BF16)。重叠的条件 ,即
——和头维度无关,只看”算力 / 带宽”。论文表 2(我们逐行重算):A100 + NVLink(312 TFLOPS、300 GB/s);A100 + InfiniBand(12.5 GB/s)(论文写 24.5K);TPU v4 。每块设备的序列至少约 。块够大时,传下一块的时间完全藏在算这一块的时间里,环形注意力几乎没有额外开销。
5.6 结果与 Large World Model
slides 列出的结果:13B 模型在 8 块 A100 上能处理 128K 的上下文;7B 模型在 32 块 A100 上能处理 400 万 token。Large World Model(Liu et al., 2024)用环形注意力训练,分几个阶段逐步把上下文扩到 100 万 token,同时处理长视频和长文本——这就是 §1.1 那个视频问答例子的答案之一。
6. 小结 · Summary
- 长上下文的代价:每 token 的 FLOPs 涨得比 直觉慢得多(256 倍长度、6–17 倍代价),真正的瓶颈是显存(激活值、KV 缓存)和预填充时间。
- 大海捞针是”最低限度”的测试;找不到的往往是远处的针,而不是长序列本身。
- RoPE 外推失败,是因为低频维度在训练时没转满一圈;PI(压缩位置)和 NTK / ABF(调大 base)都能不训练就救回很多,配合少量长数据的继续训练效果最好。
- 继续训练的数据要真正包含长距离依赖;只是”长”而依赖很短的数据几乎没用。
- 近似注意力省计算,代价取决于模式能否给远处的信息留一条可学的路:跨步稀疏借中转站几乎不损失,滑动窗口和我们的空洞版本找不到远处的针。
- BPT 把前馈层也分块;环形注意力让每块设备的显存和序列长度无关,K/V 沿环传递、和计算重叠(),能处理的上下文随设备数线性增长;条带式切分解决因果掩码的负载不均。
7. 常见误区 · Common pitfalls
- “上下文窗口是 1M,模型就能用好 1M 的信息。” 标称长度只是”放得下”;大海捞针是最低要求,多跳、聚合类任务上有效长度常常短得多。
- “长上下文主要贵在注意力的 FLOPs。” 摊到每个 token 是线性的;大模型在 128K 时注意力只占一半左右(70B:55%),显存和预填充时间才是硬约束。
- “RoPE 只编码相对位置,所以天然能外推。” 相对距离超出训练范围时,低频维度出现没见过的角度(我们:21/32 对),远处的针找不到。
- “把短文档拼成长序列继续训练,就能扩展上下文。” 依赖仍是局部的,几乎没用(我们:0.61 vs 不训练的 0.64)。
- “稀疏注意力只是精度略降的近似。” 损失取决于模式:滑动窗口在远处直接归零(0.06–0.10),跨步稀疏几乎没损失(0.97)。
- “环形注意力减少了通信量。” 总通信量和一次 all-gather 一样;它的好处是显存和序列长度无关、通信可以被计算藏住。
8. 练习 · Exercises
练习 1(FLOPs)。 一个 、、 的模型,训练时上下文 128K。(a) 每个 token 的参数部分和注意力部分各多少 GFLOP?(b) 如果不做因果掩码的跳过,注意力部分是多少?
参考答案
(a) GFLOP; GFLOP(01 的表:48 / 103,注意力占 68%)。(b) 不跳过时 GFLOP——FlashAttention 的块跳过把它减半。
练习 2(RoPE 转满一圈)。 头维度 、base 10000、训练长度 4096。哪些频率对在训练时没转满一圈?把 base 调到 50 万呢?
参考答案
第 对转满一圈要 个 token。要求 :,,所以 这 18 对没转满。base = 50 万时 , 共 32 对没转满——调大 base 让更多维度在训练时”转得慢”,相当于在训练时就为更长的距离预留了没用过的角度区间;继续训练时,模型在长数据上学会使用它们。
练习 3(PI 的代价)。 训练长度 4K、用 PI 扩展到 128K()。相邻两个 token 在最高频那一对上的角度差变成多少?为什么这会伤害局部的建模?
参考答案
原来是 弧度,插值后是 弧度。注意力要区分”上一个 token”和”上上个 token”,靠的就是高频维度上的角度差;它被压缩 32 倍后,相邻位置几乎不可分辨,模型需要重新学习(所以 PI 要配合微调),这也是 NTK / YaRN “高频不动、只插值低频”的动机。我们的 1024()上 PI 每个深度都略降,就是这个效应的小规模版本。
练习 4(滑动窗口的感受野)。 层、窗口 的模型,第 层最远能用到多远的信息?为什么我们的 2 层、 模型连距离 39 的针都找不到?
参考答案
(第 4 讲 §6.3):2 层是 30。距离 39 超出了感受野,信息在两层之内根本过不来(0.10)。即使在感受野之内,“找针”还要求第二层直接看到一个已经收进了”键–值”配对的位置,所以实际能用的距离可能更短。
练习 5(环形注意力的显存)。 7B 模型()、BF16、每块设备的块 。(a) 每层每块设备的最大激活值是多少?(b) 要处理 100 万 token 的序列、每块设备 8192 个 token,需要多少块设备?(c) InfiniBand 互联时这个块够大吗?
参考答案
(a) 字节 = 192 MiB。(b) 块(取 128)。(c) InfiniBand 要求 ,8192 不够——通信藏不住,要么换 NVLink 域内的设备、要么把块加大到 25K 以上。
练习 6(条带式切分)。 为什么条带式切分下,每一轮每块设备的工作量约是”半块”?
参考答案
设备 持有 token ,设备 的键是 。第 个查询 能看第 个键 当且仅当 ,即 ,或 且 。所以每一对设备之间都是一个”下三角”(含或不含对角线),约占一块的一半。连续切分时则要么整块()、要么半块()、要么 0()。
9. 延伸阅读 · Further reading
- 评测:Kamradt (2023) 大海捞针;Liu et al. (2023), Lost in the Middle;Hsieh et al. (2024), RULER。
- 位置编码的扩展:Chen et al. (2023) PI;Peng et al. (2023), YaRN;Xiong et al. (2023), Effective Long-Context Scaling of Foundation Models(ABF);Press et al. (2022), ALiBi。
- 长数据:Fu et al. (2024), Data Engineering for Scaling Language Models to 128K Context。
- 长上下文 ICL:Mosbach et al. (2023);Bertsch et al. (2024);Agarwal et al. (2024), Many-Shot In-Context Learning。
- 近似注意力:Child et al. (2019);Beltagy et al. (2020);Zaheer et al. (2020), BigBird;Ding et al. (2023), LongNet。
- 精确注意力的并行:Li et al. (2021), Sequence Parallelism;Liu & Abbeel (2023), BPT;Liu et al. (2023), Ring Attention;Brandon et al. (2023), Striped Attention;Liu et al. (2024), Large World Model。
10. 下一讲预告 · Next lecture
第 20 讲:推理模型。长上下文让模型”读得更多”;推理模型让模型”想得更久”。o1 和 DeepSeek-R1 先写出很长的思考过程再回答:训练时用强化学习(不需要奖励模型,只用”答案对不对”的规则),测试时花更多计算(想得更长、采样更多次)就能答对更难的题。我们会造一个能自己决定”想多少”的小模型,看测试时计算、STaR 自举和 GRPO 各自做了什么——包括 R1-Zero 那张”思考越练越长”的曲线是怎样出现的。