27届大模型面试准备(七十一):多租户 GPU 虚拟化与推理隔离工程——MIG、MPS 与噪声邻居治理

27届大模型面试准备(七十一):多租户 GPU 虚拟化与推理隔离工程------MIG、MPS 与噪声邻居治理

引言

上篇(六十九)讲 Prefill-Decode 分离,把单卡算力按阶段拆开调度;(七十)讲网关层如何把请求路由到不同实例。本篇把视角再抬一层:当一张 A100/H100 要同时服务多个业务方(多租户)时,怎么在显存、算力、延迟三个维度做隔离与复用,既把卡利用率榨干,又不让某个租户的突发流量把别人的 P99 拖垮。这是华为云、大模型推理平台岗的高频题,也是面试里最容易区分"只会调 API"和"真做过平台"的分水岭。

前文链接:A70 推理服务负载均衡与智能请求路由、A69 Prefill-Decode 分离式推理架构、A66 推理调度与弹性扩缩容工程。

复制代码
                ┌──────────────────────────────────────────┐
                │           推理网关 / 多租户调度器           │
                │  租户标识 → 路由 → 配额 → 优先级队列 → 限流 │
                └───────────────────┬──────────────────────┘
                                    │
      ┌─────────────────────────────┼─────────────────────────────┐
      │ 租户A(高优/SLA)             │ 租户B(中优)                  │ 租户C(best-effort)
      ▼                             ▼                             ▼
 ┌───────────┐              ┌───────────┐               ┌──────────────┐
 │ MIG slice │              │ MIG slice │               │ 共享 MPS 时间片│
 │ 1g.10gb   │              │ 3g.40gb   │               │ (无硬隔离)    │
 └───────────┘              └───────────┘               └──────────────┘
      │                             │                             │
      └─────────────────────────────┴─────────────────────────────┘
                                    ▼
                   ┌────────────────────────────────────┐
                   │     NVIDIA A100 80GB 单卡           │
                   │  SM 阵列 / HBM / NVLink 物理资源    │
                   └────────────────────────────────────┘

表:四种隔离手段对比

手段 隔离粒度 算力隔离 显存隔离 切换开销 典型适用场景
MIG 硬件物理切片 强(独占 SM 子集) 强(独占 HBM 分区) 中(需重建 slice) 稳定多租户、强 SLA 合同
MPS 进程级共享引擎 中(按 CUDA context 分时) 弱(共享显存池) 低 同信任域、提利用率
时间片调度 调度器级 弱(时分复用整卡) 无 低 best-effort 错峰复用
容器+Cgroup 主机级 依赖驱动/MPS 依赖驱动 低 物理机多实例混部

一、为什么推理平台必须做多租户隔离

云上推理的两个矛盾:(1) 单卡跑一个小模型太浪费,7B/13B 模型 decode 阶段显存占用可能只有 8GB,剩下 70GB 空转;(2) 把多个模型塞一张卡,某个租户来一波长上下文突发,就会把共享的 HBM 带宽和 SM 占满,别人的 TTFT 从 200ms 飙到 3s。不做隔离,利用率和公平性只能二选一。

面试常问:"你们线上一张卡跑几个模型?怎么保证互不干扰?"标准答案不是"用 Docker",而是分层:硬件切片(MIG)→ 驱动级共享(MPS)→ 调度器配额(K8s/Volcano)→ 应用级限流(网关)。

二、硬件级 MIG:把一张卡切成多张"小卡"

MIG(Multi-Instance GPU)在 A100/H100 上把 SM 阵列、L2 Cache、HBM 带宽、显存做物理分区。一个 7g.40gb 的 slice 就是一张"逻辑 GPU",有独立的显存和算力,一个 slice 的故障不影响其他 slice。

复制代码
# 创建 1 个 1g.10gb + 1 个 3g.40gb 的组合(需先置 admin 模式)
sudo nvidia-smi -i 0 -mig 1
sudo nvidia-smi mig -i 0 -cgi 1g.10gb,3g.40gb -C
# 查看 slice
nvidia-smi mig -lgi
# 输出示例:
#   GI ID  CI ID  Profile
#   9      0     1g.10gb
#   10     1     3g.40gb
# 应用侧用 CUDA_VISIBLE_DEVICES 绑定到具体 GI
CUDA_VISIBLE_DEVICES=9 python -m vllm.entrypoints.openai.api_server --model qwen2.5-7b

MIG 的代价:slice 之间不能共享 KV Cache,跨 slice 不能做张量并行;且创建/销毁 slice 需要短暂中断整卡。所以它适合"长期稳定、SLA 不同"的租户组合,不适合频繁变配。

三、驱动级 MPS:同信任域提利用率

MPS(Multi-Process Service)让多个进程共用同一个 CUDA context,kernel 在 SM 上并发调度,显存仍共享。它没有硬隔离,但能把"两张卡各跑 30% 利用率"的两个小模型合并到一张卡跑 60%,省一张卡的钱。

复制代码
# 启动 MPS 服务端(按用户/按卡)
export CUDA_VISIBLE_DEVICES=0
nvidia-cuda-mps-control -d
# 之后该卡上的所有 CUDA 进程都走 MPS 共享引擎
# 限制单进程可用 SM 比例(需 MPS 配置 + 配合 cgroups)
echo "set_default_active_thread_percentage 50" | nvidia-cuda-mps-control

注意 MPS 下的故障传染:一个进程显存越界可能拖垮同 context 的其他进程。所以 MPS 只在"同团队、同信任等级"的内部租户间用,对外售卖必须用 MIG。

