用大模型迟早撞上三堵墙:资料明明在上下文里却答错;上下文塞到几十万字效果反而变差;同一提示这次对下次不对。这不是产品缺陷,而是同一层机制的必然结果——下一个词预测的目标、注意力的计算方式、位置编码的外推能力。
1. 从"下一个词预测"到可用能力
预训练只做一件事:给定前文,最大化下一个 token 的概率。但链上每个环节决定的东西不同。
| 环节 | 做了什么 | 决定的能力边界 |
|---|---|---|
| 预训练目标 | 最小化下一个 token 的交叉熵 | 语言规律、世界知识的粗粒度压缩 |
| 参数量 | 决定可压缩的信息容量上限 | 能记住多少事实、能同时处理多少关系 |
| 数据质量与配比 | 决定学到的分布重心 | 擅长的领域、默认语气、语种强弱 |
| 后训练对齐 | 把"会续写"改造成"会按要求回答" | 指令遵循、输出格式、拒答边界 |
loss = -log P(token_t | token_1 ... token_{t-1})
# teacher forcing:一次前向对所有位置同时算损失
关键推论:模型优化的是"像不像训练数据里的续写",不是"对不对"。正确性是这条目标的副产品。对齐阶段只改变条件分布的形态,不新增知识:SFT 抬高"回答问题"的续写概率,偏好优化压低"啰嗦空洞"的输出概率。
2. 自注意力在算什么
一个 token 的表示,是它"按相关度加权吸收其他 token 信息"的结果。Q/K/V 是这次吸收的三个角色。
| 名称 | 直觉 | 类比 |
|---|---|---|
| Query(Q) | 我这个位置想找什么 | 检索时输入的查询词 |
| Key(K) | 我这个位置能提供什么 | 文档的索引标签 |
| Value(V) | 我这个位置实际给出的内容 | 文档正文 |
scores = Q @ K.transpose(-1, -2) / sqrt(d_k) # 相关度 [n, n]
weights = softmax(scores, dim=-1) # 每行一次"看哪里"的分配
out = weights @ V
三个必读细节:
sqrt(d_k)不是装饰。不除,点积方差随维度线性增长,softmax 进饱和区,梯度接近 0。weights形状是[n, n]。每个 token 都要和所有 token 算相关度——长度问题的根源。- 多头不是"多算几遍"。把
d_model切成h份并行,让不同的头学不同关系(指代、依存、复制粘贴、局部性);头数增加不显著增加计算量,但增加 KV Cache 条目。
3. 上下文长度为什么是硬限制
三条独立的物理原因,任一条都足以卡死。
计算随长度平方增长。 scores 是 n × n,长度翻倍,计算量与中间激活占用变 4 倍。
KV Cache 显存随长度线性增长。 自回归生成时历史 token 的 K、V 不重算但要一直存着。
KV Cache 字节 ≈ 2 × layers × kv_heads × head_dim × n_tokens × bytes × batch
# 代入一组典型量级(实际以模型 config.json 为准)
layers=32, kv_heads=8, head_dim=128, fp16 → 每 token 约 131 KB
按上式核对:单条 32K token 会话的 KV Cache 就是数 GB 量级,并发 10 条即吃满一张卡余量。长上下文贵的不是算力,是显存。
训练长度分布决定"它见过多长"。 样本绝大多数远短于最大长度,超长位置经验稀疏。宣称支持的长度 ≠ 有效利用的长度。
| 长度区间(典型量级) | 常见表现 |
|---|---|
| 短于训练主分布 | 稳定,指令遵循最好 |
| 接近训练上限 | 可用,长文细节开始丢 |
| 超出训练分布(靠外推) | 首尾还能用,中段明显退化 |
4. 位置编码的三种思路
注意力本身置换不变:打乱 token 顺序,scores 只是行列重排。位置信息必须额外注入。
| 思路 | 做法 | 外推能力 | 代价 |
|---|---|---|---|
| 绝对位置编码 | 每个位置一个可学习向量加到词向量上 | 弱:超出训练最大位置无对应向量 | 简单,长度写死 |
| 相对位置编码(T5 bias、ALiBi) | 注意力分数上加距离惩罚,与绝对位置解耦 | 较强:距离函数对未见长度仍成立 | 要改注意力计算 |
| 旋转位置编码(RoPE 类) | 按位置角旋转 Q、K,使点积只依赖相对位移 | 中上:可插值/缩放扩展 | 频率设计决定外推质量 |
# RoPE:第 i 对维度的旋转角 θ_i = m / base^(2i/d)
def rotate(x, m, theta):
c, s = cos(m * theta), sin(m * theta)
xe, xo = x[..., 0::2], x[..., 1::2]
return stack([xe * c - xo * s, xe * s + xo * c], dim=-1)
# 旋转后 q_m · k_n 只剩 (m - n) 的函数
外推难在哪:高频维度在短距离上分辨力强,低频维度负责长距离。拉到训练长度之外,低频角度进入未见区间,相位开始"绕圈",注意力分布失真。补救是位置插值(位置索引压回训练范围)或频率缩放(调 base),本质都是拿分辨率换长度:换来能跑,代价是近距离分辨力下降。
5. 注意力衰减与"中间遗忘"
长上下文里信息可用性不均匀,普遍呈 U 形:首尾召回明显好于中段。两层原因:位置编码让近距相关度天然偏高;训练数据里"关键信息在开头或结尾"的分布远多于"埋在中间"。
| 摆放位置 | 召回倾向 | 用法建议 |
|---|---|---|
| 最开头 | 高 | 角色设定、全局约束、术语表 |
| 中段 | 低 | 只放可被检索替代的原始素材 |
| 最结尾 | 最高 | 当前问题、输出格式、判定标准 |
| 分块重复 | 高 | 长文档按段处理,每段自带指令头 |
1. 头部:角色、全局约束、术语定义(约 10%~15%)
2. 中部:素材按"段 — 小结"成对出现,每段自带一句要点
3. 尾部:任务、输出 schema、判定标准、示例,并重申一次关键约束
4. 超预算时:先删中段原文保留小结,不要删尾部指令
6. tokenization 的影响
模型看到的不是字也不是词,而是子词(subword)。分词器决定一个概念花几个 token,进而决定成本、长度上限和某些能力缺陷。
| 内容类型 | token 效率(典型量级) | 后果 |
|---|---|---|
| 英文常用词 | 高,约 1 词 ≈ 1~1.5 token | 成本低 |
| 中文 | 中低,1 汉字 ≈ 1~2 token | 同字数更贵、更快撞上限 |
| 代码 | 中,标点与缩进也占 token | 缩进风格影响成本 |
| 少见专名 | 低,可能一词拆多 token | 易被截断或拼错 |
数字切分是算术弱点的直接机制:
"1234567" 可能被切成 ["123","456","7"] 而不是逐位
→ 模型没有个位/十位/百位的对齐概念
→ 位数一多,进位靠模式匹配而非计算
这解释了"数位对齐的算术容易错、写推理步骤的算术明显更准":中间步骤把隐式的位对齐显式化了。
7. 幻觉的机制解释与采样
幻觉不是撒谎,是目标函数与任务要求的错位:模型被训练成"生成最可能的续写",而不是"生成有依据的断言"。它没有内建的事实校验回路——没有模块在输出前回查"这句有出处吗"。
| 触发条件 | 机制 | 缓解方向 |
|---|---|---|
| 训练分布里该实体稀疏 | 靠邻近模式的概率补全 | 提供原文,要求引用 |
| 问题预设了错误前提 | 续写倾向顺着前提走 | 显式允许"前提不成立" |
| 要求精确数字/日期 | 参数化记忆精度天然有限 | 要求"从给定材料摘取" |
| 长尾细节 + 强制格式 | 格式约束压过事实约束 | 先抽取事实,再套格式 |
| 采样参数 | 作用 | 什么时候调 |
|---|---|---|
temperature |
压低/抬高分布锐度 | 抽取类调低,创意类调高 |
top_p |
截断累计概率尾部 | 通常与温度二选一 |
低温度让输出更像最可能的续写,但不会让错误消失:最可能的续写本身错了,低温只让这个错误更稳定地复现。
8. "理解"与"记忆"的边界
| 维度 | 参数化知识 | 上下文知识 |
|---|---|---|
| 来源 | 预训练权重 | 当前输入的 token |
| 更新方式 | 只能重训/微调 | 改提示即生效 |
| 精度 | 模糊,易混淆相似实体 | 逐字保真 |
| 可追溯 | 无法给出处 | 可要求引用原文位置 |
| 典型用途 | 语言能力、常识、推理模式 | 私有数据、最新事实、精确条款 |
实践含义:凡要求精确、可追溯、最新的内容都走上下文;参数化知识只用来判断"怎么处理它们"。 把模型当数据库查,是用最不精确的通道做最需要精确的事。
9. 三个常见误解
| 误解 | 实际机制 | 正确做法 |
|---|---|---|
| 上下文越长越好 | 有效利用率呈 U 形;KV Cache 成本线性涨 | 用检索压到必要范围,关键信息重排到首尾 |
| 模型是数据库,问就能答 | 参数化记忆是压缩后的近似 | 精确事实给原文并要求引用 |
| 一次答对 = 稳定能力 | 采样有随机性,边界样本波动大 | 同批用例多次跑,看通过率 |
10. 排错:五种机制层异常
| 现象 | 机制原因 | 处理 |
|---|---|---|
| 长文中段答不出,首尾却好 | 注意力 U 形衰减 | 问题与小结移到尾部,或分块问 |
| 答案流畅但引用了不存在的条款 | 生成目标不含事实校验 | 要求逐条给原文片段,缺则输出"未找到" |
| 未超上限但质量突然下降 | 有效长度低于标称长度 | 压回训练主分布区间,去冗余素材 |
| 算术/日期错误率高 | 数字分词未按位对齐 | 要求写中间步骤,或改走工具调用 |
| 同一提示两次结果差异大 | 采样随机 | 抽取类降到近确定性,或多次投票 |
11. 边界:机制解释不到的地方
| 问题 | 机制层能解释吗 | 该看什么 |
|---|---|---|
| 某模型为何在某任务更强 | 部分(规模、配比) | 评测集实测 |
| 内部激活的具体语义 | 不能(注意力权重 ≠ 解释) | 可解释性研究,结论有限 |
| 部署成本与延迟 | 能(KV Cache、批处理) | 压测与显存核算 |
一句话:机制解释回答"为什么会这样",不回答"这个模型到底多强"——后者只能测。
12. 自测
- 为什么"预测下一个词"这一个目标能同时解释风格模仿强与事实核对弱?
- 注意力
scores的形状为什么直接决定了长上下文的成本结构? - KV Cache 显存与哪些量成正比,为什么它和并发数直接冲突?
- RoPE 类编码把长度直接翻倍外推,最先失真的是哪一段距离的分辨力?
- 同字数中文技术文档为什么比英文更快撞长度上限?
- 温度调低能消除幻觉吗?从生成目标角度说明理由。