
最近半年AI圈子里有个话题被反复提起除了会调用现成的模型API、会拉开源权重跑推理你有没有能力从一个随机初始化的权重开始自己训出能用的模型我给自己立的目标很直接——走完一条真正“from scratch”的AI工程链路从原始语料清洗、tokenizer训练、模型架构实现、预训练、推理能力强化一直推到服务化部署上线。这篇文章就是我在这条路上踩坑、拆解、复盘的完整记录。它不是一份教程的目录而是我实际动手做下来后回头整理出的思路和教训。适合已经上手过Python、跑过开源模型的工程师也适合正在犹豫要不要把底层原理啃下来的同学。1. 别把“from scratch”当成炫技它是AI工程能力的照妖镜1.1 只会调API和真正从零构建差距到底在哪我在组里带过几个新人简历上都写着“熟悉大语言模型应用开发”实际工作里遇到最多的情况是调用某个模型API返回了异常或者推理结果突然变差了第一反应是换一个更大的模型或者把温度参数调小。问到底层为什么基本答不上来。这不是他们的错而是“应用层开发”本身就很难触及到模型内部。但你一旦开始从零构建一个AI系统视角会完全不一样。举个具体例子。很多人不知道同样的温度参数在不同的采样实现里结果差别很大。比如有的框架用top-p叠加temperature有的先做top-k再做temperature有的在softmax之前乘temperature、有的在之后乘。你在API里调了一个temperature0.8本地拿开源权重用vLLM跑同样的提示词结果就是不一样。这种问题只有自己实现过采样器、自己对比过输出分布才会真正理解。再比如KV cache的显存占用为什么长上下文那么吃内存为什么量化后的模型在某些任务上突然变笨为什么同样的LoRA在不同框架里merge出来的结果会有细微差异。这些全是从零构建时会迎面撞上的东西。物理学家费曼有句话我一直很认同What I cannot create, I do not understand。放在AI工程里尤其准确。你只有亲手把一个大语言模型从零搭起来、训练起来、部署起来才算真正理解这套系统。而这个过程也会把你和那些只会“调包”的开发者彻底区分开。1.2 “AI工程从零开始”的真实定义链条上的每一环都不能断很多人以为“from scratch”就是自己写一个Transformer架构训练一个模型完事。真做过一轮就会发现模型架构只是整条链路里很小的一段。我做完一遍后把“从零开始”拆成了下面七个环节数据工程原始语料的采集、清洗、去重、语言/领域配比。Tokenizer训练自己训练BPE词表设置词表大小和特殊token。模型实现从空文件开始写Transformer包括多头注意力、前馈网络、LayerNorm、位置编码。预训练实现训练循环、学习率调度、混合精度、梯度累积、分布式训练。后训练SFT指令微调、基于人类反馈的强化学习RLHF/DPO或者近两年火起来的推理强化。评估搭建自己的评测集量化模型在不同任务上的能力变化。服务化部署量化、推理优化、KV cache管理、监控与灰度。有人会说我只想训练一个模型做研究后面那些服务化、数据工程是不是可以跳过我的经验是跳过任何一环后面都会以某种方式回来找你麻烦。我见过不少研究者只关注模型训练结果数据管道不规范训练完发现语料里混了大量重复数据模型只会输出重复文本也有人只做服务化模型上线后评估体系缺失一次微调迭代直接让线上效果暴跌还不知道是哪一轮数据导致的。真正的AI工程不是某一个环节的深度而是整条链路的稳定和可追溯。2. 从零构建LLM复现那本书的路线时我啃下的硬骨头2.1 Tokenizer训练BPE合并规则里的编码直觉我最早走的路子是照着Sebastian Raschka的《Build a Large Language Model from Scratch》一步步来。这本书的核心思路是让你用PyTorch从零实现一个类似GPT的模型从数据预处理一路做到指令微调。书里第一章就讲数据准备和tokenizer这一步的枯燥程度被绝大多数人低估了。Tokenizer本质上是文本和数字ID之间的桥梁。BPEByte Pair Encoding的思路很朴素先把文本拆到字节级别然后不断统计相邻token对出现的频率把最高频的pair合并成一个新token反复迭代直到达到目标词表大小。比如“low”和“lower”里的“low”出现频率很高BPE就会把“low”合并成一个token而不是让模型每次都通过“l”、“o”、“w”三个token去拼。实操里最关键的两个参数是词表大小和是否使用字节级BPE。词表太小长尾词汇要靠多个token拼接序列长度变长训练和推理成本都上去词表太大embedding矩阵和输出层占的显存会非常夸张。我试过用16k词表训练中文垂类模型一句话被切成了50多个token训练效率惨不忍睹。后来换成字节级BPE、词表扩到32k效果立刻不一样。还有一个容易踩的坑训练tokenizer的语料和预训练的语料必须保持一致的口径。我第一版图省事直接用通用英文语料训练tokenizer然后拿中文语料去预训练结果中文全被切成单字或乱码loss迟迟降不下来。后来才意识到tokenizer的统计分布和你真实语料的字节分布必须匹配这是最基础的工程常识但很多初学者都会忽略。2.2 多头注意力与前馈网络所有张量形状都要过一遍手算模型实现这部分我不建议直接复制开源代码。我自己实现了一遍然后在纸上把所有张量的形状推导了一遍收获比看十篇教程都大。以d_model512、n_heads8、d_k64的配置为例输入x的形状是[batch_size, seq_len, 512]。Q、K、V三个线性投影矩阵都是[512, 512]所以三个矩阵相乘后输出还是[batch_size, seq_len, 512]。把最后维度拆成8个头变成[batch_size, 8, seq_len, 64]。缩放点积注意力Q * K^T / sqrt(64)得到注意力分数形状[batch_size, 8, seq_len, seq_len]。因果掩码保证只能看到当前位置之前的tokensoftmax后乘V最后把8个头拼回[batch_size, seq_len, 512]再过输出投影。这一套逻辑并不复杂但如果你只调库永远不会直观感受到“为什么KV cache能省算力”“为什么GQA能降低显存占用”。当你看到每步计算都要为完整的键值对分配显存时就会理解KV cache的核心价值是复用历史token的K和V矩阵而不是每步重新算一遍。参数量也可以手算。单层Transformer里注意力部分是Q、K、V、O四个矩阵每个是d_model的平方即4×512²≈1,048,576前馈网络是d_model × 4*d_model和4*d_model × d_model两个矩阵共8×512²≈2,097,152。加起来单层约314万参数。12层就是约3770万。加上词表32k×512的embedding约1600万一个“小模型”总共约5400万参数。这个数字一算出来你就知道模型参数规模的结构性来源了。位置编码上现在主流都用旋转位置编码RoPE代替早期的绝对位置编码。它的好处是能将相对位置信息直接编码到注意力计算里。我建议至少手写一遍RoPE的实现理解高频和低频旋转分量的含义这对后面做长上下文扩展很有帮助。2.3 训练循环与工程参数这些数字不是玄学预训练的核心是一个循环取一批数据前向计算损失反向传播更新权重。这个循环本身不复杂复杂的是你围绕它设置的所有工程参数。学习率调度我采用的是warmup加cosine decay。比如1B参数模型峰值学习率3e-4前2000步线性热身之后按余弦曲线衰减到峰值的十分之一。为什么要warmup因为训练初期模型权重还是随机的梯度方向噪声很大过高的学习率会让loss直接冲到NaN。为什么衰减到十分之一而不是更小因为训练后期需要更精细的收敛但太低的学习率会导致模型在小区域抖动过拟合。序列长度和批次大小的取舍也直接影响训练稳定性和显存。序列长度从512加到2048注意力矩阵占用的显存是平方增长。我最初直接上2048单卡80GB都不够用被迫加了梯度累积和gradient checkpointing。梯度累积的本质是把一个大batch拆成多个小batch分多次前向反向累加梯度后再更新一次参数等价于更大的batch size但显存占用更低。gradient checkpointing则是在前向过程中不保留中间激活值反向时重新计算牺牲时间换显存。数据配比是预训练效果的上限来源。我按通用文本、代码、数学、多语言四个领域按6:3:0.5:0.5的比例混合。代码数据虽然占比不高但能显著提升模型的逻辑推理能力因为它天然包含大量结构化、可推导的模式。数学数据占比再少也必须在预训练阶段就混入否则后训练阶段用RL强化推理时模型连最基础的等式推导都做不了。训练过程中我只看两个指标loss曲线和梯度范数。loss下降说明模型在从数据里学到规律梯度范数突然飙升说明学习率太高或数据里混入了异常样本。我自己的观测是从随机初始化开始训练前几百步loss会从接近log(vocab_size)的水平快速下降相当于模型在快速掌握“哪些token是高频的”。之后进入平台期下降越来越慢。这个阶段很多人会焦虑但说实话1B参数级别的模型用单卡A100连续训练几天能看到loss稳定下降就已经说明配置是健康的。3. 从零训练一个会“推理”的模型策略梯度、奖励和思维链数据的组合拳3.1 推理模型的核心本质把“思考过程”变成训练目标传统LLM的训练目标是预测下一个token模型回答问题时是“一步到位”的。但复杂任务不是一步到位的比如数学题、代码调试、多步逻辑推断需要先想清楚中间步骤再给出答案。OpenAI o1系列和DeepSeek-R1带火的推理模型本质上做了一件事把模型的“思考过程”显式生成出来并用强化学习让这个过程越来越好。我自己的理解是推理模型不再只是“模仿人类写过的答案”而是“自己去试错、探索然后通过奖励信号学会什么样的思路能得出正确答案”。这才是从模仿到强化的关键跃迁。DeepSeek-R1-Zero最震撼的一点是没有依赖大量人工标注的思维链数据直接用强化学习在基础模型上训练就涌现了“自我反思”和“重新审视”的行为被研究者称为“aha moment”。这说明推理能力有一部分是可以在适当激励下涌现出来的而不是非得手把手教出来。但完全从零上RL也不是个好路子。DeepSeek-R1-Zero虽然推理能力很强但输出可读性差、语言混杂、思考长度不可控。所以后来R1加了“冷启动”阶段先用少量高质量思维链数据做SFT再上大规模RL。3.2 数据从哪来冷启动SFT与合成思维链数据的构成构建推理模型最费时间的不是训练而是数据。冷启动SFT数据的目标不是求多而是求“规范”。每条数据的基本格式是问题 思考过程 最终答案。思考过程要分步、有逻辑、有自查最终答案要简洁、绝对正确。这些数据怎么来我试过两条路人工标注成本极高大概一条高质量数学思维链数据需要20-40分钟一个人一天也就标几十条。好处是质量有保证适合起步阶段做几百条冷启动数据。合成数据用能力更强的推理模型生成候选思维链然后用规则或小模型打分过滤。比如让一个强模型生成10条解题思路保留能得出正确答案且步骤不缺失的那几条。这样数据量可以很快扩到几万甚至几十万条。我现在的建议是先人工标注300-500条作为冷启动种子再扩量做合成。合成数据一定要做过滤否则会放大幻觉。我最初让强模型生成几万条数据直接拿去训练结果模型学到了一个坏习惯先写一堆废话推理最后答案还是错的。因为生成数据里有一部分答案本身是错的但模型以为只要“过程长”就能得奖励。3.3 强化学习阶段GRPO的工程实现与训练稳定性问题推理模型的RL阶段我采用的是DeepSeek-R1公开路线里的GRPO算法。GRPO全称是Group Relative Policy Optimization核心思想和PPO类似都是最大化策略模型的期望奖励但有一个关键区别GRPO不需要价值模型critic而是用同一组采样结果的相对表现来计算优势。具体流程是一个prompt输入策略模型采样出G个不同的完整回复然后对每个回复计算奖励。奖励通常由两部分组成格式奖励和正确性奖励。格式奖励是规则化的检查模型是否包含think和answer标签正确性奖励则对最终答案做判断数学题可以直接比对数值。每个回复的优势值不是绝对奖励而是组内相对奖励的归一化结果A_i (r_i - mean(r)) / std(r)。也就是说如果这一组里所有回复都比较差那相对最好的那个依然有正优势如果所有回复都对那它们的优势都趋近于0模型不会被推向某一条特定路径而是保持稳定。这符合我们想要的探索特性——不只模仿某一条成功路径而是持续探索更好的解法。GRPO不用价值模型的直接好处是显存减半。1B参数的策略模型加一个7B价值模型光价值模型就要占14GB加上策略模型的权重、优化器状态和激活值单卡80GB根本不够。用GRPO后多出来的显存可以开更大的采样组数量G。RL训练里最常见的三个坑我全部踩过熵坍缩模型策略收起多样性总是输出同样的文本。原因是KL散度约束系数设得太小或者学习率太大。我处理的方式是调高KL系数并监控生成文本的重复率和熵值。Reward Hack模型找到了奖励函数的漏洞比如不回答问题但正确输出标签或者重复“正确”的文本片段来刷格式奖励。这个只能靠奖励设计者自己抽检生成样本来发现。我的教训是规则奖励越简单越好越复杂的规则越容易被钻空子。长度失控模型为了“显得认真”无限拉长思考过程。R1也遇到过类似问题后来通过长度奖励和采样截断来约束。4. AI工程真正的护城河评估、数据管道与服务化的隐形工作量4.1 评估体系没有它你根本不知道模型是进步还是退步我见过不少团队模型训练完只看loss和几个“好听”的指标就上线结果用户反馈一塌糊涂。原因很简单loss下降和任务质量提升没有直接等价关系。你在预训练里把困惑度从8降到5不代表它数学解题能力变强了。我自己搭建的评估体系分三层通用基准用公开benchmark比如MMLU测知识广度、GSM8K和MATH测数学推理、HumanEval测代码生成。这些指标的好处是可以横向对比坏处是测试集可能被污染尤其当你的训练数据里包含评测集时。领域任务集根据自己的应用场景专门构造一批评测样本。比如我做的垂类模型是代码辅助方向就整理了几百道真实代码补全和Bug定位题多轮迭代中每次评估都用同一批题。人工抽检机器评估永远无法替代人的判断。我每条prompt至少看20个模型生成的样本重点看流畅度、逻辑自洽性和幻觉程度。我最大的教训是评估集要版本管理。早期我用一个固定的评估集跑多轮迭代结果发现模型在某个数据集上分数越涨越高换一个没见过的数据集却大幅下降。后来定位到原因评估集反复使用模型通过训练数据或人工筛选时“背题”。解决方式是多准备几个平行评估集每过几轮就换一批新题并且监控训练数据里是否意外混入了评估集的原始文本。4.2 训练数据管道的工程化比模型架构更吃时间真正做过从零训练以后你会发现最耗时的不是模型代码而是数据管道。原始语料获取只是第一步后面紧跟着清洗、去重、过滤、配比、版本管理每一步都有细节。比如去重如果你直接对整文本做哈希去重可能会把合法的重复模板文本全删掉。我的做法是先做MinHash近似去重再对高相似度文本做精确去重。还有质量过滤简单按文档长度过滤不够还要用困惑度或者关键词规则过滤低质量文本比如纯广告、乱码、无意义字符。数据配比不是一次性设置的要动态调整。我训练到一半发现模型对代码任务的泛化变差排查后原因是代码语料在混合比例里被通用语料稀释了。后来我把代码语料比例从20%提到35%模型代码能力明显回升。数据管道还要做版本管理每次数据改动都打标签记录。否则后面模型出问题时你根本不知道是哪份数据引入的噪声。我自己吃过一次亏一次数据清洗误删了一部分特殊字符语料导致模型对某些代码符号的理解出现退化回滚数据版本重新训练两周才算恢复。4.3 模型服务化的最后5%工作才是生产环境的分水岭模型训练完只是第一步服务化部署里藏着大量“最后5%”的隐性工作量。首先是量化。FP16权重直接部署一个7B模型光权重就要14GB加上KV cache和CUDA上下文单卡16GB很难跑。我用INT8量化后权重降到约7GB再配合AWQ或GPTQ做校准精度损失控制在可接受范围内。但量化不是无脑上的我碰到过某些层在量化后数值分布严重偏移导致模型输出明显变差的情况最后只能layer-wise混合精度保留关键敏感层为FP16。其次是KV cache管理。前面计算过一个7B模型每个token的KV cache大约128KB8K上下文就需要约1GB。这意味着并发用户越多显存占用涨得越快。我在生产环境里限制了最大序列长度并启用了前缀缓存把系统提示词和常用对话历史的KV计算结果复用到新请求上显著降低了首Token延迟。最后是监控和灰度。模型上线不等于结束我需要盯着误差率和用户反馈。每一次微调后的模型都要小流量灰度分桶对比关键指标再决定是否全量。这套流程虽然不性感但它是AI工程最终能稳定运行的基础。5. 复盘一条具体的学习路线、资源与避坑清单5.1 从零到一我推荐的四阶段路线第一阶段是跟着《Build a Large Language Model from Scratch》从头实现一遍模型、训练循环和微调流程。这本书的主线很清晰每章都能跑出可视化的结果适合建立全貌。它不涉及强化学习但把预训练和微调讲得非常扎实。我建议每章代码都要自己敲一遍不要直接跑GitHub上的答案敲的过程中才能发现问题。比如我自己就是在手敲注意力实现时才发现因果掩码的方向写反了导致模型能看到未来的token损失还在下降但推理结果根本没有意义。第二阶段是训练一个小的垂类模型参数规模控制在0.5B到1B之间。用开源框架也好自己写的训练脚本也好目标不是突破SOTA而是掌握数据配比、超参调优和训练日志分析。第三阶段是后训练SFT指令微调 DPO或RLHF。先让模型学会对齐人类偏好再做推理强化也就是我前面说的GRPO路线。第四阶段是部署和评估闭环。把模型量化、服务化搭建自动评估流程形成一个从数据迭代、模型训练、效果评估到上线灰度的可持续循环。5.2 我踩过的坑与应对方法坑现象根因处理方式Tokenizer语料与预训练语料口径不一致中文被切成乱码loss不降词表统计分布和真实语料分布不匹配统一语料口径用同源数据训练tokenizer显存溢出8×A100训练1B模型仍然OOM未开混合精度激活值没有checkpointing启用BF16混合精度加gradient checkpointingRL时Reward Hack模型输出大量重复文本刷格式分规则奖励设计被钻漏洞简化奖励规则人工抽检生成样本评估集污染多次迭代后评估分数虚高训练数据意外混入评测数据建立数据版本管理定期换平行评估集量化后精度崩塌INT8模型某些任务大幅变差敏感层数值分布偏移逐层评估关键层保留FP16混合精度量化5.3 成本与算力怎么省先想清楚再做比什么都省普通人做从零训练最大的障碍不是技术是算力成本。我自己的经验是用一张或两张A100 / H100级别的卡先跑通一个小模型的全流程把每个环节的脚本和数据管道都调稳定再考虑大规模训练。直接用大模型和大规模数据起步一旦配置错了几天的时间和几万元的算力费用就全搭进去了。云上租GPU按需付费比自购服务器划算得多。前期开发调试用低规格卡就行正式训练再租高规格卡。训练过程中一定要定期保存checkpoint我一般每两三个小时存一次。这样即使训练中途崩溃损失最多是几个小时的计算时间而不是从头再来。另外如果只是做推理验证优先用量化后的模型而不是FP16原始权重显存占用差距可能超过一半成本差距被进一步放大。最后说点实在话这一轮“from scratch”做下来我最大的体会是真正的AI工程能力不是会实现某一个具体算法而是知道整个系统每一个环节为什么这样设计、哪里会出问题、出了问题怎么排查。从零构建一遍等于把模型从“黑盒”变成了“灰盒”——虽然内部还有很多不透明的地方但你至少知道哪些旋钮会影响哪些结果哪些环节的改进会带来什么代价。如果你也打算走这条路我给你一个最实际的建议不要急着直接上几百亿参数的大模型先从一个1B左右的模型开始把数据、训练、评估、部署整条链路跑通。这个过程里你会踩到无数个坑但每一个坑都会变成你后续决策的依据。等到你真的需要构建更大的系统时这些积累会让你少花几十万的算力成本。