跳转至

数据混合与课程

多源训练不是把若干数据集拼接后随机打乱。采样单位、文档长度、截断、loss mask 和重复暴露共同决定每个来源的实际梯度权重;课程学习则让这个分布随训练进度变化。

问题

按语料规模比例采样会让高资源来源占主导;提高低资源来源概率又可能快速重复并造成记忆。理想配比取决于目标能力、模型规模、token 预算、训练阶段和来源质量,不存在可跨任务照搬的固定比例。

数学契约

文档概率与 token share

设每次先以概率 \(p_i\) 选择来源 \(i\),再从中抽一条文档;该来源平均产生 \(\mu_i\) 个有效 loss token。长期真实 token share 为

\[ q_i =\frac{p_i\mu_i} {\sum_j p_j\mu_j}. \]

只有当各来源都生成等长、等 mask 比例的训练序列时,才近似有 \(q_i=p_i\)。因此 sampler 配置必须与训练日志中的实际 token 计数同时保存。

最小语义实现

若已经给定目标 token share \(q_i\) 与每次抽样的平均有效长度 \(\mu_i\),document_prob 反解文档采样概率 \(p_i\propto q_i/\mu_i\);observed_token_share 则把候选概率映射回预期 token 占比。输入输出都位于概率单纯形上。

import torch

def mixture_inputs(probability, mean_loss_tokens):
    probability = torch.as_tensor(probability, dtype=torch.float64)
    mean_loss_tokens = torch.as_tensor(
        mean_loss_tokens, dtype=torch.float64, device=probability.device
    )
    if (probability.ndim != 1 or probability.numel() == 0
            or probability.shape != mean_loss_tokens.shape):
        raise ValueError("probability and token mass must be aligned vectors")
    if not torch.isfinite(probability).all() or not torch.isfinite(mean_loss_tokens).all():
        raise ValueError("mixture inputs must be finite")
    if torch.any(probability < 0) or not torch.isclose(
            probability.sum(), probability.new_tensor(1.)):
        raise ValueError("probability must lie on the simplex")
    if torch.any(mean_loss_tokens <= 0):
        raise ValueError("mean loss-token mass must be positive")
    return probability, mean_loss_tokens

def document_prob(target_token_share, mean_loss_tokens):
    q, mu = mixture_inputs(target_token_share, mean_loss_tokens)
    unnormalized = q / mu
    mass = unnormalized.sum()
    if not torch.isfinite(unnormalized).all() or not torch.isfinite(mass) or mass <= 0:
        raise ValueError("derived document probability has invalid mass")
    return unnormalized / mass

def observed_token_share(prob, mean_loss_tokens):
    prob, mu = mixture_inputs(prob, mean_loss_tokens)
    mass = prob * mu
    total = mass.sum()
    if not torch.isfinite(mass).all() or not torch.isfinite(total) or total <= 0:
        raise ValueError("observed token share has invalid mass")
    return mass / total

正常 round-trip 之外,回归还覆盖 shape 广播、非有限数、非单纯形,以及零、负或非有限 token mass。

q = torch.tensor([0.5, 0.5], dtype=torch.float64)
p = document_prob(q, [100., 400.])
torch.testing.assert_close(p, torch.tensor([0.8, 0.2], dtype=torch.float64))
torch.testing.assert_close(observed_token_share(p, [100., 400.]), q)
bad_inputs = [
    ([.5, .5], [100.]),
    ([.5, float("nan")], [100., 400.]),
    ([1.1, -.1], [100., 400.]),
    ([.4, .4], [100., 400.]),
    ([.5, .5], [100., 0.]),
    ([.5, .5], [100., -1.]),
    ([.5, .5], [100., float("inf")]),
]
for probability, token_mass in bad_inputs:
    try:
        document_prob(probability, token_mass)
    except ValueError:
        continue
    raise AssertionError("invalid mixture input must be rejected")
for probability, token_mass in [
        ([[.5, .5]], [[100., 400.]]), ([0., 0.], [100., 400.])]:
    try:
        observed_token_share(probability, token_mass)
    except ValueError:
        continue
    raise AssertionError("broadcast or zero-mass probability must be rejected")

这是稳态期望而不是执行器:截断、过滤失败、无放回采样和随时间变化的长度都会让实测比例偏离,因此训练日志仍要按来源累计真实 loss token。每个 token 的归一化怎样影响最终梯度,可继续对照训练目标:Token-normalized cross entropy。

若来源 \(i\) 有 \(N_i\) 个可用 token,整个训练消费 \(T\) 个有效 token,则平均重复暴露约为

\[ E_i=\frac{Tq_i}{N_i}. \]

\(E_i=1\) 不是严格的“每条样本恰好一次”:有放回采样、长度窗口和动态过滤会让样本暴露不均。它仍是发现小来源被过度重复的重要审计量。

温度采样

以来源规模 \(n_i\) 构造

