1517 字
4 分钟
Fine Tuningfine tuning
失败复盘与二次优化:system、数据重构与 agent 配合

第一次训练没有达到预期后,真正重要的不是继续堆轮数,而是重构数据、重新定义任务边界,再判断哪些能力应该交给模型,哪些应该交给 agent。

第一次训练的意义是把问题暴露出来。第二次的重点,就不再是"再训一遍",而是先重新理解:到底是哪一层出了问题。

一、先把问题重新说清楚#

目标还是同一个:
对 Qwen2.5-VL 做微调,让它能准确描述图片并完成血液分类任务。

原笔记里把分类树整理成了这样:

.
├── 被动的、重力
│ ├── 大量血液自由落体
│ ├── 滴落
│ ├── 接触
│ ├── 浸润、血泊
│ └── 流动
├── 变动的
│ ├── 虫咬的
│ ├── 干缩的
│ ├── 空白区
│ ├── 扩散的
│ ├── 凝固的
│ ├── 顺序的
│ └── 稀释的
└── 溅落的
├── 二次作用机理
├── 喷射机理
└── 撞击机理

但第一次实验后暴露出来的问题很明确:

  1. 数据太少
  2. 类别不平衡
  3. 模型对分类任务的"使命感"不够强
  4. 会自行联想出不存在的类别
  5. 回答过于简洁

所以第二轮优化的核心不是"多训一点",而是:

如何在小样本前提下,让模型更明确地知道它究竟要做什么。

二、第一步尝试:把分类规则写进 system#

这一步的想法非常自然:
既然模型不知道分类边界,那就把分类标准显式写给它。

原笔记把各类血迹的规则进行了细化整理,然后准备写成一段 system 信息,让模型在训练时直接看到这些标准。

这里的出发点其实完全合理:

  • 样本少
  • 领域标准复杂
  • 靠样本自己学出分类边界太难

所以想用 system 给它补规则。

1. 但是这一步为什么失败了#

原笔记里记录得很清楚:
直接把大段规则写进 system 去训练,效果反而变差,模型开始胡言乱语。

这件事很值得记,因为它说明:

"更多任务说明"不一定等于"更好的微调效果"。

一个很可能的原因是:

Qwen2.5-VL-Instruct 这类模型在预训练和指令微调阶段,已经形成了它熟悉的对话格式分布。如果强行引入一套与原有分布不一致、而且很重的 system 结构,模型在小样本上反而更容易学歪。

所以这里第一次真正感觉到:

有些约束适合写进模型,有些约束更适合交给外部 agent 或系统逻辑。

三、真正有效的改动:先重构数据#

既然"直接灌 system"不行,那就回到更基础的一层:数据本身。

1. 把描述写得更细#

第一次训练里,很多图像描述过于简短,导致模型很难抓住真正能支持分类的细节。

所以第二轮开始做的第一件事,是把描述写得更具体、更像"真正有助于分类的观察记录"。

重构后的样本示意

这个改动非常朴素,但往往最有效。因为分类任务不只是要求模型"看到了图像",而是要求它"看到并描述了对分类有帮助的要点"。

2. 把 system 的职责往 agent 迁#

原笔记里有一句特别关键的判断:

如果不框定范围,模型会联想;但直接把范围硬写进训练用 system,又会把模型训练搞乱。

所以最终想到的折中办法是:

  • 模型微调只学核心任务模式
  • 更重的任务约束交给外部 agent 的 system 提示去控制

这其实非常像现在很多真实系统的设计:

模型参数负责"底层能力",agent/system 负责"运行时边界"。

四、第二轮参数怎么改#

第二次训练并没有彻底推翻第一轮,而是在原有参数上做了几处更有针对性的微调:

--num_train_epochs 10.0
--lora_dropout 0.1
--warmup_steps 20

对应的直觉分别是:

  1. num_train_epochs 增加:小样本下让模型多看几遍
  2. lora_dropout 增加:给 LoRA 一点正则化,防止过拟合
  3. warmup_steps 增加:让学习率更平稳地升起来

而有几项则保持不变:

  • 学习率不变
  • per_device_train_batch_size=1
  • gradient_accumulation_steps=1

原笔记里的判断是:继续让模型"细着学",而不是靠更大 batch 去换更平滑的梯度。

五、第二轮训练结果#

调整后再次微调,Loss 曲线如下:

第二轮曲线

这张图至少说明一点:

第二轮不是乱改,而是沿着第一次暴露出来的问题在做针对性修正。

六、第二轮怎么评估#

后面没有直接让微调模型裸跑,而是用了一个快速搭起来的 agent,把:

  • 微调后的模型
  • vLLM 启动出来的服务
  • 外部 system 提示

重新组合到一起,再去跑测试集。

这个做法本身就很有启发性,因为它说明:

微调不是一个非黑即白的过程,不一定所有约束都必须写进权重。

最终在 10 张测试图上的结果是:

  • 正确率约 50%
  • 流动型识别最好
  • 接触型最容易出错
  • 回答风格仍然偏简洁

原笔记最后把现象概括得很直白:

  1. 特征明显的类别更容易识别
  2. 团聚型血液更容易误判
  3. 接触型容易被识别成流动型
  4. 回答格式化且过于简短

七、这次复盘真正留下了什么#

如果只看数字,50% 正确率显然不理想。
但如果站在学习和工程角度看,这次复盘其实留下了几条很重要的结论:

  1. 数据设计比单纯加轮数更重要
  2. system 提示并不是越重越好
  3. 小样本下,任务边界必须明确
  4. 微调与 agent 不必对立,它们可以分工

所以第二轮最大的价值,并不是"已经训好了",而是:

终于开始知道该把什么交给模型、把什么交给系统。

专题阅读

Fine Tuning

这篇文章属于同一条阅读链。你可以直接在这里切换,不用再回到列表页重新找。

当前进度7 / 7

留言区

留言

欢迎纠错、补充、交流。昵称和评论内容必填;如果你愿意,也可以留下联系方式,仅站主可见。

0

正在加载评论...

0 / 2000

阅读导航

文章目录

当前阅读位置将在这里显示

0 节