在这篇长文里,我想用最直观、同时不省略关键细节的方式,带你把 ChatGPT 这类大语言模型(LLM)从头到尾拆开看一遍。

当你打开 ChatGPT,在网页输入框里敲下一行字、看着屏幕对面像真人一样流利地吐出回答时,这个被称为“大语言模型”的魔法黑盒里到底装了什么?它为什么有时候像无所不知的博学者,有时候却连 strawberry 里有几个字母 r、或者 9.11 和 9.9 谁更大都能算错?要真正用好这些工具,你不需要自己去写矩阵乘法代码,但你必须建立起一套准确的底层心智模型(Mental Model)。

接下来,我们会完全按照业界打造 ChatGPT 的真实工业流水线,一步步走完它的全生命周期:第一阶段「预训练(Pre-training)」、第二阶段「监督微调(SFT)」 与 第三阶段「强化学习(RL)」。


1. 阶段一:预训练数据——如何把整个互联网洗成 44 TB 的 FineWeb

打造一个大语言模型的第一步,叫做预训练(Pre-training)。在这一步里,我们的目标非常纯粹:收集海量的高质量人类文本,塞进一个庞大的神经网络里。

那么,像 OpenAI、Anthropic 或 Meta 这样的顶级实验室,到底去哪里找这么多文本?答案是:把整个公开互联网抓下来,然后像淘金一样层层过滤。由于商业公司通常把自己的预训练数据集视为核心机密,我们可以直接看开源社区复现的生产级标杆——由 Hugging Face 团队构建并完全公开的 FineWeb 数据集(诸如 Meta 的 Llama 3 等主流模型,在内部构建的都是与它同量级、同结构的语料库)。

从 Common Crawl 27 亿原始网页到 44 TB FineWeb 纯净语料的五步清洗管线

很多人以为“装下整个互联网”需要天文数字般的存储空间,但实际上,经过严苛清洗后的整个 FineWeb 数据集,在硬盘上只占大约 44 TB——你去买几块大容量的机械硬盘就能装下。为什么只有 44 TB?因为原始互联网实在是太脏了。我们可以顺着 FineWeb 的构建管线,看看原始网页在进入神经网络之前经历了哪五道大清洗:

  1. 起点:Common Crawl 原始网页库:几乎所有大模型的数据源头都是 Common Crawl——这是一个从 2007 年开始就在不知疲倦地爬取全网的非营利组织,截至 2024 年已经索引了大约 27 亿个网页。
  2. 第一道筛子:URL 过滤(URL Filtering):爬虫抓回来的网页鱼龙混杂,因此第一步是对照一份巨大的域名黑名单,把包含恶意软件、垃圾营销农场(Spam)、赌博、成人色情、种族主义仇恨言论等低质网站直接整站拉黑。
  3. 第二道筛子:纯文本提取(Text Extraction):你在浏览器里看到的网页,底层其实是一大堆 HTML 代码、CSS 样式表、JavaScript 脚本以及顶栏导航、侧边栏广告。我们需要把这些代码骨架和页面噪音全部剥离,只把每个网页正中央那篇干净的正文段落抽出来。
  4. 第三道筛子:语言过滤(Language Filtering):各家团队会根据产品定位设置语言门槛。比如 FineWeb 使用了一个语言分类器,只保留英文内容占比超过 65% 的网页。顺便说一句,这其实是一个早期设计取舍:如果你在这里把非英语网页大量过滤掉,训练出来的模型在其他语种上的表现自然就会打折扣。
  5. 第四道筛子:去重与个人隐私剔除(Deduplication & PII Removal):进一步删掉全网反复转载的重复网页,并用规则和模型把正文中暴露的个人敏感隐私信息(PII,比如某人的家庭住址、美国社保号 SSN、电话号码等)抹除掉。

走完这五道工序后,留下的纯净文本长什么样?在视频里我直接打开了 Hugging Face 上的 FineWeb 样本查看器:它们就像把全网成千上万篇毫不相干的文章首尾相连拼成的一卷超长文档——前一篇还是 2012 年 3 月美国肯塔基州和印第安纳州遭遇龙卷风袭击的新闻报道,紧接着下一篇就是科普人体肾上腺(大小跟一节 9 伏方块电池差不多)的医学文章。这就是神经网络即将日夜苦读的“教材”。


2. 分词(Tokenization):从 UTF-8 比特流到 100,277 词表的 BPE 压缩

