☰
大语言模型工作原理:从 Token 预测到多轮对话的系统性解析
2026/10/22 2:09:38 网站建设 项目流程

目录

1. 核心机制:自回归下一个 Token 预测

2. Token:模型理解文本的最小单位

2.1 Token 是什么

2.2 Token 的常见形态

2.3 为什么需要 Token

2.4 解决“词汇爆炸”问题

2.5 词表(Vocabulary)

2.6 Byte-fallback:零 UNK 的幕后功臣

3. 如何选出下一个 Token:从 Logits 到采样

3.1 采样策略

3.2 终止符

4. 推理工程:Prefill、Decode 与 KV Cache

4.1 输入 Token 和输出 Token

4.2 致命伤一:算力闲置

4.3 致命伤二:显存带宽被榨干

4.4 致命伤三:KV Cache 占用显存

4.5 工程优化

5. 多轮对话:无状态模型如何“记住”上下文

5.1 LLM 本质是无状态的

5.2 多轮对话靠应用层维护

5.3 为什么需要多轮对话

5.4 核心瓶颈:上下文窗口

6. 多轮对话的优化:摘要、滑动窗口、RAG 与剪枝

6.1 对话摘要

6.2 滑动窗口

6.3 RAG:检索增强生成

6.4 KV Cache 与提示词缓存

6.5 上下文剪枝

6.6 工程建议


大语言模型(LLM)看起来能对话、能推理、能写代码,但底层生成机制极其简单:给定前文,预测下一个 Token。完整回答并不是一次性写出来的,而是“逐字预测、文字接龙”地自回归生成。

本文从五个层面展开:

  1. LLM 的核心生成机制:自回归下一个 Token 预测;

  2. Token、Tokenizer 与词表:文本如何变成数字;

  3. 如何选出下一个 Token:Logits、Softmax 与采样策略;

  4. 推理工程:Prefill、Decode、KV Cache 与输出 Token 为什么贵;

  5. 多轮对话:无状态模型如何“记住”上下文,P(x1​,x2​,…,xT​)=t=1∏T​P(xt​∣x<t​)以及摘要、滑动窗口、RAG、剪枝等优化方案。

  • 这个过程叫自回归生成(Autoregressive Generation)。

  • DeepSeek 默认终止符是<|end▁of▁sentence|>,不同模型终止符不同。

1. 核心机制:自回归下一个 Token 预测

LLM 本质上是一个条件概率模型:

其中:

  • 模型输出的是词表中所有 Token 的概率分布;

  • 通过采样策略选出一个 Token,拼接到前文后面,继续预测下一个。

这就是自回归生成(Autoregressive Generation):

用自己刚刚生成的结果,作为预测下一个结果的依据,像滚雪球一样,一步一步往外推。

伪代码可以写成:

context = tokenizer.encode(prompt) while True: logits = model(context) # 计算词表中每个 token 的分数 probs = softmax(logits / temperature) # 转成概率分布 next_token = sample(probs, top_k, top_p) # 采样 if next_token == eos_token: break context.append(next_token) return tokenizer.decode(context)

举个例子:

用户输入:

中国的首都是哪里?

模型可能依次生成:

中国 → 的 → 首都 → 是 → 北京 → 。

当然,实际切分不一定按词,而是按 Token。每次生成一个 Token 后,模型会把它拼回上下文,再预测下一个,直到遇到终止符。

不同模型的终止符不同。例如 DeepSeek 默认终止符是:

<|end▁of▁sentence|>

2. Token:模型理解文本的最小单位

2.1 Token 是什么

Token(词元)是 LLM 理解和处理文本的最小基本单位。

人类阅读时,大脑会自动断句:

我爱大模型开发
我 / 爱 / 大模型 / 开发

LLM 也需要把文本切分成一个个 Token,这个过程叫分词(Tokenization)。

不同的人断句方式不同,不同模型厂商的切词方式也不同。同一句话,在不同 Tokenizer 下可能切出不同的 Token。

