想象一间开在深夜的智能食堂。顾客并不会冲进后厨自己炒菜,而是先在收银台下单,订单被传菜员送到灶台;大厨根据口味合并菜品、控制火候,最后把菜一盘盘端出来。这里的“大厨”是大模型,而“后厨与前台调度系统”就是推理服务。用户发出的每一个 Prompt,都像一张订单;推理服务要负责接单、排队、配菜、掌勺、装盘,再以流利的文字把结果端回给用户。它是整个 LLM 应用的必经之路,也是吞吐与延迟的心脏泵:只要它停跳一拍,整个应用都会立刻变得迟钝。 推理服务不是一个模型文件,而是一整套工程系统。从模型加载、请求调度、动态批处理,到 GPU 显存管理、健康检查和优雅重启,每一步都决定用户是“秒回”还是“转圈”。对 AI 从业者来说,理解了推理服务,就理解了让大模型真正可用、可上线、可运维的那道命门。

岗位关联

推理服务决定了 LLM 应用的上限:不懂它,你只能调用模型;理解它,你才能设计、优化并保障整个 AI 系统的“心脏”稳定跳动。

目录
  1. 可视化演示
  2. 服务化架构:后厨的岗位分工
  3. 推理引擎:大火煮汤,一勺一勺尝
  4. 动态批处理:拼桌和拼锅
  5. 显存管理:冰箱里的空间争夺战
  6. 高可用设计:晨检、交接班与备班
  7. 性能观测:上菜节奏的可视化
  8. 部署实践:连锁食堂的成套路
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

动态演示推理服务的核心机制,通过输入/处理/存储/输出四种模式展示关键概念与交互流程。

本节配有交互动效(进入视口后自动加载,约 3KB)。

推理服务:LLM推 LLM推理服务总览与核心职责定 服务化部署架构设计与组件分工 核心机制可视化 推理服务整体架构与关键组件

服务化架构:后厨的岗位分工

假设这家智能食堂生意火爆,但顾客从不需要进厨房催菜。收银台负责接单,传菜员按号排队,大厨专心掌勺,出菜口统一上菜。推理服务就是这套后厨体系:它把“模型能用”变成“模型好用”。

模型部署完成后,推理服务启动时先把模型权重从磁盘读进 GPU 显存,相当于大厨到岗后先备好汤底和食材。请求入口模块负责接收 HTTP 或 gRPC 请求,完成鉴权、校验和限流;调度器为核心环节,负责为每个请求分配显存、决定何时启动计算;模型生成完成后,结果通过流式接口以 Token 为单位返回客户端,用户看到的就是逐字输出的打字机效果。

生产环境的推理服务通常拆成 API 网关、推理引擎、模型仓库和监控模块。API 网关管流量,推理引擎跑前向计算,模型仓库管理多个版本权重,监控模块上报延迟和资源水位。一个常见的错误是把业务逻辑塞进推理服务,这就像让大厨同时接电话、收银、洗碗,出餐效率必然下降。

岗位清晰,后厨才不会乱;组件职责清晰,推理服务才能稳定扩展、快速排障。这种“接单、调度、掌勺、上菜”的分工,是整个 LLM 服务化的地基。

Ttotal=Tqueue+Tprefill+Tdecode+TreturnT_{\text{total}}=T_{\text{queue}}+T_{\text{prefill}}+T_{\text{decode}}+T_{\text{return}}
直观说:用户感受到的等待时间,等于排队等位、大火煮汤、一勺勺盛菜和传菜上桌四段耗时之和。
  1. 总耗时 \(T_{\text{total}}\)从用户发出请求到完整收到回答的总时间,这是体验的直接体现。
    TtotalT_{\text{total}}
  2. 排队时间 \(T_{\text{queue}}\)请求到达后等待 GPU 资源的时间,队列越长,这个值越大。
    TqueueT_{\text{queue}}
  3. 预填充时间 \(T_{\text{prefill}}\)模型并行处理用户输入 Prompt 的时间,类似把整锅汤底煮开。
    TprefillT_{\text{prefill}}
  4. 解码时间 \(T_{\text{decode}}\)逐 Token 生成回答的时间,生成越多,耗时越长。
    TdecodeT_{\text{decode}}
  5. 返回时间 \(T_{\text{return}}\)结果从 GPU 传到客户端的时间,流式返回能减小首字延迟。
    TreturnT_{\text{return}}

推理引擎:大火煮汤,一勺一勺尝

大厨收到一锅菜的订单,会先开大火把汤底煮开,之后每加一味调料都要停下来尝一口。Transformer 的 LLM 也遵循同样的节奏:先“预填充”,再“解码”。

预填充阶段并行处理整个输入 Prompt,为每个 Token 计算注意力所需的 Key 和 Value 并写入 KV Cache;解码阶段则是典型的自回归生成:每一步只生成一个 Token,再把它拼进输入序列,继续预测下一个 Token,直到遇到停止符或达到 max_tokens。许多新手以为模型生成是“一次性吐出全文”,实际上它更像逐个字地“续写”。

推理引擎还负责生成策略与采样参数。temperature 控制随机性,top_p 控制候选集范围,max_tokens 限制回答长度,stop 列表决定结束条件。这些参数不改变模型权重,却直接决定输出的风格与长度。

尝汤的次数省不下来,但可以拼锅、备菜、让每一次尝汤更便宜。这正是动态批处理、KV Cache 和显存管理要解决的事。

T生成=Tprefill+N生成×t解码T_{\text{生成}}=T_{\text{prefill}}+N_{\text{生成}}\times t_{\text{解码}}
这句话在说:生成 Token 数越多,解码步数越多,耗时几乎线性增长。要降低延迟,要么减少生成长度,要么让单步解码更快。
  1. 生成总耗时 \(T_{\text{生成}}\)从模型开始计算到输出全部 Token 的耗时。
    T生成T_{\text{生成}}
  2. 预填充耗时 \(T_{\text{prefill}}\)处理 Prompt 的固定开销,与输入长度相关。
    TprefillT_{\text{prefill}}
  3. 生成数量 \(N_{\text{生成}}\)模型实际生成的 Token 个数,决定了要解码多少次。
    N生成N_{\text{生成}}
  4. 单步解码耗时 \(t_{\text{解码}}\)每生成一个 Token 所需的平均时间,和显存带宽、批大小强相关。
    t解码t_{\text{解码}}

动态批处理:拼桌和拼锅

如果四位顾客都点番茄锅,后厨不会傻到开四口锅各煮一遍,而是拼成一大锅,煮好后再分装。推理服务里的“拼锅”就是批处理。

传统静态批处理必须等一整批请求全部生成完,才一起释放资源;先完成的请求即使空闲,也得占着位置陪跑。动态批处理则完全不同:它允许先完成的请求立刻离队,新到的请求马上补进空位。GPU 是极其昂贵的“灶台”,最怕的就是空烧,动态批处理正是为了让每一秒都有请求在锅里翻滚。

具体实现时,调度器维护一个请求队列,按到达顺序或优先级挑选请求进入运行批次,批大小受显存上限和模型支持的最大序列数约束。vLLM、TGI 等框架采用的 continuous batching 或 in-flight batching,都是这种“边煮边加菜、熟一锅出一锅”的思路。

拼桌不仅让食堂翻台更快,也让顾客觉得等待可以接受。动态批处理是推理服务提升吞吐量最便宜、最立竿见影的杠杆。

R=∑j=1Bnjmax⁡j(tj)−min⁡j(tj)R=\frac{\sum_{j=1}^{B} n_j}{\max_j(t_j)-\min_j(t_j)}
这是吞吐率的本质:一段时间内服务完成了多少个 Token。动态批处理让分母尽可能小、分子尽可能大,GPU 的“翻台率”自然就上去了。
  1. 吞吐率 \(R\)单位时间内服务生成的 Token 总数,是推理成本的核心指标。
    RR
  2. 每个请求的生成数量 \(n_j\)第 \(j\) 个请求实际生成的 Token 数,分子把所有并行请求的成果相加。
    ∑j=1Bnj\sum_{j=1}^{B} n_j
  3. 批次起止时间 \(\max_j(t_j)-\min_j(t_j)\)一个批次窗口从第一个请求开始到最后一个请求结束的时间跨度。
    max⁡j(tj)−min⁡j(tj)\max_j(t_j)-\min_j(t_j)
  4. 批大小 \(B\)同一时刻并行处理的请求数量,不是越大越好,受显存限制。
    BB

显存管理:冰箱里的空间争夺战

后厨冰箱容量有限,汤底、配菜、半成品都要占格子。推理服务的“冰箱”就是 GPU 显存,而 KV Cache 是其中最贪吃的角色。

LLM 推理时显存主要被四部分占用:模型权重、KV Cache、激活值和运行时开销。模型权重在一次部署中基本固定,激活值短暂存在,真正随并发和序列长度疯狂增长的,是 KV Cache——每个请求每生成一个 Token,都要为每一层注意力保存一份 Key 和 Value。对话越长、并发越多,KV Cache 占用的显存就越大,甚至常常超过模型权重本身。

KV Cache 的用途是避免每生成一个 Token 都重新计算前文的注意力。为了高效管理它,现代推理框架采用类似 PagedAttention 的方案,把显存切成小块按需分配,减少碎片;前缀缓存则复用相同 Prompt 的 KV 结果,让相似请求省去重复计算。当显存不足时,服务只能让新请求排队等待,甚至拒绝超限请求。

冰箱规划好了,后厨才不会爆仓;显存管理好了,推理服务才能长期稳定运行,不会三分钟一次 OOM。

MGPU=M权重+MKV+M激活+M运行M_{\text{GPU}}=M_{\text{权重}}+M_{\text{KV}}+M_{\text{激活}}+M_{\text{运行}}
估算显存时不能只算模型权重。KV Cache 是动态变量,它决定了你的服务到底能同时接多少客。
  1. GPU 显存总量 \(M_{\text{GPU}}\)一张卡上可供模型使用的显存上限。
    MGPUM_{\text{GPU}}
  2. 模型权重 \(M_{\text{权重}}\)加载原始模型参数所需的空间,部署后基本不变。
    M权重M_{\text{权重}}
  3. KV Cache \(M_{\text{KV}}\)所有并发请求缓存下来的 Key/Value 总和,随请求数和序列长度增长。
    MKVM_{\text{KV}}
  4. 激活值 \(M_{\text{激活}}\)前向计算过程中临时产生的中间张量。
    M激活M_{\text{激活}}
  5. 运行时开销 \(M_{\text{运行}}\)CUDA 上下文、框架缓冲等固定消耗。
    M运行M_{\text{运行}}

高可用设计:晨检、交接班与备班

食堂每天开门前要检查食材和灶台,员工换班时会把手头最后一道菜做完再走,遇到突发情况还有备班厨师顶替。推理服务的高可用设计,正是这套“晨检、交接班、备班”机制的工程版。

健康检查分两种:存活探针和就绪探针。存活探针只看进程有没有僵死,相当于“人有没有晕倒”;就绪探针则要确认模型是否加载完成、GPU 是否可用、服务能不能真正处理请求,相当于“现在能不能上灶接单”。只有就绪探针通过后,负载均衡才会把流量放进来。

优雅重启是发布和扩缩容时的关键动作:实例收到停止信号后,先把自己从负载均衡中摘掉,不再接收新请求,再等待正在推理的请求正常结束或超时回收,最后才退出进程。自动扩缩容则根据 QPS、排队长度或 token 吞吐动态调整实例数;故障转移让新实例快速顶替故障实例,避免服务雪崩。

顾客看不到后厨的晨检和交接班,但每一顿安稳的饭都靠这些细节撑起来。同样,用户感知不到探针和优雅重启,但没有它们,服务迟早会在某个深夜悄悄崩溃。

A=MTBFMTBF+MTTRA=\frac{\text{MTBF}}{\text{MTBF}+\text{MTTR}}
可用性由两部分决定:尽量不出故障(MTBF 大),出了故障尽快恢复(MTTR 小)。健康检查和优雅重启都是在同时优化这两个数。
  1. 可用性 \(A\)服务在统计周期内正常可用时间的比例。
    AA
  2. 平均故障间隔 \(\text{MTBF}\)两次故障之间正常运行的平均时长,越大越好。
    MTBF\text{MTBF}
  3. 平均恢复时间 \(\text{MTTR}\)从故障发生到服务恢复的平均时长,越小越好。
    MTTR\text{MTTR}

性能观测:上菜节奏的可视化

顾客对一家餐厅的耐心,取决于三个数字:第一道菜多久上来,两道菜之间隔多久,以及餐厅同时能接待多少桌。推理服务的性能观测,盯的也是这三件事。

TTFT 是从请求发出到第一个 Token 返回的时间,它反映排队与预填充的合计速度,决定用户的第一印象;TPOT 是每生成一个 Token 的平均耗时,决定回答“打字”的连贯感;吞吐量则是单位时间内服务生成的 Token 总数,直接关联 GPU 成本和扩容决策。三个指标必须放在一起看:只看 TTFT 会忽略输出阶段的卡顿,只看吞吐量又会牺牲单用户延迟。

实际运维中,推理服务应持续上报批量大小、显存利用率、排队长度、TTFT 和 TPOT,并通过 Prometheus、Grafana 或框架自带指标面板展示。vLLM 等框架内置 metrics,几乎零成本接入。

没有仪表盘的食堂很难改进,没有观测的推理服务也很难定位瓶颈。把这三个指标当成心跳、血压和体温,你才能第一时间发现心脏哪里出了问题。

TTFT=t首token−t发送,TPOT=t最后−t首tokenN生成\text{TTFT}=t_{\text{首token}}-t_{\text{发送}},\quad \text{TPOT}=\frac{t_{\text{最后}}-t_{\text{首token}}}{N_{\text{生成}}}
TTFT 决定“用户愿不愿意等”,TPOT 决定“等得舒不舒服”,吞吐量决定“服务赚不赚钱”。
  1. TTFT 首 Token 延迟用户发出请求到看到第一个字的时间。
    t首token−t发送t_{\text{首token}}-t_{\text{发送}}
  2. TPOT 每 Token 输出时间首 Token 之后,平均生成一个 Token 需要多久。
    t最后−t首tokenN生成\frac{t_{\text{最后}}-t_{\text{首token}}}{N_{\text{生成}}}
  3. 生成总数 \(N_{\text{生成}}\)回答中除去 Prompt 后新生成 Token 的个数。
    N生成N_{\text{生成}}

部署实践:连锁食堂的成套路

一家食堂成功之后,要开成连锁店,就不能再靠大厨个人手感,而是要有标准化的设备、流程和应急预案。部署推理服务同样需要“成套路”。

生产环境最常用的推理框架是 vLLM、TGI 和 SGLang,它们内置了动态批处理、KV Cache 优化和 PagedAttention,几行命令就能拉起一个高性能服务。更有价值的是 OpenAI 兼容 API:客户端只需改 base_url 就能从在线大模型切换到自建服务,业务代码完全不用重写。

多模型管理场景下,需要增加路由层,把不同请求分流给不同模型或不同版本,便于灰度发布。安全防护包括接口鉴权、限流、Prompt 注入检测和输出内容审核。容量估算则要回答一个问题:到底需要几台实例?最朴素的计算方法是把 QPS、平均耗时和单实例并发上限放在一起。

按固定流程开店,出餐质量才稳定;按成熟框架和监控体系部署服务,LLM 应用才真正敢面向生产环境上线。

K=⌈QPS×Tavgconcurrency⌉K=\left\lceil \frac{\text{QPS}\times T_{\text{avg}}}{\text{concurrency}} \right\rceil
这个公式说的是:QPS 乘平均耗时得到“同时进行中的请求数”,再除以单实例并发上限,向上取整就是最少实例数。
  1. 所需实例数 \(K\)满足当前流量至少需要的服务实例数量。
    KK
  2. 每秒请求数 \(\text{QPS}\)高峰时要承受的请求速率。
    QPS\text{QPS}
  3. 平均处理耗时 \(T_{\text{avg}}\)单个请求从进入到完成平均需要多少秒。
    TavgT_{\text{avg}}
  4. 并发上限 \(\text{concurrency}\)单实例在保证延迟前提下能同时处理的请求数。
    concurrency\text{concurrency}

AI 应用场景

智能客服系统的服务化上线

阶段:模型部署与推理服务化

解决的问题:传统方式单独部署一个模型 URL 给业务调用,没有任何排队、批处理、显存保护机制。高并发时请求全部打到 GPU 上,互相争抢显存,轻则超时,重则 OOM。推理服务把模型加载、请求排队、动态批处理和健康检查封装成标准后端,业务方只需调用 API,高峰期也能稳定输出。

具体案例:某电商平台在大促期间将 7B 客服模型用 vLLM 部署成推理服务,配置动态批处理和自动扩缩容。原本 1000 并发下大量超时,优化后 TTFT 稳定在 800ms 以内,GPU 利用率从不到 30% 提升到 70% 以上。

企业知识库问答的长上下文管理

阶段:显存优化与 KV Cache 管理

解决的问题:RAG 问答系统中,用户携带大量检索文档作为上下文,Prompt 很长。每个请求都重复计算相同文档的 KV Cache,既慢又费显存。推理服务通过前缀缓存复用同一文档的 KV,结合块式显存分配,让长上下文请求不再轻易触顶显存上限。

具体案例:某企业内部知识库每天有数万次问答请求,其中 30% 的 Prompt 共享相同的企业制度文档。启用 prefix caching 后,这部分请求的 TTFT 下降了近一半,整体吞吐提升了 40%。

Python 演示

python50 行
from collections import deque  class Request:    def __init__(self, req_id, arrive_step, need_tokens=6):        self.req_id = req_id        self.arrive_step = arrive_step        self.need_tokens = need_tokens        self.finish_step = None  class DynamicBatchScheduler:    def __init__(self, max_batch=4):        self.max_batch = max_batch        self.wait_queue = deque()        self.running = []        self.finished = []        self.token_count = 0        self.current_step = 0     def enqueue(self, req):        self.wait_queue.append(req)     def _fill_batch(self):        while len(self.running) < self.max_batch and self.wait_queue:            self.running.append(self.wait_queue.popleft())     def step(self):        self.current_step += 1        self._fill_batch()        for req in list(self.running):            req.need_tokens -= 1            self.token_count += 1            if req.need_tokens == 0:                req.finish_step = self.current_step                self.finished.append(req)                self.running.remove(req)        self._fill_batch()  if __name__ == "__main__":    sched = DynamicBatchScheduler(max_batch=3)    for t in range(30):        if t % 3 == 0:            req_id = len(sched.finished) + len(sched.running) + len(sched.wait_queue) + 1            sched.enqueue(Request(req_id, t, need_tokens=6))        sched.step()    print("已完成的请求数:", len(sched.finished))    print("运行中:", len(sched.running), "排队中:", len(sched.wait_queue))    print("生成的Token总数:", sched.token_count)
目的:用 30 步仿真模拟一个极简的动态批处理调度器,展示请求如何排队、进入批次、逐 Token 生成并完成离队。
  1. self.wait_queue = deque()请求先进入先进先出的排队区,对应食堂门口的叫号等位。
  2. self.running = []表示正在 GPU 上并行生成 Token 的请求集合。
  3. def _fill_batch(self):只要运行批次没满,就把排队中的请求拉进来,对应“空位补菜”。
  4. for req in list(self.running):复制一份列表再遍历,防止边遍历边删除出现跳过问题。
  5. req.need_tokens -= 1每个 step 代表一次解码,生成一个 Token。
  6. if req.need_tokens == 0:请求生成完毕,立刻从运行批次移除,把位置让给新请求。
  7. if t % 3 == 0:每 3 个 step 模拟一个新请求到达,制造动态流量。
  8. sched.step()推进一个解码步,调度器会在步内补满批次。

常见误区

误区把 max_num_seqs 调到几百,服务应该能处理更多请求;如果还卡,就继续调大并发。

正解并发超过显存和算力上限后,KV Cache 迅速撑满显存,排队时间暴涨,吞吐反而下降。正确的做法是结合显存余量和 TPOT 找到“甜点批大小”,再用动态批处理让 GPU 持续满载,而不是盲目调大数值。

为何常见:人们习惯认为“资源越多越快”,却忽略了每个请求都要独立占显存,GPU 算力也是共享的。

误区动态批处理要等请求长度接近才拼接,否则短请求会被长请求拖死。

正解动态批处理最核心的机制是“先完成先离队,新请求随时补位”,这种连续批处理并不需要长度对齐。短请求生成完就走,长请求继续在批次里跑,互不阻塞。

为何常见:受传统批处理训练思维影响,以为批处理必须网格化对齐,忽略了推理阶段的流式特性。

误区KV Cache 是模型权重的一部分,缓存越多,模型回答越聪明。

正解KV Cache 只是把已经算好的 Key/Value 临时存下来,避免每个 Token 都重算前文。它主要影响速度和显存,不改变模型能力,更不会让回答变聪明。

为何常见:看到“Cache”就想到了浏览器缓存带来的体验提升,忘了它只是计算结果复用。

误区进程还活着、端口能连通,就说明推理服务健康,可以放心接流量。

正解存活不等于就绪。模型可能还在加载权重、显存被占满或请求队列爆掉,此时即使进程活着也无法正常推理。生产环境必须区分存活探针和就绪探针,等到模型真正 ready 后再放流量。

为何常见:传统 Web 服务的健康检查习惯只看进程状态,但推理服务还有“模型是否就绪”这一层特殊状态。

面试题

Q1. 推理服务在 LLM 应用中的核心作用是什么?

单选题 · easy

  • A.对训练语料做清洗与标注
  • B.加载模型并处理推理请求← 正确答案
  • C.为模型设计提示词模板
  • D.负责模型参数微调流程

答案:B。推理服务是把模型权重加载到 GPU、接收请求、调度生成并返回结果的后端模块。清洗数据、设计提示词、微调模型都属于其他环节,不在推理服务的核心职责内。

Q2. 一个请求在推理服务中的完整处理顺序是什么?

单选题 · easy

  • A.加载模型、解析请求、返回结果
  • B.排队、预填充、解码、返回← 正确答案
  • C.解码、排队、返回、预填充
  • D.采样、批处理、加载、返回

答案:B。请求先进入队列等待 GPU 资源,接着进入预填充阶段并行处理 Prompt,再进入解码阶段逐 Token 生成,最后通过流式接口返回。加载模型发生在服务启动阶段,不属于单次请求的完整链路。

Q3. 动态批处理相比静态批处理的主要优势是什么?

单选题 · mid

  • A.必须等整批请求全部结束
  • B.完全不用考虑显存限制
  • C.完成请求离队,新请求补位← 正确答案
  • D.每次只处理一个超长请求

答案:C。动态批处理允许请求先完成先离开,新请求立即补进空位,让 GPU 始终忙碌。静态批处理才需要等整批结束;动态批处理同样受显存限制,也不是单请求执行。

Q4. KV Cache 最直接的用途是什么?

单选题 · mid

  • A.缓存历史 Key/Value 避免重算← 正确答案
  • B.保存模型权重以加速加载
  • C.存储训练样本和标签数据
  • D.缓存用户输入用于数据挖掘

答案:A。解码阶段每个新 Token 都要重新计算前文注意力,KV Cache 将之前算好的 Key/Value 存下来,避免重复计算。它不保存训练数据,也不是模型权重,更不应被用来做用户数据挖掘。

Q5. 在推理显存组成中,随并发与序列长度增长最快的是哪一部分?

单选题 · mid

  • A.模型权重
  • B.KV Cache← 正确答案
  • C.激活值
  • D.运行时开销

答案:B。模型权重和运行时开销在部署后基本固定,激活值短时存在。KV Cache 会随着每个请求的 Token 数和并发请求数持续增长,是显存规划中最需要关注的动态变量。

Q6. 当推理实例收到停止信号时,优雅重启首先应该做什么?

单选题 · mid

  • A.立刻杀掉所有进程转移流量
  • B.停止接收新请求并等待在途请求结束← 正确答案
  • C.清空 KV Cache 后继续服务
  • D.重启加载所有模型预热版本

答案:B。优雅重启的核心是“先摘流量,再等存量”。实例应从负载均衡中摘除,停止接收新请求,等待正在生成的请求完成或超时后再退出,避免用户请求在发布瞬间被硬杀。

Q7. 哪些属于推理服务架构中的典型组件?

多选题 · mid

  • A.请求入口和调度器← 正确答案
  • B.GPU 显存管理器← 正确答案
  • C.数据标注平台入库
  • D.健康检查与监控模块← 正确答案

答案:ABD。推理服务关心请求入口、调度器、显存管理、健康检查和监控等模块。数据标注平台属于数据处理与训练阶段,不在推理服务架构的职责边界内。

Q8. 下列哪些措施能提升推理服务的吞吐量?

多选题 · mid

  • A.动态批处理← 正确答案
  • B.增加超时重试次数
  • C.使用前缀 KV 缓存复用← 正确答案
  • D.无限提高单请求 max_tokens

答案:AC。动态批处理让 GPU 满载,前缀 KV 缓存复用减少重复计算,都能提升吞吐。增加重试只会放大流量,盲目调大 max_tokens 会让单个请求占住资源,反而降低整体吞吐。

Q9. 以下哪些指标与用户感知的推理延迟直接相关?

多选题 · hard

  • A.TTFT 首Token延迟← 正确答案
  • B.TPOT 每Token输出耗时← 正确答案
  • C.模型参数量大小
  • D.排队长度← 正确答案

答案:ABD。TTFT 决定首字等待,TPOT 决定后续节奏,排队长度影响两者。模型参数量是静态属性,不等同于延迟体验,参数量大也不一定延迟更高。

Q10. 某服务高峰 QPS=10,单请求平均耗时 5 秒,单实例并发上限 20,至少需要几个实例?

单选题 · hard

  • A.1 个
  • B.2 个
  • C.3 个← 正确答案
  • D.10 个

答案:C。根据容量估算公式 \(K=\lceil \text{QPS}\times T_{\text{avg}} / \text{concurrency}\rceil\),10×5÷20=2.5,向上取整为 3。2 个实例只有 40 并发,无法覆盖 50 个同时在途请求,必须 3 个。