ms-swift如何加载自定义数据集?格式转换全说明

1. 引言:为什么需要自定义数据集支持?

在大模型微调实践中,使用领域特定的自定义数据集是提升模型性能的关键手段。尽管ms-swift内置了150+公开数据集(如alpaca-gpt4-data-zh、swift/self-cognition等),但在实际业务场景中,用户往往需要基于私有知识库、行业语料或特定任务构建专属训练数据。

本文将系统性地解析 ms-swift 框架如何加载和处理自定义数据集,涵盖:

  • 支持的数据格式与结构要求
  • 文本/多模态数据的组织方式
  • 常见格式转换方法(CSV/JSON → JSONL)
  • 训练命令配置技巧
  • 实际案例演示

目标是让开发者能够“零踩坑”完成从原始数据到可训练输入的全流程打通。


2. ms-swift数据集加载机制解析

2.1 数据集抽象模型:Dataset Registry

ms-swift通过统一的 Dataset Registry 管理所有数据集,无论是ModelScope/HuggingFace上的公开数据集,还是本地路径下的自定义数据集。

其核心逻辑如下:

# 内部伪代码示意
if dataset_name.startswith('hub://') or '/' in dataset_name:
    load_from_remote(dataset_name)
else:
    try:
        load_builtin_dataset(dataset_name)
    except DatasetNotFound:
        # 尝试作为本地路径加载
        load_from_local_path(dataset_name)

因此,只要你的数据符合ms-swift期望的格式,并通过 --dataset /path/to/your/dataset 指定路径,即可实现无缝接入。

2.2 核心数据格式:JSONL 是首选

ms-swift 推荐使用 JSON Lines (JSONL) 格式作为自定义数据的标准输入格式。每行一个独立JSON对象,适用于流式读取,尤其适合大规模数据集。

✅ 正确示例(SFT指令微调):
{"messages": [{"role": "user", "content": "请解释量子纠缠。"}, {"role": "assistant", "content": "量子纠缠是一种……"}]}
{"messages": [{"role": "user", "content": "写一首关于春天的诗。"}, {"role": "assistant", "content": "春风拂面花自开……"}]}
✅ 多模态示例(图文对话):
{
  "messages": [
    {"role": "user", "content": [{"type": "image", "image": "images/cat.jpg"}, {"type": "text", "text": "图中有什么?"}]},
    {"role": "assistant", "content": "这是一只坐在地毯上的橘猫。"}
  ]
}

📌 注意:图像路径可以是相对路径(相对于数据集根目录)、绝对路径或URL。


3. 自定义数据集构建指南

3.1 文本类数据集格式规范

(1)基础SFT任务(单轮对话)
字段类型说明
messageslist对话历史列表,至少包含 user 和 assistant 角色
{"messages": [{"role": "user", "content": "你好"}, {"role": "assistant", "content": "我是AI助手。"}]}
(2)多轮对话任务
{
  "messages": [
    {"role": "user", "content": "推荐一部科幻电影"},
    {"role": "assistant", "content": "《银翼杀手2049》非常经典。"},
    {"role": "user", "content": "还有别的吗?"},
    {"role": "assistant", "content": "也可以看看《降临》。"}
  ]
}
(3)带 system prompt 的场景
{
  "messages": [
    {"role": "system", "content": "你是一个翻译专家,擅长中英互译。"},
    {"role": "user", "content": "把‘今天天气很好’翻译成英文"},
    {"role": "assistant", "content": "The weather is great today."}
  ]
}

3.2 多模态数据集组织结构

对于图像、视频等多模态数据,需遵循以下目录结构:

my_multimodal_dataset/
├── data.jsonl
└── images/
    ├── img1.jpg
    ├── img2.png
    └── ...

其中 data.jsonl 内容为:

{
  "messages": [
    {
      "role": "user",
      "content": [
        {"type": "image", "image": "images/img1.jpg"},
        {"type": "text", "text": "描述这张图片"}
      ]
    },
    {
      "role": "assistant",
      "content": "这是一个阳光明媚的公园,孩子们在玩耍……"
    }
  ]
}

⚠️ 路径建议使用相对路径,确保可移植性。


4. 常见格式转换实战

4.1 CSV → JSONL 转换(以Alpaca格式为例)

假设你有一个 train.csv,字段为 instruction, input, output:

instructioninputoutput
解释相对论狭义相对论指出……

转换脚本如下:

import json
import pandas as pd

def csv_to_sft_jsonl(csv_path, output_path):
    df = pd.read_csv(csv_path)
    with open(output_path, 'w', encoding='utf-8') as f:
        for _, row in df.iterrows():
            prompt = row['instruction']
            if pd.notna(row['input']) and row['input'].strip():
                prompt += f"\n{row['input']}"
            
            messages = [
                {"role": "user", "content": prompt},
                {"role": "assistant", "content": row['output']}
            ]
            f.write(json.dumps({"messages": messages}, ensure_ascii=False) + '\n')

# 使用示例
csv_to_sft_jsonl('train.csv', 'sft_data.jsonl')

4.2 单条样本JSON → JSONL 批量格式

