12k
All articles

LLM 的实际工作原理

LLM如何运作:token、嵌入、Transformer注意力、训练、采样、温度、幻觉,以及ChatGPT为何会出错。

OpenReplay Team
OpenReplay Team
LLM 的实际工作原理

大型语言模型是一种神经网络,其训练目标是预测序列中的下一个 token。它将文本转换为数值向量,通过注意力机制让每个 token 从其他 token 中获取上下文信息,并通过对词汇表的概率分布进行采样,逐个 token 地生成输出。这一单一机制——预测一个 token、将其追加到序列、再预测下一个——正是 ChatGPT、GitHub Copilot、Claude 和 Gemini 背后的核心引擎。其余的一切,不过是规模、训练流程和工程实现上的叠加。

如果你每天都在使用这些工具,却从未深入了解其内部机制,那么你所注意到的那些行为——自信满满却答错的回复、“忘记”对话开头的聊天记录、措辞稍有不同就产生截然不同的输出、无法数清”strawberry”中字母的个数——并非随机的怪癖。每一种现象都直接源于其底层机制。本文将为你建立一个准确的机制认知模型,涵盖以下内容:token 与 embedding、transformer 的注意力层与前馈层、三个训练阶段、文本生成时的实际采样方式,以及对标题中”实际”二字所要纠正的那些常见误解的逐一说明。

核心要点

  • LLM 并非从数据库中检索答案——它在每一步都对整个词汇表重新计算一次概率分布,选取一个 token,然后不断重复,因此你所读到的”推理”是从左到右逐步生成的,而非整体查找得到的。
  • LLM 读取的是子词 token,而非单个字母,这正是为什么拼写和字母计数任务的失败率,往往高于模型整体语言流畅度所应预示的水平。
  • 训练分三个阶段进行:自监督预训练(下一个词即为其自身的标签)、基于人工编写的提示-回复对的指令微调,以及基于人类反馈的强化学习(RLHF)。
  • 默认情况下,LLM 是概率性的,而非确定性的:在温度高于零时,相同的提示可能返回不同的答案,因为模型是从概率分布中采样,而非始终选取概率最高的 token。
  • 幻觉是一个被优化为生成统计上合理文本的系统的默认行为——它被奖励的是”听起来正确”,而非”实际正确”。

LLM 的本质:下一个 token 的预测

从本质上看,大型语言模型反复解决的是同一个具体问题:给定一个 token 序列,下一个 token 是什么?它将这一问题建模为跨越整个词汇表的分类问题——词汇表中可能有数万个 token——并为每个 token 输出一个概率值。模型选取其中一个,将其追加到序列末尾,然后再次运行整个流程。文本生成,就是这个循环不断运行直至满足停止条件的过程。

这一重新理解是关键所在。“写一个对回调函数进行防抖处理的函数”并不是模型去查找答案的指令,而是模型逐个 token 地续写的提示——因为在其训练数据中,形如该提示的序列之后,往往跟随着形如可运行代码的序列。模型本质上是一个续写引擎,以你的输入作为起点。

使这一机制在大规模场景下得以实现的架构,是 transformer,由 Vaswani 等人在 2017 年的论文 Attention Is All You Need 中提出。ChatGPT 中的”GPT”代表 Generative Pre-trained Transformer(生成式预训练 Transformer)。在 transformer 出现之前,模型大致按从左到右的顺序处理文本,难以关联句子中相距较远的词语;而注意力机制让模型能够并行地对每个 token 与其他所有 token 进行权重计算,这正是同时提升模型质量和训练速度的关键突破。

Token 与 Embedding:文本如何转化为数字

在模型处理你的提示之前,它会先将文本拆分为 token——子词块,既不是完整的单词,也不是单个字母——并将每个 token 映射为一个数字。一个 token 可以是一个完整的单词(如 " the")、一个词的片段(如 "ing")、单个字符或标点符号。这一分词步骤在聊天界面中是不可见的,但它解释了一整类失败现象的根源。

由于模型读取的是子词 token 而非单个字母,要求它计算一个单词中的字母数量,本质上是在与其文本表示方式对抗——这正是为什么字母计数和拼写任务的失败率,往往高于模型整体语言流畅度所应预示的水平。模型从未”看到”过”strawberry”中的三个字母 r;它看到的是几个不透明的整数 ID,代表着若干 token 块,字母信息早已在其中消融。

你可以通过 OpenAI 开源的 tiktoken 分词器亲眼观察这一过程:

# pip install tiktoken
import tiktoken

