本地 Llama 3 回答变短、答非所问,先别急着把原因归到量化上。量化确实会掉精度,但通常只在低位宽(比如 4bit 以下)、小参数量模型、长回答和严格指令遵循这类任务上才明显暴露;更多时候,你看到的“变差”来自采样参数没固定、提示词模板套错、上下文长度不够,或者单纯是小模型在难题上的正常波动。要判断量化档位是不是主因,可行路径是:用同一批固定问题、同一套采样参数,分别跑高位宽和量化文件,把输出存下来逐条对比,而不是凭一次对话的感受下结论。下面按“先控制变量、再比较档位、最后取舍”的顺序给出一套可执行的对照流程。
先排除参数与模板这两个高频干扰项,再用固定问题集对比两个量化文件的输出,才能判断答复变差是否由量化精度损失引起。适用场景是本地单机跑 Llama 3、显存受限、需要在多个量化档位间选一个。操作动作:固定温度与 top-p、核对 Llama 3 的角色标记模板、保存两档输出并逐条比对。验证方式:看差异是否集中在长回答和严格指令任务上。边界是单机小样本对照只能说明趋势,不能给出通用质量结论。
固定一批问题作为对照样本
没有统一基准,不同档位之间的比较就没有意义。样本不用多,覆盖三类任务各三到五条即可:事实问答(模型应给出确定信息,便于看是否记错或含糊)、指令遵循(例如“用三条要点回答,每条不超过二十字”,看格式是否被遵守)、多轮改写(先给一段话,再要求换语气或压缩,看上下文是否被记住)。问题一旦选定就不要再改,否则两档结果无法对齐。
输出保存方式建议按目录分档存放,文件名带档位和参数指纹,例如 out/q4_k_m/q01.txt、out/q8_0/q01.txt,并在同目录写一份 run.txt 记录启动命令。评分维度保持简单可操作:正确性(对/错/含糊)、指令遵循(完整/部分/未遵守)、长度(字符数)、是否出现异常符号或截断。档位划分按你手上实际有的文件来,常见是 q8_0、q6_k、q5_k_m、q4_k_m 这几档,先选两档对比即可,不必一次全跑。
把采样参数固定下来再比较量化档位
温度、top-p、top-k、重复惩罚这些参数控制的是采样随机性。同一档位跑两次结果不同,往往只是随机性在起作用,和量化无关。比较量化档位时,建议先把温度调到较低值(如 0.1–0.3),top-p 固定,top-k 固定,重复惩罚固定,并显式指定随机种子,让两次运行尽可能可复现。max tokens 也要一并固定,否则长回答档位会因为生成上限不同而显得“话更多”。
# 通用启动骨架,按实际框架替换可执行文件名
llama-cli -m ./models/llama3-q4_k_m.gguf \
-p "$(cat prompt01.txt)" \
`--temp` 0.2 `--top-p` 0.9 `--top-k` 40 `--repeat-penalty` 1.1 \
`--seed` 42 -n 512 -c 4096 -ngl 99 > out/q4_k_m/q01.txt 2> out/q4_k_m/q01.log
每次运行都填一张参数记录表,方便回看时确认两次比较的变量是否真的只有量化档位不同:
| 参数 | 本次取值 | 说明 |
|---|---|---|
| temperature | 0.2 | 越低越确定,便于对照 |
| top-p / top-k | 0.9 / 40 | 两档必须一致 |
| repeat penalty | 1.1 | 过高会让回答变短 |
| seed | 42 | 便于复现 |
| max tokens / ctx | 512 / 4096 | 影响长度与上下文 |
需要一并排除的变量还有:推理框架与版本是否相同、线程数与 GPU 卸载层数是否相同、KV cache 是否被单独量化、系统模板(system prompt)是否被两个脚本写得不一样。这些差异都足以让输出看起来“掉档”,但它们和权重量化无关。
核对提示词模板是否与模型匹配
Llama 3 系列用的是带角色标记的对话格式,通常由 start_header_id、end_header_id 和 eot_id 这类标记组成,而不是 Llama 2 时代的 [INST] 写法。如果推理框架里手动拼接模板,或者直接套用了旧模板,模型会把标记当成普通文本,表现通常是:复述你的问题、把标记原样吐出来、多轮时角色混乱、回答在第一个换行处就断掉。这些现象很容易被误判成量化掉精度。
检查点是:system、user、assistant 三种角色标记是否成对出现;每条消息结尾是否有正确的结束标记;框架内建的 chat template 是否被覆盖。替换模板后,用样本里的两个多轮问题重跑一遍,把修正前后的输出并排放在同一张记录里:
| 问题ID | 修正前表现 | 修正后表现 |
|---|---|---|
| m01 | 把标记原样输出 | 正常回答 |
| m02 | 第二轮丢失角色 | 上下文延续正常 |
用同一问题比较两个量化文件的输出
模板和参数都控制住之后,再拿两个量化文件做对照。启动命令骨架相同,只替换 -m 指向的模型文件:
# 档位 A(高位宽)
llama-cli -m ./models/llama3-q8_0.gguf -p "$(cat prompt01.txt)" \
`--temp` 0.2 `--top-p` 0.9 `--top-k` 40 `--repeat-penalty` 1.1 `--seed` 42 -n 512 -c 4096 > out/q8_0/q01.txt
# 档位 B(低位宽)
llama-cli -m ./models/llama3-q4_k_m.gguf -p "$(cat prompt01.txt)" \
`--temp` 0.2 `--top-p` 0.9 `--top-k` 40 `--repeat-penalty` 1.1 `--seed` 42 -n 512 -c 4096 > out/q4_k_m/q01.txt
逐条问题跑完两档,记录差异。判据不要只看“哪个回答更漂亮”,而是看差异的分布:如果短的事实问答两档基本一致,差异集中在长回答、复杂推理和严格格式任务上,这更符合量化精度损失的典型特征;如果连简单的单轮事实问答都出现明显偏差,先回头检查模板和参数,而不是直接换档位。
| 问题ID | 档位A长度 | 档位B长度 | 差异类型 |
|---|---|---|---|
| f01 事实问答 | — | — | 基本一致 / 偏差 |
| i01 指令遵循 | — | — | 格式是否遵守 |
| m01 多轮改写 | — | — | 上下文是否延续 |
按可接受质量与可承受显存做最终取舍
把对照结论收敛成一份自己环境下的档位表。下面三列是判断依据,具体取值需要结合你的显存、上下文长度和可接受速度填写:
| 量化档位 | 质量倾向 | 显存占用 | 速度倾向 |
|---|---|---|---|
| q8_0 | 接近原始权重 | 高 | 相对慢 |
| q6_k / q5_k_m | 折中 | 中 | 中等 |
| q4_k_m | 长回答任务易暴露差距 | 低 | 相对快 |
使用场景上,如果任务以短问答、字段抽取、简单分类为主,低位宽通常够用;如果任务包含长文改写、多步推理、严格格式输出,优先保证档位质量,必要时用更小的模型配合更高档位来换取显存余量。回退与复测步骤:先记录当前档位下的失败样本,换到上一档位重跑同一批问题,若差异集中在长回答上消失,则说明该场景确实需要更高位宽;若差异依旧,问题多半在模板、参数或上下文长度,继续在这三处排查即可。