news 2026/4/17 21:18:01

Unsloth微调后模型如何保存与加载?看这篇就行

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Unsloth微调后模型如何保存与加载?看这篇就行

Unsloth微调后模型如何保存与加载?看这篇就行

微调完一个大模型,最常被问到的问题就是:训练好的模型怎么保存?保存后又该怎么加载使用?尤其是用 Unsloth 这种主打“快+省”的框架时,很多人发现——明明训练跑通了,但一到保存和加载环节就卡住:模型打不开、报错找不到权重、推理结果乱码、甚至连 tokenizer 都加载失败……别急,这不是你操作错了,而是 Unsloth 的保存加载逻辑和标准 Hugging Face 流程有关键差异。

这篇文章不讲原理、不堆参数,只聚焦一件事:手把手带你把 Unsloth 微调后的模型,稳稳当当地存下来,再清清楚楚地加载回来,还能直接跑推理。全程基于真实命令、可复制代码、常见报错解析,小白照着做就能成功。

1. 为什么 Unsloth 的保存加载不能照搬 Hugging Face?

先说结论:Unsloth 默认不生成标准的pytorch_model.binconfig.json,它走的是自己的高效序列化路径。如果你直接用AutoModel.from_pretrained("your_output_dir")去加载 Unsloth 保存的模型,90% 的概率会报错:

  • OSError: Can't load config for 'xxx'. Make sure the config file is in the correct format.
  • KeyError: 'model.layers.0.self_attn.q_proj.weight'
  • 或者加载成功但推理输出全是乱码、空字符串、重复 token

原因很简单:Unsloth 在训练中做了大量底层优化(比如 fused kernels、4-bit 量化嵌入、自定义 attention 实现),这些优化无法被原生transformers库直接识别。它保存的不是“通用格式”,而是“自己能读、别人难懂”的紧凑结构。

所以,保存必须用 Unsloth 的方式,加载也必须用 Unsloth 的方式。记住这个铁律,后面所有步骤都围绕它展开。

2. 正确保存:两步到位,不漏任何文件

Unsloth 提供了两种保存方式,推荐使用model.save_pretrained()+tokenizer.save_pretrained()组合。这是最稳妥、兼容性最好、后续迁移最方便的方式。

2.1 保存前的关键准备

确保你的训练脚本末尾包含以下三行(这是很多教程遗漏但极其关键的一步):

# 确保模型处于评估模式(避免 dropout 等影响推理) model.eval() # 强制将 LoRA 权重合并进基础模型(可选,但强烈建议) model = model.merge_and_unload() # 保存模型和分词器 model.save_pretrained("output/unsloth_finetuned") tokenizer.save_pretrained("output/unsloth_finetuned")

为什么必须merge_and_unload()
Unsloth 默认以 LoRA 形式微调,即只训练少量适配层,原始大模型权重保持冻结。如果不合并,保存下来的只是一个“带补丁的壳”,加载时必须同时加载基础模型 + LoRA 适配器 + PEFT 配置,极易出错。而merge_and_unload()会把 LoRA 的增量更新物理写入到原始权重中,生成一个“开箱即用”的完整模型,体积略大但绝对稳定、零依赖。

2.2 完整保存示例(含注释)

下面是一段可直接运行的保存代码,整合在训练脚本末尾:

# ====== 训练结束后,执行保存 ====== if __name__ == "__main__": # 1. 切换为评估模式(关闭 dropout/batch norm 更新) model.eval() # 2. 合并 LoRA 权重(核心!) # 注意:这一步会消耗显存,确保 GPU 有足够空间 model = model.merge_and_unload() # 3. 创建保存目录(自动创建) save_directory = "output/unsloth_qwen2_05b_huanhuan" os.makedirs(save_directory, exist_ok=True) # 4. 保存模型(Unsloth 专用方法) model.save_pretrained( save_directory, save_method="merged_16bit", # 保存为 16-bit 合并权重,平衡精度与体积 # save_method="lora" # 若想保留 LoRA 结构,用此选项(不推荐新手) ) # 5. 保存分词器(必须!且必须和模型一起保存) tokenizer.save_pretrained(save_directory) print(f" 模型已成功保存至:{save_directory}") print(f" 目录内应包含:config.json, pytorch_model.bin, tokenizer_config.json, tokenizer.model 等文件")

保存成功后,你的output/unsloth_qwen2_05b_huanhuan目录里应该有这些文件:

文件名说明
config.json模型结构配置,Unsloth 已自动适配
pytorch_model.bin合并后的 16-bit 权重文件(核心!)
tokenizer_config.json分词器配置
tokenizer.model分词器模型文件(如 sentencepiece)
special_tokens_map.json特殊 token 映射(如 `<

常见错误排查

  • 报错RuntimeError: merge_and_unload() failed→ GPU 显存不足。解决方案:先del model清理内存,或改用save_method="lora"保存(但加载更复杂)。
  • 保存后没有pytorch_model.bin→ 检查是否漏掉model.save_pretrained(),或误用了trainer.save_model()(这是 Hugging Face 的,对 Unsloth 不适用)。

3. 正确加载:三行代码,零配置启动

加载比保存更简单,但必须用 Unsloth 提供的FastLanguageModel.from_pretrained(),而不是AutoModel.from_pretrained()

3.1 加载代码(极简版)

from unsloth import FastLanguageModel # 一行加载模型 + 分词器(自动识别保存格式) model, tokenizer = FastLanguageModel.from_pretrained( model_name = "output/unsloth_qwen2_05b_huanhuan", max_seq_length = 384, # 必须和训练时一致! dtype = None, # 自动推断,一般不用设 load_in_4bit = False, # 因为已合并为 16-bit,设为 False ) # 可选:启用推理加速(Unsloth 特有) FastLanguageModel.for_inference(model)

就这么三行,模型和分词器就 ready 了。不需要手动AutoTokenizer.from_pretrained(),也不需要AutoModelForCausalLM—— Unsloth 全包了。

3.2 完整推理示例(验证加载是否成功)

加载后立刻跑个推理,确认一切正常:

# 构造一个测试 prompt(注意:必须用训练时的相同模板!) prompt = """<|im_start|>system 现在你要扮演皇帝身边的女人--甄嬛<|im_end|> <|im_start|>user 皇上今日气色不佳,可是朝中出了什么事?<|im_end|> <|im_start|>assistant """ # 编码输入 inputs = tokenizer(prompt, return_tensors="pt").to("cuda") # 生成回答 outputs = model.generate( **inputs, max_new_tokens = 128, use_cache = True, temperature = 0.7, top_p = 0.9, ) response = tokenizer.decode(outputs[0], skip_special_tokens=True) print(" Prompt:") print(prompt) print("\n 模型回答:") print(response.split("<|im_start|>assistant")[-1].strip())

如果看到类似这样的输出,说明加载完全成功:

“皇上今日气色不佳,可是朝中出了什么事?”
“回皇上,臣妾观您眉间微蹙,似有心事。莫非是西北军报未至,抑或户部银钱调度不畅?”

3.3 加载时的三个必填参数(新手最容易错)

参数必须设置?为什么重要常见错误
model_name指向你保存的目录路径,不能是模型ID(如 "Qwen2.5-0.5B-Instruct")写成"Qwen2.5-0.5B-Instruct"→ 找不到本地文件
max_seq_length必须和训练时FastLanguageModel.from_pretrained(..., max_seq_length=384)的值完全一致训练用 384,加载写 512 → 报错sequence length mismatch
load_in_4bit训练时若用了load_in_4bit=True,这里也要设True;但如果你执行了merge_and_unload(),则必须设False合并后还设True→ 加载失败

小技巧:如何快速确认训练时的max_seq_length
查看你训练脚本中FastLanguageModel.from_pretrained()这一行,或者打开保存目录下的config.json,搜索"max_position_embeddings"字段,它的值就是你需要的max_seq_length

4. 进阶场景:如何保存/加载 LoRA 适配器(不合并)?

虽然推荐合并保存,但有些场景你确实需要保留 LoRA 结构,比如:

  • 想在多个任务上复用同一个基础模型,只切换不同 LoRA 适配器;
  • 模型太大,合并后显存爆满,只能边加载边合并;
  • 需要后续继续微调(LoRA 支持增量训练)。

4.1 保存 LoRA 适配器(不合并)

# 训练完成后,不 merge,直接保存 LoRA model.save_pretrained( "output/unsloth_lora_huanhuan", save_method = "lora", # 关键!指定保存为 LoRA 格式 ) tokenizer.save_pretrained("output/unsloth_lora_huanhuan")

此时目录下不会生成pytorch_model.bin,而是:

  • adapter_model.bin(LoRA 权重)
  • adapter_config.json(LoRA 配置)
  • non_lora_trainables.bin(如果有额外训练的非 LoRA 参数)

4.2 加载 LoRA 适配器(需两步)

from unsloth import FastLanguageModel from peft import PeftModel # 第一步:加载基础模型(必须是原始模型,不是你微调的目录!) base_model_path = "/root/autodl-tmp/qwen/Qwen2.5-0.5B-Instruct" model, tokenizer = FastLanguageModel.from_pretrained( model_name = base_model_path, max_seq_length = 384, load_in_4bit = True, # 基础模型加载方式 ) # 第二步:用 PEFT 加载 LoRA 适配器(注意:这里用的是标准 PEFT API) model = PeftModel.from_pretrained( model, "output/unsloth_lora_huanhuan", device_map = "auto" ) # 可选:合并进内存(不写入磁盘,仅用于当前推理) model = model.merge_and_unload()

注意:这种方式加载更慢、依赖更多、出错率更高,仅建议高级用户或特定需求时使用。

5. 常见问题速查表(5分钟定位故障)

问题现象最可能原因一句话解决
OSError: Can't load config for 'xxx'用了AutoModel.from_pretrained()加载 Unsloth 模型改用FastLanguageModel.from_pretrained()
加载成功但推理输出为空/乱码分词器没加载,或skip_special_tokens=False确保tokenizer.save_pretrained()且解码时加skip_special_tokens=True
ValueError: max_seq_length must be <= 384加载时max_seq_length小于训练值config.jsonmax_position_embeddings,设为相等值
CUDA out of memorymerge_and_unload()GPU 显存不足del model,或改用save_method="lora"
保存后目录里只有adapter_model.bin,没有pytorch_model.bin忘记merge_and_unload()save_method="lora"检查保存代码,确认save_method="merged_16bit"且调用了merge_and_unload()
推理结果和训练时差异很大Prompt 模板不一致(如少写了 `<im_start

6. 总结:记住这三条铁律

微调只是开始,保存和加载才是交付的关键。对 Unsloth 而言,只需牢记这三点,就能避开 95% 的坑:

6.1 保存铁律

必须merge_and_unload()+model.save_pretrained(..., save_method="merged_16bit")+tokenizer.save_pretrained()
三者缺一不可。不要图省事跳过合并,也不要混用 Hugging Face 的保存方法。

6.2 加载铁律

必须FastLanguageModel.from_pretrained(),且max_seq_length必须和训练时完全一致。
把它当成密码——输错一位,门就打不开。

6.3 验证铁律

加载后第一件事:用训练时完全相同的 prompt 模板跑一次推理。
不看日志,不看参数,只看输出是否合理、是否连贯、是否符合预期。这是唯一真实的验收标准。

做到这三点,你的 Unsloth 模型就真正“活”起来了——不再是训练日志里的一串数字,而是可以部署、可以集成、可以创造价值的 AI 能力。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 9:50:59

游戏开发必看:Visual C++ Redistributable实战指南

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个Unity游戏项目示例&#xff0c;演示如何正确打包和部署Visual C Redistributable依赖。包含自动检测系统环境、静默安装必要组件、错误处理等功能。项目要展示如何在Unity…

作者头像 李华
网站建设 2026/4/18 9:45:53

1小时打造定制串口助手:基于快马平台实战

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 在InsCode平台快速开发一个可扩展的串口助手原型&#xff0c;要求&#xff1a;1. 基础收发功能 2. 插件式架构设计 3. 蓝牙/WIFI扩展接口 4. 最小化UI布局 5. 支持功能模块热加载。…

作者头像 李华
网站建设 2026/4/18 7:03:26

好写作AI论文润色实测:你的文本能“升值”多少?

朋友们&#xff0c;是不是经常觉得自己的论文写出来像“学术草稿”&#xff0c;离“导师点赞”总差一口气&#xff1f;今天我们不谈虚的&#xff0c;直接上硬核测评&#xff1a;用好写作AI修改润色&#xff0c;你的文本究竟能“升值”几个level&#xff1f;好写作AI官方网址&am…

作者头像 李华
网站建设 2026/4/17 14:13:52

零基础教程:5分钟学会用AI DRAW.IO画流程图

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 新手友好提示&#xff1a;教我画一个简单的用户登录流程图&#xff0c;包含成功和失败路径。 AI DRAW.IO将分步引导完成&#xff0c;自动推荐图形、布局&#xff0c;并提供实时修正…

作者头像 李华
网站建设 2026/4/18 9:43:37

10分钟用AI打造数据库连接工具原型

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 快速生成一个数据库连接工具原型&#xff0c;要求&#xff1a;1. 使用Python Flask开发Web界面&#xff1b;2. 支持MySQL连接配置和测试&#xff1b;3. 提供简单的表数据查看功能。…

作者头像 李华
网站建设 2026/4/18 7:37:00

颠覆传统硬件控制逻辑:GHelper引发笔记本效率革命

颠覆传统硬件控制逻辑&#xff1a;GHelper引发笔记本效率革命 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops. Control tool for ROG Zephyrus G14, G15, G16, M16, Flow X13, Flow X16, TUF, Strix, Scar and other models 项目地址: h…

作者头像 李华