文章 · 2024-10-07

大语言模型是如何"思考"的:从分词到推理的全过程揭秘

  1. 输入文本 – 模型接收到原始的文本字符串。
  2. 分词 (Tokenization) – 将文本拆解成一个个 Token(词元) 序列。
  3. 映射 ID – 每个 Token 对应到模型词表中的一个 整数 ID 。
  4. 向量化 (Embedding) – 使用嵌入矩阵将每个 Token ID 转换为高维向量表示 。这一步使得计算机能够用数字"理解"文本语义。
  5. 模型推理 – 模型(例如 Transformer 神经网络)接收这些 Token 向量,经过多层计算,产生对下一 Token 的预测评分(logits)。
  6. Softmax 概率分布 – 将 logits 通过 Softmax 函数转换为每个词的概率分布 。
  7. 采样生成 – 根据设定的解码策略(如贪心、Top-k、Top-p、温度采样等)从概率分布中选出下一个输出 Token。然后将该 Token 添加到输出序列,并重复步骤5-7,直到生成完整答案。

下面我们将沿着这条"思维"流程,逐步揭秘大语言模型如何从分词到推理再到最终的文本生成。

文本分词:从字符串到 Token 序列

为什么要分词? 大语言模型无法直接处理原始文本字符——模型只能理解数字。因此,输入的句子首先必须转换为数字才能送入模型 。这个转换过程的第一步就是分词(Tokenization)。简单来说,分词就是将一串文本切分为一个个较小的单元,这些单元被称为 Token(词元)。每个 Token 通常对应一个词、一段子词,甚至可能是一个字符或符号,具体取决于所使用的分词算法和词汇表。分词的结果,是把文本转化为一个 Token 序列。

如何分词? 为了高效地表示不同语言内容,现代 LLM 常使用子词分词算法,例如 Byte-Pair Encoding (BPE,字节对编码) 或 WordPiece 等。以 BPE 为例,它通过反复合并高频的字符序列来构建词汇表,使模型的词表既不至于过大,又能将常见词或片段作为整体 Token 表示。例如,在英文中,"international" 这样的词可能被拆分为 "inter"、"na"、 "tion"等子词;在中文中,常见的词组(如"机器""学习")也可能作为一个 Token。BPE 分词器会根据训练语料统计常见的字符对,将它们合并为新的 token,不断迭代。这意味着模型的词汇表中既包含完整单词,也包含这些高频子词或字片段。

Token 与 ID: 无论采用哪种分词算法,最后都会得到一系列 Token。每个 Token 再通过查表被映射为一个唯一的整数 ID,方便模型处理 。可以把模型的词汇表想象成一个巨大"字典",里面收录了模型所能识别的所有 Token 及其对应编号。例如,GPT-2 模型的词汇表大小约为 50,257 ;每个 Token(无论是"apple"这样的完整单词,还是"ap"这样的子词,亦或是标点符号等)都对应于 0 到 50256 之间的某个ID。

一个直观示例: 假如我们有一句英文输入 "I have a dream",使用 GPT-2 的 BPE 分词器会将其拆成 Token:["I", " have", " a", " dream"](其中空格也作为 Token 一部分)。再比如中文句子"我有一个梦想",若使用中文分词器,可能得到 Token 序列:["我", "有", "一个", "梦想"](具体取决于词表和算法)。每个 Token 会被查找映射到对应的ID,例如 "I" 可能对应 ID 40," dream" 对应 ID 14324 等等(这里仅做示意)。分词的关键在于:模型只能接收固定词汇表内的 Token,如果输入中出现了不在词表的字串(比如生僻词),分词器会进一步把它拆成更小的已知片段或使用特殊的未知标记来处理。

经过分词和ID映射,我们就把文本成功地转换成了一串数字序列。接下来,需要将这些离散的数字进一步转换为计算方便的向量形式,这就是 Token 向量化。

Token 向量化:让计算机"理解"自然语言

得到 Token 的 ID 序列后,模型并不会直接拿这些 ID 数字进行计算。原因很简单:直接使用 ID(例如 14324 这样的数字)并没有任何语义上的意义——ID 之间的大小关系并不反映词语含义的关系。模型需要的是一种能够体现语义信息的表示方式。因此,LLM 的第一层通常是一个嵌入层(Embedding Layer),用于将每个 Token ID 映射为一个稠密的向量。这个过程我们称为 Token 向量化(Token Embedding)。

什么是嵌入向量? 简而言之,嵌入向量是用来表示词元的高维向量(通常数百维)。与简单的"单热(one-hot)"编码不同,Embedding 向量的每个维度都是连续值。这些向量是模型训练过程中学出来的,使得在向量空间中,语义相似的 Token 会有相似的向量表示 。换句话说,Embedding 把离散的符号(单词或字)映射到一个连续空间,使得模型可以通过数学运算来"理解"它们之间的关系 。例如,在一个训练良好的嵌入空间中,表示"国王"和"王后"的两个向量可能彼此接近,并且"国王-男人+女人"≈"王后"这样的关系可以通过向量运算近似体现出来,这正是嵌入向量捕捉语义的威力。

