数据准备与处理:微调数据的“炼金术”
说实话,我见过太多团队在模型微调上翻车了。翻来覆去找原因,最后发现——数据没处理好。模型再强,喂进去的是垃圾,吐出来的只能是更精致的垃圾。今天咱们就聊聊数据准备这件事,我把这几年踩过的坑、总结的经验,一次性倒给你们。
微调数据格式:Alpaca 与 ShareGPT
先说说数据格式。你可能会问:“不就是把文本整理一下吗?”嗯,还真不是这么简单。格式选不对,后面训练的时候会出各种幺蛾子。
Alpaca 格式:最经典的“三件套”
Alpaca 格式是斯坦福搞出来的,结构特别清晰。每条数据就三个字段:instruction、input、output。说白了就是“指令-输入-输出”。
{
"instruction": "解释什么是反向传播",
"input": "",
"output": "反向传播是一种计算梯度的算法..."
}
我个人习惯用这种格式做单轮对话任务。比如指令跟随、文本分类、信息抽取。为什么?因为它简单。你想想看,一个 JSON 对象就搞定了,解析起来毫无压力。
但有个坑——input 字段经常被忽略。我在项目中遇到过,有人把所有内容都塞进 instruction,结果模型训练出来,指令和输入混在一起,效果大打折扣。记住:instruction 是任务描述,input 是具体输入,别搞混了。
ShareGPT 格式:多轮对话的利器
如果你要做聊天机器人,Alpaca 格式就不够用了。这时候 ShareGPT 格式上场。它用 conversations 数组来组织多轮对话,每条消息带 from 和 value 字段。
{
"conversations": [
{"from": "human", "value": "什么是机器学习?"},
{"from": "gpt", "value": "机器学习是AI的一个分支..."},
{"from": "human", "value": "能举个例子吗?"},
{"from": "gpt", "value": "比如垃圾邮件分类..."}
]
}
这里要注意角色标识。我见过有人把 from 写成 user 和 assistant,结果训练时角色映射出错。建议统一用 human 和 gpt,这是社区约定俗成的。
- 单轮任务用 Alpaca,多轮对话用 ShareGPT
- 字段名称不要随意改,否则解析器会报错
- 数据量少的时候,Alpaca 格式更容易做数据增强
数据清洗:别让脏数据毁了你的模型
数据清洗这件事,我刚开始做的时候觉得“差不多就行了”。直到有一次,模型训练到一半 loss 突然飙升,查了两天才发现——数据里混进了一条乱码。从那以后,我养成了严格的清洗习惯。
清洗清单
| 问题类型 | 处理方法 | 我的经验 |
|---|---|---|
| HTML 标签残留 | 正则替换 <.*?> |
爬虫数据常见,别漏了 |
| 特殊字符 | 保留标点,删除控制字符 | Unicode 控制字符最坑 |
| 重复数据 | 基于文本相似度去重 | 用 SimHash 效率高 |
| 过短/过长样本 | 设置长度阈值过滤 | 我一般设 10-2048 token |
| 语言混杂 | 语言检测 + 过滤 | 用 fastText 做检测 |
嗯,这里要注意:清洗不是越狠越好。我曾经把数据里的英文标点全换成中文标点,结果模型在代码生成任务上直接崩了。所以清洗策略要跟任务匹配。
我曾经在清洗时用了全局替换,把 "AI" 替换成了 "人工智能"。结果 "TRAINING" 变成了 "TR人工智能NING"——模型直接学废了。所以替换操作一定要加边界匹配。
数据增强策略:让有限的数据发挥最大价值
数据不够怎么办?这是每个做微调的人都会遇到的问题。我自己的经验是:别急着去网上扒数据,先把手头的数据增强好。
三种我常用的增强方法
1. 回译法
把中文翻译成英文,再翻译回中文。这样能产生语义相似但表达不同的数据。我在做客服对话微调时用过,效果出奇的好。但要注意:翻译模型的质量要过关,否则会引入噪声。
# 伪代码示例
original = "请帮我查询一下订单状态"
en_text = translate(original, target="en") # "Please check my order status"
augmented = translate(en_text, target="zh") # "请帮我查看我的订单状态"
2. 同义词替换
把句子中的关键词替换成同义词。比如“查询”换成“查看”,“订单”换成“订单信息”。我一般用 synonyms 库来做,但要注意上下文——有些词替换后意思就变了。
3. 模板填充
这个我最常用。先定义几个模板,然后从数据中抽取出实体,再填充到模板里。比如:
模板: "请帮我{动作}{对象}"
实体: {"动作": ["查询", "取消", "修改"], "对象": ["订单", "地址", "密码"]}
生成: "请帮我查询订单"、"请帮我取消地址"
你想想看,10个模板配上20个实体,就能生成200条数据。效率非常高。
数据增强不是越多越好。我一般控制在原始数据的 3-5 倍。超过这个量,模型容易学到重复模式,反而过拟合。
知识体系总览
说了这么多,咱们用一张图把整个流程串起来。这是我做数据准备时脑子里一直挂着的框架。
这张图就是我每次做数据准备时的路线图。从原始数据开始,经过格式选择、清洗、增强,最后得到可用的微调数据集。每一步都有讲究,跳过去就会出问题。
最后说一句:数据准备这件事,花的时间越多,后面训练就越省心。我见过太多人急着训练,结果数据没处理好,反复调参也救不回来。所以,别急,先把数据搞干净。