enc = tiktoken.get_encoding("cl100k_base")
ids = enc.encode("strawberry")
print(ids)                       # a short list of integer token IDs
print([enc.decode([i]) for i in ids])  # the sub-word chunks, not letters

运行后,你会得到一组整数 ID,每个 ID 解码为一个多字符的块——而非十个独立的字母。模型就是在这些 ID 上进行运算的。字符计数需要分词过程已经丢弃的信息,因此模型只能进行近似推断,并且经常出错。

每个 token ID 随后被映射为一个 embedding:一个长数字列表(即向量),将该 token 定位在一个高维”词语空间”中。在这个空间里,语义相近的词语聚集在一起——catdogkittenpet 相邻——而这种几何关系编码了语义信息。最经典的示例来自 word2vec(Mikolov 等人,2013 年),该研究表明向量运算能够捕捉词语关系:大致上,biggest − big + small ≈ smallestParis − France + Italy ≈ Rome。这些向量也继承了训练文本中存在的人类偏见,这正是为什么 doctor − man + woman 可能会偏向 nurse。Embedding 是在训练过程中学习得到的,而非手工构建的。

Transformer 内部:注意力层与前馈层

Transformer 是由若干相同层堆叠而成的,每一层依次完成两项工作:注意力步骤(各 token 从其他 token 中汇聚上下文信息)和前馈步骤(模型将其权重中存储的知识应用于每个 token)。前沿模型会堆叠数十个这样的层,在每一层对每个 token 的表示进行进一步精炼。早期层处理语法和歧义等局部结构;后期层则追踪更高层次的语义——谁对谁做了什么,以及段落的主旨。

注意力机制的工作方式类似于一个匹配服务。 对于每个 token,模型会生成一个查询向量(“我在寻找什么?“)和一个键向量(“我能提供什么?”)。它将每个查询与每个键进行比对,在匹配的地方,信息便在这些 token 之间流动。在句子”When John gave the book to Mary, she thanked him”中,注意力机制正是将”she”与”Mary”、“him”与”John”关联起来的机制,以便后续层能够利用这些信息。单个层会并行运行多个这样的注意力操作——称为注意力头(head)——每个头学习追踪不同类型的关系。

前馈步骤是习得事实的存储之处。在注意力机制汇聚了相关上下文之后,前馈网络对每个 token 单独进行处理,根据训练过程中吸收的模式对其进行变换。这里有一个清晰的分工:注意力机制从当前提示中检索信息,而前馈层则提供从训练语料库中学习到的知识。当模型将”The capital of Poland is”续写为”Warsaw”时,这一事实来自前馈权重,而非你提示中的任何内容。

关于注意力机制背后的线性代数和精确方程,原始 transformer 论文是首要参考来源。而这一心智模型——匹配、汇聚上下文、应用存储知识,在多个层中反复进行——已足以用来推断模型的行为。

LLM 的训练方式:预训练、微调与 RLHF

训练分三个阶段进行:自监督预训练(普通文本中的下一个词即为其自身的标签)、基于人工编写的提示-回复对的指令微调,以及基于人类反馈的强化学习(RLHF,用于使模型输出与人类偏好对齐)。每个阶段产出的是不同类型的模型。

阶段输入”标签”的来源产出结果
预训练海量无标注文本(网页、书籍、代码)文本中的下一个词本身——无需人工标注一个流畅的文本续写器,能够续写任意提示,但不遵循指令
指令微调经过筛选的提示-回复对人工编写期望的回复一个能够回答问题、像助手一样遵循指令的模型
RLHF经人工排序的模型输出人类偏好判断训练一个奖励模型输出对齐为有帮助、无害且专注于任务

预训练是自监督的:由于正确的下一个词已经存在于文本中,训练信号是免费的,且实际上是无限的——互联网上的每一个句子都是一个带标注的样本。模型从随机权重出发,初期预测极差,通过在数千亿个样本上调整权重来降低预测误差,逐步改进(这一调整的数学原理是反向传播,在其他文献中有详细记录)。2020 年的缩放定律论文(Kaplan 等人)发现,模型精度随模型规模、训练数据量和算力呈幂律增长——正是这一实证结论,为构建规模越来越大的模型提供了依据。

纯粹经过预训练的模型只是一个续写器。问它”你的名字是什么?“,它可能会续写”你的姓氏是什么?“——因为这是一个合理的续写,而非因为它在故意不配合。指令微调RLHF 解决了这个问题。将原始模型转化为助手的完整流程,在 InstructGPT 论文(Ouyang 等人,2022 年)中有详细阐述,这正是 ChatGPT 的直接前身——ChatGPT 于 2022 年 11 月 30 日作为公开研究预览版发布。目前大多数聊天模型都采用这一流程的某种变体进行训练,但具体方案属于专有信息。

