跳到主要内容

推断系统 — 每一秒都不能崩的那本账

这一章讲三件事: 为什么同一次生成要被拆成性格完全相反的两段——先算得动,再喂得快; 为什么推断系统最贵的不是模型,而是那份随对话越聊越长的一份缓存,以及把它管理起来的一整套办法; 还有服务真正上线之后的考题:请求超时了动作算不算发生了?新版本怎么换上去?高峰期怎么退而不崩?

它在全书链条里的位置:上一章是钢与硅的上半场(把模型造出来),这一章是下半场(把模型用起来)。 第 01 章留下的那道题——同样一句话,怎么让它答一次比一次便宜,便宜到一天一亿次也付得起——整章都在还这笔债; 第 11 章以后的智能体,全部站在这套运行时之上。

顶层全景:一条请求的一生

用户按下回车


┌─ 预填充 §2 ────────────────┐ 把整段输入一次性吃进模型
│ 计算密集:算力利用率 60–80% │ 决定「首字时延」(TTFT)
└────────────────────────┘

┌─ 解码 §2–§5 ───────────────┐ 一个词元一个词元往外吐
│ 访存密集:利用率仅 20–40% │ 决定「逐字时延」(TPOT)
│ 每一步都要读一遍不断变长的 │
│ KV 缓存 ← §4 它同时限制了并发 │
└────────────────────────┘

┌─ 调度层 §7 ─────────────────┐ 连续批处理:边生成边吸收新请求
│ 温度/top-p §5 · 缓存复用 §6 │ 量化/蒸馏/投机解码 §8 往下压成本
└────────────────────────┘

生产平台 §10–§14:波峰、故障、版本切换时不挂,
退也退得清楚、可追踪

图说: 一条请求从上往下穿过四层,每层的优化各管一件事: 预填充保首字、解码保流畅、调度保吞吐、平台保活着。 本章 §1 先立住一个总判断:这一切和训练共享同一套硬件,却是两本不同的账。

1. 两本账

同一个模型,同一个机房,训练和使用写的是两套差别巨大的工程账本:一套负责把模型造出来,一套负责把它供出去1。 训练赌的是几千张卡连跑几周不出大故障;使用赌的是每次用户请求在几百毫秒内吐出第一个字, 并且单位成本能压到可持续——这个量级差距,书里用一个直白的画面给了参照: 千亿参数级的模型要几千张卡连转数周,每一次中断都意味着几个小时甚至几天的计算回滚重来2

书里还配了一对气质判词:小规模实验像在本地养一只宠物,等它学会某件事; 大模型工程像经营一条连转数周的工业生产线,任何环节断掉全线停摆—— 而最容易出事的地方从来不是算法,是通信、显存、数据管线和调度这些工程细节3。 本章的主角是第二条生产线上的营业窗口:训练受限于显存和通信,推断更受限于延迟、吞吐和缓存4

还有一个身份值得记住:推断系统是个能力翻译器。 研究团队交付的是一个有本事上限的模型,用户实际拿到手的却是五件东西的组合—— 首字时间、流式速度、可承载并发、单位请求成本、故障恢复能力5。 训练贵是一次性的,推断贵是天天发生的:模型上线后,每一次请求都要触发一遍完整生成, 请求量一大,成本就从一次投入变成持续支出6。所以,推断慢一点或贵一点,不是体验问题,是这门生意成不成立的问题。

2. 预填充与解码:一次生成的两副面孔

按一下回车之后发生的事,可以精确切成两段。第一段叫预填充(prefill): 把整段提示、上下文和历史对话一次性送进模型,完成对已有上下文的编码; 第二段叫解码(decode):像续写一样,一个词元接一个词元往后生成答案7

预填充解码
干什么把你给的几千字一口气读完一个字一个字往外蹦
性格一次集中计算,天然好并行每步依赖上一步,天生串行
利用率高(通常 60%–80%)低(通常只有 20%–40%)8
卡什么矩阵乘法吞吐受访存和调度限制
用户感受「首字慢」「续写速度慢」9

为什么要分这么细?因为这两段的物理瓶颈不同到可以被拆开伺候: 预填充适合吃满大矩阵算力,解码容易被访存拖住——于是很多系统开始把两者分离部署, 甚至用不同的资源池分别承载10。这不是过度设计,后面 §3 会看到这句话的物理依据。

3. 算术强度:显卡到底在忙还是在等

第 05 章埋过一句伏笔:训练的矩阵乘法算术强度高,使用阶段却常常落在「等数据」那一段。 现在把这笔账算完,用的正是那里介绍过的 Roofline 模型(一张「算得多快 vs 搬得多快,谁先封顶」的判断尺)11

预填充阶段:一次过的是成百上千个词元,同一份模型权重被这一大批词元反复共用—— 搬一次货,够一堆人吃,算术强度高,GPU 接近满负荷运转,瓶颈是真算不动12

解码阶段:每生成一个新词元,要把整套权重外加越来越长的缓存从显存重新拉一遍; 读的数据没少多少,能换来的计算量却小得可怜——整个阶段都被钉在「等搬运」区, GPU 大部分时间在等数据搬运,电在烧,算力空着13

再把这锅粥分成两块看,一个关键的不对称就露出来了14:

  • 前馈网络部分的权重是全体请求共享的:20 个请求凑一批,权重读一次大家分摊, 人越多摊得越薄——这一块的「等搬运」可以靠凑批缓解;
  • 注意力部分每个请求只能读自己那份缓存:人再多也不能共用, 凑批救不了它,只能去压缩缓存本身。

这一个不对称,直接解释了现代推断系统的三个招牌设计(也是本章后面的路线图): 为什么连续批处理能把吞吐放大几倍(多请求分摊权重读取,救前馈那一块); 为什么分页——像操作系统切内存页那样管理——注意力缓存要从占用本身下手(注意力那一块 batch 救不了); 为什么预填充和解码越来越被分到不同的资源池上跑15。 还有一句总结值得原样记走:推断提速靠的不是把解码拉回算力区,而是在仍然等搬运的前提下尽量提高有效吞吐16

4. 缓存吃掉了并发

第 04 章末尾留下了一个未收的尾:KV 缓存为什么必须存在已经讲过(不重复算旧词), 但它怎么反过来限制「同一台机器能同时接多少人」、又怎么被当成内存精细管起来,在这里收。

先看这份缓存有多占地方。长对话如果每个新词元都重算一遍旧内容,成本根本没法接受, 所以旧的键和值算过一次就直接存下来复用——这是现代推断的地基设施17。 书里的比方很形象:像侦探小说作者手边的资料夹,每个角色线索都做成了一张张便签卡, 写新情节时不必翻旧稿,拿新线索对一对卡片就行18。但便签卡本身要占地: 显存占用有一个可以背下来的公式——层数 × 缓存头数 × 头维度 × 序列长度 × 批大小(一次同时处理几条请求),再乘 K/V 两份19。 代入书里给的典型数字(Llama 3 70B 的配置,8K 上下文):单条会话就要约 2.5GB 显存做缓存; 拉到 128K,一条就是将近 40GB——已经接近整张 H100 的一半20

这就是 §4 标题的含义:限制并发的往往不是模型多大,而是缓存随会话长度线性膨胀。 一台机器装下十份权重,却未必装得下十个聊了半小时的用户21

三招应对,各有分工:

招式做法对应哪种病
分页管理(PagedAttention)像操作系统分页那样把缓存拆成小块调度复用,不要求每条会话占连续大块显存,从而减少碎片、提高并发22显存被切得七零八落
前缀缓存许多请求共享同一段系统提示或工具说明,这段前缀的缓存 everyone 复用一份,避免重复计算23同样的开头算一万遍
压缩缓存结构MQA/GQA/MLA 这类改造把多头注意力里几十份键值折叠成少数几份,Llama 3 70B 把 64 头压成 8 个,缓存直接省 8 倍24缓存的绝对体积

