合并 LoRA 时那句全大写的 DO NOT 到底在禁什么
本文所有事实以
hiyouga/LlamaFactory官方仓库 2026-08-09 的内容为准。我们没有安装、训练、合并或部署过任何模型,文中所有值都是从仓库源码与示例配置里读出来的。
examples/merge_lora/qwen3_lora_sft.yaml 这份文件连空行一共十三行、去掉空行是十一行,最扎眼的是第一行——它不是配置,是一句注释:### Note: DO NOT use quantized model or quantization_bit when merging lora adapters。翻成中文就是:合并 LoRA 适配器时,不要使用量化模型或 quantization_bit。
我们逐行读过的这几份示例 YAML 里,其它注释都是在解释某个字段的可选值(比如 export_device 后面跟着 # choices: [cpu, auto]),只有这一条是把 DO NOT 两个词全大写顶在文件最上面。这篇就只干一件事:把这条禁令拆开,说清它到底在禁哪两样东西、你怎么判断自己撞没撞上、以及什么情况下它跟你无关。
先把这份配置整份摊在桌上
这是全文,逐行照抄:
### Note: DO NOT use quantized model or quantization_bit when merging lora adapters
### model
model_name_or_path: Qwen/Qwen3-4B-Instruct-2507
adapter_name_or_path: saves/qwen3-4b/lora/sft
template: qwen3_nothink
trust_remote_code: true
### export
export_dir: saves/qwen3_sft_merged
export_size: 5
export_device: cpu # choices: [cpu, auto]
export_legacy_format: false
之所以敢整份贴出来,是因为它确实只有这么长——两个块,### model 四行,### export 四行。这跟它在仓库里的位置是相称的:README 的 Quickstart 一共只有三条命令,合并导出是最后一条。
llamafactory-cli train examples/train_lora/qwen3_lora_sft.yaml
llamafactory-cli chat examples/inference/qwen3_lora_sft.yaml
llamafactory-cli export examples/merge_lora/qwen3_lora_sft.yaml
三份 YAML 的字段是严格对齐的:同一个基座 Qwen/Qwen3-4B-Instruct-2507,同一个 template qwen3_nothink,训练配置里的 output_dir: saves/qwen3-4b/lora/sft 原样出现在推理和合并配置的 adapter_name_or_path 上,合并产物落到 export_dir: saves/qwen3_sft_merged。这条对齐关系是逐行对照三份文件读出来的——你自己改配置时,改动任何一头都得同步另一头,尤其是 template,训练和推理两侧必须是同一个值。
禁令的两个对象,分别是什么
那句注释里点名了两样东西,它们不是一回事。
第一样是 quantization_bit,这是 src/llamafactory/hparams/model_args.py 里的一个字段,源码默认值是 None。它旁边还有一组同族参数:quantization_method 默认 QuantizationMethod.BNB,quantization_type 默认 "nf4",double_quantization 默认 True,quantization_device_map 默认 None。
默认 None 这个事实很关键:你不在 YAML 里显式写 quantization_bit,它就保持源码里的 None——至于代码拿到 None 之后具体怎么走,我们没有读过那段实现,不做推断。所以这半条禁令落到操作上的含义是——别往合并配置里加这一行。上面那份示例配置里确实一行都没有它,这跟注释是自洽的。
第二样是「量化模型」,指的是 model_name_or_path 指过去的那个基座本身。这一半禁的不是某个字段,而是你填进去的模型是什么。配置里写的是 Qwen/Qwen3-4B-Instruct-2507,禁令说的是不要把这一行换成一个已经量化过的模型。
至于为什么禁——README 和示例注释都只给了这条禁令,没有给理由,我们也没有读过 llamafactory-cli export 那段实现。所以这里就到此为止,不做任何推断。你只需要知道它是仓库里明确写下来的一条操作禁令,而且原文用的是 DO NOT,不是 “we recommend not to”。
「加载侧量化」和「导出侧量化」是两组参数名
这是最容易混的地方,也是我认为这条禁令最值得展开的一层。
model_args.py 的导出组里,另有一批带 export_ 前缀的量化参数:
| 参数 | 默认值 |
|---|---|
export_dir | None |
export_size | 5 |
export_device | "cpu" |
export_quantization_bit | None |
export_quantization_dataset | None |
export_quantization_nsamples | 128 |
export_quantization_maxlen | 1024 |
export_legacy_format | False |
export_hub_model_id | None |
注意 quantization_bit 和 export_quantization_bit 是两个不同的字段名,各自独立默认 None。前者属于模型加载那一层,后者属于导出那一层。那句 DO NOT 点名的是前者,没有点名后者。
这个划分在 examples/README.md 的章节结构里也能看到对应:Merging LoRA Adapters and Quantization 这一节下面挂着两条独立的条目——「合并 LoRA 适配器」和「用 AutoGPTQ 量化模型」。是两条,不是一条。同一个 examples/merge_lora/ 目录里也确实有五个文件:mossvl_lora_sft.yaml、qwen3_full_sft.yaml、qwen3_gptq.yaml、qwen3_lora_sft.yaml、qwen3vl_lora_sft.yaml。其中 qwen3_gptq.yaml 这个文件名和那条 AutoGPTQ 条目对得上,但它的内容我们没有读过,所以这里只报文件名,不描述里面写了什么。
对你的实际意义是:如果你的诉求是「合并完还要量化」,那它在仓库的组织方式里是另一件事、另一份配置,不是往这份 13 行的合并配置里塞一个 quantization_bit 就能顺带办掉的。先去读 examples/README.md 那一节的两条条目,确认自己要走的是哪一条。
怎么确认你有没有撞上这一条
按顺序做三个动作,都不需要跑训练:
动作一,打开你的合并配置,搜 quantization_bit。 有这一行就是直接撞上;没有就进下一步。顺手把 export_quantization_bit 和它区分开,别看到前缀相同就当成一个。
动作二,看 model_name_or_path 填的是什么。 这一行如果指向的是一个已经量化过的权重,那就撞上了禁令的另一半。示例里填的是基座 Qwen/Qwen3-4B-Instruct-2507。
动作三,回头翻你训练时用的那份 YAML。 如果你训练走的是 QLoRA 路线——仓库为它单独准备了 examples/train_qlora/ 目录,examples/README.md 的 QLoRA 一节列了 Bitsandbytes/HQQ/EETQ、Ascend NPU 上的 4-bit Bitsandbytes、GPTQ、AWQ、AQLM 几条路径,其中只有「4/8-bit Bitsandbytes/HQQ/EETQ 量化」那一条被标了 (Recommended)——那你训练侧配置里大概率是有量化相关字段的。这些字段不要顺手复制到合并配置里。合并配置和训练配置是两份文件,字段需要对齐的只有 model_name_or_path、adapter_name_or_path、template 这三样,量化那一组不在其中。
处置之后怎么验证
处置本身很简单:把 quantization_bit 那一行删掉,model_name_or_path 换回基座。
验证要看两处。第一处是 export_dir 指的目录——示例里是 saves/qwen3_sft_merged,合并跑完后产物应该落在这里。第二处是拿这个产物起一次推理。这里要提醒一句:examples/inference/ 下的五份配置分别是 mossvl.yaml、qwen3.yaml、qwen3_full_sft.yaml、qwen3_lora_sft.yaml、qwen3vl.yaml,我们只逐行读过其中 qwen3_lora_sft.yaml 这一份,它走的是「基座 + adapter_name_or_path」的路子:
model_name_or_path: Qwen/Qwen3-4B-Instruct-2507
adapter_name_or_path: saves/qwen3-4b/lora/sft
template: qwen3_nothink
infer_backend: huggingface # choices: [huggingface, vllm, sglang, ktransformers]
trust_remote_code: true
合并之后你手上是一个完整的模型目录,不再需要挂 adapter,因此这份配置不能直接照用。按字段语义,该改的是把 model_name_or_path 指向 export_dir、去掉 adapter_name_or_path,template 保持 qwen3_nothink 不变。以上是按官方参数语义组合的示例,未逐项实测,以官方文档与 --help 的实际输出为准;动手前先把 examples/inference/ 里我们没读过的另外几份翻一遍,官方可能已经给了现成写法,比自己拼稳当。
什么情况说明问题不在这一条
这一步不能省,否则这篇就成了一条注释的复读。
如果你的合并配置里根本没有 quantization_bit,model_name_or_path 也是干净的基座,那这条禁令跟你无关,别在这儿耗时间。按这三份配置的对齐关系,更值得先排的是另外几处:
adapter_name_or_path和训练配置里的output_dir是不是同一个路径。示例里两处都是saves/qwen3-4b/lora/sft,写歪一个字符就对不上。template两边是不是同一个值。示例里训练、推理、合并三处都是qwen3_nothink。export_device填的是不是[cpu, auto]之外的东西。注释里给的可选值就这两个,示例用的是cpu。export_size和export_legacy_format这两行,示例值分别是5和false,与源码默认值一致(export_size源码默认5)。它们该不该改,取决于你的产物要怎么分发,官方没有给通用值,我们也不给建议。
最后说一句 trust_remote_code
这份合并配置里还有一行 trust_remote_code: true。值得点出来的是:这个字段在 model_args.py 里的源码默认值是 False,而 examples/ 下的示例 YAML——训练的 train_lora/qwen3_lora_sft.yaml、推理的 inference/qwen3_lora_sft.yaml、合并的 merge_lora/qwen3_lora_sft.yaml——三份都显式写了 true。
代码默认保守、示例配置显式打开,这是一处可核实的客观差异。我们只陈述到这里:不推断作者为什么这么写,也不给「你该不该开」的结论。这一行关系到是否信任模型仓库里附带的远程代码,请你结合自己的来源和环境判断。
本文依据 LlamaFactory 官方仓库(github.com/hiyouga/LlamaFactory)的 README、data/README.md、examples/ 下的配置与 src/llamafactory/hparams/ 的参数定义整理,核对日 2026-08-09。本文内容为仓库源码与文档口径,我们没有安装、训练或部署过任何模型,文中显存数字均为官方标注的估算值(README 原文标 * estimated)而非实测占用。参数与默认值随版本变动,请以 llamafactory-cli train -h 的实际输出为准。安全相关做法请结合自身环境评估,本文不构成安全方案建议。