第 7 章 第二部分:预训练数据工程

数据混合配比(核心)

配比决定模型性格——静态配比(Llama-1)、DoReMi动态配比(Group DRO)、RegMix学习式配比(LightGBM)、阶段化配方、退火策略详解

数据配比 DoReMi RegMix 静态配方 阶段化配方 退火策略

数据质量决定上限,数据配比决定性格。

多代码→编程强;多论文→推理强;多对话→闲聊强——配方是模型的灵魂。


7.1 为什么配比是核心

7.1.1 配比 = 模型性格

不同数据配比训出来的模型,能力天差地别:

配方模型性格代表
网页 95%通用对话型,闲聊强,推理弱早期 GPT-3
网页 60% + 代码 30%编程强,通用 OK,推理 OKCode Llama
网页 50% + 数学 30% + 论文 20%推理极强,编程 OKDeepSeek-Math
网页 70% + 多语 30%多语种强BLOOM, Qwen

7.1.2 经典实证:Llama-1 配方

Llama-1(Meta, 2023)首次公开了详细的预训练配方:

Llama-1 经典配方 (1T tokens):
  English CommonCrawl:  67%
  C4:                   15%
  GitHub:               4.5%
  Wikipedia:            4.5%
  Books:                4.5%
  ArXiv:                2.5%
  StackExchange:        2%

这个配方成为后续开源模型的基准,但它的问题也很明显——配比是静态的,整个训练过程不变。

7.1.3 静态 vs 动态配比

方式优点缺点
静态配比简单、可解释、可复现不能优化、不适应数据变化
动态配比自动优化、效果更好复杂、需要小模型消融
学习式配比数据驱动、可解释需要训练分类器

7.2 静态配比:Llama-1 经典配方

7.2.1 Llama-1 配方解析

# Llama-1 静态配方
pretrain_mix:
  - source: 'cc_filtered'       # 过滤后的 CC
    weight: 0.67
    tokens: 670B
  - source: 'c4'                # C4 数据集
    weight: 0.15
    tokens: 150B
  - source: 'github_clean'      # 高质量 GitHub
    weight: 0.045
    tokens: 45B
  - source: 'wikipedia'         # 多语种 Wiki
    weight: 0.045
    tokens: 45B
  - source: 'books3'            # 书籍
    weight: 0.045
    tokens: 45B
  - source: 'arxiv'              # 学术论文
    weight: 0.025
    tokens: 25B
  - source: 'stackexchange'     # 问答
    weight: 0.020
    tokens: 20B

total_tokens: 1T

7.2.2 静态配比的实现

import numpy as np

class StaticMixer:
    """静态配比采样器"""
    
    def __init__(self, sources_weights):
        """
        sources_weights: dict, {source: weight}
        权重之和应为1
        """
        # 归一化
        total = sum(sources_weights.values())
        self.weights = {k: v/total for k, v in sources_weights.items()}
        
        # 计算每个 source 的目标 token 数
        self.sources_tokens = {}
    
    def sample(self, target_tokens):
        """
        按权重采样到目标 token 数
        """
        for source, weight in self.weights.items():
            self.sources_tokens[source] = int(target_tokens * weight)
        
        return self.sources_tokens

# Llama-1 经典配方
llama1_mix = {
    'cc_filtered': 0.67,
    'c4': 0.15,
    'github_clean': 0.045,
    'wikipedia': 0.045,
    'books3': 0.045,
    'arxiv': 0.025,
    'stackexchange': 0.020,
}

mixer = StaticMixer(llama1_mix)
print(mixer.sample(target_tokens=1_000_000_000_000))  # 1T tokens

7.2.3 静态配比的局限

Llama-1 用静态配比训出来效果不错,但存在三个问题:

  1. 配比靠经验:67% CC 是 Meta 工程师拍脑袋的,没有理论依据
  2. 训练全程不变:早期应该多通用、晚期应该多高质量精选
  3. 不适应数据变化:如果某个 source 突然变小,配比自动失效

