从数据集划分理解大模型的数据工程

大模型为什么"聪明":从数据集划分到数据工程的一次入门梳理

很多人聊大模型时,会先想到参数量、GPU、Transformer、推理速度,但真正决定模型上限的,往往还有一个更基础的问题:数据。

如果把大模型训练类比成人学习,算力像学习时能投入的时间和精力,算法像学习方法,而数据就是教材、作业和考试题。没有高质量、结构清晰、覆盖充分的数据,再强的算力和算法也很难训练出稳定可靠的模型。

这篇文章结合一个中文点评情感分类数据集,梳理三个问题:

  • LLM 的智能主要从哪里来
  • 训练集、验证集、测试集分别解决什么问题
  • 数据集如何划分,以及常见划分方式里容易踩的坑

一、LLM 的智能从哪里来

大模型能力通常可以粗略理解为三部分共同作用:

  • 数据:模型学习语言、知识、任务模式和统计规律的来源
  • 算力:支撑海量数据训练和模型参数更新的计算资源
  • 算法:包括 Transformer 架构、优化方法、损失函数、训练策略等

其中,数据非常关键。

模型并不是简单地把训练语料"背下来",而是在大量样本中学习词语、句子、知识、任务目标之间的关联规律。训练之后,它需要面对从未见过的新输入,并给出尽量符合上下文、知识和任务要求的输出。

所以,大模型训练里的"聪明",更准确地说来自:

  • 大规模、高质量、低噪声的数据
  • 合理的数据组织方式
  • 训练、验证、测试之间清晰的边界
  • 持续的数据清洗、去重、评估和迭代

二、训练集、验证集、测试集分别是什么

在机器学习里,一个完整数据集通常会被拆成三部分:

数据集 英文 类比 作用
训练集 training set 教材 让模型学习数据中的规律
验证集 validation set 课后作业 辅助开发者调参、选模型
测试集 test set 期末考试 评估最终模型在未知数据上的泛化能力

1. 训练集:让模型学习规律

训练集是模型真正参与训练的数据。

比如在情感分类任务中,一条样本可能长这样:

python 复制代码
{
    "sentence": "纯粹的就是一般性的超市,没什么特点,就是觉得酸奶特别便宜而已......",
    "label": 0,
    "dataset": "dianping"
}

模型会基于大量类似样本,学习文本和标签之间的关系。比如哪些表达更可能对应负向评价,哪些表达更可能对应正向评价。

2. 验证集:帮助开发者调模型

验证集不直接参与参数训练,而是在训练过程中反复用来观察模型效果。

它的主要用途包括:

  • 判断模型是否还在变好
  • 调整学习率、batch size、训练轮数等超参数
  • 选择不同训练方案中效果更好的版本
  • 观察模型是否出现过拟合

验证集有点像平时作业。它不参与最终考试评分,但会告诉你当前学习方法有没有问题。

3. 测试集:评估最终泛化能力

测试集应该尽量只在最后使用。

它的目标是回答一个问题:模型在没有见过的数据上,表现到底怎么样?

如果开发过程中频繁查看测试集,并根据测试集结果反复调参,模型和开发决策就会逐渐"适应"测试集,最终评估结果可能虚高。这通常可以理解为测试集污染,属于数据泄漏风险的一种表现。

三、用 ModelScope 数据集做一个划分示例

示例中使用的是魔搭社区的 DAMO_NLP/yf_dianping 数据集。它是一个中文点评类文本数据集,每条样本包含:

  • sentence:评论文本
  • label:分类标签
  • dataset:数据来源标识

加载方式如下:

python 复制代码
from modelscope.msdatasets import MsDataset

full_ms_ds = MsDataset.load(
    "DAMO_NLP/yf_dianping",
    subset_name="default",
    split="train"
)

full_ms_ds[44983]

因为这个数据集原始只提供了一个 train split,所以我们需要自己再切分出训练集、验证集和测试集。

四、一个容易出错的划分方式

很多人会这样写:

python 复制代码
full_hf_ds = full_ms_ds.to_hf_dataset()

split1 = full_hf_ds.train_test_split(test_size=0.1, seed=42)

train_temp_hf = split1["train"]  # 90%
test_hf = split1["test"]         # 10%

split2 = train_temp_hf.train_test_split(test_size=0.1, seed=42)

train_hf = split2["train"]
val_hf = split2["test"]

这段代码本身能运行,但比例并不是很多人以为的 80% / 10% / 10%

原因是第二次切分的 test_size=0.1,切的是剩余 90% 里的 10%,所以最终比例是:

  • 测试集:原始数据的 10%
  • 验证集:90% * 10% = 9%
  • 训练集:90% * 90% = 81%

也就是约 81% / 9% / 10%

如果这是你想要的比例,没问题。但如果你想得到常见的 80% / 10% / 10%,代码就应该改一下。

五、正确切分 80% / 10% / 10%

一种更直观的写法是:先切出 20% 临时集合,再把这 20% 平分成验证集和测试集。

python 复制代码
full_hf_ds = full_ms_ds.to_hf_dataset()

# 先切出 80% 训练集,20% 临时集合
split1 = full_hf_ds.train_test_split(test_size=0.2, seed=42)

train_hf = split1["train"]       # 80%
temp_hf = split1["test"]         # 20%

# 再把 20% 临时集合平分为验证集和测试集
split2 = temp_hf.train_test_split(test_size=0.5, seed=42)

val_hf = split2["train"]         # 10%
test_hf = split2["test"]         # 10%

print(f"训练集 train:{len(train_hf)}")
print(f"验证集 val:{len(val_hf)}")
print(f"测试集 test:{len(test_hf)}")
print("\n单条样本:", train_hf[0])

这段代码的语义更清晰:

  • 训练集负责学习
  • 验证集负责调参和选模型
  • 测试集负责最终评估

同时,seed=42 可以保证每次随机切分结果可复现。实际项目中,固定随机种子非常重要,否则每次运行得到的数据集不同,实验结果也就很难对比。

由于样本总数不一定能被 10 整除,最终三个集合的实际条数可能会有 1 条左右的取整差异,但整体比例仍然接近 80% / 10% / 10%

对于分类任务,还要额外关注标签分布。如果正负样本比例明显不均衡,最好使用分层抽样,让训练集、验证集、测试集里的标签比例尽量接近原始数据。否则某个集合可能恰好抽到过多正样本或负样本,评估结果会不稳定。

六、为什么不能只做一次固定划分

固定的 8:1:1 划分简单、直观,也是很多项目的默认选择。但它有一个问题:结果可能受单次随机划分影响。

比如某一次切分时,验证集刚好更简单,模型效果看起来就会偏高;或者验证集刚好更难,模型效果看起来就会偏低。

这时可以考虑交叉验证。

七、K 折交叉验证是什么

K 折交叉验证的核心思想是:让每一份数据都有机会做一次验证集。

假设 K=5,流程大致是:

  1. 把数据集分成 5 份
  2. 第 1 轮:第 1 份做验证集,其余 4 份做训练集
  3. 第 2 轮:第 2 份做验证集,其余 4 份做训练集
  4. 重复 5 轮
  5. 汇总 5 次验证结果,得到更稳定的评估

这里有一个细节很重要:K 折交叉验证不是同一个模型连续训练 5 次,而是每一轮通常都重新初始化并训练一个新模型。

它主要用于更可靠地评估模型表现,减少一次随机划分带来的偶然性。

不过,在大模型训练里,完整 K 折训练成本通常非常高,所以它更常见于传统机器学习、小模型、数据量较小或实验验证阶段。对于大规模模型,更常见的是维护高质量验证集、测试集和专项评测集。

八、大模型时代的数据工程更像一个循环系统

在传统项目里,数据处理可能是一次性的:

text 复制代码
采集 -> 清洗 -> 标注 -> 训练

但在 LLM 时代,数据工程更像一个持续循环的系统:

text 复制代码
采集 -> 清洗 -> 去重 -> 标注 -> 训练 -> 评估 -> 发现问题 -> 重新采样和清洗

其中有几个非常关键的环节。

1. 数据清洗

原始数据里经常会有乱码、重复、广告、低质量文本、格式不统一等问题。

如果这些数据直接进入训练集,模型会学习到很多噪声,最终表现也会受到影响。

2. 数据去重

去重不只是为了节省存储,更是为了降低模型记忆重复样本的风险。

如果测试集中的样本在训练集中出现过,测试结果就不再可信。模型可能不是学会了泛化,而是见过答案。

3. 数据污染检测

数据污染指的是评测数据、测试数据或答案泄漏进训练数据。

这在大模型评测中尤其重要,因为一旦测试题进入训练集,评测分数就很难代表真实能力。

4. 知识覆盖率分析

数据不是越多越好,还要看覆盖是否均衡。

如果语文类数据很多,数学、编程、英文、法律、医学等领域数据不足,模型能力就会出现明显偏科。数据工程需要持续分析不同知识领域、任务类型、难度层级的覆盖情况。

5. 多验证集与阶段性评估

验证标准不一定只有一套。

在一些复杂训练流程中,团队通常会维护多个相对固定的验证集或评测集,例如:

  • 通用能力验证集
  • 代码能力验证集
  • 数学推理验证集
  • 安全对齐验证集
  • 长文本理解验证集
  • 多轮对话验证集

不同训练阶段关注不同指标,评估时也会选择不同集合来观察模型短板。但要注意,同一项指标前后对比时,评测集合和统计口径应该保持稳定,否则结果就不具备可比性。

九、一个更工程化的理解

从模型训练视角看,数据集不是简单的文件集合,而是一套工程系统。

训练集决定模型能学到什么,验证集决定开发者如何调整训练过程,测试集决定最终评估是否可信。数据采集、清洗、去重、标注、污染检测、覆盖率分析,则决定了这套系统能不能持续产出高质量样本。

所以,大模型能力并不只来自"模型很大"。

更准确地说,它来自数据、算力、算法共同作用;而在很多时候,数据质量和数据组织方式,决定了模型能力的天花板。

总结

本文围绕数据集做了一个入门梳理:

  • LLM 的能力来自数据、算力和算法的共同作用
  • 训练集用于学习,验证集用于调参和选模型,测试集用于最终评估
  • 二次随机切分时要注意比例,90% 里再切 10% 得到的是总量的 9%
  • 如果想切出 80% / 10% / 10%,可以先切 80% / 20%,再把 20% 平分
  • 分类任务要关注标签分布,必要时使用分层抽样
  • K 折交叉验证可以降低单次随机划分带来的偶然性
  • 大模型时代的数据工程是持续循环的系统,不是一次性处理流程

一句话概括:模型之上,是数据的艺术;模型之下,是数据的地基。

相关推荐
用户8299792943931 小时前
一文带你彻底搞懂claude code中的上下文压缩
人工智能
IT_陈寒2 小时前
Vue的这个响应式陷阱让我熬到凌晨三点
前端·人工智能·后端
冬奇Lab11 小时前
Workflow 系列(01):基础理论——三种执行模型与 Anthropic 5 种模式
人工智能·agent·工作流引擎
冬奇Lab11 小时前
每日一个开源项目(第143篇):page-agent - 纯 JS 的网页 GUI Agent,无需截图、无需插件、无需后端
前端·人工智能·agent
程序员cxuan13 小时前
虽迟但到!GPT-5.6 终于来了!
人工智能·后端·程序员
ZhengEnCi15 小时前
Q03-UI设计进阶技巧-让界面更高级的7个核心原则
人工智能
IT_陈寒16 小时前
React的这个渲染问题连官方文档都没说清楚
前端·人工智能·后端
不加辣椒17 小时前
第12章 工具调用与 Agent 提示工程
人工智能
用户16931761726617 小时前
前端给AI消息做日期分组与时间线
人工智能