2.2 Token 的常见形态

类型示例说明
完整单词Hello可能是 1 个 Token
子词un + believe + able一个单词拆成多个 Token
标点,.!通常各占 1 个 Token
中文我、爱、大模型一个汉字通常 1 到 2 个 Token,视词频而定

LLM 不看完整句子,而是把句子拆成 Token 来“理解”和“生成”。

2.3 为什么需要 Token

计算机只能处理数字和数学运算,无法直接理解文本。Token 是连接“人类语言”和“模型数字世界”的桥梁。

第一步:切分编号。

unhappiness → ["un", "happi", "ness"] → [432, 891, 256]

此时计算机拿到的是纯数字[432, 891, 256]。但注意:数字 891 并不比 432 “更大”或“更开心”,它只是索引。

第二步:把离散 ID 映射成高维向量。

"happy" → [0.8, 0.9, -0.1, ...] "glad" → [0.79, 0.88, -0.09, ...]

语义越近,向量在空间中距离越近。un的向量带有“否定”方向,与happy组合后,会把语义推向sad附近。

2.4 解决“词汇爆炸”问题

如果按字母为单位:

  • 词表很小,但粒度太细;

  • unhappiness会被拆成 11 个字符;

  • 每个字符几乎没有独立语义;

  • 序列变长,计算量按平方增长,效率极低。

如果按单词为单位:

  • 词表会爆炸;

  • 英语有几十万单词,还有大量派生词;

  • 遇到新造词如cryptocurrency,模型只能当成未知。

主流方案是子词分词,如 BPE、WordPiece、Unigram、SentencePiece,把文本切分成介于字和词之间的子词单元。

2.5 词表(Vocabulary)

词表是模型预定义的映射字典,包含模型“认识”的所有 Token。

IDToken
0!
1#
......

词表定义模型能“看见”和“写出”的所有基本单位。模型输出 ID,再通过词表映射回文本。

常见词表大小:

  • GPT-2:50,257;

  • Llama 2:32,000;

  • Llama 3:128,256。

模型不能生成词表外的 Token ID。例如词表大小是 50,257,它永远不可能输出编号 50,258 的 Token。

但模型可以组合词表内的 Token,拼出词表里没有的“词”。例如:

un + believe + able → unbelievable

如果遇到词表无法表示的字符,比如某些 Emoji,就会触发字节级回退(Byte-fallback)。

2.6 Byte-fallback:零 UNK 的幕后功臣

以 😊 为例,其 UTF-8 编码是 4 个字节:

text

0xF0 0x9F 0x98 0x8A

传统 Tokenizer 如果词表里没有 😊,会抛出[UNK],模型完全不知道它代表什么。

Byte-fallback 会把 4 个字节拆开,映射到词表里的专用字节 Token:

<byte_0xF0> <byte_0x9F> <byte_0x98> <byte_0x8A>

这样模型不会报错,也不会丢弃字符。正常高频词仍然用大 Token 保证效率,极端情况下降级到字节模式保证鲁棒性。

3. 如何选出下一个 Token:从 Logits 到采样

LLM 决定下一个 Token 的核心流程是:

  1. 基于前文上下文,计算词表中所有 Token 的分数(Logits);

  2. 通过 Softmax 转成概率分布;

  3. 通过采样策略选出一个 Token;

  4. 拼接到上下文,循环往复。

这就是自回归生成。

3.1 采样策略

策略说明特点
贪婪搜索每次选概率最大的 Token确定性强,但容易重复、呆板
Beam Search保留多个候选序列适合翻译等任务,开放生成中多样性差
温度采样用温度 TT 调整分布平滑度TT 低更确定,TT 高更随机
Top-k只保留概率最高的 k 个 Token过滤长尾
Top-p保留累积概率达到 p 的最小集合又称 Nucleus Sampling
重复惩罚降低已出现 Token 的概率减少复读

3.2 终止符

模型生成到终止符时停止。常见终止符:

