不小心吹个牛
一两个月前,我对大模型还比较迷信。觉得这模型真厉害,平时遇到啥问题,问它都可以回答个八九不离十。
遂心向往之~
后来也看到有UP主分享:“现在不流行训练自己的小模型了!真实项目中往往都是使用开源大模型+行业数据。”
-
同事问我:“元芳,你怎么看?”
-
我回答他,“耳听为虚,眼见为实。我要微调个自己的小模型看看。”
然后,就拖到了现在。。。
本文会分享以下内容:
- 模型训练工具介绍(LLaMA-Factory)
- 在Transformer 架构下模型训练算法(本次使用微调 LoRA)
- 从0 开始,0花费地训练一套小模型出来
- 讨论什么场景下 更适合微调模型
效果展示
咱们老规矩,还是先上效果图——

这个模型的用途是:用户输入任意新闻标题后,它可以进行类型标注。
例如,下面这两个新闻:
用户提问:“新闻分类:真相了?外媒:特朗普想在伊朗“更迭政权””
AI 回答:“国际”
用户提问:“新闻分类:许昕发文感谢队友?从陪练张继科到世界冠军!称霸世界的国乒!”
AI 回答:“体育”
这里的训练数据需要提前准备,格式上是这样的——
可以看出:“人类输入的内容” + “AI回答的内容” 这样一问一答作为一条训练数据。
本次训练集由300条这样的问答对组成。
我们的预期则是:
用户输入问题A –> “训练后的模型” –> 回答最合适的新闻类型(如:科技、体育、政治。。。)
训练后的模型输出,越接近训练集的结果,就认为这个模型越符合预期。反之,效果就一般。
后续模型测试中会看到,训练不成功的效果长什么样。
下面介绍下 训练AI模型使用到的工具:LLaMA-Factory。
它是模型训练工具的一种,适合初学者(无需编写代码)快速上手操作。也是一个开源项目,官方介绍如下:
模型训练基础
如果了解并熟悉Transformer架构和 LoRA算法 或者 希望先上手微调训练,可以跳过本部分,查看后续操作步骤。
有三点关键内容需要提前了解下:基座模型,微调方法以及训练参数。不然,后面的操作过程中会有点懵。。。
1. 基座模型
先说 “基座”,顾名思义就是我们的训练是基于一个“底座”的。不是完完全全从0 开始训练一个新模型。
因为训练这个模型的目的只是希望加强它在某一领域的知识和能力,不是取代现有大模型的通用能力。
所以,这个基座模型一般会选择开源模型中效果和开销比较平衡的。
比如这里使用的 DeepSeek-R1-Distill-Qwen-7B ,实测效果比 小规模的DeepSeek-R1-Distill-Qwen-1.5B 好不少。
Q:关于这个名字,怎么既有 DeepSeek又有 Qwen?这么长一串到底啥意思?
A: 这里涉及到开源大模型的命名规范: 机构名/产品系列+技术和知识来源+规模。以“DeepSeek-R1-Distill-Qwen-7B” 为例。分为三个部分:
- DeepSeek-R1:DeepSeek 下的推理模型(慢思考,善于处理复杂逻辑内容)
- Distill-Qwen:通过蒸馏(distillation) 通义干问 Qwen2.5 的通用知识
- 7B:模型参数量70 亿
它结合了 DeepSeek-R1的推理能力 + qwen 的通用知识,资源消耗也不大。
这里我们只关心,相关“行业数据”(新闻)的输出效果。而其他方面的能力在训练后可能会变弱,例如计算能力,写作能力等。
2. 微调方法(LoRA)
这块涉及到 Transformer 架构下的数学矩阵计算:
1)模型参数被转化为了数字向量
2)向量的值是一个范围巨大的矩阵。为了方便理解这里以 100*100 的矩阵(全秩矩阵),表示原先的 模型参数量。
3)问题来了:如果按照传统的训练微调(全参数微调)方式,就要训练全秩矩阵中每一个(10000)的值,工程量大 控制起来也复杂。
有人就想出个优化的办法:通过两个小矩阵相乘 [ 100 * 2 ] * [ 2 *100 ] 可以填充全秩矩阵(100 * 100)的每个单元。
所以,LoRA(Low-Rank Adaptation of Large Language Models)方法就是精简训练上图 A B两个小矩阵。
与LoRA 类似的训练小参方法,还有 QLoRA、Adapter、P-Tuning。简单了解一下——

