想象你周末走进一家网红餐厅,饥肠辘辘地坐下,结果从点单到上菜等了整整二十分钟,你会怎样?大概率下次不会再来了。AI 产品也一样:用户敲下一段 prompt,服务端要排队、推理、生成答案再传回来,如果端到端要等上十几秒,用户的耐心早就被耗光了。延迟优化策略,就是这家“AI 餐厅”的后厨管理术——提前备好招牌菜(缓存命中)、把多桌订单合并一起炒(请求批处理)、让学徒也能烧出名厨的菜(模型蒸馏)、先端上小菜稳住顾客(渐进式渲染)。本文就带你走进这家餐厅的后厨,看看每一秒的等待都花在了哪里,又是怎样被一步步压缩回去的。

岗位关联

对 AI 从业者而言,延迟优化是产品从“能用”走向“好用”的分水岭。掌握这套方法论,你才能在资源有限、体验至上的真实环境中,让模型既快又稳地服务用户,也让自己成为团队里最懂“端到端体验”的那个人。

目录
  1. 可视化演示
  2. 1. 延迟问题剖析
  3. 2. 模型蒸馏压缩
  4. 3. 请求批处理
  5. 4. 缓存命中机制
  6. 5. 渐进式渲染
  7. 6. 端到端优化
  8. 7. 工程落地实践
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

演示延迟组成分解、请求批处理调度、语义缓存命中三大优化策略,点击按钮切换模式查看不同优化维度。

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

端到端延迟组成分解 模型推理占主要延迟,量化蒸馏可压缩 网络传输和排队也是重要组成部分 T_total = T_net + T_queue + T_infer + T_render 渐进式渲染可降低感知延迟

1. 延迟问题剖析

要优化上菜速度,得先搞清楚顾客的时间到底耗在哪一步。是排队等位(服务端排队),是后厨烹饪(模型推理),还是服务员传菜(网络传输)?把一次请求的完整链路摊开看,延迟不是单一数字,而是一串依次相加的环节。用户感受到的“卡顿”,往往是其中最慢的那个环节在拖后腿。

技术视角下,一次 AI 推理的端到端延迟可以拆成三块:排队等待(请求进入服务后等待计算资源)、计算耗时(模型前向推理,包括输入预填充和输出生成)、传输耗时(结果从服务器回到用户浏览器)。不同产品形态,三块占比截然不同,优化也必须对症下药。

这里先用一个统一的量化指标来评估优化效果。无论采用哪种手段,最终都要回答一个问题:到底快了多少?

回到餐厅的比喻:先把顾客从进门到吃上菜的全流程画出来,测量每道工序耗时,再决定是加人手(扩容)、改菜谱(蒸馏)还是提前备菜(缓存)。没有这个拆解,所谓的“优化”就只是凭感觉在碰运气。

R=Lold−LnewLold×100%R = \frac{L_{\text{old}} - L_{\text{new}}}{L_{\text{old}}} \times 100\%
延迟优化率 $R$ 表示优化前后相比,端到端延迟被压缩的百分比。它把“快了还是慢了”变成团队可以对齐的数值目标。
  1. 分子含义$L_{\text{old}} - L_{\text{new}}$ 表示优化前后延迟的绝对差值,即真正节省下来的时间。
    Lold−LnewL_{\text{old}} - L_{\text{new}}
  2. 分母基准$L_{\text{old}}$ 是优化前的原始延迟,用它做分母,衡量的是相对优化幅度。
    Lold−LnewLold\frac{L_{\text{old}} - L_{\text{new}}}{L_{\text{old}}}
  3. 转为百分比$\times 100\%$ 把比率放大成百分数,便于直观对比目标和进度。
    ×100%\times 100\%

2. 模型蒸馏压缩

餐厅后厨有位名厨,菜做得极好,但每道菜都要耗费大量时间和高级食材。聪明的做法是让名厨把做法“教”给学徒,学徒用更普通的食材、更快的动作做出 90% 相近的口感。模型蒸馏就是这个思路:用一个又大又准的“教师模型”指导一个又小又快的“学生模型”。

学生模型不仅有正确答案,还要模仿教师模型的“思考方式”。教师模型的输出不是一个硬邦邦的标签,而是一组概率分布——比如一张猫的图片,教师会说“93% 是猫、4% 是狗、2% 是兔子”。这种“软标签”里藏着类别间的相似关系,正是学生模型要重点学习的知识。