拿到了 44 TB 的纯净文本后,我们还不能直接把英文字母或汉字塞进神经网络。

因为从数学结构上看,现代语言模型(Transformer)要求输入必须是一条一维的离散符号序列(1D Sequence of Symbols),而且这些符号必须来自一个有限且固定大小的词表(Vocabulary)。站在设计者的角度,我们马上会面临一个核心权衡:词表里到底应该有多少个符号?序列应该有多长?

从 UTF-8 原始比特流到 256 字节序列,再通过 BPE 算法合并成 100,277 词表的压缩过程

让我们顺着计算机存储文本的底层逻辑,一步步推演工业界是怎么找到最优解的:

第一层:原始 UTF-8 比特流(词表极小,序列极长)

在电脑内存里,任何文本按 UTF-8 编码展开后,本质上都是一长串由 0 和 1 组成的二进制比特流(Bits)。如果我们直接把 0 和 1 当作神经网络的基本符号,那词表小到了极致(总共只有 2 个符号),但代价是序列长度会爆炸——随便一句话都会变成几千个 0 和 1。而在大模型里,上下文窗口的长度是极其昂贵的稀缺资源,我们绝对不希望把宝贵的窗口浪费在排列组合基础的 0 和 1 上。

第二层:按 8 位打包成字节 Byte(256 个符号,序列缩短 8 倍)

既然每 8 个比特(8 bits)正好组成 1 个字节(1 Byte,取值范围是 0 到 255),我们自然可以把每 8 个比特打包成一个符号。这样一来,我们的词表扩大到了 256 个符号,而同一段文本的序列长度立刻缩短到了原来的 1/8!

第三层:字节对编码算法(BPE, Byte-Pair Encoding)

但对于动辄阅读几十万亿字的前沿大模型来说,256 个符号还是太细碎了。于是整个行业普遍采用了字节对编码算法(Byte-Pair Encoding,简称 BPE),在这 256 个字节的基础上继续做“高频合并压缩”:

  1. 扫描统计最高频的相邻对:算法遍历整个预训练文本,看看哪两个符号最喜欢肩并肩挨在一起出现。比如在英文里,按 UTF-8 / ASCII 编码代表字母 t 的 116 号字节和代表空格的 32 号字节经常紧挨着出现;
  2. 铸造新 Token 并替换:我们就把 (116, 32) 这一对高频组合打包熔铸成一个全新的符号,赋予它新的编号 256,然后把语料里所有的 (116, 32) 全部替换成单个 256 号符号——词表大小加 1,而整条文本序列又缩短了一截!
  3. 循环迭代约 10 万次:把这个“找最高频相邻对 → 合并成新符号”的过程反复迭代十万次,我们就得到了今天主流大模型的词表。例如,OpenAI 在 GPT-4 中使用的分词器,其精确词表大小就是 100,277 个符号。

这些最终被收录进 100,277 词表里的文本小块,就是我们常说的 Token(词元),而执行这套切分转换的程序就叫做 Tokenizer(分词器)。

我们可以直接打开 Tiktokenizer 网站亲手试一试:在输入框里敲入 hello world,你会看到它被切成了 2 个 Token——hello 对应 ID 15339,而带着前导空格的 world 对应 ID 1917。但如果你稍微改一下大小写,或者在中间多敲一个空格,切出来的 Token 数量和 ID 就会彻底改变:

  • hello world → 15339 (hello) + 1917 ( world),共 2 个 Token;
  • Hello World(首字母大写)→ 9906 (Hello) + 4435 ( World),变成了完全不同的 2 个 Token ID;
  • hello world(中间两个空格)→ 15339 (hello) + 220 ( ) + 1917 ( world),变成了 3 个 Token!

经过这道分词工序,刚才那 44 TB 的 FineWeb 原始文本就会被彻底转换成一串长达 15 万亿(15 Trillion)个 Token 的一维整数数组。从这一刻起,神经网络的世界里不再有“字母”或“单词”,只有范围在 0 到 100,276 之间的整数 Token ID。


3. 神经网络内部黑盒:Transformer 调音台、无状态前向传播与随机采样

现在,我们手头有了长达 15 万亿个 Token 的整数序列。接下来怎么拿它训练神经网络?

1. 神经网络的输入与输出:猜下一个 Token 的游戏

在预训练阶段,我们会从这 15 万亿个 Token 里随机截取一段一段的窗口喂给神经网络。这个窗口的长度可以从 0 一直到我们设定的最大上下文长度(Maximum Context Length)——虽然技术上你可以喂无限长的序列,但由于计算开销会随长度剧增,工程上通常会设一个硬上限,比如 4,000、8,000 甚至几万个 Token。