<|endoftext|> <|eot_id|> <|end▁of▁sentence|>

不同模型终止符不同,工程上需要正确配置。

4. 推理工程:Prefill、Decode 与 KV Cache

4.1 输入 Token 和输出 Token

类型内容计费
输入 Token用户提示词、系统提示、联网搜索结果、历史对话按输入 token 计价
输出 Token模型生成的完整回复按输出 token 计价

为什么输出 Token 更贵?核心有三个原因。

4.2 致命伤一:算力闲置

输入阶段叫Prefill:

  • 把 1000 个 Token 打包成一个大矩阵;

  • GPU 的 Tensor Core 可以满载并行计算;

  • 算得多,但 0.1 秒就干完了;

  • 占用硬件时间极短。

输出阶段叫Decode:

  • 每次只算 1 个 Token 的 Q;

  • 但为了算这 1 个 Q,要把缓存里的 1000 个 K 搬出来做点积;

  • GPU 计算单元大量时间在等数据搬运;

  • 生成 1000 个输出 Token 需要串行跑 1000 步;

  • 总耗时可能是输入阶段的 10 倍以上。

类比:

  • 输入像满载货车走高速:费油但跑得快;

  • 输出像市区堵车走走停停:不费油但耗时极长。

4.3 致命伤二:显存带宽被榨干

输出阶段瓶颈从“计算速度”变成“显存搬运速度”,即Memory Bound。

阶段瓶颈硬件资源
输入 Prefill计算密集算力
输出 Decode内存带宽密集HBM 带宽

为了算一个新 Token,要把缓存里几千个 K、V 向量从显存搬到缓存。显存带宽是 GPU 最稀缺、最贵的资源之一。例如 H100 带宽 3.35TB/s,输出阶段疯狂搬运数据,带宽容易打满。

4.4 致命伤三:KV Cache 占用显存

Transformer 解码时,自注意力需要 K 和 V。每生成一个新 Token,就要把该 Token 的 K、V 追加进显存,直到对话结束。

生成第 1 个 Token:缓存 1 份 K/V 生成第 2 个 Token:缓存 2 份 K/V ... 生成 1000 个 Token:缓存 1000 份 K/V

对于云厂商,显存就是钱。一块 A100 只有 80GB 显存,如果一个用户生成超长文本占了 40GB,这张卡能同时服务的用户数就急剧减少。

4.5 工程优化

  • KV Cache:缓存历史 K/V,避免重复计算;

  • MQA / GQA:减少 KV 头数,降低 KV Cache 大小;

  • PagedAttention:像操作系统虚拟内存一样分页管理 KV Cache,减少碎片;

  • Continuous Batching:连续批处理不同请求的 Decode 阶段,提高吞吐;

  • KV Cache 量化:用低精度存储 K/V,降低显存占用;

  • 投机采样:用小模型草拟多个 Token,大模型并行验证,加速 Decode。

5. 多轮对话:无状态模型如何“记住”上下文

5.1 LLM 本质是无状态的

LLM 本身是无状态(Stateless)的。处理每条指令时,默认不知道你之前说过什么。

你问 DeepSeek:

我叫小明,我今年 6 岁了,你叫什么?

它回复后,你打开一个新会话,它并不知道你是谁。因为大模型没有记忆,只是在做概率预测。

5.2 多轮对话靠应用层维护

所谓“多轮对话”,其实是应用层把历史对话记录连同当前新问题一起,重新打包发送给模型。

messages = [ {"role": "system", "content": "你是一个助手。"}, {"role": "user", "content": "我叫小明,我今年6岁了,你叫什么?"}, {"role": "assistant", "content": "你好小明,我是AI助手。"}, {"role": "user", "content": "我叫什么,我明年几岁了?"} ]

模型看到完整 messages 后,就能回答:

你叫小明,明年 7 岁了。

这种能力就是多轮对话带来的。

