想象一家生意红火的餐厅后厨。客人川流不息,订单纸条一张接一张夹到主厨面前的铁架子上;主厨不会来一张炒一锅,而是先等几秒,把好几张订单拼在同一口锅里一起炒——菜一锅出,燃气只烧一次。这个“攒订单、拼锅炒”的动作,就是本期主题“动态批处理”;那排等待认领的订单纸条,就是“请求队列”。攒多久开火是批处理窗口,VIP 要不要插队是优先级,菜的长短不一怎么拼锅是变长序列处理,客人等急了会不会走是延迟与超时。后厨怎么知道快撑不住了?靠监控告警。开业前怎么验证?靠试营业压测。换一家厨房怎么搬?靠多云迁移评估。这篇文章就用这间厨房的日常,把推理服务提速的完整套路讲清楚。

岗位关联

掌握请求队列与动态批处理,是 AI 推理工程师优化吞吐、控制延迟、规划容量与降低云成本的核心技能,直接决定线上服务的稳定性与账单水平。

目录
  1. 可视化演示
  2. 队列设计:订单架上的排队规则
  3. 批处理窗口:主厨等多久再开火
  4. 动态批处理:一锅多菜与变长配菜
  5. 延迟控制:别让客人等太久
  6. 监控告警:后厨里的仪表盘
  7. 压测验证:开业前的试营业
  8. 多云适配:换一家厨房怎么搬
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

展示推理服务请求队列调度、三种批处理模式吞吐对比及延迟-吞吐调优曲线。

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

请求队列调度流程 FIFO队列暂存到达请求 动态批处理器运行时凑批 Latency=Queue+Batch+Infer 三阶段流水线降低GPU空闲

队列设计:订单架上的排队规则

餐厅里订单从传菜口一张张飞进来,主厨面前有一排铁夹子,订单按到达顺序夹好。这个“订单架”决定了谁能先进锅。如果服务员随手乱放,熟客的菜可能等半小时还没排上——所以餐厅有条规矩:先来后到,同时 VIP 和外卖可以插队。推理服务里,GPU 面前也挂着这样一个“订单架”,学名叫请求队列。

请求队列是推理网关的缓冲地带。客户端发来的推理请求先进入队列排队,调度器按策略取出并组成批次。队列的两条基本规则是:先进先出(FIFO)保证公平,优先级让重要请求插队。排队论中,队列长度、到达率、等待时间三者被一条著名的定律绑定:

想控制订单架的长度,要么降低进单速率(限流),要么缩短每张单在架上的停留时间(加快出菜)。队列容量也不是无限大,洪峰来临时要设上限并配合拒绝策略——直接丢弃还是返回忙,都需要提前定好。这正是后续所有调优的方向。

L=λ×W\displaystyle L = \lambda \times W
Little 定律像“订单架守恒”:架上的订单数,等于每秒进单量乘以每单在架停留时间,三者的变化互相绑定。
  1. L平均队列长度:系统里正在排队和正在处理的请求总数,单位是个。
    LL
  2. λ请求到达速率:每秒新到达多少个请求,单位是“个/秒”,反映客流快慢。
    λ\lambda
  3. W平均停留时间:一个请求从进队到被处理完的平均秒数,反映上菜速度。
    WW
  4. 三者相乘队列越积越多,一定是到达率上升或停留时间变大的结果,找到失控的那一头才能对症下药。
    L=λ×WL = \lambda \times W

批处理窗口:主厨等多久再开火

主厨最怕一口锅只炒一个菜:燃气一样烧,锅气一样起,出菜量却少得可怜。于是有了“拼锅”:新订单先在台面上攒着,攒够三张就开火;但如果等太久,最早下单的客人已经不耐烦了。攒多久再开火,就是批处理窗口。