四、显存配额与上下文隔离

即使不用 MIG,也要防止某个租户申请超大 KV Cache 把整卡 OOM。做法是在调度器层给每个模型实例设显存预算,并在推理引擎里做硬性上限。

复制代码
# 伪代码:按租户维度限制 KV Cache 预算
class TenantGPUScheduler:
    def __init__(self, total_hbm_gb=80):
        self.budget = {}          # tenant -> 显存配额(GB)
        self.used = {}            # tenant -> 已用(GB)

    def admit(self, tenant, need_gb):
        if self.used.get(tenant, 0) + need_gb > self.budget.get(tenant, 0):
            return False, "tenant_gpu_quota_exceeded"
        if sum(self.used.values()) + need_gb > self.total_hbm_gb * 0.92:
            return False, "node_hbm_pressure"
        self.used[tenant] = self.used.get(tenant, 0) + need_gb
        return True, "ok"

    def release(self, tenant, free_gb):
        self.used[tenant] = max(0, self.used.get(tenant, 0) - free_gb)

五、噪声邻居(Noisy Neighbor)治理

"噪声邻居"指同卡其他租户的突发把你的延迟拖垮。治理三板斧:

  1. 优先级抢占:高优租户到来时,低优租户的长 decode 被挂起或限速。

  2. 带宽隔离:MIG 天然隔离 HBM 带宽;非 MIG 场景用 MPS thread percentage + 限流近似。

  3. 延迟 SLO 监控:每个租户独立打 P99,越界自动触发扩容或迁移。

    优先级队列 + 加权公平调度(WRR)

    import heapq

    class PriorityAdmitter:
    def init(self):
    self.queues = {0: [], 1: [], 2: []} # 0高 1中 2低

    复制代码
     def schedule(self):
         # 高优先发,中优按权重,低优有空才发
         for level in (0, 1, 2):
             if self.queues[level]:
                 return self.queues[level].pop(0)
         return None

六、调度器层:K8s Device Plugin 与公平性

在 K8s 上,MIG 通过 nvidia.com/mig-1g.10gb 这类扩展资源暴露,Volcano / 自研调度器按租户 namespace 做配额(ResourceQuota)和优先级(PriorityClass)。避免"一个租户 Pod 占满节点 MIG slice 导致别人 Pending"。

面试速答

问:MIG 和 MPS 有什么区别,什么时候用哪个?

答:MIG 是硬件物理切片,算力和显存都硬隔离,故障不传染,适合对外多租户强 SLA;MPS 是驱动级共享引擎,提利用率但不隔离,故障可能传染,适合内部同信任域复用。对外卖算力用 MIG,内部提效用 MPS。

问:一张卡跑多个模型,怎么防止 OOM 互相影响?

答:三层------硬件用 MIG 物理隔离显存;驱动/调度层给每实例设显存预算和 KV Cache 上限;节点层保留 8% HBM 余量防整卡 OOM。

问:噪声邻居怎么治?

答:优先级抢占 + 带宽/算力配额 + 每租户独立 P99 SLO 监控,越界自动限速、扩容或迁移。

高频追问清单

  1. MIG slice 之间能共享 KV Cache 吗?跨 slice 张量并行有什么限制?
  2. MPS 故障传染的根因是什么,生产上怎么规避?
  3. best-effort 租户和 SLA 租户混部,调度器怎么做加权公平?
  4. 显存预算按 tenant 还是按 model instance 计量更合理?长上下文突发怎么处理?
  5. K8s 上 MIG 资源如何暴露和做 namespace 配额?
  6. 节点 HBM 压力时,应该拒绝新请求还是抢占低优请求?怎么选?
  7. 租户级限流(QPS/并发)和 GPU 配额怎么联动?
  8. 单卡多模型场景下,NVLink 带宽争用怎么观测和隔离?
相关推荐
程序猿编码4 天前
告别改源码适配模型:纯 C++ 可配置 LLM 推理引擎,全格式全结构兼容
c++·大模型·llm·推理引擎
蔡俊锋4 天前
华为昇腾 960 超节点发布:4096 卡、5500 个光引擎替 4.8 万光模块——国产算力拐点到了吗?
大模型·模型部署·ai架构·国产算力·华为昇腾
O。O蛋黄酥啊4 天前
Claude Code 记忆机制全拆解:Auto Memory 与 CLAUDE.md 双轨解析
大模型·agent·memory·claude·codex·记忆
BlackStar_L4 天前
第二章 上下文工程
大模型·llm·agent
User_芊芊君子4 天前
让 Claude Code 换上国产大脑:蓝耘元生代上 GLM-5.2 / DeepSeek / Qwen 模型横评实测
人工智能·ai·大模型
寻道码路4 天前
大模型工程化实战(十二):RAG 数据工程底座——采集到入库流水线(离线+在线双链路)
大模型·知识库·rag·ai工程化·llmops`·数据工程底座·文档采集
Web3&Basketball5 天前
CRM Agent 后训练实战:3 倍更少错误
python·架构·大模型·agent·推理
蚁小二官方5 天前
AI 安全治理框架更新|大模型训练数据合规,企业实操落地思路
大模型·数据合规·ai安全
AI模力圈5 天前
On-Policy Distillation:原理、变体与工程实现解析
大模型·强化学习·知识蒸馏
长谷深风1115 天前
根因定位:三步隔离法破解AIBadcase
人工智能·ai·大模型·retrieval·ai智能体·aiagent·aibadcase