7.3 DoReMi:动态配比的开山之作

DoReMi(Xie et al., 2023)是第一个被广泛认可的动态配比方法,核心思想:用 Group DRO(Distributionally Robust Optimization)自动调整配比。

7.3.1 核心思想

DoReMi 分两阶段:

  1. Reference 阶段:用初始配比训练一个小的 reference 模型
  2. Domain Weight 阶段:基于 reference 模型在各个 domain 上的 loss,自动调整权重——loss 大的 domain 加权重,loss 小的减权重
原始配比 → 训练 ref 模型 → 计算各 domain loss
   → 调整权重(loss 大的加权重) → 用新配比训练大模型

7.3.2 实现

import torch
import torch.nn.functional as F

class DoReMi:
    """
    DoReMi 动态配比
    简化版实现,工业级用 Ray/Spark 分布式
    """
    
    def __init__(self, domains, initial_weights, lr=0.01):
        """
        domains: list of domain names
        initial_weights: 初始权重(softmax 概率)
        lr: 权重更新学习率
        """
        self.domains = domains
        self.weights = torch.tensor(initial_weights, requires_grad=False)
        self.lr = lr
        
        # 记录每个 domain 的历史 loss
        self.domain_losses = {d: [] for d in domains}
    
    def update_weights(self, domain_losses):
        """
        根据各 domain 的 loss 更新权重
        domain_losses: dict, {domain: loss}
        """
        # 计算 excess loss(相对参考模型)
        # loss 大的 domain 加权重(因为它"难",需要更多数据)
        losses = torch.tensor([domain_losses[d] for d in self.domains])
        
        # Group DRO 更新:softmax on losses
        # 让权重更倾向于 loss 大的 domain
        temperature = 0.1
        new_weights = F.softmax(losses / temperature, dim=0)
        
        # 指数平滑更新(避免震荡)
        momentum = 0.9
        self.weights = momentum * self.weights + (1 - momentum) * new_weights
        
        # 归一化
        self.weights = self.weights / self.weights.sum()
        
        return {d: self.weights[i].item() for i, d in enumerate(self.domains)}

# 使用示例
doremi = DoReMi(
    domains=['cc', 'github', 'arxiv', 'wiki', 'books', 'stackexchange'],
    initial_weights=[0.67, 0.045, 0.025, 0.045, 0.045, 0.020],
    lr=0.01
)

# 假设训练一段时间后,各 domain loss
losses = {
    'cc': 2.5, 'github': 1.8, 'arxiv': 3.2,
    'wiki': 2.0, 'books': 2.3, 'stackexchange': 2.1
}

# 更新权重
new_weights = doremi.update_weights(losses)
print(f'Adjusted weights: {new_weights}')
# arxiv 的 loss 最大(3.2),权重会被调高

7.3.3 DoReMi 实证效果

DoReMi 论文报告的效果(在 8B 模型上):

配比策略MMLUARCTriviaQA
Llama-1 静态24.541.035.8
DoReMi 动态26.843.537.2

用同样数据,仅靠配比优化,MMLU 提升 2.3 分——零成本改进。

7.4 RegMix:学习式配比

RegMix(Hardy et al., 2024)是另一种动态配比思路,用回归模型学习最优配比。

7.4.1 核心思想

  1. 用大量小模型(如 1B)跑各种配比实验
  2. 记录每个配比对应的最终 loss
  3. 训练一个回归模型(如 LightGBM)预测”配比 → loss”
  4. 用回归模型优化出最优配比,再用于大模型训练
设计 1000 种配比 → 跑 1B 小模型 → 收集 (配比, loss) 数据
   → 训练 LightGBM 回归 → 优化出最优配比 → 用于大模型

7.4.2 实现

import lightgbm as lgb
import numpy as np
from scipy.optimize import minimize

