大模型炼成记:Token、预训练与 RLHF 对齐

中等 🟡AI 学习
5 个标签
预计阅读时间:19 分钟
大语言模型Token化预训练RLHFScaling Laws

大模型炼成记:Token、预训练与 RLHF 对齐

一个能流畅聊天、写代码、做推理的大模型,是怎么从"一堆参数"变成今天的样子的?很多介绍只会说一句"先预训练再微调",但真正决定模型能力和体验的,恰恰藏在这条流水线的每一个具体环节里:文字是怎么被切碎喂给模型的、"预测下一个词"这个朴素任务为什么能催生出智能、ChatGPT 是怎么从一个只会接话茬的模型变得"听话"的、同一个问题为什么每次回答都不一样、以及为什么大家都在拼命堆参数和数据。本文按照训练流水线的真实顺序,逐一拆解这些技术细节。

🔤 Token:大模型眼中的世界

为什么不直接处理字符

人类阅读文字是一个个汉字、一个个字母地看,但大模型内部既不处理"字符",也不直接处理"单词",而是处理一种介于两者之间的单位——Token(词元)。原因很直接:

如果按字符切分,英文一个句子会被拆成几十个字符,序列长度暴涨,模型要花更多算力才能学到"字符组合成单词"这种浅层规律,效率很低。
如果按单词切分,英文词表要覆盖所有单词、所有变形(如 run/runs/running/ran)、所有新造词和拼写错误,词表会大到不可维护,而且永远会遇到"没见过的词"(OOV,Out-Of-Vocabulary)问题。

Token 化就是在这两个极端之间找一个平衡点:用一个规模适中(几万到几十万)的词表,把文本切成"子词"(subword)单元,常见词整体是一个 token,生僻词或新词被拆成几个小片段的组合。

BPE:从字节对开始"贪心合并"

目前主流大模型(GPT 系列、LLaMA 等)大多使用 BPE(Byte Pair Encoding,字节对编码) 或其变体(如 GPT-4 用的 BPE 改进版、SentencePiece 里的 Unigram)来构建词表。BPE 的训练过程可以理解为一种"贪心合并"算法:

1.先把训练语料里的所有文本拆成最小单元(字节或字符),作为初始词表。
2.统计语料中相邻两个单元同时出现的频率,把出现频率最高的那一对合并成一个新的 token,加入词表。
3.重复第 2 步,每次都合并当前最频繁的相邻对,直到词表达到预设大小(比如 5 万、10 万)为止。

用一个极简的伪代码可以说明这个思路:

