swift LoRA 合并:3 条命令
【免费下载链接】swiftUse PEFT or Full-parameter to CPT/SFT/DPO/GRPO 600+ LLMs (Qwen3.6, DeepSeek-V4, GLM-5.1, InternLM3, Llama4, ...) and 300+ MLLMs (Qwen3-VL, Qwen3-Omni, InternVL3.5, Ovis2.5, GLM4.5v, Gemma4, Llava, Phi4, ...) (AAAI 2025).项目地址: https://gitcode.com/GitHub_Trending/swift1/swift
LoRA 训完,checkpoint 里只有一张几百 MB 的适配器权重,vLLM 加载不了这种"增量"。用 swift 模型合并把 LoRA 权重合回基础模型,产出一个能独立上线的完整模型,整个过程三条命令以内。
先跑通
swift export \ --adapters output/v0-xxx/checkpoint-1000 \ # swift 训练产出的 checkpoint 目录 --merge_lora true # 开启 LoRA 权重合并这条命令做了三件事:从 checkpoint 目录里的 args.json 还原基础模型信息(所以不用手写--model),把 LoRA 增量写回对应权重,最后把完整模型存盘。产物默认落在output/v0-xxx/checkpoint-1000-merged,想换位置就加--output_dir。
产物默认按 safetensors 分片保存,单片上限 5GB(--max_shard_size可调),大模型会自动切成多片,和 Hugging Face 的加载方式完全兼容。
FP16 全量合并时,显存要装得下整个基础模型,大致参考:
- 7B:约 16GB 起
- 13B:约 24GB 起
- 70B:约 80GB 起,建议 A100/H100,或直接在 CPU 上合并
补充:
--merge_lora不只支持普通 LoRA,llamapro、longlora 同样适用;它只处理适配器权重,不碰基础模型的其余部分。
官方示例脚本见 examples/export/merge_lora.sh。多个 checkpoint 只合并最终要上线的那个,中间的留在原地备查即可。
一分钟看懂原理
把基础模型想成一份完整底稿,LoRA 权重只是页边批注——它只记录了一小部分参数的修正量,本身不是完整模型。vLLM、SGLang 这类推理引擎只认"定稿",不认批注,所以上线前必须把批注合成回底稿。这就是 LoRA 合并要解决的问题。
一句话:LoRA 是增量,不是模型;部署认的是完整权重。
合成完之后,每个挂了适配器的线性层和"从没挂过 LoRA"在推理上完全等价,除了你训练的那部分能力。以 7B 模型为例,合并后不再走适配器分支,单条延迟约降 20-30%,吞吐约升 15-25%。
产物里有什么:config.json、tokenizer 全套文件、generation_config.json,以及切好片的权重文件,ls一下目录就能确认。
进阶场景
合并时顺手量化到 4-bit
合并产物还要再压显存,把量化并进同一步,省掉中间产物。
swift export \ --adapters output/v0-xxx/checkpoint-1000 \ --merge_lora true \ --quant_method awq \ # 量化方式,可选 awq / gptq / bnb / fp8 --quant_bits 4 \ # 量化到 4 位 --dataset 'AI-ModelScope/alpaca-gpt4-data-zh#256' # awq/gptq 需要的校准数据awq、gptq 必须给校准数据集,fp8、bnb 不需要;量化批大小默认 1,校准样本数默认 256(--quant_n_samples可调)。AWQ、GPTQ 精度损失通常更小但校准耗时较长,适合对质量敏感的服务;FP8、BNB 出结果快。量化后的产物同样支持 vLLM 加载,7B 模型显存占用能从约 16GB 压到 4-5GB 量级。
多个 LoRA 适配器权重融合
同一基础模型上训了客服、代码两个 LoRA,想压成一个模型上线。
把多个路径传给--adapters,用空格隔开,例如--adapters output/客服/checkpoint-500 output/代码/checkpoint-800,swift 会按给定顺序把每个适配器的增量依次合入基础模型,两份增量都会计入最终权重,相当于叠加而不是二选一。
注意:swift 不提供各适配器之间的权重比例参数。想控制融合配比,要么训练时就调好 rank 和缩放系数,要么手动缩放各自权重后再合并。
最终产物只有一个完整模型,线上不再维护多套适配器。
合并后的 LoRA 部署到 vLLM 或 SGLang
合并完要上线,服务侧直接用 vLLM 或 SGLang 承接。
swift infer \ --model output/v0-xxx/checkpoint-1000-merged \ # 合并产物目录 --infer_backend vllm \ # 换成 sglang 就走 SGLang 加速 --stream true部署链路里不再需要"加载适配器"这个环节,引擎直接读合并后的权重,启动更干净。
排错自查
合并卡住或结果不对,先按症状对号入座,再动手改参数。
| 症状 | 大概率原因 | 处理动作 |
|---|---|---|
| 合并时显存 OOM | 基础模型在 GPU 上装不下 | 加--device_map cpu放到内存里合并,或换更大显存的卡 |
| 拉取基础模型时报错 | 本地没有 args.json 里记录的那个模型 | 按 checkpoint 中记录的模型 ID 重新下载基础模型,再跑合并 |
| 合并后效果反而变差 | LoRA 秩或缩放系数偏大,增量盖过了原有能力 | 降低 rank 重新微调;顺带核对训练时挂载的目标模块是否合理 |
| 命令跑完但没合并 | checkpoint 不是 swift 产出的,缺 args.json | 手动加--model指定基础模型 |
| 提示输出目录已存在 | 目录里已有旧产物 | 加--exist_ok true覆盖,或换一个--output_dir |
上线前核对清单
- 用同一组 prompt 分别跑合并前(带适配器)和合并后的模型,回答一致
- 检查产物目录:config.json、tokenizer 文件、safetensors 分片齐全
- 原始适配器和基础模型都保留不删,方便回退重合并
- 给合并产物打版本标记(如 merged-v1),别只留一个 checkpoint 路径
- 把这条 export 命令写进发布流程,下次能原样重放
合并、验证、打标记都完成,这个模型就可以进你的部署流水线了。遇到问题先看官方文档的 Export-and-push 章节,仍复现不了就去仓库提 issue,附上完整命令和报错日志。
【免费下载链接】swiftUse PEFT or Full-parameter to CPT/SFT/DPO/GRPO 600+ LLMs (Qwen3.6, DeepSeek-V4, GLM-5.1, InternLM3, Llama4, ...) and 300+ MLLMs (Qwen3-VL, Qwen3-Omni, InternVL3.5, Ovis2.5, GLM4.5v, Gemma4, Llava, Phi4, ...) (AAAI 2025).项目地址: https://gitcode.com/GitHub_Trending/swift1/swift
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考