ms-swift自定义数据集教程,三步完成格式转换
1. 引言:为什么你需要自定义数据集?
你有没有遇到过这种情况:手头有一堆高质量的业务数据,比如客服对话记录、产品描述文案、内部知识库内容,但就是没法直接用来训练大模型?不是格式不对,就是字段混乱,折腾半天还报错。
别急,今天这篇教程就是为了解决这个问题而生的。
我们用ms-swift框架来教你如何把“野数据”变成“标准粮”,只需要三步,就能让你的数据顺利喂给 Qwen、Llama、InternLM 等主流大模型进行微调。整个过程不讲黑话,不说术语,就像朋友手把手带你操作一样简单。
你能学到什么?
- ✅ 自定义数据长什么样?怎么组织最省事
- ✅ 三种常见原始数据(JSON/CSV/TXT)如何统一转成 ms-swift 能吃的格式
- ✅ 实战演示:从一份杂乱的对话数据到成功启动训练
- ✅ 避坑指南:那些文档里没写但你会踩的雷
前置准备
- 已安装
ms-swift(可通过 pip 安装) - 有基础 Python 和命令行使用经验
- 准备好你的原始数据文件(支持 .json、.jsonl、.csv、.txt)
好了,咱们直接开干。
2. 第一步:搞清楚 ms-swift 要什么格式
在动手转换之前,先得知道目标是什么。ms-swift 支持多种任务类型,但最常见的还是指令微调(SFT),也就是让模型学会按你的要求回答问题。
这类任务的标准输入是一个结构化的数据集,每条样本包含至少两个字段:
{ "messages": [ { "role": "user", "content": "请介绍一下你自己" }, { "role": "assistant", "content": "我是通义千问,由阿里云研发的超大规模语言模型……" } ] }关键点解析:
messages是一个列表,按对话顺序排列- 每条消息必须有
role(可以是user、assistant、system) content是具体的文本内容- 可以有多轮对话,比如先提问 → 回答 → 再追问 → 再回答
如果你的数据是单轮问答、文章生成、摘要任务,也都适用这个结构,只是messages里只有两轮(用户问 + 模型答)。
提示:ms-swift 还支持其他格式,如
prompt+response,但我们推荐统一用messages格式,兼容性最好,未来扩展也方便。
3. 第二步:三类常见数据的转换方法
现实中,我们的数据往往五花八门。下面我挑三种最典型的场景,手把手教你转成标准格式。
3.1 场景一:JSON/JSONL 文件(最常见)
假设你有一个my_data.jsonl,每行长这样:
{"instruction": "写一首关于春天的诗", "output": "春风拂面花自开,柳绿桃红映山川……"}这种结构清晰,转换起来最容易。
转换脚本(Python):
import json def convert_jsonl(input_path, output_path): with open(input_path, 'r', encoding='utf-8') as f_in: with open(output_path, 'w', encoding='utf-8') as f_out: for line in f_in: data = json.loads(line.strip()) # 构造标准 messages 结构 messages = [ {"role": "user", "content": data["instruction"]}, {"role": "assistant", "content": data["output"]} ] # 写入一行 JSON f_out.write(json.dumps({"messages": messages}, ensure_ascii=False) + '\n') # 使用示例 convert_jsonl('my_data.jsonl', 'train.jsonl')✅ 执行后生成train.jsonl,就可以直接丢进 ms-swift 训练了。
3.2 场景二:CSV 表格数据
很多运营、客服导出的数据都是 CSV,比如:
| question | answer |
|---|---|
| 如何退货? | 登录账号后进入订单页面… |
| 发货时间? | 下单后48小时内发出… |
转换脚本(Python):
import csv import json def convert_csv(input_path, output_path): with open(input_path, 'r', encoding='utf-8') as f_in: reader = csv.DictReader(f_in) with open(output_path, 'w', encoding='utf-8') as f_out: for row in reader: messages = [ {"role": "user", "content": row["question"]}, {"role": "assistant", "content": row["answer"]} ] f_out.write(json.dumps({"messages": messages}, ensure_ascii=False) + '\n') # 使用示例 convert_csv('qa_data.csv', 'train.jsonl')📌 小技巧:如果表头不是英文,比如“问题”、“回复”,只需把row["question"]改成row["问题"]即可。
3.3 场景三:纯文本(TXT),适合故事/文章生成
有些数据是纯文本段落,比如小说章节、产品介绍文案。例如story.txt:
【标题】春日游 【内容】春日暖阳洒在湖面上,小舟轻轻荡漾。岸边桃花盛开,香气扑鼻……我们需要把它包装成“用户提需求,模型生成内容”的形式。
转换脚本:
def convert_txt(input_path, output_path): with open(input_path, 'r', encoding='utf-8') as f_in: content = f_in.read().strip() # 按段落或标记分割(这里以【】为界) parts = [p.strip() for p in content.split('【') if p] with open(output_path, 'w', encoding='utf-8') as f_out: for part in parts: if '标题' in part and '内容' in part: title = part.split('】')[1].split('【')[0] text = part.split('】')[2] messages = [ {"role": "user", "content": f"写一篇题为《{title}》的文章"}, {"role": "assistant", "content": text} ] f_out.write(json.dumps({"messages": messages}, ensure_ascii=False) + '\n') convert_txt('story.txt', 'train.jsonl')💡 提示:TXT 的处理方式很灵活,关键是设计一个合理的“触发语句”(即 user 的 input),让训练时的输入和推理时保持一致。
4. 第三步:验证并开始训练
数据转完了,别急着跑训练,先检查一下对不对。
4.1 快速验证格式是否正确
运行这条命令,看能不能正常读取前几条数据:
head -n 2 train.jsonl | python -m json.tool如果输出是整齐的 JSON 结构,说明格式没问题。
也可以用 Python 读一下:
import json with open('train.jsonl', 'r') as f: for i in range(2): line = f.readline() print(json.loads(line))预期输出:
{ 'messages': [ {'role': 'user', 'content': '写一首关于春天的诗'}, {'role': 'assistant', 'content': '春风拂面花自开...'} ] }✅ 如果能看到这个,恭喜你,数据已经 ready!
4.2 启动训练(以 LoRA 微调为例)
现在你可以像官方示例一样,用swift sft命令开始训练了:
CUDA_VISIBLE_DEVICES=0 swift sft \ --model Qwen/Qwen2.5-7B-Instruct \ --dataset ./train.jsonl \ --train_type lora \ --output_dir output-qwen-lora \ --num_train_epochs 3 \ --per_device_train_batch_size 1 \ --gradient_accumulation_steps 8 \ --learning_rate 1e-4 \ --lora_rank 64 \ --lora_alpha 128 \ --max_length 2048 \ --save_steps 100 \ --logging_steps 10📌 注意事项:
--dataset后面直接跟你的本地文件路径(支持相对路径)- 如果数据量小,建议减少
num_train_epochs防止过拟合 - LoRA 参数可以根据显存调整,7B 模型建议
lora_rank=64,lora_alpha=128
5. 常见问题与避坑指南
5.1 数据加载失败?检查这几点
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
报错KeyError: 'messages' | 字段名写错了 | 确保是"messages",不是message或conversations |
报错Invalid format | JSON 格式不合法 | 用json.tool检查每一行是否都能解析 |
| 训练卡住不动 | 文件编码问题 | 保存为 UTF-8 编码,不要用 GBK |
| 显存爆了 | max_length 太大 | 设置--max_length 1024或2048,避免默认 32768 |
5.2 多轮对话怎么写?
如果你要做客服机器人,支持多轮交互,messages可以更长:
{ "messages": [ {"role": "user", "content": "我想买手机"}, {"role": "assistant", "content": "您想要什么品牌?"}, {"role": "user", "content": "华为"}, {"role": "assistant", "content": "推荐Mate 60系列,性能强劲……"} ] }✅ ms-swift 会自动处理这种上下文依赖,不需要额外设置。
5.3 能不能加 system prompt?
可以!在messages最前面加上就行:
{ "messages": [ {"role": "system", "content": "你是一个专业的电子产品导购员"}, {"role": "user", "content": "我想买手机"}, {"role": "assistant", "content": "您想要什么品牌?"} ] }这样模型在训练时就会记住这个角色设定,效果更好。
6. 总结:三步走通全流程
我们来回顾一下整个流程,其实就三步:
## 6.1 数据准备三步曲
- 看清结构:确认原始数据是 JSON、CSV 还是 TXT
- 统一格式:转成
{"messages": [...]}的 JSONL 格式 - 验证可用:用
head + json.tool检查前几行
## 6.2 训练建议清单
- ✅ 文件命名建议:
train.jsonl、dev.jsonl,清晰明了 - ✅ 编码务必 UTF-8,避免中文乱码
- ✅ 每行一个样本,不要合并成大数组
- ✅ 多轮对话自然写,不用拆开
- ✅ 可加入
system角色提升效果
## 6.3 下一步你可以尝试
- 把公司内部 FAQ 转成训练集,打造专属客服模型
- 用历史工单数据训练一个自动摘要模型
- 结合 Web UI 界面,实现零代码训练部署
只要数据格式对了,剩下的交给 ms-swift 就行。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。