class RegMixOptimizer:
    """
    RegMix 学习式配比优化器
    """
    
    def __init__(self, domains):
        self.domains = domains
        self.regressor = None
    
    def generate_random_mixes(self, n_mixes=1000):
        """
        生成 n_mixes 种随机配比
        """
        mixes = []
        for _ in range(n_mixes):
            # 用 Dirichlet 分布生成随机权重
            alpha = np.ones(len(self.domains))
            weights = np.random.dirichlet(alpha)
            mixes.append(weights)
        return np.array(mixes)
    
    def train_regressor(self, mixes, losses):
        """
        训练回归模型
        mixes: (n_samples, n_domains) 配比
        losses: (n_samples,) 各配比对应的 loss
        """
        # 用 LightGBM 回归
        self.regressor = lgb.LGBMRegressor(
            n_estimators=200,
            learning_rate=0.05,
            num_leaves=32
        )
        self.regressor.fit(mixes, losses)
    
    def optimize_weights(self, target_loss='minimize'):
        """
        优化最优配比
        """
        def objective(weights):
            # 约束:权重之和=1
            normalized = weights / weights.sum()
            
            # 预测 loss
            mix = normalized.reshape(1, -1)
            predicted_loss = self.regressor.predict(mix)[0]
            
            return predicted_loss
        
        # 初始值:均匀分布
        x0 = np.ones(len(self.domains)) / len(self.domains)
        
        # 约束:每个权重在 [0, 1]
        bounds = [(0, 1) for _ in self.domains]
        
        # 约束:权重之和=1
        constraints = {'type': 'eq', 'fun': lambda x: x.sum() - 1}
        
        # 优化
        result = minimize(
            objective, x0,
            method='SLSQP',
            bounds=bounds,
            constraints=constraints
        )
        
        optimal_weights = result.x / result.x.sum()
        return {d: w for d, w in zip(self.domains, optimal_weights)}

# 使用示例
optimizer = RegMixOptimizer(
    domains=['cc', 'github', 'arxiv', 'wiki', 'books', 'stackexchange']
)

# Step 1: 生成 1000 种随机配比
mixes = optimizer.generate_random_mixes(n_mixes=1000)

# Step 2: 跑 1B 小模型,记录每种配比的 loss(伪代码)
losses = run_small_models_with_mixes(mixes)  # 实际需要分布式训练

# Step 3: 训练回归模型
optimizer.train_regressor(mixes, losses)

# Step 4: 优化最优配比
optimal_mix = optimizer.optimize_weights()
print(f'Optimal mix: {optimal_mix}')

7.4.3 RegMix vs DoReMi

特性DoReMiRegMix
思路基于参考模型 loss基于小模型消融数据
计算量中(需训 reference 模型)高(需跑 1000+ 小模型)
准确性中-高高
可解释性中高
适用场景配比不确定时有充足算力做消融

推荐:算力充裕用 RegMix,算力紧张用 DoReMi。

7.4.4 配比方法的前沿进展

CausalMix:因果推断化解数据池漂移(清华,2026-07)

RegMix 的致命缺陷是假设数据池固定不变——当数据源刷新/过滤/扩展时回归模型失效。CausalMix 将配比优化重定义为因果推断问题:数据池统计特征→协变量,配比权重→treatment,目标→估计 CATE(条件平均处理效应)。因果模型吸收分布漂移而非崩溃。在 Qwen2.5-0.5B 上 512 次代理训练后,可外推到 7B 模型+800K 文档池,无需重跑回归。

⚠️ 预印本(未经同行评议),但问题定义方式有理论创新性。

RegMix-D:从静态配比到动态混合(东京大学/NII, 2026-06)

RegMix 只用终点 loss,RegMix-D 利用完整损失轨迹预测多阶段最优配比,支持离线(预生成混合计划)和在线(训练中自适应)两种模式。仅需 RegMix 25% 代理算力(128 个代理模型)即可超越 RegMix 性能。

