干过这事的人都知道,训练一个大模型绝不是"把数据喂进去、等Loss降下来"那么简单。从数据清理到分布式训练,从对齐调优到上线服务,任何一环掉链子,前面所有的算力和人力投入都可能打水漂。这篇就把大模型底层开发的几个核心环节拆开讲,聊聊每个阶段在做什么、为什么这么做、有哪些我实际踩过的坑。打算自训模型的团队,或者对大模型训练管线好奇的朋友,可以拿去当个路线图参考。
1. 数据工程:决定模型上限的"食材供应链"
1.1 数据从哪来:爬取、清洗、过滤的三级管线
很多人误以为模型的能力取决于网络结构或参数量,但真正决定上限的往往是数据。业内常说"垃圾进,垃圾出",这句话在大模型身上会被放大得极其明显。一个几百亿参数的模型,训练数据里如果有大量重复、低质、带偏见的内容,模型就会把这些"坏味道"学得结结实实,后期再想洗掉非常困难。
数据来源通常是公开网页爬取、开源语料、电子书、代码仓库、问答社区等。但原始数据完全不能直接用,得走一条三级管线。第一级是格式清洗,把HTML标签、脚本代码、乱码字符、异常编码全部干掉;第二级是质量过滤,按规则筛掉过短的碎片、纯标点内容、广告文案、机器生成的垃圾页;第三级是敏感内容过滤,把违法、暴力、色情这类内容在源头挡掉,避免模型学进去。
这里我想强调一个容易被低估的步骤:语言识别。如果你的模型主打中文,那数据管线里必须加一道语言检测,把英文、日文等无关语料按比例筛掉。实际操作中我见过一个翻车案例——某团队忘了过滤低质量英文网页,结果模型在中文任务上频繁蹦出英文单词,检查后才发现是数据里混入了大量英文噪声。这类问题在数据阶段发现只需要改一行过滤规则,等模型训练完了再发现,就是灾难级返工。
1.2 去重不是可选项,是必选项
数据去重常常被新人认为是"锦上添花",但在我做过的大模型项目里,去重是影响训练效果最明显的单点操作之一。原因很简单:重复数据会让模型产生记忆偏差。假设某段高质量文本在语料里出现了1万次,它的权重就相当于其他出现1次文本的1万倍,模型会对这段文本"过度学习",导致生成时频繁复述原句,泛化能力被严重削弱。
去重分两个层级。一是精确去重,把文本做哈希后直接比对,适合处理完全相同的重复内容;二是近似去重,处理"改了几个字、换了个链接"的变体重复,这类要靠MinHash加局部敏感哈希做指纹比对。我建议两个层级都做,先跑精确去重(成本低),再跑近似去重(效果显著)。
还有个细节容易漏:去重要去在"切词之前"。如果你已经做了分词再去重,语义相近但表达不同的句子可能被漏掉,而去重在原始文本层面做,覆盖更全。另外,跨批次去重也要做,因为数据往往是分批爬取的,第一批和第二批之间可能存在大量重叠,这个问题我当年就没注意到,直到后面对比数据分布才发现重叠率接近15%,白白浪费了一部分训练算力。
1.3 Token切分与数据配比:两个容易被轻视的"参数"
数据准备好之后,还有一个被90%的科普文章忽略的环节:Token化。简单说,Token是把文本切成模型能处理的最小单元,中文可以按字、按词、按子词切。目前主流是子词切分,常见实现是BPE算法。这里面有两个关键决策:词表大小和切分粒度。
词表大小选择要平衡压缩率和模型容量。词表太小,一段文本会被切成很多个Token,等于变相缩短了模型的有效上下文;词表太大,Embedding层参数暴涨,训练和推理都变慢。以中文场景为例,词表定在5万到10万之间是比较常见的区间,太小了大模型学中文的效率很低,太大了收益递减。这些参数不是拍脑袋定的,需要用真实语料做实验,测平均每个Token对应的字符数,再对比不同词表大小下的训练收敛速度。
数据配比则是另一个"细节决定成败"的点。通用文本、代码、数学、多语种语料,不能一股脑倒进去,要有比例控制。代码数据占比过高会让模型在自然语言上变得生硬,纯文本占比过高则影响推理能力。我见过一个公开的模型报告,他们的配比是通用文本占七成、代码占两成、数学和专业知识占一成,这个结构比较稳妥。但适合自己的数据才是最好的,我建议每次配比调整都做小规模实验,对比不同配比下的评测分数,而不是直接抄别人的比例。
2. 预训练:算力调度和训练稳定性的持久战
2.1 并行策略:数据并行、张量并行、流水线并行怎么选
预训练是烧钱的大头,而烧钱的效率取决于并行策略。单个GPU装不下大模型,这是物理限制,所以必须把模型和数据切成多份,铺到成百上千张卡上协同训练。这里面有三种基本维度。
数据并行最简单,每张卡都持有完整的模型副本,大家分头算不同的数据批次,然后同步梯度。但模型超过单卡显存就玩不转。张量并行是把一个Transformer层的矩阵乘法拆到多张卡上,适合单机多卡场景,因为卡间通信量大,跨机延迟受不了。流水线并行则是按层切分,把不同的层放到不同的卡上,数据像流水线一样依次经过,但容易产生GPU闲置的"气泡"。
实际项目中没人只用一种策略,都是组合拳。千卡级别的训练,典型配置是数据并行加上每台机器内部做张量并行,再配合流水线并行。每种并行维度怎么分配,要考虑通信瓶颈。我的体感是:张量并行尽量限制在单机内部,因为NVLink带宽远高于跨机网络;流水线并行层数要和Global Batch Size匹配好,否则气泡率会显著拉高训练成本。这些看起来是"部署细节",实际上直接决定你每花一块钱能训练多少个Token。
2.2 Loss曲线不会说谎:波动和发散怎么排查
预训练开始后,最重要的监控指标就是Loss曲线。但很多第一次训练大模型的人不知道,Loss曲线不是越陡峭越好,而是要"平滑下降"。如果Loss曲线出现尖刺(突然暴涨又回落),说明训练状态不稳定,可能是学习率过大、数据批次里有异常样本,或者某个并行通信环节出错。
我自己踩得最深的一个坑是学习率预热设置不当。大模型训练初期参数处于随机状态,梯度方向混乱,如果一上来就给大学习率,参数会被推到损失面的危险区域,轻则收敛变慢,重则直接发散(Loss变成NaN)。标准做法是先用几百到几千步做学习率预热,从接近零的值线性升到目标学习率。至于目标学习率定多少,要看模型规模和批次大小。一个粗略经验是:几十亿参数、批次大小在几百万Token量级时,峰值学习率放在1e-4到3e-4之间比较稳。但要记住这只是起点,必须用小规模实验先探路。
Loss发散还有一种隐藏原因:混合精度训练里的Loss缩放因子设置不对,或者FP16的数值溢出。遇到Loss变成NaN,不要急着调学习率,先检查Loss缩放策略、检查数据里有没有包含异常值,再回头看梯度统计。排查看似枯燥,但90%的训练事故都能在日志堆里找到线索。
2.3 断点续训与故障恢复:千卡训练的日常必修课
千卡规模训练持续时间以周甚至月计,在这个周期里,硬件故障是必然事件,不是偶然事件。我几乎没见过哪次长训练从头到尾不重启一次的。GPU卡可能掉线、网络可能抖动、CPU节点可能死机,所以"checkpoint(模型快照)"机制是整个训练的救命稻草。
Checkpoint策略核心是两点:频率和方式。频率上,每训练一定步数就存一次快照,间隔不能太密否则存储开销太大,也不能太疏否则故障时丢失的进度太多。常见做法是每隔几百步存一份,再循环覆盖旧的,只保留最近几份。方式上,推荐异步保存,也就是让保存动作在后台线程完成,不阻塞训练主流程。这里有个经验之谈:如果保存快照时训练卡顿非常明显,说明你的存储带宽不够,可以考虑把快照先写到本地临时目录再异步转存到共享存储。
故障恢复还有一类问题是软件层面的。分布式训练中某个节点报错超时,自动拉起后如果数据加载的随机种子没固定,数据分布变了,训练曲线会出诡异波动。所以断点续训要保证数据读取的随机状态也能恢复到故障前的状态,这件事很容易被忽略,但影响很大。
3. 指令微调与对齐:从"会说话"到"说人话"
3.1 SFT数据构造:质量是唯一的王
预训练出来的模型本质上是个"文本续写器",你问它问题,它能接出看起来合理的下文,但未必是按"回答问题"的格式来。指令微调(SFT)就是拿一批"指令+标准回答"的样本,教模型学会人类的对话格式和意图理解。
SFT数据贵在质量,不在数量。一个常见误区是疯狂堆数据,希望模型通过海量指令学会更多能力。实际上,我观察到SFT数据量从几千条涨到几十万条,效果提升远没有第一轮从零到几千条那么明显;反而是数据质量差带来的副作用很大,比如指令和答案不匹配、答案本身有事实错误、格式不统一,都会让模型学会坏习惯。
构造高质量SFT数据的核心是"任务多样性"。要覆盖问答、写作、总结、翻译、代码、数学等不同类型,每种类型内部还要有难度梯度。我在实际项目中用过一个组合方式:拿公开指令集做初筛(过滤明显低质的),再人工编写一批高质量种子数据,最后用种子数据诱导模型生成候选,再由人工筛选修正。整个过程里,人工质检是绝对不能省的环节。你可以在项目里先定一个简单的质检标准——每条数据是否包含明确指令、是否包含一个可验证的正确回答、格式是否与其他数据一致,不满足的坚决不进训练集。
3.2 偏好对齐:RLHF和DPO之间的取舍
SFT让模型会答题,但要让模型符合人类偏好——比如更简洁、更有帮助、更少编造——需要偏好对齐。早期的主流方案是RLHF,做法分三步:先训练一个奖励模型来给回答打分,再用强化学习(常见是PPO算法)让模型朝高分方向更新。这个方案效果不错,但工程复杂度极高,PPO训练不稳定,超参敏感,动不动就崩,而且训练和推理成本都很大。
后来出现的DPO方案,思路完全不同。DPO不需要单独训练奖励模型,也不跑强化学习,而是直接用偏好数据对(好回答和差回答各一条)构造损失函数,让模型在训练中直接加大好回答的概率、压低差回答的概率。从我的实测感受看,DPO在大多数任务上和RLHF效果接近,而工程复杂度低了一个量级,训练稳定性也好很多。尤其是小团队,我会建议先从DPO入手,把偏好对齐的流程跑通,再去评估是否有必要上RLHF这种重武器。
偏好数据的采集也值得多说一句。不要迷信"让标注员凭空写更好回答"这种模式,更高效的做法是让模型针对同一指令生成多个回答,再由标注员排序。排序任务比创作任务快得多,而且多人排序可以算一致性指标,方便挑出分歧大的样本做二次讨论。这能显著提升偏好数据的可靠度。
3.3 灾难性遗忘:学了新技能,别丢了老本行
对齐阶段最常见的副作用是灾难性遗忘——模型在指令跟随和偏好对齐上学好了,但预训练阶段掌握的通用知识和推理能力反而退化了。这很反直觉,但非常普遍。我记得有一次,模型对齐后对话体验明显变好,但拿通用知识基准一测,分数掉了好几个百分点,这就是典型症状。
缓解方法主要有三种。第一种是数据混合,在对齐数据里掺入一部分预训练阶段的通用语料,让模型在学新技能的同时不忘记旧知识。第二种是加KL散度约束,让对齐后的模型输出分布不要偏离原始模型太远,相当于给模型的更新范围上了道保险。第三种是低学习率加少量步骤,很多对齐工作其实不需要模型改变太多参数,用小学习率做少步数更新,能显著减少遗忘。
这三种方法可以叠加使用。我个人的默认配方是:SFT阶段在训练数据里混5%到10%的预训练语料,学习率设置为预训练阶段的十分之一左右,训练步数控制在1到3个epoch以内。跑完后再用评测集验证通用能力没有明显下跌。这个配方不算最优,但足够稳。
4. 评测体系:模型行不行,要用尺子量
4.1 公开基准要跑,但别只信公开基准
模型训练完,第一件事是评测。业界通用的做法是跑一批公开基准,比如综合知识理解、数学推理、代码生成、多语言理解这些维度的标准测试集。公开基准的好处是可以横向对比其他模型,但问题也很突出:基准集可能已经被训练数据"污染"了。
数据污染是评测里最隐蔽的坑。如果训练语料里包含了评测集的题目和答案,模型在评测上的高分就是"作弊"得来的。我遇到过的情况是,某个推理基准的题目在网上广泛流传,清洗数据时没有被过滤掉,导致模型在该基准上分数虚高,但实际使用时推理能力明显不匹配。所以每跑一个公开基准,都要做污染检测——把题目切块后在训练语料里检索,能匹配到高分相似片段就必须警惕。
4.2 自建评测集和人工评估才是立身之本
公开基准之外,一定要建自己的评测集。这个评测集要贴近你的真实应用场景。如果你做的是法律问答助手,那评测集应该包含法条理解、案例推理、文书写作;如果你做的是代码助手,评测集应该围绕实际编程任务来设计。自建评测集不追求大,几百条精心设计的样本就比几万条通用样本有价值。
自建评测我特别推荐按能力维度分层,比如基础事实问答、逻辑推理、指令跟随长度控制、格式遵从、拒绝回答(模型应该承认不知道,而不是编造)。每个维度单独打分,这样可以精确定位模型的短板,而不是只有一个笼统的总分。
人工评估也不能省。机器指标只能衡量"是否接近标准答案",但真实用户体验里,回答的条理性、语气、分寸感都是机器测不出来的。我建议定期做两两对比评估:把两个模型的回答放在一起,请人盲评哪个更好。这个结果虽然主观,但往往比任何公开基准都更接近产品体验的真相。
4.3 红队测试:安全底线要靠对抗式攻击来验证
评测不只是测能力,还要测"边界"。红队测试就是专门让人去尝试"攻击"模型——诱导它输出有害内容、突破安全限制、编造事实、泄露隐私等。这项工作往往被团队放在最后,但其实应该提前介入。
红队测试有一套方法论。可以从"攻击维度"出发设计测试用例:角色扮演诱导、假设前提诱导、多轮套话、编码绕过等等。红队测试的结果通常不是二元的"安全/不安全",而是一条光谱——需要判断哪些拒答是合理的(保护安全),哪些拒答是过度的(影响体验)。这里有个度的问题:模型被训练得过于保守,会把"帮我写一份演讲稿"这类正常请求也拒掉,这种过度拒答同样会毁掉产品体验。所以红队报告出来后,要回过头调整对齐策略,在安全和可用性之间找平衡。这通常需要好几轮迭代,没有任何捷径。
5. 推理部署与持续迭代:训练完只是开始
5.1 推理优化:量化、批处理、KV Cache三件套
模型训练完成后,真正的考验才开始——让它稳定、快速、低成本地服务线上请求。大模型的推理和普通模型推理不太一样,它有两个阶段:预填充阶段(处理输入,生成首个Token)和解码阶段(逐个生成后续Token)。前者是计算密集型的,后者是访存密集型的。两者的优化手段完全不同。
量化是目前性价比最高的优化手段。把模型权重从高精度压缩到低精度,比如从16位降到8位甚至4位,显存占用直接缩水,推理速度也明显提升。代价是精度有轻微损失,但在大部分任务上感知不到。实际项目中,我建议先用一小批评测集对比量化前后的指标,确认损失在可接受范围内再上线。这里有个坑:有些层对量化非常敏感,比如注意力层的某些计算,量化后误差会累积,所以混合精度量化(敏感层保持高精度,其他层量化)是更稳的做法。
KV Cache是另一个重要优化点。推理时每个Token都要重新计算之前所有Token的键值向量,如果不缓存,计算量会随生成长度线性爆炸。把历史键值缓存下来,能省掉大量重复计算。但KV Cache非常吃显存,所以后续还有很多变体——比如缓存压缩、共享前缀缓存等。做推理服务的人,可以说一半时间都在跟KV Cache打交道。
5.2 服务化部署:首Token延迟和吞吐量的博弈
线上服务的两个核心指标是首Token延迟(用户发出请求到看见第一个字的时间)和吞吐量(单位时间能处理多少请求)。这两个指标往往此消彼长,工程上要按业务场景取舍。做聊天助手,首Token延迟更敏感,用户等太久会流失;做离线批处理,则更看重吞吐量。
有一个非常实用的技巧叫连续批处理。传统做法是一个批次的所有请求都结束后才释放资源,但大模型生成时,不同请求的长度差异巨大,会导致大量GPU空等。连续批处理是动态地把新请求插入到即将有空闲的位置,把GPU利用率拉满。实测下来,同样的硬件,连续批处理能把吞吐量提升两到三倍。
部署环节还要考虑服务降级和限流策略。模型推理的算力开销远大于传统服务,如果流量突发,很容易把GPU打爆。我建议在服务入口设置token级别的限流,同时给超长输入设上限,从工程上保证单个请求不会拖垮整个服务。
5.3 数据飞轮:让模型越用越聪明
上线只是起点,迭代才是常态。业界常说"数据飞轮",意思是:模型服务线上用户,用户的使用行为产生新的优质数据,这些数据经过筛选和标注后反哺下一版模型的训练。
这个飞轮的运转有几个关键环节。第一是日志采集,要记录用户请求、模型回答、用户反馈(点赞、点踩、复制、重新生成等)。第二是数据筛选,从日志里捞"高价值样本"——比如用户明确点赞的回答对、用户反复改写后的最终版本。第三是定期质量审查,筛选出来的数据不能直接进训练集,要过一道人工或模型辅助的质检,防止把低质数据喂回去。
我把这些环节落地成一套周级流程:每周导出日志、筛选候选、人工抽检、补充标注,然后攒够一批数据就触发一次增量微调,跑完评测如果分数有提升就发布新版本。这个流程听起来朴素,但它才是让模型持续变强的核心动力。很多团队把精力全放在预训练上,忽略了上线后的迭代闭环,结果模型版本半年不更新,体验被竞品越拉越远,这是非常可惜的。
做了几个大模型项目之后,我最大的体会是:这个领域的门槛从来不在于某单点技术的难度,而在于它把太多环节串成了一条长链,每一环都需要对应的专业能力和工程纪律。数据工程师、分布式系统工程师、算法研究员、评测分析师、推理优化工程师,这些人得在同一套目标下紧密协作,任何一环掉链子,整个项目都会被拖住。如果看完这篇能让你对"大模型开发到底在做什么"有了更具体的画面,在规划自己项目时能少走几条弯路,那就值了。最后再分享一个小建议:第一个大模型项目不要贪大,把一条小而完整的管线跑通,比一开始就追求千亿参数更有价值。