为了直观演示,我们假设现在从某个英文论坛网页上截取了 4 个 Token 作为输入:bar(ID 3703)、view(ID 1689)、in(ID 304)、single(ID 3254)——这是论坛网页顶栏常见的一截半句话(意思是“导航栏 | 在单篇……中查看”)。

  1. 输出 100,277 个概率值:神经网络吃进这 4 个 Token 后,它的唯一任务就是预测紧接着的第 5 个 Token 是什么。因为我们的词表里一共有 100,277 种可能,所以神经网络在最后一层会同时吐出 100,277 个概率数字,分别代表词表里每一个 Token 接在后面的可能性(比如刚开始参数是完全随机的,它猜下一个词是 apple 的概率是 1.9%,是 case 的概率是 2.2%,是 post 的概率是 3.0%)。
  2. 对照正确答案拧旋钮(训练更新):因为在预训练语料里,这 4 个词原本就是从真实网页上截下来的,所以我们手里握着标准答案——在原文里,紧跟在 bar view in single 后面的第 5 个 Token 其实就是 post(ID 3962,连起来就是“在单篇帖子中查看”)!既然知道标准答案是 3962,我们就通过微积分(反向传播)去微调神经网络内部的参数,让它下次再遇到这 4 个词时,给 post 打出的概率变高一点(比如从 3.0% 升到 4.0%),而给其他所有词的概率稍微压低一点。
  3. 海量并行批处理:在实际训练中,这个“看前文 → 猜下一个词 → 对照原文调参数”的过程,会在窗口里的每一个位置上、跨越成千上万个文本批次(Batches)同时并行发生。
Transformer 的无状态前向传播计算与基于输出概率分布抛硬币采样的循环过程

2. 拆开 Transformer 黑盒:几十亿个旋钮的「无状态数学公式」

那个吃进 Token、吐出概率的神经网络内部到底长什么样?

你可以把一个拥有数十亿乃至上万亿参数(Parameters / Weights)的神经网络,想象成一台上面密密麻麻排满了上万亿个旋钮的巨型 DJ 调音台。刚初始化时,所有旋钮都是乱拧的,出来的全是噪音;而整个预训练过程,就是根据那 15 万亿个 Token 的标准答案,把这上万亿个旋钮一点点拧到最恰当的刻度上。

如果你想亲眼看看 Token 是怎么流过这台调音台的,我强烈推荐你打开工程师 Brendan Bycroft 制作的 3D Transformer 交互式可视化网站(bbycroft.net/llm)。网页里完整展示了我写的教学小模型 nano-gpt(包含 85,000 个参数)的内部三维结构:

  • 最顶部的输入 Token 首先被转换成代表语义坐标的数字向量(Embedding 词嵌入);
  • 随后,这些数字一层接一层地向下流经 Transformer 的核心积木块——自注意力层(Self-Attention,负责让一句话里不同位置的词互相核对上下文信息)、多层感知机(MLP,负责对每个词单独做深度特征加工与知识提取) 与 层归一化(LayerNorm,保证数字规模稳定不跑偏),中间全是巨量的矩阵乘法;
  • 穿过几十上百层网络到达最底部时,输出再经过一次归一化(Softmax),正好变成词表里每一个 Token 加起来等于 100% 的最终预测概率。

在这里,我想帮你建立一个至关重要的认知分水岭:人工神经网络里的“神经元”,和我们人类大脑里的生物神经元完全不是一回事。人类大脑里的生物神经元是有复杂内部记忆和动态演化状态的生命体;而 Transformer 神经网络本质上只是一个纯粹无状态的固定数学公式(Stateless Mathematical Expression)——在单次前向传播(Forward Pass)中,顶部塞入一串数字,中间乘过一长串固定的参数矩阵,底部吐出一串概率,算完即焚,模型内部根本不会留下任何动态记忆或持续运转的“思绪”。

3. 推理(Inference):按概率转盘抽签的「互联网混音器」

一旦参数旋钮全部拧好并彻底冻结,我们就进入了日常使用它的阶段——推理(Inference,即生成文本)。

