# 自定义数据集

ms-swift的标准格式数据集可接受的keys包括: 'messages'、'rejected_response'、'label'、'images'、'videos'、'audios'、'tools'和'objects'。其中'messages'是必需的key，'rejected_response'用于DPO等RLHF训练，'label'用于KTO训练，'images'、'videos'、'audios'用于存储多模态数据的路径或者url，'tools' 用于Agent任务，'objects'用于grounding任务。

ms-swift中存在三种核心预处理器：`MessagesPreprocessor`、`AlpacaPreprocessor`、`ResponsePreprocessor`。MessagesPreprocessor用于将类messages和sharegpt格式的数据集转换为标准格式，AlpacaPreprocessor则转换alpaca格式的数据集，ResponsePreprocessor则转换类query/response格式的数据集。`AutoPreprocessor`则可以自动选择合适的Preprocessor进行处理。通常情况下`AutoPreprocessor`能覆盖90%以上的情况。

以下四种格式在`AutoPreprocessor`处理下都会转换成ms-swift标准格式中的messages字段：

messages格式:
```jsonl
{"messages": [{"role": "system", "content": "<system>"}, {"role": "user", "content": "<query1>"}, {"role": "assistant", "content": "<response1>"}, {"role": "user", "content": "<query2>"}, {"role": "assistant", "content": "<response2>"}]}
```

sharegpt格式:
```jsonl
{"system": "<system>", "conversation": [{"human": "<query1>", "assistant": "<resonse1>"}, {"human": "<query2>", "assistant": "<resonse2>"}]}
```

alpaca格式:
```jsonl
{"system": "<system>", "instruction": "<query-inst>", "input": "<query-input>", "output": "<response>"}
```

query-response格式：
```jsonl
{"system": "<system>", "query": "<query2>", "response": "<response2>", "history": [["<query1>", "<response1>"]]}
```

