微调数据集格式转换,不同框架之间数据集互转脚本

微调数据集格式转换是大模型训练前绕不开的一步。
不同框架(比如 PyTorch + HuggingFace、PaddlePaddle、LLaMA Factory)对训练数据的格式要求并不一样,有的是 JSONL,有的是 JSON,还有 Alpaca、ShareGPT 这些对话模板。
本文直接用 Python 脚本演示几种常见格式的互转,并告诉你转换时最容易踩的坑。

先搞清楚常见的数据集格式结构

转换之前必须先认格式,否则脚本写出来也容易出错。
目前主流的微调数据集格式有这几种:

  • Alpaca 格式:每条数据包含 instructioninputoutput 三个字段,input 可以为空字符串。
  • ShareGPT 格式:每条数据包含 conversations 列表,每个元素是 fromvaluefromhumangpt
  • HuggingFace Dataset 格式:通常是一个 JSON/JSONL 文件,字段名按任务而定,也可能直接是 Arrow 格式。
  • 纯对话格式:只有 promptresponse 两个字段,常用于基础指令微调。

不同框架会读取不同字段,所以转换脚本的核心就是「字段映射」。

准备环境

不需要安装额外框架,只需要本机有 Python 3.7 以上。
为了读写 JSONL,建议用标准库 json
如果你的原始数据是 CSV,还需要 pandas,但这里我们尽量用标准库实现,减少依赖。

创建一个工作目录,比如 dataset_convert,在里面放一个 convert.py 脚本。

实战:Alpaca 格式转 JSONL

假设你手里是一份 Alpaca 格式的 JSON 文件,内容如下:

[
  {
    "instruction": "用一句话描述春天",
    "input": "",
    "output": "春天是万物复苏的季节。"
  }
]

现在要转成 HuggingFace 常用的 JSONL 格式,也就是每一行一个 JSON 对象,字段改成 promptresponse

import json

# 读取 Alpaca 格式 JSON
with open('alpaca.json', 'r', encoding='utf-8') as f:
    data = json.load(f)

# 转成 JSONL
with open('train.jsonl', 'w', encoding='utf-8') as f:
    for item in data:
        # 这里把 input 拼接进 prompt,如果为空就直接用 instruction
        prompt = item['instruction']
        if item.get('input'):
            prompt += "\n" + item['input']
        new_item = {
            "prompt": prompt,
            "response": item['output']
        }
        f.write(json.dumps(new_item, ensure_ascii=False) + '\n')

运行后你会得到一个 train.jsonl,每行是一个完整的 JSON。
有些框架在训练时不需要 prompt 字段,而是要求 instructionoutput,那只要把 new_item 改成对应字段名即可。

实战:ShareGPT 格式转 Alpaca

再举一个反过来的例子。
下面是一份 ShareGPT 风格的数据:

{
  "conversations": [
    {"from": "human", "value": "你好"},
    {"from": "gpt", "value": "你好,有什么可以帮你?"},
    {"from": "human", "value": "推荐一本Python书"},
    {"from": "gpt", "value": "《Python编程:从入门到实践》不错。"}
  ]
}

要转成 Alpaca 格式,需要把多轮对话拆开或者合并成一条指令和输出。
通常更合理的做法是转为「多轮对话」结构,但 Alpaca 本身是单轮的。
如果强行转,建议只保留第一轮,或者把整个对话内容作为输出。

import json

with open('sharegpt.json', 'r', encoding='utf-8') as f:
    data = json.load(f)

output = []
for conv in data['conversations']:
    if conv['from'] == 'human':
        instruction = conv['value']
    elif conv['from'] == 'gpt':
        output.append({
            "instruction": instruction,
            "input": "",
            "output": conv['value']
        })

with open('alpaca_converted.json', 'w', encoding='utf-8') as f:
    json.dump(output, f, ensure_ascii=False, indent=2)

注意这个脚本会把多轮对话拆成多条单轮数据,可能丢失上下文。
如果框架支持 ShareGPT,保留 conversations 字段更安全。

通用互转脚本思路:字段映射 + 批量处理

与其每次手工改,不如写一个通用的转换脚本。
核心逻辑是:先定义一个映射字典,把当前字段名映射为目标字段名,再按目标格式重组数据。

