外观
GPU 资源耗尽与推理服务雪崩故障复盘
30 秒复盘结论: 这是一场故障演练:少量超长输入和 KV Cache 增长使 GPU 显存接近极限,碎片化触发 OOM;实例反复重启后客户端继续重试,队列和并发进一步放大,形成推理雪崩。止损是限制 Token、负载丢弃、熔断重试并降级到小模型;长期修复是以 Token 和显存为单位做容量门禁,结合连续批处理、显存水位、预热实例和可回滚扩缩容。当前没有真实 GPU 型号、峰值流量或容量数字。
目录
1. 摘要与小白解释
想象餐厅只有一张有限大小的操作台。普通订单占一小块位置,但突然来了一批超大宴会单,厨师把食材铺满台面;即使还有零散空位,也放不下新的整盘菜。厨师不断重启清台,门外顾客却因为等待而重复下单,最终订单更多。
操作台对应 GPU 显存,零散空位对应碎片,宴会单对应超长上下文和大 KV Cache,重复下单对应客户端重试,备用小菜单对应小模型降级。类比忽略了张量并行、权重常驻、Prefix Cache、CUDA Graph 和硬件故障。
| 项目 | 内容 |
|---|---|
| 现象 | OOM、实例重启、队列堆积、延迟上升、重试放大 |
| 直接原因 | 单请求显存峰值与碎片触发分配失败 |
| 根本原因 | 准入只按请求数,不按 Token、KV Cache 和显存预算 |
| 止损 | Token 限制、负载丢弃、熔断重试、小模型降级 |
| 修复 | 容量门禁、连续批处理、显存水位、预热实例 |
2. 故障教学图片
图:故障教学图片|GPU OOM、重试反馈与容量恢复
替代文本: 请求入口、批处理队列、模型服务、GPU 显存和扩缩容形成推理链路;超长输入、碎片和 OOM 引发实例重启与客户端重试,通过 Token 限制、负载丢弃、熔断和容量门禁恢复,事实边界为故障演练。
教学图片待人工审图请求入口、批处理队列、模型服务、GPU 显存和扩缩容形成推理链路;超长输入、碎片和 OOM 引发实例重启与客户端重试,通过 Token 限制、负载丢弃、熔断和容量门禁恢复,事实边界为故障演练 暂不公开,正文与 Mermaid 图可正常阅读。
读图结论: 恢复 GPU 容量前必须先切断客户端重试和实例重启之间的正反馈回路。
红色回路表示 OOM、重启、排队与重试互相放大;绿色路径按 Token 和显存预算逐步恢复。图片不表达具体显存大小和模型参数量。
图片生成记录: model=gpt-image-2,generated=2026-07-15,prompt_version=v1;查看 Prompt。PNG C2PA 记录 softwareAgent=gpt-image、version=2.0。
质检状态: Agent 已检查文字、箭头与演练标签;维护者审图待完成。
3. 证据、影响与指标
| 结论 | 类型 | 证据或验证动作 |
|---|---|---|
| GPU 使用率高说明显存不足 | 不成立 | 计算利用率与显存水位是不同维度 |
| OOM 一定因为流量大 | 不成立 | 超长单请求、碎片和模型配置也可能触发 |
| 客户端重试会扩大恢复压力 | 工程风险 | Trace 比较入口请求与实际 attempt 数 |
| 本文描述真实容量事故 | 不成立 | 没有真实运行指标和实例日志 |
合成证据字段:request_id、model_id、input_tokens、max_output_tokens、batch_size、kv_cache_bytes、gpu_memory_used、largest_free_block、queue_depth、oom_count、restart_count、retry_count、degrade_target。
text
token_admission_load = 在途请求的预计输入 Token 与最大输出 Token 之和
retry_amplification = 推理 attempt 总数 / 入口业务请求数
oom_restart_loop_count = 窗口内因 OOM 重启后再次 OOM 的实例次数指标按模型、GPU 类型、实例、输入长度桶和批处理策略分组。显存安全水位、队列上限和降级阈值必须通过目标模型与硬件基准测试确定。
相对时间线:T0 注入超长输入和碎片场景;T0+1 实例 OOM;T0+2 重启期间队列增长;T0+3 客户端重试放大;T0+4 限制 Token、熔断和降级;T0+5 预热健康实例并灰度恢复。
4. 技术栈与架构
4.1 技术点清单
| 技术点 ID | 技术点/环节 | 类型 | 采用方案 | 链路职责 | 版本/证据边界 |
|---|---|---|---|---|---|
| TP-01 | 容量准入 | 服务 | Token/显存估算加有界队列 | 在进入 GPU 前拒绝不可承载请求 | 需硬件基准 |
| TP-02 | 批处理 | 推理机制 | 连续批处理与长度感知调度 | 提高吞吐并限制头阻塞 | 需真实模型验证 |
| TP-03 | 故障隔离 | 服务治理 | OOM 熔断、重试抑制、小模型降级 | 切断雪崩反馈回路 | 待演练 |
| TP-04 | 容量恢复 | 基础设施 | 显存水位、预热池、可回滚扩缩容 | 恢复健康实例而非反复冷启动 | 依赖部署平台 |
图:架构|推理准入、批处理、GPU 实例与降级边界
替代文本: 请求经 Token 校验和容量准入进入有界队列,长度感知调度器组成连续批次并调用 GPU 模型服务;显存与队列指标控制熔断、降级和预热实例扩容。
图表加载中…
读图结论: 容量控制必须在请求进入 GPU 队列前生效,扩容不能代替准入和重试抑制。
5. 故障与恢复流程
图:技术调用流程|OOM 后切断反馈、降级与灰度恢复
替代文本: 请求到达容量门禁,超长输入或无剩余显存时被拒绝或降级;若运行中 OOM,实例从服务发现摘除、停止客户端重试并保留证据,预热实例健康后才小流量恢复。
图表加载中…
读图结论: OOM 后应先摘除和熔断,再预热验证;让流量继续击中重启实例只会延长雪崩。
6. 止损、根因与选型
止损顺序:冻结模型和批处理配置;入口限制输入与最大输出 Token;停止客户端和网关自动重试;摘除 OOM 循环实例;丢弃低优先级负载;降级到容量已确认的小模型;保留关键流量;预热后小比例恢复。
- 直接原因: 超长请求和碎片导致单次显存分配失败。
- 根本原因: 准入仅按 QPS/请求数,未把 Token、KV Cache、批次和显存水位纳入容量模型。
- 促成因素: 无界队列、实例冷启动、重试不带预算、健康检查只看进程存活。
- 非原因: 仅看到 GPU 利用率高不足以证明根因;CPU、网络和模型加载也需排除。
- 防线失效: 压测使用固定短输入,没有覆盖长度分布、碎片和 OOM 重启循环。
| 技术点 ID | 候选方案 | 优点 | 缺点/代价 | 适用场景 | 不适用场景 | 选择结论与依据 |
|---|---|---|---|---|---|---|
| TP-01 | 按请求数限流 | 简单 | 不区分长短请求 | 长度稳定 | LLM 可变上下文 | 不足 |
| TP-01 | Token/显存容量准入 | 更贴近资源 | 需要估算校准 | LLM 在线推理 | 无 Token 概念的服务 | 采用 |
| TP-02 | 静态批处理 | 行为稳定 | 等待最慢请求、利用率低 | 离线同长度任务 | 在线混合长度 | 不优先 |
| TP-02 | 连续批处理 | 吞吐和调度更灵活 | 调度与观测复杂 | 在线推理 | 强确定性批次 | 采用前基准 |
| TP-03 | OOM 后原实例立即重试 | 实现简单 | 重启反馈循环 | 无 | 生产推理 | 禁止 |
| TP-03 | 熔断加受控降级 | 保护系统 | 质量可能下降 | 有可接受降级模型 | 模型不可替代的强约束任务 | 条件采用 |
| TP-04 | 只依赖自动扩容 | 自动化 | GPU 启动慢且可能无库存 | 平稳增长 | 突发雪崩 | 不足 |
| TP-04 | 预热池 + 水位扩容 | 恢复更快 | 闲置成本 | 严格在线 SLA | 成本极敏感离线任务 | 按 SLO 采用 |
7. 验证、防复发与面试表达
验证矩阵覆盖:不同输入长度分布、最大输出 Token、混合批次、碎片累积、单实例 OOM、多个实例同时 OOM、客户端重试、扩容无库存、降级模型不可用和恢复后流量回灌。除成功率外,必须核对队列边界、OOM 循环、Token 吞吐、首 Token 延迟、端到端延迟与降级质量。
防复发:建立按模型和硬件版本的容量基线;请求入口校验 Token;模型或批处理配置变更先做影子压测;健康检查包含真实小推理和显存水位;OOM 实例隔离并保留 dump;扩容前预热权重;Runbook 固定“限额—熔断—摘除—降级—预热—灰度”。
难点卡: 最难的是把可变 Token、动态批次和 KV Cache 映射成可执行准入规则,并在资源不足时保护关键请求而非平均分配失败。
反模式: 只看 GPU 利用率;把 OOM 交给进程无限重启;遇到排队就扩容;用截断输入作为无条件降级而不验证语义损失。
7.1 30 秒面试回答
这是一次 GPU 推理雪崩演练:超长输入和显存碎片触发 OOM,实例重启与客户端重试继续放大队列。我先限制 Token、熔断重试、摘除异常实例并降级小模型,根因是准入只按请求数,没有按 KV Cache 和显存预算。长期修复采用容量门禁、连续批处理、显存水位和预热实例,并通过长度分布、碎片和重启循环故障注入验证;当前没有真实容量数据。
7.2 60~90 秒与追问
排查时分开看 GPU 计算利用率、显存已用、最大连续空闲块、KV Cache、队列等待和输入长度分布,避免把所有 OOM 都归因于 QPS。先切断重试反馈,再决定丢弃、降级或扩容;扩容必须等待实例完成模型加载和真实探针。方案的边界是小模型质量需要业务基准集验证,Token 容量估算也必须按模型和硬件校准。
追问:显存碎片怎么证明?为什么连续批处理更适合在线推理?如何估算 KV Cache?扩容慢时如何保护关键租户?截断输入有什么风险?
8. 总结
一句话记忆: GPU 雪崩先切断 OOM、重启和重试反馈,再按 Token 与显存预算恢复。
- 显存容量不能只用请求数或 GPU 利用率衡量;
- 准入、队列、批处理和实例必须共享容量信号;
- OOM 后先熔断摘除,不能立即把请求打回原实例;
- 扩容需预热和灰度,降级需验证质量边界;
- 本文是故障演练,不是实际事故数据。