蒸馏损失函数把“答对题”和“学思路”两件事加权组合在一起:

名厨把毕生功力浓缩成几页菜谱,学徒只要照着练就能出师。蒸馏后的学生模型参数量少、推理快,部署成本低,是延迟优化里最“治本”的一招——直接从源头缩短了计算耗时。

L=α LCE(y,σ(zs/T))+(1−α) T2 KL(σ(zt/T) ∥ σ(zs/T))L = \alpha \, L_{\text{CE}}\left(y, \sigma(z_s / T)\right) + (1-\alpha)\, T^2 \, \text{KL}\left(\sigma(z_t / T) \,\|\, \sigma(z_s / T)\right)
蒸馏损失 = 硬标签交叉熵(保证答案正确)+ 软标签 KL 散度(模仿教师思路),温度 $T$ 控制分布的平滑程度。
  1. 硬标签项$L_{\text{CE}}(y, \sigma(z_s / T))$ 是学生模型输出与真实答案的交叉熵,保证学生能答对题。
    α LCE(y,σ(zs/T))\alpha \, L_{\text{CE}}(y, \sigma(z_s / T))
  2. 温度软化$z_s / T$ 把模型的输出分数除以温度 $T$,$T$ 越大概率分布越平滑,暴露类别间的相似关系。
    σ(zs/T)\sigma(z_s / T)
  3. 软标签项$\text{KL}\left(\sigma(z_t / T) \,\|\, \sigma(z_s / T)\right)$ 衡量学生分布与教师分布的差距,让学生贴着老师的思路走。
    T2 KL(σ(zt/T) ∥ σ(zs/T))T^2 \, \text{KL}(\sigma(z_t / T) \,\|\, \sigma(z_s / T))
  4. 加权与平衡$\alpha$ 在“答对题”和“学思路”之间取权重,$(1-\alpha)$ 配给软标签项,$T^2$ 用于补偿温度带来的梯度尺度变化。
    α与(1−α)T2\alpha \quad \text{与} \quad (1-\alpha) T^2

3. 请求批处理

餐厅高峰期,如果每桌客人都单独点一份炒饭,厨师就得一次次起锅烧油,时间和燃气全耗在重复的准备工作上。聪明的后厨会把好几桌的炒饭合在一口大锅里一次炒完——这就是请求批处理。GPU 推理同理,多个请求一起前向计算,能摊薄加载权重、分配显存这类固定开销。

动态批处理是常见的实现方式:请求先进入队列攒着,攒够一定数量或等待超过阈值,就整批发出去。它的代价也很直观——早来的请求得等晚来的伙伴凑齐才能出发。连续批处理则更精细,在 token 级别动态插入新请求,让 GPU 始终满负荷运转。

批处理对吞吐的提升可以用一个简单模型来描述:

把三桌客人的炒饭并成一锅,火候更集中、翻台更快。但批次也不是越大越好——锅就那么大,硬塞太多反而让每桌顾客都等得更久。批处理的价值在于平衡“吞吐”与“等待”,让后厨始终以最经济的节奏运转。

Tthroughput=Ntsetup+N×tsampleT_{\text{throughput}} = \frac{N}{t_{\text{setup}} + N \times t_{\text{sample}}}
批处理吞吐 = 批内请求数除以(固定启动开销 + 各样本解码耗时之和)。当 $N$ 增大,单个请求摊到的平均开销下降。
  1. 分子含义$N$ 是本批次包含的请求数量,批次越大,一次处理“喂给”GPU 的活越多。
    NN
  2. 固定开销$t_{\text{setup}}$ 是启动一次推理的固定成本,如权重加载、显存分配,与请求数无关。
    tsetupt_{\text{setup}}
  3. 线性增长部分$N \times t_{\text{sample}}$ 是批内所有样本逐条解码的时间总和,它是随 $N$ 线性增长的。
    N×tsampleN \times t_{\text{sample}}
  4. 整体比值分子除以分母得到单位时间处理的请求数。分母中存在固定项,意味着批次收益存在边际递减。
    Ntsetup+N×tsample\frac{N}{t_{\text{setup}} + N \times t_{\text{sample}}}