关于数字,有两点需要说明。经常被引用的 GPT-3 参数——1750 亿参数、96 层、12288 维 embedding、50257 个 token 的词汇表——来自 2020 年的 GPT-3 论文,适合作为具体示例参考,而非当前规格。前沿实验室已不再公布其最新模型的参数量:当前 GPT-5 系列、Claude Opus/Sonnet/Haiku 以及 Gemini 3.x 系列均无官方参数数量。任何关于当前模型”X 万亿参数”的说法,都应视为未经证实的传言。

生成机制:采样、温度与概率性输出

当 LLM 生成文本时,它逐个 token 地运行预测循环,并从其计算出的概率分布中采样下一个 token——而非直接输出”答案”。以下是该循环的伪代码:

tokens = tokenize(prompt)
while not done:
    logits = model.forward(tokens)        # one score per vocabulary token
    probs  = softmax(logits / temperature) # convert scores to probabilities
    next_token = sample(probs)             # pick one, weighted by probability
    tokens.append(next_token)
    if next_token == END_OF_TEXT:
        break
output = detokenize(tokens)

temperature 参数控制分数如何转化为概率。默认情况下,LLM 是概率性的,而非确定性的:温度高于零意味着相同的提示可能产生不同的答案,因为模型是从概率分布中采样,而非始终选取概率最高的单个 token。当温度为 0 时,模型变为贪婪模式——始终选取概率最高的 token——这近似于确定性输出,适用于代码生成或信息提取场景。较高的温度会使概率分布趋于平坦,让低概率 token 更有可能被选中,从而使输出更具多样性。temperature 参数在 OpenAI API 参考文档Anthropic Messages API 参考文档中均有说明,两者都支持在每次请求中单独设置。

这正是为什么在 ChatGPT 中重复运行相同的提示可能会得到不同的答案,也是为什么”将温度设为 0”是需要从 API 获取可复现输出时的标准建议。

关于 LLM 的常见误解

关于 LLM 工作原理,有几种直觉性的认知是错误的,而每一种错误认知都会导致开发者误用工具或误判其失败原因。本文标题中的”实际”二字,正是为了纠正这些误解。

误解实际情况
”它从数据库中查找答案。“不存在可供检索的事实存储表。模型在每一步都对整个词汇表重新计算一次概率分布。
“它在写出答案之前就已经知道答案了。“每个 token 都是根据其之前的所有 token 选取的。答案是从左到右逐步构建的,而非整体检索得到的。
“参数以可读文本的形式存储事实。“参数是数值权重。“事实”是分散在数十亿个权重中的统计规律,而非可检索的字符串。
“它是确定性的——相同输入,相同输出。“在温度 > 0 时,模型进行采样,因此相同的提示可能产生不同的续写结果。

它不是数据库查询。 LLM 不会从数据库中查找答案——它没有可供检索的事实存储表;它在每一步都对整个词汇表重新计算一次概率分布,然后选取一个 token 并不断重复。将参数理解为”知识库”是一种误导:权重编码的是统计规律,而非索引记录。

它事先并不知道自己的答案。 模型在写出答案之前并不知道答案是什么:每个 token 都是根据其之前的所有 token 选取的,因此你所看到的”推理”是从左到右逐步生成的,而非整体检索得到的。这正是为什么模型可能在开始一个充满自信的句子之后,将自己”逼入死角”——它并非在读取某个预设的计划,而是在实时计算续写内容。

LLM 为何表现出这些行为

一旦理解了底层机制,这些工具在日常使用中的种种行为便不再神秘。每一种行为都是在习得概率上进行下一个 token 预测的直接结果。

幻觉。 幻觉并非附加在系统上的缺陷——它是一个被优化为生成统计上合理文本的模型的默认行为,这类模型被奖励的是”听起来正确”,而非”实际正确”。当模型对某个事实没有强烈的信号时,它仍然会生成看起来最合理的续写内容,并带有自信的语气——因为自信的文本在其训练数据中占主导地位。一个捏造的函数名或一篇不存在的引用,正是模型在做它被训练去做的事情。

上下文窗口。 上下文窗口是模型一次能够关注的固定 token 数量;任何超出该限制的内容对模型而言根本不可见,这正是为什么长对话最终会”忘记”其开头的原因。截至 2026 年 6 月,当前前沿模型的上下文窗口大致收敛在约一百万 token 左右——Gemini 3.5 Flash 支持 1,048,576 个输入 token,Claude Opus 4.8 默认提供 1M token 的上下文窗口,GPT-5 系列也通过 API 提供 1M token 的上下文窗口。容量虽大,但仍然是固定的:一旦你的对话或代码库超出该限制,最早的 token 便会落在模型的可见范围之外。

