先保护用户等待时间,再谈 GPU 跑得有多满
Serving 设计题不是把 vLLM、Kubernetes 和缓存名词排成一行。稳定的回答从 workload 和 SLO 开始,画清请求、KV 与队列在哪里,再用容量、过载与故障闭环证明系统在高峰和发布时仍然可用。
先看整套知识的坐标,再逐题理解
这不是背答案清单。先用地图确认概念之间的依赖,再沿“白话直觉 → 核心结论 → 原理与取舍 → 常见误区”阅读每个知识点。
先看关键链路,单个知识点才不会变成碎片
面试官追问的方向,往往就是这张图里的下一根箭头:输入怎样变化、状态存在哪里、哪一步最贵、失败怎样被验证。
换一个关键词,或切回“全部章节”。
先把“快”和“扛得住”翻译成可验证目标
没有 workload 和 SLO,所有架构选择都只是猜。先说用户在等什么,再说系统在什么流量与长度分布下保证多少。
TTFT、TPOT、E2E 和吞吐分别衡量什么?为什么不能只看 tokens/s?#
先用大白话把它讲明白
把一次回答想成餐厅上菜:TTFT(Time to First Token,首 Token 时间)是点单到第一口菜上桌,TPOT(Time per Output Token,每输出 Token 时间)是后续上菜节奏,E2E(End-to-End Latency,端到端延迟)是整顿饭结束。
边界必须先声明。本题采用客户端口径:TTFT 从提交请求到观察到首 token,包含网关、排队、Prefill、首步 Decode 和首包网络;TPOT 采用 GenAI-Perf 的首 token 之后平均间隔。不同工具可能使用不同定义,不能直接混表。
系统 tokens/s 可以很高,单个请求仍可能排队很久。除了按输入/输出长度与租户分桶的 P50/P95/P99,还要分别报告完成请求延迟、所有合格请求的成功率与 SLO-goodput。
先声明客户端测量边界与工具口径。TTFT 衡量首 token 等待,TPOT 衡量首 token 后的生成节奏,E2E 是请求总时长,吞吐是系统单位时间产出;高吞吐可能以排队和尾延迟为代价,所以要把延迟、成功率和 SLO-goodput 联合看。
展开原理与工程取舍FORMULA · TRADE-OFF · FOLLOW-UP
原理拆解
在 NVIDIA GenAI-Perf 口径中,TPOT=(E2E−TTFT)/(N_out−1),因此只有 N_out≥2 时才定义;TTFT 已包含首 token,不应再在公式中重复相加。
若延迟 SLI 只统计完成请求,就必须另设以全部合格请求为分母的可用性 SLI;否则超时和拒绝会从“漂亮的延迟”里消失。SLO 还应声明窗口、长度桶、冷暖缓存与客户端/服务端边界。
E2E = TTFT + (N_out−1)·TPOT,N_out ≥ 2(GenAI-Perf 口径)工程取舍
扩大 batch 常提高总吞吐,却可能增加排队和单请求 TPOT;过于激进的低延迟目标则会留下大量空闲容量。目标应来自产品体验、成功率与成本预算。
常见误区
“模型每秒 100 token,所以每位用户每秒都看到 100 token”错误。系统吞吐会在并发请求间共享,单请求节奏还受调度、KV 读取、排队和网络影响。
面试官可能继续问
追问:Streaming 请求的 E2E 在客户端还是服务端量?为什么 P99 需要按 Prompt 长度分桶?Goodput 和 throughput 有何区别?
怎样从到达率、服务时间和 Token 分布估容量?Little’s Law 能告诉我们什么?#
先用大白话把它讲明白
容量估算不能只写“每卡每秒多少 token”。真实请求有长短 Prompt、不同输出上限和突发到达:长请求会占 KV 更久,也更容易干扰同批短请求。
Little’s Law(利特尔法则)的直觉是:稳定系统中平均在途数等于单位时间进入该边界的请求数乘平均停留时间。若每秒接纳 10 个、从接纳到离开平均 2 秒,系统平均约有 20 个在途请求。
它是同一系统边界上的均值恒等式,不给 P99 或稳定性保证。还要用长度分布、突发、KV/算力/带宽瓶颈和故障场景回放,按达标 goodput 而不是理论峰值配副本。
先固定系统边界,用真实输入/输出 token 与到达分布测每类请求的 service demand;再以 L=λW 对账平均在途数,并检查 KV、算力、带宽和尾延迟。容量用代表性 workload 的每副本 SLO-goodput 推导,再为明确的故障损失留余量。
展开原理与工程取舍FORMULA · TRADE-OFF · FOLLOW-UP
原理拆解
L、λ、W 必须描述同一总体:例如 L 统计已接纳的排队与运行请求,W 从接纳到完成或取消,λ 用该总体的长期进入/离开率;入口前被拒绝的请求不应混入其中。
Token workload 至少记录 prompt_tokens、output_tokens、到达间隔、会话并发、前缀复用、取消率和 deadline。利用率逼近 1 时,随机波动更容易形成长队列,不能按理论峰值 100% 配置。
L = λW;N_healthy = ceil(D_peak / G_replica);N_provisioned ≥ ceil(N_healthy / (1−f_loss))工程取舍
高预留降低尾延迟和故障风险,但成本更高;过度依赖自动扩容会被模型加载、GPU 调度和冷启动时间限制。f_loss 还要按真实故障域定义,不能随手写一个百分比。
常见误区
“平均 GPU 利用率只有 60%,所以还能安全加 40% 流量”错误。利用率可能掩盖 KV 容量、队列热点、长短请求干扰与 P99 性能悬崖。
面试官可能继续问
追问:如何把取消请求计入 L、λ、W?N+1 故障时容量怎样重算?为什么平均服务时间相同的两种分布,尾延迟可能差很多?
Open-loop 与 Closed-loop 压测有什么区别?怎样避免“压测越慢,结果越好”的假象?#
先用大白话把它讲明白
Closed-loop 客户端发一个请求,等完成后才继续;服务变慢时,客户端也跟着少发,实际施加的压力自动下降。若只看完成样本,过载期会被“协调遗漏”(Coordinated Omission)隐藏。
Open-loop 按独立到达过程发请求,更接近大量用户分别到来的场景,也更容易暴露排队崩塌。vLLM 的有限 request rate 可用 Poisson 到达,也可调 burstiness;还应限制最大在途数,避免压测器把无限队列当系统能力。
可复现不等于只固定随机种子:还要固定模型/Tokenizer、引擎与驱动版本、硬件、采样参数、长度/到达 trace、缓存冷热、并发和预热流程。报告客户端 TTFT/TPOT/E2E、错误、超时与服务器资源。
Closed-loop 的发起速率受响应时间反向限制,服务越慢越会自动降压;Open-loop 按目标到达过程独立发起,更能测排队与过载。压测应固定完整 workload,区分 offered、admitted、completed 和 SLO-goodput,并让超时、拒绝、取消留在总账里。
展开原理与工程取舍FORMULA · TRADE-OFF · FOLLOW-UP
原理拆解
若 closed-loop 有 C 个客户端,近似发起率受 C/mean(E2E+think time) 限制;这个值是测试实际发出的速率,不是外部无限需求的独立 offered load。
完成请求可以单独计算延迟分位数,但超时不是普通的有限延迟,也不能静默删除:应另报 deadline miss/可用性,必要时以明确的删失或惩罚规则分析。
issued_rate_closed ≈ C / mean(E2E + think_time)工程取舍
Open-loop 更真实地暴露过载,却会快速堆积在途请求;Closed-loop 适合模拟交互会话,但若要测固定外部压力,需使用独立 arrival trace 或具备协调遗漏修正的工具。
常见误区
“并发 100”不是完整 workload。100 个短请求与 100 个长上下文会话的 KV、Prefill 和 Decode 压力完全不同。
面试官可能继续问
追问:压测为什么要区分冷/暖 Prefix Cache 与编译?如何设计 burst?超时样本应该怎样进入成绩单?
单机优化的核心是调度活跃序列与复用昂贵状态
模型权重只是常驻底座;请求的 KV、批次形状和通信方式决定多少序列可以同时推进。
Continuous Batching 为什么比静态批处理更适合自回归 Decode?#
先用大白话把它讲明白
静态批处理像让一车人必须一起到终点:某条回答已经结束,也要等最长回答;新请求还得等整批完成。生成长度不一时会留下 padding 和空槽。
Continuous Batching(连续批处理)在调度迭代之间重组活跃序列:完成或取消的移出,等待请求可加入。一次迭代仍批量执行,但成员不必从请求开始到结束都固定。
调度器还要在 token budget 下安排 Decode、Prefill 与 Chunked Prefill。以当前 vLLM V1 为例,可用时默认启用 Chunked Prefill,并优先安排 Decode、让 Prefill 使用剩余预算;预算大小会在 TTFT、ITL 与吞吐之间移动取舍。
连续批处理把组批边界从“整条请求”缩到调度迭代,及时回收完成序列并加入新工作,减少 padding 和等待。它既不等于 Paged KV,也不等于 Chunked Prefill;生产实现仍要用 token budget、优先级、公平和 deadline 管理 Prefill/Decode 干扰。
展开原理与工程取舍FORMULA · TRADE-OFF · FOLLOW-UP
原理拆解
自回归 Decode 通常每个活跃序列每轮推进一个 token,但调度迭代也可混入 Prefill token;因此引擎调度单位应描述为“本轮被调度的 token/序列”,不应写成只能执行纯 Decode batch。
PagedAttention 解决 KV 的块式分配与寻址,使动态序列更容易管理,但连续批处理是调度策略,两者可组合却不是因果依赖。Chunked Prefill 则把长 Prefill 切块参与预算。
scheduled_tokens(t) ≤ token_budget;effective_decode_batch(t) = 本轮被调度的活跃 Decode 序列数工程取舍
更大动态 batch 常提高总吞吐,却可能恶化单请求 TPOT、排队和公平;更小 token budget 往往有利于 ITL,过小又可能降低 GPU 利用率并增加调度开销,必须按 workload 扫描。
常见误区
“Continuous Batching 就是把所有请求拼成一个长序列”错误。各序列的因果边界和 KV 状态独立,只是在同一调度迭代中批量推进。
面试官可能继续问
追问:Prefill 和 Decode 能否放同一个调度迭代?Chunked Prefill 解决什么?如何避免长输出一直占槽?
KV Cache、Paged KV 与 Prefix Cache 分别解决什么?容量怎样估?#
先用大白话把它讲明白
KV Cache 保存每层历史 token 的 K/V,让 Decode 不必重复计算旧上下文。其逻辑体积随层数、KV head 数、head dim、精度和驻留 token 增长,是并发容量的重要变量。
Paged KV 用固定大小物理块和块表映射逻辑序列,减少为最大长度连续预留造成的外部碎片;它仍有尾块内部空位和块表开销。Prefix Cache 则让请求复用完全相同前缀已算出的 KV:一个管理分配,一个消除重复 Prefill。
命中率应按复用 token 或节省工作量衡量。vLLM 只缓存完整 KV block;一个 4000-token 公共前缀的命中价值通常远高于 20-token 前缀,还要处理 LoRA、多模态输入、租户隔离和淘汰。
KV Cache 避免重算历史;Paged KV 用非连续块管理请求状态,降低连续预留与外部碎片;Prefix Cache 复用相同前缀的完整 KV blocks,主要降低 Prefill 与 TTFT。逻辑每 token KV 约为 2×层数×KV heads×head_dim×元素字节,实际每 rank 占用还取决于并行切分与实现。
展开原理与工程取舍FORMULA · TRADE-OFF · FOLLOW-UP
原理拆解
该公式先算一个完整逻辑模型、一个序列的 K/V,不含 allocator 元数据、对齐、尾块浪费、复制与临时缓冲;Tensor Parallel 或其他 KV sharding 下,每 rank 的物理占用必须按运行时实测。GQA/MQA 与 KV 量化会改变体积。
vLLM 的 block hash 包含父块 hash、当前块 token,以及 LoRA ID、多模态内容 hash、cache salt 等附加项;部署还要把模型/配置版本隔离在兼容的 cache namespace。cache_salt 可阻断跨租户已知前缀的复用与部分 timing side channel。
KV_logical_bytes ≈ 2·L·H_kv·d_head·bytes_per_element·resident_tokens工程取舍
更小 block 降低尾块内部浪费,却扩大块表与管理开销;更积极缓存提高命中,但占用本可接纳新请求的 HBM。跨租户共享虽可能增命中,却要先满足授权与侧信道边界。
常见误区
“Prefix Cache 会让 Decode 也按命中比例加速”不准确。它主要跳过已缓存完整块的 Prefill;新生成 token 的 Decode 仍需逐步执行,分支末尾的不完整块也不能直接当作完整命中。
面试官可能继续问
追问:如何定义 token-weighted hit rate?缓存 key 为什么要包含 LoRA 与多模态内容?遇到 HBM 压力先淘汰还是 offload?
模型放不下一张卡时,Tensor、Pipeline、Expert Parallel 怎样选?#
先用大白话把它讲明白
Tensor Parallel(TP,张量并行)把层内矩阵切到多卡,在被切分层中反复做 collective;Pipeline Parallel(PP,流水并行)把层放到不同 stage,在 stage 边界传激活并引入流水气泡。谁的通信更少取决于模型 shape、batch、节点拓扑与实现,不能把“PP 通信较少”当通则。
Expert Parallel(EP,专家并行)只适用于 MoE 稀疏专家层,token 通常经 All-to-All 去往所选专家,还要处理负载不均;Data Parallel(DP,数据并行)复制模型或并行组扩吞吐,不帮助单副本装入显存。
选择不是“卡越多越快”。Decode 常受权重/KV 带宽限制,增加 TP 也会增加同步;vLLM 官方甚至提示,在无 NVLink 的多卡节点上,PP 有时会因通信模式不同优于 TP——这是拓扑条件,不是普遍排名。
TP 切层内张量、PP 切层、EP 切 MoE 专家、DP 复制完整执行单元。先满足权重和 KV 容量,再按 Prefill/Decode 的关键路径、互联拓扑、目标 batch 与故障域实测;不要给 PP/TP 写脱离硬件和 shape 的固定通信优劣。
展开原理与工程取舍FORMULA · TRADE-OFF · FOLLOW-UP
原理拆解
TP collective、显存读写和计算可以部分重叠,性能由未被隐藏的关键路径决定;跨 NVLink/NVSwitch 与跨节点 fabric 的代价差异很大。PP 则受 stage 划分、microbatch 数和气泡影响。
生产容量应把一个完整 replica 或 TP/PP/EP group 当作调度与故障单元。单张 GPU 只是资源组成,不能把“副本数”和“GPU 数”混为一谈。
T_step ≈ critical_path(compute, memory, communication, synchronization) + T_pipeline_bubble工程取舍
更高 TP 降每卡权重和部分计算,却提高同步与故障耦合;PP 容量扩展好但小 batch 气泡可能明显;多副本扩吞吐和隔离简单,但每个副本都复制权重。
常见误区
“TP=8 一定比 TP=4 快一倍”错误。局部矩阵变小、通信占比上升、拓扑跨界和调度开销都可能抵消收益。
面试官可能继续问
追问:为什么 Prefill 与 Decode 的最优 TP 可能不同?MoE 的专家热点如何处理?Replica 与 TP group 怎样做故障隔离?
把单机引擎扩成集群时,局部性和排队开始互相冲突
集群层不只做轮询。它要知道请求成本、缓存在哪里、哪个阶段饱和,以及新增网络路径是否抵消收益。
Prefill/Decode Disaggregation 解决什么干扰?为什么不是所有场景都更快?#
先用大白话把它讲明白
Prefill 一次处理一段 Prompt,通常有较大的矩阵计算;Decode 每步推进少量 token,却反复读取权重和 KV,常对带宽与调度抖动更敏感。二者同处一个 worker 时,长 Prefill 可能拉高正在流式输出请求的 ITL。
P/D Disaggregation(Prefill/Decode 分离)让两类 worker 独立选并行度和扩缩容:Prefill 侧计算前缀状态,Decode 侧在兼容的 KV 可用后继续生成。实现可整批传输,也可按层异步传输并与计算重叠。
它新增两侧排队、KV 传输、状态协调和失败恢复。vLLM 当前文档明确把该能力标为 experimental,并说明其目标是分别调 TTFT/ITL、控制尾 ITL,而不是保证提升 raw throughput。
P/D 分离的价值是隔离 Prefill 对 Decode 尾延迟的干扰并独立调优资源,不是凭空减少计算。只有在同 workload 下,隔离收益超过未隐藏的 KV 传输、双边排队与协调开销时,SLO-goodput 才可能优于聚合部署;先测 aggregated baseline。
展开原理与工程取舍FORMULA · TRADE-OFF · FOLLOW-UP
原理拆解
Decode 需要逻辑上可访问兼容的逐层历史 K/V,而不只是最后一个 hidden state;具体实现可一次传完,也可 layer-by-layer、后台传输并隐藏部分代价。公式中应只把暴露在关键路径上的传输计入 TTFT。
NIXL 是数据传输库/connector 层,可使用 UCX、GDS 等后端并利用 NVLink、InfiniBand/RDMA 等路径;这些名词不在同一抽象层,不能并排列成可互换协议。DistServe 报告的是其评测条件下的 SLO-goodput 提升,不是所有部署的通用倍率。
TTFT_PD ≈ Q_p + T_prefill + T_KV_exposed + Q_d + T_first_decode工程取舍
分离允许 xPyD 独立伸缩和硬件异构,却增加组件、网络、容量协调和故障面;KV 传输失败需明确重算、回退聚合路径或终止,且不同后端的同步/异步语义不同。
常见误区
“Prefill 算完只传一个 hidden state”错误。后续 Decode 依赖每层历史 K/V;长上下文状态可能很大,传输是否值得取决于拓扑、重叠程度和排队收益。
面试官可能继续问
追问:在什么 KV 大小和网络拓扑下 TCP fallback 才会成为主瓶颈?Prefill worker 失败后 Decode 能否继续?怎样用同一 SLO 选择 xPyD 比例?
KV-aware Routing 为什么不能只选缓存命中最多的 Worker?#
先用大白话把它讲明白
若某个 worker 已有相同系统 Prompt 的 KV,把请求送过去可少做 Prefill;但它也可能已有很多长 Decode。只追命中,会把热点越堆越热。
只看最少连接也不够:一个 100-token 请求和一个 10000-token 请求的新增 Prefix、KV 驻留和 Decode 工作量不同,连接数相同不代表负载相同。
路由还要先满足模型/Adapter、租户、拓扑与 deadline 等硬约束,再在新增 Prefill 工作和 Decode 负载之间权衡。缓存事件可能延迟或丢失,因此“状态多精确、多久失效、失联如何回退”都是设计合同。
KV-aware 路由先过滤兼容候选,再平衡缓存 overlap 与实时负载。当前 Dynamo 的代表性代价由扣除 overlap credit 后的 Prefill blocks 和 Decode blocks 组成;只追命中会制造热点,只追最少连接会浪费可复用 KV。状态失真时应有明确的负载优先或保守回退策略。
展开原理与工程取舍FORMULA · TRADE-OFF · FOLLOW-UP
原理拆解
Dynamo 先按 allow-list、exact pin、DP rank、taint 与 busy threshold 等条件过滤候选,再对 eligible workers 比较 cost。当前配置将 cost 写成 prefill_load_scale×adjusted_prefill_blocks+decode_blocks,其中 adjusted prefill work 已应用缓存 overlap credit;这是具体实现的单位归一化,不是通用物理公式。
事件模式可由 KV cache events 更新视图;近似模式则根据路由决策预测状态并用 TTL 过期。生产还应记录候选 worker、硬约束、估算 blocks、事件/近似模式和最终选择,才能解释热点与命中下降。
eligible = hard_filter(workers);对 w∈eligible 比较 cost(w)=prefill_load_scale·adjusted_prefill_blocks(w)+decode_blocks(w)工程取舍
更精确的全局缓存索引可提升复用,却增加事件流、状态一致性与路由延迟;近似状态简单但会误判。提高 overlap credit 可能改善 TTFT,也可能把更多 Decode 压到热点 worker、伤害 ITL。
常见误区
“一致性哈希就等于 KV-aware”错误。一致性哈希稳定映射键,却通常不知道块级 prefix overlap、实时 Decode 负载、LoRA/模型兼容与 deadline。
面试官可能继续问
追问:Router 状态过期怎样降级?长公共前缀造成单点热点怎么办?跨可用区命中是否值得网络代价?
过载时怎样做 Admission Control、Backpressure、Load Shedding 和降级?#
先用大白话把它讲明白
过载不是“服务器忙一点”,而是到达工作量长期超过可完成能力,队列持续增长。若仍全部接收,请求会在超时前占住 KV、内存与连接,重试又会放大负载,最终拖死原本能按时完成的请求。
Admission Control(准入控制)在入口估算 token/KV 成本、配额和 deadline;Backpressure(背压)让上游减速;Load Shedding(丢弃负载)主动拒绝;降级可缩短输出、切小模型、关闭昂贵工具或转异步。
HTTP 429 表示请求触发了客户端/租户或资源的速率限制,503 表示服务因临时过载或维护不可用;两者都可以带 Retry-After。返回码与是否可安全重试是两份合同,写操作仍需幂等键。
过载保护要守住可完成请求的 SLO:按预测成本、队列、租户预算和 deadline 做启发式准入,向上游背压;超预算时尽早 shedding 或进入已评测的降级模式。分别定义 429/503、Retry-After、幂等与取消传播,避免重试风暴。
展开原理与工程取舍FORMULA · TRADE-OFF · FOLLOW-UP
原理拆解
“过了 deadline 就没有价值”只适用于有明确截止时间的同步交互请求;异步批任务可能仍有价值,应进入另一队列和 SLO。被取消的工作还必须传播到 scheduler、KV allocator 与工具链,否则客户端离开了,GPU 仍在烧。
限流可按 requests、input tokens、output budget、concurrent sequences 或 KV blocks;多维预算更贴合 LLM 成本。准入的 predicted_finish 和 predicted_cost 都是估计值,需用线上误差与公平性持续校准。
admit ⇐ estimated_cost fits budgets ∧ estimated_finish ≤ deadline(启发式,不是确定性保证)工程取舍
保守准入减少尾延迟但会增加拒绝;切小模型或缩输出提高可用性,却可能降质量,因此降级路径也要单独评测、标识和观测。过度重试会把局部过载变成级联故障。
常见误区
“加一个无限队列就能吸收突发”错误。队列只是推迟失败;没有上限、deadline 和取消传播,会放大 KV、连接、超时与重试风暴。
面试官可能继续问
追问:VIP 与普通租户怎样公平?429 与 503 分别何时返回?取消请求为何仍可能消耗 GPU?
系统设计的最后一半,是证明失败不会扩散且可以回退
发布、Worker 丢失、网络抖动与指标缺口都会发生。要区分可重试的计算和不可重复的外部副作用。
Worker 故障、滚动升级和客户端重试怎样设计,才不会重复输出或重复副作用?#
先用大白话把它讲明白
纯文本生成可以重新计算,但那是一次新的生成:随机采样、运行时和外部上下文可能让答案不同,已经流给客户端的 token 也无法收回。协议要明确是报错、从头重试,还是由客户端展示不完整结果。
更危险的是下单、发邮件等写操作。超时只说明客户端没收到结果,第一次调用可能已经成功;自动重试非幂等请求前,必须确认请求未生效,或用业务幂等键、状态查询和事务式 outbox 去重。
滚动升级的目标是停止接新请求并在 grace period 内 drain,但 Kubernetes 不保证“Endpoint 先摘除、然后才发 TERM”的串行顺序;本地终止与控制面的 EndpointSlice 更新会并行发生,外部负载均衡还可能继续送来短暂滞后流量。
把路由摘除、应用停止接单和 drain 设计为可重叠且幂等的过程,不能依赖一个理想顺序。流式生成失败要声明重算语义;工具写操作用持久业务幂等键和状态查询。发布单元绑定模型、Tokenizer、Prompt、Adapter 与 KV 兼容版本,异常停止放量并回滚。
展开原理与工程取舍FORMULA · TRADE-OFF · FOLLOW-UP
原理拆解
Kubernetes 终止时,若配置了 preStop 且 grace period 非零,kubelet 会先执行该 hook,再向容器发送 TERM;与此同时控制面更新 EndpointSlice,终止中的 endpoint 通常 ready=false,并可用 serving condition 表示是否仍在 drain。默认 grace period 是 30 秒,超时后会强制终止。
RFC 9110 只允许客户端在请求是幂等的、或能确认原请求从未生效时自动重试非幂等请求。Exactly-once 不是网络天然保证,而要由幂等业务键、持久结果与去重实现。
工程取舍
长 drain 提高完成率,却拖慢发布和故障恢复;快速 kill 简单但增加重算、断流与重试。高风险写操作应优先正确性,并把外部负载均衡传播延迟纳入 grace period。
常见误区
“HTTP 请求超时说明服务端没有执行”错误。超时只说明客户端没按时收到结果,服务端、数据库或外部工具可能已经完成。
面试官可能继续问
追问:已流 50 个 token 后 worker 挂了怎么办?KV 能否复制?怎样防止新旧 Tokenizer 或 KV namespace 混用?
一套可定位瓶颈的 Serving 可观测性,至少要记录什么?#
先用大白话把它讲明白
只有 GPU 利用率,无法解释用户为什么慢。要用同一个请求 ID 串起网关、排队、Prefill、Prefix 命中、KV 传输、Decode 与流式网络,并同时保留客户端观测边界。
请求记录至少包含匿名 ID、release/model/Prompt/Adapter 版本、输入输出 token、finish reason、错误、取消和关键阶段时间。聚合指标看 RED(Rate、Errors、Duration,速率/错误/时延)与 saturation,再看 TTFT/TPOT/E2E、队列、batch、KV、GPU 和网络。
Trace 定位一次慢请求,Metric 发现总体趋势,Log 记录离散状态变化。Prompt 可能含敏感数据,默认只记录受控元数据、哈希或脱敏样本;request_id、tenant_id 等高基数字段不能直接成为常规 metric label。
建立请求级 trace,把 queue、prefill、KV hit/transfer、decode 和 network 分段;指标覆盖 RED、saturation、TTFT/TPOT/E2E、token/长度分布、队列、batch、KV 与 GPU/网络,并绑定 release 版本。日志用于状态解释但要脱敏;告警绑定 SLO 和错误预算。
展开原理与工程取舍FORMULA · TRADE-OFF · FOLLOW-UP
原理拆解
Span 可能嵌套或并行,服务端各阶段不能机械相加;应按关键路径与客户端 E2E 对账。差额再检查未追踪网络、缓冲、时钟偏差与采样缺口。vLLM 当前已有 queue/prefill/TTFT/ITL/E2E、running/waiting、KV usage 和 NIXL transfer 等指标可作为实现参考。
OpenTelemetry GenAI Semantic Conventions 截至本页核查时仍标为 Development。可借用其通用模型、token usage 与 operation 字段,但应钉住约定版本,并以自己的稳定 schema 承载业务成功、租户和内部调度字段。
client_E2E ≈ critical_path(traced_spans) + untraced_network/client_buffer(不是所有 span 的简单求和)工程取舍
高基数 trace 与细粒度指标定位能力强,却增加存储和性能开销;通常全量低基数聚合、错误全采,正常请求按概率、尾延迟或 exemplar 采样。
常见误区
“GPU 利用率 100% 就代表系统优化到头”错误。它可能来自低效 kernel、memory stall 或长 Prefill;用户 SLO-goodput 仍可能很差。
面试官可能继续问
追问:哪些 label 会造成指标高基数爆炸?如何从 token 级 query/hit 计数解释 Prefix Cache?P99 告警窗口怎样防抖?
给你一个企业聊天模型,怎样在 30 分钟内完成 Serving 系统设计?#
先用大白话把它讲明白
先问清模型大小、上下文、输入/输出分布、峰值到达过程、地域、租户、SLO、安全与预算。没有数据就显式声明假设,并写出可被 benchmark 推翻的基线。
接着画最小主链:网关鉴权与准入、负载路由、聚合式 Prefill+Decode worker、KV/Prefix Cache 和流式输出;按目标硬件上代表性 workload 的 SLO-goodput 与 KV 容量估完整 replica/并行组,而不是直接估“几张卡”。
最后主动谈失败:过载怎样拒绝或降级,worker 怎样 drain,版本怎样灰度回滚,观测怎样定位 TTFT/TPOT,租户怎样隔离。只有数据证明长 Prompt 干扰、缓存局部性或独立伸缩有收益,才加 KV-aware 路由、P/D 分离与全局状态。
我按“需求/SLO → workload → 聚合数据面 → 容量 → 过载/故障 → 验证”回答。先量化长度、到达率、尾延迟与成功率;画准入、负载路由、worker、KV 和流式输出;以实测 SLO-goodput 估完整调度单元并留故障余量,再补降级、幂等、灰度、隔离和分阶段指标。复杂拓扑用 A/B benchmark 证明后再加。
展开原理与工程取舍FORMULA · TRADE-OFF · FOLLOW-UP
原理拆解
容量不能用峰值 FLOPS 除理论单请求 FLOPs。先在目标硬件、引擎版本和代表性 workload 下得到每个完整 replica/parallel group 的 goodput frontier;N+1 指再留一个完整调度单元,不等于随手加一张 GPU。
若要承受一个 fault domain 损失比例 f_loss,应先算健康需求 N_healthy,再反推总配置;若故障是整机架/可用区,f_loss 也必须按该域定义。架构先守住聚合基线,P/D 与全局 KV 是可选演进,不是标准答案的必装组件。
N_healthy = ceil(D_peak / G_replica);N_provisioned ≥ ceil(N_healthy / (1−f_loss))工程取舍
简单聚合部署更易运维;分离、全局缓存和复杂路由可能提高特定 workload 的 SLO-goodput,却扩大状态、网络和故障面。设计应给触发条件、回退路径与逐步演进。
常见误区
“系统设计题要尽可能画多组件”错误。面试官更看重假设、量纲、关键路径、取舍和验证;没有证据的 KV-aware、P/D 或跨区缓存只是在增加故障面。
面试官可能继续问
追问:流量翻三倍先改哪里?跨地域怎么做?一个租户 100K Prompt 如何防止拖垮其他租户?