
大模型训练这件事外行看热闹内行看门道。很多人以为从零训一个模型就是找一堆数据丢进去跑——真上手了才发现数据清洗能吃掉你一半时间预训练烧钱烧到你怀疑人生SFT做完发现模型变傻了DPO调完又发现通用能力掉了。我前后参与过几个从零到一的中小规模模型训练项目踩过的坑比读过的论文还多。这篇就把整条链路——数据准备、预训练、SFT、DPO/RLHF、评估——按实际操作的顺序拆开讲每一步为什么这么做、参数怎么定、哪里最容易翻车都给你说明白。适合有一定深度学习基础、想真正跑通全流程的工程师也适合想搞清楚各阶段到底在干什么的产品和算法同学。1. 先把训练链路的地图铺开1.1 四个阶段各自解决什么问题从零训练一个大模型本质上是把一个随机初始化的神经网络逐步塑造成能听懂人话、能按指令干活、还符合人类偏好的助手。这个过程被拆成四个阶段不是拍脑袋定的而是每一阶段解决上一阶段遗留的问题。预训练Pre-training解决的是知识从哪来。模型在这个阶段通过海量文本做下一词预测把语言规律、世界知识、推理模式的统计结构压进参数里。这个阶段出来的叫基座模型Base Model它的能力是续写你给它今天天气它会接不错适合出门——但它不会乖乖回答你的问题因为它没见过问答这种格式。SFTSupervised Fine-Tuning监督微调解决的是怎么听懂指令。用人工标注的指令-回答对教模型把基座的续写能力对齐到对话格式上。做完SFT模型才知道用户问什么我该答什么。DPO/RLHF偏好对齐解决的是回答得好不好。SFT只教了模型该怎么答但没教它哪种答法更好。偏好对齐用人类对多个回答的排序数据让模型学会偏向更helpful、更honest、更harmless的输出。评估Evaluation贯穿始终解决的是我怎么知道它变好了还是变坏了。没有评估的训练就是盲开你根本不知道这一步是进步还是退步。1.2 各阶段的资源量级差异很多人对资源没概念以为四个阶段花的钱差不多。实际差距是数量级的阶段数据量级算力占比典型耗时中小规模预训练数十B~数T token95%以上数天到数周SFT数万~数十万条2%~4%数小时到一天DPO/RLHF数万~十万条偏好对1%~3%数小时评估数千条测试集可忽略数十分钟这张表最想告诉你的是预训练是吞金兽后三个阶段是精雕细琢。所以业界主流做法是——预训练尽量复用开源基座比如拿一个已有的中文基座继续预训练把精力砸在SFT和偏好对齐上因为这两步才是决定好不好用的关键。从零训一个7B模型的全量预训练没有几十张卡和几周时间根本下不来个人和小团队几乎不可能。所以本文讲的从零更准确说是从基座开始走完整链路预训练部分会讲清楚原理和续训continue pre-training的实操。2. 数据工程决定上限的隐形战场2.1 预训练数据的清洗流水线预训练数据的质量直接决定模型上限这句话不是口号。我见过太多项目模型效果上不去最后定位到是数据里混了大量重复、乱码、低质内容。一条靠谱的清洗流水线通常包含这几步第一步格式统一与解析。把各种来源网页、书籍、论文、代码统一转成纯文本。网页数据要用解析库提取正文去掉导航栏、广告、页脚。这一步的坑在于很多解析库对中文网页支持差会把正文和噪声混在一起建议对解析结果做长度和标点密度过滤。第二步去重。这是最容易被低估的一步。网页数据里重复内容极多同一篇新闻被转载几十次很常见。去重要做两个粒度精确去重对文档做哈希完全相同的直接删和模糊去重用MinHash或SimHash把高度相似的文档聚类后只留一篇。实测下来模糊去重能把数据量砍掉30%~50%而且几乎不损失有效信息。第三步质量过滤。常用规则包括过滤过短文档比如少于50个字符、过滤标点符号占比异常的乱码特征、过滤重复行占比过高的、过滤包含大量特殊字符的。还可以训一个轻量分类器用高质量语料比如百科、书籍做正样本给网页数据打分低于阈值的丢掉。第四步敏感与有害内容过滤。这一步必须做而且要留痕。用关键词表加分类模型双重过滤把违规内容挡在训练之前。别想着训完再对齐预训练阶段混进去的有害内容后面对齐很难完全洗掉。提示清洗流水线的每一步都要记录输入多少条、输出多少条、丢弃原因分布。这个日志在后期排查模型行为异常时是救命稻草。2.2 SFT数据的构造与标注陷阱SFT数据的核心是指令-回答对的质量而不是数量。我踩过最大的坑就是早期贪多用自动生成的方式造了十几万条SFT数据结果模型学了一堆套话和错误格式反而比用两万条精标数据训出来的差。构造SFT数据有几个实操要点指令多样性比数量重要。覆盖问答、摘要、改写、代码、推理、多轮对话等不同任务类型每类都要有。如果全是单轮问答模型遇到多轮就崩。回答要像人写的不要像AI写的。很多标注员会写出首先...其次...最后...这种模板化回答模型学完就变成复读机。要明确要求标注员用自然、有信息量的表达。长度分布要合理。如果所有回答都是200字左右模型会失去长短控制能力。要刻意混入短回答一句话和长回答上千字。多轮对话要单独构造。多轮数据的格式和单轮不同要保留完整的对话历史让模型学会根据上下文回答。标注环节最大的陷阱是标注员理解偏差。同一个指令不同标注员的理解可能完全不同。解决办法是先写详细的标注规范做小批量试标开校准会统一标准再大规模铺开。试标阶段发现的问题比大规模返工便宜一百倍。2.3 偏好数据的收集方式DPO/RLHF需要的是偏好对——同一个prompt下一个chosen更好的回答和一个rejected更差的回答。收集方式主要有三种人工标注质量最高但最贵。让标注员对同一个prompt的多个模型输出排序取最好和最差的组成偏好对。模型生成人工筛选是性价比之选。用当前模型对同一prompt采样多个回答调高temperature增加多样性再让人工挑出好的和差的。AI反馈RLAIF用更强的模型当裁判给回答打分。成本低但要注意裁判模型的偏好会传染给被训模型可能引入偏见。偏好数据的坑在于chosen和rejected的差异要有意义。如果两个回答只是措辞不同、质量相当模型学不到有用信号反而会过拟合到无关特征上。理想情况下rejected应该在事实性、有用性、安全性等维度上有明确缺陷。3. 预训练从基座续训的实操路径3.1 为什么大多数人应该选续训而非从零从零预训练一个模型意味着随机初始化所有参数用海量数据从头学。这条路的问题在于你需要的算力和数据量和你能拿到的往往差一个数量级。一个7B模型要达到可用的中文能力至少需要几百B到上T的token对应几十到上百张高端卡的持续训练。个人开发者和小团队根本扛不住。续训Continue Pre-training的思路是拿一个已经预训练好的开源基座比如已有的中文基座用你自己的领域数据继续训练。这样模型已经具备通用语言能力你只需要注入领域知识或适配目标语言分布。算力需求降低一到两个数量级效果却往往更好。选择续训的前提是你的目标领域和基座的原始训练分布有差异。比如基座主要训英文你要做中文法律问答那就需要续训注入中文法律语料。如果基座已经覆盖你的领域直接跳到SFT可能更划算。3.2 续训的关键参数与学习率策略续训不是简单地把预训练脚本再跑一遍参数设置有讲究学习率要小。从零预训练常用1e-4到3e-4的学习率续训建议降到1e-5到5e-5。原因很简单模型已经在一个不错的参数位置上学习率太大会把它踢飞破坏已有的通用能力。我一般从2e-5起步观察loss曲线如果下降太慢再适当调高。用余弦退火加warmup。warmup步数设为总步数的1%~3%让学习率从0平滑升到峰值再余弦衰减到接近0。这样训练末期模型更稳定。批次大小和序列长度。序列长度建议用基座训练时的长度常见2048或4096太短学不到长程依赖太长显存吃不消。批次大小在显存允许范围内尽量大配合梯度累积达到目标有效批次。数据配比要控制。续训数据里领域数据和通用数据建议按7:3或8:2混合。全用领域数据会导致灾难性遗忘——模型领域内很溜通用能力全丢。混入通用数据能缓解这个问题。# 续训关键参数示例基于常见训练框架的配置风格 training_args { learning_rate: 2e-5, # 续训用小学习率 lr_scheduler_type: cosine, # 余弦退火 warmup_ratio: 0.02, # 2% warmup num_train_epochs: 1, # 续训通常1个epoch足够 per_device_train_batch_size: 4, gradient_accumulation_steps: 8, # 有效批次4*8*卡数 max_seq_length: 4096, bf16: True, # 混合精度省显存 }3.3 灾难性遗忘的监测与缓解灾难性遗忘是续训最大的风险。表现是领域任务变好了但通用问答、常识推理明显变差。监测方法是在续训过程中定期跑通用能力评测集比如常识问答、阅读理解一旦发现通用指标掉超过阈值就要调整数据配比或降低学习率。缓解手段除了混入通用数据还有两个实用技巧一是分层学习率底层靠近输入的层学习率设得更小因为底层学的是通用语言特征不该被大幅改动二是LoRA等参数高效微调只训练一小部分参数对原模型扰动最小。如果算力紧张LoRA续训是性价比极高的选择。4. SFT把基座变成听话的助手4.1 全量微调还是LoRASFT阶段第一个决策就是全量微调还是参数高效微调LoRA/QLoRA。两者没有绝对优劣看你的资源和目标维度全量微调LoRA显存需求高需存优化器状态低只训少量参数训练速度慢快效果上限略高接近全量多任务切换需存整个模型只存适配器可热插拔适合场景资源充足、追求极致资源有限、多版本迭代我的经验是中小团队优先LoRA。7B模型用LoRA单张24G显存的卡就能跑起来效果和全量微调的差距在多数任务上小于1个百分点。而且LoRA适配器只有几十MB方便做A/B测试和版本管理。只有当LoRA效果明显不够、且你有充足算力时才上全量。LoRA的关键参数是秩rank和alpha。rank一般设8~64任务越复杂、数据越多rank可以越大。alpha通常设为rank的1~2倍。学习率比全量微调高一个数量级常用1e-4到3e-4。4.2 训练轮数与过拟合的博弈SFT最容易犯的错是训太多轮。SFT数据量通常不大几万条模型很容易记住训练集表现为训练loss持续下降但验证集loss先降后升生成结果开始出现训练集里的原句。实操建议训1~3个epoch边训边看验证集。每训一定步数就存一个checkpoint用固定的评测集测一遍选验证效果最好的那个而不是最后一个。我一般会存5~10个checkpoint最后挑。另一个信号是生成多样性下降。如果模型对同一个问题不管怎么调temperature都给出几乎一样的回答说明过拟合了。这时候要么减少轮数要么增加数据多样性。4.3 对话模板与特殊token的处理SFT阶段有个特别容易被忽略的细节对话模板必须和推理时一致。训练时用什么格式拼接system、user、assistant推理时就得用什么格式。格式不一致会导致模型看不懂输入效果断崖式下跌。常见做法是定义特殊token比如用|im_start|和|im_end|标记每轮对话的边界。训练数据要严格按模板拼接并且只在assistant的回答部分计算lossuser和system部分要mask掉。这一点如果搞错模型会学着去预测用户的提问而不是生成回答。# 对话模板拼接示例示意 def build_prompt(messages): text for msg in messages: text f|im_start|{msg[role]}\n{msg[content]}|im_end|\n text |im_start|assistant\n return text # loss mask只对assistant部分计算损失 # 需要在tokenize后把非assistant部分的label设为-100注意特殊token要在tokenizer里注册并确保模型embedding层有对应的位置。如果用了基座没有的新token需要resize embedding并让新token也参与训练。5. DPO与RLHF让模型学会哪种回答更好5.1 RLHF的三步走与它的痛点经典RLHF分三步第一步训一个奖励模型Reward Model用人类偏好数据学一个打分器第二步用强化学习通常是PPO优化策略模型让它生成的回答能拿高分第三步用KL散度约束防止模型为了拿高分而跑偏。RLHF效果好但痛点明显流程复杂、训练不稳定、资源消耗大。PPO需要同时加载策略模型、参考模型、奖励模型、价值模型显存直接翻几倍。而且PPO对超参极其敏感调不好就训崩。这也是为什么DPO一出来就迅速流行。5.2 DPO为什么更受欢迎DPODirect Preference Optimization的核心洞察是可以跳过奖励模型和强化学习直接用偏好数据优化语言模型。它把RLHF的目标函数做了一个数学变换变成一个类似分类的损失——让模型提高chosen回答的概率降低rejected回答的概率。DPO的优势很直接只需要策略模型和参考模型两个模型训练稳定超参少效果在多数任务上不输RLHF。对中小团队来说DPO几乎是偏好对齐的首选。DPO的关键参数是beta控制模型偏离参考模型的程度。beta越大约束越强模型越保守beta越小越激进。常用0.1~0.5我一般从0.1起步。学习率要比SFT再小一个量级常用5e-7到5e-6。# DPO训练核心逻辑示意 # 对每个偏好对(prompt, chosen, rejected) # 计算策略模型和参考模型对chosen/rejected的log概率 # loss -log(sigmoid(beta * ((logp_chosen - logp_ref_chosen) # - (logp_rejected - logp_ref_rejected))))5.3 偏好对齐中的对齐税问题偏好对齐有个绕不开的现象叫对齐税Alignment Tax模型在偏好指标上变好了但通用能力比如知识问答、推理反而下降了。原因是偏好数据往往集中在某几类任务上模型过度优化这些任务把其他能力挤掉了。缓解对齐税的办法一是在偏好数据里混入通用任务的偏好对别只盯着安全性和格式二是DPO的beta别设太小给模型足够的约束三是对齐后做一次能力回补用少量高质量SFT数据再微调一下把掉下去的能力拉回来。这个回补步骤很多人会忽略但实测很有效。6. 评估别让训练变成盲盒6.1 自动评测与人工评测的分工评估分两大类自动评测快、便宜、可复现但只能测有限维度人工评测慢、贵但能捕捉自动指标测不到的东西比如回答的自然度、有用性。自动评测常用两类指标一是困惑度Perplexity衡量模型对测试文本的预测能力但困惑度低不代表回答好二是任务指标比如分类准确率、问答F1、代码通过率。对于生成任务还可以用模型裁判用强模型给弱模型的输出打分但要注意裁判模型的偏见。人工评测建议用成对比较给评测员同一个问题的两个模型输出让他们选更好的或者选差不多。成对比较比绝对打分更稳定因为人对绝对分数的标准不一致但对哪个更好的判断相对一致。6.2 构建有区分度的评测集评测集的质量决定评估的价值。一个没区分度的评测集所有模型都考90分等于没测。构建评测集要注意难度分层。简单、中等、困难各占一定比例。全是简单题测不出差距全是难题又容易让所有模型都挂零。覆盖核心能力。知识、推理、指令遵循、安全性、格式控制每个维度都要有题。防止数据泄漏。评测集绝对不能出现在训练数据里。我见过项目因为评测集泄漏指标虚高上线后翻车。定期更新。模型会记住固定的评测集所以要定期换题或者保留一个不公开的暗测集。6.3 训练全程的评估节奏评估不是训完才做而是贯穿全程预训练/续训阶段每隔一定步数跑通用能力评测监测灾难性遗忘。SFT阶段每个checkpoint都跑指令遵循和任务评测选最佳checkpoint。DPO阶段跑偏好胜率用模型裁判或人工加通用能力评测监测对齐税。上线前做一轮完整的人工评测覆盖真实用户场景。我习惯建一个评测看板把各阶段的指标画成曲线一眼就能看出哪一步在进步、哪一步在退步。这个看板在向团队汇报和定位问题时特别有用。7. 几个反复踩过的坑和应对7.1 loss正常但生成崩坏这是最迷惑人的情况训练loss一路下降看起来一切正常但模型生成的东西是乱码或者重复。原因通常是推理时的解码配置和训练不匹配或者对话模板拼接错误。排查顺序先检查模板再检查tokenizer是否一致最后检查解码参数temperature、top_p、repetition_penalty。我遇到过一次是tokenizer版本不一致训练用了新版推理用了旧版直接导致输出崩坏。7.2 显存不够的降级方案显存不够是常态。降级顺序建议先开梯度检查点用时间换显存再上混合精度bf16再减小批次配合梯度累积再考虑QLoRA4bit量化最后才考虑换更小的模型。梯度检查点能省30%~50%显存代价是训练慢20%左右通常是最划算的第一步。7.3 多卡训练的通信瓶颈多卡训练时如果卡间通信慢GPU利用率会很低。用数据并行DDP时确保用了高效的通信后端并且批次大小别设太小太小通信占比高。如果卡多但带宽低可以考虑梯度累积模拟大批次减少通信频率。实测中同样的卡数通信配置优化后训练速度能差一倍。从零训练一个大模型技术链路长、坑多但每一步都有章可循。数据决定上限预训练打底子SFT塑形偏好对齐调优评估兜底。真正拉开差距的往往不是用了多新的算法而是把每个环节的细节做扎实——数据洗干净、模板对齐、参数调对、评估跟上。我个人最大的体会是别急着上大模型先用小模型把全流程跑通7B甚至1B的模型足够你验证整条链路等流程顺了、坑踩明白了再放大规模成功率会高得多。