import json

def convert(input_file, output_file, mapping):
    """
    mapping 示例: {"instruction": "prompt", "output": "response"}
    """
    with open(input_file, 'r', encoding='utf-8') as f:
        content = f.read()
    
    # 自动判断是 JSON 还是 JSONL
    if content.lstrip()[0] == '[':
        data = json.loads(content)
    else:
        data = [json.loads(line) for line in content.strip().split('\n') if line]
    
    converted = []
    for item in data:
        new_item = {}
        for src, dst in mapping.items():
            if src in item:
                new_item[dst] = item[src]
        converted.append(new_item)
    
    with open(output_file, 'w', encoding='utf-8') as f:
        if output_file.endswith('.jsonl'):
            for item in converted:
                f.write(json.dumps(item, ensure_ascii=False) + '\n')
        else:
            json.dump(converted, f, ensure_ascii=False, indent=2)

使用时只要传入对应的映射关系,比如从 Alpaca 转 JSONL:

python convert.py

脚本内调用方式自己修改即可。
实际项目中还需要处理 input 字段的拼接,这里只是让你理解映射思路。

避坑指南:这些坑很容易导致训练时报错

转换数据集最大的问题不是脚本,而是字段不对称。
下面几个点一定要检查:

  • 中文不会乱码:所有文件读写都要带 encoding='utf-8',否则 Windows 环境下容易报错。
  • JSON 和 JSONL 别混用:JSON 是一个数组,JSONL 是每行一个独立 JSON 对象。读取方式完全不同,脚本里要先判断。
  • 空字段要处理:Alpaca 的 input 可以为空,但有些框架不允许 None,必须转成空字符串。
  • 多轮对话不要强行拆:如果原始数据是 ShareGPT,你的目标框架也支持多轮,就保留 conversations 结构,不要拆成单轮。
  • 字段名大小写敏感Instructioninstruction 是不同字段,转换后务必用 head -n 3 检查一下。

转换后怎么验证

转换完不能直接拿去训练,先做两步验证。

第一步,用命令查看文件前几行是否有合法 JSON:

head -n 3 converted.jsonl

第二步,用 Python 快速校验每一行能否被解析:

import json
with open('converted.jsonl', 'r', encoding='utf-8') as f:
    for i, line in enumerate(f):
        try:
            json.loads(line)
        except Exception as e:
            print(f'第 {i+1} 行错误:{e}')

如果没有任何报错,再确认字段名和目标框架要求是否一致。
例如 HuggingFace 的 Dataset.from_json 会直接读取 JSONL,字段名需要和训练脚本里 data_collator 中指定的对应上。

最后补充一点:不同框架对数据集格式的官方要求可能会更新,转换前最好先查一下当前框架的文档。
如果你在转换过程中遇到具体的报错,把报错信息贴出来,可以根据实际框架再调整字段映射。
微调数据集格式转换并不复杂,只要理清字段关系,写一个自己的互转脚本就能一劳永逸。

分享到:
上一篇
Ollama模型预下载脚本,批量部署多台推理服务器
下一篇
RAG检索结果过滤相似度阈值调参,减少无关文档混入
1
系统公告

机房迁移升级通知

尊敬的用户: IP 段 103.23.148.x、156.224.29.x 原香港一区线路波动、攻击频繁,平台定于 7 月 5 日凌晨分批迁移至香港 GIA 机房,硬件升级 AMD 铂金机型。 迁移均在凌晨操作,最大程度降低业务影响,迁移期间服务器临时关机; 升级后配置不降低、费用不涨价,数据默认同步迁移; 迁移后 IP 全部更换,请及时修改域名解析、防火墙白名单; 建议提前备份重要数据,有问题可联系在线客服。 感谢理解与支持! 泽御云科技 2026.06.30
服务中心
客服
在线客服
24小时为您服务
咨询
联系我们
联系我们,为您的业务提供专属服务。
24/7 技术支持
如果您遇到寻求进一步的帮助,请过工单与我们进行联系。
24/7 即时支持
泽御云
售前客服
泽御云
泽御云
售后客服
泽御云
技术支持
评价
您对当前页面的整体感受是否满意?
😞
非常不满意
😕
不满意
😐
一般
🙂
满意
😊
非常满意