推理的机制极其简单:我们随便给它塞几个起始 Token 作为前缀,模型跑一次前向传播,在底部吐出 100,277 个概率值;接着,我们就像转动一个分成十万格的幸运大转盘(或掷一枚十万面的概率骰子,即随机采样 Stochastic Sampling)一样——哪个词的概率高,它在转盘上占的扇区就宽,被抽中的可能性就大——从中抽中某一个 Token,把它追加到原序列的末尾;然后再把变长后的序列塞回顶部,预测再下一个 Token……如此周而复始。

请注意:因为每一步都在按概率转盘抽签(哪怕某个词概率高达 90%,也有 10% 的可能转到别的词上),所以哪怕你给它一模一样的开头,每次生成的文本走向也会千变万化。比如同样输入前面那 4 个词 bar view in single,尽管原文第 5 个词是 post,但在抽签采样时,模型完全可能抽中另一个高概率词 article(组成“在单篇文章中查看”),从而顺着这个新词拐进一条全新的句子分支。因此,模型一般不会逐字照抄某篇网页,而是顺着它在预训练中学到的统计分布,现场合成出一段受互联网启发但此前从未存在过的“混音作品(Remix)”。

4. 从 GPT-2 到 10 万张 H100 的算力淘金热

为了让你对工业界的训练规模有真切的数字体感,我们可以拿 OpenAI 在 2019 年发布的里程碑模型 GPT-2 做个参照。GPT-2 是历史上第一个长成现代标准形态的 Transformer 语言模型:

  • 参数量(Parameters):16 亿(1.6 Billion);
  • 最大上下文长度:仅 1,024 个 Token;
  • 预训练语料规模:约 1,000 亿(100 Billion)个 Token。

在 2019 年,训练这样一个 GPT-2 大约要花 4 万美元($40,000)。而到了今天,得益于更干净的数据集(如 FineWeb)、飞速迭代的 GPU 硬件以及底层软件优化,我在自己的开源项目 llm.c 中用纯 C 语言和 CUDA 从零复现训练一个同等水平的 GPT-2,只需要 1 天时间、花费约 600 美元(极限优化后甚至已经压到了 100 美元以内)!

在视频里我展示了 llm.c 租用云端算力训练 GPT-2 的实时终端画面:每一个训练步(Step),模型都会在 100 万个 Token 上并行更新参数,单步耗时约 7 秒,总共要跑 32,000 步(累计阅读约 330 亿个 Token)。在长达十几个小时的训练里,研究员坐在屏幕前端着咖啡紧盯的唯一指标,就是左上角不断往下降的 损失值(Loss,衡量预测有多不准,越低越好)。你可以亲眼看到:在第 20 步时,模型吐出来的全是毫无意义的乱码字符;到了几千步,它学会了拼写英文单词和打标点;等到 32,000 步跑完,它已经能流利地续写新闻报道了。

而今天训练最顶尖的旗舰模型,成本早已从几百美元飙升到了数亿乃至数十亿美元。比如我在 Lambda 云平台上租用一台装有 8 张 NVIDIA H100 GPU 的服务器节点(每张卡租金约 $3/小时,整机约 $24/小时),这仅仅是一台机器;在大型 AI 数据中心里,成百上千个这样的机柜被高速光纤连在一起——像马斯克创立的 xAI 就搭建了拥有 10 万张 H100 的巨型超算集群来训练 Grok。这也解释了为什么卖“算力铲子”的英伟达(NVIDIA)股价一飞冲天,市值突破了 3.4 万亿美元。


4. 基座模型(Base Model)的真实面貌:Llama 3.1 405B 现场实测

跑完上面那几个月的预训练,我们就得到了大模型生命周期里的第一个核心产物——基座模型(Base Model)。

从工程角度看,一个训练好的基座模型其实就是硬盘上的两个文件:几百行定义 Transformer 计算逻辑的 Python 代码 + 一个几百 GB 到上 TB 的参数权重文件。OpenAI 从 GPT-2 之后就不再公开这些文件了,但所幸 Meta 等公司依然把训练好的参数开放了出来(Open-weights)。例如 Meta 的 Llama 3.1 405B Base,就是一个拥有 4,050 亿参数、在 15 万亿个 Token 上训练出来的顶级基座模型。

绝大多数普通用户这辈子都没直接碰过基座模型,因为大家平时在网页上用的是经过后训练改造的“聊天助手模型(Instruct / Chat Model)”。为了让你亲眼看看刚从预训练熔炉里搬出来的基座模型到底是什么工作状态,我打开了托管原始模型的 Hyperbolic 平台,把左侧设为 Llama 3.1 405B Base(基座模型),右侧设为 Llama 3.1 405B Instruct(指令微调助手模型),现场做了四组趣味实验:

直接向基座模型提问触发网页续写与机械背诵,以及通过 Few-shot 对话模板在上下文中唤醒助手的对比

实验一:它不是助手,而是一台「昂贵的网页自动补全器」

如果我们在输入框里敲入一个最简单的问题:What is 2+2?(2 加 2 等于几?),右侧的 Instruct 助手模型会乖乖回答 2 + 2 = 4。

但左侧的 Base 基座模型根本不会直接回答你!它看了看 What is 2+2?,顺手就在下面续写出了一整套数学考卷题目,或者开始长篇大论地探讨“为什么人们总喜欢问 2+2 等于几”。原因非常简单:基座模型在预训练中学的唯一本事,就是“接着往下续写互联网文档(Token Simulator)”——在互联网网页上,以一句问号结尾的句子后面,往往跟着更多并列的考题或论坛回帖,而不是客服式的标准解答。

实验二:机械背诵(Regurgitation)与高质量语料的重复采样

虽然我们前面说基座模型通常是按概率分布做“混音创作”,但如果某个段落被它背得滚瓜烂熟,它也会发生一字不差的机械背诵(Regurgitation)。

在现场演示里,我打开英文维基百科的「斑马(Zebra)」词条,把第一句话复制粘贴进 Llama 3.1 405B Base 的输入框里点击生成——结果基座模型像背课文一样,把维基百科斑马词条接下来的好几段原文、甚至连里面的分类学拉丁文都一字不差地默写出来了!这是因为在构建预训练语料时,工程师认为维基百科属于最高质量的权威知识,往往会人为调高它的采样权重,让模型在训练期间把维基百科反复精读了大约 10 轮(在机器学习里每把全量数据通读一遍叫 1 个 Epoch),从而彻底烙印在了参数权重里。

实验三:知识截止期后的「平行宇宙幻觉」

由于 Llama 3.1 的预训练语料截止于 2023 年底,它对 2024 年发生的事一无所知。如果我故意输入一段半截的新闻前缀:In the 2024 US Presidential Election, Donald Trump's running mate was...(在 2024 年美国总统大选中,特朗普的竞选搭档是……),基座模型会怎么续写?

它不会停下来跟你说“对不起,我的知识截止到 2023 年”,而是每次点击重新采样(Resample),都会面不改色地为你随机编造出一个平行宇宙:第一次采样它言之凿凿地写着“特朗普搭档前副总统迈克·彭斯对决希拉里·克林顿”,再点一次又变成了“搭档佛罗里达州州长德桑蒂斯对决乔·拜登”。在基座模型的世界里,根本没有“真假”的概念,只有“什么样的句式接在后面最像一篇通顺的新闻报道”。

实验四:上下文学习(In-Context Learning)与「零权重修改唤醒助手」

尽管基座模型看起来只是个只会顺着往下接话的“文档补全器”,但它内部其实已经蕴藏了惊人的泛化智能,这种能力被称为上下文学习(In-Context Learning):

  • 10 个单词样本现场学会英译韩:我不需要修改模型里的任何一个参数,只需要在输入框里先按固定格式写上 10 行「英文单词: 韩文翻译」作为示范样本(Few-shot Prompt),然后在第 11 行写下 teacher:,基座模型顺着这股格式惯性往下补全出来的下一个词,就是分毫不差的韩语“老师”(선생님)!
  • 用一份假剧本直接在基座模型里“唤醒”聊天助手:既然基座模型最擅长顺着前文格式往下演,那如果我们在输入框开头先写上一段包含 Human:(人类提问)和 Assistant:(乐于助人的 AI 助手回答)的多轮对话剧本,最后留出一句 Human: What is 2+2? \n Assistant: 让它补全呢?奇迹发生了——刚才还拒绝算术的基座模型,瞬间进入角色扮演状态,老老实实地回答起了用户的每一个问题!(不过因为它本质上还是在续写剧本,回答完你的问题后往往刹不住车,还会自己替 Human: 继续往下编造新一轮提问、自己跟自己聊起来——这也正是为什么我们接下来必须进入后训练阶段,用专门的停止符给它立规矩。)

看懂了这个实验,你就彻底摸清了接下来第二阶段「后训练」的底牌:基座模型脑子里早就装满了全世界的知识,后训练要做的,就是通过微调把那种“乐于助人的 Assistant 角色扮演状态”永久固化下来。