文章目录1. 先把问题讲清楚预训练到底解决什么2. 预训练目标next-token prediction 怎么读3. 一条真实预训练流水线长什么样4. token、seq_len、batch、step 的关系5. tokenizer 不是小细节6. 数据配比决定模型能力结构7. 学习率计划不要一开始就猛踩油门8. 训练显存为什么远大于模型权重9. checkpoint 不是“保存一下模型”这么简单10. 评估validation loss 重要但不够11. 小团队是否应该从零预训练12. 常见误区13. 小结大模型视角下一篇摘要大模型预训练不是“把海量文本丢进 GPU 跑很久”而是一条从数据治理、token 化、采样配比、训练目标、分布式执行、稳定性监控到评估回滚的系统工程链路。本文会先用开发者能理解的方式讲清楚预训练到底在学什么再拆解 token、batch、step、loss、学习率和基础设施之间的关系并用最小代码帮助你估算训练步数和预算。读完后你不一定能立刻训练一个大模型但应该能看懂预训练方案里每个关键字段在决定什么。前置知识专栏一的交叉熵、梯度下降、AdamW、Transformer、分布式训练基础阅读时间45-60 分钟代码环境Python 3.10示例只依赖标准库读完目标能画出预训练流水线能解释 next-token loss能估算 token、batch、step 的关系能判断一个预训练计划是否缺少关键环节1. 先把问题讲清楚预训练到底解决什么当我们说“训练一个基础大模型”时目标不是直接训练出一个会聊天的客服助手。预训练阶段更像是在训练一个强大的文本续写器给它一段上下文让它预测下一个 token。这个任务看起来很简单但当训练文本覆盖网页、书籍、代码、论文、问答、表格和多语言内容时模型会逐渐学到语言规律、世界知识、代码模式、推理格式和常见文本结构。所以预训练的第一层理解是模型不是被逐条告知规则而是在海量样本中反复做“根据前文猜下一个 token”的练习。开发者可以把它类比成日志补全或代码补全。只看一小段日志模型可能只会猜时间戳看过足够多系统日志后它会学到错误码、调用链、异常堆栈和服务命名习惯。大模型也是这样只是训练规模和文本类型大得多。如果只理解“预训练等于 next-token prediction”还不够。真正的预训练工程是让这个简单目标在万亿级 token、数百到数千张 GPU、数周到数月训练中稳定执行。2. 预训练目标next-token prediction 怎么读先从最核心公式开始。给定一段 token 序列x 1 , x 2 , . . . , x n x_1, x_2, ..., x_nx1,x2,...,xn模型在第t tt个位置要学习的是P ( x t ∣ x 1 , x 2 , . . . , x t − 1 ) P(x_t \mid x_1, x_2, ..., x_{t-1})P(xt∣x1,x2,...,xt−1)这行公式的意思是模型看到前面的 token 后给所有候选 token 分配概率其中正确答案x t x_txt的概率应该尽量高。训练 loss 通常写成交叉熵L − 1 T ∑ t 1 T log P ( x t ∣ x t ) \mathcal{L} -\frac{1}{T}\sum_{t1}^{T}\log P(x_t \mid x_{t})L−T1t1∑TlogP(xt∣xt)逐项解释T TT参与计算 loss 的 token 数x t x_{t}xt第t tt个 token 前面的上下文P ( x t ∣ x t ) P(x_t \mid x_{t})P(xt∣xt)模型给正确 token 的概率− log -\log−log正确 token 概率越低惩罚越大平均值把一批 token 的错误程度压成一个标量 loss。用大白话说如果正确答案是“数据库”模型却把最高概率给了“天气”loss 就会高如果模型逐渐学会在技术上下文里给“数据库”更高概率loss 就会下降。这里有一个容易误解的点预训练不是让模型只背下一个字而是通过预测下一个 token 被迫学习上下文结构。要预测代码里的下一个括号模型要理解语法要预测证明里的下一步模型要捕捉推理模式要预测问答里的答案模型要压缩事实和表达习惯。3. 一条真实预训练流水线长什么样一个简化但完整的预训练流水线可以写成这条链路里每一步都可能决定模型质量。比如数据清洗不充分模型会学会广告话术和乱码去重不足模型可能记住重复网页配比错误代码能力或中文能力会被稀释tokenizer 不合适中文会被切得太碎训练效率下降checkpoint 策略粗糙训练中断后可能损失几天进度。预训练方案评审时不要只问“模型多大、训练多少 token”。更应该问1. 数据源是否合法、可追溯、可复现吗 2. 数据清洗和去重的标准是什么 3. 不同领域 token 配比怎么确定 4. tokenizer 对中文、代码、数字、特殊符号是否友好 5. global batch size、seq_len、训练步数如何计算 6. 学习率计划和稳定性策略是什么 7. checkpoint 如何保存、校验、恢复 8. validation loss 和任务评估如何分层 9. 训练失败时能定位到数据、代码、硬件还是配置吗这些问题听起来琐碎但它们就是预训练能否落地的分界线。4. token、seq_len、batch、step 的关系入门读者最容易混淆的几个词是 token、样本、batch 和 step。先把它们放到一个例子里。假设训练上下文长度seq_len4096global batch size 是 1024 条序列。那么每次参数更新看到的 token 数是4096 × 1024 4,194,304 tokens如果计划训练 100B tokens那么总训练步数大约是100,000,000,000 / 4,194,304 ≈ 23841 steps下面用代码做一个小工具。它不考虑丢弃尾部、动态 padding、packing 细节只用来建立预算直觉# Python 3.10defestimate_steps(total_tokens,seq_len,global_batch_size):tokens_per_stepseq_len*global_batch_size stepstotal_tokens/tokens_per_stepreturntokens_per_step,steps plans[{tokens:100_000_000_000,seq_len:4096,global_batch:1024},{tokens:1_000_000_000_000,seq_len:4096,global_batch:2048},{tokens:1_000_000_000_000,seq_len:8192,global_batch:1024},]forpinplans:per_step,stepsestimate_steps(p[tokens],p[seq_len],p[global_batch])print(p)print(ftokens/step{per_step:,}, steps≈{steps:,.0f}\n)这段代码输出的数字告诉我们两件事seq_len 越长每条样本 token 越多同样 global batch 下每步消耗 token 越多global batch 越大每步 token 越多总 step 越少但显存和并行通信压力更大。真实训练还会有micro_batch_size_per_gpu和gradient_accumulation_steps。它们的关系通常是global_batch_size micro_batch_size_per_gpu × GPU数量 × gradient_accumulation_steps比如单卡一次只能放 2 条序列有 64 张 GPU累积 8 次梯度再更新global_batch_size 2 × 64 × 8 1024这就是为什么训练配置里经常看到很小的 micro batch 和很大的 gradient accumulation。不是工程师喜欢复杂而是显存放不下大 batch只能拆开累积。5. tokenizer 不是小细节预训练先处理 token而不是直接处理中文字符或英文单词。tokenizer 会把文本切成模型能处理的整数 id。同一句话如果 tokenizer 不同token 数可能差很多。对中文、代码、数学公式、日志路径、JSON、SQL 来说tokenizer 的效率会明显影响训练和推理成本。可以用一个极简例子建立直觉。下面不实现真实 BPE只模拟“切得粗”和“切得细”的差别texts[用户登录失败错误码为AUTH_TIMEOUT。,def get_user_profile(user_id): return db.query(user_id),]# 粗粒度为了演示把连续英文数字下划线视作一段中文按字切# 真实 tokenizer 会复杂得多这里只看 token 数差异的直觉importredeftoy_tokenize(text):returnre.findall(r[A-Za-z0-9_]|[\u4e00-\u9fff]|[^\s],text)fortextintexts:tokstoy_tokenize(text)print(text)print(toks)print(token_count,len(toks),\n)如果某个 tokenizer 把常见中文词和代码片段切得过碎同样 1B tokens 能覆盖的信息就更少。反过来tokenizer 词表太大也会增加 embedding 和输出层参数带来训练与部署成本。预训练中 tokenizer 需要关注维度为什么重要中文切分效率中文被切太碎会浪费上下文窗口和训练预算代码符号缩进、括号、下划线、路径对代码能力重要数字和公式数学、表格、金额、日期需要稳定表示特殊 tokensystem/user/assistant、BOS/EOS、padding 要明确兼容性一旦训练开始后续更换 tokenizer 成本很高很多初学者会把 tokenizer 当成前处理工具但在大模型里它是模型接口的一部分。tokenizer 错了后面的训练再贵也很难补救。6. 数据配比决定模型能力结构预训练不是把所有数据合并后随机打乱就完事。假设你有 10TB 网页、1TB 代码、200GB 数学、100GB 中文高质量文本。按体量直接采样网页会压倒其他数据但如果目标模型要有较强代码、中文和推理能力这样的配比可能不合理。数据配比要回答的是在有限 token 预算里每类数据给模型多少学习机会。一个初始数据分层可能长这样数据层主要贡献常见风险通用网页常识、语言多样性噪声、广告、重复高质量长文结构化表达、知识密度许可证和覆盖范围代码编程模式、API、错误处理许可证、重复仓库、过时依赖数学推理多步推理、符号表达模板化、答案污染中文数据中文表达和本土语境质量参差、切分效率安全数据拒答边界、风险识别过度拒答或规则僵硬后面会专门讲数据配比这里先记住一个原则配比不是静态表格而是实验假设。你需要用小规模训练、分层 validation loss、任务评估和人工抽样不断调整。7. 学习率计划不要一开始就猛踩油门预训练中优化器通常每步根据梯度更新参数。最简化的更新可以写成θ t 1 θ t − η t ∇ θ L t \theta_{t1} \theta_t - \eta_t \nabla_\theta L_tθt1θt−ηt∇θLt逐项解释θ t \theta_tθt第t tt步的模型参数∇ θ L t \nabla_\theta L_t∇θLt当前 batch 计算出来的梯度η t \eta_tηt当前学习率更新方向沿着让 loss 下降的方向移动。这行公式真正想告诉你的是学习率控制每一步走多远。步子太大可能直接跨过稳定区域出现 loss spike步子太小训练进展很慢。常见学习率计划包括 warmup 和 decay。下面是一个线性 warmup cosine decay 的简化实现# Python 3.10importmathdeflr_schedule(step,total_steps,warmup_steps,max_lr,min_lr0.0):ifstepwarmup_steps:returnmax_lr*step/max(warmup_steps,1)progress(step-warmup_steps)/max(total_steps-warmup_steps,1)cosine0.5*(1math.cos(math.pi*progress))returnmin_lr(max_lr-min_lr)*cosineforstepin[0,100,1000,5000,9000,10000]:print(step,f{lr_schedule(step,10000,1000,3e-4,3e-5):.8f})这段代码前 1000 步逐渐升高学习率后面逐渐降低。warmup 的意义是训练初期参数、激活和优化器状态都还不稳定不要一上来就大步更新。decay 的意义是训练后期接近较优区域时逐渐减小步长让模型更稳定地收敛。8. 训练显存为什么远大于模型权重很多人第一次估算训练资源时会犯一个错误只算模型权重。比如 7B 参数用 BF16 存大约需要7B × 2 bytes ≈ 14GB于是误以为 24GB 显卡可以训练 7B。实际训练远不止权重还包括梯度AdamW 的一阶和二阶动量FP32 master weights视训练方案而定前向传播保存的激活值通信 buffer框架临时张量KV 或 attention 中间结果。用一个粗略估算看参数相关状态# Python 3.10defadam_state_memory_gb(params_billion,use_master_weightsTrue):paramsparams_billion*1_000_000_000# bf16 param 2 bytes, grad 2 bytes, Adam m/v each 4 bytesbytes_per_param2244ifuse_master_weights:bytes_per_param4returnparams*bytes_per_param/1024**3fornin[1,7,13,70]:print(f{n}B params - param-related training states ≈{adam_state_memory_gb(n):.1f}GB)这还没有算激活值。序列越长、batch 越大、层数越多激活值越大。第 44 篇会展开 DeepSpeed ZeRO 如何切分这些状态。这里先建立直觉训练显存不是推理显存乘一个小系数而是完全不同的账本。9. checkpoint 不是“保存一下模型”这么简单预训练任务可能跑很多天。硬件故障、网络抖动、进程崩溃、数据异常都可能发生。如果没有可靠 checkpoint一次故障可能浪费大量算力。一个可恢复的 checkpoint 通常不只包含模型参数还包含1. 模型权重 2. 优化器状态 3. 学习率 scheduler 状态 4. 当前 step 和已消费 token 数 5. 随机数状态 6. 数据采样器状态 7. tokenizer 和训练配置版本 8. 分布式分片信息 9. 评估记录和代码版本。如果只保存权重不保存优化器状态恢复后学习率和动量可能不连续loss 会异常。如果不保存数据采样状态恢复后可能重复训练或跳过数据。如果 tokenizer 或代码版本没有记录几周后很难复现实验。工程上建议至少有三类 checkpoint类型用途frequent checkpoint频繁保存用于故障恢复milestone checkpoint关键阶段保存用于评估和回滚final checkpoint训练结束用于后续 SFT 或发布checkpoint 还要定期做恢复演练。只会保存但从未恢复过等真正故障时才发现路径、权限或分片配置有问题就太晚了。10. 评估validation loss 重要但不够预训练中最常见的监控指标是 train loss 和 validation loss。它们能告诉你模型是否在继续学习是否过拟合是否出现训练异常。但 loss 低不等于模型一定好用。原因有三点validation 集可能和训练分布太相似只反映续写能力对话能力、工具使用、安全边界通常来自后训练业务任务关心的是可用性不只是平均 token 概率。一个更完整的预训练评估面板可以包含评估层示例语言建模分领域 validation loss、perplexity通用能力常识、阅读理解、知识问答代码能力补全、修复、单测、解释数学推理逐步解题、符号计算、应用题中文能力中文问答、写作、成语、口语化输入长上下文长文摘要、跨段引用、位置鲁棒性安全边界有害请求、隐私、偏见、拒答下游适配SFT 后是否更容易得到好助手预训练评估的关键不是追求一个万能分数而是持续监控能力结构。某次数据配比调整后代码能力上升但中文写作下降这不是简单的好坏而是取舍。11. 小团队是否应该从零预训练对大多数团队来说从零预训练不是默认选项。原因很现实高质量数据难收集、难授权、难清洗训练算力成本高稳定性问题复杂评估体系建设成本高开源基础模型已经覆盖了大量通用能力后续还要 SFT、对齐、部署和监控。更常见、更务实的路线是选择合适基础模型 - 先做 Prompt/RAG 验证需求 - 有行为格式问题再做 SFT - 显存不足用 LoRA/QLoRA - 有大量稳定领域语料再考虑持续预训练 - 最后做偏好优化、安全评估和上线监控什么时候才值得考虑从零预训练或大规模持续预训练通常需要同时满足1. 有独特且大规模的高质量数据 2. 现有基础模型无法满足核心能力 3. 有稳定训练基础设施和工程团队 4. 有清晰评估集证明训练收益 5. 预算允许多轮失败和迭代 6. 模型上线规模足以摊薄训练成本。如果只是想让模型知道公司制度RAG 往往比预训练合适。如果只是想让模型按固定 JSON 输出SFT 比预训练合适。如果只是想让模型语气更像客服少量高质量 SFT 数据可能已经足够。12. 常见误区误区一预训练数据越多越好。低质量、重复、污染和侵权数据会浪费训练预算还可能带来安全与法律风险。数据质量、去重、配比和治理同样重要。误区二loss 下降就代表模型全面变强。loss 是基础信号但代码、数学、中文、安全、长上下文等能力要分开评估。误区三只要训练能启动就能稳定跑完。大规模训练会遇到 loss spike、硬件故障、checkpoint 损坏、数据读取瓶颈和通信异常。误区四从零预训练比微调更专业。工程上应选择投入产出比最高的方案。很多业务问题用 RAG、SFT、LoRA 就能解决。误区五训练配置可以复制别人的。模型规模、GPU、网络、seq_len、数据配比和目标任务不同最优配置也不同。13. 小结预训练是大模型能力的地基但它不是神秘仪式。它的核心目标是 next-token prediction核心链路是数据、算法和基础设施三条线共同闭环。数据决定模型能看到什么tokenizer 决定文本如何进入模型batch 和 step 决定训练节奏学习率和优化器决定参数如何更新checkpoint 和监控决定训练能否稳定跑完评估决定你是否真的得到了想要的能力。从开发者视角看理解预训练的价值不只是为了自己从零训练模型更是为了看懂后续所有技术为什么数据清洗重要为什么 ZeRO 能省显存为什么 Chinchilla Law 讨论参数和 token 比为什么持续预训练有遗忘风险为什么 SFT 和 LoRA 不是预训练的替代品。大模型视角从大模型技术主线看预训练决定模型能力的上限后训练能调整行为、格式和边界但很难补回数据和算力没有给到的能力。理解这条链路你就能判断一个问题应该回到预训练解决还是交给 SFT、RAG 或提示工程。下一篇下一篇会讲预训练数据处理。因为在大模型训练里数据不是准备工作而是模型质量、风险和成本的起点。