\[ p_i =\frac{n_i^\alpha} {\sum_j n_j^\alpha}, \qquad 0<\alpha\le 1. \]

\(\alpha<1\) 会提高小来源的文档概率,却不保证目标 token share;还需要代入 \(\mu_i\) 并检查 \(E_i\)。温度只是平滑规模差异,不会自动识别数据质量和任务价值。

动态课程

阶段 \(s\) 的分布可写成

\[ p_i^{(s)}=p_i(\tau_s,\mathcal M_s), \]

其中 \(\tau_s\) 是训练 token 进度,\(\mathcal M_s\) 是截至该阶段的损失、质量与覆盖测量。课程必须预先定义切换依据和最大重复暴露,不能在看到 benchmark 结果后任意调整并仍把测试集称为独立评测。

配比机制

受控基线

先建立三种基线:

  1. 按有效 token 规模比例;
  2. 统一来源概率;
  3. 一个有明确目标和重复上限的人工配比。

任何自适应方法都应与相同模型、token 预算和优化配方下的这些基线比较。

验证损失驱动

DoReMi 使用小代理模型和相对参考损失学习领域权重,目标是改善最差领域的相对表现。它依赖领域划分、参考模型、代理到目标规模的迁移和 held-out 数据,不应被简化为“按 loss 越大采得越多”。

代理实验搜索

RegMix 在较小规模上训练多种 mixture,并用回归预测更大训练的候选配比。它把配比当成实验设计问题,但代理规模、目标指标和候选空间仍决定外推质量。数据处理或模型架构变化后,旧回归不再自动有效。

阶段式退火

后期提高高质量、目标域或长上下文数据的权重,可以改变训练末端分布;同时也可能:

  • 过度重复小集合;
  • 降低语言和领域覆盖;
  • 把格式偏好误当能力提升;
  • 与学习率 decay、长度增长同时变化,导致无法归因。

退火阶段应保留通用 replay,并用独立消融分开数据切换与优化器日程。

执行契约

每个训练区间记录:

mixture version and stage
sampling unit and replacement rule
nominal document probabilities
observed documents / raw tokens / loss tokens
truncation and mask ratios
unique coverage and repeated exposure
per-source loss and evaluation slices
RNG, shard order and data cursor

数据源耗尽、解析失败或动态过滤不得静默回退到其他来源。任何实际配比偏离都要显式计数和告警。

正确性与失效

  • 用样本数报告配比:长文档或长回答来源的有效 token 权重被隐藏。
  • 重复度只按 epoch 计算:有放回采样和窗口切分下,epoch 不能描述每条内容的暴露。
  • 自适应权重追逐噪声:小验证集的随机波动被放大为大幅配比变化。
  • 领域标签过粗:同一来源内部的语言、时间和质量差异被平均。
  • 代理模型结论直接外推:规模、tokenizer 或优化配方改变后最优混合可能迁移。
  • 训练与评测共用反馈:反复根据测试分数调 mixture 会耗尽测试集独立性。
  • 课程变量同时改变:数据、长度和学习率一起切换,收益无法归因。

何时使用简单配比

来源数量少、规模接近、目标与训练分布一致且重复暴露很低时,按有效 token 比例可能是最可靠的起点。数据或预算不足以支持多次代理训练时,也应优先使用透明基线与小范围消融,而不是引入无法验证的自适应 sampler。

验证

  1. 对每个来源同时画 nominal \(p_i\)、observed document share、raw token share 和 loss-token share。
  2. 报告 \(E_i\)、unique document coverage 与 cluster-level 重复度。
  3. 用固定 held-out slice 比较每个阶段前后的收益和遗忘。
  4. 在相同总 token、长度分布、学习率和模型初始化下做 mixture 消融。
  5. 恢复 checkpoint 后验证 data cursor、累计 token 和下一批来源完全连续。
  6. 对低资源来源抽查是否因过滤器或 tokenizer 膨胀而被系统性削弱。

从文档到有效 token 的细节见序列构造与打包,训练预算与规模外推见规模律与实验设计。

GLM-5:按能力轴改变数据,而非只调来源权重

GLM-5 的数据课程同时沿质量、领域、长度与交互结构变化。网页使用基于句向量的 DCLM 风格分类器和 world-knowledge classifier;代码侧增加模糊去重后的独特 token、修复 Software Heritage 元数据并强化低资源语言;数学与科学部分由模型评分,并明确不混入该部分的合成、AI 生成或模板数据。mid-training 再加入约千万 issue–PR 对、过滤后约 160B unique tokens,以及自然和合成长序列。

这类课程不能只保存一个最终 percentage。至少应为每阶段记录 source × domain × language × length × provenance × synthetic 的实际 loss-token 张量,并单列 issue–PR 的原始对数、过滤后 unique tokens 与采样暴露。GLM-5 没有公开完整 mixture 权重与过滤器,因此这些做法提供的是设计坐标,不是可逐项复刻的数据配方。详见 GLM-5 的数据阶段。

Reference