4. 缓存命中机制

餐厅总会提前卤好一批招牌牛肉,客人一点单,直接切片装盘,十秒钟就能上桌。AI 服务也一样:如果两个用户问了同一个问题,第二次完全没必要再让 GPU 从头算一遍。把热门请求的答案存起来,就是缓存命中机制。

最基础的是结果缓存:请求内容完全一致,直接返回上次的结果。更进一步是语义缓存:用向量嵌入把问题映射到语义空间,意思相近的问题也能命中同一份答案,比如“今天天气如何”和“现在气温多少度”。缓存预热则是在流量高峰前,提前把预测的热门请求算好塞进缓存,对抗“冷启动”。

缓存对延迟的影响可以用有效延迟公式刻画:

备菜是后厨对抗高峰期最锋利的武器。缓存同样三分靠命中率、七分靠热度预测——把最常点的菜备好,顾客自然觉得这家餐厅“上菜神速”。

Leff=h×Lhit+(1−h)×LmissL_{\text{eff}} = h \times L_{\text{hit}} + (1 - h) \times L_{\text{miss}}
有效延迟 = 命中率 × 命中延迟 + 未命中率 × 未命中延迟。命中率越高,平均响应越接近“秒回”。
  1. 命中率权重$h$ 是缓存命中率,表示请求在缓存中找到现成答案的比例,取值在 0 到 1 之间。
    hh
  2. 命中延迟$L_{\text{hit}}$ 是命中时的响应延迟,通常只有几毫秒,相当于直接端出备好的菜。
    h×Lhith \times L_{\text{hit}}
  3. 未命中部分$(1 - h)$ 是未命中的比例,$L_{\text{miss}}$ 是需要走完整推理链路的延迟。
    (1−h)×Lmiss(1 - h) \times L_{\text{miss}}
  4. 加权求和两部分相加得到系统整体的期望延迟。$h$ 越接近 1,$L_{\text{eff}}$ 越被“秒回”主导。
    h×Lhit+(1−h)×Lmissh \times L_{\text{hit}} + (1 - h) \times L_{\text{miss}}

5. 渐进式渲染

再快的后厨,一道精致的烤鸭也得现片现吃。与其让顾客干等二十分钟,不如先端上开胃小菜、再逐步上主菜。AI 产品的渐进式渲染就是这个道理:与其让用户盯着空白界面等全部结果生成完,不如让答案“边说边出”。

流式输出(SSE)让模型每生成一个 token 就立即推送给前端,用户看到的不是一整段文字突然出现,而是文字像打字机一样逐字蹦出来。这里有个关键指标——首 Token 延迟(TTFT),即从发出请求到收到第一个字的耗时。它决定了用户“第一次感到有反应”的速度。

TTFT 的构成和优化方向可以用公式拆解:

先上开胃菜,顾客就有了“这顿饭在进行中”的感觉。前端的骨架屏、打字机效果、流式进度条,本质上都是在管理学中的“感知等待”——把不可控的总时长,拆成一段段可控的即时反馈。

TTFT=tqueue+tprefill+tnetworkTTFT = t_{\text{queue}} + t_{\text{prefill}} + t_{\text{network}}
首 Token 延迟 = 排队时间 + 预填充时间 + 网络传输时间。流式输出不改变总推理时间,但彻底改变了用户的等待体验。
  1. 排队时间$t_{\text{queue}}$ 是请求在服务端的排队等候时间,批处理策略和负载均衡会影响它。
    tqueuet_{\text{queue}}
  2. 预填充时间$t_{\text{prefill}}$ 是指模型一次性处理用户全部输入 prompt 的前向计算时间,也是 TTFT 里占比最大的一块。
    tprefillt_{\text{prefill}}
  3. 网络时间$t_{\text{network}}$ 是第一个 token 从服务器传到用户浏览器的往返时间,CDN 和网络协议的选择会影响它。
    tnetworkt_{\text{network}}
  4. 三者相加首 Token 延迟由三段累加而成。优化 TTFT 就是要让用户“更快看到第一个字”。
    tqueue+tprefill+tnetworkt_{\text{queue}} + t_{\text{prefill}} + t_{\text{network}}

6. 端到端优化

前厅再快、后厨再忙,如果传菜员在路上磨蹭,顾客照样饿肚子。延迟优化不止发生在模型推理这一环,从用户点击按钮到答案完整呈现,整条链路每一环都是可压缩的空间。端到端思维要求我们盯住全链路,而不是只盯着 GPU。

网络传输优化包括使用 CDN 就近接入、启用 HTTP/2 多路复用、压缩传输体积等;并发连接控制则是通过连接池复用、限制并发上限,避免连接风暴拖垮服务。性能指标监控则负责兜底——只看平均延迟远远不够,长尾请求才是体验崩塌的元凶。

把全链路延迟展开来看:

这就像餐厅的考核不是看后厨出菜多快,而是看顾客从进门到吃完的全程体验。端到端优化是全局视角的总调度,让每一环都成为“快”的贡献者而不是短板。

Le2e=Lclient+Lnetwork+Lqueue+Lprefill+LdecodeL_{\text{e2e}} = L_{\text{client}} + L_{\text{network}} + L_{\text{queue}} + L_{\text{prefill}} + L_{\text{decode}}
端到端延迟 = 客户端渲染 + 网络往返 + 排队等待 + 输入预填充 + 输出解码。哪一段最长,资源就优先投在哪一段。
  1. 客户端开销$L_{\text{client}}$ 包括浏览器脚本执行、DOM 渲染等前端耗时,常被后端团队忽略。
    LclientL_{\text{client}}
  2. 网络开销$L_{\text{network}}$ 是用户到服务器之间的数据往返时间(RTT),地域距离和网络质量决定它的大小。
    LnetworkL_{\text{network}}
  3. 排队与推理$L_{\text{queue}}$ 是服务端排队时间,$L_{\text{prefill}}$ 是预填充输入,$L_{\text{decode}}$ 是逐字生成输出。
    Lqueue+Lprefill+LdecodeL_{\text{queue}} + L_{\text{prefill}} + L_{\text{decode}}
  4. 全链路求和所有环节相加才是用户真实感受到的延迟,任何一个短板都会拖垮整体体验。
    Lclient+Lnetwork+Lqueue+Lprefill+LdecodeL_{\text{client}} + L_{\text{network}} + L_{\text{queue}} + L_{\text{prefill}} + L_{\text{decode}}

7. 工程落地实践

菜谱再精妙,也要靠数据来证明翻台率真的提高了。延迟优化落地到工程中,离不开三件套:压测工具摸清当前的基线,SLO 目标把体验承诺量化,灰度验证确保新策略不会引入灾难。

压测工具(如自研压测脚本或 wrk、ghz 等)通过模拟真实流量找到系统的吞吐上限和延迟拐点;SLO(服务等级目标)则把“体验要好”翻译成可量化的指标,比如“P95 延迟不超过 2 秒”;灰度验证让优化策略先在 5% 流量上试跑,对比指标后再决定全量上线。

P95 延迟的定义是衡量长尾优化的核心指标:

餐厅经理每天看的不只是“平均翻台率”,更要盯“高峰期最慢的一桌等了多久”。P95 指标就是那个专门抓长尾的探照灯——平均延迟能被几个快请求拉低,但 P95 会让最差的 5% 体验无所遁形。

P95=L⌈0.95×M⌉P_{95} = L_{\left\lceil 0.95 \times M \right\rceil}
P95 延迟 = 把所有请求按延迟升序排列后,取第 95% 位置的延迟值。它代表 95% 的用户体验都不差于这个数值。
  1. 总请求数$M$ 是采样窗口内的请求总数,样本量越大,分位数估计越稳定。
    MM
  2. 位置计算$\lceil 0.95 \times M \rceil$ 是对 95% 位置向上取整,找到排序后对应的下标。
    ⌈0.95×M⌉\lceil 0.95 \times M \rceil
  3. 取对应值$L_{\lceil 0.95 \times M \rceil}$ 表示第 95 百分位的延迟值,即只有 5% 的请求比它慢。
    L⌈0.95×M⌉L_{\lceil 0.95 \times M \rceil}

AI 应用场景

智能客服机器人

阶段:推理服务部署与调优

解决的问题:高峰时段客服请求量大,单个请求推理耗时数秒,用户排队等待期间不断流失。通过动态批处理提升 GPU 吞吐、对高频问题建立语义缓存直接秒回、配合流式输出让用户立刻看到回复开头,三重手段叠加后平均响应时间下降约 70%。

具体案例:某银行在线客服接入大模型后,常见业务咨询(如查询余额、办理挂失)命中语义缓存,毫秒级返回;复杂问题走蒸馏后的小模型,配合连续批处理,高峰期吞吐提升 3 倍,用户满意度明显回升。

代码补全 IDE 插件

阶段:模型压缩与交互体验优化

解决的问题:代码补全模型如果端到端延迟超过 1 秒,开发者就会感觉“卡手”,打断编程心流。工程团队用知识蒸馏把大模型压缩成可在本地运行的轻量模型,并通过流式输出让补全建议逐词出现,首 Token 延迟控制在 200ms 以内。

具体案例:某 IDE 插件团队先将 70B 教师模型蒸馏为 3B 学生模型,再对高频代码模式建立补全缓存,最终实现边打字边出建议的流畅体验,插件周活跃用户增长 40%。

电商推荐系统

阶段:在线推理链路优化

解决的问题:大促期间推荐接口 QPS 激增,GPU 资源成为瓶颈,部分请求延迟超过 10 秒。团队为热门商品池建立结果缓存,冷门商品走批处理通道,并用 P95 监控长尾请求,保证用户体验。

具体案例:某电商平台在双十一大促前,对 Top 1000 热门商品做缓存预热,推荐接口 P95 延迟从 5.2 秒降至 0.8 秒,且 GPU 成本节省了 35%。

Python 演示

python64 行
"""模拟延迟优化:动态批处理与结果缓存"""import randomfrom collections import deque  class MockRequest(object):    def __init__(self, rid, question):        self.rid = rid        self.question = question        self.cost = len(question) * 0.1  class TurboEngine(object):    """集成缓存命中与动态批处理的推理引擎"""     def __init__(self, max_batch=4):        self.max_batch = max_batch        self.cache_map = {}        self.pending = deque()        self.batch_count = 0        self.cache_count = 0        self.lat_list = []     def submit(self, req):        if req.question in self.cache_map:            self.cache_count += 1            self.lat_list.append(0.05)            return self.cache_map[req.question]        self.pending.append(req)        if len(self.pending) >= self.max_batch:            return self.flush()        return None     def flush(self):        if not self.pending:            return None        batch = [self.pending.popleft()                 for _ in range(min(self.max_batch, len(self.pending)))]        self.batch_count += 1        setup = 0.2        total = setup + sum(r.cost for r in batch) * 0.6        avg = total / len(batch)        for r in batch:            self.cache_map[r.question] = "answer-" + str(r.rid)            self.lat_list.append(avg)        return "answer-" + str(batch[0].rid)  def main():    random.seed(42)    questions = ["q" + str(random.randint(0, 3)) for _ in range(20)]    engine = TurboEngine(max_batch=4)    for i, q in enumerate(questions):        engine.submit(MockRequest(i, q))    engine.flush()    avg_lat = sum(engine.lat_list) / len(engine.lat_list)    print("平均响应延迟:", round(avg_lat, 3))    print("批处理次数:", engine.batch_count)    print("缓存命中次数:", engine.cache_count)    print("总请求数:", len(questions))  if __name__ == "__main__":    main()
目的:用 20 个随机请求模拟一台集成了结果缓存和动态批处理的推理服务,对比观察批处理次数与缓存命中对平均延迟的影响。
  1. if req.question in self.cache_map:判断问题是否已在缓存中,命中则直接返回,几乎零延迟。
  2. self.pending.append(req)未命中的请求先进入队列,等待和其他请求凑成一个批次。
  3. if len(self.pending) >= self.max_batch:队列攒满 max_batch 个请求后立即触发批量推理。
  4. setup + sum(r.cost for r in batch) * 0.6模拟批量推理的固定开销被摊薄,且批量计算有共享收益(0.6 的折扣系数)。
  5. self.cache_map[r.question] = "answer-" + str(r.rid)批量推理完成后把结果写入缓存,后续相同问题直接秒回。

常见误区

误区只要把模型蒸馏得更小、量化得更狠,延迟自然就降下来了,其他环节不用管。

正解模型大小只影响“计算耗时”这一段。真实场景里,排队等待和网络传输往往占据延迟的 50% 以上。就像餐厅后厨出菜再快,传菜员磨蹭、顾客等位太久,体验照样崩。正确做法是先拆解全链路,找到最长的短板再对症下药。

为何常见:模型压缩是技术感最强、最容易写进汇报里的一步,初学者天然会把注意力集中在模型本身,忽略了链路其他环节。

误区批次越大,GPU 利用率越高,所以应该把队列攒得越长越好,拼命往一批里塞请求。

正解批次过大会让先来的请求等太久,单请求延迟反而飙升。动态批处理的核心是平衡:在等待时间和吞吐收益之间找均衡点。现实工程中通常会给“最大等待时长”设上限,超过阈值即使没攒满也要发出去,保证用户不会被饿死。

为何常见:人们容易看到“摊薄成本”的收益,却忽略了等待成本也是成本,而且等待是用户直接感知的。

误区缓存不过是个键值对,把问题和答案对应存好,下次查一下就行。

正解结果缓存只是最简单的一层。真实 AI 场景里几乎没有完全相同的用户提问,语义缓存需要把问题编码成向量、用相似度匹配答案,还要处理缓存过期、数据一致性、冷启动预热等问题。就像备菜不是把菜放冰箱就完事,还要考虑食材保鲜期和热门菜品的备货比例。

为何常见:大家对传统 Web 缓存的印象太深,容易低估 AI 场景下“语义匹配”带来的额外复杂度。

误区用了流式输出(SSE),模型推理就变快了,用户看到答案的时间就缩短了。

正解流式输出改变的只是“感知等待”,推理总耗时并没有变短。它让用户边看边等,把 10 秒的空白等待变成 10 秒的持续反馈。真正决定“第一反应速度”的仍然是首 Token 延迟(TTFT),需要靠预填充优化和排队优化来压缩。

为何常见:从用户视角看,流式输出确实“感觉快多了”,这种主观感受很容易被误认为客观加速。

误区监控面板上显示平均响应 1.2 秒,看起来挺快,系统应该没问题。

正解平均值会被少数极快请求拉低,掩盖大量慢请求的存在。可能出现“平均 1 秒、P99 却要 15 秒”的情况——这意味着每 100 个用户里就有 1 个在忍受 15 秒的等待。必须同时监控 P95、P99 分位数,才能发现真正的长尾问题。

为何常见:平均数是大家最熟悉的统计量,直觉上觉得它能代表整体水平,忽视了长尾分布对体验的巨大杀伤力。

面试题

Q1. 多数用户在等待 AI 应用响应时,普遍能接受的临界时间大约是?

单选题 · easy

  • A.0.1 秒以内给出反馈
  • B.2 秒以内给出响应← 正确答案
  • C.10 秒以内完成生成
  • D.30 秒以上也能忍受

答案:B。行业经验认为,用户对交互反馈的耐心阈值大约是 2 秒,超过这个时间就会明显感到卡顿和焦虑。0.1 秒属于流畅交互的理想区间,但很难做到;10 秒和 30 秒则早已超出大多数用户的耐心边界。这就像等待上菜,等两分钟还行,等十分钟就得催单了。

Q2. 一次 AI 推理的端到端延迟通常不包括下面哪一项?

单选题 · easy

  • A.用户在键盘上的打字时间← 正确答案
  • B.请求在队列中的等待时间
  • C.模型预填充输入的时间
  • D.模型逐字输出的生成时间

答案:A。端到端延迟从用户发出请求开始计算,包括排队、预填充、解码和网络传输。用户打字是在请求发出之前的行为,不算在服务响应时间里。好比餐厅考核上菜速度,不会把顾客点菜前看菜单的时间也算进去。

Q3. 知识蒸馏中“软标签”的主要作用是什么?

单选题 · mid

  • A.让训练标签彻底消失
  • B.传递类别间的相似信息← 正确答案
  • C.把标签压缩成二进制
  • D.增加训练数据的数量

答案:B。软标签是教师模型输出的概率分布,比如“93% 是猫、4% 是狗”,它比硬标签(只是“猫”)包含更多类别间相似性的知识。学生模型学习软标签,就能模仿教师的判断边界,而不仅仅是死记答案。这就像学徒不仅要学会“这是鱼香肉丝”,还要理解它和宫保鸡丁的微妙差别。