⚠️ 预印本,但方法是对 RegMix 的自然扩展。

GEM:几何熵混合优化语义分桶(ICML 2026)

GEM 解决了 DoReMi/RegMix/Aioli 等 mixing 框架的前提问题——如何划分”语义桶”。现有 K-Means(欧氏空间)与 cosine-based embedding 不兼容导致 cluster collapse。GEM 用 vMF(von Mises-Fisher)混合在超球面上聚类+平衡正则防塌缩+Teacher-Student 蒸馏到 FastText,在 1.1B 模型上叠加三种 mixing 框架平均提升 1.2%。

核心启示:配比优化的输入质量同样重要——垃圾入桶,垃圾出配比。

配比方法论演进总览

方法范式核心创新局限性
DoReMi在线动态配比Group DRO 自适应收敛慢,噪声大
RegMix学习式配比LightGBM 回归预测假设数据池固定
CausalMix因果配比CATE 吸收漂移预印本待验证
RegMix-D动态学习式完整损失轨迹预印本待验证
GEM语义桶优化vMF 超球面聚类与配比方法解耦

7.4.5 静态 vs 在线:2026 配比研究的最大转向

将上述方法按”是否随训练状态自适应”划分,可以看到一条清晰的演进谱系:

范式代表方法核心假设
静态配比DoReMi / DoGE / RegMix”单一配方全程最优”
在线配比ODM / AC-ODM / AutoScale / Aioli / HDS / TiKMiX配方随训练状态/数据漂移自适应

静态方法的核心假设缺陷:预训练的学习动态是非平稳的(早期需要多通用数据打底,晚期需要多高质量数据精修),“单一配方全程最优”在实践中不成立。这是 2026 年配比研究的最大转向——从”算出一个好配方”转向”让配方随训练自适应”。

HDS(Holistic Data Scheduler, arXiv:2606.24133) 是这条线上较新的代表:将配比建模为连续控制 MDP,用 Soft Actor-Critic(SAC)在线调整各域采样概率,奖励由三维 holistic 信号构成——数据质量驱动(data-driven)+ 域间影响梯度对齐(gradient-driven,承接 AC-ODM)+ 模型中心权重范数(weight-norm,促进收敛稳定)。

TiKMiX(arXiv:2508.17677) 走 influence-function 路线:定义 Group Influence(域级影响估计)作为动态配比目标,TiKMiX-D(直接优化)在 20% RegMix 计算资源下超越 RegMix,TiKMiX-M(回归预测器)在 9 个下游任务平均 +2%,训练规模达 1T tokens。其核心观点与 RegMix-D 一致:域偏好随训练进度与模型规模漂移,静态配比会”欠消化”(underdigestion)。

DoGraph(ACL 2026) 则挑战了更底层的前提——“域”本身:用梯度空间聚类构建”模型眼中的域”,超越人工定义的”数据来源类别”。主实验(GPT-2 Medium / SlimPajama)平均分 37.9,高于 DoReMi(36.5)、RegMix(35.7)、Uniform(35.4),PPL 3.09 为所有对比方法最低(Uniform 4.13);在 LLaMA-1.1B / LLaMA-3.2-3B / The Pile 上稳定领先;计算开销仅比 RegMix 高约 4.51%。

CausalMix 与 RegMix-D 的路线差异:两者都回应”数据池漂移”,但改的是不同对象——RegMix-D 在训练中动态调整配方(时序维度),CausalMix 改的是拟合对象(用 CATE 刻画”数据池特征如何驱动性能”,而非”哪些固定配比碰巧有效”)。理解这一点,就能抓住配比研究的两大前沿分支。

7.5 阶段化配方

7.5.1 训练阶段切分

工业级预训练通常分 4 个阶段,每个阶段配比不同:

阶段定位配比特点规模
Pretrain 一阶段建立通用能力网页 60%+代码 15%+书籍 10%+数学 10%+多语 5%10-15T
Midtrain 二阶段注入推理/代码代码 30%+数学 20%+推理 15%+网页 25%+其他 10%1-3T
Annealing 退火收尾提分高质量精选 50%+数学代码 30%+少量 SFT 20%50-500B
Long Context 长文扩展上下文拼接长文档、书籍、代码仓库50-200B

7.5.2 各阶段配方详解

Pretrain 一阶段配方

# Pretrain 一阶段(10-15T tokens)
pretrain_phase1:
  duration: 10T-15T tokens
  learning_rate: 3e-4
  
  mix:
    - source: 'cc_high_quality'    # FineWeb-Edu ≥3
      weight: 0.60                # 6-9T
    - source: 'github_clean'
      weight: 0.15                # 1.5-2.25T
    - source: 'books'
      weight: 0.10                # 1-1.5T
    - source: 'arxiv_latex'
      weight: 0.07                # 0.7-1.05T
    - source: 'wikipedia_multilingual'
      weight: 0.05                # 0.5-0.75T
    - source: 'stackexchange_high_vote'
      weight: 0.03                # 0.3-0.45T
  
  # 多语种细分(在 wiki 内部)
  language_split:
    en: 0.40
    zh: 0.15
    other: 0.45

Midtrain 二阶段配方

# Midtrain 二阶段(1-3T tokens)
midtrain_phase2:
  duration: 1T-3T tokens
  learning_rate: 1e-4  # 比 Phase1 低
  
  mix:
    - source: 'cc_filtered'         # 通用网页(保持语言能力)
      weight: 0.25
    - source: 'github_clean'
      weight: 0.30                # 提升代码能力
    - source: 'arxiv_math'
      weight: 0.20                # 提升推理
    - source: 'reasoning_chains'   # 合成推理链
      weight: 0.15
    - source: 'wikipedia'
      weight: 0.05
    - source: 'stackexchange'
      weight: 0.05

Annealing 退火阶段配方

# Annealing 退火(50-500B tokens)
annealing_phase3:
  duration: 50B-500B tokens
  learning_rate: 3e-5  # 大幅降低
  schedule: linear_decay_to_zero  # 线性衰减到0
  
  mix:
    - source: 'fineweb_edu_4plus'  # ≥4分精选
      weight: 0.50                # 50%
    - source: 'arxiv_math'         # 数学/论文
      weight: 0.20
    - source: 'github_clean'       # 代码
      weight: 0.15
    - source: 'stackexchange_top'  # 高赞问答
      weight: 0.10
    - source: 'synthetic_reasoning' # 合成推理链(GSM8K等)
      weight: 0.05

Long Context 长文阶段配方

# Long Context 长文(50-200B tokens)
long_context_phase4:
  duration: 50B-200B tokens
  learning_rate: 1e-5
  context_length: 32768  # 从 8K 扩展到 32K
  position_encoding: rope_scaling  # 用 RoPE scaling
  
  mix:
    - source: 'long_documents'      # 拼接长文档
      weight: 0.40
    - source: 'books_full'           # 完整书籍
      weight: 0.30
    - source: 'github_repo_full'     # 完整代码仓库
      weight: 0.20
    - source: 'multi_turn_dialogues' # 多轮对话
      weight: 0.10

7.6 退火策略详解

7.6.1 什么是退火

退火(Annealing)源自金属处理的退火工艺——缓慢冷却使晶体更稳定。在大模型训练中,退火指:

  1. 学习率线性衰减:从训练中后期的 lr 衰减到 0
  2. 数据切换为高质量精选:用退火专用数据集

7.6.2 为什么退火有效

退火有效的核心是“最后一刻”的精炼:

  1. 训练末期是巩固期:模型已经在大量数据上学到模式,最后阶段是”打磨”
  2. 低学习率避免破坏:用低 lr 微调,不会破坏已有能力
  3. 高质量数据注入”精华”:精选数据是”知识浓缩”,每个 token 信息密度高