第 04 章讲过 GQA 的机制,这里补上它的动机——上面这张表第三行就是它存在的理由。

还有一层书里特别点出的现实:缓存管理最终会变成服务治理问题。 会话什么时候该保留、什么时候该淘汰?留太久,显存被历史会话占满;清太狠,又频繁重算前缀拖慢响应速度25。 到这一步,KV 缓存已经不只是个数学对象,它是排队策略和成本账本的入口。

5. 解码策略:模型输出的最后一道「性格」工序

解码的最后一步是从概率分布(每个候选词各多大可能)里挑一个具体的词。这一步看似琐碎,却很大程度上决定了模型的风格: 死板还是灵动,「稳如老狗还是偶尔放飞自我」26

先把几个名字一次性认全(第 05、07 章用过其中一些,这里给全谱)27:

  • 贪心解码:每步选最高分。简单可靠,但容易复读机——万一「是的」是最可能的下一个词, 它能一直「是的、是的、是的」,对话场景里是灾难;
  • 随机采样:按分布抽签,多样但有概率抽到离谱词;
  • 温度:调分布的尖锐度的旋钮(温 0=永远挑最常见的,像字典;1 左右像诗人;更高像喝醉); 实际产品常设在 0.7 附近;
  • Top-K / Top-P:前者只在得分最高的 K 个候选里抽;后者划一条累计概率线,线内的候选数量随分布形状自动伸缩, 尖锐时少选几个、平坦时多选几个——这是当代大模型最常见的截断方式;
  • 束搜索:同时保留最可能的多条路径最后择优,翻译时代的老将,如今因产出「安全但平庸」用得越来越少。

实战标配是温度 + Top-P 组合:温度管整体的多样性,Top-P 过滤掉尾部低概率选项; 严谨任务用低温度(0.1–0.3),创意写作用高温度(0.8–1.2)。 书里点了一句容易被忽略的真相:产品预设的那个看不见的默认温度, 对用户感受到的「这个模型听话不听话」影响巨大28

这一步还和第 07 章打通:Best-of-N、自一致性这些测试时扩展方法,本质上都是在解码层多花算力换准确率—— 它们改的不是单个词怎么打分,而是怎么把很多次打分组合成一个更可靠的答案29。 推理模型把这条路推到了极致:主要体现为想得更长。到这里,第 07 章说的「推理预算从隐式变成显式参数」就有了运行时的根。

6. 结果缓存与语义缓存:命中之后还可靠吗

除了缓存模型内部状态,还可以直接缓存答案本身。 完全相同的请求再次出现时,直接返回旧输出——这对高频模板化请求是实打实的省钱手段30。 更进一步是语义缓存:不要求字面一致,只要新问题和某个历史问题语义足够接近,就把旧答案翻出来复用31

听着很美,但书里给了一段冷静的警告,值得整段抄进任何工程师脑子里: 缓存的难点从来不只是能不能命中,而是命中之后是否仍然可靠。 普通问答容忍度高;可一旦系统带着工具、权限和环境状态,用户角色变了、依赖的数据源更新了、外部环境变化了, 哪怕问题长得一模一样,旧答案也可能已经不该被复用32。 换句话说,缓存这个加速技巧,自带了一套「哪些状态可以被视为等价」的判断,判断做错,省下的就不是算力,而是在更快地传播旧错误33

所以成熟平台的姿态是:结果绑定有效期、数据版本、身份或环境快照,显式规定哪些只能当候选草稿; 书里有句反直觉的判语——只盯着命中率往上冲的平台是危险的,命中率每涨一个百分点, 都得问一句里面有多少早就该失效34。缓存该用的地方是那些被证明稳定、低风险、重复度高的子步骤, 而不是整段生成照单全收。

7. 连续批处理与调度:边吐字边接客

一个用户时,推断问题很单纯;真实流量一来,立刻变成一道调度题:请求长短不一、到达时刻随机、 吐字快慢各异,组织不好,设备就会空转,或者被个别长请求拖住35

传统深度学习服务的做法是凑批:攒够一批一起算,矩阵运算饱满。但文本生成就麻烦在每个请求结束的时刻都不一样, 新请求还在源源不断地来——硬凑批就得互相等待。现代答案是连续批处理: 不再一批算完再接下一批,而是生成过程中持续吸收新请求、结束一个释放一个36, 让设备始终保持在较高的占用水平,也不会让长请求霸住队列。 代价是新问题:短请求和长请求之间的公平性怎么办,高优先级任务来了怎么抢占,队头堵住了怎么疏通37。 这些都是经典的服务工程,只是被 KV 缓存和流式生成搅得更复杂。

顺带认识一下工具箱里的名字:vLLM 以高吞吐服务和 PagedAttention 式缓存管理著称; SGLang 强调结构化生成和复杂语言模型程序的执行;TensorRT-LLM 贴近特定硬件的高性能内核; LMDeploy 代表从压缩到部署的一体化取向38。 框架名全会过时,趋势不会:大模型推断已经从「调用模型生成文本」,长成了围绕调度、缓存、内核和服务治理的一整套系统工程39

另一条容易被忽略的主线:训练时的并行套路不能照搬。 同样是切开模型,在推断里要围绕延迟、会话状态和请求的不均匀性重新评估——不能简单把训练阶段的并行策略照搬过来40

8. 量化、蒸馏与投机解码:让模型本身更好跑

前面都在优化「同一个模型怎么跑」,这一节换个思路:让它本身变得更小、更快、更少做无用功

量化:用更少的比特表示参数甚至部分激活,直接减小显存占用和搬运压力; 代价是精度可能受损,低比特设置尤其需要细致的校准和实现。 GPTQ、AWQ 是低比特权重量化的代表路线,FP8 则在新硬件的训练和推断里越来越多见41

蒸馏:让一个小学生模型去模仿大模型的输出行为,牺牲一点能力,大幅换取速度和成本。 它的常见形态其实你已经见过:成熟产品不会把最强的模型顶在所有场景上,而是分层分流—— 小模型先承接常规请求,难活才升级给大的42。(这条线在第 14 章讲部署成本分层时会正式收口。)

投机解码:最巧妙的一种过程优化。让一个飞快的小草稿模型先猜一小段候选词元, 再由目标模型一次性并行验证43。关键约束只有一句话:草稿可以乱猜,但最终输出必须严格服从目标模型的分布—— 接受准则保证被打纳的候选不改变输出的统计性质,拒绝时按修正后的分布重采样补位, 所以正确性无损,赢的全是速度44。期望(平均意义上的)加速由三个变量决定:单 token(词元)平均接受率 α、每轮草稿长度 k、 草稿与目标的速度比 c——草稿越准、越快、越长收益越高,但 k 太大会饱和甚至回落: 大量被拒绝的候选反而拖慢节奏45。EAGLE、Medusa 这类方法做的事,本质都是让草稿更贴近目标模型的内部分布, 把 α 逼近 146

这一族技术有个共同的隐含教训,书里写得很实在:「一种优化在一套模型上的成功经验,直接平移到所有模型」是推断系统最常见的误区; 唯一稳妥的做法是针对具体模型、具体硬件、具体业务实测47。 另外注意方向性:并非所有推断优化都是为了省——测试时扩展那种「把更多计算花在更值得搜索的地方」也算推断优化, 那是第 07 章的主场48

9. 推断性能怎么量