5.3 为什么需要多轮对话

  1. 上下文依赖
    代词“它”“那个”需要前文才能理解。

  2. 复杂问题逐步澄清
    用户往往不会一次提供全部信息,而是多轮互动逐步完善需求。

  3. 纠错与对齐
    模型第一轮可能出错,多轮对话给用户“指正”的机会。

5.4 核心瓶颈:上下文窗口

大模型的“记忆”完全依赖输入文本,即上下文窗口。这个窗口有固定长度上限,例如 32K tokens。一旦对话历史超出限制,最早的信息就会被遗忘或截断。

用户:我对花生过敏,以后推荐食物时请避开花生。 助手:明白了,我会记住您对花生过敏。 ... 多轮之后 ... 用户:有没有适合下午茶的蛋糕配方? 助手:推荐花生酱玛芬蛋糕:低筋面粉、花生酱、鸡蛋、牛奶、糖、泡打粉。 用户:???我一开始就说了我对花生过敏!

这就是上下文窗口溢出导致关键信息丢失。

6. 多轮对话的优化:摘要、滑动窗口、RAG 与剪枝

6.1 对话摘要

超过长度后,让模型把旧对话压缩成简短摘要。

摘要:用户对花生过敏。用户是烘焙新手,已尝试白面包,烤箱为30升。 用户询问过戚风蛋糕塌陷的原因,正在寻找简单的下午茶蛋糕配方(不能含花生)。

后续对话带上摘要,而不是全量历史。

优点:节省 Token。
缺点:可能丢失细节,需要保留关键实体。

6.2 滑动窗口

只保留最近 N 轮对话,超过就移除最早的消息。

优点:实现简单。
缺点:可能丢失早期关键信息,比如“花生过敏”。

6.3 RAG:检索增强生成

把历史对话或外部知识存入向量数据库,按需检索相关片段,而非全量输入。

流程:

当前消息 → 检索器 → 向量库 → 相关片段 → 拼接当前消息 → 模型生成

常用向量数据库:FAISS、Milvus、Chroma、Weaviate。

优点:可以保留长期关键信息。
缺点:检索质量依赖 Embedding 和召回策略。

6.4 KV Cache 与提示词缓存

KV Cache 缓存已计算的历史 K/V,每轮只算新内容。

["今", "天", "天", "气"] 生成“真”:缓存前 4 个 token 的计算信息。 生成“不”:取出之前 5 个结果,和新算的拼接。 生成“错”:取出之前 6 个结果,和新算的拼接。

几乎所有生产级服务都会用 KV Cache 或提示词缓存(Prompt Caching)来降低延迟和成本。

6.5 上下文剪枝

移除历史中对当前生成无用的 Token。

剪枝前:

[1] 小明:帮我推荐几本好看的科幻小说,要短篇的。 [2] AI:《你一生的故事》《呼吸》《献给阿尔吉侬的花束》都不错。 [3] 小明:谢谢!对了,你吃午饭了吗? [4] AI:我不吃饭,不过你可以去食堂看看。 [5] 小明:好吧。我现在要写物理作业,是关于“动量守恒”的。 ...

剪枝后:

[5] 小明:我现在要写物理作业,是关于“动量守恒”的。 [6] AI:动量守恒的关键是系统不受外力或合外力为零。你有具体题目吗? ...

优点:减少 Token。
缺点:可能剪掉后续需要的信息,需谨慎。

6.6 工程建议

设计多轮对话系统时,可以按 Token 预算分配上下文:

模块建议
系统提示固定关键约束,如“用户对花生过敏”
历史摘要压缩旧对话,保留实体和意图
检索片段RAG 召回相关历史或知识
最近历史保留最近 3-5 轮,保证连贯
当前问题必须完整保留

触发策略:

  • 当历史 Token 超过阈值时,自动生成摘要;

  • 关键信息置顶到系统提示;

  • 使用 KV Cache / Prompt Caching 降低重复计算;

  • 对长对话使用 RAG,而不是全量拼接。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询