批处理窗口是调度器等待请求凑批的最长时间。窗口越长,凑到的请求越多,单批计算效率越高;但新到达的请求必须等窗口结束(或批满)才能被处理,延迟随之上升。窗口之外还有第二个约束:最大批次上限——锅就那么大,硬塞会爆(显存溢出)。

一次批处理分为两个阶段:收集(等请求到齐)和计算(GPU 执行)。吞吐量由批次大小和整个周期共同决定:

窗口调优就像选“拼锅等待时间”:高峰期客流大,几秒就能攒满一锅,窗口可以调短;闲时客人稀疏,窗口太短等于一锅一菜,不如适当延长。聪明的调度器还会动态调整窗口——空闲时拉长多攒几单,繁忙时缩短尽快出发,这就是窗口动态调整与超时强制出发的意义。

T=Btwindow+tcompute\displaystyle T = \frac{B}{t_{\text{window}} + t_{\text{compute}}}
吞吐量等于“一锅菜的量”除以“等菜与炒菜的总时间”——想多出菜,要么增大锅量,要么压缩周期。
  1. B批次大小:一批包含的请求个数,受显存和批次上限约束。
    BB
  2. t_window窗口时长:收集阶段等待请求到齐的时间,单位秒。
    twindowt_{\text{window}}
  3. t_compute计算时长:GPU 处理一整批请求的耗时,锅越大炒得越久。
    tcomputet_{\text{compute}}
  4. T吞吐量:分子是“一锅的量”,分母是“一个完整周期”,周期越短单位时间出菜越多。
    T=Btwindow+tcomputeT = \frac{B}{t_{\text{window}} + t_{\text{compute}}}

动态批处理:一锅多菜与变长配菜

拼锅也有讲究:一份红烧肉和一份炒时蔬,火候完全不同。如果硬把十分钟的炖菜和两分钟的爆炒放一锅,锅必须迁就慢菜——快菜就糊了。深度学习模型同样遇到“菜长不一”:每条输入文本的长度不同。

动态批处理就是在窗口内把到达的请求动态合并成批,而不是死等固定数量到齐才一次性出发。变长序列的处理依赖填充(padding):所有序列都补到与批内最长序列相同的长度,才能拼成规整的张量。但填充是纯粹的浪费——多出来的都是空转。

填充引入的浪费可以精确度量。批内序列参差不齐时,有效算力占比就是填充效率:

聪明的主厨会把“时长接近”的订单分到不同灶台——这就是分桶调度:按长度区间分桶,桶内序列长度接近,填充浪费大幅降低。再配合请求合并原理(新请求随时加入正在执行的批次),GPU 的每一份算力都用在刀刃上。

η=∑i=1BℓiB×Lmax⁡\displaystyle \eta = \frac{\sum_{i=1}^{B} \ell_i}{B \times L_{\max}}
填充效率反映了“有效食材”占“锅内容量”的比率,越低说明空烧越多。
  1. ℓᵢ第 i 条序列长度:每条输入的有效 token 数,相当于每道菜的份量。
    ℓi\ell_i
  2. L_max批内最长序列:填充的基准长度,锅要迁就最慢的那道菜。
    Lmax⁡L_{\max}
  3. η填充效率:分子是有效 token 总数,分母是填充后占用的总容量,两者之比越接近 1 越省。
    η=∑i=1BℓiB×Lmax⁡\eta = \frac{\sum_{i=1}^{B} \ell_i}{B \times L_{\max}}

延迟控制:别让客人等太久

餐厅向客人承诺:点单后 20 分钟内上齐。为了这个承诺,即使锅里还能再塞一张订单,窗口到点也必须开火。推理服务的承诺叫 SLO(服务等级目标),常见写法是“P99 延迟小于 500 毫秒”——99% 的请求都要在期限内完成。

排队等待是延迟的主要来源。请求到达速率逼近服务能力时,等待时间会急剧恶化。排队论里的 M/M/1 模型给出了平均排队等待时间与负载的关系:

控制手段有三板斧:超时机制——队列中等待超过阈值的请求直接返回或降级,不让客人无限等;抢占式调度——让高优请求插队;窗口调短——牺牲吞吐换延迟。延迟与吞吐本质上是一对跷跷板,调优就是根据 SLO 找平衡点,而不是一味追求吞吐数字好看。

Wq=ρμ(1−ρ)\displaystyle W_q = \frac{\rho}{\mu (1 - \rho)}
排队等待时间在负载升高时会非线性飙升——“快满了”和“满了”之间往往只差几秒钟。
  1. ρ服务强度:到达速率与服务速率的比值,ρ 必须小于 1 系统才稳定,等于 1 就会无限堆积。
    ρ=λμ\rho = \frac{\lambda}{\mu}
  2. μ服务速率:GPU 单位时间能处理的请求数,相当于主厨的颠勺速度。
    μ\mu
  3. 1−ρ剩余余量:服务能力还剩多少,余量越少,分母越小,等待时间越长。
    1−ρ1 - \rho
  4. W_q平均等待时间:利用率到 70% 后延迟开始陡增,这就是延迟拐点的由来。
    Wq=ρμ(1−ρ)W_q = \frac{\rho}{\mu (1 - \rho)}

监控告警:后厨里的仪表盘

后厨再好,也要有领班盯着。传菜口堆积的订单、灶台的空烧时间、客人的催促声——这些信号让领班知道该加人手还是改流程。推理服务也需要这样一套“后厨仪表盘”。

核心指标有四件套:队列长度(订单堆积)、GPU 利用率(灶台忙闲)、吞吐量(出菜率)、P99 延迟(最慢客人的等待)。原始指标每秒都在抖,直接设阈值会导致告警轰炸——半夜一个抖动就把值班人吵醒三次。所以先要平滑:

告警阈值不能拍脑袋:上限要留出余量(比如队列超过容量的 70% 触发预警),分级告警——Warn 只记日志,Critical 才叫醒值班人。结合队列长度、GPU 利用率与批窗口超时次数三者的组合,还能快速定位“队列在堆积但 GPU 在空烧”这类配置问题。监控不是装完就完事,阈值要随压测结果和线上数据持续校准。

St=α×xt+(1−α)×St−1\displaystyle S_t = \alpha \times x_t + (1 - \alpha) \times S_{t-1}
EWMA 是给抖动指标做“加权平均”:最新数据权重最大,历史数据以指数衰减的方式参与平滑。
  1. x_t当前观测值:这一秒采样的原始指标,比如此刻队列长度是 50。
    xtx_t
  2. S_{t-1}上一时刻平滑值:历史的记忆,携带了过去的趋势信息。
    St−1S_{t-1}
  3. α平滑系数:α 越大越听信当下、反应快但抖动大;越小越依赖历史、曲线平但反应慢。
    α\alpha
  4. S_t新的平滑值:新旧信息加权平均,告警判断基于它而不是原始抖动值。
    St=α×xt+(1−α)×St−1S_t = \alpha \times x_t + (1 - \alpha) \times S_{t-1}

压测验证:开业前的试营业

新餐厅开业前一定要试营业:请一批“志愿食客”模拟高峰客流,看后厨会不会崩。推理服务上线前同样要压测,用工具制造并发的推理请求,提前暴露瓶颈。试营业暴露的是后厨流程问题,压测暴露的是队列、批处理和显存的短板。

常用压测工具:wrk、vegeta 适合简单 HTTP 压测;Locust 能模拟复杂业务场景;针对 GPU 推理还可以用 Triton 自带的 perf_analyzer。压测场景要覆盖三类负载:均匀流量、突发洪峰、长尾大请求——只测一种等于只模拟了一种客人。

压测的核心产出是性能基线和容量模型。单实例容量估算用一条简单公式:

试营业还要盯住“最差一桌”:记录 P99 延迟随 QPS 变化的曲线,找到延迟拐点。容量规划以拐点为上限,而不是压测的最大 QPS——因为最大 QPS 往往建立在延迟已经不可接受的基础上。压测通过后,容量基线与告警阈值一起写进运维手册,成为后续扩容的决策依据。

N=⌈QPStargetQPScapacity⌉\displaystyle N = \left\lceil \frac{QPS_{\text{target}}}{QPS_{\text{capacity}}} \right\rceil
容量规划公式告诉你:目标吞吐除以单机实测能力,向上取整,得到最少需要的实例数。
  1. QPS_target目标吞吐:业务要求的每秒请求数,相当于餐厅承诺的接待能力。
    QPStargetQPS_{\text{target}}
  2. QPS_capacity单实例容量:压测得到的单机最大吞吐,注意要取延迟拐点处的值。
    QPScapacityQPS_{\text{capacity}}
  3. 向上取整除法结果有余数就进一位,实际部署还会额外加缓冲实例应对洪峰。
    N=⌈QPStargetQPScapacity⌉N = \left\lceil \frac{QPS_{\text{target}}}{QPS_{\text{capacity}}} \right\rceil

多云适配:换一家厨房怎么搬

餐厅开到另一个城市,炉灶型号、燃气标准、食材供应链全都变了。推理服务从一个云迁移到另一个云,也远不是“重新部署”这么简单。直接搬过去大概率会踩坑:GPU 卡型不同、配额要重新申请、监控面板不兼容。

差异点集中在四个方面:GPU 实例规格与配额(A 云有 A100 而 B 云只有等效卡,算力曲线不同)、网络带宽与跨可用区延迟、模型仓库与镜像服务的兼容性、监控告警体系(CloudWatch 与云监控的指标口径和 API 完全不同)。

有些业务为了高可用会同时跑在两朵云上,此时整体可用性不是简单相加。两台“灶台”只要有一台活着就能出菜,整体可用性是两者的并集:

迁移前要做差异清单与降级预案:队列组件(如 Redis 队列)是否跨云通用、云厂商托管的调度服务差异、限流组件是否一致。先在测试云跑通压测基线,再灰度迁移,把“换厨房”的风险降到最低。迁移完成后还要回头看成本账单——不同云的 GPU 计费差异可能高达 30%,别忘了把成本优化写进验收标准。

A=1−(1−aA)(1−aB)\displaystyle A = 1 - (1 - a_A)(1 - a_B)
多云高可用的本质是“只要有一朵云活着就算活着”,组合后的可用性通常比其中任何一朵都高。
  1. a_A、a_B单云可用性:例如 A 云 99.9%、B 云 99%,每个都接近但不到 100%。
    aA,aBa_A, \quad a_B
  2. (1−a_A)(1−a_B)同时故障概率:两朵云同时挂掉的概率,相乘让它变得极小。
    (1−aA)(1−aB)(1 - a_A)(1 - a_B)
  3. 整体可用性99.9% 与 99% 组合后约为 99.999%,这就是多云冗余的价值。
    A=1−(1−aA)(1−aB)A = 1 - (1 - a_A)(1 - a_B)

AI 应用场景

LLM 在线对话服务的吞吐优化

阶段:推理服务部署与性能优化阶段

解决的问题:传统逐条推理在高并发时 GPU 大量空转,单卡吞吐上不去、延迟抖动明显。引入请求队列 + 动态批处理后,高峰期并发请求被合并成批,GPU 利用率显著提升;批处理窗口上限又约束了 P99 延迟,避免“吞吐上去了、体验崩了”。

具体案例:某智能客服平台晚高峰涌入 300 QPS 对话请求,采用排队 + 动态批处理后,单卡吞吐从 40 QPS 提升到 120 QPS,P99 延迟从 2 秒降到 800 毫秒,支撑了双十一期间的流量洪峰。

跨云迁移的推理服务适配

阶段:架构迁移与多云适配阶段