不说清楚刻度,一切「优化」都是口头说服。这套尺子有四个刻度,各自盯一种感受49:

刻度量的什么直接受谁影响
TTFT(首字时延)发出请求到看见第一个词的时间预填充长度直接决定它
TPOT(逐字时延)进入解码后每个词元的间隔决定读完整答案的流畅感
吞吐(requests/sec、tokens/sec)单位时间完成多少请求/吐多少词元衡量硬件利用率的最直接数字
每千词元成本折旧+电力+运维折到业务可比的单位决定这门生意能不能可持续50

三组关系决定你会不会被报表骗到51:

  1. 吞吐与时延互为代价:批越大并发越高,单个请求的逐字时延越容易劣化。 所以有意义的说法永远是带条件的——「在 P99 时延不超过 500ms 的前提下,系统能跑多少 tokens/sec」, 单独报任意一项都会误导决策;
  2. 平均 ≠ 尾部:GPU 利用率上,预填充能做到 60%–80%,解码通常只有 20%–40%52; 只看均值会让你对高峰期的雪崩毫无防备;
  3. 增量解码有两个速度:没有 KV 缓存的「全量解码」每出一个词都重算全部上文,慢到基本不可用; 有缓存的「增量解码」快几个数量级,是现代系统的默认——但也从此把「首字」和「续字」拆成两个独立可调的量: 长上下文让首字变慢,缓存让续字变快。这个分离决定了对话产品和智能体的用户体验形状53

工具侧一句话带过:vLLM 自带的基准脚本能模拟不同长度、到达率和并发的请求流, 社区还有跨框架的统一口径(LLMPerf、GenAI-Perf 等)。它们的价值不在跑分, 在于让团队换模型、改量化、调参数时有同一把尺子做前后对照——没有可重复的评测,所谓优化都只是讲故事54

10. 生产级平台:考题不再是「快」,是「稳」

平时的快只及格了一半。真实的线上系统还要在波峰、故障和版本切换时依然可控55: 观测上要看的东西也跟着变多——除了利用率和时延,还有队列积压、缓存命中率、请求取消率、 结构化输出失败率、超时重试比例……因为很多线上问题的根子不在模型突然变差, 而在调度策略于某些负载模式下开始失衡;观测粒度不够,团队就只能收到一句模糊的「用户觉得变慢了」56

容灾的姿态也随之改变:成熟的推断平台不会把所有请求押在单一路径上, 高峰时切更轻的模型、结构化输出失败时回退更保守的模板、局部节点失效时优先保关键业务流量57。 看起来不如「任何时候都用最强配置」理想,但那才是真实服务世界的逻辑。 书里由此给出定位判断:大模型一旦成为基础设施,推断系统就会越来越像云服务—— 性能重要,稳定性、可观测性和容灾同样重要58

弹性伸缩也有大模型特有的难处:预热成本。扩容不只是多开机器——加载权重、建立 KV 缓存、初始化编译图都要时间; 很多系统真正难受的不是高峰本身,而是高峰刚来的冷启动那几分钟59。 于是有了冷池、温池、热池的分层管理;请求侧则按价值路由: 高价值请求走更强模型、更保守的解码和更高优先级的队列,常规请求走便宜的路径, 必要时先由轻量模型做筛分和摘要60。终局形态是:超出「一台机器托管一个模型」的朴素图景, 长成一整套为智能应用分配计算资源的运行时平台61

当多个团队共享同一个资源池,还多了租户隔离这道题。书里把病灶起了个精准的名字: 吵闹邻居——一个批量离线任务突然吃掉大量吞吐,或一个智能体因重试和递归(自己调用自己)式调用制造流量尖峰, 一视同仁地丢进同一个队列,就变成少数重负载租户拖慢所有人62。 对策是递进的:配额与限流是地基,再往上是保留容量、优先级队列和准入控制; 而且这里的优先级不只看商业价值,常与风险约束绑定——需要人工确认的任务不能无限重试, 涉及交易和权限变更的请求不该跟普通摘要共用调度规则63。 隔离还有一层意思:故障边界必须清晰,一个租户的失控重试要被困在自己的资源范围内64。 这层设计的尽头是个哲学问题,书里问得很准:当计算有限时,凭什么把这一次推断机会给这个请求,而不是另一个65

回到成本与体验的总权衡。首字时间、吞吐、单位成本、稳定性,这几把刻度并不总能同时最优; 聊天在意首字时间和顺滑感,离线批量在意单位成本和总吞吐,企业工作流(企业内固定流程)还得加上审计66。 「推断优化」从来没有放之四海皆准的终极方案,只有针对具体业务目标的取舍67。 成熟的分层推断就此成型:简单请求走便宜路径,复杂请求升级强模型;高价值场景允许更长等待换更多搜索; 低价值场景优先锁成本68。最后一句忠告式判断留给你品味:一个模型能否真正改变产业, 既看它在榜单上排第几,也看它能否在现实预算、现实时延和现实并发里活下来69

11. 会话粘性与中断恢复:智能体带来的新约束

普通问答一问一答就结束,智能体不行:它围绕同一个会话反复调用模型、工具和外部环境, 于是推断平台多回答一个问题——下一次推断,是不是最好仍落在理解当前状态的那台机器上? 这就是会话粘性:频繁跳机器虽然全局看灵活,却不断丢失局部缓存和前缀状态,把时延和成本双双推高; 对长任务和多轮工具调用来说,稳定的会话落点往往比单次最优调度更有价值70

但粘性不等于把状态焊死在一台机器上。节点会缩容、会失效、会被抢占,长任务的寿命超过单台实例—— 所以平台还得回答:哪些状态值得迁移,哪些更适合重建。书里给了一个四分的拆法, 值得所有做智能体的人抄走:状态不是一个笼统的上下文团块, 而要拆成可缓存、可迁移、可重建、可丢弃的不同层次——部分前缀缓存可以跨节点复用, 工具调用历史应放进独立的状态层,短暂的中间张量不值得远程搬运71

最后一块拼图是中断恢复。智能体任务随时可能在「模型生成到一半、工具还没返回、外部接口超时、人工审批还没结束」时被打断; 没有恢复机制,就只能整条链从头再跑——既浪费,还会改变任务轨迹。 稳妥的做法是给长任务设检查点和恢复语义:哪些中间产物已可信、哪些步骤可直接重放、哪些需要重新确认72。 这套机制决定了系统遇到网络抖动时是优雅续跑,还是把每一次抖动都放大成一次完整失败73。 推到极致就是书里那句定位:推断平台服务的早已不只是文本生成请求,而是带着生命周期和状态演化的任务执行过程74

12. 超时、取消与重试:失败也要有明确的语义

传统问答接口里,超时只意味着「这次回答没返回」。智能体场景全变了: 请求超时≠动作没生效。一个 agent(智能体)可能已经发起了外部调用——模型响应超时并不等于那件事没有发生; 用户取消了,也不代表所有子任务都停了;平台自动重试,更不能默认重试是无副作用的75

书里给的解法是把动作事先分类,对不同类别给出不同的失败语义76:

动作类别超时/失败后怎么办
纯推断、只读查询重试代价低,放心重试
幂等写入(做两次也无害)用请求标识或事务(一笔要么全成、要么全不算的完整操作)语义保证不重复生效
非幂等写入(付款、发单)「是否允许自动重试」必须是显式的策略项,不许交给默认中间件

「幂等」这个词值得当场讲透:指同一个操作执行一次和执行多次,效果相同—— 比如「把头像设置为 X」天然幂等,「余额减 100」就不幂等。分类的目的, 是把失败处理从「网络层的肌肉记忆」提升为「任务语义的一部分」77

取消也分三层,缺一层就会出鬼:前台取消只停止界面等待;后台终止尝试停掉尚未完成的子任务; 结果作废标记那些虽然已完成、但不该继续向后传递的中间结果78。 很多系统只做了第一层——界面上点了「停止」,后台的工具调用还在悄悄推进,这是真实发生过无数次的坑。 合起来,衡量标准变成:任务是否始终处于一个可解释、可恢复、可回滚的状态机中; 真正可靠的系统未必从不超时,而是超时发生后仍然知道任务走到了哪、哪些动作已生效、下一步该怎么安全接上79

13. 灰度发布、版本切换与容量预案

线上那个「同一个模型名」,底层可能早换了权重、换了编译版本、换了缓存布局——版本切换每天都在发生, 它是推断平台的常规手术而非偶发事件80

发布姿势是教科书式的三段:先在影子环境比较延迟、错误率和输出差异,再逐步扩大到小比例流量、特定租户, 最后才进主路径81。之所以必须渐进而非一刀切,是因为推断系统的退化往往不表现为崩溃, 而表现为长上下文的尾部延迟悄悄上升、某类请求的缓存忽然失效、某些工具调用前后格式偏移—— 这类慢性病只有灰度的小流量才来得及暴露82

切换本身比想象中难:新旧版本之间可能不共享同样的缓存格式、会话状态和工具调用习惯; 会话进行到一半被切到新版本,可能丢掉前缀收益,甚至在动作语义上出现细微偏移。 所以平台要明确区分:哪些任务可以无缝切,哪些必须「粘」在同一版本直到完成,哪些高风险任务在切换窗口内应当延后83

最后是最容易被低估的一环:容量预案决定回退能不能落地。 很多系统不是没有回退开关,而是回退瞬间没有足够预热的容量接流量, 「理论上可回退」在真故障时变成了更大的一坨拥塞84。 书里给的标准配置:关键版本保留最小可用热备,提前估算峰值回滚流量,把路由、缓存、配额一起纳入演练—— 能让系统在前进和后退两个方向上都维持秩序的,才算接近生产级基础设施85

14. 降级路径:退也要退得清楚

最优路径总有不可用的时候:高峰、局部故障、外部依赖超时。成熟平台的标志, 是在压力下退而不崩——而且这套退路必须在故障来临之前就设计好,属于架构的一部分,不是临场发挥86

可以退的方式很多:切更小的模型、缩短上下文、减少搜索深度、关闭昂贵的重排(把候选答案重新排一次序的)部件、改走缓存或规则模板; 高风险任务则宁可延迟排队、返回「稍后再试」,也不该在不满足条件时悄悄降质执行87。 关键是事后可查:系统为何降级、降到了哪一层、哪些能力被关闭、哪些结果因此只能视作候选——优雅退化绝不能演变成隐蔽退化, 否则排障和责任归因都会变成罗生门88。 书里的结语放在这里刚好:「即使退,也要退得清楚、退得可追踪」,这件事比单次极限性能更重要89

至此,训练与推断的两本账都翻完了。下一章开始换主角: 模型不再是被伺候的对象,而被嵌进一个会观察、会行动、会反馈的闭环里——智能体登场。

主走查:一份 8000 词元的报告,从回车到摘要

这条走查贯穿本章。 场景:你上传了一份约 8000 词元的项目报告,说「帮我总结成三点」。 凡我编的演示数,当场标明;书中给出的数注明出处。

① 预填充:一口气读完。(§2–§3) 8000 个词元的提示一次性进入模型,所有权重被这批词元反复共用——这一段 GPU 忙碌得很, 利用率冲到六成以上(区间来自书里);假设这段在我们示例服务上耗时 0.9 秒(此数为演示编的)。 它就是你按下回车之后那句沉默的全部内容:首字时延主要由预填充长度决定90

② 缓存:报告被「记住」的代价。(§4) 读完的报告以 KV 缓存的形式留在显存里。用书里的公式和 Llama 3 70B 典型配置代入, 8K 长度单条会话约占 2.5GB91;如果你接着追问三轮、上下文涨到 32K, 这份缓存就涨到四倍左右(倍数为线性公式的演示推演)。 同一张卡本来还能接待下一个用户,现在它的余量为负——这就是「缓存吃掉并发」的字面意思。

③ 解码:一个字一个字往外蹦。(§2–§5) 摘要逐词元生成,每一步都要带着当前这份查询去匹配 ② 留下的旧缓存, 并把整套权重从显存再拉一遍。利用率跌到两到四成(区间来自书里)92; 设 TPOT 为 30ms/词元(演示编的),500 词元的摘要再花 15 秒。 温度 0.7、Top-P 截断在背后默默工作着——你的三点式摘要是「稳」出来的,不是抽签抽出来的(§5)。

④ 排队:你不是一个人在战斗。(§7) 服务端此刻正用连续批处理同时伺候另外 19 个请求(并发放大为演示设定): 大家共享同一份权重读取,各自的缓存互不干扰,先完成的先退出,新请求随时插进来。 weights 一读多用,这就是 §3 那个不对称里「前馈靠凑批省钱」的直接兑现。

⑤ 出事与自救。(§11–§12) 第 12 个请求调用了外部检索接口,3 秒未归触发超时。因为是只读查询,平台选择安全重试(§12 的第一行表); 若是「提交订单」类的非幂等写入,重试决策就必须走显式策略而不是默认重试。 这个会话从始至终粘在同一台节点上——长任务下,稳定的落点比每次挑当下最快的机器更省(§11)。

⑥ 高峰到来。(§10 §14) 晚八点,流量冲上峰值的 120%(演示设定)。平台按预案行动: 新请求的摘要任务改走更轻的小模型路径、检索深度降低、重排序器关闭—— 这些是预先规划的降级档位,而不是临时抱佛脚;日志里如实记录「因何降级、降到哪层」, 第二天早上的复盘有一整条可追踪的痕迹(§14)。

⑦ 收尾算钱。(§9) 这条请求全程:预填充 0.9s + 解码 15s + 排队等待,端到端约 17 秒(合成演示数); 落到报表上是 TTFT 0.9s、TPOT 30ms、约 1.4 万个词元的处理量(输入+输出+开销,演示口径)。 把这十七秒乘以每天一亿次的提问——第 01 章那道「一次不多,一天一亿次」的题,答案就是本章: 把每一段都抠到更便宜,是唯一让它成立的办法。

作者的判断与证据

书里给出明确依据的地方:

  • Llama 3 70B 配置下 8K 会话 2.5GB、128K 近 40GB 的缓存账,是书里公式加公开配置算出的具体数字91;
  • 预填充利用率 60%–80%、解码 20%–40%,书里给的是经验区间,并在能耗一节重申为普遍现象892;
  • 投机解码的三条公式(接受、重采样、期望加速),书里给了完整的推导——这在通识书里相当罕见4445;
  • 各推断框架的分工(vLLM/SGLang/TensorRT-LLM/LMDeploy)是书里点名归纳的现状描述38

书里标成判断或立场的地方:

  • 「推断提速靠的不是把解码拉回算力区」——作者的工程哲学式总结,有 Roofline 论证支撑,但没有对应某一篇论文16;
  • 「只盯着命中率往上冲的平台是危险的」「缓存并非越激进越好」——作者的判断,理由给得很足(等价性判断),但无实证数据34;
  • 「大模型推断已长成一整套系统工程」——作者的行业判断,由框架格局间接支撑39;
  • 「平台上线的真正考题是波峰、故障、版本切换」——经验之谈,属于可辩驳但难以被事实推翻——术语叫证伪——的领域共识55