7.6.3 退火数据组成

退火数据是预训练的”压轴戏”,组成推荐:

# 退火阶段数据组成(500B tokens 为例)
ANNEALING_MIX = {
    # 主力:高质量网页精选(50%)
    'fineweb_edu_4plus': {
        'weight': 0.50,
        'tokens': 250_000_000_000,  # 250B
        'description': 'FineWeb-Edu ≥4 分'
    },
    
    # 数学/推理(25%)
    'arxiv_math': {
        'weight': 0.15,
        'tokens': 75_000_000_000,
        'description': 'arXiv 数学论文'
    },
    'synthetic_reasoning': {
        'weight': 0.10,
        'tokens': 50_000_000_000,
        'description': 'GSM8K/MATH 合成推理链'
    },
    
    # 代码(15%)
    'github_clean': {
        'weight': 0.15,
        'tokens': 75_000_000_000,
        'description': '高 star GitHub'
    },
    
    # 少量 SFT 风味(10%)
    'sft_like_data': {
        'weight': 0.10,
        'tokens': 50_000_000_000,
        'description': '指令风格数据,为后训练"破冰"'
    }
}

7.6.4 退火策略对比

# 三种退火策略
ANNEALING_STRATEGIES = {
    # 策略1:纯线性衰减(最简单)
    'linear': {
        'lr_start': 3e-5,
        'lr_end': 0,
        'schedule': 'linear',
        'description': '简单但效果中等'
    },
    
    # 策略2:余弦退火(更平滑)
    'cosine': {
        'lr_start': 3e-5,
        'lr_end': 1e-6,
        'schedule': 'cosine',
        'description': '更平滑,效果略好'
    },
    
    # 策略3:阶梯式衰减(复杂但有效)
    'step': {
        'lr_start': 3e-5,
        'steps': [
            {'tokens': '200B', 'lr': 3e-5},
            {'tokens': '150B', 'lr': 1e-5},
            {'tokens': '100B', 'lr': 3e-6},
            {'tokens': '50B',  'lr': 1e-6}
        ],
        'description': '复杂,效果最好'
    }
}

# 推荐:算力紧张用 linear,算力充裕用 step

7.6.5 退火实证

Llama3 的退火实验:

策略数据退火 tokenMMLU
不退火-084.2
线性退火同主训练数据200B86.1
线性退火高质量精选200B88.6
阶梯退火高质量精选200B88.4

关键发现:退火数据的”质量”比退火策略本身更重要。

7.7 配比实验设计

7.7.1 小模型消融实验

# 用 1B 模型做配比消融
def ablation_experiment(mix_configs):
    """
    用 1B 小模型测试不同配比
    """
    results = []
    
    for config_name, mix in mix_configs.items():
        print(f'Running experiment: {config_name}')
        
        # 训练 1B 模型(伪代码)
        model = train_1b_model(
            mix=mix,
            tokens=100_000_000_000,  # 100B
            lr=3e-4
        )
        
        # 评测
        scores = {
            'mmlu': eval_mmlu(model),
            'arc': eval_arc(model),
            'human_eval': eval_human_eval(model),
            'gsm8k': eval_gsm8k(model)
        }
        
        results.append({
            'config': config_name,
            'mix': mix,
            'scores': scores
        })
    
    return results

# 设计 5-10 个对比配方
ABLATION_CONFIGS = {
    'baseline': {'cc': 0.7, 'code': 0.1, 'math': 0.05, 'wiki': 0.05, 'other': 0.1},
    'more_code': {'cc': 0.5, 'code': 0.3, 'math': 0.05, 'wiki': 0.05, 'other': 0.1},
    'more_math': {'cc': 0.5, 'code': 0.1, 'math': 0.25, 'wiki': 0.05, 'other': 0.1},
    'balanced': {'cc': 0.4, 'code': 0.2, 'math': 0.2, 'wiki': 0.1, 'other': 0.1},
}

