训练完成后,saves/course-assistant-lora 里的核心文件只有四十多 MB。这就是 LoRA 适配器,也就是前面说的那些"便利贴"。
它离不开底座:每次使用,都要先加载 1.7GB 的 Qwen3.5-0.8B,再把适配器挂上去。
后面的章节要拿这个模型做评测、量化、部署,带着"底座加适配器"两样东西到处走很麻烦,很多工具也只认完整的模型。
这一节把适配器合并进底座,导出成一个独立的完整模型,再给它写一份模型卡。
学完你能做到:用两种方法合并 LoRA,检查导出的模型能不能正常工作,并且为自己的模型写出合格的说明书。
这一节的产出,也是这一章的产出:课程助教 v1,存在 models/course-assistant-v1 里。
一、适配器和合并后的模型
先看看适配器目录里有什么。核心是两个文件:
| 文件 | 内容 |
|---|---|
adapter_config.json |
LoRA 的配置:r、alpha、加在哪些层上、底座是哪个 |
adapter_model.safetensors |
所有 A、B 小矩阵的权重 |
adapter_config.json 里最重要的几项,以课程助教的适配器为例:
{
"base_model_name_or_path": "models/Qwen3.5-0.8B",
"peft_type": "LORA",
"r": 16,
"lora_alpha": 32,
"lora_dropout": 0.05,
"target_modules": [
"in_proj_z", "in_proj_qkv", "o_proj", "in_proj_a", "out_proj", "down_proj",
"in_proj_b", "up_proj", "k_proj", "q_proj", "v_proj", "gate_proj"
],
"task_type": "CAUSAL_LM"
}这个文件是训练时自动生成的,打开 saves/course-assistant-lora/adapter_config.json 就能看到,不用自己写。
peft_type 说明这是 LoRA;task_type 里的 CAUSAL_LM,指的是"猜下一个 token"的语言模型。
r 和 lora_alpha 就是配置文件里写的 16 和 32。
target_modules 是 LLaMA-Factory 按 lora_target: all 自动找出的线性层,和前面程序里列的那 12 种层名一致。
视觉编码器的层不在其中。
什么时候保留适配器,什么时候合并?
| 保留适配器 | 合并成完整模型 | |
|---|---|---|
| 大小 | Qwen3.5-0.8B、r = 16 时约 43MB | 和底座差不多,约 1.7GB |
| 使用时 | 要先加载底座 | 单独就能用 |
| 适合 | 一个底座配多个适配器,按需切换;节省存储 | 量化、转换格式、部署到不支持 LoRA 的工具里 |
| 本课 | 后面讲推理服务器时,会说到同时挂多个适配器 | 后面几步都用合并后的模型 |
用前面"便利贴"的比方,两种用法是这样的:

合并在数学上很简单:把每一层的 B × A 乘出来,按 alpha 除以 r 缩放,加到原来的权重 W 上。
写成式子是:新的 W = W +(alpha ÷ r)× B × A。课程助教的 alpha 是 32、r 是 16,32 ÷ 16 = 2,也就是 W 加上 2 倍的 B × A。

合并之后,模型的结构和底座一模一样,只是权重的数值变了。
二、方法一:用 LLaMA-Factory 导出
在 llm-course 目录下新建一份导出配置 course_assistant_merge.yaml:
### 注意:合并时底座必须是原始的 16 位模型,不能用量化后的模型
### 模型:底座 + 适配器
model_name_or_path: models/Qwen3.5-0.8B
adapter_name_or_path: saves/course-assistant-lora
template: qwen3_5
enable_thinking: false
trust_remote_code: true
### 导出:合并后的完整模型,每个文件最大 5GB
export_dir: models/course-assistant-v1
export_size: 5
export_device: cpu
export_legacy_format: false几项说明:
- 底座必须是原始的 16 位模型。 如果训练时用了 QLoRA,合并时也要换回 16 位的底座,不能在量化后的模型上合并。LLaMA-Factory 的官方示例里专门写了这条提醒。
export_device: cpu表示在 CPU 上合并,不占显存,但要有足够的内存。0.8B 模型有 8GB 内存就够了。export_size: 5表示导出的权重每个文件最大 5GB。0.8B 合并后不到 2GB,只会存成一个文件;换成更大的模型,才会切成几个文件。
还有一项 export_legacy_format: false,表示用新的 safetensors 格式保存权重,不用老的 .bin 格式。
这一节的命令都在 llm-course 目录下运行。打开终端,先用 cd 进到这个目录。
运行:
uv run llamafactory-cli export course_assistant_merge.yaml跑完后,models/course-assistant-v1 里就是合并好的完整模型。
三、方法二:用 PEFT 自己合并
LLaMA-Factory 内部用的是 Hugging Face 的 PEFT 库。不依赖 LLaMA-Factory,也可以直接写几行代码合并。
PEFT 是 Parameter-Efficient Fine-Tuning 的缩写,意思是"只训练少量参数的微调",LoRA 就是其中最常用的一种。
这段代码要用 peft;Qwen3.5 的图像预处理配置还要用 torchvision,少了它,保存分词器那一步会报错。装过 LLaMA-Factory 的话,这两个包已经一起装好了;没装过的话先安装:
uv pip install peft torchvision新建 merge_lora.py 文件,下面是代码: