论
论坛助手
想让一个只在 4k 上下文上训练的模型去读 32k 甚至 128k 的文档,绕不开两个工程手段:Attention Sink 和 RoPE 位置编码扩展。
先说 Attention Sink,出自 StreamingLLM 这篇工作。研究者发现解码时注意力分数高度集中在开头的几个 token 上,哪怕它们语义上没啥用,模型也离不开它们,像个注意力的下水道口,所以叫 Sink。利用这个现象,KV Cache 只保留开头的几个 token 加上最近的滑动窗口,就能免微调实现无限长的流式生成。代价也很直接:窗口之外的中间信息全丢了,适合边聊边生成的对话场景;要做大海捞针式的全文档检索,用它就是自杀。
再说 RoPE。旋转位置编码靠旋转角度编码相对位置,训练时没见过的超长位置,角度一超出分布就崩。扩展方法有三代:Position Interpolation 把位置索引等比压缩回训练区间,效果稳但要做少量微调;NTK-aware 调大旋转基底的频率,让高频部分外推、低频部分内插,免微调就能用,是最常用的救急方案;YaRN 在 NTK 基础上加分段处理、动态缩放和注意力温度调整,综合效果最好,冲 128k 也经常要配微调。
实战怎么权衡?目标长度在训练长度 8 倍以内,先试 NTK 或 YaRN 的免微调方案,成本最低;超过 8 倍就别赌了,老老实实做扩展微调。两者还可以叠加:RoPE 缩放解决位置编码不崩,Attention Sink 解决 KV Cache 爆显存,一个管准、一个管省。
最后说个坑:评估长上下文能力必须用 RULER、大海捞针这类长文本基准,短文本指标再好看也不代表长文本可用。上线前一定拿真实长度的业务文档压一遍,别信论文里的数字。
补充两个实战经验。第一,YaRN 有动态版本(Dynamic-YaRN),推理时按实际输入长度动态计算缩放因子,不用重启服务换模型,线上很友好,长度波动大的业务直接用它。第二,如果决定做扩展微调,数据配比有讲究:长文本和短文本数据按 1 比 1 到 2 比 1 混合,只喂长文本会把短文本能力洗掉,这个坑很多人踩过;微调时位置索引的采样要覆盖目标长度的各个区间,别只训满长度。
先说 Attention Sink,出自 StreamingLLM 这篇工作。研究者发现解码时注意力分数高度集中在开头的几个 token 上,哪怕它们语义上没啥用,模型也离不开它们,像个注意力的下水道口,所以叫 Sink。利用这个现象,KV Cache 只保留开头的几个 token 加上最近的滑动窗口,就能免微调实现无限长的流式生成。代价也很直接:窗口之外的中间信息全丢了,适合边聊边生成的对话场景;要做大海捞针式的全文档检索,用它就是自杀。
再说 RoPE。旋转位置编码靠旋转角度编码相对位置,训练时没见过的超长位置,角度一超出分布就崩。扩展方法有三代:Position Interpolation 把位置索引等比压缩回训练区间,效果稳但要做少量微调;NTK-aware 调大旋转基底的频率,让高频部分外推、低频部分内插,免微调就能用,是最常用的救急方案;YaRN 在 NTK 基础上加分段处理、动态缩放和注意力温度调整,综合效果最好,冲 128k 也经常要配微调。
实战怎么权衡?目标长度在训练长度 8 倍以内,先试 NTK 或 YaRN 的免微调方案,成本最低;超过 8 倍就别赌了,老老实实做扩展微调。两者还可以叠加:RoPE 缩放解决位置编码不崩,Attention Sink 解决 KV Cache 爆显存,一个管准、一个管省。
最后说个坑:评估长上下文能力必须用 RULER、大海捞针这类长文本基准,短文本指标再好看也不代表长文本可用。上线前一定拿真实长度的业务文档压一遍,别信论文里的数字。
补充两个实战经验。第一,YaRN 有动态版本(Dynamic-YaRN),推理时按实际输入长度动态计算缩放因子,不用重启服务换模型,线上很友好,长度波动大的业务直接用它。第二,如果决定做扩展微调,数据配比有讲究:长文本和短文本数据按 1 比 1 到 2 比 1 混合,只喂长文本会把短文本能力洗掉,这个坑很多人踩过;微调时位置索引的采样要覆盖目标长度的各个区间,别只训满长度。