7.7.2 Scaling Law 外推

# 用小模型结果外推到大模型
def extrapolate_scaling_law(small_results, target_params):
    """
    用 Chinchilla Scaling Law 外推
    """
    import numpy as np
    from scipy.optimize import curve_fit
    
    def loss_fn(N, A, alpha, B, beta, E):
        return E + A / N**alpha + B / small_results['tokens']**beta
    
    # 拟合参数
    popt, _ = curve_fit(
        loss_fn,
        small_results['params'],
        small_results['losses']
    )
    
    # 外推
    predicted_loss = loss_fn(target_params, *popt)
    return predicted_loss

7.8 配比的踩坑经验

坑1:配比过偏向某一类

某团队为了提升数学能力,把数学数据配比拉到 50%,结果模型闲聊能力崩塌,“hello” 都不会回答。任何单一类型不能超过 30%。

坑2:多语种配比失衡

某团队中文项目,配比 80% 中文,结果模型英文能力极弱,无法理解英文 prompt。多语种模型至少 20% 英文。

坑3:代码数据过多导致”代码味”

某团队配比 40% 代码,结果模型生成自然语言时频繁吐出 print()、def 等代码片段。代码配比建议 15-25%。

坑4:退火数据与主训练重复

某团队退火用的是主训练数据的子集,结果退火几乎无效果。退火数据必须独立精选,且质量更高。

坑5:阶段切换太突然

某团队从 Pretrain 切到 Midtrain 时学习率突然降 10 倍,loss 跳变。阶段切换时学习率应平滑过渡(如 1000 步线性插值)。

7.9 推荐配方模板

7.9.1 通用模型配方

# 通用大模型(如 Llama3 类)
recommended_general:
  pretrain:
    cc_high_quality: 0.60
    github_clean: 0.15
    books: 0.10
    arxiv: 0.05
    wiki: 0.05
    stackexchange: 0.05
  midtrain:
    cc: 0.30
    github: 0.30
    arxiv_math: 0.20
    reasoning: 0.15
    wiki: 0.05
  annealing:
    fineweb_edu_4plus: 0.50
    arxiv_math: 0.20
    github: 0.15
    stackexchange_top: 0.10
    sft_like: 0.05

7.9.2 中文模型配方

# 中文大模型
recommended_chinese:
  pretrain:
    cc_zh: 0.50           # 中文 CC
    cc_en_filtered: 0.15  # 英文 CC(保留通用能力)
    github_clean: 0.10
    wiki_zh: 0.10
    books_zh: 0.05
    books_en: 0.05
    baike: 0.05           # 百科类

7.9.3 代码模型配方

# 代码模型(如 Code Llama)
recommended_code:
  pretrain:
    github_clean: 0.50    # 代码占大头
    cc_tech: 0.25         # 技术网页
    stackexchange: 0.10
    arxiv: 0.10
    wiki: 0.05

7.10 本课总结

  • 配比决定性格:多代码→编程强,多数学→推理强
  • 静态配比:Llama-1 经典配方,简单但不可优化
  • DoReMi 动态配比:用 Group DRO 自动调整,零成本 +2-3 分
  • RegMix 学习式配比:用 LightGBM 回归预测最优配比
  • 阶段化配方:Pretrain → Midtrain → 退火 → 长文,每阶段配比不同
  • 退火策略:低学习率 + 高质量精选数据,最后 50-500B tokens 是”压轴戏”

课后练习

  1. 设计 5 种配比方案,用 1B 模型做消融实验
  2. 实现 DoReMi 简化版,在小数据集上验证
  3. 模拟一个阶段化切换的配方(Pretrain → Midtrain → 退火)
  4. 思考:你的模型最需要的能力是什么?对应的配比应该怎么调?

下一章我们将进入 Tokenization 与 Packing——把文本切分成 token、打包成定长张量,这是模型训练消费数据的最后一步。