解决的问题:从云 A 迁到云 B 时,GPU 型号、队列组件、监控体系不兼容会导致服务中断。通过迁移评估清单(实例规格、配额、监控告警映射)和降级预案,把不可预知的迁移风险变成可执行的检查项。

具体案例:某出海公司因合规要求把推理服务从海外云迁回国内云,GPU 从 A100 换成等效卡后,压测发现填充策略参数需要重新调整,监控从 CloudWatch 迁移到自建 Prometheus,最终用灰度迁移平滑完成切换。

新模型上线前的容量规划

阶段:模型上线验证阶段

解决的问题:不压测就上线,容易在流量洪峰时被打爆。通过容量规划公式计算所需实例数,设计均匀、洪峰、长尾三类压测场景,找到延迟拐点再定容量,避免“拍脑袋买机器”。

具体案例:某文生图模型上线前压测确认单实例容量 8 QPS,业务目标 40 QPS,按公式部署 5 台并额外加 1 台缓冲,上线后运行平稳,GPU 利用率维持在 85% 左右。

Python 演示

python58 行
"""请求队列与动态批处理模拟器。""" from collections import deque  class BatchScheduler:    """模拟一个带批窗口和最大批次上限的调度器。"""     def __init__(self, batch_max=4, window_sec=0.5, compute_per_req=0.08):        self.batch_max = batch_max        self.window_sec = window_sec        self.compute_per_req = compute_per_req        self.queue = deque()        self.served = 0        self.wait_times = []        self.busy_until = 0.0     def submit(self, arrival):        self.queue.append(arrival)     def tick(self, now):        if now < self.busy_until or not self.queue:            return 0        first = self.queue[0]        waited = now - first        batch_full = len(self.queue) >= self.batch_max        window_done = waited >= self.window_sec        if not batch_full and not window_done:            return 0        size = min(self.batch_max, len(self.queue))        for _ in range(size):            self.queue.popleft()        self.busy_until = now + self.compute_per_req * size        for _ in range(size):            self.wait_times.append(waited)        self.served += size        return size  def run_simulation(batch_max, window_sec, total=300, rate=12):    scheduler = BatchScheduler(batch_max, window_sec)    now = 0.0    next_arrival = 0.0    while scheduler.served < total:        now += 0.01        if now >= next_arrival:            scheduler.submit(now)            next_arrival = now + 1.0 / rate        scheduler.tick(now)    avg_wait = sum(scheduler.wait_times) / len(scheduler.wait_times)    qps = scheduler.served / now    return qps, avg_wait  if __name__ == "__main__":    for bmax, win in [(1, 0.1), (4, 0.3), (8, 0.6)]:        qps, avg_wait = run_simulation(bmax, win)        print("batch_max=%d window=%.1fs -> QPS=%.1f avg_wait=%.3fs" % (bmax, win, qps, avg_wait))
目的:用一个小型调度器模拟“不批处理”与“动态批处理”的差异,直观看到批次越大吞吐越高、平均等待时间也越长的跷跷板效应。
  1. scheduler = BatchScheduler(batch_max, window_sec)创建调度器,传入最大批次和窗口时长两个关键参数,就像设定“锅的大小”和“等多久开火”。
  2. if not batch_full and not window_done: return 0批次没满且窗口没到,就继续攒单不发车,这正是动态批处理的核心节拍。
  3. self.busy_until = now + self.compute_per_req * size模拟 GPU 忙碌:批越大计算越久,锅越大炒得越慢。
  4. qps = scheduler.served / now用总完成数除以总耗时得到吞吐量,对应正文里的 T = B / (t_window + t_compute)。
  5. for bmax, win in [(1, 0.1), (4, 0.3), (8, 0.6)]三组参数对比:批次为 1 时相当于一锅一菜,4 和 8 时体现拼锅收益。

常见误区

误区批处理窗口越长、批次越大,GPU 一锅炒得越多,吞吐一定更高,所以参数往大了调准没错。

正解批次增大确实提升计算效率,但每个请求都必须等整批算完才能返回,窗口越长新请求等待越久,P99 延迟线性上升;同时显存占用随批次增长,超过上限直接内存溢出。吞吐会在某个点饱和甚至下降(等待空转加显存换入换出)。正确做法是让窗口和批次上限服从延迟 SLO,找到饱和前的拐点。

为何常见:只盯着 GPU 利用率一个指标,忽略了延迟和显存两个隐形成本,把局部最优当成了全局最优。

误区队列里堆的请求越多,说明系统处理得快、业务火爆,是好事,不用管。

正解队列积压是“请求进来速度 > 处理速度”的失衡信号,意味着延迟已经恶化。Little 定律 L = λW 表明队列变长可能是到达率上升,也可能是处理变慢。当队列持续增长而 GPU 利用率偏低时,往往是批处理窗口配置不当或调度空转,需要立即排查而不是庆祝。

为何常见:把“排队人多”等同于“生意好”,混淆了吞吐量的表象与延迟的真实代价。

误区动态批处理是离线训练才用的优化,在线推理要低延迟,只能一个一个算。

正解在线推理恰恰是动态批处理的主战场。LLM 服务大量使用连续批处理:在序列级灵活调度、在生成间隙插入新请求,让 GPU 不再空烧。只要窗口与批次上限配合 SLO 设置,在线场景同样能大幅提升吞吐。批处理不等于延迟不可控,关键在于参数配比。

为何常见:把批处理和“必须等固定数量凑齐”的静态批处理混为一谈,误以为批处理必然带来不可接受的延迟。

误区压测就是拿工具猛打接口,测出最大 QPS 然后照着这个水位线部署就万事大吉。

正解最大 QPS 往往发生在延迟已经崩溃的时刻,直接按它部署等于埋雷。正确做法是记录延迟-QPS 曲线,找到延迟拐点(P99 从平缓变陡的位置),以拐点作为容量上限;同时压测场景要覆盖均匀流量、突发洪峰和长尾大请求,而不是单一恒定压力。

为何常见:压测工具默认输出高吞吐容易让人兴奋,忽略了 SLO 才是容量规划的真正约束。

误区GPU 利用率高就说明系统没问题,监控只看利用率这一个数字就够了。

正解GPU 利用率高可能同时伴随着队列堆积和延迟暴涨——利用率只说明“灶台没闲着”,不说明“菜按时上了”。监控必须同时看队列长度、P99 延迟、批窗口超时次数和吞吐量,组合起来才能定位“队列在堆积但 GPU 在空烧”这类配置问题。

为何常见:GPU 利用率是面板上最直观的数字,容易一叶障目,忽略端到端的用户体验指标。

面试题

Q1. 动态批处理的核心收益是什么?

单选题 · easy

  • A.压缩模型的参数量
  • B.合并请求减少空闲开销← 正确答案
  • C.降低网络传输的带宽
  • D.提升单次推理的精度

答案:B。动态批处理把多个请求合并成一批交给 GPU 并行计算,核心收益是减少 GPU 空闲开销、提升吞吐。压缩参数量是模型压缩的范畴,降低带宽和提升精度都不是批处理能直接做到的。

Q2. 批处理窗口时间变长,通常会带来什么效果?

单选题 · easy

  • A.延迟增加吞吐上升← 正确答案
  • B.吞吐下降延迟增加
  • C.延迟下降吞吐增加
  • D.延迟吞吐同时下降

答案:A。窗口变长意味着收集阶段等更久,新请求的排队延迟增加;但每批能凑到更多请求,批次数变少、计算效率更高,吞吐通常上升。这就是延迟与吞吐跷跷板效应的最直接体现。

Q3. Little 定律 L = λW 中,W 表示什么?

单选题 · easy

  • A.系统平均吞吐量
  • B.请求平均等待时间← 正确答案
  • C.模型参数量大小
  • D.批窗口时间长度

答案:B。Little 定律中 L 是平均队列长度,λ 是请求到达速率,W 是请求从进队到处理完的平均停留时间。它告诉我们队列变长要么是进单快了,要么是停留久了,是排查队列问题的第一公式。

Q4. 变长序列导致批内填充效率低,最直接的后果是什么?

单选题 · mid

  • A.浪费显存与计算资源← 正确答案
  • B.提高请求到达的速率
  • C.减少响应文本的长度
  • D.增加模型参数的数量

答案:A。填充把短序列补到批内最长序列的长度,多出来的部分全是无效计算,既占显存又耗算力。填充效率 η 就是用来度量这份浪费的,分桶调度正是为了减少浪费而生。

Q5. 队列长度持续增长但 GPU 利用率很低,最可能的原因是什么?

单选题 · mid

  • A.请求到达的速率过慢
  • B.批处理窗口配置过长← 正确答案
  • C.输入序列长度都过长
  • D.模型推理的速度过快

答案:B。任务在排队却没人干活,说明调度层“攒单”策略出了问题——窗口太长导致迟迟不发车,GPU 干等。如果到达速率过慢,队列不会持续增长;序列过长通常 GPU 会一直忙,利用率不会低。

Q6. 压测得到单实例容量为 200 QPS,业务目标为 1000 QPS,按容量规划公式需要多少台实例?

单选题 · mid

  • A.至少需要三台实例
  • B.至少需要五台实例← 正确答案
  • C.至少需要四台实例
  • D.至少需要六台实例

答案:B。N = ⌈QPS_target / QPS_capacity⌉ = ⌈1000 / 200⌉ = 5。注意实际部署时还要考虑冗余缓冲,因为压测容量是理想值,洪峰来临时需要额外余量。

Q7. 合理设置推理服务告警时,应重点关注哪些指标?

多选题 · mid

  • A.平均队列长度指标← 正确答案
  • B.p99尾延迟水平← 正确答案
  • C.GPU利用率波动← 正确答案
  • D.代码注释的详细度

答案:ABC。队列长度反映积压程度,P99 延迟反映最差体验,GPU 利用率反映资源是否空转,三者组合才能定位“队列堆积但 GPU 空烧”的问题。代码注释与运行时监控无关。

Q8. 跨云迁移推理服务时,需要重点评估哪些差异?

多选题 · hard

  • A.实例规格与配额限制← 正确答案
  • B.网络带宽与延迟差异← 正确答案
  • C.监控告警的兼容程度← 正确答案
  • D.代码变量命名风格

答案:ABC。GPU 实例规格决定算力曲线,网络带宽与跨可用区延迟直接影响推理时延,监控告警体系决定运维能否平移。变量命名是代码风格问题,与云平台无关。

Q9. 为什么批处理窗口不能无限加长?

单选题 · hard

  • A.显存占用会持续增长
  • B.新来请求等待时间变久
  • C.批次数会无限地增加
  • D.A与B两项均符合← 正确答案

答案:D。窗口越长批次越大,显存占用随批次线性增长,可能 OOM;同时新到达的请求必须等窗口结束才能被处理,延迟持续上升。批次大小由窗口和上限共同决定,不会无限增加,C 表述错误,故选 D。

Q10. 使用指数加权移动平均(EWMA)平滑告警指标时,以下说法正确的有哪些?

多选题 · extreme

  • A.α越大对近期数据越敏感← 正确答案
  • B.α越小曲线越平滑← 正确答案
  • C.α的取值与告警无关
  • D.α调节延迟与吞吐

答案:AB。EWMA 中 α 是平滑系数,α 越大越听信当前观测值、反应快但抖动大;α 越小越依赖历史、曲线平但反应慢。α 直接影响告警阈值判断的灵敏度,且它只作用于指标平滑,不调节延迟与吞吐本身,C、D 错误。