27届大模型面试准备(九十四):大模型弹性推理与GPU资源池化工程——GPU池化/虚拟化复用/弹性扩缩/显存碎片整理

27届大模型面试准备(九十四):大模型弹性推理与GPU资源池化工程------GPU池化/虚拟化复用/弹性扩缩/显存碎片整理

引言

本文是 A 系列第 94 篇。前面 A71 讲了多租户 GPU 虚拟化与推理隔离,A66 讲了请求级的推理调度与弹性扩缩容,A92 讲了单卡显存与算力极致优化。本文把视角从"单卡/单实例"拉到"一池 GPU":如何把一堆异构、散落在不同机器的 GPU,抽象成一个统一资源池,按需切分、弹性伸缩、并持续做碎片整理,让昂贵的卡不再空转。

华为多模态 LLM 推理岗位上,一个常见局面是:白天对话流量高、深夜批处理任务多、突发活动流量尖峰。如果给每个业务静态独占整卡,浪费惊人;如果池化复用,利用率能从 20% 拉到 60%+。本文就讲这套"池化 + 弹性 + 整理"的工程栈,和 A71 的关系是:A71 关注"隔离边界",本文关注"池的供给与编排"。

复制代码
GPU 资源池化全景
==================================================
  物理层: 异构 GPU (A100/H100/...), 跨节点
      │ 虚拟化层 (MIG / MPS / 超分)
      ▼
  资源池: 统一计量(卡/切片/显存/算力)
      │ 调度层 (bin-pack / 抢占 / 弹性)
      ▼
  实例层: 多模型推理服务(按需起停)
      │ 弹性层 (HPA 式扩缩 + 碎片整理)
      ▼
  GPU 利用率↑  成本↓  SLO 稳

一、为什么需要 GPU 资源池化

传统静态分配的问题:

  • 整卡独占:一个小模型(如 0.5B 分类)占一张 80GB 卡,显存利用率可能只有 3%,算力几乎全空转。
  • 形状碎片:不同模型要不同显存/算力配比,固定分配后剩下的"边角"无法被别的任务用。
  • 峰谷浪费:为应对 1% 的流量尖峰而常备过量卡,其余时间闲置。

池化的目标三件套:时分复用 (一张卡的时间切片给多个任务)、空间切分 (一张卡的物理切片给多个任务,如 MIG)、超分(overcommit)(承诺总量超过物理容量,靠调度错峰)。

二、GPU 虚拟化的三种粒度

方式 隔离级别 切分粒度 适用 代价
MIG(硬件切片) 硬隔离(独立显存/算力) 1/7、1/4、1/2 卡 强隔离多租户 仅 A100/H100 支持,粒度固定
MPS(多进程服务) 软隔离(共享上下文) 任意比例时间片 同信任域提利用率 一进程崩可能影响同卡其他进程
整卡时分复用 进程级隔离 整卡时间片 通用、最灵活 切换有开销、无空间并行

MIG:在硬件层面把一张卡切成多个"实例",每个实例有独立的显存、L2 缓存分区和计算引擎,故障互不影响。适合强隔离场景。

bash 复制代码
# 查看并创建 MIG 实例 (A100/H100)
nvidia-smi mig -lgi                      # 列出现有
nvidia-smi mig -cgi 19,19,19,19 -C       # 切 4 个 1/4 卡实例(compute instance)
nvidia-smi mig -lgi                      # 确认
# 之后推理进程通过 CUDA_VISIBLE_DEVICES=MIG-xxx 绑定到切片

MPS:不开多份上下文,多个进程共享一个 CUDA context,按份额分时间片。提利用率明显,但隔离弱------一个进程越界可能拖垮同卡其他进程,所以只适合同信任域。

三、显存与算力超分(Overcommit)

池化要想"装下更多",常需要超分:

  • 显存超分:按需分配而非预先独占,配合抢占。风险是真正同时用满时 OOM,需要准入控制(admission control)和优先级抢占。
  • 算力超分:时间片轮转,多个低负载任务错峰跑满算力。

工程上必须配套:优先级 + 抢占。高优先级(如付费 SLA 业务)可抢占低优先级(如离线批处理)的切片,被抢占任务要么挂起要么迁走。这与 A71 的多租户优先级抢占一脉相承。

复制代码
超分示意 (物理 1 卡 = 100 单位算力)
==================================================
  不超分: 任务A 60 + 任务B 30 = 90, 余 10, 利用率 90%
  超分:   任务A 60 + 任务B 50 + 任务C 30 = 承诺140 > 100
          靠错峰: A忙时B/C闲, 实际峰值<100 -> 皆大欢喜
          风险: 三者同时忙 -> 触发抢占/降级/排队

四、弹性推理:流量驱动的扩缩容

池化之上要做"弹性"------实例数量随流量自动增减。

扩缩容信号(按敏感度排序):GPU 利用率、请求队列长度、P99 延迟(SLO)、KV Cache 占用率。通常组合判断,避免抖动(flapping)。

冷启动是弹性最大的敌人 :新实例起来要加载几 GB~几十 GB 权重、建 KV 缓存池、预热 CUDA graph。对策:

  • 权重预取 + 内存映射(mmap)减少加载时间。

  • 维持少量"热备实例"(warm pool)应对尖峰。

  • 复用 A63 的前缀缓存,让新实例承接已有对话时免重复 prefill。

python 复制代码
# 基于队列长度的弹性决策(伪代码)
def scale_decision(q_len, capacity, slo_p99):
    util = q_len / capacity
    if util > 0.8 or slo_p99 > THRESH:
        return "scale_up"          # 申请新实例(从池里分切片)
    if util < 0.2 and idle_min > 60s:
        return "scale_down"        # 释放切片回池(先排空在途请求)
    return "hold"
