报错是这么冒出来的。喂一段 6000 字的文档做摘要,输出被截断且日志提示 context shift,模型只处理了前面一部分内容。
中间走过弯路,把「prompt 里带了大量格式字符,实际 token 更多」当成主因,改完现象没变。
真正麻烦的地方在于,几个原因的现象几乎一样。默认上下文只有 2048 或 4096,超出后滑动窗口丢弃前文。少数情况下是训练时的原生上下文本来就小于输入长度。
另外,多轮对话累积后超过了设定上限。
动手时先把上下文调到模型支持的范围
./llama-cli -m qwen2.5-7b-q4.gguf -c 8192 -p "总结这段文字" -f doc.txt
随后开启动态位置编码以支持更长输入
./llama-cli -m qwen2.5-7b-q4.gguf -c 16384 --rope-scaling yarn -p "hi"
接着用分词工具确认实际 token 数
python -c "print(len(open('doc.txt', encoding='utf-8').read()))"
超长文档改为分块摘要再汇总
python split_doc.py --size 3000 --input doc.txt
别只看报错消失,验证要多做一步。日志里不再出现 context shift,摘要覆盖了文档结尾的内容,输出长度符合预期。
提醒一点。上下文开得越大显存占用和首字延迟都会上升,强行扩到训练长度之外还会让模型答非所问,长文优先考虑分块。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。