首页 / 文章

LLM端到端推理:预填充、解码、KV缓存与采样机制

通过流式处理对分词器的全面解析——为何预填充受计算能力限制、解码受带宽限制,以及GQA、分页和推测机制如何改变相关成本结构。

发布者:REACTAPP.TOP阅读约 40 分钟9213 词

来源: How LLMs Actually Generate Text: The Full Inference Pipeline, Explained Question by Question

从按键到流式标记

本指南将完整展示推理流程——分词器、嵌入模型、注意力机制、KV缓存、采样以及推测性解码——并解答每个阶段的关键问题。其目的是形成便于理解的思维模型,而非供应商的宣传材料。

第一部分——两种工作负载,而非一种

问题1:按下回车键与出现第一个单词之间发生了什么?

真实的端到端流程如下:

  1. 输入。 诸如 "什么是重力?" 这样的UTF-8字符串会被传入。服务框架通常会将其封装在聊天模板中,为系统、用户和助手的发言设置专用标记。
  2. 分词。 文本会被拆分成子词单元,并映射为整数ID。这一步仅涉及字符串处理,尚未使用神经网络。
  • 嵌入查找。每个ID从嵌入矩阵E ∈ ℝ^(V × d_model)中选取一行,生成一个(seq_len, d_model)形状的张量。位置信号在此处或注意力机制内部(RoPE)之后被添加。
  • 预填充。每个提示词标记会**同时**经过所有N个Transformer层。每层都会将其K和V投影存储到KV缓存中。这一阶段的计算量较大。
  • 语言模型头。仅将**最终**位置的隐藏状态投影为词汇表大小的形式(约128K个对数概率值)。
  • 采样。Softmax函数将対数概率值转换为概率分布;随后通过某种策略(贪婪采样、top-k采样、top-p采样、温度参数调节等)选定一个ID。
  • 解码循环。该ID会被附加、嵌入,并通过KV缓存再次传递到栈中——每一步生成一个新标记——直到触发停止规则。
  • 反标记化并流式输出。ID会变成文本片段;一旦这些片段有效,服务器就可以立即将它们发送给客户端。
  • 从开始到生成第一个标记的时间几乎总是预填充阶段所需的时间,之后的过程即为解码阶段。

    问题2:为何将推理分为两种不同的工作负载?

    预填充与解码处于模型结构的两端。

    预填充 解码
    每步的形状 (batch, prompt_len, d) (batch, 1, d)
    主要运算 矩阵×矩阵(GEMM) 矩阵×向量(GEMV)
    瓶颈 FLOPs/计算量 内存带宽 算术强度 高 第一批次时约为1–2 FLOPs/字节 跨令牌处理方式 完全并行 严格顺序处理 延迟影响因素 TTFT TPOT/ITL 随以下因素变化 提示词长度 输出长度 MFU(第一批次) 通常为40–60% 通常为1–5%

    在预填充阶段,权重只需加载一次即可应用于数千个令牌向量;而在解码阶段,则需为单个向量重新加载相同权重——为了完成数百万次FLOPs运算需要传输数十亿字节的数据。GPU需等待HBM提供数据。

    几乎所有的优化技巧——批量处理、KV缓存、量化、推测性解码、FlashDecoding以及分阶段预填充/解码——都是为了为那个资源匮乏的计算单元提供更多支持。

    问题3:哪些延迟指标很重要,又有哪些参数可以影响它们?

    • TTFT——主要与预填充相关;随提示词长度增加而上升(当注意力机制起主导作用时情况会更糟)。前缀缓存、分块预填充、更快的注意力机制以及更短的提示词有助于降低该值。
    • TPOT / ITL——主要与解码相关;大致相当于每步字节数 / 带宽。量化、GQA/MQA、推测性解码以及更小的模型都有助于降低该值。
    • 端到端延迟 ≈ TTFT + TPOT × 输出标记数。
    • 吞吐量(每秒/ GPU的标记数)——这是一个整体指标;更大的批量处理会提升该值,但通常会降低每个用户的TPOT。

    吞吐量与延迟相互制约。服务策略就是在这一曲线中选择一个平衡点。

    第4题:为什么解码无法像预填充那样并行化?

    生成过程是自回归的:每个新生成的标记都依赖于之前的所有标记。预填充已经知晓整个提示语,因此可以在因果掩码的作用下同时计算各个位置的信息。而在解码过程中,“未来”的内容还不存在。

    推测性解码是一种解决方案:先生成廉价的初步猜测,然后在一次并行的目标处理中对其进行验证——从而将顺序依赖关系转化为并行验证(第8部分)。

    第二部分——第一阶段和第二阶段:输入文本

    第5题:什么是标记?为何以整个单词或原始字符作为标记是错误的极端做法?

    标记是固定词汇表中的子词单元。纯粹的极端做法行不通:

    • 词汇表没有上限;拼写错误和罕见名称会被标记为<UNK>,这不仅会破坏信息,还会导致嵌入表规模急剧膨胀。
    • 字符词汇表虽能避免出现未知字符,但会使序列长度增加4–5倍,从而加重二次注意力计算负担,并迫使早期层重新分析词形结构。

    子词法则折中解决了这一问题:常见词汇保持完整;罕见形式则分解为有意义的片段;不存在真正的未知字符。

    Q6. BPE是如何训练的?

    字节对编码法从字符(或字节)开始,不断合并出现频率最高的相邻字符对,直至达到目标词汇表大小。这些合并操作会被存储为有序列表。在推理时,会按从左到右的顺序贪婪地应用这些合并规则。其训练基于计数统计而非梯度下降——但由此产生的分词结果会影响到后续的所有处理环节。

    Q7. BPE与WordPiece以及Unigram/SentencePiece的对比

    • BPE——按出现频率进行合并;给定合并表后解码是确定性的。
    • WordPiece(BERT时代)——合并方式类似,但依据概率评分;通常使用##作为延续标记。
    • Unigram/SentencePiece——从大量候选项出发,利用单字母模型进行剪枝;能够随机选择分词方式,并且无需语言特定的预分词器即可直接处理原始字节/Unicode数据。

    如今的实用型大型语言模型多采用字节级的BPE或SentencePiece变体。

    Q8. 为何选择字节级的BPE?

    直接处理原始字节可确保所有字符串都能被编码——不会出现神秘的Unicode编码错误。该模型仍会学习常见的多字节词组,因此英语等语言的编码效率依然很高,而那些罕见的文字系统则可以平滑地降级为字节级处理方式。

    Q9. 为什么模型在统计“strawberry”中的字母时会出错?

    因为模型看到的不是字符,而是令牌ID。如果“strawberry”被拆分成一到两部分,“统计r的个数”这个要求实际上是在询问在第一层处理之前就已经被丢弃的结构。字符级任务需要使用能够保留字符的分词器或外部工具。

    Q10. 令牌ID单独来看有意义吗?

    没有。ID仅仅是指向该模型嵌入表中的索引而已。某个分词器中的ID 100与另一个分词器中的ID 100毫无关联。绝不要在不同模型之间混用分词器。

    Q11. 生产环境中的分词器注意事项

    • 聊天模板和特殊令牌必须与训练数据保持一致。
    • 开头的空格通常会变成独立的令牌——" Hello"与"Hello"是不同的。
  • 如果按字符而非标记计数,截断处理可能会悄悄丢弃系统指令。
  • 多语言字节回退机制会增加数据长度与处理成本。
  • 图像/音频等多模态特殊标记会改变数据打包规则。
  • Q12. 词汇量大小的权衡

    较大的 V 值虽能缩短序列长度并提升多语言支持能力,但会增加嵌入层与语言模型头部参数的规模(各为 V × d_model),同时提高解码时的 softmax 计算成本。现代系统的典型词汇量范围在 32K–150K 之间;超过此范围后,虽然收益逐渐降低,但内存和带宽消耗却会显著上升。

    Q6. BPE 实际上的训练方式

    字节对编码是一种被重新用于词汇学习的压缩技术:

    1. 用基础符号作为词汇表的初始内容(对于字节级 BPE,则为全部 256 个字节)。
    2. 将语料库表示为这些符号的序列。
    3. 统计相邻符号对的出现频率,选出出现最频繁的组合。
  • 将那对字符合并为一个新符号,将其添加到词汇表中,并记录排序后的合并规则。
  • 重复此过程,直到达到目标大小(例如现代模型中的约10万–12.8万)。
  • 生成的结果包括:一个符号→ID映射表以及一个有序的合并列表。在推理过程中,编码会按照该顺序进行贪婪合并——属于确定性方法,而非全局最短分割搜索。

    需要注意的一点是:合并操作优化的是出现频率,而非语言学特征。ing之所以能成为独立词元,只是因为它出现频率高;形态学上的优雅性则是附带效果。

    Q7. BPE与WordPiece以及Unigram/SentencePiece的比较

    • BPE(GPT系列、Llama模型):基于频率进行合并;采用确定性编码方式。
  • WordPiece(BERT时代):结构类似,但会选择在单字模型下能最大化训练数据概率的合并方式——通过评估一对字符组合在一起与分开时的信息量差异来做出决策。
  • Unigram LM(通常通过SentencePiece实现;属于T5/Gemma系列):先从较大规模开始,然后剪除那些移除后对概率影响最小的标记。概率分割机制支持子词规范化(在训练过程中采样不同的分词方式)。
  • SentencePiece是一个可执行BPE或Unigram算法的库。它的实用优势在于能用可见的空格标记处理原始字符,从而使分词过程可逆且无需预处理空白符——这对中文、日文和泰文尤为重要。
  • Q8. 字节级BPE之所以重要,是因为……

    Unicode字符的首字母需要约15万个起始码点,但仍需使用<UNK>。从UTF-8字节出发意味着所有字符串——表情符号、西里尔字母、损坏的字节——都能被编码,不会出现超出范围的情况。

    成本方面:表情符号会消耗更多token;非拉丁字母脚本表达相同含义时通常需要2到4倍于英语的字符数,因此非英语使用者的速率限制和上下文长度上限会更快达到。更大的字典规模(从32K提升到128K级别)部分就是为了缩小这种公平性差距。

    Q9. 为什么“strawberry里有多少个r?”这个测试会失败?

    网络从未直接看到字符,而是看到标识符。如果“strawberry”由多个子词组成,那么要统计字符数就需要从嵌入向量中还原拼写并进行聚合处理——因为不存在专门的“逐字符遍历”操作。同样的问题也会出现在变位词、回文、字符串反转,以及当不同数字的位数分组不一致时的简单算术运算中。现代分词器有时会刻意拆分数字,以便让算术运算能够被模型学习。

    Q10. 孤立视角下的标记标识符

    标识符只是指向该模型对应表格的索引。跨分词器比较是没有意义的。即便是“特殊”标识符,在不同分词器系列中也各不相同。

    Q11>生产环境中可能出现的隐患

    必须使用与训练时相同的聊天模板及特殊标记集。开头空格往往也被视为有效标记。API在按字符计费时会隐式截断指令内容。多模态哨兵标记会改变数据打包方式。缓存键必须包含分词器版本信息。处理BOS/EOS时的偏移错误会破坏停止条件及对数概率校验。

    Q12. 词汇量大小的权衡

    较大的V值虽能缩短序列长度并有助于多语言数据打包,但会增加嵌入层、语言模型头部参数以及解码时softmax运算的负载。当词汇量超过约10万–20万时,除非需要支持多语言,否则通常只会为微小的性能提升付出更高的内存/带宽成本。

    第三部分 — 嵌入层

    Q13. 嵌入层:gather操作与矩阵乘法

    行查找相当于将独热向量与E相乘。核函数实现的是数据聚合,而数学运算本身仍是线性的。

    Q14. 是否需要上下文信息?

    输入行是无上下文关联的。上下文是通过各层之间的注意力机制构建的。检索嵌入通常代表更深层的状态,而非输入表中的行。

    Q15. 权重绑定

    为节省参数,会将嵌入权重与语言模型头部分共享(通过转置实现)——这在小型模型中较为常见。大型语言模型则往往为保证质量而取消权重绑定。绑定的结构并非额外的独立 d × V 矩阵。

    Q16. 位置信息

    绝对嵌入会为每个索引添加向量。RoPE 机制通过旋转Q/K向量,使相对偏移量体现在得分中,并与KV缓存机制协同工作。相对偏差方案也是可选方式,但RoPE在新型语言模型中更为常用。

    Q17. RoPE与长上下文处理

    RoPE的相对几何结构比简单的绝对值表具有更好的外推能力。通过各种扩展功能(位置插值、考虑NTK特性的缩放、YaRN等),可以重新调整旋转频率,从而使更长的上下文在无需从头训练的情况下仍能保持稳定。

    问题18:√d_model因子

    当令牌向量与位置向量被相加时,其比例可能会出现冲突;将嵌入向量乘以√d_model即可平衡这些比例。基于旋转的RoPE结构通常会省略这一乘法操作。

    第四部分 — 变换器块

    问题19–23:注意力机制(详细说明)

    x → MultiHeadSelfAttention → Add & Norm → FFN → Add & Norm → out
    
    Attention(Q, K, V) = softmax(QKᵀ / √d_k) V
    

    查询负责检索,键值对用于标注,实际内容则由值来传递。通过对缩放后的数值应用softmax函数可得到混合权重。为防止随着维度增大分数趋于饱和,需将结果除以√d_k。多个处理头能够使子空间多样化。因果掩码会在被禁止的未来时间点写入−∞,从而使softmax函数的输出恰好为零——不过掩码中的零值仍可能造成信息泄露。在仅使用缓存进行解码时,键集不包含任何未来位置,因此掩码是隐含的;但预填充操作仍需要掩码(或因果核)。

    Q24–Q26. 形状、成本与残差

    每个投影的维度约为d × d(在GQA下有所调整)。FFN的参数量占比最高,约为其他结构的4倍。注意力机制的计算复杂度为O(n² d),而FFN则为O(n d²)。对于较短提示词,权重和FFN的限制起主导作用;而对于较长上下文,则注意力机制与KV内存的消耗更为显著。残差连接通过提供梯度传递路径和附加修正方式,使得深层结构仍可被训练。

    Q27–Q30. 标准化方法、FFN宽度、激活函数与MoE

    RMSNorm无需进行均值归一化,因此比LayerNorm更高效。预标准化方式能更好地稳定非常深的神经网络,优于传统的后标准化方法。宽度较大的FFN(约4倍)可为注意力混合器之间的每个标记提供更多处理能力。非线性函数可防止多层线性结构出现崩溃现象;SwiGLU在众多LLM对比实验中表现优异。MoE技术将标记分配到少数几个专家FFN中,从而使参数量增长速度快于每标记的FLOPs数量——这种架构内存占用高但计算密度低。

    Q31–Q32. 深度/宽度与注意力机制的变体

    深度促进混合,宽度丰富特征。实验室需在数据量和集群限制下进行选择。MHA为每个键值对单独存储;MQA在多次查询中共享同一个键值对;GQA按组共享;MLA则进一步压缩键值对。服务成本推动了行业沿此发展路径前进。

    第5部分 — 键值缓存

    Q33. 什么是键值缓存,为何只有K和V?

    在解码步骤t时,会有一个新的标记出现。它的查询代码q_t需要参考位置1..t的键和值。而1..t−1位置的键和值仅取决于之前的标记以及固定的权重。因果关系确保了引入标记t后无法修改那些历史上的键值张量——它们是不可变的——因此这些键值张量只需计算一次并存储起来。

    查询各有不同:当前步骤只需使用 q_t 即可。之前的查询已经生成了对应的输出,且不会再被读取,因此缓存 Q 会浪费内存。

    如果没有缓存,每次生成标记 t 都需要重新处理整个前缀序列——其计算量会随着序列长度的增加而急剧上升。而有了缓存后,每一步的注意力计算量与当前序列长度成线性关系,且 FFN 每处理一个新标记的运算量基本保持不变。这样一来,文本生成的计算量将与解码步骤数成线性关系,而非与处理轮次成二次方关系。

    Q34. 用具体数值推导 KV 缓存大小

    KV bytes = 2 (K and V)
             × n_layers
             × n_kv_heads × d_head
             × seq_len
             × batch_size
             × bytes_per_element
    

    以 Llama-3–70B 级别的 GQA 结构为例:共 80 层,每个层有 8 个键/值头,每个头有 128 维,这些数据均以双精度浮点数存储。

    将这些因素相乘:两个张量(K和V)×80×8×128×2字节,最终每条实时序列的每个标记所需空间接近320 KB。

    若对话长度达到8k个标记,单个用户所需空间约为2.6 GB。当上下文长度增至128k时,按照同样的计算方式,所需空间将达到数十GB——甚至在考虑权重之前,单次对话就已占用了H100级设备的大量存储空间。

    如果不使用GQA(64 KV头)的情况:8K长度的序列所需空间会上升至约21 GB/条。GQA的存在使得系统能够同时处理数十个用户,而非仅少数几个。

    权重是一次性支付的固定费用。KV缓存则是按用户、按令牌计费且无上限的费用。它决定了最大批量大小,进而影响处理速度,最终决定每百万令牌的成本。正因如此,图表中将其标为内存瓶颈。

    Q35. 为何解码受内存限制——计算层面分析

    以一个70B的fp16模型在单批次处理一个令牌为例:

    • 数据传输量:约140 GB的权重加上几GB的KV缓存,总计约142 GB。
    • FLOPs数值:约为2 × 70e9 × 1 = 140 GFLOPs。
    • 计算强度:约为1 FLOP/字节。

    H100显卡的HBM带宽约为3.35 TB/s,fp16运算能力约为1000 TFLOPs。当计算负载超过带宽上限时,其阈值在数百FLOPs/字节左右。而在1 FLOP/字节的计算强度下,GPU仅使用了其峰值算力的一小部分——此时GPU主要承担数据传输功能。

    实际耗时 ≈ 142 GB / 3.35 TB/s ≈ 42 ms → 仅从带宽角度计算约为24 tok/s。实际系统的性能会在该估算值的两倍范围内,这正是带宽限制对性能影响的体现。

    推论:在计算资源不足之前,增加批次大小对权重传输几乎不会带来额外成本。从批次大小1增加到32时,一个权重负载可在32个序列中重复使用,从而相应提升token处理速度。这种成本分摊正是大语言模型服务中的核心经济规律。

    Q36. 如果批次处理是“免费”的,为什么不能设置为512?

    因为每个序列都需要独立的KV存储空间,而缓存内存的大小与batch × seq_len成正比:

    GPU memory = model weights + KV cache + activations + fragmentation overhead
    

    举例:2台H100(总容量160 GB)存储的权重为140 GB,因此缓存剩余约20 GB。按每token 320 KB计算,整个批次最多可处理约65K个token。即便只有16名用户,每人的上下文长度为4K,也会耗尽这部分缓存资源。

    因此,KV尺寸限制了批量处理规模,进而限制了吞吐量。GQA、MLA、缓存量化、分页以及驱逐策略其实都是披着内存外衣的吞吐量优化技术。

    Q37. PagedAttention与碎片化问题

    简单的服务器会为每个请求预留长度不超过max_seq_len的连续KV空间。这种方式存在两个问题:

    • 内部碎片化——为100个标记的输入预留了4096个槽位,导致大部分空间被浪费。
    • 外部碎片化——释放出的大小不一的区域会留下空洞,无法再放入新的KV空间。

    采用简单分配策略时,KV内存的浪费率通常在60–80%之间。

    PagedAttention(由vLLM推广)借鉴了操作系统的虚拟内存机制:固定大小的块(例如16个标记),以及一个将逻辑位置映射到内存池中任意物理块的块表。随着生成内容的增加,会逐步分配更多块。

    优势:

    • 内存碎片化问题得到解决 → 同一组GPU上可处理的并发序列数量通常可提升2–4倍。
    • 前缀共享/写时复制 —— 多个带有相同系统提示的请求可共享物理块,直到其后续内容出现差异;非常适合用于智能体、RAG指令及少样本任务。
    • 搜索束与并行样本可共享公共前缀,而无需复制该前缀。

    相应的代价是增加了间接性,以及需要一个能够从非连续块中收集数据的注意力内核。

    Q38. 静态批处理与连续批处理

    静态批处理会等待批量数据填满,让所有序列同步运行至最长的那个长度,然后再进行填充。较短的请求必须等待较长的请求完成;GPU的运算周期会被用于处理这些填充数据。

    连续(迭代级)批处理会在每个解码步骤中重新构建批次:已处理的序列会被移除,新的序列会加入,GPU仅持续处理当前正在处理的token。这样延迟的波动会显著降低,吞吐量则大幅提升——这正是现代引擎(如vLLM、TensorRT-LLM等)所追求的标准。

    Q39. 分块预填充与预填充/解码分离

    数千token的预填充操作可能会占用GPU的全部资源,导致交互式用户的解码过程受阻。分块预填充则将长提示语拆分成多个部分,与解码步骤交错进行,这样虽然TTFT会有所上升,但TPOT仍能保持较为平稳的运行状态。

    细粒度分解的做法更为深入:在计算优化型池中执行预填充操作,在内存优化型池中进行解码,通过网络传输键值对。虽然这会增加调度复杂性,但能让每个处理阶段都匹配到其真正能充分发挥性能的硬件。

    Q40. 超出GQA范围的键值对压缩

    可采用的手段包括:

    • MQA / GQA / MLA — 减少键值对数量或对其进行压缩。
    • 量化缓存(如INT8/FP8/NF4格式)——通常对键和值而言几乎无损失。
    • 窗口化/滑动注意力机制——在任务允许的情况下丢弃较远的标记。
    • 针对极端场景的驱逐/流式处理策略。
    • 在不同层次间共享表示的跨层重用研究思路。

    每种方法都会在一定的质量或通用性上做出牺牲,以换取更大的内存优势。

    Q41. 前缀缓存——当架构发生变化时

    如果多个调用共享一个长度固定且不可更改的前缀(系统提示、工具架构、获取的粘性上下文),缓存该前缀的键值对即可避免重复计算。因此,相关架构更倾向于使用稳定的前缀和可变的后缀:将易变的用户输入放在末尾,保持共享部分完全一致以便缓存键能够匹配。产品文案和提示词编译器也成为了影响性能的因素。

    Q42. 键值缓存何时会失效?

    只要历史令牌被修改,而不仅仅是追加,都会导致缓存失效:包括在对话进行中重新生成内容、修改系统提示、更换工具定义,或是进行非因果性的编辑。前缀缓存必须以精确的令牌标识(以及模板版本)作为键。采样参数不会使键值对失效——它们仅改变逻辑值如何转化为下一个标识符——但在运行过程中更换模型适配器、草稿模型或RoPE缩放系数则可能使其失效。

    第6部分 — LM头(线性层 + softmax)

    问题43:LM头的功能及其结构

    最后一个模块会输出h ∈ ℝ^(seq_len × d_model)。经过最终归一化处理后,通过一个线性变换即可得到词汇表的逻辑斯蒂值:

    logits = h @ W_lm      W_lm ∈ ℝ^(d_model × V)
    

    当d_model = 4096且V = 128,000时,W_lm包含524M个参数,每个被评估的位置都会生成一个宽度为128K的向量。

    问题44:解码时每个位置都需要逻辑斯蒂值吗?

    不需要。在训练或某些特定接口中,预填充机制可能会为多个位置生成评分,但普通解码仅需最后一个位置的隐藏状态,因为之前的位置早已确定了对应的标记。

    问题45:解码时LM头的计算成本

    每一步都会将一个 d-向量乘以 d × V,运算量约为 2 × d × V 次浮点运算,同时还需要完整读取可能未关联的头部信息。当 V 的值很大时,这种运算量与FFN切片相当,因此需要在可行情况下采用自适应softmax、词汇表并行分片以及关联嵌入。

    Q46. 对数几率与概率

    对数几率是无界得分,而softmax则用于对其进行归一化:

    p_i = exp(z_i) / Σⱼ exp(z_j)
    

    请记住平移不变性:给所有对数几率加上一个常数不会改变概率——这是实现稳定算法以及利用温度参数调整差异值的基础。

    Q47. 数值稳定的softmax实现

    直接使用 exp(z_i) 的方法在fp16格式下,对于中等数值的对数几率会导致溢出,甚至使整行数据变为零,从而产生 0/0 错误。解决此问题的方法是先减去该行的最大值:

    p_i = exp(z_i − max(z)) / Σⱼ exp(z_j − max(z))
    

    最大的项为exp(0) = 1;其余项则位于(0, 1]区间内。在线算法(如FlashAttention)会将这一结果与矩阵乘法结合使用,以避免生成庞大的得分矩阵。

    Q48. 困惑度

    困惑度是指对所有标记计算exp(平均负对数似然值)的结果——即模型感到“惊讶”的程度。它是在相同的logits/softmax计算阶段得出的。某个领域的困惑度越低,说明该模型对该领域下一个标记的预测能力越强,但这并非衡量其有用性或安全性的直接指标。

    第7部分 — 抽样策略

    在语言模型输出层之后,会得到一个logits向量。抽样过程就是将这个向量转换为下一个ID的过程。

    Q49. 贪心解码——以及为何会令人失望

    贪心算法总是选择argmax结果。它具有确定性且计算成本低,但往往生成的文本较为平淡或存在局部固执问题:早期出现的高概率词元可能会使序列陷入重复性高、可能性大的循环中,而人类会认为这类结果比那些概率稍低的替代方案更差。可将其用于对稳定性要求较高的提取任务,但不宜作为开放式文本生成的默认策略。

    Q50. 为何不使用束搜索?

    束搜索会保留排名前B位的候选假设。当目标文本较短且约束较多(如翻译任务)时,这种算法效果较好。但在开放式对话场景中,它往往生成内容泛化、可能性高的安全文本,需要B×的计算量,且与核采样式的多样性策略配合不佳。大多数大型语言模型应用已放弃使用它而转而采用采样方法。

    Q51. Top-k算法

    仅保留最大的 k 个对数概率值,进行重新归一化后采样。方法简单,但 k 的选择较为生硬:有时排名靠后的概率值仍然重要;而在分布较集中的情况下,前 k 个值中可能包含无用信息。固定的 k 值无法适应分布的集中程度。

    Q52. Top-p(核方法)

    按概率排序,保留累积概率≥p的最小样本集,然后从中采样。当模型较为确定时,核范围会缩小;当模型不确定时,核范围则会扩大。正是这种适应性使得 Top-p 在许多框架中取代了固定的 Top-k 成为默认选项。典型的 p 值在 0.9–0.95 之间,具体数值需根据应用场景调整。

    Q53. 温度参数——数学原理与直观理解

    p_i = exp(z_i / T) / Σⱼ exp(z_j / T)
    

    在应用 softmax 函数之前,先将对数概率值除以 T。

    • T → 0 ——概率值之间的差距会急剧扩大,分布会收敛到 argmax 值(即贪婪策略)。
    • T = 1 ——未经过缩放的模型分布。
  • T > 1 — 扁平化处理;会产生更多意外情况,且存在逻辑不连贯的风险。
  • 在实现中,温度参数本身并不会“增加随机性”——它只是改变采样器所依据的分布形态。

    Q54. 顺序:温度参数与截断处理

    应**首先**对对数概率应用温度参数,然后再在得到的分布上使用 top-k / top-p 方法(或等价地在经过温度调整后的概率值上进行截断)。在应用温度参数之前就进行截断会改变存在的概率尾部,通常属于错误的处理方式。请明确记录服务器所采用的顺序;隐式的顺序调整会改变程序行为。

    Q55. 重复、频率及出现次数惩罚

    • 重复/频率 — 对已出现过的标记降低权重,通常按出现次数进行缩放。
    • 出现次数 — 无论出现多少次,只要某个标记出现过一次就会受到惩罚。

    它们在创造性解码中会对抗循环现象,但可能损害有意的重复结构(如代码、诗歌、法律条文)。相比过度限制,它们更倾向于轻度的惩罚机制和严格的停止规则。

    Q56. 除 top-p 之外的因素

    Min-p 阈值是与最高概率相关的(p_i ≥ min_p × p_max),在温度较高且概率分布较分散时表现更好。Mirostat 及相关控制器旨在控制惊喜程度。目前的实际应用仍以温度和 top-p 为主,而 min-p 的使用比例正在上升。

    Q57. 温度为 0 时仍存在差异——为何?

    即便是“贪婪”算法在不同情况下也会存在差异:

    • 非确定性的 GPU 计算方式及融合内核。
    • 不同的批量处理/连续批量调度策略。
    • 推测性路径以及数值上有所差异的 softmax 实现方式。
    • 服务器端的默认惩罚机制、停止条件及模板设置。
  • 如启用,则会有MoE路由噪声。
  • 位稳定贪心算法需要锁定内核、批次大小为1以及完全相同的软件版本——在多租户环境中极为罕见。

    问题58:强制使用JSON或模式

    可选方案依次为:

    1. 强制要求使用JSON(但较为脆弱)。
    2. 受限解码/语法掩码——在每一步中都将非法标记置零(通过正则表达式、JSON模式或上下文无关文法实现)。
    3. 调用能够解析侧信道而非自由文本的工具/函数API。
    4. 事后修复(最后手段)。

    当数据的有效性是必须满足的条件时,受限解码是可靠系统的解决方案。

    问题59:评估采样设置

    固定模型,对带标签的数据集测试温度参数和top-p值:任务完成度、毒性、多样性(distinct-n)、重复率以及延迟。建议采用离线评估结合在线A/B测试,并明确产品相关指标。切勿仅基于单个精心挑选的提示词进行调优。

    第8部分 — 推测解码

    问题60:核心理念

    一个成本较低的草稿模型会提出若干个未来的标记;目标模型则通过一次并行前向传播来验证这些标记。被接受的标记前缀将成为输出;若首次被拒绝,则从目标分布中抽取替代项并舍弃其余候选。这样可以将大部分目标模型的计算资源用于并行验证,而非逐个标记的串行处理。

    问题61:为何输出分布保持不变

    接受机制通过目标值 p 与草稿值 q 之间的比率,使得被接受的标记加上剩余的重采样能够精确地重建出 p:

    P(emit x) = q(x)·min(1, p(x)/q(x)) + P(reject)·p'(x)
    

    被接受的路径贡献 min(q,p);剩余重采样则填补 max(0, p−q)。两者相加即得到 p。因此,与普通的目标采样相比,推测解码是无损的——这提升了系统速度,而非对模型的近似。

    Q62. 预期加速效果

    在接受率为 α 且草稿长度为 k 的情况下,每个目标正向处理预期产生的标记数为:

    E[tokens] = (1 − α^(k+1)) / (1 − α)
    

    即便每个草稿标记都未被选中,仍可从目标的验证阶段获得一个标记。若以目标步骤为基准,草稿处理的成本为 c:

    speedup ≈ E[tokens] / (1 + k·c)
    

    示例:α=0.8,k=4 → 预期约3.36个标记;当c=0.05时 → 约2.8倍。已发表的优质结果通常处于2–3×区间。较大的k值会导致收益递减,因为存活概率会按α^k的规律下降。

    Q63. 何时投机会带来危害

    接受率低(提示词难度高、领域偏移、草稿质量差)、草稿生成成本过高,或是内核无法高效并行验证。此时额外开销会超过收益——需根据实测的α值来决定是否继续。

    Q64. 被拒绝时的KV缓存处理

    为被拒绝的生成结果保存回滚目标(及对应草稿)的缓存条目。实现时需控制检查点的长度并适当截断;此类错误会破坏后续的注意力机制。已被接受的标记则保留其K/V值。

    Q65. 现代变体

    美杜莎/多头生成器、鹰式特征级生成器、基于上下文本身的提示词查找/n-gram生成器以及级联生成器。均遵循“与目标对比验证”的原则。

    Q66. 树形注意力

    生成器可以提出候选项的树结构,而不仅仅是线性链。树形注意力可在一次目标遍历中验证多个分支,当分支生成成本较低时,能提高每次调用的通过率。

    第9部分 — 反分词器与流式处理

    Q67. 反分词并非简单的逆向映射

    反分词器必须消除分隔符、处理字节回退问题、组合多字符字形,并避免输出不完整的UTF-8编码。流式反分词会暂存数据,直到有完整字符/片段可安全输出——否则客户端会看到替代字符。

    Q68. 流式处理的原理及衡量标准

    服务器在生成令牌时会立即输出这些令牌(或部分字符串)。需要测量TTFT、TPOT以及解码缓冲后的首个可读字符出现的时间。对于客户端用户体验而言,最后一个数值比原始令牌时间戳更为重要。

    Q69. 结束序列处理较为复杂

    结束标记可能跨越令牌边界(如\n\n与包含两个换行符的单一令牌)。必须检查解码后的文本(或经过仔细筛选的令牌窗口),而不仅仅是单一ID是否匹配。若部分生成的结束标记存在重叠,则需要回滚操作,以避免显示错误的结束文本。

    Q70. 什么会终止生成过程?

    EOS/特殊结束标记ID、匹配到的结束字符串、最大令牌数量限制、客户端取消请求,或是服务器的监控机制。建议采用与聊天模板一致的明确EOS处理方式。

    第10部分 — FlashAttention、量化与rooftop算法

    Q71. FlashAttention — 精确性说明

    FlashAttention通过分块技术和在线softmax统计方法来计算注意力,无需在HBM中生成完整的得分矩阵。这减少了内存访问量,使得处理更长的序列或更大的批次成为可能。它不会改变数学上的注意力计算结果(数值误差除外);这是一种注重I/O效率的算法,而非不同的模型。

    Q72. 它有助于解码吗?

    使用缓存进行解码时,通常会以长度为1的q向量与缓存的个键向量进行注意力计算——传统FlashAttention的优势(巨大的方阵得分)在此处会减弱。尽管有FlashDecoding等变体仍有助于优化KV带宽利用,但除非批次规模很大,否则解码过程依然受权重加载的制约。

    Q73. 量化

    将权重(有时还包括激活值/KV)存储或计算为更紧凑的格式(FP8、INT8、INT4等)。内存占用和带宽大致随位宽降低而减少;质量损失则取决于所用的量化方法(GPTQ、AWQ、平滑量化等)。根据实践经验,8位量化几乎无需额外成本;4位量化会带来一定代价,有时其影响甚至可被基准测试中的噪声掩盖——务必在具体任务上进行测试。

    Q74. 用一段文字概括“屋顶线”概念

    绘制可实现的FLOPs值与算术强度之间的关系图。预填充操作位于计算“屋顶”附近;单批次解码则处于带宽“屋顶”附近,约为1 FLOP/字节。那些能提升算术强度的优化措施(如批量处理、每次有效FLOP传输更少的比特数)会让你更接近该“屋顶”;而单纯的核函数加速无法突破现有的限制。

    Q75. 将大型模型分配到多块GPU上

    张量并行将层内的矩阵拆分(需要快速的互连)。流水线并行为不同节点分配层范围(存在气泡风险)。专家并行则对MoE中的专家模型进行拆分。副本/数据并行通过复制模型来提升处理速度。实际部署中通常会结合多种方式使用;KV存储必须与注意力机制的布局保持一致地进行分区或复制。

    第11部分 —— 白板计算数值

    • 70B fp16权重: 70e9 × 2 ≈ 140 GB。
    • 前向计算FLOPs:约等于2 × 参数量 × 令牌数(数量级估算)。
    • 每个令牌的KV存储量(Llama-3-70B-class GQA):约等于2 × 层数 × kv_heads数量 × head_dim × 数据类型字节数,每个令牌约为三分之一兆字节。
  • 第一批次解码速率(tok/s):约等于带宽 / weight_bytes(H100级模型:在其他优势出现之前,FP16格式下可达数十tok/s)。
  • V=128K、d=4096时的嵌入层与独立语言模型头部:各自约含524M个参数。
  • 注意力机制与FFN结构的参数比例:在标准模块中约为1:2(4d²对比约8d²)。
  • 第12部分 — 图表说明

    常见的教学图表未展示:分词前的对话模板、影响KV宽度的GQA/MQA机制、采样顺序细节、反分词缓冲处理、分页式KV存储以及推测性验证循环。应将图表视为参考,而非严格规范。

    结语

    推理是一个从字节到流式文本的处理流程,其中预填充阶段受计算能力限制,解码阶段则受带宽限制,KV缓存占据了多用户系统的大部分内存;而所有重要的优化措施——GQA、分页、连续批处理、量化、FlashAttention以及预测执行——都是为了在不过度改变数学模型的前提下,将计算任务更好地适配硬件的优势特性。

    深入探讨A——实际应用中预填充与解码的成本对比

    在规划算力规模时,应从顶线分割点开始考虑。需要处理长文本的任务非常依赖张量核心:在代码辅助或RAG查询中,若内核性能良好,长提示语也能保持较高的MFU利用率。第一批解码任务看起来就像随机进行的内存性能测试——同样的70B权重在处理单个GEMV运算时就能快速通过HBM传输。正因如此,即便使用旗舰级GPU,那些只能生成500个标记长度答案的系统也会显得缓慢,除非采用批量处理、量化或推测解码技术。

    TTFT性能下降通常意味着提示语内容(历史记录、RAG数据、工具结构)不断增多,而未进行前缀缓存。TPOT性能下降则多因批量处理失效、带宽不足,或是KV存储压力迫使系统只能使用极小的批次。端到端延迟并非单一因素所能决定:缩短答案长度可让TPOT时间减少N倍;对系统提示语进行缓存有助于改善TTFT性能;在接受率较高的情况下,推测解码技术也能提升TPOT效率。

    仪表板上显示的吞吐量指标很容易被通过大量批量处理来操纵,从而导致交互式用户体验不佳。应同时展示每台 GPU 每秒处理的令牌数,以及在真实混合负载下的 p50/p95 TPOT 值。连续批量处理能让 GPU 不断获得数据,避免静态批量处理带来的额外负担;而分块预填充则能防止单个 32K 长度的提示词导致其他所有内容的解码过程停滞。

    将预填充与解码分开处理,实际上意味着这两种工作负载需要不同的硬件配置。预填充节点可以采用更高密度的计算资源,而解码节点则需要足够的内存容量以及处理 KV 数据的带宽。如果无法高效传输 KV 数据,就无法实现良好性能。并非每个团队都应在一开始就构建这样的架构——但每个团队都应该明白这种设计模式的存在原因。

    深入探讨 B — 分词器与多语言处理成本

    字节级BPE的通用性既是优势也是负担。英语聊天应用在处理印地语、泰语或包含大量表情符号的社交文本时,成本估算往往不足。如果你的利润模型以每秒英语标记数为基础,多语言扩展可能会在不知不觉中消耗预算。当相关流量较为重要时,应选择覆盖更多语言的分词器;需基于真实语料库而非伪文本来统计每个字形簇对应的标记数。

    聊天模板是模型身份的重要组成部分。一旦遗漏某个特殊结束标记,就可能导致生成的文本过长或被截断。应在注册表中将模板版本与模型修订版本一同存储。当遇到“模型忽略系统提示”这一问题时,应在指责权重问题之前,先对双方内容进行分词并对比其标识符。

    数字处理规则对电子表格工具和数学辅导服务而言至关重要。如果“1000”与“1,000”的处理方式不同,列计算算法就会变得像彩票一样不可预测。在基于大语言模型构建计算器时,应选择具有明确数字处理规则的分词工具,或将算术运算交由专用工具处理。

    深入探讨C——注意力机制、GQA与内存

    多头注意力机制的本质是在预算限制下的专业化设计。GQA则关注KV字节的数量。从多头注意力机制转向GQA,可大致按查询头数与KV组数的比例减少缓存大小——通常可缩减4到8倍——且在针对性训练后质量损失较小。MQA则是极端方案;MLA及相关压缩方法则通过不同的算法思路来解决同样的瓶颈问题。

    使用负无穷作为因果掩码并非吹毛求疵:任何有限的掩码值都会导致信息泄露。那些意外允许未来注意力机制参与的训练缺陷,会造就出在教师引导的评估指标上表现优异、但在实际自回归应用中却失败的模型。解码时的核函数假定缓存布局必须与训练时的结构(头数、RoPE基数、缩放因子)完全一致。

    残差项与预归一化正是80–100层模型结构普遍存在的原因。当某些自定义架构为“简化设计”而去除这些元素时,首先出现的问题往往是训练不稳定,而非性能提升。SwiGLU的门控机制虽能提升性能,但也会影响内存使用效率——需明确所使用的模型架构是否已对其进行了优化整合。

    深入探讨D——KV分页与前缀策略

    PagedAttention将KV存储视为由多个块组成的堆结构。由此带来的影响包括:

    • 那些包含大量共享系统提示的智能体框架,应当对相关前缀进行标准化处理,以避免块哈希值发生冲突。
  • 少样本库应保持示例的稳定顺序;重新排序会降低缓存命中率。
  • 个性化字段应放在共享词干之后。
  • 调试工具应像CDN显示缓存命中率那样展示块表命中率。
  • 前缀缓存失效是一个正确性问题,而不仅仅是性能问题。如果工具的架构发生了变化但缓存键未对此作出响应,模型就会使用过时的KV数据来处理新指令——这是隐蔽且严重的故障。应在缓存键中包含分词器ID、模板哈希值、LoRA ID以及RoPE缩放系数。

    在内存压力下进行数据淘汰需要相应的策略:对闲置对话采用LRU机制,为上下文设置上限,或通过摘要压缩来处理。无论选择哪种策略,都需在产品中明确体现——隐秘的截断行为会损害用户信任。

    深入探讨E——Softmax、采样与确定性

    在 fp16/bf16 模式下必须使用稳定的 softmax 函数。虽然融合内核可以隐藏最大值减法操作,但自定义的研究代码仍可能引发溢出问题。在更改内核或量化方案时,困惑度依然是一种有效的回归检测指标:数值激增意味着分布发生了变化。

    采样流程应当进行单元测试:先设置温度参数,再截断处理,接着应用惩罚机制,最后进行采样。若在测试用例中交换这些步骤的顺序,就会发现标准输出结果出现偏差。针对 JSON 的受限解码功能需要进行负载测试;如果实现方式不当,掩码生成可能会成为 CPU 的瓶颈。

    “温度值为零即意味着确定性结果”只是营销话术,并非真实 GPU 上的数学保证。如果需要符合审计标准的可重复结果,应记录下采样的 ID(或随机数生成器的种子以及第 1 批次的固定内核参数)。对于大多数应用而言,版本发布范围内的可重复性就已足够——只需对此进行文档说明即可。

    深入探讨 F — 推测性解码操作

    无损失推测之所以有效,是因为产品负责人担心质量下降。不过,运营团队仍需按提示类别跟踪接受率。代码补全通常能获得较高接受度,而创意类开放式对话则未必如此。根据近期接受情况动态调整草稿长度,比固定猜测更为有效。

    当草稿能够以较低成本提出多种替代方案时,树结构推测会很有帮助。KV回滚正确性测试应纳入持续集成流程:在运行过程中故意拒绝某些结果,并确保后续的注意力机制符合非推测性的基准。

    草稿模型必须与目标模型共享分词器(或兼容的映射关系)。不匹配的分词器会产生隐形垃圾数据,让人误以为推测导致模型变笨了。

    深入探讨 G — 流式用户体验与停止机制

    用户感知的是去标记化后的字符所带来的流畅性,而非原始ID。在Unicode格式有效之前请先缓存数据;为提升聊天用户体验,可在遇到空白字符时立即刷新。对于那些会导致序列与标记重叠的情况,需要谨慎处理撤销操作,以确保客户端永远不会看到这些终止文本。如果产品支持继续处理,最大标记数量限制应附加明确的继续信号。

    深入探讨H——服务端中的FlashAttention与量化技术

    FlashAttention通过节省HBM资源,实现了更长的预填充长度和更高的批次处理密度。虽然这一技术值得肯定,但并不能说它彻底改变了解码机制。量化则是提升性能的关键手段:每个权重所占的字节数越少,每秒能处理的有效标记数量就越高。在宣称4位量化技术已可广泛应用之前,务必通过自身的测试套件进行验证——尤其是工具调用功能以及长上下文召回能力方面。

    基于架构逻辑的思考能让论证更加客观:如果受带宽限制,单纯增加TFLOPS数值而不提升带宽(或减少数据量)只会带来失望。在预填充阶段若受计算能力限制,优化GEMM运算和数据分块调度比削减KV存储更重要。

    深入探讨I — 多GPU的实际应用

    张量并行需要快速的互连机制,否则在全归约操作时会陷入停滞。流水线并行则需要通过微批次处理来避免性能瓶颈。将这两种方式与连续批处理及分页KV存储结合使用,正是推理引擎代码量庞大的原因。当有人提议直接对模型进行分片时,应询问是按哪个维度分片,以及KV存储结构会如何变化。

    深入探讨J — 构建流水线

    值得记住的请求处理流程:

    1. 在CPU上完成模板生成与分词处理
    2. 利用因果注意力机制进行嵌入操作和预填充,并将KV数据写入GPU(此时受计算能力限制)
  • 在最后位置使用LM头进行采样(采用CPU策略的GPU)
  • 带缓存的解码循环,连续批处理,可选预测功能(适用于GPU且受带宽限制的场景)
  • 反序列化、停止条件检查,在CPU上处理流式数据
  • 在分配器中释放或复用KV块
  • 每一项优化都对应着列表中的一条箭头。如果无法找到对应的箭头,说明你还没有真正思考推理过程——只是在收集一些口号而已。

    额外的FAQ式说明

    提高温度值能否以可测量的方式提升创造力?它确实会增加下一个标记的分布熵。人类是否认为结果具有创造性取决于具体任务;应通过多样性和质量指标来衡量,而不能仅凭感觉判断。

    贪婪策略真的永远正确吗?是的——分类即生成、带约束解码的结构化提取,以及一些评估工具都能体现这一点。而开放式对话通常并非如此。

    可以删除KV缓存后重新计算吗?当然可以,但代价是时间复杂度呈二次方增长。边缘设备有时会采用无缓存的短窗口处理方式;服务器则几乎绝不应如此。

    为什么图表中会在注意力机制内部和语言模型头部都显示softmax?因为是不同的softmax应用:一种用于在层内混合数值,另一种则将词汇表的logit值转换为可用于采样的类别分布。同属同一函数家族,但功能各异。

    新工程师首先应该记住什么?预填充与解码瓶颈、每个标记的KV字节数公式、TTFT与TPOT的区别,以及批量处理是以延迟为代价换取吞吐量的。其他所有知识都基于这四个概念。

    深入解析——预填充核与TTFT调控机制

    预填充服务质量主要取决于将提示语转换为热KV缓存的速度。注意力核、融合的MLP路径以及是否对提示语进行分块处理,都会影响TTFT曲线的形态。当多个提示语具有相似的前缀时,前缀缓存可将重复的预填充开销转化为快速查询;若没有该机制,则每个新会话都需要支付全额成本。

    分块预填充既是降低延迟的手段,也是保障公平性的工具。没有它,一次40k令牌的输入可能会阻塞GPU上其他所有任务的解码工作;有了它,即使长任务正在分块处理中,交互式流仍能持续运行。其代价是长任务本身的TTFT值会略有上升——但这通常是可以接受的。

    前缀的位置属于产品设计决策。将易变的用户文本放在固定的词干之后,这样缓存键就能保持稳定。如果营销团队每天都会重写系统提示语,应将其视为触发缓存失效的事件,并预计TTFT值会上升,直到新的词干再次被频繁使用。

    详细解析——用文字解释带宽计算原理

    假设在批量大小为1的情况下,每生成一个标记就需要从HBM中读取整个权重集。此时计算强度会降低到几乎相当于每移动一个字节只进行一次有效的乘累加操作。那些在密集GEMM运算中表现出色的硬件,会因为等待内存控制器而处于闲置状态。批量处理可以让每次权重加载在多个序列中重复使用;量化则能减少加载量本身;而推测性验证则可将多个串行步骤合并为一次并行检查。这些都是通往同一目标的不同途径。

    当有人声称某个内核在解码方面的速度是“快两倍”时,先问问他们是在什么环境下做的测试。如果性能受限是由于带宽问题,仅靠算术逻辑单元优化是无法实现两倍速度提升的。如果他们还声称减少了数据传输量,那只有在看了性能分析工具的截图之后才能相信他们的说法。

    深入讲解——服务策略与SLO

    应为TTFT和TPOT分别设定SLO。即便吞吐量提升了,而p95 TPOT值却翻了一倍,对于聊天用户体验而言这也属于退化现象,即便容量监控面板显示一切正常。连续批处理参数(最大批次令牌数、最大等待队列长度、解码任务与预填充任务的优先级)正是实现这些SLO的实际调控手段。

    准入控制应与KV内存管理一同考虑:当预计的缓存内存超过设定阈值时,就拒绝新会话或将其放入队列。否则,内存不足导致的程序崩溃在客户端看来就会像是模型随机故障。

    深入讲解——分词器操作检查清单

    在推广模型之前:

    1. 将分词器文件和聊天模板文本与权重一起存储在同一个资源库中。
    2. 对少量多语言字符串和表情符号进行黄金测试,以防出现分词长度异常。
    3. 如果产品需要执行数学运算,则需对包含大量数字的字符串进行黄金测试。
    4. 确认停止标记的ID与模板中的结束标识一致。
    5. 确认日志概率计算工具使用的分词器与推理时的一致。

    如果跳过其中任何一步,你调试的“模型质量”问题实际上只是封装层面的偏差。

    详细指南——以时间线形式展示注意力机制的变体

    早期的大型语言模型使用完整的MHA结构,并通过缓存来支付其成本。生产环境的压力催生了MQA,随后又出现了GQA作为大多数前沿检查点所采用的折中方案。MLA及相关低秩KV理念延续了同样的思路:保持查询的丰富度,同时减少每个历史标记所存储的数据量。在阅读论文时,应将相关表述转化为“每个KV标记的字节数”以及“我们在评估中的质量变化”——否则那些关于“高效注意力机制”的营销用语就毫无意义。

    详细解析——分页KV与多租户行为

    对于连续分配的场景,碎片化计算会带来极大挑战。分页机制则将其转化为具有固定块大小的分配问题。多租户集群需要跟踪分配失败情况,从块表中获取延迟优势,并关注前缀匹配率。匹配率的突然下降通常意味着模板空白格式发生了变化,或是分词器版本悄然升级了。

    在多束搜索和并行样本之间实现写时复制共享对于类似搜索的解码来说是必不可少的;如果没有这一机制,就会无端地使内存占用随束宽增加。

    详细讲解——产品相关的采样策略

    根据任务需求设置默认参数:

    • 提取/工具参数:较低温度、受限解码、贪婪策略或小型核心结构。
    • 支持聊天功能:中等温度,核心值设定在0.9左右,若出现循环则给予轻微的重复惩罚。
    • 创意头脑风暴:较高温度,考虑最小概率值,并对方差问题给出更明显的用户警告。

    为每条回复记录采样参数,以便处理支持请求。没有这些记录,“模型昨天说了X”这类问题将无法得到解答。

    详细讲解——推测性解码的逐步应用

    在标志后逐步推出该功能。通过终端点来衡量接受度。当 α 值低于根据预估成本 c 和预估长度 k 计算出的盈亏平衡点时,应禁用该功能。始终保留一部分非推测性的测试流量——它是衡量质量的实际标准。

    确保拒绝处理流程会清除键值对。添加一种混沌测试,以便在负载较高时强制触发序列中途的拒绝处理。

    详细讲解——流式协议细节

    决定数据传输格式是传输令牌、已反令牌化的字符串,还是两者皆有。如果客户端采用不同的反令牌化方式,就会对数据边界产生分歧。建议在完整字符群组准备好时由服务器端进行反令牌化,并通过明确的“刷新”事件来通知。需记录如何移除停止序列,以避免用户界面代码对其重复处理。

    详细讲解——量化功能的验收测试

    在正式环境中启用4位权重之前:

    • 运行标准的评估套件。
    • 运行工具调用测试用例。
    • 运行长上下文检测测试。
    • 如适用,比较拒绝响应/安全检测结果。
    • 比较p95吞吐量、TPOT值及显存使用情况。

    如果质量在约定的容差范围内且延迟优势真实存在,则可发布该模型;否则仍需保持该模型为8位格式。

    详细流程说明——以文字形式阐述白板练习的答案

    一个包含700亿个参数的fp16检查点中,仅权重部分就需要大约140吉字节的内存。每次前向传播时,每个参数每个标记的处理成本约为2次浮点运算。KV矩阵的大小与实时处理的标记数量以及实际存储的键/值单元数量成线性关系。单批解码速度取决于内存带宽除以每步处理的字节数。在词汇量较大的情况下,嵌入表和独立的语言模型单元可能各自占用数亿个参数——这并非四舍五入误差。在某个模块内部,前向传播路径的投影参数通常大约是注意力机制投影参数的两倍。

    详细解析——如何绘制准确的流程图

    在为新手绘制处理流程时,应标注出那些被省略的部分:模板、分页机制、连续批处理、预测功能以及反标记化缓冲区。否则工程师在按照流程图实现后,往往会在实际运行中遇到意外问题。

    补充说明——推理任务完成的标准

    无需借助幻灯片,你就能解释特定事件为何会对TTFT造成影响而不会影响TPOT。你可以估算在给定的并发度与上下文目标下的KV内存需求。你能明确指出哪些措施——批量处理、量化、GQA、推测机制、前缀缓存——适用于解决相应问题。你需要将分词器和模板视为具有版本号的依赖项。这就是LLM推理所需的操作素养;其余内容都是可以查阅的细节。

    案例研究——一个70B参数的交互式服务

    假设你在两块高内存容量的GPU上部署了一个70B参数的fp16格式聊天模型。仅权重部分就大约需要140吉字节的空间,因此在任何对话开始之前这两块GPU的存储就已接近满载。剩余的空闲空间必须用于存储所有正在进行的会话的KV数据、激活值以及分配器碎片。

    你设定了产品目标:16个并发用户、4000个标记的上下文长度,以及流式响应。粗略计算可知,每个标记需要几百千字节的内存,16乘以4000再乘以这个数值,结果将达到数十吉字节——这超出了剩余内存的容量。此时立即出现了几种解决方案:切换到GQA检查点、对缓存进行量化处理、降低并发用户数、缩短上下文长度,或是增加GPU。正是这样的简单计算,让“我们需要更多GPU”这种模糊的诉求变成了具体的容量规划。

    你还注意到,每当大量客户端使用相同的系统提示重新连接时,每小时初都会出现TTFT数值的激增。一旦确定了问题根源并对其进行缓存,这些峰值就会消失。如果在修改提示后仍未锁定问题根源,那么在指标面板上就会显示为模型性能下降。

    案例研究——智能体循环与缓存键

    每个回合,智能体都会发送相同的工具架构。如果该架构的 JSON 以不稳定的键顺序序列化,前缀哈希就会失效,从而导致每步都需要重新填充数千个标记。采用标准 JSON 编码便能优化推理过程。同样,将用户资料放在架构之前会破坏不同用户之间的数据共享;而将其放在之后则能保持工具核心部分的共享性。

    案例研究叙述——代码与聊天场景下的推测解码

    在代码补全接口上,基于类似数据训练的小型模型能够处理大部分标记;端到端的延迟降低了约两倍。而在开放式创意接口上,该模型的处理能力大幅下降,同样的小型模型也会浪费资源。为不同路径设置特征标志比全局启用推测模式更为有效。

    案例研究叙述——停止序列错误

    一个团队为 markdown 标记设置了停止点。一半情况下该标记为一个令牌,另一半情况下则被拆分。用户会看到结尾的反引号。修复方案通过检查解码后的文本窗口来撤销该停止范围。仅基于令牌 ID 的停止点才是根本问题所在。

    案例研究叙述——量化带来的意外

    在内存受限的解码路径上,4 位权重使令牌/秒的处理效率提升了约 40%。而工具调用相关的评估结果则下降了 3 分。折中方案是:对工具相关路径保持 8 位精度,而对长篇博客草稿使用 4 位精度。通过网关的路由机制,一个模型可以对应两种服务配置。

    实用检查清单——部署准备情况

    • [ ] 已为预填充和解码过程记录相关说明
    • [ ] 已在实际检查点上测量 KV 字节/令牌的数值
    • [ ] 并发数量与上下文预算之和需留有余量,以适应 GPU 内存容量
    • [ ] 已启用连续批处理功能,并设置了解码优先级策略
  • [ ] 前缀缓存键包含模板、分词器、LoRA及RoPE缩放参数
  • [ ] 每次响应都会记录采样元组信息
  • [ ] 对任何JSON格式的输入都进行受限解码
  • [ ] 对不完整的UTF-8数据流进行分词器反操作
  • [ ] 在标记边界处测试停止序列效果
  • [ ] 根据实际接受率决定是否启用推测解码
  • [ ] 通过特定任务评估验证量化效果
  • [ ] 张量/流水线并行方案需与实际互连结构匹配
  • 实用检查清单——故障排查

    1. TTFT或TPOT功能是否出现故障?
    2. 提示词长度或批次组成是否有变化?
    3. KV内存使用量是否接近上限?
    4. 分词器/模板版本是否有变动?
    5. 内核或量化相关标志是否发生改变?
    6. 推测解码的接受率是否较低?
    7. 当前是在带宽限制还是计算能力限制下运行?

    请按顺序处理列表中的各项;大多数“模型今日表现不佳”的问题都能在第四步得到解决。

    术语汇总

    TTFT——从请求开始到生成第一个标记所需的时间。
    TPOT / ITL——后续各标记之间的平均时间间隔。
    Prefill——并行处理提示语以填充KV缓存。
    Decode——通过自回归方式生成新标记的步骤。
    KV cache——存储过往标记对应的键值对。
    GQA——分组查询注意力机制,用于减少KV头数量。
    PagedAttention——按块分配KV资源的方式。
    Nucleus (top-p)——对概率尾部进行自适应截断的机制。
    Speculative decoding——先生成草稿再验证的加速方法。
    Roofline——将模型强度与峰值FLOPs及带宽关联起来的曲线。

    最终总结段落

    将推理过程视为一条生产线。分词器负责确定零件的存放位置,嵌入层和计算块则是加工机器,KV缓存则相当于在处理中的库存,每有一个未完成的订单就会占用仓库空间。采样则是针对每个单元的质量控制手段,流式处理则相当于货物装卸码头,而推测性解码则类似并行检测通道。如果在不考虑库存和带宽状况的情况下优化某个环节,就会导致大量未完成的工作以及愤怒的客户——尽管单独看每个环节似乎都“更快”。

    附录 — 面试中常出现的思维模型对比

    面试官常常要求你调和三个口号:“变换器是并行的”、“解码是顺序的”以及“注意力机制是二次方的”。它们在不同范畴内都是正确的。训练和预填充利用了已存在位置间的并行性。解码无法在不进行推测的情况下提前生成未来的标记。当序列长度相对于基于宽度的矩阵运算而言较大时,注意力机制中的二次项作用最为显著。一个出色的回答会在提及口号之前先说明其适用范围。

    另一个常见的陷阱是将参数数量与解码速度等同起来。参数决定了每步需要处理的字节数;而布局(GQA)、数据类型以及批量处理则决定了这些字节如何转化为标记/秒的速率。在考虑了这些因素后,两个70B模型的交互延迟可能会有两倍的差异。

    第三个陷阱是将采样视为“单纯的随机数生成”。温度参数、截断处理、惩罚机制以及各种约束都会改变分类分布;随机数生成器仅能在剩余选项中选择。要排查异常输出,首先需要记录下那个元组。

    附录 — 值得记住的最基本公式

    KV字节数 ≈ 2 × 层数 × kv_heads × head_dim × 字节数 × 序列长度 × 批次大小。 批次1解码时的计算强度 ≈ 2 × 参数数 / 权重字节数,对于密集型fp16格式约为O(1) FLOP/字节。 每次验证预期产生的推测性标记数 ≈ (1 − α^(k+1)) / (1 − α)。 Softmax函数稳定性:在取指数之前先减去最大值。 因果掩码:在被禁止的得分处填入−∞而非零。

    如果你能在白板上重新推导出这些公式并解释每个符号的含义,那你就已经超越了大多数含糊其辞的解释。

    附录 — 进一步深入学习的方向

    完成这个流程演示后,接下来的自然步骤是:在已运行的引擎中读取基于PagedAttention的分配器路径,使用厂商提供的分析工具对预填充和解码步骤进行性能分析,以及在NumPy或PyTorch中实现一个带有显式KV缓存的简单贪心解码循环,以便了解数据结构。这些练习无需完整的训练框架,就能将上述概念转化为条件反射式的操作能力。

    再深入一步——将指标与用户痛点关联起来

    当收到“人工智能响应速度太慢”的反馈时,需要对其具体原因进行分析。如果加载指示器出现在任何文本之前,应检查TTFT相关问题:提示词长度、冷启动前缀、预填充任务拥堵或缓存缺失。如果文本能快速显示但随后加载缓慢,则需排查TPOT相关问题:批次过大导致内存压力、KV内存迫使使用过小的批次、带宽受限的显卡上使用未量化的权重,或是原本有效的路径被关闭了推测功能。

    当工单上写着“周二之后答案质量变差”时,在重新训练之前,请先比较采样元组、模板哈希值以及量化标志。那些表现为性能下降的问题其实往往是智能水平下降的伪装。

    当工单上提到“它自动生成JSON”时,就别再调整温度参数了,直接采用受限解码方式。采样无法强制遵循语法规则,而掩码技术却可以。

    在容量规划会议上,如果有人能在黑板上写下三个数字——每个KV令牌所占字节数、目标并发量以及目标上下文长度,会议就会进展得更顺利。将这些数值相乘后再加上权重占用量,再与GPU内存容量进行对比。关于“AI魔法”的争论就会停止,取而代之的是实际的计算分析。

    这就是整个流程介绍的初衷:用量化指标取代未知因素,再用这些可操控的指标来推动工作。

    关于范围的总结

    这种重写方式仍属于推理流程的范畴:即在权重生成之后、客户端发送文本之前,且在运营团队开始讨论微调之前所发生的内容。训练阶段的诸多问题——数据混合、优化器选择、并行训练计划——虽然极为重要,但属于另一个讨论范畴。如果你能在压力之下牢记预填充/解码的分工、KV开销以及采样构成,那就已经具备了支撑其他相关内容讨论的基础框架。

    读者练习

    从日志中选取一个生成请求。记下其提示词token数量、输出token数量,以及已记录的TTFT/TPOT数值(如有)。根据模型各层及输出头的结构,运用每token对应的公式估算KV内存占用。判断该请求更偏向于受计算能力限制的预填充阶段,还是受带宽限制的解码阶段。指出一个能够改变你最关心的指标的优化手段——可以是前缀缓存、批量大小调整、量化处理、GQA技术或预测机制等。如果你无需再次查阅本文就能完成上述任务,那就说明重写后的内容已经达到了预期效果。

    准备一份简短的个人备忘单:预填充与解码、KV字节计算公式、TTFT与TPOT的区别以及采样顺序。在评估系统容量或指责模型存在缺陷之前先查看这份备忘单。这样的小习惯会逐渐形成可靠的直觉。