大模型运行原理面试总结
更新: 8/23/2026 字数: 0 字 时长: 0 分钟
Token和Tokenizer
Token是大模型文字生成/阅读计量的最小单位,这个单位不一定是按字符去分割的,一般来说,一个Token会是一个常见的词组,而这个词组的常见于否则取决于训练数据
这里也直接反应一个曾经的老笑话:“如果我只用文言文是不是可以省Token”
聪明的小伙伴肯定就已经明白了,实际上是不会的,因为文言文在训练数据中占比过小,他很有可能是一个字作为一个Token,而我们常见的白话文存在一个词(2个或以上的字符)作为一个Token
举个例子,我们使用:OpenAI Tokenizer
"时色已晚,宜速归。"这句话9个字符转换成了9个Token,而"时间很晚了,最好早点回来。"同样的意思13个字符也是用了9个Token
特殊的Token
除了正常的输出之外,大模型输出的内容还有特殊的Token,他们的作用主要是为了区分不同的回答内容,比如区分思考内容和正式回复,以便更好的被结构化成JSON
(如果想要体验,可以自行在Ollama上下载一个小模型体验一下)
常见的特殊Token有
| 特殊 Token | 用途 | 示例 |
|---|---|---|
| BOS(Beginning of Sequence) | 标记序列开始 | < s > |
| EOS(End of Sequence) | 标记序列结束 | < /s > |
| PAD(Padding) | 批处理时填充短序列 | < pad > |
| 工具调用标记 | Function Calling 边界 | <tool_call/> |
这些部分都会被转换到我们大模型服务商提供的回复JSON中
多模态大模型的Token
对于多模态大模型,每个公司会有不同的方式将图片转换为Token
- DeepSeek:小于384x384的图片等比放大,大于384×384的图片等比缩小,缩小后的总像素约相当于 800×800 的图片,最大token消耗为384
- Anthropic:按缩放后的图片像素数估算,官方给出的近似公式是
tokens ≈ width × height / 750 - OpenAI:High-Detail动态切片,基础 85 Token + 每个 512×512 切块 170 Token。
上下文容量
大模型标注的128k,200k或1M上下文都是指的一次调用最大容纳的Token上限,这里就设计一个大模型开发的基础知识:对于我们人来说看到的多条对话,其实是一次性全部塞给大模型的,而这个对话大小的上限就是大模型上限
我们的工具调用数据,用户-模型对话,模型推理内容,系统提示词全在这个上下文里面
特别注意的是:上下文窗口!=最大生成长度,一般最大生成长度远小于上下文窗口
上下文溢出与幻觉
当上下文呢过长的时候,我们的模型往往会容易遗忘中间的部分,所以重要的信息一般会放在开头或者结尾
之所以大模型容易忘记中间部分,这和大模型的训练机制——Self-Attention密切相关,头部内容往往放的是System Prompt,所以在训练时给了人为给了很高的权重,而尾部由于紧邻着接下来模型要输出的内容所以自然权重就很高,而中间部分既没有人为扶持,有没有尾部优势,自然就容易被遗忘
输入与输出的Token计费
查看Token价格表,我们会发现输出的Token一般会比输入的Token贵上不少(大多数情况是2~4倍,但只是统计学规律),这是因为输入的Token在GPU中是使用多个核心并行计算的,而输出由于必须逐字进行自回归(即生成第N个字必须依赖第N-1个),所以GPU要把整个模型权重从显存完整读取一遍,这个过程算力被严重浪费
Prefill与Decode
Prefill与Decode其实是相对偏底层的内容了,但是由于直接和输入输出相关所以粗俗的解释一下
- Prefill阶段(输入后的阶段):当用户输入完文字之后,大模型会内部进行将这段文字转换成一个矩阵,然后内部进行一系列复杂的矩阵运算,最后得到一个Logits矩阵,这个矩阵计算的过程中每对词之间的计算是可以并行的(可以类比在进行二维矩阵乘法的过程中,我们每一步其实是互不影响的),所以对硬件的利用率较高
- Decode阶段(输出后的阶段):第1个字生成后,将这个新字作为新的输入送回模型,结合先前的上下文,计算并输出针对第2个字的单行 Logits 向量 (
)。因为每次只能算1个字,属于单向量与矩阵的计算,GPU 绝大部分时间在等显存搬运数据,硬件利用率极低。
Prompt Caching
众所周知,大模型十分甚至九分的贵,为了节省成本,同时也是节省算力,我们引入了Prompt Caching机制
Prompt Caching是基于多轮对话一定拥有相同的前缀这一事实进行的,他会预先缓存这一部分的Prompt计算出的KV矩阵(在Prefill阶段被计算出),当用户打入了相同的Prompt,就省去了计算KV矩阵的时间和算力,进而节约了成本
补充:
- KV矩阵:本质上是一个词-整个Prompt中该词的语义的Map,但由于我们在数学层面没有办法计算文字,所以词和语义都是以矩阵的形式保存
- KV矩阵的作用:在模型的每一层中计算自注意力,在Prefill计算出并写出显存,Decode阶段读出用于计算Logits向量,下一次的Prefill阶段也会用这个矩阵计算Logits矩阵
- Prompt Caching和KV Caching的关系:Prompt Caching基于KV Caching实现,本身是“底层技术”与“上层产品”的关系
由于Prompt Caching的这个特性,他会在固定前缀的任务中获得较大的收益,比如:
- 多轮对话(长的历史Message)
- RAG应用(重复的Chunk)
对于设计Agent我们应该将不变的内容放在对话的最前端,同时监控缓存的Token量来检测命中率进而进一步改善Agent提示词
Logits到Temperature
在Prefill阶段,模型会给所有的候选Token进行一个打分,这里可以立即成完形填空,我在一句话的最后挖了一个空,然后有许多待选词,模型会依次给这些词打分,分数越高这里就越应该出现这个词(这也是为什么我们说Language Model本质上还是一个预测模型,他只是在预测下一个该出现的Token而已)
一般这个过程分为两步,一个是Logits一个是Softmax,Logtis就是具体的打分,Softmax是将分数进行归一化,把所有的得分换算成一个0~100%的概率分布,从而方便在得到概率分布后,模型再通过采样决定输出哪个Token
我们大模型中有一些参数,比如Temperature,Top-p,Top-K,这些参数就是在这个时候选择Token的时候做的影响
- Temperature:调整概率分布的“形状”,越小高分词被选中的概率越大,模型回答越理智稳定,越大模型回答越又创造力,默认为1,取值为0~n,工作原理及其简单,就是将得的分/T
- Top-K:让模型只能在排名前几的词中选择,已逐渐被Top-P淘汰,取值范围是1~n(有的模型可以设置取值0或-1表示无限制)
- Top-P:让模型在总和占比前百分之多少的词中选择,优势在于数量不固定了(比如大于50%的Token可能有一个也可能有10个),取值为0~100%(0~1)
- Penalty系列:对于重复出现的Token的惩罚值,防止一直出现重复句子
停止条件与截断风险
当生成达到MaxTokens时,大模型会直接停止输出,不论话有没有说完,这就导致我们在生成结构化数据(如JSON)时常常出现问题,对于这个问题,我们可以通过检测返回值的finish_reason字段进行排查,如果该字段返回max则说明本次停止是因为到maxTokens了,此时不应该进行JSON.parse(),而应该标记为截断异常并进行重试机制
有时我们会为了让模型在固定的内容输出后结束会设定stop字符串,但这可能会错误导致模型意外结束,因此推荐使用官方支持的Structured Outputs / JSON Schema 模式