
写《从零训练一个大语言模型》写到第五篇后台私信里出现频率最高的不再是具体的训练报错而是一个更“大”的问题明明训练目标只是让模型预测下一个字它凭什么能翻译、写代码、做逻辑推理这个问题问得多了我越觉得应该专门写一篇把它讲透。这个系列的读者里有刚入门的学生也有做AI应用开发的工程师。大家起点不同但通常会在某个深夜盯着loss曲线发呆数字确实在往下掉可模型真的“变聪明”了吗这篇文章不打算堆公式只想讲清楚三件事为什么偏偏是“预测下一个字”孕育了智能训练过程中模型内部大致发生了什么以及这种智能的边界到底在哪里。如果你也在从零训练大语言模型这篇读起来应该比纯论文推导舒服得多。1. “预测下一个字”的本质不是语文题而是信息压缩题1.1 一个被低估的目标函数交叉熵到底在算什么先回到训练的最基本动作。所谓“预测下一个字”在工程上对应的是“下一个token预测”配合交叉熵损失。训练时模型读取一段文本的前面部分对“下一个token”输出一个覆盖整个词表的概率分布正确的token概率越高损失越低。这个动作看起来人畜无害但它的数学含义非常深它等价于你在用模型把一段文本编码成尽量短的比特序列。香农信息论告诉我们一个事件携带的信息量等于它出现概率的负对数。一个不容易猜到的词一旦被猜中说明模型对上下文的解释力很强一个经常出现却总也猜不对的词则说明模型还有信息没吸收。所以模型训练的整个过程其实是在做“压缩”把海量文本里的规律一点点转移进模型参数里。参数是压缩后的字典前向传播是解压过程。这个角度看过去大语言模型和zip压缩本质是同一类数学问题。1.2 想猜中“下一个字”你必须先“理解世界”我经常用一个例子来跟人解释这件事。给你一句话“她推开门一阵风吹过来桌上的纸突然____。”要让模型合理地填出“飞”或“飘起来”它至少得知道风能对轻物体施加力纸是轻的桌面不是一个封闭盒子。这些知识并非被显式写进代码而是从海量文本中统计出来的。再比如“他体温三十九度医生建议先____”合理的续写依赖医疗常识“铁块在太阳下晒一天会变得更____”涉及基础物理直觉。模型对每个位置都做预测就相当于被一个极其严苛的老师按着头要求如果你不想一直得低分就必须把文本背后的物理规律、因果链条、空间关系、社会惯例全部内化到参数里。这里有一个需要澄清的误区模型并不是像人一样真有一个世界模拟器而是为了降低预测误差被迫寻找一个“统计意义上够用”的内部表征。当这个表征越能预测语料它就越像一个可用的世界模型。“世界模型”不是说它脑子里真的在渲染画面而是说在行为上它能正确预判大部分事件的结果。1.3 为什么“随便猜一个高频词”不行有人可能会说那我干脆每次都猜“的”“是”“了”这类高频词是不是也能拿低损失答案是不行。语言里信息量最大的部分往往集中在低频、强上下文相关的词上。高频功能词占比很大但每个词携带的熵极少“线粒体”“司法解释”“量子纠缠”这类词出现频率低可一旦出现对预测的约束力就极强。交叉熵是对所有位置预测质量的综合打分你猜对一百个“的”也弥补不了猜错一个“线粒体”。这也在相当程度上解释了为什么数据规模和数据多样性如此重要一个只会复读高频词的模型在信息论上毫无价值。1.4 为什么不需要人工标注也能学自监督的妙处“预测下一个字”还有一个经常被低估的好处它不需要人工标注。传统机器学习要花大力气标数据而自然语言本身就自带标签——任何一个“上文”都是下一个词的提示任何一个词都可以成为前文的答案。训练用的语料有多大“免费标签”就有多少。这个特性让语言模型可以从互联网级别的文本里吸收知识这是它最后能变得“聪明”的规模前提。一个需要人工标注的任务规模撑死到百万级自监督任务规模可以轻松到千亿token级。所谓智能很多时候就藏在规模门槛的另一边。2. 训练路线图一个 token 一个 token 地逼出“世界模型”2.1 从随机噪声到能说话的模型训练阶段长什么样我手头跑过的小规模复现参数规模在千万到十亿之间让我对“智能如何长出来”有了很具体的体感。说实话“智能时刻”不会像烟花一样在某一个迭代突然炸开它更像一层一层地长出来。为了讲清楚我把它拆成四个阶段阶段损失曲线形态生成效果词频复读期快速下降只会复读“的”“是”“了”句子断裂语法习得期下降放缓能生成通顺短句但内容空洞、经常跑题话题稳定期缓慢下降能在同一话题内保持连贯常识错误减少规则沉淀期逼近数据熵下界对没见过的新组合也能给出合理延续这张表也对应了一个训练规律前期损失下降靠的是背下高频搭配后期损失下降主要靠抽象规则。这也是为什么数据质量在后期比数据数量更重要的原因。看loss曲线时别只盯着数值要看生成样本的结构复杂度。2.2 数据分布是隐藏的课程表语料顺序的现实影响从零训练一个模型的人经常把注意力全放在模型结构和学习率上对数据分布配比不够敏感。我自己踩过坑把高质量长文全部堆在前面早期模型会显得很“木讷”把大量低质量网络文本混进早期语料模型又会花更长的步数才能把基础语言能力打牢。比较稳的做法是把数据排成一个从通用到专业的顺序通用网页和书籍垫底代码和专业语料按比例混入指令数据放到最后的收尾阶段。这样安排的逻辑很简单——先学语言本身再学事实最后学交互格式。课程学习听上去很高级但小规模训练里简单的分层排序已经够用复杂策略的收益并不明显调试成本反而更高。另外去重这件事别偷懒。我在一次小规模实验里只是对语料做了模糊去重最后阶段的验证损失就降了一截生成里的重复套话也明显减少。数据工程做得如何直接决定后面能走多远这在前几篇里反复强调过这里旧事重提是因为它和“理解”的形成关系实在太密切。2.3 教师强迫和自回归生成两个模式的关键差异一个容易被新手忽略的细节训练时和推理时模型的工作方式完全不同。训练用的是teacher forcing把整段真实文本一次性喂进去在每个位置都做预测不管模型在这个位置猜得对不对下一个位置看到的仍然是真实文本。推理时则变成自回归模型自己预测出的token作为下一次预测的输入。也就是说训练时它一直在“看标准答案上下文”推理时却要面对“自己瞎编的上下文”。误差会随着生成逐步累积这也就是生成文本越写越离谱的原因之一。理解了这一点你就会明白为什么第四章里的解码策略那么重要也能理解“让模型看着自己的输出训练”这类技巧为什么会有效。3. 它是在“记忆”还是在“理解”两个实验能看出分水岭3.1 实验一把训练集里的段落改一个词看模型怎么反应我评估模型时常用一个便宜但有效的测试取一段训练数据里确实出现过的文本把其中一个关键名词换成同类的另一个词然后让模型续写。如果模型真的背诵了这段文字续写时它会自动把原来的名词补回来驴唇不对马嘴如果模型学到的是更抽象的概念它会顺着新词给出一个语义上还讲得通的新续写。这个现象在小参数量模型上极其明显几乎等于复读机。参数量上去之后即使loss差不多模型“修补”能力也会显著增强更倾向于理解式重建。当然这里没有一条绝对的分界线本质上“记忆”和“理解”在这类系统里是混在一起的。但如果你只能选一个指标这个测试可能是最便宜的判断方式。注意做这种测试时要确保改写后的句子在语法上完全通顺。如果新词和原词在语法位置上不一致模型续写跑偏就不能算作测试结果的有效证据。3.2 实验二问一个反事实问题看模型会不会“顺着规则走”比改词更苛刻的是反事实测试。比如把“猫喜欢吃鱼”改成“猫喜欢吃石头”再追问“如果猫真的改吃石头它们在生态系统里的角色会怎样变”纯靠统计搭配的模型会当场懵掉因为训练数据里根本没出现过这种组合具备一定规则抽象能力的模型则会尝试在“食性变化影响生态位”的框架下推导。实测下来小模型经常把反事实条件当成普通事实来复述稍大一点的模型能部分利用条件约束看似在推理但往往在第二个转折点上泄气。这说明所谓“理解”在模型里是分层出现的简单规则容易沉淀复杂因果链非常不稳定。这也是为什么学术界对“模型究竟理不理解”争论不休的原因——它确实在不同层次上都展现出了理解的影子。3.3 记忆与理解之间其实是一片连续谱我们习惯把“记忆”和“理解”当成两种截然不同的能力但在神经网络里它们更像同一个压缩过程的两个端点。模型会优先尝试直接存储当存储空间不足或者数据本身存在很强的规律时它才会被“逼”出抽象规则。参数规模增大不等于说它背诵的东西更多而是它能容纳更多规则性的描述因此对没见过的新输入也能做出合理反应。把模型训练到接近数据熵下界时它几乎是在用一套抽象模式去复现数据而不是逐字背诵。我在从零训练时最深的体会就是不要只盯着loss值定期做这类对比测试比什么都可靠。3.4 小心评估集污染别把“见过”误判成“理解”做这类实验最容易犯的错是评估集和训练集存在重叠。如果你设计的补全测试其中的句式或关键词在你训练语料里频繁出现那么模型给出的漂亮回答很可能只是“见过”而非“理解”。我自己的做法是专门留一部分样本训练过程中绝对不看、不用甚至刻意构造训练语料里没有的句式来测试。只有当你拿着这种“隔离评估集”去测还观察到稳定的规律性反应才说明规则真正沉淀进了参数。否则你感受到的智能可能只是记忆的回声。4. 采样温度与解码策略把“预测概率”翻译成“智能表现”的最后一步4.1 greedy解码为什么会让人觉得“呆”训练完模型后很多人直接拿贪婪解码去生成结果发现输出死板、重复、像复读机就怀疑训练出了问题。实际上greedy解码每一步都选概率最高的token表面看是最优选择实际却很容易让整个句子滑向平庸甚至循环的套路。打个比方一个人永远只做最有把握的事短期内无风险但长期会把自己的路越走越窄。语言生成也是如此局部最高概率的选择往往会把后面带进一个低质量的沟里。大模型推理时真正该做的是“从合理分布中采样”而不是“挑最大概率”。这个认知对从零训练的人尤其重要因为你还没有做偏好对齐直接greedy出来的观感通常会非常差而这不代表模型没训练好。4.2 temperature、top-k、top-p到底在改什么temperature这个参数数学上就是先把logits除以一个温度值然后再做softmax。温度越低概率分布越尖锐输出越保守温度越高分布越平低概率词被选中的机会越大。top-k是保留概率最高的k个词作为候选top-p是保留累计概率达到阈值p的最小候选集合。两者都是截断策略目的是把尾部那些又低又离谱的词挡在门外。实操区间我整理成了一张表参数作用常用区间备注temperature缩放logits0.2-1.1低保守高发散top-k候选数量截断50-100过小容易呆板top-p累计概率截断0.9-0.99过小会丢失多样性repetition penalty重复惩罚1.0-1.2过大会导致输出破碎具体场景上代码生成我一般用temperature 0.2-0.4、top-p 0.9通用对话用temperature 0.7-0.9、top-p 0.95创意写作才敢放到0.9-1.1。这几个参数是组合生效的先改温度再截断最后采样。我见过不少新手只调temperature不调top-p结果生成质量飘忽不定。建议固定一组基准确认再各自微调。提示temperature不是越高越好。超过1.2之后大多数场景下模型只是在随机组织词句并不会变得更“有创意”。4.3 同一个checkpoint两种解码策略体验像两个模型我做过一个很直观的对比用同一个模型、同一个提示词分别用greedy和temperature0.9top-p0.95。我给过一句“夜晚的城市总是让人______”greedy输出直接是“让人想起夜晚的城市总是让人想起夜晚的……”换成temperature0.9、top-p0.95后输出变成“夜晚的城市总是让人想起白天看不见的那层秩序路灯、车流和玻璃幕墙里的灯光各怀心事”。后者明显更像“懂了一些什么”尽管底层参数一模一样。这个对比残酷地说明了一件事我们感知到的“智能程度”有很大一部分根本不在模型上而在推理时怎么用模型。你训出一个底座模型先别急着骂“不够聪明”把解码参数来回扫一遍往往能发现它比你想的能打很多。这也是我在这个系列里坚持给新手强调“先调解码器再下结论”的原因。5. “下一个字”路径的已知边界能涌现什么又缺什么5.1 通过“预测下一个字”拿到手的能力清单到目前为止用“下一个token预测”训练出来的模型已经被验证能做很多事跨语言翻译、摘要、改写、代码补全、常识问答以及部分推理痕迹。这些能力有一个共同特点就是都有大量文本样本可供学习并且都能被简化成“给定上文预测下文”。翻译靠的是平行语料里两种语言的交替出现代码补全靠的是仓库里海量的“上文-下文”结构。预测目标本身并不关心输入是数学题还是闲聊它只关心统计一致性。而统计一致性恰好覆盖了数量惊人的智能行为。5.2 还没有拿到手的东西可靠推理、自我纠错、事实一致性这条路也有清晰的天花板。“预测下一个字”只在文本表面工作它不会直接惩罚“生成一句流畅但错误的话”只要这句话在语言统计上说得通损失就不会升高。幻觉问题有一半的根源就埋在这个目标函数里。同样模型在推理时更倾向于“把话说顺”而不是“把题做对”。你让它算一道数学题它可能给出像模像样的推导步骤但结果就是错的。可靠的推理要求模型在中间步骤里反复验证这不是“预测下一个字”的直接优化目标。自我纠错也是一样除非“发现错-修正”的文本模式大量存在于训练语料里否则模型即使推理跑偏了也完全意识不到。5.3 目标函数不是终点但它是一切后续工作的地基正因为边界清晰现在业界才会在预训练底座上加各种对齐技术比如偏好优化、带验证的奖励函数、推理时计算。这些方法本质上都是在“预测下一个字”得到的底座上加一层额外的挑选和修正机制。底座负责海量语言知识和模式的压缩后续的对齐负责告诉它“在什么场景下更多输出哪种风格”。我的看法是“预测下一个字”不是大模型的终点但它是所有后续工作的地基。你把它理解透再去看微调、对齐、推理优化里的各种反直觉现象会清醒很多。这也是我愿意花一整个连载篇幅来写这个“简单问题”的原因。最后说点个人体会。我训练这类小规模模型的那段时间最深的感受是所谓的“智能感”不是某一个组件单独给的而是数据质量、参数规模、解码策略三者相乘的结果。你单独调结构收益有限你把数据质量提上去loss会有实质性的下降你再把解码参数调对生成体验立刻上一个大台阶。这个世界并不存在“因为目标简单所以做不出智能”的诅咒真正稀缺的是你愿不愿意把“填词游戏”背后的压缩逻辑吃透。如果你也正在从零训练自己的模型建议先别急着追更复杂的目标函数把你手头这个“猜下一个字”的玩法练到极致很多困惑会自己解开。