常见错误:将多个样本写在一个JSON数组中。

❌ 错误格式:

[
  {"messages": [...]},
  {"messages": [...]}
]

✅ 正确做法:逐行写入

import json

data = [
    {"messages": [{"role": "user", "content": "问1"}, {"role": "assistant", "content": "答1"}]},
    {"messages": [{"role": "user", "content": "问2"}, {"role": "assistant", "content": "答2"}]}
]

with open('converted.jsonl', 'w', encoding='utf-8') as f:
    for item in data:
        f.write(json.dumps(item, ensure_ascii=False) + '\n')

4.3 HuggingFace Dataset 导出为本地JSONL

如果你的数据在HF Hub上:

from datasets import load_dataset

ds = load_dataset("your_username/your_dataset")
for split in ds:
    with open(f"{split}.jsonl", "w", encoding="utf-8") as f:
        for sample in ds[split]:
            f.write(json.dumps(sample, ensure_ascii=False) + "\n")

然后使用 --dataset ./train.jsonl 加载。


5. 训练命令配置详解

5.1 基础训练命令(LoRA微调)

CUDA_VISIBLE_DEVICES=0 swift sft \
    --model Qwen/Qwen2.5-7B-Instruct \
    --dataset /path/to/your/sft_data.jsonl \
    --train_type lora \
    --output_dir output-qwen-lora \
    --num_train_epochs 3 \
    --per_device_train_batch_size 2 \
    --learning_rate 1e-4 \
    --lora_rank 64 \
    --lora_alpha 128 \
    --max_length 2048 \
    --use_flash_attn true

5.2 多文件数据集拼接

支持同时加载多个数据集文件,按比例采样:

--dataset \
    "/path/to/data1.jsonl#1000" \
    "/path/to/data2.jsonl#500" \
    "AI-ModelScope/alpaca-gpt4-data-zh#200"

#N 表示从该数据集中随机采样N条用于训练。

5.3 指定数据字段映射(高级用法)

若你的数据字段名不匹配标准格式,可通过 --dataset_map 进行映射:

--dataset_map '{"instruction": "messages[0].content", "response": "messages[1].content"}'

但更推荐预处理阶段统一格式,避免运行时开销。


6. 验证与调试技巧

6.1 快速验证数据格式是否正确

使用Python加载并检查前几条数据:

def check_jsonl(path, n=3):
    with open(path, 'r', encoding='utf-8') as f:
        for i, line in enumerate(f):
            if i >= n: break
            try:
                item = json.loads(line.strip())
                print(f"Sample {i+1}: {item.keys()}")
                if 'messages' in item:
                    for msg in item['messages']:
                        print(f"  [{msg['role']}] {msg['content'][:50]}...")
            except Exception as e:
                print(f"Parse error at line {i+1}: {e}")

check_jsonl('sft_data.jsonl')

6.2 启用详细日志查看数据加载过程

添加 --logging_steps 1 参数后,可观察到类似输出:

[INFO] Loading dataset from /path/to/sft_data.jsonl
[INFO] Loaded 1200 samples from dataset
[INFO] Applying template: qwen
[INFO] Tokenizing dataset...

6.3 使用Web UI可视化调试

启动Web界面进行交互式测试:

swift web-ui

在“Data”标签页上传JSONL文件,系统会自动解析并展示前几条样本,便于确认格式无误。


7. 常见问题与解决方案

❌ 问题1:ValueError: No valid dataset found

原因:路径错误或格式不符合预期。

解决方法:

  • 确保路径为绝对路径或相对当前工作目录正确的路径
  • 检查文件是否存在且非空
  • 使用 file 命令确认是文本文件而非二进制
file /path/to/your/data.jsonl
# 应输出:ASCII text, with very long lines

❌ 问题2:KeyError: 'messages'

原因:字段命名不一致。

解决方案:

  • 统一使用 messages 字段
  • 或使用 --dataset_map 映射旧字段

❌ 问题3:图像路径无法加载

表现:报错 Image not found 或 cannot identify image file

排查步骤:

  1. 检查图像路径是否正确(建议使用相对路径)
  2. 确认图像文件存在且可读
  3. 安装Pillow依赖:pip install pillow
  4. 测试单张图像能否打开:
from PIL import Image
Image.open("images/test.jpg").verify()  # 不报错即正常

8. 总结

本文全面介绍了 ms-swift 如何加载自定义数据集 的完整流程,核心要点总结如下:

  1. 推荐格式:使用 JSONL 格式组织数据,每行一个样本。
  2. 标准结构:文本任务使用 messages 列表,多模态任务结合 type: image/text。
  3. 路径管理:图像等资源建议使用相对路径,保持项目可移植性。
  4. 格式转换:掌握 CSV/JSON → JSONL 的自动化脚本编写能力。
  5. 训练集成:通过 --dataset /path/to/file.jsonl 直接加载本地数据。
  6. 调试验证:利用日志、Python脚本和Web UI三重手段确保数据正确性。

通过以上实践,你可以轻松将任意领域的私有数据接入 ms-swift 框架,实现高效、可控的大模型微调。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