向量化的过程: 可以将嵌入层看作一个查表操作:它维护了一个形状为 $(|V|, d)$ 的矩阵 $E$,其中 $|V|$是词汇表大小,$d$是嵌入维度(如 512, 768 或更高)。当一个 Token 的ID为 $i$ 时,嵌入层输出的就是矩阵 $E$ 的第 $i$ 行向量 $E[i]$ 。比如,前述 "I have a dream" 的 Token 序列会被转换为一组向量 $[\mathbf{e}{I}, \mathbf{e}{have}, \mathbf{e}{a}, \mathbf{e}{dream}]$。这些向量往往是浮点数值,比如 [0.12, -0.45, ...] 这样的形式,高维空间中每个向量可能无法直接直观理解,但模型可以利用它们进行后续计算。

经过嵌入层的处理,原本的文本已经变成了一个个可以被模型"消化"的向量。正如 Hugging Face 的博文所述:这些嵌入向量序列才是神经网络真正的输入。有了它们,模型接下来就能在连续向量空间中对文本含义进行复杂的推理计算。这一步让计算机以数学形式"理解"了自然语言,为后续的推理奠定了基础。

模型推理:上下文理解与下一个词预测

当我们得到 Token 的向量序列后,这些向量将被送入大语言模型内部进行推理计算。当前主流的 LLM(如 GPT 系列、BERT 等)采用的都是 Transformer 架构。Transformer 由多层**自注意力机制(self-attention)**和前馈神经网络组成,它能够高效地建模序列数据的长程依赖。虽然本篇焦点不在 Transformer 细节,但了解其作用有助于理解模型如何"思考":

经过 Transformer 多层计算后,模型最终在输出层得到对于下一个 Token的预测结果。具体来说,模型不会直接输出一个词或句子,而是输出一个对词汇表中每一个 Token 的评分,即通常所说的 logits 。可以将 logits 理解为"未归一化的分数":分数高的 Token 更有可能是模型认为的下一个词,分数低的可能性则小。

举例来说,如果我们让模型接着输出 "I have a dream" 之后的内容,模型最后一层可能计算出像 "of"、","、"..." 等数万个 Token 各自的分数。假设其中 Token "of" 的得分很高。此时模型实际上已经完成了"下一词预测"的主要工作,但这些 logits 还需要转换成概率形式才能用于最终输出决策。**注意:**这种按词给出分数的过程会在每一步重复,每生成一个 Token 后,新 Token 会被加到输入中继续用于下一个 Token 的预测 。这就是自回归语言模型生成文本的基本方式:一步步预测下一个词的概率分布 。

概率分布与采样:模型如何选择下一个 Token

Softmax 转换概率: 模型得到每个 Token 的分数(logit)后,需要将其变为直观的概率。这是通过Softmax 函数实现的。Softmax 会考虑所有词的分数,将其指数化并归一化,得到一个概率分布,使所有可能 Token 的概率之和为 1 。Softmax公式一般表示为:

$$ P(w_i) = \frac{\exp(\text{logit}i)}{\sum{j}\exp(\text{logit}_j)} $$

其中 $P(w_i)$ 就是模型认为 Token $w_i$ 作为下一个词的概率。例如,上述 "I have a dream" 的案例,如果 Softmax 计算得到 Token "of" 的概率为 17%,我们可记作:$P(\text{"of"} \mid \text{"I have a dream"}) = 0.17$ 。概率越高的 Token,自然是模型认为越符合上下文的续接词汇。

贪心还是随机? 有了下一词的概率分布,直觉上,我们可以选择其中概率最高的 Token 作为输出(这被称为贪心搜索或 Greedy Decoding)。贪心策略每一步都选择最可能的词,优点是简单直接,且如果我们设置每次都选最高概率,那么相同输入每次都会得到相同输出(即完全确定性的输出) 。乍一听这很好,但贪心策略往往会导致模型输出千篇一律甚至死板重复的内容 。试想如果一个人说话永远只选最可能的词,而不考虑变化,听起来会非常单调。同样地,大语言模型若总是选择概率最高的词,生成的文本可能缺乏变化,甚至陷入重复循环 。因此,在生成长文本时,我们通常希望引入适当的随机性,以获得更加多样和自然的结果。

引入随机性的采样策略: 为了让模型的输出更灵活多样,业界发展出多种采样(sampling)策略,在保证文本连贯的同时引入随机选择。主要策略包括 Temperature 温度系数、Top-k 采样和Top-p(核)采样等 。它们的核心思想都是:不每次都死板地选最大概率那个词,而是给概率排名靠前的几个候选词一个被选中的机会 。下面分别简要解释这些策略:

需要注意的是,以上策略可以结合使用。例如我们经常会同时设置一个较高的 $p$(如 0.9)和一个适中的 $k$(如 50),模型会先选出Top-k,再在其中应用Top-p限制,从而"双重过滤"。调节这些参数可以在文本质量和多样性之间取得平衡——过低的温度或 p 值会让输出非常确定但可能乏味,过高又可能让模型输出无关甚至荒谬的内容 。

同一输入为何输出不同? 基于以上采样机制,我们可以理解:如果引入了随机采样,每次生成时在高概率候选中可能抽到不同的词,因此即使提示完全相同,模型生成的回应也可能不同 。这并不意味着模型"不可靠",而是生成式任务的正常现象——LLM 本质上生成的是概率驱动的一个合理答案,而非唯一确定的答案。只有在采用完全贪心且设置温度为0等极端确定性配置时,相同输入才会始终得到相同输出。事实上,ChatGPT 等对话系统之所以每次对同一问题可能给出略有差异的回答,就是因为其背后设置了温度采样等机制以保证对话不至于每次一模一样。这种随机性来源于模型推理阶段的采样策略,而并非模型在"记不住"之前的回答。

小示例: 假设模型当前的上下文是 "今天的天气",它预测下一个词可能是:"很好"(概率40%)、"不好"(概率30%)、"一般"(概率25%)、其他词(合计5%)。如果采取贪心策略,模型将选择概率最高的"很好",输出句子可能是"今天的天气很好"。但如果使用采样策略,模型有一定几率选择"不好"或"一般",从而可能输出"今天的天气不好"或者"今天的天气一般"。由此产生了不同的句子走向。这样的随机采样使得模型的输出更加丰富,不会千篇一律。当然,如果我们希望确保回答一致,可以将温度调低或固定随机种子来获得可重复的结果。

工程实践角度的说明

了解了上述原理后,我们来看在工程实践中如何应用这些知识。通常,我们会使用现有的深度学习框架和模型库(如 Hugging Face Transformers)来处理 Token 化和文本生成。这些库已经封装好了大部分细节,让我们可以方便地调用:

from transformers import AutoTokenizer  
tokenizer = AutoTokenizer.from_pretrained("gpt2")  
ids = tokenizer("I have a dream", return_tensors='pt').input_ids  

这样就得到了对应的 Token ID 序列。实际应用中要确保使用与模型训练时相同的分词器和词表。

from transformers import AutoModelForCausalLM  
model = AutoModelForCausalLM.from_pretrained("gpt2")  
output = model.generate(input_ids=ids, max_new_tokens=50, temperature=0.8, top_p=0.9)  

这里 generate 方法内部会处理模型的前向计算、Softmax 和采样策略等步骤。我们只需通过参数 temperature、top_p、top_k 等控制采样策略。例如,上述代码设置了温度0.8和 Top-p 0.9 来生成文本。如果将 temperature=0 和 top_p=1.0(或 do_sample=False)则会采用贪心方式生成确定性输出。

result_text = tokenizer.decode(output[0], skip_special_tokens=True)  
print(result_text)  

得到模型最终生成的自然语言句子。

工程实践中还有一些值得注意的点:比如最大长度和结束标记的设置,以避免模型无限输出;截断或填充以适应模型的上下文窗口大小等等。这些超参数的选择可以显著影响模型性能和生成效果。实践时,常需要调参来找到较佳的输出质量与多样性平衡 。

结语

通过以上步骤解析,我们揭开了大语言模型从分词到向量化再到推理生成的完整过程。简而言之,LLM 的"思考"过程其实是:将输入转换成数字表示,在庞大的神经网络中基于训练所得的知识计算出下一词的概率分布,然后按照一定策略抽取输出,从而逐步生成文本答复。

这种生成机制使得模型能够产出连贯且富有语义的语言,但也决定了它本质上是一个概率模型。我们驳斥了"相同输入必定得到相同输出"的误解,理解了随机采样在生成中的作用。同时,我们也强调了嵌入向量对于模型"理解"语言的重要意义:没有恰当的向量表示,计算机无法以数学方式处理人类的语言信号。

对于开发者而言,理解这些原理有助于更好地调优模型行为。例如,知道如何调整 temperature 可以控制回答的随机性,了解分词机制可以避免不必要的长度增长或意外的 Token 切分。正如 Hugging Face 博客所言,大语言模型的神奇表现背后有着确定的逻辑流程和数学基础,我们可以既仰赖它强大的预训练知识,又通过工程手段精细地掌控它的输出。

大语言模型的发展仍在继续,从改进分词方法到更先进的采样策略,都有大量研究涌现。希望这篇文章为您提供了一个清晰的全景视角,帮助技术从业者更深入地理解 LLM 的工作原理,也为实际应用和调优提供一些指导。在未来,我们有理由相信,随着对这些机制理解的加深,我们将能构造出更高效、更智能的语言模型。

© 2026 Yuxu Ge ·