Q4. 动态批处理在攒批次过程中可能付出的代价有哪些?

多选题 · mid

  • A.单请求的排队等待变长← 正确答案
  • B.早期请求需要等待同伴← 正确答案
  • C.GPU 显存占用自动降低
  • D.模型推理精度完全不变

答案:AB。批处理攒批次的核心代价就是“等”:先来的请求要等后续请求凑齐,导致单请求排队延迟增加。C 和 D 不是代价——显存占用不会因批处理自动降低,推理精度也和批处理无关。这就像凑满一桌才开炒,前面到店的客人就得干坐着等。

Q5. 以下哪些属于端到端延迟优化的常见手段?

多选题 · easy

  • A.使用语义缓存命中技巧← 正确答案
  • B.将模型蒸馏变小变轻← 正确答案
  • C.无限增大批次的大小
  • D.开启流式输出降低等待← 正确答案

答案:ABD。语义缓存、模型蒸馏和流式输出都是标准优化手段。无限增大批次会加剧等待,属于错误做法。优化讲究对症下药,缓存解决重复计算、蒸馏压缩推理、流式改善感知,唯独“往死里塞批次”只会适得其反。

Q6. 流式输出(SSE)主要改善了用户的哪种体验?

单选题 · mid

  • A.边生成边看降低等待感← 正确答案
  • B.首字返回速度大幅提升
  • C.生成内容准确率大幅提高
  • D.模型推理成本显著降低

答案:A。流式输出让答案像打字机一样逐字出现,用户从“干等结果”变成“看着生成过程”,等待焦虑大幅下降。但它的总推理时间、TTFT、准确率和成本都没有本质变化。就像火锅店先上几碟小吃,顾客感觉“已经在吃了”,但主菜该多久还得多久。

Q7. 语义缓存与精确结果缓存的核心区别是什么?

单选题 · hard

  • A.前者按语义相似度匹配← 正确答案
  • B.后者完全不占存储空间
  • C.前者只缓存图片内容
  • D.后者不需要任何计算量

答案:A。精确缓存要求问题文本完全一致才命中,语义缓存则把问题转成向量,按语义相似度匹配命中,能处理“今天天气如何”和“现在气温多少度”这类意思相近的问题。后者的实现成本更高,但覆盖更广。B、C、D 都是对缓存的错误理解——缓存当然占存储,也不限于图片。

Q8. 相比动态批处理,连续批处理(Continuous Batching)的优势有哪些?

多选题 · hard

  • A.每个 token 级插入新请求← 正确答案
  • B.等待批次填满的时间变短← 正确答案
  • C.GPU 利用率得到有效提升← 正确答案
  • D.模型权重参数必然减少

答案:ABC。连续批处理在解码的每一步都动态插入新请求,粒度更细,GPU 空闲的缝隙被填满,等待时间也更短。它属于调度策略的改进,不改变模型参数。就像流水线火锅店随时往空位加菜,而不必等一整桌客人到齐才开火。

Q9. 在蒸馏损失中,把温度 T 调大时,教师模型的概率分布会怎样变化?

单选题 · extreme

  • A.概率分布变得更加平滑← 正确答案
  • B.概率分布变得更尖锐
  • C.输出类别数量自动减少
  • D.教师模型参数不再更新

答案:A。温度 T 越大,softmax 输出的分布越平滑,高置信度类别的概率被“稀释”,低置信度类别的概率则被放大,从而暴露出更多类别间的相似关系。T=1 时是原始分布,T 趋近 0 时退化为硬标签。它不改变类别数,也与教师模型是否更新无关。

Q10. P95 延迟指标的含义是下列哪一项?

单选题 · mid

  • A.5% 的请求比该延迟值更慢← 正确答案
  • B.95% 的请求比该延迟值更慢
  • C.平均延迟乘以 0.95 的结果
  • D.最快请求所消耗的延迟时间

答案:A。把一段时间内所有请求的延迟升序排列,P95 就是第 95 百分位的值——95% 的请求都比它快,只有 5% 比它慢。它用来捕捉长尾风险,比平均延迟更能反映真实体验。就像餐厅统计“最慢的 5% 顾客等了多久”,比平均翻台率更能暴露问题。