最近在 GRPO 强化学习训练中用到了 DAPO-Math-17k 数据集,一开始理所当然地 load_dataset("BytedTsinghua-SIA/DAPO-Math-17k"),结果踩了两个大坑。
一、数据量异常:1.7 万变 170 万
HuggingFace 上 BytedTsinghua-SIA/DAPO-Math-17k 显示约 1.7M 行,名字里的"17k"让人困惑。实际跑起来发现一个 Epoch 要跑几十个小时,显存和时间暴涨。
原因很简单:官方仓库上传了 100 倍的重复数据。17,000 条原始数据被复制粘贴了约 100 次,变成了 1,700,000 行。导致:
- 显存与时间暴涨:原本几小时跑完的 Epoch,平白无故多跑 100 倍
- 模型严重过拟合:同一个 Epoch 内反复死记硬背完全相同的数学题,泛化能力彻底崩塌
这也是为什么 Open-R1 团队推出了 open-r1/DAPO-Math-17k-Processed,去重后只保留最原始的 1.7 万多条唯一数据。
二、字段改名:prompt 变 source_prompt
本以为切到 Processed 版就万事大吉,结果又报 ValueError: num_samples should be a positive integer。
原因是 Processed 版把字段名从 prompt(原版)改成了 source_prompt,answer 字段也变成了 solution。代码里还在用 dataset["train"]["prompt"],自然拿到空列。
三、正确用法
我使用的是 verl(Volcano Engine Reinforcement Learning)框架,这是字节跳动开源的 LLM 强化学习训练框架,支持 PPO/GRPO 等算法,底层兼容 vLLM 推理。
方案 A:直接改 verl 框架参数(推荐)
verl 框架本身就支持通过配置参数映射数据字段,不需要改数据集也不需要改代码:
# verl 训练配置中直接指定字段映射
data.prompt_key=source_prompt
data.response_key=solution
这样 verl 会自动从 source_prompt 列取 prompt,从 solution 列取 response,一行配置搞定。
方案 B:load 时 rename_column(备选)
如果不想改框架配置,也可以在加载数据时做字段重命名:
from datasets import load_dataset
dataset = load_dataset("open-r1/DAPO-Math-17k-Processed")
dataset = dataset.rename_column("source_prompt", "prompt")
dataset = dataset.rename_column("solution", "response")
prompts = dataset["train"]["prompt"]
四、两个坑对照
| 坑 | 现象 | 修复 |
|---|---|---|
| 数据重复 | 原版 1.7M 行 = 17k × ~100 次重复 | 用 open-r1/DAPO-Math-17k-Processed |
| 字段改名 | Processed 版 prompt → source_prompt | verl: 设 data.prompt_key / response_key |
总结
- 千万不要直接用
BytedTsinghua-SIA/DAPO-Math-17k的 100 多万条训练 - 务必使用去重后的
open-r1/DAPO-Math-17k-Processed - verl 框架用户直接配
data.prompt_key=source_prompt+data.response_key=solution,零代码改动 - 其他框架用户可用
rename_column做字段映射
简记。