# 关键: scale_down 必须等实例"排空"(drain)再回收, 否则切断在途会话

缩容要小心"在途请求"------直接杀实例会丢会话。正确做法是先标记"不再接新请求",等现有请求跑完(drain)再回收切片回池。

五、碎片整理与重调度

池跑久了必然碎片:A 任务要 1/2 卡、B 要 1/4 卡、C 要 1/4 卡,三个分散在不同物理卡,剩的 1/4 凑不出一个 1/2。

整理策略

  1. 紧凑装箱(bin-pack) :新任务优先放进"最满但不溢出"的卡,留空卡整卡回收。

  2. 迁移/重调度 :低峰期把分散的小实例迁移合并,腾出整卡休眠省电。

  3. 碎片打分:监控"可用显存总和够、但最大连续块不够"的碎片化指标,超阈值触发整理。

    碎片 vs 整理后

    碎片: 卡X[ A½ ][ 空¼ ][ B¼ ] 卡Y[ C¼ ][ 空¾ ]
    想放一个 ½ 任务 -> 两卡都放不下(连续块不足)

    整理: 把 B 迁到卡Y -> 卡X 释放成整卡 [ 空1 ] 可用
    卡Y[ C¼ ][ B¼ ][ 空½ ] 也能再塞

六、调度策略:从 Gang 到 Bin-pack

调度器是池的大脑,决定"新实例去哪张卡"。

  • Spread(分散):容错好,但易碎;

  • Bin-pack(紧凑):利用率高,碎片可控,是推理池主流;

  • Gang scheduling:一组相关实例(如 TP=8)必须同时落位,否则全部等待,避免部分就绪死锁------大模型 TP 部署必备。

    推理调度器架构

    复制代码
    准入控制 ──► 碎片/容量检查
        │
    调度器 ──► bin-pack / gang / 优先级抢占
        │
    资源池 ──► MIG/MPS 切片分配
        │
    生命周期 ──► 热备/冷启/排空/回收/碎片整理
        │
    反馈环 ──► 利用率/队列/SLO 指标 -> 弹性决策

七、常见坑

现象 根因 对策
池利用率高但 SLA 崩 超分过度 / 无抢占 加准入控制、降级低优先级
MPS 一崩全崩 软隔离无故障域 同卡只放同信任域任务
扩容后更慢 权重加载慢/网络瓶颈 热备实例 + 权重预取
缩容丢会话 未排空直接回收 drain 后再回收切片
碎片导致新任务起不来 连续块不足 bin-pack + 低峰迁移整理
MIG 粒度不匹配 固定切片 按模型画像选切片组合

面试速答

  • 为什么 GPU 要池化?静态独占浪费(小模型占整卡、峰谷闲置),池化通过时分复用+空间切分+超分把利用率从 20% 拉到 60%+。
  • 三种虚拟化粒度?MIG 硬隔离(A100/H100 硬件切片)、MPS 软隔离(共享上下文时间片)、整卡时分复用(最灵活)。
  • 超分风险与配套?承诺超物理容量靠错峰;必须配优先级抢占与准入控制,峰值触发降级/排队。
  • 弹性冷启动痛点?权重加载慢;用热备实例、权重预取/mmap、复用前缀缓存缓解。
  • 碎片整理?bin-pack 紧凑装箱 + 低峰迁移合并腾整卡 + 碎片化指标触发;缩容须先 drain 排空。

高频追问清单

  1. MIG 和 MPS 在故障隔离上本质区别是什么?什么场景必须上 MIG?
  2. 超分(overcommit)在什么指标上最先爆雷?怎么设安全的超分比?
  3. 弹性缩容为什么不能直接 kill 实例?drain 在推理服务里具体怎么做?
  4. bin-pack 和 spread 对"碎片率"和"容错性"分别有什么权衡?
  5. Gang scheduling 在 TP=8 部署里解决什么死锁?没它会怎样?
  6. KV Cache 在池化/弹性下如何跨实例共享或迁移?和 A63 前缀缓存怎么结合?
  7. 多模态 LLM 视觉编码器与 LLM 头显存配比差异大,池化切分怎么为它定制?
  8. 资源池的"利用率"指标会不会骗人?除了利用率还要看哪些信号判断池健康?
相关推荐
蔡俊锋6 小时前
DeepSeek 语音对话灰度上线:四种音色背后的端侧 AI 交互架构与商业逻辑
架构·大模型·语音交互·deepseek·端侧ai
IT·陈寒9 小时前
Python的GIL问题又把我坑惨了
人工智能·大模型·api·创业·变现·简历优化
长谷深风11111 小时前
支付审批的智能风险控制设计
大数据·人工智能·ai·大模型·支付·aiagent·hitl
Java后端的Ai之路11 小时前
一文搞懂 GitHub Actions-CICD
开发语言·大模型·github·cicd·action
IT·陈寒12 小时前
React状态更新为啥有时吞了我的变更?
人工智能·大模型·api·创业·变现·简历优化
codigger13 小时前
从 LLM 到 Agent Skill:9 个底层概念,一次理清整个 AI 技术栈
ai·大模型·#人工智能·#agent
香吧香14 小时前
语义理解和向量相似度
大模型
VIP_CQCRE15 小时前
Visual Studio 接入 AI 编程助手:用 LMLocal 连接 Ace Data Cloud
ai·大模型·开发工具·visual studio·ace data cloud
微软技术分享16 小时前
基于 HuggingFace Tokenizers 训练自定义分词器
python·ubuntu·大模型·huggingface