判断(我们的,不是书里的): 这一章的 14 节其实只讲了一句话——推断系统正在把「操作系统课」重修一遍。 分页内存(PagedAttention)、进程调度(连续批处理)、多租户隔离与配额、容灾降级、 甚至事务语义(幂等与取消三层),全是四十年前操作系统解决过的老问题换了主角重来。 判断的实用含义:学推断系统最好的教材清单之一,是任何一本经典的操作系统教材。 如果错,会错在: 大模型负载的「状态随对话无限增长」和「每步都要重读全部状态」这两个特性, 是传统进程所没有的——若这两点持续主导优化空间,那么新的解法会更接近数据库和存储系统, 而不是操作系统。书里 PagedAttention 恰恰借的是分页的形,MQA 借的是压缩的魂,两边都有影子。

边界与局限

  • 结构与原书的对应: 本章对应原书第 6 章后半(6.3–6.4)。原书第 6 章前半的训练系统并入了本书第 09 章;这是审读后定下的切分,不是原书结构。
  • 没有覆盖的: 原书 6.3.6「并行、编译与算子优化」我们只收了两句(§7 末段);推测解码的完整公式证明(为何严格保持分布)书里也给了一版,本文只讲了直觉,想看推导请翻原文;CUDA 图、FP8 内核细节未提。
  • 所有示例数字(TTFT 0.9 秒、TPOT 30ms、19 个并发、峰值 120%)都是为演示编的,不是任何真实产品的测量值;书内区间(60–80%/20–40%)才是引用来源。
  • 时效性: vLLM/SGLang 等框架的具体特性描述截至成书;解码策略一章没有涉及更新的束控制方法。
  • 一处呼应缺口主动声明: 第 04 章脚注引过这条缓存显存公式的出处;公式全文与代入样例在本章 §4 收全,两处引用指向原文同一段(text/07-ch06.txt 公式所在行),阅读顺序上无论先读哪章都不会断链。

可带走的

  1. 一次生成 = 预填充(吃算力)+ 解码(等搬运),解码阶段的显卡大半时间在等数据搬运——两段瓶颈不同到可以拆到不同机器上跑,优化的主战场是搬运,不是算式。
  2. 凑批能救共享的权重读取,救不了每请求私有的缓存——这一条不对称解释了大半个推断系统设计史。
  3. 限制并发的常常是缓存,不是模型——8K 会话 2.5GB、128K 快到 40GB(70B 级配置);缓存管理即服务治理,何时保留、何时淘汰是产品级决策。
  4. 温度 + Top-P 是事实标准的解码组合;产品的默认温度深刻影响「这个模型听不听话」的观感。
  5. 结果缓存和语义缓存的命门是「命中之后是否仍然可靠」——等价性判断错了,就是在更快传播旧错误。
  6. 投机解码的正确性来自接受准则:草稿随便猜,输出分布严丝合缝;α 越高赚得越多,k 过长反而亏。
  7. 没有条件的「更快」没有意义:合格的话术永远是「P99 不超过 X 的前提下,吞吐多少」;判断一个模型产业的成败也别只看榜单——看它在现实预算、现实时延、现实并发里活不活得下来。
  8. 增量解码把「首字」和「续字」拆成两个独立旋钮——它们的分离形状就是对话产品的体验形状。
  9. 超时≠没生效:动作要先分类(纯推断/只读/幂等写/非幂等写),失败语义跟着类别走。
  10. 降级必须在故障之前规划好,而且退得清楚、可追踪——隐蔽退化比宕机更腐蚀信任。

原文地图

