swift 模型合并实战指南:一条 export 命令,把 LoRA checkpoint 变成可上线的完整模型
【免费下载链接】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
用 swift(魔搭社区的大模型训练推理工具箱)做 LoRA 微调后,产出的是一个几 MB 的 adapter 目录,直接上线还要在推理端动态加载,既慢又挑框架。swift 模型合并能解决这个问题:一条swift export --merge_lora true命令,把 LoRA 权重融合进基础模型,产出一个独立、可直接被 vLLM 等引擎加载的完整模型。下面按"合并前检查 → 执行融合 → 验证部署"的顺序走完整个流程。
从 checkpoint 到可部署模型,中间差了什么
一次 swift LoRA 训练结束,output/vx-xxx/checkpoint-xxx目录里通常有两类东西:adapter 权重文件和一份args.json(记录训练时的全部参数)。前者是"增量",后者是"说明书"。
合并的价值在于:
- 推理不再需要挂 adapter,请求处理路径更短,延迟更低
- 产出的就是标准 Hugging Face 权重目录,vLLM、SGLang、lmdeploy 这类推理框架原生支持
- 单个模型目录便于分发、备份和版本管理
合并前:先确认 checkpoint 里有没有"说明书"
swift export 的关键机制是自动读参:当指定了--adapters或--model指向一个本地 checkpoint 目录时,swift/arguments/base_args/base_args.py 中的load_args_from_ckpt会加载该目录下的args.json,把基础模型 ID、模板、量化配置等字段回填进当前参数。所以只要你的 checkpoint 是用 swift 训练出来的,就不需要手动写--model:
- 有
args.json→ 什么都不用多说,只给--adapters - 没有
args.json(旧版本或第三方产物)→ 必须显式补--model Qwen/Qwen2.5-7B-Instruct之类的基础模型参数,否则会在断言处直接报错
硬件方面,合并过程需要把基础模型完整加载进内存并做矩阵融合,7B 级模型建议留足 24GB 显存或直接用--device_map cpu走 CPU(配合 examples/export/quantize/awq.sh 的做法)。
一条命令完成权重融合
仓库自带的官方示例 examples/export/merge_lora.sh 只有三行:
swift export \ --adapters output/vx-xxx/checkpoint-xxx \ --merge_lora true如果不写--output_dir,输出目录默认取"checkpoint 同级目录 +checkpoint-xxx-merged"后缀(规则见 swift/arguments/export_args.py 的_init_output_dir);且默认用 safetensors 分片保存,单片上限由--max_shard_size控制(默认 5GB)。
权重融合的数学很直白,每个挂了 LoRA 的线性层执行一次低秩增量叠加:
# 对每个融合层: weight = weight + (B @ A) * (lora_alpha / r)代码入口在 swift/pipelines/export/merge_lora.py:prepare_model_template加载基础模型和 adapter,Swift.merge_and_unload执行上面的叠加并卸载 adapter,最后save_checkpoint写出config.json、分片权重和 tokenizer 文件。
进阶用法:多适配器、合并即量化、直接推 Hub
- 🔀多适配器融合:
--adapters可以传多个 checkpoint 路径,swift 会依次把每份 adapter 叠加到基础权重上;每个适配器的"音量"由其训练时的lora_alpha / rank缩放因子决定,不同任务的结果可以这样混入同一个模型 - 📦合并即量化:同一条命令追加
--quant_method和--quant_bits即可,方法支持awq / gptq / gptq_v2 / bnb / fp8,位宽取 4 或 8。注意awq、gptq需要校准数据(--dataset xxx#N),bnb、fp8则不需要。实现细节是先在未量化的原始权重上完成合并、落盘后再做量化,避免量化状态下融合失真
swift export \ --adapters output/vx-xxx/checkpoint-xxx \ --merge_lora true \ --quant_method awq \ --quant_bits 4 \ --dataset 'AI-ModelScope/alpaca-gpt4-data-zh#500'- 🚚来源与推送:
--use_hf true控制基础模型从 Hugging Face 而非 ModelScope 拉取;加--push_to_hub true --hub_model_id 'user/repo'可把合并结果直接推到对应 Hub(参考 docs/source/Instruction/Export-and-push.md) - 🐳导出 Ollama:
--to_ollama true会顺带生成 Modelfile(见 examples/export/ollama.sh)
合并后:先验一致性,再上 vLLM 部署
🔬一致性验证:对合并前后的模型各问一次同样的问题,输出应当一致(采样参数记得固定temperature 0或同一seed):
# 合并前:基础模型 + adapter swift infer --model Qwen/Qwen2.5-7B-Instruct \ --adapters output/vx-xxx/checkpoint-xxx --stream false # 合并后:只给新目录 swift infer --model ./output/vx-xxx/checkpoint-xxx-merged --stream false🩹常见报错定位:
| 现象 | 大概率原因 | 处理 |
|---|---|---|
| OOM | 基础模型装不下显存 | --device_map cpu或auto拆分到多卡 |
断言args_path: ... args.json不存在 | checkpoint 不是 swift 生成的 | 手动补--model <基础模型> |
output_dir already exists | 目标目录已存在 | 换个--output_dir或加--exist_ok true覆盖 |
🚀上推理引擎:验证通过后,把合并目录交给 vLLM 即可(仓库示例 examples/deploy/vllm.sh 展示的是 swift deploy 方式,也可直接起 vLLM 服务):
swift deploy \ --model ./output/vx-xxx/checkpoint-xxx-merged \ --infer_backend vllm \ --served_model_name qwen2.5-merged更完整的参数说明见 docs/source/Instruction/Export-and-push.md 和 docs/source/Instruction/Inference-and-deployment.md。
现在就动手
回到你的训练输出目录,确认checkpoint-xxx里有args.json,然后执行开头那条三行命令。跑完先看输出目录是否生成了完整的config.json与 safetensors 分片,再做一次前后推理对比——十分钟内,你的 adapter 就能变成一个可以直接部署的完整模型。
【免费下载链接】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),仅供参考