提示敏感性、思维链与少样本提示。 提示的确切措辞会改变概率分布,进而改变答案,因为输出是根据前面的 token 逐个 token 计算得出的。同样的特性也解释了为什么各种提示技巧是有效的。少样本提示(展示已解决的示例)通过在上下文中植入你希望模型续写的模式来发挥作用。思维链提示(“逐步思考”)之所以有效,是因为模型自身生成的文本会成为它下一步读取的输入的一部分——中间步骤充当了模型可以在其上继续构建的工作记忆,而不是强迫模型在一次跳跃中直接输出最终答案。

知识接地与 RAG。 检索增强生成(RAG)将相关文档直接放入提示中,使模型能够通过对其面前文本的注意力来提取事实,而非依赖其有损耗的前馈权重。这正是为什么配备了网络搜索或将你的文档纳入上下文的模型,在具体细节上更为准确——你已经将负担从”从训练中回忆该事实”转移到”从提示中读取该事实”,而后者正是该架构更为可靠地完成的任务。

“随机鹦鹉”之问

下一个 token 预测是否构成真正的理解,还是仅仅是复杂的模仿,这是一个悬而未决、争议持续的问题。持怀疑态度的观点在 2021 年的论文 On the Dangers of Stochastic Parrots(Bender、Gebru 等人)中得到了清晰的阐述,该论文认为,一个通过统计概率将训练文本拼接在一起、缺乏意义接地的模型,更像是鹦鹉而非有思维的主体。对立的观点则认为,足够好地预测文本,本身就需要对其所描述的世界建立一个压缩的、可用的模型。本文所阐述的机制是确定的;而这一解释则并非如此——你无需解决这个问题,也能很好地使用这些工具。

你真正需要的,是这一机制模型:token 输入,注意力层与前馈层在多个 transformer 层中对其进行精炼,最终输出一个概率分布,逐个 token 地生成。牢记这幅图景,下次当 Copilot 凭空捏造一个方法,或 ChatGPT 在对话进行到第三轮时自相矛盾,你就能清楚地知道是机器的哪个部分产生了这一结果——同样重要的是,你也会知道哪种提示调整或检索步骤能够解决它。

常见问题解答

LLM 中的 token 与单词有什么区别?

token 是子词块,而非完整的单词。分词器将文本拆分为若干片段,这些片段可以是一个完整的单词、一个词的片段(如 "ing")、单个字符或标点符号,然后将每个片段映射为一个整数 ID。一个常见单词可能对应一个 token,而一个较生僻的单词则可能被拆分为多个 token。模型始终在这些 token ID 上进行运算,而非在原始单词或字母上,这正是为什么字母计数等字符级任务与其文本表示方式相悖。

增大上下文窗口能提升 LLM 的准确性吗?

不能直接提升。更大的上下文窗口只是让模型能够一次关注更多的 token,并不会使模型在推理或记忆方面变得更强。当相关信息距离其被需要的位置较远时,质量仍可能下降;而在提示中放入过多无关文本,也可能稀释有效信号。其好处在于,更少的早期 token 会落在窗口之外,因此模型在处理长对话或长文档时 "遗忘" 的内容会更少。

如果将温度设为 0,LLM 是否总会给出相同的输出?

温度为 0 时,生成变为贪婪模式,始终选取概率最高的 token,对于给定的模型和提示,这近似于确定性输出。但在实际中,由于并行硬件上的浮点数非确定性、模型版本更新以及服务提供商侧的路由等因素,跨 API 调用的精确可复现性并不总能得到保证。温度为 0 是需要代码生成或信息提取场景下一致输出时的正确设置,但应将其视为 "近似确定性",而非严格保证。

为什么检索增强生成能减少幻觉?

RAG 将相关文档直接放入提示中,使模型能够通过对其面前文本的注意力来提取事实,而非依赖其有损耗的前馈权重。该架构从提示中检索信息,远比从训练过程中习得的弥散模式中回忆信息更为可靠。这将任务从 "记住这个事实" 转变为 "读取这个事实",这正是为什么将你的文档或网络搜索结果纳入上下文的模型,在具体细节上能够更准确地作答——尽管它仍然可能误读或误用所提供的内容。

Understand every bug

Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — self-hosted, with full data ownership.

Star on GitHub

We use cookies to improve your experience. By using our site, you accept cookies.