\`\`\`text

语料(已按字符切分):

l o w l o w l o w e s t n e w e r w i d e r

第 1 轮:统计相邻字符对频率,(l, o) 和 (o, w) 出现最多 → 合并 "lo" 和 "ow"

第 2 轮:在新序列上再统计一次,"low" 整体出现频率变高 → 合并成 "low"

第 3 轮:继续合并 "er"、"est" 等高频片段

...

最终词表里既有完整单词 "low",也有常见后缀 "est"、"er",

还保留单个字符作为兜底,保证任何字符串都能被切分。

\`\`\`

这样训练出来的分词器有一个很实用的特性:常见词是一个完整 token,生僻词会被拆成几个子词的拼接,比如 "unhappiness" 可能被拆成 "un" + "happi" + "ness",模型依然能通过学过的词根组合理解和生成这个词,而不会因为"没见过整词"就束手无策。

中英文 token 切分的差异

中文和英文在 token 化上的表现差别很大,这也是很多人感觉"中文输入更贵"的直接原因:

英文:单词之间天然有空格分隔,BPE 学到的很多 token 接近"完整单词"或"常见词根",一个英文单词平均约等于 1.3 个 token。
中文:没有空格分隔,且汉字本身信息密度高,分词器往往需要把常见的双字词、三字词合并成一个 token,但覆盖不到的组合就会退化成单字甚至更细的 UTF-8 字节级切分。同样语义信息量的一段话,中文消耗的 token 数通常比英文更多(不同模型的分词器差异较大,粗略经验值是中文字符数与 token 数比例接近 1.5~2 : 1,具体因分词器训练语料而异)。

这也解释了一个常见现象:中文用户写同样意思的一句话,往往会比英文用户"更快用完"上下文窗口和 API 额度。

为什么 API 按 token 计费

大模型的两项核心成本——显存占用计算量——都直接和序列的 token 数挂钩:Transformer 的自注意力计算复杂度与序列长度的平方成正比,输入越长的 token 序列,每一层的计算和显存开销越大;同时 API 厂商的算力成本本质上是"处理了多少个 token、生成了多少个 token",而不是"处理了多少个字"或"多少次请求"。因此按 token 计费(通常输入和输出 token 分开计价,输出更贵,因为生成需要逐 token 自回归解码,成本更高)是最贴近真实算力消耗的计费方式,也是为什么理解 token 化对成本控制很重要——精简 prompt、减少不必要的重复内容,本质上都是在减少 token 消耗。

🌐 预训练:用整个互联网玩文字接龙

"预测下一个词"这一个任务

预训练阶段模型要做的事情说起来极其朴素:给定前面一段文字,预测下一个 token 是什么。这个任务在学术上叫自回归语言建模(Autoregressive Language Modeling),本质上是一种自监督学习——不需要人工标注任何"正确答案",因为语料本身就是答案:一句话的第 N+1 个词,就是训练时的标签。

具体训练过程可以简化理解为:

1.从海量文本中截取一段,比如"今天天气很"。
2.模型基于已经看到的内容,输出一个覆盖整个词表的概率分布,预测下一个 token 最可能是什么(比如"好"的概率最高)。
3.和语料里真实出现的下一个 token(比如确实是"好")计算损失(交叉熵损失),根据误差反向传播更新参数。
4.在数万亿 token 规模的语料上,对每一个位置都重复这个过程。

为什么"文字接龙"能学出语言、常识、甚至推理

这是最反直觉但也是预训练最迷人的地方:只靠"猜下一个词"这么简单的目标,为什么模型能学会语法、常识、甚至一定程度的推理?

原因在于,要把"下一个词"预测得准,模型被迫在内部隐式地建立起远超"词语接龙"的知识结构:

要接对语法,模型必须学会主谓宾搭配、时态、语序等句法规律
要接对常识,比如"太阳从____升起",模型必须在参数里编码"东方"这样的世界知识
要接对逻辑链条,比如一段包含"因为...所以..."的推理文本,模型要接得通顺,就必须隐式学会因果和推理模式
要在代码语料上把下一行代码接对,模型必须学会编程逻辑

换句话说,"预测下一个词"只是一个训练信号(loss 的来源),但要把这个信号优化到极致,模型不得不把语言背后的结构性规律都压缩进自己的参数里。这也是为什么预训练语料的多样性和质量至关重要:网页文本教会常识和语言习惯,书籍教会长程逻辑和叙事结构,代码教会精确的形式化推理,学术论文教会专业知识。

预训练的规模量级

预训练之所以被称为"大力出奇迹"的工程,是因为它同时在三个维度上堆到极限:

数据量:主流大模型的预训练语料通常在数万亿(trillion 级别)token 量级,来源包括网页爬取(如 Common Crawl)、书籍、代码仓库、百科、论坛问答等,且需要经过去重、质量过滤、有害内容清洗等复杂的数据处理流程。
参数量:从早期的百万级参数,到今天主流模型动辄百亿、千亿参数,参数越多,模型能够存储的知识和模式就越丰富。
算力:训练一个千亿参数级别的模型,往往需要数千张高端 GPU/TPU 持续训练数周到数月,消耗的算力以 FLOPs(浮点运算次数)计算,通常在 10^23 ~ 10^25 量级。

这三者不是孤立的,业界发现它们之间存在可以量化的相互制约关系,这一点会在本文最后一节详细展开。

🎓 从 GPT 到 ChatGPT:SFT 与 RLHF 对齐

预训练模型只会"文字接龙"

一个刚做完预训练的模型(业内常称为 base model 或 pretrained model),本质上只学会了一件事:把一段文本自然地续写下去。如果你问它"如何做番茄炒蛋?",它并不理解这是一个需要被"回答"的问题——它更可能把这句话当成一篇作文的标题,接着续写出"这是一道简单又好吃的家常菜,很多人小时候就学过……"这样的文本,而不是直接给出步骤。它甚至可能续写出更多类似的问题,因为在预训练语料里,问题后面经常跟着更多问题(比如 FAQ 列表)。

这就是预训练模型和"能对话的助手"之间的核心差距:预训练模型学到的是"语言的统计规律",但不知道当前场景下用户期待的是什么样的回应格式和态度。要跨越这个差距,需要两个关键步骤:SFT 和 RLHF。

第一步:监督微调 SFT

SFT(Supervised Fine-Tuning,监督微调)的做法是:找人工标注员(或者用更强模型辅助生成后再人工审核)写出大量"问题 - 高质量回答"的示例对,用这些数据继续训练预训练模型,让它学会"看到一个问题(指令),就应该输出一个直接、有帮助的回答"这种格式和行为模式,而不是继续做单纯的文字接龙。

SFT 数据的典型形式是"指令 + 回答",比如:

\`\`\`text

指令:解释一下什么是光合作用,给小学生听。

回答:光合作用就像植物在做饭。植物的叶子里有一种绿色的小工厂,

它们用阳光当"火",用空气里的二氧化碳和从根部吸来的水当"食材",

做出植物自己需要的"食物"(也就是糖),同时还会呼出我们需要的氧气……

\`\`\`

经过 SFT 之后,模型已经初步具备了"听得懂指令、给出对应格式回答"的能力,这也是为什么很多早期开源模型只做完 SFT 就可以拿来对话使用。但 SFT 有一个局限:它只能教会模型"模仿标注员写过的那些回答",无法处理"同一个问题有好答案和坏答案之分,但标注员没写全"的情况,也很难精细地引导模型在语气、安全性、有用性之间做权衡。这就需要下一步 RLHF。

第二步:RLHF——用人类偏好继续调教模型

RLHF(Reinforcement Learning from Human Feedback,基于人类反馈的强化学习)是让模型更"像人"、更懂得权衡的关键一步,完整流程通常分为两个阶段:

阶段一:训练奖励模型(Reward Model)

1.让 SFT 之后的模型对同一个问题生成多个不同的回答(比如 4 个候选)。
2.请人类标注员对这几个回答按质量从好到差排序(而不是直接打分,排序比打分更容易保持一致性)。
3.用这些排序数据训练一个奖励模型:输入"问题 + 一个回答",输出一个标量分数,训练目标是让奖励模型给排序中更靠前的回答打更高的分。

阶段二:用强化学习(通常是 PPO)优化策略模型

1.把 SFT 模型作为初始的"策略模型"(policy)。
2.让策略模型针对新的问题生成回答。
3.把生成的回答交给上一步训练好的奖励模型打分,作为强化学习中的"奖励信号"。
4.PPO(Proximal Policy Optimization,近端策略优化)算法,根据奖励信号调整策略模型的参数,让它更倾向于生成能拿高分的回答。
5.同时会加入一个"和原始 SFT 模型的差异惩罚"(KL 散度约束),防止模型为了骗取高分而生成语言不通顺、脱离常识的"奖励黑客"(reward hacking)内容。

用一句话概括这个循环:奖励模型学会了"人类更喜欢什么",PPO 则让语言模型学会"如何生成人类更喜欢的内容"。这一步之所以关键,是因为人类的偏好(比如"更礼貌一点""不要啰嗦""拒绝危险请求但语气要委婉")很难写成规则或直接的监督样本,但很容易通过"两个回答哪个更好"这种相对比较来表达,而 RLHF 恰恰是把这种"相对偏好"转化成可优化目标的工程方法。经过 RLHF 之后的模型,通常会在有用性、安全性、语气自然度上有明显提升,这也是 ChatGPT 相比早期只做过 SFT 的模型体验更好的核心原因之一。

需要补充的是,近年也出现了 DPO(Direct Preference Optimization)等更简化的对齐方法,跳过了显式训练奖励模型和强化学习采样的过程,直接用偏好数据优化策略模型,工程复杂度更低,但核心思想仍然是"利用人类偏好数据引导模型对齐"。

🎲 温度与采样:AI 为什么每次回答不一样

模型输出的本质是一个概率分布

很多人以为大模型"计算"出一个确定的答案,但实际上,模型在每一步生成时,输出的是词表中每一个 token 成为下一个词的概率。比如给定"今天天气真",模型可能输出:"好"的概率 45%,"不错"的概率 20%,"糟糕"的概率 8%,其余概率分散在词表里的其他几万个 token 上。模型本身并不会自动选择概率最高的那个词作为最终答案——具体怎么从这个概率分布里"抽"出一个词,是由解码策略(decoding strategy)决定的,这也是为什么同一个问题问两次,模型给出的措辞常常不完全一样。

贪心解码 vs 随机采样

贪心解码(Greedy Decoding):每一步都直接选择概率最高的 token。优点是结果完全确定、可复现;缺点是容易陷入重复、生硬、缺乏变化的表达(比如反复生成同一个短语),因为它完全放弃了"次优但也合理"的可能性。
随机采样(Sampling):按照概率分布"抽签",概率越高的 token 被抽中的机会越大,但不是必然。这样生成的文本更自然、更有多样性,是目前对话类产品的主流选择,代价是结果不可完全复现。

Temperature:控制概率分布的"平滑度"

Temperature(温度)是采样前对概率分布做的一步再加工,公式上是把模型输出的原始分数(logits)除以温度值 T,再做 softmax 归一化:

温度较低(如 0.2):相当于把概率分布"变尖",原本领先的高概率 token 会被进一步放大优势,采样结果更接近贪心解码,输出更保守、更确定、更适合需要精确性的任务(如代码生成、数学计算、事实问答)。
温度较高(如 1.2):把概率分布"压平",原本较低概率的 token 也有更大机会被选中,输出更有创造性、更多样,但也更容易出现不连贯或跑题的内容,适合创意写作、头脑风暴一类的场景。
温度为 0:数学上等价于贪心解码,每次都选概率最高的 token,结果完全确定。

Top-k 与 Top-p(nucleus sampling)

单纯调温度还不够,因为即使压平了分布,词表尾部那些几乎不可能合理的 token 依然有极小的非零概率被抽到,可能导致偶尔输出完全不合逻辑的词。因此实践中通常会先用一种"截断策略"缩小候选范围,再做采样:

Top-k 采样:只保留概率最高的 k 个 token(比如 k=40),把候选范围限制在这 k 个之内,再按概率重新归一化后采样。缺点是 k 值是固定的,对于概率分布很集中或很分散的场景不够灵活。
Top-p 采样(nucleus sampling,核采样):不固定候选个数,而是从概率最高的 token 开始累加,直到累计概率达到设定阈值 p(比如 0.9)为止,把这个"核心集合"作为候选范围。这样在分布很确定时(比如只有一两个词概率极高)候选集会自动收窄,在分布很分散时候选集会自动放宽,比 top-k 更自适应,是目前工业界最常用的采样策略之一。

一段简化的采样伪代码可以直观展示这个流程:

\`\`\`python

def sample_next_token(logits, temperature=0.7, top_p=0.9):

# 1. 用温度调整分布的平滑度

scaled_logits = logits / temperature

probs = softmax(scaled_logits)

# 2. 按概率从高到低排序,累加直到超过 top_p 阈值,构成候选集

sorted_probs, sorted_idx = sort_descending(probs)

cumulative = cumsum(sorted_probs)

cutoff = first_index_where(cumulative > top_p)

candidate_idx = sorted_idx[: cutoff + 1]

# 3. 在候选集内重新归一化后随机抽取一个 token

candidate_probs = normalize(probs[candidate_idx])

next_token = random_choice(candidate_idx, weights=candidate_probs)

return next_token

\`\`\`

实际使用中,temperature 和 top-p/top-k 经常组合使用:先用 top-p 圈定一个"合理候选池",再用 temperature 微调池内的抽样倾向性,这也是为什么很多 API 会同时暴露 \`temperature\` 和 \`top_p\` 两个参数给开发者调节。

📈 Scaling Laws 与涌现:大力出奇迹

Scaling Laws:性能和规模的幂律关系

一个足够朴素但影响深远的发现是:大模型的最终性能(用预训练阶段的损失值衡量)与三个规模变量——参数量、数据量、算力——之间存在相当稳定、可预测的幂律关系(power law)。简单说就是:在其他条件不变的情况下,把参数量或数据量扩大若干倍,模型的损失会按照一条可以拟合出来的曲线持续下降,而且这条曲线在很大的规模范围内都成立,没有明显的"提前失效"。

这个发现的意义在于,它把"要不要训一个更大的模型"从一件靠直觉赌一把的事情,变成了一件可以提前用小规模实验外推、预估收益的工程决策——研究者可以先在较小规模上训练一系列模型,观察损失随规模变化的曲线,再推算出"如果把规模扩大到 N 倍,损失大概会降到多少",从而决定资源该往参数、数据还是算力哪个方向倾斜。

Chinchilla:不是参数越大越好,是要按比例来

早期业界的普遍做法是拼命堆参数量,但相对而言训练数据量没有等比例跟上。DeepMind 在 Chinchilla 相关研究中提出了一个重要修正:在给定的算力预算下,很多此前发布的大模型其实是"参数过多、数据量不够"的次优组合——如果把同样的算力预算,改成用一个更小的参数规模但配上多得多的训练数据来训练,反而能达到更低的损失、更好的效果。这一发现推动了后续大模型训练策略的转变:不再单纯追求参数量的"军备竞赛",而是更重视参数量和数据量按照最优比例同步扩大,用有限算力换取更高的性价比。这也是为什么此后很多新发布的模型即便参数量不再一味增大,效果依然能持续提升——因为训练数据量和数据质量在同步跟上。

涌现能力:规模跨过某个阈值后"突然会了"

比 Scaling Laws 更有意思、也更难解释的现象是涌现能力(Emergent Abilities):有一些能力(比如多步算术、复杂的链式推理、遵循复杂指令、某些小样本任务)在模型规模比较小的时候几乎完全不具备,表现和随机瞎猜差不多;但当参数量、算力跨过某个规模阈值之后,这些能力会在相对很窄的规模区间内迅速跳变,从"几乎不会"变成"明显掌握",而不是像整体损失曲线那样平滑连续地提升。

这和整体的 Scaling Laws 曲线(预训练 loss 的下降是平滑的)形成了有意思的对比:宏观的语言建模能力是连续改善的,但很多具体的、离散的下游任务能力却表现出"量变到质变"的跳跃特征。对这一现象的解释在学术界仍有讨论——一种观点认为这是评测指标本身的离散性造成的错觉(如果换成连续的评分方式,很多"涌现"曲线其实也是平滑的),另一种观点则认为确实存在某些任务需要模型同时具备多个子能力才能完成,而这些子能力各自独立地在不同规模跨过门槛,叠加起来就表现为看似突然的跃升。无论哪种解释更准确,涌现现象都提醒我们:仅凭小规模模型的表现,很难可靠地预测大规模模型会不会具备某些复杂能力,这也是大模型研发中"规模是否值得投入"这一判断天然带有不确定性的原因之一。

✅ 小结

把这条流水线串起来看:Token 化解决了"文字如何变成模型能处理的符号"这个基础问题;预训练用"预测下一个词"这一个简单到极致的自监督任务,在海量数据和算力的堆叠下,逼出了语言、常识乃至推理能力;SFT 教会模型"应该以什么格式、什么角度回应用户",RLHF 则用人类偏好数据进一步把模型调教得更有用、更安全、更像人;temperature 与 top-p/top-k 采样策略决定了同一个模型在"确定性"和"多样性"之间如何权衡;而 Scaling Laws 与涌现能力则解释了为什么"堆规模"在大模型这个领域格外有效,也格外难以精确预测。理解这些具体环节,不仅有助于看懂"大模型是怎么来的",也能在实际使用 API、调参数、评估模型能力边界时,做出更有依据的判断。