自定义数据集的接入方法有三种，对预处理函数的控制能力逐渐加强：
1. 【推荐】直接使用`--dataset <dataset_id_or_path>`接入，使用AutoPreprocessor。支持csv、json、jsonl、txt、文件夹。
2. 书写dataset_info.json文件。可以参考ms-swift内置的[dataset_info.json](https://github.com/modelscope/ms-swift/blob/main/swift/llm/dataset/data/dataset_info.json)。其中ms_dataset_id/hf_dataset_id/dataset_path必填其中的一项，通过`columns`字段进行列名转换。格式转换使用AutoPreprocessor。使用`--custom_dataset_info xxx.json`解析json文件。
3. 手动注册数据集，具有最灵活的预处理函数定制能力，但难度较高。可以参考[examples](https://github.com/modelscope/swift/blob/main/examples/custom)中的样例，通过指定`--custom_register_path xxx.py`解析注册内容。


## 推荐数据集格式

以下给出ms-swift的推荐数据集格式，其中system字段是可选的，默认使用template中定义的`default_system`。

### 预训练

```jsonl
{"messages": [{"role": "assistant", "content": "I love music"}]}
{"messages": [{"role": "assistant", "content": "教练我要打篮球"}]}
{"messages": [{"role": "assistant", "content": "西红柿鸡蛋盖饭和地三鲜盖饭哪个更权威"}]}
```

### 监督微调

```jsonl
{"messages": [{"role": "system", "content": "你是个有用无害的助手"}, {"role": "user", "content": "告诉我明天的天气"}, {"role": "assistant", "content": "明天天气晴朗"}]}
{"messages": [{"role": "system", "content": "你是个有用无害的数学计算器"}, {"role": "user", "content": "1+1等于几"}, {"role": "assistant", "content": "等于2"}, {"role": "user", "content": "再加1呢"}, {"role": "assistant", "content": "等于3"}]}
```

### RLHF

#### DPO/ORPO/CPO/SimPO/RM

```jsonl
{"messages": [{"role": "system", "content": "你是个有用无害的助手"}, {"role": "user", "content": "告诉我明天的天气"}, {"role": "assistant", "content": "明天天气晴朗"}], "rejected_response": "我不知道"}
{"messages": [{"role": "system", "content": "你是个有用无害的数学计算器"}, {"role": "user", "content": "1+1等于几"}, {"role": "assistant", "content": "等于2"}, {"role": "user", "content": "再加1呢"}, {"role": "assistant", "content": "等于3"}], "rejected_response": "我不知道"}
```

#### KTO

```jsonl
{"messages": [{"role": "system", "content": "你是个有用无害的助手"}, {"role": "user", "content": "告诉我明天的天气"}, {"role": "assistant", "content": "我不知道"}], "label": false}
{"messages": [{"role": "system", "content": "你是个有用无害的数学计算器"}, {"role": "user", "content": "1+1等于几"}, {"role": "assistant", "content": "等于2"}, {"role": "user", "content": "再加1呢"}, {"role": "assistant", "content": "等于3"}], "label": true}
```

### 序列分类
```jsonl
{"messages": [{"role": "user", "content": "今天天气真好呀"}], "label": 1}
{"messages": [{"role": "user", "content": "今天真倒霉"}], "label": 0}
{"messages": [{"role": "user", "content": "好开心"}], "label": 1}
```

### 多模态

对于多模态数据集，和上述任务的格式相同。区别在于增加了`images`, `videos`, `audios`几个key，分别代表多模态资源，`<image>` `<video>` `<audio>`标签代表了插入图片/视频/音频的位置。下面给出的四条示例分别展示了纯文本，以及包含图像、视频和音频数据的数据格式。

预训练：
```
{"messages": [{"role": "assistant", "content": "预训练的文本在这里"}]}
{"messages": [{"role": "assistant", "content": "<image>是一只小狗，<image>是一只小猫"}], "images": ["/xxx/x.jpg", "/xxx/x.png"]}
{"messages": [{"role": "assistant", "content": "<audio>描述了今天天气真不错"}], "audios": ["/xxx/x.wav"]}
{"messages": [{"role": "assistant", "content": "<image>是一个大象，<video>是一只狮子在跑步"}], "images": ["/xxx/x.jpg"], "videos": ["/xxx/x.mp4"]}
```

微调：
```jsonl
{"messages": [{"role": "user", "content": "浙江的省会在哪？"}, {"role": "assistant", "content": "浙江的省会在杭州。"}]}
{"messages": [{"role": "user", "content": "<image><image>两张图片有什么区别"}, {"role": "assistant", "content": "前一张是小猫，后一张是小狗"}], "images": ["/xxx/x.jpg", "xxx/x.png"]}
{"messages": [{"role": "user", "content": "<audio>语音说了什么"}, {"role": "assistant", "content": "今天天气真好呀"}], "audios": ["/xxx/x.mp3"]}
{"messages": [{"role": "system", "content": "你是个有用无害的助手"}, {"role": "user", "content": "<image>图片中是什么，<video>视频中是什么"}, {"role": "assistant", "content": "图片中是一个大象，视频中是一只小狗在草地上奔跑"}], "images": ["/xxx/x.jpg"], "videos": ["/xxx/x.mp4"]}
```
RLHF的数据格式可以参考纯文本大模型的格式。

#### grounding

如果是grounding（物体检测）任务，SWIFT支持两种方式：
1. 和上述多模态数据集格式保持一致，自行在数据集中添加特殊字符，例如：
```jsonl
{"messages": [{"role": "system", "content": "你是个有用无害的助手"}, {"role": "user", "content": "<image>找到<ref>一只大象</ref>"}, {"role": "assistant", "content": "<box>(200,450),(500, 800)</box>"}], "images": ["/xxx/x.jpg"]}
```
使用这种类型的数据需要您注意：
  - grounding任务往往需要特殊字符，您需要确定使用哪个模型，并阅读模型论文来确定该模型grounding任务的特殊字符，并拼合数据
  - bbox的坐标可能使用图片真实坐标，也可能使用千分位坐标，在拼合数据前请确定这一点
  - 不同模型需要的数据格式不同，更换模型请重新制作数据集

2. 使用SWIFT的grounding数据格式：

```jsonl
# Object detection
{"messages": [{"role": "system", "content": "你是个有用无害的助手"}, {"role": "user", "content": "<image>识别<bbox>"}, {"role": "assistant", "content": "<ref-object>"}], "images": ["/coco2014/train2014/COCO_train2014_000000001507.jpg"], "objects": "[{\"caption\": \"guy in red\", \"bbox\": [138, 136, 235, 359], \"bbox_type\": \"real\", \"image\": 0}]" }
# Grounding to multiple bboxes
{"messages": [{"role": "system", "content": "你是个有用无害的助手"}, {"role": "user", "content": "<image>找到<ref-object>"}, {"role": "assistant", "content": "<bbox>"}], "images": ["/coco2014/train2014/COCO_train2014_000000001507.jpg"], "objects": "[{\"caption\": \"guy in red\", \"bbox\": [[138, 136, 235, 359], [1,2,3,4]], \"bbox_type\": \"real\", \"image\": 0}]" }
```

该格式比通用格式多了objects字段，该字段包含的字段有：
 - caption bbox对应的物体描述
 - bbox 坐标 建议给四个整数（而非float型），分别是x_min,y_min,x_max,y_max四个值
 - bbox_type: bbox类型 目前支持三种：real/norm_1000/norm_1，分别代表实际像素值坐标/千分位比例坐标/归一化比例坐标
 - image: bbox对应的图片是第几张, 索引从0开始

### 文生图格式

```jsonl
{"messages": [{"role": "system", "content": "你是个有用无害的助手"}, {"role": "user", "content": "给我画出一个苹果"}, {"role": "assistant", "content": "<image>"}], "images": ["/xxx/x.jpg"]}
```

### Agent格式

Agent格式请参考[Agent文档](../Instruction/智能体的支持.md).
