本仓库公开了我们在多轮对话指令微调工作(MDS)中使用的核心数据选择与评测流程。当前公开内容包括:
- MDS 全局阶段选择代码
- MDS 局部阶段选择代码
- 将选出的训练/测试对话转换为 disk-style 数据的脚本
- 多轮对话预测结果的统一评测代码
- 公开的训练与评测数据集
- 记录依赖包及版本的环境文件
requirements.txt
多轮对话语料往往存在噪声大、结构不一致等问题。与单轮指令数据相比,它更容易出现话题漂移、重复闲聊、信息推进不足,以及多轮之间回答格式不匹配等现象。MDS 从对话级数据选择的角度来解决这一问题。
MDS 包含两个阶段:
-
全局阶段
MDS 首先在用户查询轨迹空间中表示每个对话,将对话聚类到语义 bin 中,并在每个 bin 内进行带冗余控制的候选选择。该阶段旨在尽量保留广泛的语义覆盖,同时避免高频交互模式被过度选中。 -
局部阶段
MDS 随后通过对话级结构打分进一步精炼全局候选池,其中包括基于实体的信号以及问答形式/风格一致性信号。最终训练子集通过带预算约束的 bin-wise 方式选出。
论文中的完整流程为:
dialogue pool -> global-stage candidate construction -> local-stage selection -> disk-style train/eval data -> model training -> model prediction -> evaluation
本仓库主要覆盖其中的数据选择、数据转换和评测部分。
本仓库包含以下组成部分:
-
mds_global_stage.py
在用户查询轨迹空间中进行全局阶段的对话选择。 -
mds_local_stage.py
进行局部阶段的对话打分与最终按 bin 预算选择。 -
build_disk_data.py
将选出的训练对话和公开的评测对话转换为下游训练或评测所需的 disk-style 数据格式。 -
mds_dialogue_eval.py
用于模型预测文件的统一评测脚本。
requirements.txt
列出本仓库所需依赖包及版本的环境文件。
-
data/train/baize_chat_data_use.jsonlbanking_train_50k_use.jsonl
-
data/eval/banking_test_300.jsonlConsistentChat_use_270.jsonldialogue_test_unseen_use.jsonlmt_eval_part_use.jsonl
.
├── README.md
├── README_zh.md
├── requirements.txt
├── mds_global_stage.py
├── mds_local_stage.py
├── build_disk_data.py
├── mds_dialogue_eval.py
├── data/
│ ├── train/
│ │ ├── baize_chat_data_use.jsonl
│ │ └── banking_train_50k_use.jsonl
│ └── eval/
│ ├── banking_test_300.jsonl
│ ├── ConsistentChat_use_270.jsonl
│ ├── dialogue_test_unseen_use.jsonl
│ └── mt_eval_part_use.jsonl
└── outputs/
典型流程如下:
data/train/*.jsonl
-> mds_global_stage.py
-> outputs/mds_global_candidates*.jsonl
-> mds_local_stage.py
-> outputs/mds_final_selected*.jsonl
-> build_disk_data.py
-> disk-style train / eval data
-> model training (external to this repo)
-> model inference (external to this repo)
-> mds_dialogue_eval.py
建议使用 Python 3.10 及以上版本。
可按你喜欢的方式安装环境,例如:
pip install -r requirements.txt根据你的运行环境,可能还需要额外安装 GPU 相关依赖。
公开的训练对话数据位于:
data/train/
当前训练文件:
baize_chat_data_use.jsonlbanking_train_50k_use.jsonl
这些文件用于运行 MDS 的数据选择流程。
公开的评测数据位于:
data/eval/
当前评测文件:
banking_test_300.jsonlConsistentChat_use_270.jsonldialogue_test_unseen_use.jsonlmt_eval_part_use.jsonl
这些文件用于评测,或转换为 disk-style 的评测数据。
每一行 JSONL 表示一个对话级样本。
本仓库默认推荐的数据格式如下:
{
"messages": [
{"content": "I want to know the step by step guide to invest in share market in India.", "role": "user"},
{"content": "Sure, I can help with that. Firstly, you need to open a demat and trading account with a registered stockbroker.", "role": "assistant"},
{"content": "How do I find a registered stockbroker in India?", "role": "user"},
{"content": "You can visit the websites of National Stock Exchange (NSE) or Bombay Stock Exchange (BSE) to get a list of registered stockbrokers in India.", "role": "assistant"},
{"content": "What documents are required to open a demat and trading account?", "role": "user"},
{"content": "You will need to provide identity proof (PAN card), address proof, bank details and a passport size photograph to open a demat and trading account.", "role": "assistant"},
{"content": "How do I start trading once I have a demat and trading account?", "role": "user"},
{"content": "You can start trading by placing buy and sell orders for stocks through your stockbroker either online or offline.", "role": "assistant"},
{"content": "How do I track my investments?", "role": "user"},
{"content": "You can track your investments through your demat account. It will provide you with a consolidated view of all your investments in various stocks and other financial instruments.", "role": "assistant"}
],
"id": "conv_id_0"
}要求:
messages必须是对话轮次列表- 每一轮都必须包含
role和content role通常为user或assistantid应唯一标识该对话
公开脚本也可能支持一些相近变体,但以上格式是推荐默认格式。
训练对话文件应为 JSONL 格式,每行一个对话。
本仓库主要使用的格式为:
{
"messages": [
{"role": "user", "content": "User utterance 1"},
{"role": "assistant", "content": "Assistant reply 1"},
{"role": "user", "content": "User utterance 2"},
{"role": "assistant", "content": "Assistant reply 2"}
],
"id": "conv_id_xxx"
}选择脚本会保留原始对话内容,并可能附加如下元数据:
conv_idbin_id/cluster_id- 与选择相关的中间字段
- 局部阶段分数
具体字段取决于脚本配置和中间处理步骤。
评测脚本接收 JSONL 格式的预测文件。
每一行至少应包含:
{
"idx": 0,
"conv_id": "dialog_001",
"turn_index": 3,
"prompt": "<prompt string>",
"gold": "reference answer",
"prediction": "model output"
}评测脚本会把各类指标追加到每条记录中,也可以保存汇总统计信息。
全局阶段会从用户轮次构建对话表示,将对话聚类到语义 bin 中,并在每个 bin 内进行覆盖性与冗余控制下的候选选择。
示例:
python mds_global_stage.py \
--input_jsonl data/train/baize_chat_data_use.jsonl \
--output_jsonl outputs/mds_global_candidates.jsonl \
--output_ids_json outputs/mds_global_candidate_ids.json \
--n_clusters 1000 \
--retain_ratio 0.5 \
--min_keep_per_cluster 5 \
--lambda_mmr 0.5主要输出:
- 候选对话 JSONL
- JSON 格式的已选对话 ID 列表
局部阶段通过对话级结构打分进一步精炼候选池,并执行带预算约束的最终选择。
示例:
python mds_local_stage.py \
--input_jsonl outputs/mds_global_candidates.jsonl \
--output_jsonl outputs/mds_final_selected.jsonl \
--output_ids_json outputs/mds_final_selected_ids.json \
--judge_model /path/to/judge_model \
--budget 10000 \
--tau_form 1.0主要输出:
- 最终选中的对话 JSONL
- JSON 格式的最终对话 ID 列表
转换脚本会将多轮对话展开为逐轮样本,并以 disk-style 格式保存,供下游训练或评测使用。
示例:
python build_disk_data.py运行前请在脚本中更新以下路径:
- 模型路径
- 输入 JSONL 文件路径
- 输出根目录
默认情况下,转换脚本会在配置的输出根目录下保存:
train/下的训练集eval/下的评测集
完成对话选择后,选中的对话会被展开成 turn-level 的监督样本,并用于标准 chat-style 监督微调。你可以使用常见的 SFT / LoRA 训练框架完成这一步。
一个典型训练流程如下:
- 在原始对话池上运行 MDS 全局阶段选择
- 运行 MDS 局部阶段选择,获得最终子集
- 将选出的对话转换为 disk-style 训练数据
- 在处理后的逐轮样本上微调 backbone chat 模型
- 在评测集上运行推理
- 使用
mds_dialogue_eval.py对预测结果进行评测
你可以使用任意标准 chat 推理流程,对转换后的评测数据生成预测结果。
最终预测文件应符合前文给出的评测 JSONL 格式。
评测脚本为多种指标提供统一接口。
示例:
python mds_dialogue_eval.py运行前请更新脚本中的相关设置,例如:
- OpenAI-compatible API 配置
- 评测输入文件路径
- 输出文件路径
- 启用 / 关闭的指标开关
- 如有需要的 embedding 模型路径
统一评测脚本支持以下指标:
-
LLM-EVAL
- content
- grammar
- relevance
- appropriateness
- overall
-
G-EVAL
- coherence
- naturalness
- engagement
- groundedness
- overall
-
Entity-F1
- 基于 GPT 的实体抽取
- 抽取实体上的 micro F1
-
Embedding cosine similarity
- 基于 sentence-transformers
-
BLEU-3
- 基于 sacreBLEU
-
ROUGE-L
- 基于 rouge-score
- GPT 类指标需要有效的 API 配置。
- 在较大的测试集上,受模型接口和速率限制影响,GPT 类评测可能耗时较长。
- 不同 API 后端或 judge 模型可能会带来轻微分数波动。
一个最小可运行的端到端流程如下:
# 1. 全局阶段选择
python mds_global_stage.py \
--input_jsonl data/train/baize_chat_data_use.jsonl \
--output_jsonl outputs/mds_global_candidates.jsonl \
--output_ids_json outputs/mds_global_candidate_ids.json
# 2. 局部阶段选择
python mds_local_stage.py \
--input_jsonl outputs/mds_global_candidates.jsonl \
--output_jsonl outputs/mds_final_selected.jsonl \
--output_ids_json outputs/mds_final_selected_ids.json \
--judge_model /path/to/judge_model \
--budget 10000 \
--tau_form 1.0
# 3. 转换选中训练/评测数据为 disk 格式
python build_disk_data.py
# 4. 使用任意标准 SFT / LoRA 框架训练模型
# 5. 在评测数据上运行推理
# 6. 评测预测文件
python mds_dialogue_eval.py主要功能:
- 读取对话级 JSONL 文件
- 提取用户查询轨迹表示
- 计算对话嵌入
- 将对话聚类到语义 bin 中
- 执行 bin-wise 的 MMR 风格候选选择
主要功能:
- 规范化对话格式
- 从对话中抽取 QA 对
- 使用 judge model 做逐轮形式/风格分析
- 计算局部结构信号
- 执行按 bin 预算约束的最终选择
主要功能:
- 读取选中的训练对话和评测对话文件
- 将每个对话展开为 turn-level 的监督样本
- 对 prompt 和 label 进行 tokenize
- 以 disk-style 格式保存处理后的数据集
主要功能:
- 读取预测 JSONL 文件
- 计算 GPT 类和本地自动指标
- 保存逐样本结果
- 保存或打印汇总结果
在大 batch 或严格速率限制下,GPT 类评测可能出现超时。
建议处理方式:
- 减少 worker 数量
- 降低请求并发
- 重试失败样本
- 适当增大超时设置
运行前请先在转换脚本中更新 tokenizer / model 路径。
如果你的对话 JSONL 不符合推荐的 messages + role + content + id 格式,可能需要在运行流程前增加一个轻量预处理步骤。
为了更稳定地复现结果,建议在不同运行中固定局部阶段使用的 judge model。
这是预期行为。本仓库主要公开与选择和评测直接相关的部分,训练和预测阶段可使用标准 chat 微调框架复现。
@misc{li2026dataselectionmultiturndialogue,
title = {Data Selection for Multi-turn Dialogue Instruction Tuning},
author = {Bo Li and Shikun Zhang and Wei Ye},
year = {2026},
eprint = {2604.07892},
archivePrefix = {arXiv},
primaryClass = {cs.CL},
url = {https://arxiv.org/abs/2604.07892}
}