主题原书节原文位置
两本账6 引言text/07-ch06.txt:6(搜「连跑几周不出大故障」) · text/07-ch06.txt:7(搜「几百毫秒内吐出第一个字」)
中断即回滚6 引言text/07-ch06.txt:15(搜「回滚重来」)
宠物与生产线6 引言text/07-ch06.txt:19(搜「训练一只宠物」) · text/07-ch06.txt:20(搜「工业生产线」) · text/07-ch06.txt:22(搜「“工程细节”」)
推断的定位6.3 引言text/07-ch06.txt:345(搜「训练受限于显存和通信」) · text/07-ch06.txt:346(搜「更受限于延迟、吞吐和缓存」)
能力翻译器6.3.1text/07-ch06.txt:364(搜「首字时间、流式速度」) · text/07-ch06.txt:360(搜「真正长期烧钱的往往是推断」)
预填充与解码定义6.3.2text/07-ch06.txt:372(搜「一次性送进模型」) · text/07-ch06.txt:374(搜「token 地往后生成答案」)
两段瓶颈6.3.2text/07-ch06.txt:375(搜「预填充更像一次集中计算」) · text/07-ch06.txt:376(搜「受访存和调度限制」) · text/07-ch06.txt:377(搜「“首字慢”和“续写速度慢”」)
分离部署6.3.2text/07-ch06.txt:383(搜「吃满大矩阵算力」) · text/07-ch06.txt:384(搜「两者分离部署」)
Roofline 适用6.3.2text/07-ch06.txt:389(搜「Roofline 模型在这里非常直接地适用」)
权重共享 vs 自有缓存6.3.2text/07-ch06.txt:394(搜「MLP 部分的权重在多个并发请求间是共」) · text/07-ch06.txt:400(搜「只能从 cache 占用本身下手」)
三大设计解释6.3.2text/07-ch06.txt:397(搜「连续批处理」)
提速的本质6.3.2text/07-ch06.txt:402(搜「把解码重新拽回」)
KV 复用地基6.3.3text/07-ch06.txt:444(搜「把之前所有内容重新计算一遍」) · text/07-ch06.txt:446(搜「几乎是现代大模型推断的基础设施」)
侦探资料夹6.3.3text/07-ch06.txt:448(搜「写侦探小说时的资料夹」) · text/07-ch06.txt:449(搜「旧索引卡」)
缓存显存公式6.3.3text/07-ch06.txt:474(搜「bytes_per_elem」) · text/07-ch06.txt:478(搜「大约要2.5 GB显存」) · text/07-ch06.txt:479(搜「接近整张 H100 80 GB 的一半」)
GQA 省八倍6.3.3text/07-ch06.txt:485(搜「cache 直接省8 倍」)
PagedAttention 与前缀复用6.3.3text/07-ch06.txt:490(搜「很有代表性的思想」) · text/07-ch06.txt:491(搜「占据连续大块显存」) · text/07-ch06.txt:493(搜「系统提示、工具说明或检索上下文」)
淘汰策略与治理化6.3.3text/07-ch06.txt:495(搜「什么时候该保留」) · text/07-ch06.txt:498(搜「服务治理问题」)
结果缓存与语义缓存6.3.4text/07-ch06.txt:501(搜「缓存“结果本身”」) · text/07-ch06.txt:502(搜「最直接的方式是结果缓存」) · text/07-ch06.txt:505(搜「语义上是否已经足够接近某个历」)
命中可靠性与等价判断6.3.4text/07-ch06.txt:510(搜「命中之后是否仍然可靠」) · text/07-ch06.txt:514(搜「被视为等价」) · text/07-ch06.txt:515(搜「更快地传播出去」)
危险的高命中率6.3.4text/07-ch06.txt:520(搜「往上冲的平台是危险的」)
凑批与连续批处理6.3.5text/07-ch06.txt:528(搜「凑成一个批次一起算」) · text/07-ch06.txt:530(搜「持续接纳和移除请求」) · text/07-ch06.txt:536(搜「一批请求算完再接下一批」)
公平性与头部阻塞6.3.5text/07-ch06.txt:538(搜「公平性」) · text/07-ch06.txt:538(搜「头部阻塞」)
四家推断框架6.3.5text/07-ch06.txt:541(搜「vLLM、SGLang、TensorRT-LLM、LMDeploy」) · text/07-ch06.txt:542(搜「代表性特征是高吞吐服务」)
系统工程定性6.3.5text/07-ch06.txt:549(搜「一整套系统工程」)
不能照搬训练并行6.3.6text/07-ch06.txt:563(搜「照搬过来」)
量化与蒸馏6.3.7text/07-ch06.txt:569(搜「更少的比特数表示参数」) · text/07-ch06.txt:572(搜「学生模型去模仿」) · text/07-ch06.txt:574(搜「模型分层、任务分流」)
投机解码与接受约束6.3.7text/07-ch06.txt:576(搜「草稿模型先预测一小段候选 token」) · text/07-ch06.txt:580(搜「草稿可以乱猜」) · text/07-ch06.txt:589(搜「与目标模型完全一致」)
加速的形状6.3.7text/07-ch06.txt:600(搜「平均接受率」) · text/07-ch06.txt:603(搜「先升后趋平甚至下滑」) · text/07-ch06.txt:604(搜「EAGLE、Medusa」)
量化路线与误区6.3.7text/07-ch06.txt:606(搜「GPTQ 和 AWQ」) · text/07-ch06.txt:613(搜「最常见的误区之一」) · text/07-ch06.txt:614(搜「目标做实测」)
测试时扩展的呼应6.3.7text/07-ch06.txt:617(搜「更值得搜索的地方」)
三类时延指标6.3.7.1text/07-ch06.txt:627(搜「看到第一个词的时间」) · text/07-ch06.txt:631(搜「Time per Output Token」) · text/07-ch06.txt:633(搜「end-to-end latency」)
吞吐与 P99 口径6.3.7.1text/07-ch06.txt:646(搜「批越大、并发越高」) · text/07-ch06.txt:648(搜「误导决策」)
利用率与命中率与单位成本6.3.7.1text/07-ch06.txt:651(搜「60%–80%」) · text/07-ch06.txt:652(搜「20%–40%」) · text/07-ch06.txt:653(搜「缓存命中率:前缀缓存」) · text/07-ch06.txt:654(搜「cost per 1K tokens」)
全量与增量解码6.3.7.1text/07-ch06.txt:658(搜「差几个数量级」) · text/07-ch06.txt:660(搜「决定了用户体验的形状」)
评测工具6.3.7.1text/07-ch06.txt:661(搜「benchmark 脚本可以模拟」) · text/07-ch06.txt:666(搜「都只是讲故事」)
波峰故障版本切换6.4.1text/07-ch06.txt:677(搜「波峰、故障和版本切换时依然可控」)
观测指标扩展6.4.1text/07-ch06.txt:683(搜「结构化输出失败率」) · text/07-ch06.txt:684(搜「负载模式下开始失衡」)
容灾与降级策略6.4.1text/07-ch06.txt:688(搜「高峰时切换到更轻模型」) · text/07-ch06.txt:694(搜「越来越像云服务」)
冷启动与池化分层6.4.2text/07-ch06.txt:701(搜「明显的预热成本」) · text/07-ch06.txt:704(搜「冷池、温池和热池」)
请求价值路由6.4.2text/07-ch06.txt:706(搜「高价值请求可以走更强模型」) · text/07-ch06.txt:707(搜「轻量模型做筛分」)
运行时平台的终局6.4.2text/07-ch06.txt:709(搜「一台机器托管一个模型」) · text/07-ch06.txt:715(搜「分配计算资源」)
吵闹邻居与配额6.4.3text/07-ch06.txt:722(搜「吵闹邻居」) · text/07-ch06.txt:724(搜「配额与限流」) · text/07-ch06.txt:726(搜「准入控制」)
故障边界与机会分配6.4.3text/07-ch06.txt:730(搜「故障边界必须清晰」) · text/07-ch06.txt:733(搜「这一次推断机会给这个」)
成本权衡与场景6.4.4text/07-ch06.txt:739(搜「并不总能同时最优」) · text/07-ch06.txt:742(搜「更在意首字时间」) · text/07-ch06.txt:745(搜「放之四海而皆准的终极方案」)
活下来6.4.4text/07-ch06.txt:752(搜「现实预算、现实时延和现实并发里活下来」) · text/07-ch06.txt:753(搜「简单请求交给更便宜、更快的路径」) · text/07-ch06.txt:756(搜「面向业务目标的系统分层能力」)
会话粘性6.4.5text/07-ch06.txt:758(搜「会话粘性、状态迁移与中断恢复」) · text/07-ch06.txt:764(搜「稳定的会话落点往往比单次最优调度更有价值」)
状态四分法6.4.5text/07-ch06.txt:766(搜「抢占,长任务也可能跨越比单次实例」) · text/07-ch06.txt:771(搜「可重建和可丢弃」)
中断恢复6.4.5text/07-ch06.txt:772(搜「工具结果尚未」) · text/07-ch06.txt:775(搜「可直接重放」) · text/07-ch06.txt:777(搜「放大成一次完整失败」) · text/07-ch06.txt:779(搜「生命周期和状态演化」)
超时语义6.4.6text/07-ch06.txt:786(搜「这次回答没有返回」) · text/07-ch06.txt:787(搜「响应超时并不等于」)
动作四分类6.4.6text/07-ch06.txt:790(搜「纯推断、只读查询、幂等写入、非幂等写入」) · text/07-ch06.txt:792(搜「事务语义避免重复生效」)
取消三层6.4.6text/07-ch06.txt:796(搜「停止继续输出文本」) · text/07-ch06.txt:797(搜「前台取消、后台终止和」) · text/07-ch06.txt:798(搜「结果作废三层」)
状态机判据6.4.6text/07-ch06.txt:802(搜「可解释、可恢复、可回滚的状态机」)
影子与灰度6.4.7text/07-ch06.txt:814(搜「影子环境里比较延迟」) · text/07-ch06.txt:816(搜「长上下文尾延迟上升」)
版本切换难点6.4.7text/07-ch06.txt:819(搜「缓存格式、会话状态、量化约束」) · text/07-ch06.txt:758(搜「“粘”在同一版本直到完成」)
回退容量6.4.7text/07-ch06.txt:827(搜「理论上可回退」) · text/07-ch06.txt:828(搜「最小可用热备」) · text/07-ch06.txt:829(搜「版本前进和版本后退」)
退而不崩6.4.8text/07-ch06.txt:837(搜「退而不崩」) · text/07-ch06.txt:840(搜「关闭昂贵的重排序器」)
隐蔽退化6.4.8text/07-ch06.txt:843(搜「二元关系」) · text/07-ch06.txt:845(搜「不能演变成隐蔽退化」) · text/07-ch06.txt:847(搜「系统为何降级、降到了哪一层」) · text/07-ch06.txt:849(搜「退得清楚、退得可追踪」)