3. 训练参数
先看一眼基本的训练参数:

常用来调整的参数 加粗表示下。
- 训练阶段(stage):常用 SFT(Supervised Fine-Tuning)有监督微调,不常用 DPO(Direct Preference Optimization)和 PPO(Proximal Policy Optimization)
- 学习率(Learning Rate):决定了模型每次更新时权重改变的幅度。过大可能会错过最优解;过小会学得很慢或陷入局部最优解
- 训练轮数(Epochs):太少模型会欠拟合(没学好),太大会过拟合(学过头了)
- 最大梯度范数(Max Gradient Norm):当梯度的值超过这个范围时会被截断,防止梯度爆炸现象
- 最大样本数(Max Samples):每轮训练中最多使用的样本数
- 计算类型(Computation Type):在训练时使用的数据类型,常见的有 float32 和float16。在性能和精度之间找平衡
- 截断长度(Truncation Length):处理长文本时如果太长超过这个阈值的部分会被截断掉,避免内存溢出
- 批处理大小(Batch Size):由于内存限制,每轮训练我们要将训练集数据分批次送进去,这个批次大小就是 Batch Size
- 梯度累积(Gradient Accumulation):默认情况下模型会在每个 batch 处理完后进行一次更新一个参数,但你可以通过设置这个梯度累计,让他直到处理完多个小批次的数据后才进行一次更新
- 验证集比例(Validation Set Proportion):数据集分为训练集和验证集两个部分,训练集用来学习训练,验证集用来验证学习效果如何
- 学习率调节器(Learning Rate Scheduler):在训练的过程中帮你自动调整优化学习率页面上点击启动训练,或复制命令到终端启动训练
好了,铺垫了这么多。终于可以动手操作了。
模型微调实操
下面就是从0 开始,一步一步 微调我们需要的模型。
相关测试数据和训练后的模型,我放在公众号 【AI 热气球】中,感兴趣的话可以回复1117 获取。
0. 环境准备
既然是训练自然少不了显卡的加速,通常有三种方式:使用大模型提供商的在线微调服务、租用云平台的机器、本地自集成部署。
数据安全方面考虑: 本地自集成部署 > 租用云平台的机器 > 大模型提供商的在线微调服务
成本开销方面考虑: 本地自集成部署 > 租用云平台的机器 > 大模型提供商的在线微调服务
这么一看,优先选择“租用云平台的机器”完成小模型的训练和微调。毕竟我们这里数据不多,一次训练大约1小时左右。
而且,用到的平台“魔塔” 为新用户提供36小时 带24g显卡云主机的使用优惠,还是很划算的。
-
申请并创建个人魔塔账号(https://modelscope.cn/home),过程中需要登录阿里云帐号。
-
在“我的 Notebook” (https://modelscope.cn/home) 中启动GPU主机—— 版本选择 Ubuntu 22.04 的就行。
-
点击“查看 Notebook”,进入控制台界面后,点击 “插件”按钮搜索并安装中文语言包。
-
检查显卡工作正常
|
|
1. llama-factory 工具安装
因为是在云平台上训练模型,云主机关机后除了个人工作目录 /mnt/workspace 下的数据都会被清空、还原。
所以,后续相关操作(安装包下载 测试数据上传 训练模型合并、下载)都是在 /mnt/workspace 这个目录下 。
另外,也为了llama-factory 环境运行依赖的 python 包之间不会冲突。一般建议使用conda 创建虚拟环境。
- 我们这里 使用更轻量、便捷的社区版 “Miniforge”创建虚拟环境 。
|
|

- 虚拟环境准备好后,正式进入 llama-factory 安装环节:
|
|
- 上述步骤完成,llama-factory 工具就安装好了。先查看下当期版本,后启动web界面
|
|

启动成功后,VSCode 会提示 打开一个http页面。
该页面映射刚启动的llama-factory web 服务(http://127.0.0.1:7860)。
- 打开网页,看到如下页面,表示 llama-factory 已经启动成功了。
2. 基座模型下载
这一步中,需要下载用到的基座模型 DeepSeek-R1-Distill-Qwen-7B 。
- 具体操作如下:
|
|
如果模型下载速度太慢的话:参考这篇文章<如何快速下载huggingface模型——全方法总结>
-
下载完成后, 在指定的目录 /mnt/workspace/Hugging-Face 中可以看到多出一个目录 叫“models–deepseek-ai–DeepSeek-R1-Distill-Qwen-7B”这个就是刚才下载完成的模型。
然后,复制模型路径,稍候启动参数时需要指明模型具体位置。
|
|
3. 基座模型运行测试
先测试当前下载的模型加载、执行是否正常:
-
在已经打开的llama-factory 页面中,语言切换至“zh”,指定“模型名称”和“模型路径”。
-
然后点击“Chat” – > “加载模型”,提示加载成功后。输入用户 input,查看模型响应:

如上图,表示模型正常响应,可以继续操作。
4. 上传训练数据
训练数据格式有展示过,这里有两个数据文件+配置文件需要上传到 云主机上。
其中 train.json 为训练用数据,eval.json 为评估数据。dataset_info.json 为相关配置文件。

|
|
5. 微调模型
模型准备好了,训练数据也有了。"微调方法" 默认就是 lora。这里就可以开始调整微调参数了——
-
点击“Train” 界面,“训练阶段”中默认是SFT(有监督微调)不用修改。
“数据路径”和 “数据集”选择上一步中的训练数据集“train”。
-
修改微调相关参数,如:“学习率” -> 5e-4, “训练轮数” -> 10,“梯度累积” -> 4, “LoRA+ 学习率比例” -> 16, “LoRA 作用模块” -> “all”。
-
点击“开始”按钮,llama-factory 会加载模型和训练数据 进行训练。
进行过程中,会有一副关于训练损失和训练步数的关系图。
不同训练参数和模型,其训练时长不等。这里 20轮训练下来 差不多25分钟左右。
训练期间 云主机 GPU 发力工作:
- 最终训练好的模型,输出在上面的“输出目录”中。后续可以基于此次训练结果,进行评估和测试。
6. 人工测试
回到 “Chat”界面,加载刚训练得到的模型检查点“train_2025-11-14-17-23-08”。
手动测试下新模型的效果——
测试两三次,感觉起来好像还行。模型微调的过程就告一段落了。
但到底新模型效果如何,还是需要数据说话——
新模型评估
我们之前不是准备了 评估数据集 “eval.json” 么,此时派上用场。
- 点击“Evaluate& Predict” 界面,“数据路径”和 “数据集”选择之前上传的数据集“eval”。
- 其他评估参数保持默认,点击“开始”按钮。
- 完成后,注意其中 “predict_rouge-1”的分数。这个分值越高,表明新模型生成质量越好。
上图中该值为 53.85——说明新模型生成的文本与评估数据(eval.json)在单词级别上有 53.85%的重合。
新模型导出
此时新训练出来的模型还在云主机上。我们怎么把它拖到本地呢?
1. 首先导出模型
点击“Export” 界面,“导出设备” -> auto,在“导出目录”中输入模型导出路径后,点击“开始导出”。

看到“模型导出完成”,代表成功导出了此次训练出来的新模型。
在云主机 VSCode界面中,也可以看到新模型有哪些文件组成——

但是,这些模型文件不能直接在本地使用 Ollama 调用。
我们需要用到第二个开源工具——llama.cpp。
2. 使用llama.cpp 工具
使用 llama.cpp 工具,可以将上述模型文件转为 一个 .gguf 格式的文件。
而后者,是可以在ollama 平台中加载、运行的。
与传统基于 Python 的 AI 框架(如 PyTorch/TensorFlow)不同,llama.cpp 选择回归底层语言C/C++的实现策略。这种设计使其摆脱了 Python 解释器、CUDA 驱动等重型依赖,通过静态编译生成单一可执行文件,在资源受限环境中展现出独特优势。
这里,同样在云主机中完成转换工作——
|
|
格式转换成功——
|
|
ollama 上运行新模型
-
下载 dsr1_1.5b_newstype.gguf 文件到本地目录,如 D:\download\export_models 中。
-
然后,创建一个名为 ModelFile 的配置文件。注意,该文件没有后缀名。
文件中内容如下:
|
|
- 确认本机 ollama 服务正在运行。执行以下命令完成 新模型的导入——
|
|
导入成功:

- 后续会很方便在 AI 应用中直接调用这个训练好的模型。
如今,为何不建议自己训练模型
我想有两方面原因:
-
现有模型80%~90% 是基于transformer架构的生成式AI,该架构下的AI响应结果严重依赖训练数据,因为模型自己是不会推理的。
而有用的小模型,需要行业大量的数据。如果数据不够,真实上线时,会放心交给模型自己去猜?
所以,在数据量不足的前提下,花时间、金钱去训练自己的模型是在找死。
但是,反过来说,如果自己的数据量充足,这个训练就很有意义了——一定场景下可以实现低成本和快速响应!
-
通用大模型的能力在快速迭代,他们获取数据的广度和成本不是 中小公司可以匹敌的。两者的维度不一样,存在跨维打击的可能。
每人希望看到:今天花了100W得到的模型 视为珍宝,明天就被通用模型超越变成黄花的局面。
除非,自己领域的数据市面上没有第二家。
所以,本质上要看行业数据的情况而定,如果样本足够多,样本足够稳定,才可以考虑微调训练自己的模型。
另外,在关于 微调和 RAG的对比上——
| 对比维度 | 模型微调 | RAG |
|---|---|---|
| 核心逻辑 | 让模型学会新知识或技能,改变其内部参数 | 为模型提供外部知识,利用其现有能力进行回答 |
| 时间成本 | 长(数据准备、训练、迭代) | 短(主要工作是知识库构建) |
| 资金成本 | 高(训练计算、评估、迭代成本) | 低(主要是构建和检索成本) |
| 适用场景 | 改变模型行为、学习隐性知识(如风格、格式、复杂推理) | 查询动态、具体的事实性知识,要求信息溯源 |
| 数据需求 | 需要高质量、大规模的标注数据集,力求覆盖所有场景 | 按需提供,需要什么知识就准备什么文档 |
| 技术门槛 | 高(需机器学习/深度学习专业知识) | 相对较低(更多是工程和数据处理) |
| 迭代与维护 | 困难(更新知识需重新训练或增量训练) | 简单(直接增删改知识库文档即可) |
| 实时性 | 差,知识固化在模型中,无法感知新信息 | 好,知识库更新后立即可用 |
| 响应速度 | 生成速度快(推理阶段无需额外检索) | 整体响应较慢(需"检索+生成"两个步骤) |
| 可解释性/溯源 | 差,是"黑盒",无法确认答案来源 | 好,可以提供引用的原始文档片段 |
| “幻觉"问题 | 可能基于错误学习产生幻觉 | 能有效减少幻觉,答案基于提供的事实 |
=============================================================
最后,推荐一个学习资源——来自极客时间的 课程 <DeepSeek 应用开发实战>。
本文一部分内容,也是参考了这门课程。我自己目前也收益良多。
课程章节感兴趣的朋友,可以免费试看这门课程中任意4个章节内容。


