微调后如何加载?Qwen2.5-7B Adapter使用教程
1. 你不是在“部署模型”,而是在“唤醒一个新身份”
1.1 这篇教程能帮你解决什么问题?
如果你已经用镜像完成了 Qwen2.5-7B 的 LoRA 微调,但卡在最后一步——不知道怎么把训练好的 Adapter 加载进模型里,让模型真正“记住”你是谁、为谁服务,那这篇就是为你写的。
它不讲原理推导,不堆参数说明,只聚焦一个动作:如何正确加载微调产出的 Adapter 权重,并验证它是否生效。你会学到:
- 微调产物长什么样、存在哪、怎么找
swift infer命令中--adapters参数的真实含义和写法- 为什么直接改路径会报错、怎么避免“文件找不到”或“权重不匹配”
- 如何用最简对话快速验证身份是否成功注入
- 一个可复用的加载脚本模板(含错误排查提示)
全程基于单卡 RTX 4090D 环境实测,命令可直接复制粘贴运行。
1.2 你需要提前确认三件事
别急着敲命令,先花30秒确认以下状态:
- 微调已成功结束:终端最后出现类似
Saving checkpoint to output/v2-20250412-1532/checkpoint-500的日志 - 当前工作目录是
/root:执行pwd应输出/root,否则所有路径都会失效 - 原始模型未被移动或删除:
/root/Qwen2.5-7B-Instruct目录必须完整存在
如果其中任一条件不满足,请先回到微调步骤检查,否则后续加载必然失败。
2. 理解微调产物:Adapter 不是“新模型”,而是“附加补丁”
2.1 它到底是什么?用修车来比喻
想象 Qwen2.5-7B 是一辆出厂设定为“阿里云助手”的汽车。LoRA 微调不是给你换了一台新车,而是给你发了一张可插拔的智能控制卡——它不改变原车发动机(基础模型权重),只在关键电路(线性层)上叠加微小的电流调节信号(LoRA A/B 矩阵),让车在启动时自动播报:“我是 CSDN 迪菲赫尔曼 开发的 Swift-Robot”。
这张“控制卡”就存放在/root/output/下,它本身不能单独运行,必须和原车(基础模型)配合使用。
2.2 文件结构长这样(真实截图级还原)
进入/root/output目录后,你会看到类似结构:
/root/output/ ├── v2-20250412-1532/ # 时间戳命名的训练任务目录 │ ├── checkpoint-50/ # 第50步保存的中间检查点 │ ├── checkpoint-100/ # 第100步 │ ├── checkpoint-500/ # 最终保存点(通常是你需要的) │ └── adapter_config.json # LoRA 配置文件(关键!) ├── v2-20250413-0921/ # 另一次训练的目录(可能有多个) └── latest/ # 符号链接,指向最新一次训练的最终 checkpoint重点看
adapter_config.json:打开它,你会看到"target_modules": ["all-linear"]和"r": 8等字段——这证明该目录确实是 LoRA 权重,不是全量微调结果。
2.3 为什么不能直接用--model /root/output/xxx?
因为--model参数只认完整模型目录(含config.json,model.safetensors,tokenizer.*等)。而 Adapter 目录里只有adapter_model.safetensors和配置文件,缺少模型骨架。强行指定会导致报错:
OSError: Can't find config.json or pytorch_model.bin in /root/output/v2-20250412-1532/checkpoint-500正确做法:基础模型路径 + Adapter 路径 分开指定。
3. 加载 Adapter 的三种可靠方式(附避坑指南)
3.1 方式一:命令行直接加载(推荐新手)
这是最直观、最不易出错的方式,适合快速验证。
正确命令(请严格按格式复制)
cd /root CUDA_VISIBLE_DEVICES=0 \ swift infer \ --model Qwen2.5-7B-Instruct \ --adapters output/v2-20250412-1532/checkpoint-500 \ --model_type qwen \ --stream true \ --temperature 0 \ --max_new_tokens 2048关键细节说明(90% 的失败源于这里)
| 项目 | 正确写法 | 常见错误 | 后果 |
|---|---|---|---|
--model值 | Qwen2.5-7B-Instruct(纯文件夹名) | /root/Qwen2.5-7B-Instruct或./Qwen2.5-7B-Instruct | 报错Model not found |
--adapters值 | output/v2-.../checkpoint-500(相对路径,从/root开始) | ./output/...或/root/output/... | 报错Adapter path not found |
| 工作目录 | 必须是/root | 在/root/output下执行 | --model找不到基础模型 |
验证技巧:运行后输入你是谁?,若回答中包含“CSDN 迪菲赫尔曼”,说明加载成功;若仍是“阿里云开发的”,请检查--adapters路径是否拼写错误。
3.2 方式二:Python 脚本加载(适合集成到应用)
当你需要把微调后的模型嵌入自己的 Python 服务时,用代码加载更可控。
可运行脚本(保存为load_adapter.py)
from swift.llm import get_model_tokenizer, get_template, inference from swift.utils import seed_everything # 1. 加载基础模型和分词器(不加载权重到GPU) model, tokenizer = get_model_tokenizer( 'Qwen2.5-7B-Instruct', # 模型ID,对应 /root/Qwen2.5-7B-Instruct model_kwargs={'device_map': 'auto', 'torch_dtype': 'bfloat16'} ) # 2. 加载Adapter(关键:指定adapter_dir) model = get_model_tokenizer( 'Qwen2.5-7B-Instruct', model_kwargs={ 'device_map': 'auto', 'torch_dtype': 'bfloat16', 'adapter_dir': '/root/output/v2-20250412-1532/checkpoint-500' # 绝对路径! } )[0] # 3. 获取对话模板 template = get_template('qwen', tokenizer) # 4. 执行推理 response = inference( model, template, '你是谁?', stream=False, temperature=0.0 ) print("模型回答:", response)注意事项
adapter_dir必须用绝对路径(以/root/开头),相对路径会失败- 脚本需在
/root目录下运行(python load_adapter.py) - 若报错
KeyError: 'lora_A',说明adapter_dir指向了空目录或非 LoRA 目录,请检查adapter_config.json是否存在
3.3 方式三:合并权重后加载(适合长期部署)
如果你希望彻底告别“基础模型+Adapter”的双路径依赖,可以将 LoRA 权重永久融合进基础模型,生成一个独立的新模型。
合并命令(生成新模型目录)
cd /root # 将Adapter权重合并到基础模型,输出到 merged_model/ swift export \ --model Qwen2.5-7B-Instruct \ --adapters output/v2-20250412-1532/checkpoint-500 \ --merge True \ --output_dir merged_model执行完成后,/root/merged_model就是一个完整的、带新身份的模型目录,可直接用标准方式加载:
swift infer --model merged_model --model_type qwen优势:部署简单,无额外依赖
注意:合并后显存占用会上升(约24GB),且无法再切换其他 Adapter。
4. 常见加载失败原因与速查表
4.1 典型报错及解决方案
| 报错信息 | 根本原因 | 一行修复命令 |
|---|---|---|
OSError: Can't find adapter_config.json | --adapters路径下没有该文件 | ls -l /root/output/v2-.../checkpoint-500/adapter_config.json确认存在 |
ValueError: Expected state_dict to contain ... | Adapter 与基础模型版本不匹配 | 重新运行微调命令,确保--model和微调时完全一致 |
RuntimeError: expected scalar type BFloat16 but found Float16 | 推理时精度与微调时不一致 | 在swift infer中添加--torch_dtype bfloat16 |
CUDA out of memory | 单卡显存不足(尤其合并后) | 改用--torch_dtype float16或升级到 32GB 显存卡 |
4.2 三步自检清单(1分钟搞定)
遇到问题时,按顺序执行:
- 查路径:
ls -l /root/output/v2-*/checkpoint-*确认目录存在且非空 - 查配置:
cat /root/output/v2-*/checkpoint-500/adapter_config.json \| head -5看是否含"peft_type": "LORA" - 查环境:
nvidia-smi确认 GPU 可用,pwd确认在/root
提示:所有路径都以
/root为根。镜像内一切设计都围绕这个前提,偏离即失败。
5. 加载后的效果验证与进阶用法
5.1 不止于“你是谁?”——多维度验证身份注入
不要只问一个问题。用这组测试题全面检验:
| 测试问题 | 期望回答特征 | 为什么重要 |
|---|---|---|
| “你的开发者是谁?” | 必须出现CSDN 迪菲赫尔曼(非“阿里云”、“通义实验室”) | 核心身份识别 |
| “你能联网吗?” | 回答应与self_cognition.json中完全一致(如“不能主动联网”) | 记忆准确性 |
| “请用英文介绍自己” | 仍需体现开发者信息(验证多语言泛化) | 能力保持性 |
| “写一段Python代码” | 代码质量不应下降(验证通用能力未退化) | 微调鲁棒性 |
如果前3题全部命中,第4题基本正常,说明 Adapter 加载成功且效果稳定。
5.2 加载后还能动态切换身份吗?
可以。只需在同一个swift infer会话中,用Ctrl+C退出,然后修改--adapters参数指向另一个 checkpoint 目录,重新运行即可。例如:
# 切换到另一个微调任务 --adapters output/v2-20250413-0921/checkpoint-300这正是 LoRA 的核心优势:轻量、可插拔、零成本切换。
5.3 生产环境建议:用符号链接管理版本
为避免每次都要写长长的时间戳路径,创建软链接:
cd /root ln -sf output/v2-20250412-1532/checkpoint-500 current_adapter之后加载命令简化为:
swift infer --model Qwen2.5-7B-Instruct --adapters current_adapter当需要更新时,只需rm current_adapter && ln -sf ...,服务无需重启。
6. 总结
6.1 你已掌握的核心能力
- 识别微调产物:知道
output/xxx/checkpoint-yyy是什么、在哪里、怎么确认有效性 - 三种加载方式:命令行(快验)、Python(集成)、合并(部署),按需选用
- 避坑实战经验:路径写法、精度匹配、环境校验,省去90%调试时间
- 效果验证方法:不止看一句回答,而是用多维度测试题建立信心
6.2 下一步你可以做什么?
- 将
current_adapter链接接入你的 Web 服务(FastAPI/Gradio),对外提供定制化 API - 用
swift export合并权重,打包成 Docker 镜像交付给团队 - 尝试混合数据微调(如
alpaca-gpt4-data-zh + self_cognition.json),让模型既专业又个性 - 探索更多 LoRA 配置:调整
lora_rank(8→16 提升表达力)、target_modules(只微调 attention 层更轻量)
微调的价值不在过程,而在加载后的那一声“我是 CSDN 迪菲赫尔曼 开发的 Swift-Robot”。现在,你已经拿到了唤醒它的钥匙。
--- > **获取更多AI镜像** > > 想探索更多AI镜像和应用场景?访问 [CSDN星图镜像广场](https://ai.csdn.net/?utm_source=mirror_blog_end),提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。