Footnotes

  1. 出处:「第6章」引言第 3 段(text/07-ch06.txt:3,搜「两套差别巨大的工程系统」)。

  2. 出处:引言第 6 段(text/07-ch06.txt:6,搜「连跑几周不出大故障」)与第 7 段(text/07-ch06.txt:7,搜「几百毫秒内吐出第一个字」)、第 15 段(text/07-ch06.txt:15,搜「回滚重来」)。

  3. 出处:引言第 19 段(text/07-ch06.txt:19,搜「训练一只宠物」)、第 20 段(text/07-ch06.txt:20,搜「工业生产线」)、第 22 段(text/07-ch06.txt:22,搜「“工程细节”」)。

  4. 出处:「6.3」引言第 345 段(text/07-ch06.txt:345,搜「训练受限于显存和通信」)与第 346 段(text/07-ch06.txt:346,搜「更受限于延迟、吞吐和缓存」)。

  5. 出处:「6.3.1」第 364 段(text/07-ch06.txt:364,搜「首字时间、流式速度」)。

  6. 出处:第 360 段(text/07-ch06.txt:360,搜「真正长期烧钱的往往是推断」)。

  7. 出处:「6.3.2」第 372 段(text/07-ch06.txt:372,搜「一次性送进模型」)与第 374 段(text/07-ch06.txt:374,搜「token 地往后生成答案」)。

  8. 利用率区间「预填充阶段往往能达到 60%–80%,解码阶段因为访存瓶颈通常只有 20%–40%」出自评测一节:text/07-ch06.txt:651(搜「60%–80%」)与 text/07-ch06.txt:652(搜「20%–40%」);能效一节给了同样的区间(text/10-ch09-9-gpu.txt:395,搜「20–40%」)。 2

  9. 出处:第 377 段(text/07-ch06.txt:377,搜「“首字慢”和“续写速度慢”」)。

  10. 出处:第 383 段(text/07-ch06.txt:383,搜「吃满大矩阵算力」)与第 384 段(text/07-ch06.txt:384,搜「两者分离部署」)。

  11. 出处:「从算术强度看预填充与解码」第 389 段(text/07-ch06.txt:389,搜「Roofline 模型在这里非常直接地适用」);「算术强度」概念在第 04 章第一次出现时的解释见第 05 章 §9 的铺垫与本组拆解第 05 章。

  12. 出处:第 390 段(text/07-ch06.txt:390,搜「共同使用,算术强」)。

  13. 出处:第 393 至 394 段(text/07-ch06.txt:394,搜「大部分时间在等数据搬运」)。

  14. 出处:第 394 段(text/07-ch06.txt:394,搜「MLP 部分的权重在多个并发请求间是共」)与第 396 段(text/07-ch06.txt:396,搜「batch 增大并不能直接帮上忙」)。

  15. 出处:第 397 至 400 段(text/07-ch06.txt:397,搜「连续批处理」)与第 400 段(text/07-ch06.txt:400,搜「只能从 cache 占用本身下手」)。

  16. 出处:第 402 段(text/07-ch06.txt:402,搜「把解码重新拽回」)。 2

  17. 出处:「6.3.3」第 444 段(text/07-ch06.txt:444,搜「把之前所有内容重新计算一遍」)与第 446 段(text/07-ch06.txt:446,搜「几乎是现代大模型推断的基础设施」)。

  18. 出处:第 448 段(text/07-ch06.txt:448,搜「写侦探小说时的资料夹」)与第 449 段(text/07-ch06.txt:449,搜「旧索引卡」)。

  19. 出处:第 474 段公式(text/07-ch06.txt:474,搜「bytes_per_elem」)与第 477 段符号说明(text/07-ch06.txt:476,搜「层数、𝑛kv_heads」)。

  20. 出处:第 478 段(text/07-ch06.txt:478,搜「大约要2.5 GB显存」)与第 479 段(text/07-ch06.txt:479,搜「接近整张 H100 80 GB 的一半」)。

  21. 这个推论的书内依据是「它直接限制了同一台机器上能同时承载多少会话」(text/07-ch06.txt:471,搜「承载多少会话」)。

  22. 出处:第 490 段(text/07-ch06.txt:490,搜「很有代表性的思想」)与第 491 段(text/07-ch06.txt:491,搜「占据连续大块显存」)。

  23. 出处:第 493 段(text/07-ch06.txt:493,搜「系统提示、工具说明或检索上下文」)。

  24. 出处:第 485 段(text/07-ch06.txt:485,搜「cache 直接省8 倍」)与第 485 段(text/07-ch06.txt:485,搜「GQA 或 MLA」)。

  25. 出处:第 495 段(text/07-ch06.txt:495,搜「什么时候该保留」)与第 498 段(text/07-ch06.txt:498,搜「服务治理问题」)。

  26. 出处:「6.3.2.1」第 407 段(text/07-ch06.txt:407,搜「老狗还是偶尔放飞自我」)。

  27. 六种策略的定义在第 412 至 431 段(text/07-ch06.txt:412,搜「贪心解码(Greedy Decoding)」;text/07-ch06.txt:418,搜「Temperature」;text/07-ch06.txt:422,搜「Top-K 采样」;text/07-ch06.txt:424,搜「Nucleus Sampling」;text/07-ch06.txt:429,搜「Beam Search」)。

  28. 出处:第 433 至 436 段(text/07-ch06.txt:433,搜「温度 + Top-P」)与第 435 段(text/07-ch06.txt:435,搜「听话不听话」)。

  29. 出处:第 437 至 438 段(text/07-ch06.txt:437,搜「解码策略和推断优化是耦合的」)。

  30. 出处:「6.3.4」第 501 段(text/07-ch06.txt:501,搜「缓存“结果本身”」)与第 502 段(text/07-ch06.txt:502,搜「最直接的方式是结果缓存」)。

  31. 出处:第 505 段(text/07-ch06.txt:505,搜「语义上是否已经足够接近某个历」)。

  32. 出处:第 510 段(text/07-ch06.txt:510,搜「命中之后是否仍然可靠」)与第 512 段(text/07-ch06.txt:512,搜「依赖的数据源更新了」)。

  33. 出处:第 514 段(text/07-ch06.txt:514,搜「被视为等价」)与第 515 段(text/07-ch06.txt:515,搜「更快地传播出去」)。

  34. 出处:第 520 段(text/07-ch06.txt:520,搜「往上冲的平台是危险的」)。 2

  35. 出处:「6.3.5」第 527 段(text/07-ch06.txt:527,搜「绕不开的议题」)。

  36. 出处:第 528 段(text/07-ch06.txt:528,搜「凑成一个批次一起算」)与第 536 段(text/07-ch06.txt:536,搜「一批请求算完再接下一批」)。

  37. 出处:第 538 段(text/07-ch06.txt:538,搜「公平性」)与 text/07-ch06.txt:539(搜「抢占」)。

  38. 出处:第 541 段(text/07-ch06.txt:541,搜「vLLM、SGLang、TensorRT-LLM、LMDeploy」)与第 542 段(text/07-ch06.txt:542,搜「代表性特征是高吞吐服务」)、第 544 段(text/07-ch06.txt:544,搜「高性能内核和部署流水线」)。 2

  39. 出处:第 549 段(text/07-ch06.txt:549,搜「一整套系统工程」)。 2

  40. 出处:「6.3.6」第 563 段(text/07-ch06.txt:563,搜「照搬过来」)。

  41. 出处:「6.3.7」第 569 段(text/07-ch06.txt:569,搜「更少的比特数表示参数」)、第 571 段(搜「校准和实现」)、第 606 段(text/07-ch06.txt:606,搜「GPTQ 和 AWQ」)、第 607 段(text/07-ch06.txt:607,搜「FP8 则更多出现」)。

  42. 出处:第 572 段(text/07-ch06.txt:572,搜「学生模型去模仿」)与第 574 段(text/07-ch06.txt:574,搜「模型分层、任务分流」)。

  43. 出处:第 576 段(text/07-ch06.txt:576,搜「草稿模型先预测一小段候选 token」)。

  44. 出处:第 580 段(text/07-ch06.txt:580,搜「草稿可以乱猜」)、第 584 至 586 段接受公式(text/07-ch06.txt:585,搜「min(1,」)、第 589 段(text/07-ch06.txt:589,搜「与目标模型完全一致」)。 2

  45. 出处:第 600 段(text/07-ch06.txt:600,搜「平均接受率」)与第 603 段(text/07-ch06.txt:603,搜「先升后趋平甚至下滑」)。 2

  46. 出处:第 604 段(text/07-ch06.txt:604,搜「EAGLE、Medusa」)。

  47. 出处:第 613 段(text/07-ch06.txt:613,搜「最常见的误区之一」)与第 614 段(text/07-ch06.txt:614,搜「目标做实测」)。

  48. 出处:第 617 段(text/07-ch06.txt:617,搜「更值得搜索的地方」)。

  49. 出处:「6.3.7.1」第 627 段(text/07-ch06.txt:627,搜「看到第一个词的时间」)、第 631 段(text/07-ch06.txt:631,搜「Time per Output Token」)、第 641 段(搜「tokens/sec,aggregate」)、第 654 段(text/07-ch06.txt:654,搜「cost per 1K tokens」)。

  50. 同上第 654 段;「落到业务可比的成本单位」为其原话片段(搜「落到业务可比的」)。

  51. 出处:第 646 段(text/07-ch06.txt:646,搜「批越大、并发越高」)与第 648 段(text/07-ch06.txt:648,搜「误导决策」)。

  52. 出处:第 651 段(text/07-ch06.txt:651,搜「60%–80%」)与第 652 段(text/07-ch06.txt:652,搜「20%–40%」)。

  53. 出处:第 658 段(text/07-ch06.txt:658,搜「差几个数量级」)与第 660 段(text/07-ch06.txt:660,搜「决定了用户体验的形状」)。

  54. 出处:第 661 段(text/07-ch06.txt:661,搜「benchmark 脚本可以模拟」)、第 663 段(text/07-ch06.txt:663,搜「LLMPerf」)、第 666 段(text/07-ch06.txt:666,搜「都只是讲故事」)。

  55. 出处:「6.4.1」第 677 段(text/07-ch06.txt:677,搜「波峰、故障和版本切换时依然可控」)。 2

  56. 出处:第 683 段(text/07-ch06.txt:683,搜「结构化输出失败率」)与第 684 段(text/07-ch06.txt:684,搜「负载模式下开始失衡」)。

  57. 出处:第 688 段(text/07-ch06.txt:688,搜「高峰时切换到更轻模型」)。

  58. 出处:第 694 段(text/07-ch06.txt:694,搜「越来越像云服务」)。

  59. 出处:「6.4.2」第 701 段(text/07-ch06.txt:701,搜「明显的预热成本」)。

  60. 出处:第 704 段(text/07-ch06.txt:704,搜「冷池、温池和热池」)、第 706 段(text/07-ch06.txt:706,搜「高价值请求可以走更强模型」)、第 707 段(text/07-ch06.txt:707,搜「轻量模型做筛分」)。

  61. 出处:第 709 段(text/07-ch06.txt:709,搜「一台机器托管一个模型」)与第 715 段(text/07-ch06.txt:715,搜「分配计算资源」)。

  62. 出处:「6.4.3」第 722 段(text/07-ch06.txt:722,搜「吵闹邻居」)。

  63. 出处:第 724 段(text/07-ch06.txt:724,搜「配额与限流」)、第 726 段(text/07-ch06.txt:726,搜「准入控制」)与第 727 段(text/07-ch06.txt:727,搜「和风险约束绑定在一起」)。

  64. 出处:第 730 段(text/07-ch06.txt:730,搜「故障边界必须清晰」)。

  65. 出处:第 733 段(text/07-ch06.txt:733,搜「这一次推断机会给这个」)。

  66. 出处:「6.4.4」第 739 段(text/07-ch06.txt:739,搜「并不总能同时最优」)与第 742 段(text/07-ch06.txt:742,搜「更在意首字时间」)、第 743 段(text/07-ch06.txt:743,搜「单位成本和总吞吐」)。

  67. 出处:第 745 段(text/07-ch06.txt:745,搜「放之四海而皆准的终极方案」)。

  68. 出处:第 753 段(text/07-ch06.txt:753,搜「简单请求交给更便宜、更快的路径」)与第 754 段(text/07-ch06.txt:754,搜「更多搜索,低价值场景」)。

  69. 出处:第 752 段(text/07-ch06.txt:752,搜「现实预算、现实时延和现实并发里活下来」)。

  70. 出处:「6.4.5」第 764 段(text/07-ch06.txt:764,搜「稳定的会话落点往往比单次最优调度更有价值」)。

  71. 出处:第 770 段(text/07-ch06.txt:770,搜「不会把“状态”笼统看成」)与第 771 段(text/07-ch06.txt:771,搜「可重建和可丢弃」)。

  72. 出处:第 775 段(text/07-ch06.txt:775,搜「可直接重放」)。

  73. 出处:第 777 段(text/07-ch06.txt:777,搜「放大成一次完整失败」)。

  74. 出处:第 779 段(text/07-ch06.txt:779,搜「生命周期和状态演化」)。

  75. 出处:「6.4.6」第 786 段(text/07-ch06.txt:786,搜「这次回答没有返回」)与第 787 段(text/07-ch06.txt:787,搜「响应超时并不等于」)。

  76. 出处:第 790 段(text/07-ch06.txt:790,搜「纯推断、只读查询、幂等写入、非幂等写入」)与第 792 段(text/07-ch06.txt:792,搜「事务语义避免重复生效」)。

  77. 出处:第 794 段(text/07-ch06.txt:794,搜「任务语义的一部分」)。

  78. 出处:第 796 段(text/07-ch06.txt:796,搜「停止继续输出文本」)与第 797 段(text/07-ch06.txt:797,搜「前台取消、后台终止和」)、第 798 段(text/07-ch06.txt:798,搜「结果作废三层」)。

  79. 出处:第 802 段(text/07-ch06.txt:802,搜「可解释、可恢复、可回滚的状态机」)。

  80. 出处:「6.4.7」第 809 段(text/07-ch06.txt:809,搜「换了编译版本」)。

  81. 出处:第 814 段(text/07-ch06.txt:814,搜「影子环境里比较延迟」)。

  82. 出处:第 816 段(text/07-ch06.txt:816,搜「长上下文尾延迟上升」)。

  83. 出处:第 819 段(text/07-ch06.txt:819,搜「缓存格式、会话状态、量化约束」)与第 758 段(text/07-ch06.txt:758,搜「“粘”在同一版本直到完成」)。

  84. 出处:第 827 段(text/07-ch06.txt:827,搜「理论上可回退」)。

  85. 出处:第 828 段(text/07-ch06.txt:828,搜「最小可用热备」)与第 829 段(text/07-ch06.txt:829,搜「版本前进和版本后退」)。

  86. 出处:「6.4.8」第 837 段(text/07-ch06.txt:837,搜「退而不崩」)。

  87. 出处:第 840 段(text/07-ch06.txt:840,搜「关闭昂贵的重排序器」)与第 841 段(text/07-ch06.txt:841,搜「也不应在不满足约束时悄悄降质执行」)。

  88. 出处:第 845 段(text/07-ch06.txt:845,搜「不能演变成隐蔽退化」)与第 847 段(text/07-ch06.txt:847,搜「系统为何降级、降到了哪一层」)。

  89. 出处:第 849 段(text/07-ch06.txt:849,搜「退得清楚、退得可追踪」)。

  90. 出处:「6.3.7.1」第 627 段(text/07-ch06.txt:627,搜「预填充长度」)。

  91. 出处:「6.3.3」第 478 段(text/07-ch06.txt:478,搜「大约要2.5 GB显存」)。 2

  92. 出处:第 652 段(text/07-ch06.txt:652,搜「20%–40%」)。 2