<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>Jimmy Song – 数据平面技术</title><link>https://jimmysong.io/zh/book/ai-infra/data-plane/</link><description>Recent content in 数据平面技术 on Jimmy Song</description><generator>Hugo -- gohugo.io</generator><language>zh</language><managingEditor>Jimmy Song</managingEditor><webMaster>Jimmy Song</webMaster><follow_challenge><feedId>51621818828612637</feedId><userId>59800919738273792</userId></follow_challenge><lastBuildDate>Sat, 10 Jan 2026 10:45:55 +0800</lastBuildDate><atom:link href="https://jimmysong.io/zh/book/ai-infra/data-plane/index.xml" rel="self" type="application/rss+xml"/><item><title>数据平面谱系：切分、虚拟化与隔离机制大全</title><link>https://jimmysong.io/zh/book/ai-infra/data-plane/data-plane-taxonomy/</link><pubDate>Tue, 30 Dec 2025 05:01:33 +0000</pubDate><author>Jimmy Song</author><guid>https://jimmysong.io/zh/book/ai-infra/data-plane/data-plane-taxonomy/</guid><description>系统梳理 MIG/vGPU/时间片/配额/显存策略等机制的根本差异，并建立对比基线。</description><content:encoded>
&lt;blockquote&gt;
&lt;p&gt;真正理解 GPU 共享，先要看清数据平面的“谱系”，而不是陷入口水战。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="本章要解决什么"&gt;本章要解决什么&lt;/h2&gt;
&lt;p&gt;在 GPU 场景中，“共享”常常被误解为单一能力：要么能共享，要么不能共享。实际上，&lt;strong&gt;共享是一组数据平面机制的组合&lt;/strong&gt;，涉及设备发现与暴露、资源单位的切分方式、隔离与 QoS（Quality of Service，服务质量）的实现位置，以及容器运行时/驱动栈的具体落地方式。&lt;/p&gt;
&lt;p&gt;因此，本章不直接比较具体项目（如 HAMi、MIG、GPU Operator、GPUStack 等），而是先给出一张“数据平面谱系”，将所有 GPU 共享手段归类为可验证的机制集合。后续每个项目章节都只是把“它用了哪些机制、补了哪些治理能力”回填到这张谱系里，避免陷入口号之争。&lt;/p&gt;
&lt;h2 id="数据平面与控制面的边界"&gt;数据平面与控制面的边界&lt;/h2&gt;
&lt;p&gt;理解数据平面与控制面的分工，是分析 GPU 共享机制的基础。&lt;/p&gt;
&lt;p&gt;Kubernetes 的设备扩展机制（Device Plugin，设备插件）决定了一个基本事实：&lt;strong&gt;kubelet 的 Device Manager 负责把“可用设备”暴露为可调度资源，并在 &lt;code&gt;Allocate&lt;/code&gt; 阶段做设备侧准备；但它并不定义“更细粒度资源单位、隔离与 QoS”应该如何实现&lt;/strong&gt;。这使得更细粒度的共享天然倾向于下沉到数据平面实现。&lt;/p&gt;
&lt;p&gt;在前面的 &lt;a href="../../fundamentals/k8s-device-model/"&gt;Kubernetes 资源模型&lt;/a&gt;一章中可以看到，Kubernetes 的语义天然更接近“整卡/离散设备”而不是“连续可分的 CPU”。&lt;/p&gt;
&lt;p&gt;进一步，Kubernetes DRA（Dynamic Resource Allocation，动态资源分配）把“设备分配的对象”从扩展资源升级为更可表达的 &lt;code&gt;DeviceClass/ResourceClaim&lt;/code&gt;，使“按属性筛选、按声明分配、可共享 claim”等模式更自然。但 DRA 仍然不替你解决隔离机制本身：隔离强度、资源单位、干扰与计量，依然由数据平面决定。&lt;/p&gt;
&lt;p&gt;本书的基本坐标系如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;控制面&lt;/strong&gt;：处理队列、配额、优先级、公平性、准入与编排策略。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据平面&lt;/strong&gt;：处理设备发现/暴露、切分与虚拟化、隔离与 QoS、可观测与计量，以及运行时注入（mount/env/hooks/CDI 等）。&lt;/li&gt;
&lt;/ul&gt;
&lt;figure class="mx-auto text-center"&gt;
&lt;img src="https://assets.jimmysong.io/images/book/gpu-infra/data-plane/data-plane-taxonomy/control-plane-data-plane.svg" data-img="https://assets.jimmysong.io/images/book/gpu-infra/data-plane/data-plane-taxonomy/control-plane-data-plane.svg" alt="图 1: Kubernetes GPU 共享：数据平面 vs 控制面边界" data-caption="图 1: Kubernetes GPU 共享：数据平面 vs 控制面边界"
width="1507"
height="1763"
loading="lazy" decoding="async" class="image-loading"
onload="this.classList.remove('image-loading'); this.classList.add('image-loaded');"
onerror="handleImageError(this); this.classList.remove('image-loading');"&gt;
&lt;figcaption&gt;图 1: Kubernetes GPU 共享：数据平面 vs 控制面边界&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="数据平面谱系从强隔离硬切分到软约束过量订阅"&gt;数据平面谱系：从“强隔离硬切分”到“软约束过量订阅”&lt;/h2&gt;
&lt;p&gt;所有“GPU 共享”机制可以粗略放在一条谱系线上：从&lt;strong&gt;硬切分（强隔离、单位离散）&lt;strong&gt;逐步走向&lt;/strong&gt;软约束/过量订阅（灵活，但隔离依赖实现与负载行为）&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;下图以谱系轴展示常见 GPU 数据平面机制的相对位置与交付层关系。&lt;/p&gt;
&lt;figure class="mx-auto text-center"&gt;
&lt;img src="https://assets.jimmysong.io/images/book/gpu-infra/data-plane/data-plane-taxonomy/data-plane-taxonomy-spectrum.svg" data-img="https://assets.jimmysong.io/images/book/gpu-infra/data-plane/data-plane-taxonomy/data-plane-taxonomy-spectrum.svg" alt="图 2: GPU 数据平面谱系" data-caption="图 2: GPU 数据平面谱系"
width="1503"
height="1123"
loading="lazy" decoding="async" class="image-loading"
onload="this.classList.remove('image-loading'); this.classList.add('image-loaded');"
onerror="handleImageError(this); this.classList.remove('image-loading');"&gt;
&lt;figcaption&gt;图 2: GPU 数据平面谱系&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;下面按照“机制原语”进行分类（不是按项目），并分别介绍其核心特征和适用场景。&lt;/p&gt;
&lt;h3 id="独占baseline整卡分配--pass-through"&gt;独占（Baseline）：整卡分配 / Pass-through&lt;/h3&gt;
&lt;p&gt;作为所有对比的基线，Pod/容器独占一整张 GPU。这种方式的优点是性能与故障域最清晰；缺点是利用率在推理、小 batch、间歇任务上通常较低。它本质上不提供“共享”，但会作为后续实验的基线参照（吞吐、P99、显存碎片、稳定性）。&lt;/p&gt;
&lt;h3 id="硬切分partitionmig-这类硬件级资源单元化"&gt;硬切分（Partition）：MIG 这类“硬件级资源单元化”&lt;/h3&gt;
&lt;p&gt;MIG（Multi-Instance GPU，多实例 GPU）的关键价值不是“能分”，而是&lt;strong&gt;把 GPU 的关键路径拆成多个具有更强隔离边界的硬件实例&lt;/strong&gt;。以 NVIDIA 官方定义，MIG 让每个实例在内存系统关键路径上具备独立隔离：包括 crossbar 端口、L2 cache bank、memory controller 与 DRAM 地址总线等，从而得到更可预测的吞吐与延迟。&lt;/p&gt;
&lt;p&gt;这类硬切分机制的典型特征包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;资源单位离散&lt;/strong&gt;：获得的是一组固定规格的 slice/instance，而不是任意比例。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;隔离强度高&lt;/strong&gt;：至少在显存带宽/缓存等关键资源上更可控。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;动态调整成本高&lt;/strong&gt;：切分/重配通常需要运维动作，甚至影响同卡其他实例的生命周期与排空策略。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;兼容性好&lt;/strong&gt;：对上层框架基本透明（“像一张小 GPU”）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;适用场景：多租户推理、对 P99 敏感、需要更强“性能可预测性与故障隔离”的场景。&lt;/p&gt;
&lt;h3 id="介导虚拟化mediated--vgpu以-mdevvgpu-为代表的多虚拟设备"&gt;介导虚拟化（Mediated / vGPU）：以 mdev/vGPU 为代表的“多虚拟设备”&lt;/h3&gt;
&lt;p&gt;vGPU（Virtual GPU，虚拟 GPU）以及 Linux 里的介导设备（mediated device, mdev）思路，是通过虚拟化层将一块物理 GPU 呈现为多个“虚拟 GPU 设备”。这类机制常见于虚拟机（VM, Virtual Machine）场景，也可扩展到容器，但工程复杂度显著提升。NVIDIA 官方 vGPU 文档将其定义为一种图形/计算虚拟化平台，使多台 VM 可同时访问同一块物理 GPU。&lt;/p&gt;
&lt;p&gt;这类机制的典型特征：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;资源单位通常离散&lt;/strong&gt;（按 profile/类型划分），但比 MIG 更“软件化”。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;隔离与 QoS 依赖实现&lt;/strong&gt;：隔离边界通常弱于硬切分，但比纯时间片更可控（取决于实现与硬件能力）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;运维与许可复杂&lt;/strong&gt;：驱动栈、宿主/来宾驱动、虚拟化层集成、部分场景下商业许可等，会使“可部署性”成为主要约束。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;适用场景：强虚拟化/VM 优先的企业环境、需要 VM 级隔离边界、或已有既定 vGPU 栈的组织。&lt;/p&gt;
&lt;h3 id="时间片time-slicing在同一物理-gpu-上交错运行多个工作负载"&gt;时间片（Time-Slicing）：在同一物理 GPU 上交错运行多个工作负载&lt;/h3&gt;
&lt;p&gt;时间片共享的核心是&lt;strong&gt;过量订阅（oversubscription）&lt;/strong&gt;：多个 Pod/容器被调度到同一张 GPU 上，由驱动/插件在执行层面交错运行。NVIDIA GPU Operator 明确提供了 time-slicing 的配置路径，本质是通过设备插件的扩展能力实现“共享访问”。&lt;/p&gt;
&lt;p&gt;需要特别强调，时间片与 MIG 的差异非常明显。部分平台文档也指出，MIG 提供内存与故障隔离，而时间片并不具备同等强度的隔离，更多是为了提升利用率，适配轻量推理/预处理等场景。&lt;/p&gt;
&lt;p&gt;这类机制的典型特征：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;资源单位“看起来可分”&lt;/strong&gt;（可以声明更多份额），但隔离往往较弱。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;性能与尾延迟不确定&lt;/strong&gt;：尤其在显存压力、kernel launch 冲突、PCIe 抖动等情况下，P99 往往是首要风险点。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;动态灵活&lt;/strong&gt;：适合快速提高利用率，但需要强观测与强准入策略来收敛风险。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;适用场景：轻量推理、容忍干扰、以利用率为先且有完善观测/限流/准入的场景。&lt;/p&gt;
&lt;h3 id="进程级协作共享cuda-mps-这类协作式多进程并发"&gt;进程级协作共享：CUDA MPS 这类“协作式多进程并发”&lt;/h3&gt;
&lt;p&gt;MPS（Multi-Process Service，多进程服务）是 NVIDIA 提供的一种 CUDA API 兼容实现，通过客户端 - 服务端架构让多个进程更高效地共享 GPU 的执行资源。该机制常用于 HPC（High Performance Computing，高性能计算）/MPI 等场景，以利用 Hyper-Q 能力。&lt;/p&gt;
&lt;p&gt;这类机制的典型特征：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;更像“并发执行效率优化”而非“资源治理”&lt;/strong&gt;：改善多进程并发的利用方式，但并不天然提供“多租户隔离语义”。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;适配负载类型&lt;/strong&gt;：对某些 workload 显著收益，但对推理/多租户治理不一定直接等价。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;工程落点微妙&lt;/strong&gt;：经常出现在数据平面方案的“内部实现”中，而不是用户显式选择的产品特性。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;适用场景：协作式多进程计算、HPC/训练类并发模式；在平台侧更常作为内部优化手段。&lt;/p&gt;
&lt;h3 id="容器设备暴露与注入机制cdi-让怎么把设备交付给容器更标准化"&gt;容器设备暴露与注入机制：CDI 让“怎么把设备交付给容器”更标准化&lt;/h3&gt;
&lt;p&gt;无论你使用 MIG、vGPU 还是时间片，最终都要回答一个问题：&lt;strong&gt;设备如何以一致、可审计、可组合的方式注入到容器运行时&lt;/strong&gt;。NVIDIA Container Toolkit 已支持生成 CDI（Container Device Interface，容器设备接口）规范，用于标准化“容器如何使用设备”的描述。&lt;/p&gt;
&lt;p&gt;这不是隔离机制本身，但它影响方案的可落地性：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;能否把设备注入从“运行时魔法参数”变成“声明式、可审计、可复制的交付单元”。&lt;/li&gt;
&lt;li&gt;能否在多种运行时/编排方式中复用同一套设备交付逻辑。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="五维对比基线把概念争论变成可回填的矩阵"&gt;五维对比基线：把概念争论变成可回填的矩阵&lt;/h2&gt;
&lt;p&gt;为了便于后续章节统一对比，下面给出一张五维对比表，涵盖主流机制的资源单位、隔离强度、性能损耗、动态调整成本和兼容性等维度。&lt;/p&gt;
&lt;p&gt;表格用于对比各类 GPU 共享机制的核心特征：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;机制类型&lt;/th&gt;
&lt;th&gt;资源单位&lt;/th&gt;
&lt;th&gt;隔离强度&lt;/th&gt;
&lt;th&gt;性能损耗/干扰&lt;/th&gt;
&lt;th&gt;动态调整成本&lt;/th&gt;
&lt;th&gt;兼容性/落地复杂度&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;独占（整卡）&lt;/td&gt;
&lt;td&gt;整卡&lt;/td&gt;
&lt;td&gt;最高&lt;/td&gt;
&lt;td&gt;最稳定&lt;/td&gt;
&lt;td&gt;低&lt;/td&gt;
&lt;td&gt;最简单&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;硬切分（MIG）&lt;/td&gt;
&lt;td&gt;离散实例&lt;/td&gt;
&lt;td&gt;高（硬件路径隔离）&lt;/td&gt;
&lt;td&gt;较稳定&lt;/td&gt;
&lt;td&gt;中 - 高&lt;/td&gt;
&lt;td&gt;较好&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vGPU/mdev&lt;/td&gt;
&lt;td&gt;离散 profile/虚拟设备&lt;/td&gt;
&lt;td&gt;中 - 高（依实现）&lt;/td&gt;
&lt;td&gt;中（依实现）&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;td&gt;高（栈复杂）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;时间片&lt;/td&gt;
&lt;td&gt;份额/过量订阅（时间片）&lt;/td&gt;
&lt;td&gt;低 - 中&lt;/td&gt;
&lt;td&gt;干扰显著（看负载）&lt;/td&gt;
&lt;td&gt;低&lt;/td&gt;
&lt;td&gt;中（需策略兜底）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MPS&lt;/td&gt;
&lt;td&gt;非显式单位&lt;/td&gt;
&lt;td&gt;低（偏效率优化）&lt;/td&gt;
&lt;td&gt;依负载而定&lt;/td&gt;
&lt;td&gt;低&lt;/td&gt;
&lt;td&gt;中（对模型/作业形态敏感）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CDI（交付层）&lt;/td&gt;
&lt;td&gt;设备交付单元&lt;/td&gt;
&lt;td&gt;不定义隔离&lt;/td&gt;
&lt;td&gt;不直接影响&lt;/td&gt;
&lt;td&gt;低&lt;/td&gt;
&lt;td&gt;降低集成碎片&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;figcaption class="text-center mb-3"&gt;
表 1: GPU 共享机制五维对比基线
&lt;/figcaption&gt;
&lt;h2 id="组合规律端到端方案通常是控制面治理--数据面机制--观测计量"&gt;组合规律：端到端方案通常是“控制面治理 + 数据面机制 + 观测计量”&lt;/h2&gt;
&lt;p&gt;理解数据平面谱系后，端到端方案的组合就会更清晰：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;先确定资源单位&lt;/strong&gt;：整卡 / MIG / vGPU / 时间片份额。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;再补齐治理能力&lt;/strong&gt;：队列、配额、公平性、准入、优先级（控制面）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;最后用观测与计量闭环&lt;/strong&gt;：否则“共享”只是在赌负载行为（后续《观测与计量》《验收与容量》会详细展开）。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="四种共享策略速查"&gt;四种共享策略速查&lt;/h2&gt;
&lt;p&gt;把谱系压缩成一张决策表（一块生产级 H100 造价 35000 美元以上、提供约 3958 TFLOPS 的 FP16 Tensor 算力，在它上面跑一个小推理工作负载，就像包一架 747 只为送一位乘客）：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;策略&lt;/th&gt;
&lt;th&gt;硬件隔离&lt;/th&gt;
&lt;th&gt;内存隔离&lt;/th&gt;
&lt;th&gt;K8s 资源&lt;/th&gt;
&lt;th&gt;适用场景&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;整卡独占&lt;/td&gt;
&lt;td&gt;完全&lt;/td&gt;
&lt;td&gt;完全（全部显存）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nvidia.com/gpu: 1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;大模型训练、极致性能工作负载&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;时间切片&lt;/td&gt;
&lt;td&gt;无&lt;/td&gt;
&lt;td&gt;无（共享）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nvidia.com/gpu: 1&lt;/code&gt;（超售）&lt;/td&gt;
&lt;td&gt;大量小型推理任务、开发笔记本&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MIG&lt;/td&gt;
&lt;td&gt;硬件强制（SM+L2+HBM）&lt;/td&gt;
&lt;td&gt;每实例独占&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nvidia.com/mig-Xg.Ygb: 1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;多租户推理、严格 SLO 隔离&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MPS&lt;/td&gt;
&lt;td&gt;上下文共享（非严格）&lt;/td&gt;
&lt;td&gt;部分（按客户端钉住）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nvidia.com/gpu: 1&lt;/code&gt;（共享）&lt;/td&gt;
&lt;td&gt;一块 GPU 上多个协作型推理进程&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;figcaption class="text-center mb-3"&gt;
表 2: GPU 共享策略速查
&lt;/figcaption&gt;
&lt;p&gt;配套两条运营注意：其一，时间切片是把设备插件配置成宣告多于物理存在的 GPU，每个“虚拟 GPU”通过时间复用共享硬件，&lt;strong&gt;请求多于一块时间切片 GPU 并不保证成比例的算力&lt;/strong&gt;；其二，NVIDIA 文档明确指出设备插件时间切片会让 DCGM Exporter 无法把指标关联到容器；共享场景的观测口径见&lt;a href="../../observability/gpu-metrics-semantics/"&gt;GPU 指标语义&lt;/a&gt;的多租户归因一节。&lt;/p&gt;
&lt;h2 id="本章小结与下一步阅读建议"&gt;本章小结与下一步阅读建议&lt;/h2&gt;
&lt;p&gt;通过本章梳理，你可以更系统地理解 GPU 共享的底层机制和工程落点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果你追求“可声明、可治理、可验收”的共享，第一步不是选项目，而是先落到谱系上，明确你要的隔离强度与资源单位。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MIG 与时间片不是同一类问题的不同实现&lt;/strong&gt;：它们的隔离语义与风险曲线完全不同。&lt;/li&gt;
&lt;li&gt;Kubernetes 的设备扩展能力（Device Plugin / DRA）解决“如何让调度器看到设备”，但不替你解决“如何切分与隔离”。&lt;/li&gt;
&lt;li&gt;如果你发现团队在争论“谁更强”，建议把争论强制落到上面的五维矩阵里：只讨论机制与可验证指标，不讨论口号。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;下一章将从谱系切入“硬切分”的代表机制 MIG，并用实验验证隔离与干扰的边界条件。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;本章从数据平面谱系的角度，系统梳理了 GPU 共享机制的多样性与复杂性。通过对比不同机制的特征与适用场景，为后续章节深入探讨具体机制奠定了基础。理解这些基础知识后，读者可以更有针对性地选择和优化适合自己需求的 GPU 共享方案。&lt;/p&gt;
&lt;h2 id="参考文献"&gt;参考文献&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/" target="_blank" rel="noopener"&gt;Device Plugins - kubernetes.io&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/docs/concepts/scheduling-eviction/dynamic-resource-allocation/" target="_blank" rel="noopener"&gt;Dynamic Resource Allocation - kubernetes.io&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.nvidia.com/datacenter/tesla/mig-user-guide/introduction.html" target="_blank" rel="noopener"&gt;Introduction - NVIDIA Multi-Instance GPU User Guide - docs.nvidia.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.nvidia.com/vgpu/latest/grid-vgpu-user-guide/index.html" target="_blank" rel="noopener"&gt;Virtual GPU Software User Guide - docs.nvidia.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/gpu-sharing.html" target="_blank" rel="noopener"&gt;Time-Slicing GPUs in Kubernetes - NVIDIA GPU Operator - docs.nvidia.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.nvidia.com/deploy/mps/index.html" target="_blank" rel="noopener"&gt;Multi-Process Service - docs.nvidia.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/cdi-support.html" target="_blank" rel="noopener"&gt;Support for Container Device Interface - docs.nvidia.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.nvidia.com/datacenter/tesla/mig-user-guide/" target="_blank" rel="noopener"&gt;MIG User Guide - docs.nvidia.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>MIG：强隔离的资源单位与运维代价</title><link>https://jimmysong.io/zh/book/ai-infra/data-plane/mig/</link><pubDate>Tue, 30 Dec 2025 05:02:43 +0000</pubDate><author>Jimmy Song</author><guid>https://jimmysong.io/zh/book/ai-infra/data-plane/mig/</guid><description>聚焦 MIG 的工程事实：强隔离的来源、离散单位的约束、重配置成本与调度耦合。</description><content:encoded>
&lt;blockquote&gt;
&lt;p&gt;MIG 的本质是用硬件级隔离换取可预测性，但离散资源单位和重配置成本也带来了新的工程挑战。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="mig-解决的到底是什么问题"&gt;MIG 解决的到底是什么问题&lt;/h2&gt;
&lt;p&gt;在真实的在线推理/多租户平台里，GPU 的主要矛盾往往不是“能不能共享”，而是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;共享后能否给出稳定的尾延迟（P95/P99）与吞吐承诺&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;共享后是否能避免跨租户干扰（noisy neighbor）&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;是否能做“可验收”的资源交付（SLA/QoS）&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;MIG 的设计动机就是把“一张卡”划分为多个&lt;strong&gt;彼此隔离的实例&lt;/strong&gt;，每个实例拥有独立的高带宽显存、缓存与计算资源，从而获得更可预测的性能与 QoS。&lt;/p&gt;
&lt;p&gt;这也是为什么 MIG 常被用于：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;多租户推理服务（尤其是对尾延迟敏感的场景）&lt;/li&gt;
&lt;li&gt;共享研发集群（不同团队并行试验但需要隔离）&lt;/li&gt;
&lt;li&gt;需要较强“资源边界”的 MLOps 平台&lt;/li&gt;
&lt;/ul&gt;
&lt;figure class="mx-auto text-center"&gt;
&lt;img src="https://assets.jimmysong.io/images/book/gpu-infra/data-plane/mig/mig-instance-partition-zh.svg" data-img="https://assets.jimmysong.io/images/book/gpu-infra/data-plane/mig/mig-instance-partition-zh.svg" alt="图 1: MIG 多实例 GPU 架构" data-caption="图 1: MIG 多实例 GPU 架构"
width="1505"
height="1103"
loading="lazy" decoding="async" class="image-loading"
onload="this.classList.remove('image-loading'); this.classList.add('image-loaded');"
onerror="handleImageError(this); this.classList.remove('image-loading');"&gt;
&lt;figcaption&gt;图 1: MIG 多实例 GPU 架构&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="关键概念实例离散-profile-与几何形状"&gt;关键概念：实例、离散 Profile 与“几何形状”&lt;/h2&gt;
&lt;p&gt;MIG 在概念上至少要分清两层：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;GPU Instance（GI）&lt;/strong&gt;：可以理解为“显存 + 一部分 GPU 资源”的大切片边界。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Compute Instance（CI）&lt;/strong&gt;：在 GI 内进一步划出可执行计算的单位（具体实现细节随架构/代际演进而变化）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;你不需要在本章穷尽 GI/CI 的所有细节，但必须形成一个直觉：&lt;strong&gt;MIG 的资源单位不是连续可调的，而是预定义的离散档位（profiles）&lt;/strong&gt;。这意味着：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;你可以得到强隔离，但只能在若干固定档位中选；&lt;/li&gt;
&lt;li&gt;你会遇到“内部碎片”（例如需要 9GB 显存但只能用 10GB 档位）；&lt;/li&gt;
&lt;li&gt;你会遇到“组合碎片”（某个节点上 MIG profile 的组合不再适配新工作负载）。&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;一个常见误区是把 MIG 当成“GPU 的 cgroup”。事实恰好相反：MIG 更像把一张卡变成一个&lt;strong&gt;离散设备池&lt;/strong&gt;，每个实例是一个“新设备”。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figure class="mx-auto text-center"&gt;
&lt;img src="https://assets.jimmysong.io/images/book/gpu-infra/data-plane/mig/gi-ci-hierarchy-zh.svg" data-img="https://assets.jimmysong.io/images/book/gpu-infra/data-plane/mig/gi-ci-hierarchy-zh.svg" alt="图 2: GI/CI 层次关系" data-caption="图 2: GI/CI 层次关系"
width="1507"
height="1184"
loading="lazy" decoding="async" class="image-loading"
onload="this.classList.remove('image-loading'); this.classList.add('image-loaded');"
onerror="handleImageError(this); this.classList.remove('image-loading');"&gt;
&lt;figcaption&gt;图 2: GI/CI 层次关系&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id="h100-80gb-的-mig-profile-速查"&gt;H100 80GB 的 MIG Profile 速查&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Profile ID&lt;/th&gt;
&lt;th&gt;Profile&lt;/th&gt;
&lt;th&gt;规格&lt;/th&gt;
&lt;th&gt;每卡最多实例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;1g.10gb&lt;/td&gt;
&lt;td&gt;1/7 算力，10GB HBM&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;2g.20gb&lt;/td&gt;
&lt;td&gt;2/7 算力，20GB HBM&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;3g.40gb&lt;/td&gt;
&lt;td&gt;3/7 算力，40GB HBM&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;4g.40gb&lt;/td&gt;
&lt;td&gt;4/7 算力，40GB HBM&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;19&lt;/td&gt;
&lt;td&gt;7g.80gb&lt;/td&gt;
&lt;td&gt;整卡，80GB HBM&lt;/td&gt;
&lt;td&gt;1（等于不切分）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;figcaption class="text-center mb-3"&gt;
表 1: H100 80GB 可用 MIG Profile
&lt;/figcaption&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 列出可用 profile 与当前实例&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nvidia-smi mig -lgip
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nvidia-smi -L
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# GPU 0: NVIDIA H100 80GB HBM3 (UUID: GPU-xxxx)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# MIG 1g.10gb Device 0: (UUID: MIG-xxxx)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Profile 词汇是&lt;strong&gt;世代专属&lt;/strong&gt;的：对小型推理服务理想的 profile，对长上下文模型或一个训练步可能太小。这段速查与本章“离散 Profile 与几何形状”的讨论互为印证：几何是设计约束，不是运行时旋钮。&lt;/p&gt;
&lt;h2 id="为什么说-mig-是强隔离"&gt;为什么说 MIG 是“强隔离”&lt;/h2&gt;
&lt;p&gt;多数软件级共享方案（time-slicing、进程级复用、显存软限制、MPS 等）最终都绕不开一个问题：&lt;strong&gt;隔离强度依赖实现细节与负载行为&lt;/strong&gt;，一旦负载模式变化，干扰就会暴露在尾延迟上。&lt;/p&gt;
&lt;p&gt;MIG 的核心优势在于：它把“隔离”下沉到了硬件层，把一张 GPU 分成多个&lt;strong&gt;完全隔离&lt;/strong&gt;的实例，每个实例拥有自己的显存分区、缓存与计算核心。&lt;/p&gt;
&lt;p&gt;你可以把它视为三类隔离的组合：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;显存隔离&lt;/strong&gt;：显存是第一约束，隔离能显著降低 OOM 与抢占式抖动的外溢。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;缓存/片上资源隔离&lt;/strong&gt;：降低跨租户争抢带来的长尾。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;计算资源隔离&lt;/strong&gt;：减少“同卡不同进程”互相挤占 SM 的不确定性。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这些特性共同指向一个结论：&lt;strong&gt;MIG 适合“把可预测性当成第一原则”的平台型场景。&lt;/strong&gt;&lt;/p&gt;
&lt;figure class="mx-auto text-center"&gt;
&lt;img src="https://assets.jimmysong.io/images/book/gpu-infra/data-plane/mig/isolation-comparison-zh.svg" data-img="https://assets.jimmysong.io/images/book/gpu-infra/data-plane/mig/isolation-comparison-zh.svg" alt="图 3: 隔离方案对比：软件 vs 硬件" data-caption="图 3: 隔离方案对比：软件 vs 硬件"
width="1505"
height="1271"
loading="lazy" decoding="async" class="image-loading"
onload="this.classList.remove('image-loading'); this.classList.add('image-loaded');"
onerror="handleImageError(this); this.classList.remove('image-loading');"&gt;
&lt;figcaption&gt;图 3: 隔离方案对比：软件 vs 硬件&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="代价一资源单位离散带来的碎片与弹性边界"&gt;代价一：资源单位离散带来的碎片与弹性边界&lt;/h2&gt;
&lt;p&gt;MIG 允许把 GPU 分成最多若干个实例（以代际/型号为准），但它不是任意分配，而是按照固定 profile 组合。&lt;/p&gt;
&lt;p&gt;这带来两个直接后果：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;资源匹配是离散优化问题&lt;/strong&gt;：调度从“填箱（bin packing）”进一步变成“带 profile 约束的填箱”。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;弹性变差&lt;/strong&gt;：当你的负载形态频繁变化，MIG 的 profile 组合很可能需要重配；而重配本身就是强运维动作（见下一节）。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="典型碎片模式"&gt;典型碎片模式&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;内部碎片&lt;/strong&gt;：申请略高于某档位阈值导致整体浪费。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;组合碎片&lt;/strong&gt;：节点上剩余的实例组合无法拼出新任务需要的 profile（即使总剩余显存看起来足够）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;集群碎片&lt;/strong&gt;：不同节点的 MIG“几何形状”不一致，导致队列层面长期排队与倾斜。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;因此，MIG 更适合：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;工作负载形态相对稳定（例如固定几类模型推理）&lt;/li&gt;
&lt;li&gt;你愿意用&lt;strong&gt;节点池分层&lt;/strong&gt;消化异构（把不同 MIG geometry 放在不同 nodepool）&lt;/li&gt;
&lt;/ul&gt;
&lt;figure class="mx-auto text-center"&gt;
&lt;img src="https://assets.jimmysong.io/images/book/gpu-infra/data-plane/mig/fragmentation-examples-zh.svg" data-img="https://assets.jimmysong.io/images/book/gpu-infra/data-plane/mig/fragmentation-examples-zh.svg" alt="图 4: 碎片化问题：离散档位的代价" data-caption="图 4: 碎片化问题：离散档位的代价"
width="1505"
height="1221"
loading="lazy" decoding="async" class="image-loading"
onload="this.classList.remove('image-loading'); this.classList.add('image-loaded');"
onerror="handleImageError(this); this.classList.remove('image-loading');"&gt;
&lt;figcaption&gt;图 4: 碎片化问题：离散档位的代价&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="代价二重配置是运维动作且与调度强耦合"&gt;代价二：重配置是运维动作，且与调度强耦合&lt;/h2&gt;
&lt;p&gt;在 Kubernetes 语境下，这是 MIG 的最大“隐藏成本”。&lt;/p&gt;
&lt;p&gt;以 NVIDIA GPU Operator 的 MIG 支持为例：其 MIG Manager 在配置 GPU 的 MIG 模式或 geometry 时，&lt;strong&gt;要求被配置的 GPU 上没有用户工作负载在运行&lt;/strong&gt;；在一些云环境里甚至可能需要重启节点，因此往往需要先 cordon/drain。&lt;/p&gt;
&lt;p&gt;这意味着：&lt;strong&gt;MIG 的几何形状不是一个可以随业务波动频繁调整的弹性旋钮&lt;/strong&gt;。你一旦把“动态重配”当成常规手段，就会把平台稳定性拖入运维地狱：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;需要编排停机窗口或迁移机制&lt;/li&gt;
&lt;li&gt;需要在队列/调度层面协调重配时机&lt;/li&gt;
&lt;li&gt;需要清晰的“重配触发条件”与回滚策略&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="正确姿势把-mig-当成预切分设备池"&gt;正确姿势：把 MIG 当成“预切分设备池”&lt;/h3&gt;
&lt;p&gt;更现实的工程策略是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;按 nodepool 预设 MIG geometry&lt;/strong&gt;，将其当成“节点属性”&lt;/li&gt;
&lt;li&gt;通过标签/taint/affinity 把不同工作负载导向合适的几何池&lt;/li&gt;
&lt;li&gt;由控制面（队列、配额、优先级）来做治理，而不是靠频繁改几何来追逐短期利用率&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="kubernetes-集成资源语义与暴露策略"&gt;Kubernetes 集成：资源语义与暴露策略&lt;/h2&gt;
&lt;p&gt;Kubernetes 的扩展资源（extended resources）天然更接近“设备分配”，而不是“可分配的连续度量”。这与 MIG 的“实例就是设备”非常契合：MIG 实例可以被暴露为独立资源类型，由调度器做整数分配。&lt;/p&gt;
&lt;p&gt;在 Kubernetes 中最常见的暴露方式是 NVIDIA k8s-device-plugin。它支持通过 &lt;code&gt;MIG_STRATEGY&lt;/code&gt; 决定如何在节点上暴露 MIG 设备：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;none&lt;/code&gt;：不区分 MIG 与否，仍以 &lt;code&gt;nvidia.com/gpu&lt;/code&gt; 暴露整卡&lt;/li&gt;
&lt;li&gt;&lt;code&gt;single&lt;/code&gt;：只暴露 MIG 设备（并要求节点上的 MIG 配置一致性更强）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mixed&lt;/code&gt;：同时暴露整卡与 MIG 设备（更灵活，但治理复杂度更高）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;你在本书后续章节会看到：&lt;strong&gt;“mixed 能力”经常被误用&lt;/strong&gt;：它会让资源目录更丰富，但也会让配额、计量与公平性更难解释。除非你有明确的治理模型，否则更推荐以 nodepool 隔离的方式管理“整卡池 vs MIG 池”。&lt;/p&gt;
&lt;p&gt;如果你把 GPU 共享方案放回本书的控制面地图，MIG 的定位非常清晰：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;数据平面：硬切分 + 强隔离&lt;/li&gt;
&lt;li&gt;控制面：把每个 MIG 实例当成独立设备，做队列/配额/优先级治理&lt;/li&gt;
&lt;li&gt;端到端：适合“可声明、可验收”的资源交付，而不是追求极限的细粒度弹性&lt;/li&gt;
&lt;/ul&gt;
&lt;figure class="mx-auto text-center"&gt;
&lt;img src="https://assets.jimmysong.io/images/book/gpu-infra/data-plane/mig/k8s-mig-integration-zh.svg" data-img="https://assets.jimmysong.io/images/book/gpu-infra/data-plane/mig/k8s-mig-integration-zh.svg" alt="图 5: Kubernetes MIG 集成架构" data-caption="图 5: Kubernetes MIG 集成架构"
width="1507"
height="1584"
loading="lazy" decoding="async" class="image-loading"
onload="this.classList.remove('image-loading'); this.classList.add('image-loaded');"
onerror="handleImageError(this); this.classList.remove('image-loading');"&gt;
&lt;figcaption&gt;图 5: Kubernetes MIG 集成架构&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="hands-on用你的两台-a100mig-开关建立直觉"&gt;Hands-on：用你的两台 A100（MIG 开/关）建立直觉&lt;/h2&gt;
&lt;p&gt;你当前环境非常适合做一组“对照实验”：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;机器 1：A100，MIG Disabled（整卡共享只能依赖软件方案）&lt;/li&gt;
&lt;li&gt;机器 2：A100，MIG Enabled（硬切分、多实例隔离）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;建议把本章的实践目标定义为三件事：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;确认资源单位变化&lt;/strong&gt;：从 1 张 GPU 变成 N 个 MIG 设备&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;确认 K8s 暴露语义&lt;/strong&gt;：Pod 以“设备数量”申请 MIG profile&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;确认隔离收益与边界&lt;/strong&gt;：干扰是否显著降低、但 profile 是否带来碎片与重配成本&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;下面给出一个最小操作路径，便于读者复现。具体命令可在 Lab 章节展开。&lt;/p&gt;
&lt;h3 id="在-mig-节点上确认-mig-设备枚举"&gt;在 MIG 节点上确认 MIG 设备枚举&lt;/h3&gt;
&lt;p&gt;可以通过如下命令列举 MIG 设备和实例：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 机器 2（MIG Enabled）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nvidia-smi -L
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nvidia-smi mig -lgi &lt;span class="c1"&gt;# 列出 GPU instances&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nvidia-smi mig -lci &lt;span class="c1"&gt;# 列出 compute instances（如适用）&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;观察点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;输出中是否出现多个 MIG 设备条目（每个条目是一个“新设备”）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="在-kubernetes-中暴露-mig-资源"&gt;在 Kubernetes 中暴露 MIG 资源&lt;/h3&gt;
&lt;p&gt;如果你使用 NVIDIA device plugin / GPU Operator，核心是选定 MIG 暴露策略（&lt;code&gt;single&lt;/code&gt; 或 &lt;code&gt;mixed&lt;/code&gt;），并让节点上报对应资源。&lt;/p&gt;
&lt;p&gt;常见的现象是：Node 的 &lt;code&gt;Capacity/Allocatable&lt;/code&gt; 会出现类似 &lt;code&gt;nvidia.com/mig-&amp;lt;profile&amp;gt;&lt;/code&gt; 的资源项（profile 具体命名依赖实现与配置）。&lt;/p&gt;
&lt;h3 id="用一个最小-pod-验证按-mig-设备分配"&gt;用一个最小 Pod 验证“按 MIG 设备分配”&lt;/h3&gt;
&lt;p&gt;以下 YAML 用于验证 Pod 能否按 MIG 设备分配：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Pod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mig-smoke-test&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;restartPolicy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Never&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;cuda&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nvidia/cuda:12.4.1-base-ubuntu22.04&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;bash&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;-lc&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;nvidia-smi &amp;amp;&amp;amp; sleep 3600&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;limits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 这里的资源名需要替换成你集群实际暴露的 MIG profile&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 例如 nvidia.com/mig-1g.5gb: 1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;nvidia.com/mig-&amp;lt;profile&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;观察点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pod 是否被调度到 MIG 节点&lt;/li&gt;
&lt;li&gt;容器内 &lt;code&gt;nvidia-smi&lt;/code&gt; 看到的设备是否是 MIG instance&lt;/li&gt;
&lt;li&gt;同一张卡上并行跑多个相同 profile 的 Pod 时，是否表现出更稳定的尾延迟（在后续 Lab 用基准测量）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="把-mig-回填到决策轴矩阵"&gt;把 MIG 回填到“决策轴矩阵”&lt;/h2&gt;
&lt;p&gt;你可以把 MIG 在本书决策轴中先填一个“默认结论”，后续再用实验数据修正：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;资源单位&lt;/strong&gt;：离散（profile 驱动），可作为独立设备暴露&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;隔离强度&lt;/strong&gt;：强（硬件隔离，QoS 更可预测）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;性能损耗/干扰&lt;/strong&gt;：干扰显著降低；但不同 profile 的绝对性能上限受切分约束&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;运维重配置成本&lt;/strong&gt;：高（改模式/几何通常要求无用户负载，可能需 cordon/drain，部分环境需重启）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;兼容性/侵入性&lt;/strong&gt;：对应用相对透明（像“拿到一块小 GPU”），但对平台治理模型要求更高&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;异构扩展路径&lt;/strong&gt;：适合用 nodepool/标签把几何形状固化为“节点属性”&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;MIG 不是“通用 GPU 共享”的终点，而是一个非常清晰的工程选择：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;当你的首要目标是&lt;strong&gt;隔离与可预测性&lt;/strong&gt;：MIG 常是最省心的硬件路径。&lt;/li&gt;
&lt;li&gt;当你的首要目标是&lt;strong&gt;极致弹性与细粒度分配&lt;/strong&gt;：MIG 的离散 profile 与重配成本会成为结构性瓶颈。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在本书后续章节，我们会用同一组决策轴去对比：MIG、HAMi（软件级 vGPU/共享）、以及 time-slicing 等机制，并在你的两台 A100 环境上做可复现实验，把“直觉判断”变成“可验收结论链”。&lt;/p&gt;
&lt;h2 id="参考资料"&gt;参考资料&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.nvidia.com/datacenter/tesla/pdf/MIG_User_Guide.pdf" target="_blank" rel="noopener"&gt;NVIDIA MIG 用户指南 - docs.nvidia.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.nvidia.com/en-us/technologies/multi-instance-gpu/" target="_blank" rel="noopener"&gt;NVIDIA Multi-Instance GPU 技术介绍 - nvidia.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/gpu-operator-mig.html" target="_blank" rel="noopener"&gt;NVIDIA GPU Operator MIG 官方文档 - docs.nvidia.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>HAMi：可声明共享的虚拟化数据平面</title><link>https://jimmysong.io/zh/book/ai-infra/data-plane/hami/</link><pubDate>Tue, 30 Dec 2025 05:01:54 +0000</pubDate><author>Jimmy Song</author><guid>https://jimmysong.io/zh/book/ai-infra/data-plane/hami/</guid><description>从数据平面视角拆解 HAMi，聚焦细粒度资源单位、共享治理、隔离与兼容性的工程权衡及适用场景。</description><content:encoded>
&lt;blockquote&gt;
&lt;p&gt;让 GPU 共享成为可声明、可治理的工程能力，而非“能跑就行”的经验主义。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="hami-的一句话定位"&gt;HAMi 的一句话定位&lt;/h2&gt;
&lt;p&gt;HAMi 是一个面向 Kubernetes 的 GPU 虚拟化与切分数据平面。它致力于将“GPU 共享”从经验主义的“能跑”提升为工程语义上的“可声明、可调度、可治理”。HAMi 的核心并非重写调度器，而是将 GPU 的可用资源单位从“整卡整数”扩展为“可切分的份额（core/memory 等）”，并将这些份额暴露为 Kubernetes 可理解的资源请求与分配路径。&lt;/p&gt;
&lt;h2 id="为什么-hami-必须出现在数据平面"&gt;为什么 HAMi 必须出现在数据平面&lt;/h2&gt;
&lt;p&gt;Kubernetes 对设备类资源的默认语义是“整数、不可超卖、调度时做计数”。这套模型非常适合网卡、FPGA、整卡 GPU，但对于可共享、可切分且隔离与干扰复杂的 GPU，会自然推向两种极端：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;要么&lt;/strong&gt;继续整卡分配，把利用率问题交给业务侧自己排队；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;要么&lt;/strong&gt;把共享做成容器内自觉，但无法声明与治理，难以实现队列、配额、优先级等上层策略闭环。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;HAMi 的选择是：&lt;strong&gt;在不要求应用改代码的前提下&lt;/strong&gt;，将“共享”做成数据平面能力，并把更细粒度的资源表达暴露为 Kubernetes 可调度资源。&lt;/p&gt;
&lt;h2 id="组件视图hami-是一条分配链路"&gt;组件视图：HAMi 是一条“分配链路”&lt;/h2&gt;
&lt;p&gt;理解 HAMi 最好的方式，是将其视为一条从“声明”到“生效”的分配链路。典型链路可拆为四层（实现细节随版本演进，但职责基本稳定）：&lt;/p&gt;
&lt;p&gt;在介绍各层职责前，先说明：每一层都围绕资源声明、调度、兑现与观测展开，形成完整的治理闭环。&lt;/p&gt;
&lt;p&gt;下图概括 HAMi 从声明到兑现的分配链路与治理闭环。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;HAMi 分配链路示意图&lt;/strong&gt;：展示从节点侧发现与汇报、调度侧绑定与落位、容器内资源控制到观测与计量的完整四层架构。每一层都围绕资源声明、调度、兑现与观测展开，形成完整的治理闭环。Device Plugin 负责声明，Scheduler 负责落位，容器内控制层负责兑现，监控负责将兑现程度转化为可运维数据。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figure class="mx-auto text-center"&gt;
&lt;img src="https://assets.jimmysong.io/images/book/gpu-infra/data-plane/hami/hami-allocation-chain.svg" data-img="https://assets.jimmysong.io/images/book/gpu-infra/data-plane/hami/hami-allocation-chain.svg" alt="图 1: HAMi 分配链路" data-caption="图 1: HAMi 分配链路"
width="1763"
height="461"
loading="lazy" decoding="async" class="image-loading"
onload="this.classList.remove('image-loading'); this.classList.add('image-loaded');"
onerror="handleImageError(this); this.classList.remove('image-loading');"&gt;
&lt;figcaption&gt;图 1: HAMi 分配链路&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;节点侧发现与汇报（Device Plugin 侧）&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;负责发现 GPU，并将“可分配资源”汇报给 Kubelet/调度器可见的资源视图。&lt;/li&gt;
&lt;li&gt;与默认整卡模型相比，HAMi 会把物理 GPU 映射为可被多 Pod 共享的更细粒度资源单元，并暴露相应资源名（如 core / memory 维度）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;调度侧绑定与落位（Scheduler 扩展/策略侧）&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;负责将“请求”落到具体哪张卡、哪类卡、哪组份额。&lt;/li&gt;
&lt;li&gt;关键在于将拓扑、碎片、同卡干扰等数据平面约束转化为调度可见的约束条件。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;容器内资源控制（HAMi-core / vGPU 控制层）&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;负责让“声明的份额”在容器内尽可能生效。例如对 core 份额采用 time-slicing 实现配额效果，并解释为何在 &lt;code&gt;nvidia-smi&lt;/code&gt; 里看到的利用率会波动。&lt;/li&gt;
&lt;li&gt;工程实现上，通常通过拦截 CUDA Runtime 与 Driver 之间的调用链路实现控制与计量（产物多以注入动态库形式出现）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;观测与计量（vGPUmonitor / metrics 导出）&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;负责将“共享后到底谁占了多少”转化为 Prometheus 可抓取的指标，形成治理闭环的基础数据。计量缺失意味着无法计费、无法做容量评估，也无法做 SLO。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;你可以将这条链路概括为：&lt;strong&gt;Device Plugin 负责声明，Scheduler 负责落位，容器内控制层负责兑现，监控负责将兑现程度转化为可运维数据。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="资源表达从整卡到可声明共享的关键语义"&gt;资源表达：从“整卡”到“可声明共享”的关键语义&lt;/h2&gt;
&lt;p&gt;HAMi 的工程收益，核心在于引入了更细粒度的资源表达方式，使 Kubernetes 调度与上层控制面能够“看到”你真正需要的资源。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;HAMi 资源表达示意图&lt;/strong&gt;：对比传统整卡分配模型和 HAMi 可声明共享模型，展示如何通过 GPU 份额（虚拟 GPU/slice）、Core 份额（nvidia.com/gpucores）和 Memory 份额（nvidia.com/gpumem）实现显存与 core 份额可声明，使“同卡复用”更可控。图中还包含 Pod 资源声明示例 YAML。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figure class="mx-auto text-center"&gt;
&lt;img src="https://assets.jimmysong.io/images/book/gpu-infra/data-plane/hami/hami-resource-expression.svg" data-img="https://assets.jimmysong.io/images/book/gpu-infra/data-plane/hami/hami-resource-expression.svg" alt="图 2: HAMi 资源表达：从整卡到可声明共享" data-caption="图 2: HAMi 资源表达：从整卡到可声明共享"
width="1745"
height="1395"
loading="lazy" decoding="async" class="image-loading"
onload="this.classList.remove('image-loading'); this.classList.add('image-loaded');"
onerror="handleImageError(this); this.classList.remove('image-loading');"&gt;
&lt;figcaption&gt;图 2: HAMi 资源表达：从整卡到可声明共享&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;典型做法是让 Pod 在资源请求里同时声明：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;GPU 份额（虚拟 GPU / slice）&lt;/strong&gt;：让一张物理卡可被多个 Pod 分配。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;core 份额（如 &lt;code&gt;nvidia.com/gpucores&lt;/code&gt;）&lt;/strong&gt;：用 time-slicing 近似实现计算份额控制。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;memory 份额（如 &lt;code&gt;nvidia.com/gpumem&lt;/code&gt;）&lt;/strong&gt;：将“显存第一约束”显式化，避免仅按整卡计数导致的资源错配与碎片放大。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这里有一个重要边界需明确：&lt;strong&gt;“可声明”不等于“强隔离”&lt;/strong&gt;。HAMi 在 core 维度更接近“可控的时间片分配”；在显存维度则更接近“配额化的分配与失败策略（超额时的表现）”。因此，HAMi 提供的是“比整卡更强的治理语义”，而非类似 MIG（Multi-Instance GPU, Multi-Instance GPU）那样的硬切分级别隔离。&lt;/p&gt;
&lt;h2 id="关键取舍hami-解决的是运维问题不是物理隔离问题"&gt;关键取舍：HAMi 解决的是“运维问题”，不是“物理隔离问题”&lt;/h2&gt;
&lt;p&gt;从工程视角看，HAMi 的核心价值不在于“能否共享”，而在于是否让以下问题具备可操作性：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;可声明：把共享从“隐性行为”变成“显式契约”&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;有了契约，才有治理。HAMi 的资源表达让你能在 YAML 里明确声明：需要多少 core、多少显存、是否允许与别人同卡。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;可调度：把碎片与落位变成系统责任&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;资源单位变细后，碎片必然增多。HAMi 的价值之一，是让“碎片管理/落位策略”进入调度责任域，而非留给业务侧碰运气。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;可观测：共享后的 P99 才是问题本体&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;GPU 共享的难点不在平均吞吐，而在尾延迟与抖动。HAMi 通过监控与计量组件，将共享后的使用情况导出为指标，为后续“验收与容量”章节铺路。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;可协同：为 Volcano/Kueue 提供“可用的资源语义”&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Volcano/Kueue 解决队列、配额、公平性、优先级、准入与抢占等控制面问题；HAMi 解决“节点 GPU 能怎样切分、切完如何落位、如何兑现”的数据平面问题。两者叠加，才能形成完整的 GPU 资源运维系统。&lt;/p&gt;
&lt;h2 id="适用场景与反模式"&gt;适用场景与反模式&lt;/h2&gt;
&lt;p&gt;在实际应用中，HAMi 更适合以下场景：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;多租户推理、批量小模型推理：显存与 core 份额可声明，使“同卡复用”更可控。&lt;/li&gt;
&lt;li&gt;研发/测试/POC 环境：需要快速提升 GPU 利用率，并积累计量与基线数据。&lt;/li&gt;
&lt;li&gt;平台化团队：可将 HAMi 语义与企业内部队列/配额体系打通，形成治理闭环。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;需要谨慎的场景或需额外验收门槛：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;强隔离/强确定性 SLO 的关键在线业务：如需接近物理级隔离（尤其尾延迟敏感），建议优先考虑 MIG 或整卡池化。&lt;/li&gt;
&lt;li&gt;对驱动/运行时链路极其敏感的生产环境：任何“容器内拦截/注入”方案都要求完善升级验证、兼容性矩阵与故障回滚机制。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="如何把-hami-放进本书的决策轴"&gt;如何把 HAMi 放进本书的“决策轴”&lt;/h2&gt;
&lt;p&gt;你可以用以下结论，将 HAMi 快速回填到“决策轴矩阵”中（后续实验章节会用数据验证）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;资源单位&lt;/strong&gt;：从整卡扩展到 core/mem 份额与共享 slice。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;隔离强度&lt;/strong&gt;：总体偏“软隔离/工程约束”，非硬切分。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;动态调整成本&lt;/strong&gt;：通常低于 MIG（无需重切分设备），但依赖控制链路与策略配置成熟度。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;性能与干扰&lt;/strong&gt;：平均吞吐通常可接受，关键在 P99 与干扰控制，需要用 Lab 体系验收。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可观测与计量&lt;/strong&gt;：具备导出指标的路径，是实现运维闭环的重要加分项。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;兼容性/侵入性&lt;/strong&gt;：对应用代码侵入低（无需改代码），但对运行时/驱动链路与运维流程有要求。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="资源口径与后端组合三个容易踩坑的工程细节"&gt;资源口径与后端组合：三个容易踩坑的工程细节&lt;/h2&gt;
&lt;p&gt;在把 HAMi 投入生产前，有三个介于“声明语义”与“物理现实”之间的细节值得显式确认。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;其一，core 份额的口径是执行时间，不是算力。&lt;/strong&gt; &lt;code&gt;nvidia.com/gpucores&lt;/code&gt; 通过对 kernel 执行的节流实现配额，它对算力密集型负载（训练、预填充）的限流接近直觉；但对&lt;strong&gt;显存带宽瓶颈的负载（LLM 解码）几乎不限流&lt;/strong&gt;：这类负载的 kernel 本来就大部分时间在等数据，限制执行时间对它的 token 速度影响很小，而它占用的带宽并不在配额维度内。推理租户的配额设计应“显存为主、算力为辅”，详见&lt;a href="../../fundamentals/gpu-microarchitecture-roofline/"&gt;微架构&lt;/a&gt;与&lt;a href="../../workloads/llm-inference-physics/"&gt;推理物理层&lt;/a&gt;的 Roofline 模型推导。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;其二，memory 份额的口径是分配量，不是活跃张量。&lt;/strong&gt; &lt;code&gt;nvidia.com/gpumem&lt;/code&gt;（旧文档亦写作 vgamem）在分配调用上记账，框架的显存缓存（reserved 口径）会被计为已用。跑在配额下的 PyTorch 若不配置 &lt;code&gt;PYTORCH_CUDA_ALLOC_CONF&lt;/code&gt;，可能在“真实张量没用满”时就撞注入的 OOM。reserved 与 allocated 的差异、碎片机制与排查树见&lt;a href="../../fundamentals/gpu-memory-management/"&gt;GPU 显存管理&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;其三，HAMi 是配额层，需与共享机制组合成后端。&lt;/strong&gt; 常见三种后端：默认的时间片轮转加配额（最安全，隔离最弱，适合 CI 与批处理）；MPS 后端（多进程 kernel 并发驻留，适合推理合租，但 MPS 服务进程成为共享故障点，需托管与监控）；MIG 后端（配额层叠加硬切分，隔离最强）。按租户类别选择后端，正是&lt;a href="../../fundamentals/hard-soft-slicing/"&gt;硬切分与软切分&lt;/a&gt;一章决策轴的落地应用。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;HAMi 的本质是将 GPU 共享变成工程语义的虚拟化数据平面。它让资源可以被声明、调度、计量，从而让控制面（如 Volcano、Kueue）有机会将队列、配额、优先级等治理能力落到 GPU 这一类复杂资源上。HAMi 并不承诺 MIG 级别的强隔离，而是用更低的重配置成本与更强的运维语义，换取更高的整体利用率与可治理性。&lt;/p&gt;
&lt;p&gt;下一章“生态放置”将把 HAMi、MIG、Volcano、Kueue 及典型推理/训练栈放入同一张拼装图，明确每一层的职责，避免“用数据平面能力替代控制面治理”的常见误区。&lt;/p&gt;
&lt;h2 id="参考文献"&gt;参考文献&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/Project-HAMi/HAMi" target="_blank" rel="noopener"&gt;GitHub - Project-HAMi/HAMi: Heterogeneous AI Computing Virtualization Middleware(Project under CNCF) - github.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://project-hami.io/docs/userguide/nvidia-device/examples/allocate-device-core/?utm_source=chatgpt.com" target="_blank" rel="noopener"&gt;Allocate device core resource - project-hami.io&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://koordinator.sh/docs/next/user-manuals/device-scheduling-gpu-share-with-hami?utm_source=chatgpt.com" target="_blank" rel="noopener"&gt;Device Scheduling - GPU Share With HAMi - koordinator.sh&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>DRA：Kubernetes 设备资源分配的下一代 API</title><link>https://jimmysong.io/zh/book/ai-infra/data-plane/dra/</link><pubDate>Sun, 19 Apr 2026 00:00:00 +0000</pubDate><author>Jimmy Song</author><guid>https://jimmysong.io/zh/book/ai-infra/data-plane/dra/</guid><description>深入分析 DRA 的架构动机、API 机制与设计取舍，理解它如何从 Device Plugin 的 Allocate 黑盒走向可声明、可推理的资源分配。</description><content:encoded>
&lt;blockquote&gt;
&lt;p&gt;DRA 的核心价值不是“替代 Device Plugin”，而是把设备分配从节点本地的 Allocate 黑盒推进到控制面可见、可审计、可组合的资源 API。这个转变对 GPU 调度体系的影响是结构性的。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在前面 &lt;a href="../../fundamentals/k8s-device-model/"&gt;Kubernetes 设备资源模型&lt;/a&gt;中已经看到，Device Plugin 的 Advertise→Bind→Allocate 模型把设备分配的全部决策权下沉到了 kubelet 本地，调度器只知道“这个节点有 N 块设备”，不知道设备的具体属性、参数和分配策略。DRA（Dynamic Resource Allocation，动态资源分配）正是为解决这一结构性缺陷而生的，它已在 Kubernetes v1.35 进入 GA（Stable）阶段，v1.36 起继续扩展与 PodGroup 等调度语义的整合。&lt;/p&gt;
&lt;p&gt;本文不重复 DRA 的快速入门，而是聚焦三个层面：Device Plugin 的根本局限在哪里、DRA 的 API 设计做了哪些取舍、以及它对 GPU 调度体系的长远影响。&lt;/p&gt;
&lt;h2 id="device-plugin-的三个结构性问题"&gt;Device Plugin 的三个结构性问题&lt;/h2&gt;
&lt;p&gt;Device Plugin 的设计初衷是“让厂商能接入异构设备”，这个目标它完成得很好。但随着 GPU 平台化程度加深，三个结构性问题逐渐暴露。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;参数化请求无法表达。&lt;/strong&gt; Pod spec 里 &lt;code&gt;nvidia.com/gpu: 1&lt;/code&gt; 只能声明“我要一块 GPU”，无法表达“我要一块带 40GB 显存的 H100，启用 MIG profile 4g.40gb”。调度器在选节点时，只能判断“节点上有没有至少一块 GPU”，不能判断“有没有满足我具体参数的 GPU”。所有参数化逻辑都被推迟到 kubelet 的 Allocate 阶段，这意味着调度器可能把 Pod 放到一个设备参数不匹配的节点上，分配失败后 Pod 才会 CrashLoopBackOff。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;分配过程对控制面不透明。&lt;/strong&gt; Device Plugin 的 Allocate 调用发生在 kubelet 本地，不走 API Server。调度器、准入控制器、审计日志都看不到“具体哪块设备分配给了哪个 Pod”。这对多租户平台来说是治理盲区：你无法在控制面回答“这台 H100 上的 4 个 Pod 分别占了哪几个 MIG 实例”这类问题，只能 SSH 到节点上查。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;设备生命周期与 Pod 耦合。&lt;/strong&gt; Device Plugin 没有独立的“设备分配”对象。分配随着 Pod 创建而发生，随着 Pod 删除而释放。如果你需要预先分配设备（比如在训练任务启动前先锁住 GPU）、或者让多个 Pod 共享同一块设备的特定资源份额，Device Plugin 的模型不直接支持，只能靠厂商自行实现私有方案。&lt;/p&gt;
&lt;p&gt;这三个问题的根源是同一个：Device Plugin 把“设备选择与分配”做成了节点侧的本地实现，而不是控制面的一等资源对象。&lt;/p&gt;
&lt;h2 id="dra-的核心设计四个-api-对象"&gt;DRA 的核心设计：四个 API 对象&lt;/h2&gt;
&lt;p&gt;DRA 引入了四个 &lt;code&gt;resource.k8s.io/v1&lt;/code&gt; API 组下的核心对象，各自承担不同的职责。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ResourceSlice：设备信息的发布通道。&lt;/strong&gt; DRA 驱动在集群中创建和管理 ResourceSlice，向调度器暴露节点上的设备信息，包括设备属性（型号、显存、拓扑）、可用容量以及哪些节点可以访问这些设备。调度器通过扫描 ResourceSlice 来回答“哪个节点有满足条件的设备”这个问题。ResourceSlice 替代了 Device Plugin 中“通过 gRPC 向 kubelet 广告设备”的那一步，把设备信息从节点本地提升到了集群可见的 API 对象。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;DeviceClass：管理员定义的设备类别。&lt;/strong&gt; DeviceClass 的设计思路类似 StorageClass：管理员或驱动定义“一类设备的分配策略”，包括匹配哪些设备、使用哪个驱动、分配模式（独占还是共享）等。Pod 不直接指定“我要某某型号的 GPU”，而是引用一个 DeviceClass，由 DeviceClass 的规则来决定具体匹配哪些设备。这把“设备选择策略”从 Pod spec 中解耦出来，集中到了集群治理层面。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ResourceClaim：设备分配的一等对象。&lt;/strong&gt; 这是 DRA 与 Device Plugin 最根本的区别。ResourceClaim 是一个标准的 Kubernetes 资源对象，代表“对特定设备的分配请求”。当调度器找到一个匹配的设备时，它会更新 ResourceClaim 的 status 字段，记录分配结果。整个分配过程经过 API Server，可以被审计、被观测、被其他控制器引用。ResourceClaim 支持两种使用方式：直接创建让多个 Pod 共享同一份设备分配，或者通过 ResourceClaimTemplate 为每个 Pod 自动生成独立的 Claim。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ResourceClaimTemplate：自动化生成的模板。&lt;/strong&gt; 当每个 Pod 需要独立的设备分配时（这是大多数情况），用 ResourceClaimTemplate 可以自动为每个 Pod 生成 ResourceClaim，其生命周期与 Pod 绑定。Pod 删除时自动清理对应的 Claim，避免资源泄漏。&lt;/p&gt;
&lt;p&gt;这四个对象的设计意图很清晰：把设备分配从“节点本地的 gRPC 调用”提升到“控制面的标准 API 对象”。Device Plugin 的 Allocate 黑盒变成了可审计的 ResourceClaim 状态变更。&lt;/p&gt;
&lt;figure class="mx-auto text-center"&gt;
&lt;img src="https://assets.jimmysong.io/images/book/gpu-infra/data-plane/dra/dra-api-objects.svg" data-img="https://assets.jimmysong.io/images/book/gpu-infra/data-plane/dra/dra-api-objects.svg" alt="图 1: DRA 四个核心 API 对象" data-caption="图 1: DRA 四个核心 API 对象"
width="1305"
height="1383"
loading="lazy" decoding="async" class="image-loading"
onload="this.classList.remove('image-loading'); this.classList.add('image-loaded');"
onerror="handleImageError(this); this.classList.remove('image-loading');"&gt;
&lt;figcaption&gt;图 1: DRA 四个核心 API 对象&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="调度流程对比device-plugin-vs-dra"&gt;调度流程对比：Device Plugin vs DRA&lt;/h2&gt;
&lt;p&gt;理解两个模型的差异，最直接的方式是对比调度流程。&lt;/p&gt;
&lt;p&gt;Device Plugin 的流程是三步闭环：驱动通过 gRPC 向 kubelet 广告设备（Advertise），调度器根据整数计数做节点选择（Bind），kubelet 调用驱动的 Allocate 完成交付。调度器在 Bind 阶段只能看到“节点上有 N 块设备”这个标量信息，具体分配决策完全在 Allocate 阶段才发生。&lt;/p&gt;
&lt;p&gt;DRA 的流程在此基础上增加了两个关键步骤。驱动先通过 ResourceSlice 发布设备信息（包括属性和容量），调度器在选节点时就可以基于设备属性做过滤，比如“这个节点的 GPU 显存够不够”、“是不是 H100”、“MIG profile 是否匹配”。找到匹配节点后，调度器更新 ResourceClaim 的 allocation 状态，再完成 Pod 绑定。分配结果通过 API Server 持久化，而不是在 kubelet 本地一闪而过。&lt;/p&gt;
&lt;p&gt;这个差异看起来只是多走了几步 API，但对平台治理的影响是根本性的。调度器第一次有了设备属性层面的决策能力，而不是只能“赌 Allocate 阶段不会失败”。分配结果第一次变成了可审计的 API 对象，而不是节点本地的瞬时状态。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;维度&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Device Plugin&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;DRA&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;调度器能看到的设备信息&lt;/td&gt;
&lt;td&gt;整数计数（&lt;code&gt;nvidia.com/gpu: 8&lt;/code&gt;）&lt;/td&gt;
&lt;td&gt;多维属性（显存、型号、拓扑、容量）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;分配可见性&lt;/td&gt;
&lt;td&gt;kubelet 本地 gRPC，不可审计&lt;/td&gt;
&lt;td&gt;经 API Server，ResourceClaim 可审计&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;设备生命周期&lt;/td&gt;
&lt;td&gt;与 Pod 耦合，Pod 删除即释放&lt;/td&gt;
&lt;td&gt;ResourceClaim 独立，可预先分配和共享&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;参数化能力&lt;/td&gt;
&lt;td&gt;无，只能声明整数数量&lt;/td&gt;
&lt;td&gt;CEL 表达式过滤设备属性&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;设备共享&lt;/td&gt;
&lt;td&gt;厂商私有实现&lt;/td&gt;
&lt;td&gt;ResourceClaim 天然支持多 Pod 引用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;设计类比&lt;/td&gt;
&lt;td&gt;类似静态 PV&lt;/td&gt;
&lt;td&gt;类似 StorageClass + PVC 的声明式模型&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;figcaption class="text-center mb-3"&gt;
表 1: Device Plugin vs DRA 核心差异
&lt;/figcaption&gt;
&lt;h2 id="架构演变从-classic-dra-到-structured-parameters"&gt;架构演变：从 Classic DRA 到 Structured Parameters&lt;/h2&gt;
&lt;p&gt;DRA 的架构本身也经历了一次重要的角色反转，这一点直接影响你理解 DRA 的方式。&lt;/p&gt;
&lt;p&gt;最初 KEP-3063 定义了“Classic DRA”，引入了控制面控制器和 ResourceClaim/DeviceClass 的基本框架。后来 KEP-4381 引入了 Structured Parameters（结构化参数），允许用 CEL 表达式对设备属性做精细过滤。随着 Structured Parameters 的成熟，两个 KEP 的角色发生了反转：&lt;strong&gt;KEP-4381 现在定义基础功能&lt;/strong&gt;，&lt;strong&gt;KEP-3063 变成了扩展&lt;/strong&gt;。也就是说，结构化调度是 DRA 的主流路径，Classic DRA 的控制面控制器反而成了可选的向后兼容层。&lt;/p&gt;
&lt;p&gt;这个反转的含义是：DRA 的设计重心从“让 ResourceClaim 在控制面流转”变成了“让调度器基于结构化参数做更智能的设备选择”。CEL 表达式可以表达“我要显存大于 40GB 的 GPU”、“我要支持 NVLink 的双卡配置”这类条件，调度器在选节点时就能精确匹配，而不是事后补救。&lt;/p&gt;
&lt;h2 id="版本时间线与成熟度"&gt;版本时间线与成熟度&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;版本&lt;/th&gt;
&lt;th&gt;发布&lt;/th&gt;
&lt;th&gt;要点&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;K8s 1.26&lt;/td&gt;
&lt;td&gt;DRA Alpha（Classic DRA）&lt;/td&gt;
&lt;td&gt;首个实现，ResourceClaim/ResourceClass，仅 alpha&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;K8s 1.30&lt;/td&gt;
&lt;td&gt;Structured Parameters 重设计&lt;/td&gt;
&lt;td&gt;引入 ResourceSlice，可扩展性大幅提升&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;K8s 1.31&lt;/td&gt;
&lt;td&gt;新模型稳定&lt;/td&gt;
&lt;td&gt;v1alpha3；Classic DRA 废弃&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;K8s 1.32&lt;/td&gt;
&lt;td&gt;DRA Beta（v1beta1）&lt;/td&gt;
&lt;td&gt;特性门控默认启用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;K8s 1.33&lt;/td&gt;
&lt;td&gt;v1beta2&lt;/td&gt;
&lt;td&gt;ResourceSlice 属性类型更丰富，CEL 表达能力扩展&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;K8s 1.34&lt;/td&gt;
&lt;td&gt;DRA GA&lt;/td&gt;
&lt;td&gt;默认启用；设备插件仍可用但 DRA 是推荐未来&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;K8s 1.35&lt;/td&gt;
&lt;td&gt;完全稳定&lt;/td&gt;
&lt;td&gt;v1 API 组确认；NVIDIA 向 CNCF/Kubernetes 项目捐赠 DRA Driver（2026 年 4 月，见&lt;a href="../../production/nvidia-cncf/"&gt;NVIDIA × CNCF&lt;/a&gt;）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;figcaption class="text-center mb-3"&gt;
表 2: DRA 版本演进速查
&lt;/figcaption&gt;
&lt;p&gt;一个带 CEL 选择器的 ResourceClaim 实例（配合 DeviceClass 使用）：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;resource.k8s.io/v1beta2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ResourceClaim&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;training-gpu-claim&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ml-team&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;devices&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;training-gpu&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;deviceClassName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;gpu.nvidia.com&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;selectors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;cel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;expression&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; device.attributes[&amp;#39;memory.capacity&amp;#39;].isGreaterThan(quantity(&amp;#39;80Gi&amp;#39;)) &amp;amp;&amp;amp;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; device.attributes[&amp;#39;computeCapability&amp;#39;].isGreaterThan(version(&amp;#39;8.9&amp;#39;))&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;成熟度方面请注意：核心特性在 v1.35 稳定，但设备健康监控、可分区设备、设备污点等高级能力成熟度各异；NVIDIA 的 DRA 驱动中 ComputeDomain 已正式可用，而若干共享、动态 MIG、健康特性仍为 alpha 且默认禁用。&lt;strong&gt;Kubernetes 抢占不支持 DRA 资源&lt;/strong&gt;，这是从设备插件迁移时最容易踩的行为差异。&lt;/p&gt;
&lt;h2 id="dra-没有解决什么"&gt;DRA 没有解决什么&lt;/h2&gt;
&lt;p&gt;DRA 解决的是“设备分配的可表达性和可观测性”，但有几件明确不做的事情。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;DRA 不定义隔离机制。&lt;/strong&gt; MIG 的硬件级隔离、vGPU 的虚拟化切分、时间片复用，这些仍然是数据平面的责任。DRA 让你更容易声明“我要一个 MIG 4g.40gb 的实例”，但隔离本身仍然由底层硬件和驱动提供。在前面的 &lt;a href="../data-plane-taxonomy/"&gt;数据平面谱系&lt;/a&gt;一章中已经讨论过，隔离强度和资源单位是数据平面的核心交付，DRA 只是把“请求这些能力”的过程标准化了。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;DRA 不替代调度策略。&lt;/strong&gt; 队列管理、优先级抢占、配额控制，这些仍然是 Volcano/Kueue 的领地。DRA 和 Kueue 有天然的合作点（Kueue 可以基于 ResourceClaim 做队列感知的设备分配），但 DRA 本身不包含调度策略语义。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;DRA 不支持抢占。&lt;/strong&gt; 截至 Kubernetes v1.35，DRA 资源不支持 Pod 预占。一个低优先级 Pod 占用的设备不会被高优先级 Pod 抢走，高优先级 Pod 只能等待设备释放。这对严格 SLA 场景是一个需要注意的限制。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;与 Device Plugin 的过渡期共存。&lt;/strong&gt; DRA 和 Device Plugin 在同一个集群中可以共存。同一个节点上的设备可以一部分通过 Device Plugin 暴露（作为 Extended Resource），另一部分通过 DRA 的 ResourceSlice 暴露。但这种共存增加了运维复杂度，平台需要决定迁移节奏和边界。&lt;/p&gt;
&lt;h2 id="对-gpu-调度体系的长远影响"&gt;对 GPU 调度体系的长远影响&lt;/h2&gt;
&lt;p&gt;DRA GA 之后，它对 GPU 基础设施的影响主要体现在三个方向。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;参数化调度成为可能。&lt;/strong&gt; 这是 DRA 最直接的价值。在 Device Plugin 时代，调度器选节点的依据是“这个节点有几块 GPU”；DRA 时代，调度器可以基于显存容量、MIG profile、互联拓扑、设备健康状态等多维属性做选择。结合 &lt;a href="../../control-plane/decision-axes/"&gt;决策轴&lt;/a&gt;一章的框架，DRA 直接强化了“粒度”和“兼容性”两个维度的表达能力。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;设备共享有了标准的 API 层。&lt;/strong&gt; DRA 的 ResourceClaim 天然支持设备共享，多个 Pod 可以引用同一个 ResourceClaim。结合 v1.34 引入的 Consumable Capacity（可消费容量）特性，驱动可以声明设备的可分配容量（比如一块 80GB 的 GPU 可以被多个 Claim 按需切分），调度器负责确保所有 Claim 的容量之和不超过总量。这为 GPU 共享提供了一条标准化的路径，而不依赖各家厂商的私有实现。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;异构芯片的统一接入层。&lt;/strong&gt; GPU、TPU、NPU、DPU 的接入在 Device Plugin 时代各自为政：每个厂商实现自己的 plugin，API 语义不统一。DRA 通过 ResourceSlice + DeviceClass + CEL 表达式提供了一套统一的设备描述和匹配框架。异构芯片的厂商只需要实现 DRA 驱动、发布 ResourceSlice，就可以接入 Kubernetes 的标准调度流程。这对前面 &lt;a href="../../fundamentals/gpu-landscape/"&gt;异构加速器全景与生态&lt;/a&gt;一章讨论的多芯片协同架构是一个重要的基础设施支撑。&lt;/p&gt;
&lt;h2 id="从-device-plugin-迁移到-dra"&gt;从 Device Plugin 迁移到 DRA&lt;/h2&gt;
&lt;p&gt;对于已经在生产环境使用 Device Plugin 的团队，迁移不需要一步到位。&lt;/p&gt;
&lt;p&gt;短期（当前）：DRA 和 Device Plugin 可以共存。可以在部分节点上启用 DRA 驱动做灰度验证，同时保持 Device Plugin 在其余节点上运行。&lt;/p&gt;
&lt;p&gt;中期（验证期）：选择合适的场景先迁移。参数化需求强的场景（MIG profile 选择、显存容量匹配、异构芯片混合部署）是 DRA 最能体现价值的切入点。纯整卡独占的场景，Device Plugin 仍然够用。&lt;/p&gt;
&lt;p&gt;长期（全面迁移）：当 DRA 驱动的成熟度和生态覆盖度足够时，Device Plugin 会逐步退化为向后兼容层。各主流 GPU 厂商已经在推进 DRA 驱动的实现（NVIDIA 的 CDI-based DRA driver 已进入 beta 阶段，AMD 的 ROCm DRA driver 在 alpha 阶段），生态追赶速度取决于厂商投入和社区 adoption。&lt;/p&gt;
&lt;p&gt;迁移的核心判断标准很简单：你是否需要在调度阶段表达“我要什么样的设备”，而不仅仅是“我要几块设备”。如果答案是“是”，DRA 就值得认真评估。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;DRA 的本质是把 Kubernetes 的设备资源分配从“节点本地黑盒”推进到“控制面可见的一等 API”。它解决了 Device Plugin 的三个结构性问题（参数化请求、分配透明度、生命周期解耦），同时明确地把隔离机制和调度策略留给数据平面和控制面各自处理。对 GPU 平台来说，DRA 不是锦上添花，而是让“异构、参数化、可治理”的设备调度从可能变为可行的基础设施前提。&lt;/p&gt;
&lt;h2 id="参考文献"&gt;参考文献&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/docs/concepts/scheduling-eviction/dynamic-resource-allocation/" target="_blank" rel="noopener"&gt;Dynamic Resource Allocation - kubernetes.io&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/3063-dynamic-resource-allocation" target="_blank" rel="noopener"&gt;KEP-3063: Dynamic Resource Allocation - github.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/4381-dra-structured-parameters" target="_blank" rel="noopener"&gt;KEP-4381: DRA Structured Parameters - github.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/blog/2025/09/18/kubernetes-v1-34-dra-consumable-capacity/" target="_blank" rel="noopener"&gt;Kubernetes v1.34: DRA Consumable Capacity - kubernetes.io&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.aks.azure.com/2025/11/17/dra-devices-and-drivers-on-kubernetes" target="_blank" rel="noopener"&gt;Delve into DRA, devices, and drivers on Kubernetes - Azure AKS Blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cloud.google.com/blog/products/containers-kubernetes/kubernetes-device-management-with-dra-dynamic-resource-allocation" target="_blank" rel="noopener"&gt;Kubernetes Device Management with DRA - Google Cloud Blog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>昇腾 vNPU：驱动硬切分与运行时软切分</title><link>https://jimmysong.io/zh/book/ai-infra/data-plane/ascend-vnpu/</link><pubDate>Sat, 15 Aug 2026 10:32:00 +0000</pubDate><author>Jimmy Song</author><guid>https://jimmysong.io/zh/book/ai-infra/data-plane/ascend-vnpu/</guid><description>以昇腾 NPU 为案例应用数据平面谱系：昇腾芯片谱系与历史、与 NVIDIA GPU 的架构生态差异、三条 vNPU 路径（驱动硬切分、vCANN-RT、HAMi）的原理与支持程度，以及场景选型。</description><content:encoded>
&lt;blockquote&gt;
&lt;p&gt;昇腾生态把 GPU 世界里“硬件切分还是软件共享”的路线之争，在同一厂商内部重演了一遍，而且给了两个软件答案：一个来自华为自己，一个来自 HAMi 社区。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="本章要解决什么"&gt;本章要解决什么&lt;/h2&gt;
&lt;p&gt;前面几章建立了&lt;a href="../data-plane-taxonomy/"&gt;数据平面谱系&lt;/a&gt;，并用它分析了 &lt;a href="../mig/"&gt;MIG&lt;/a&gt;（硬件切分）、&lt;a href="../hami/"&gt;HAMi&lt;/a&gt;（软件共享）和 &lt;a href="../dra/"&gt;DRA&lt;/a&gt;（资源分配 API）。这些分析都以 NVIDIA 生态为主。本章把同一组决策轴应用到昇腾（Ascend）NPU 生态，回答六个问题：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;昇腾为什么叫 NPU？它的芯片谱系经历了怎样的演进，各代产品对应哪些芯片？&lt;/li&gt;
&lt;li&gt;NPU 与 NVIDIA GPU 在架构和生态上有何本质差异，这些差异如何决定“能切什么”？&lt;/li&gt;
&lt;li&gt;昇腾官方的 vNPU 虚拟化到底是什么机制，隔离边界在哪里？&lt;/li&gt;
&lt;li&gt;华为 2026 年推出的官方软切分（vCANN-RT）与 HAMi 的 libvnpu 是什么关系？&lt;/li&gt;
&lt;li&gt;在 Kubernetes 里，Volcano 的 MindCluster 模式与 HAMi 模式有何区别，HAMi 对各代芯片的支持到什么程度？&lt;/li&gt;
&lt;li&gt;一个真实的推理集群应该怎么选？&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;结论先行：昇腾生态当前存在&lt;strong&gt;三条可用的 vNPU 路径&lt;/strong&gt;，它们在数据平面谱系上的位置如下图。驱动硬切分对应 NVIDIA 世界的 MIG，官方软切分 vCANN-RT 与 HAMi 软切分共同对应“HAMi 式运行时拦截”，三者共享同一套底层注入设施（Ascend Docker Runtime 与 &lt;code&gt;ld.so.preload&lt;/code&gt;）。&lt;/p&gt;
&lt;figure class="mx-auto text-center"&gt;
&lt;img src="https://assets.jimmysong.io/images/book/gpu-infra/data-plane/ascend-vnpu/ascend-vnpu-paths.svg" data-img="https://assets.jimmysong.io/images/book/gpu-infra/data-plane/ascend-vnpu/ascend-vnpu-paths.svg" alt="图 3: 昇腾 vNPU 三条路径：驱动硬切分与运行时软切分" data-caption="图 3: 昇腾 vNPU 三条路径：驱动硬切分与运行时软切分"
width="2443"
height="672"
loading="lazy" decoding="async" class="image-loading"
onload="this.classList.remove('image-loading'); this.classList.add('image-loaded');"
onerror="handleImageError(this); this.classList.remove('image-loading');"&gt;
&lt;figcaption&gt;图 3: 昇腾 vNPU 三条路径：驱动硬切分与运行时软切分&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="昇腾谱系从-310910-到-910c"&gt;昇腾谱系：从 310/910 到 910C&lt;/h2&gt;
&lt;p&gt;先厘清命名体系：&lt;strong&gt;昇腾（Ascend）是芯片品牌&lt;/strong&gt;，覆盖推理与训练；&lt;strong&gt;Atlas 是硬件产品品牌&lt;/strong&gt;（模块、板卡、服务器、集群）；软件栈是 CANN（Compute Architecture for Neural Networks，对标 CUDA）加框架 MindSpore，再往上是一直到 2024 年还叫 MindX DL、后来归一为 &lt;a href="https://gitcode.com/Ascend/mind-cluster" target="_blank" rel="noopener"&gt;mind-cluster&lt;/a&gt; 的集群组件。所以“昇腾 310P3”是芯片，“Atlas 300I Duo”是用这颗芯片（的两颗）做成的推理卡。&lt;/p&gt;
&lt;p&gt;芯片与产品的大事记：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;时间&lt;/th&gt;
&lt;th&gt;芯片与产品&lt;/th&gt;
&lt;th&gt;定位与要点&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;2018-10&lt;/td&gt;
&lt;td&gt;昇腾 310 发布（HC2018）&lt;/td&gt;
&lt;td&gt;12nm 达芬奇 Lite 架构 SoC，面向边缘与推理；同场预告 910&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2019-08&lt;/td&gt;
&lt;td&gt;昇腾 910 商用&lt;/td&gt;
&lt;td&gt;7nm，32 个达芬奇 Max 核心，FP16 256 TFLOPS、INT8 512 TOPS；同场发布 MindSpore&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2019 至 2020&lt;/td&gt;
&lt;td&gt;出口管制&lt;/td&gt;
&lt;td&gt;华为 2019 年 5 月被列入美国实体清单，2020 年外国直接产品规则进一步限制先进制程代工，直接重塑了后续路线&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2020 至 2022&lt;/td&gt;
&lt;td&gt;910A 世代、310P 世代&lt;/td&gt;
&lt;td&gt;910A 用于 Atlas 800 训练服务器；2022 年 310P 系列落地：Atlas 300I Duo（双芯，280 TOPS INT8，96GB LPDDR4X）与 300I Pro（单芯 140 TOPS，24GB），推理主力&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2023&lt;/td&gt;
&lt;td&gt;910B 家族与 Atlas A2 整机&lt;/td&gt;
&lt;td&gt;910B1/B2/B3/B4/B4-1 等型号；Atlas 800T A2 训练服务器（8 颗 910B）、800I A2 推理服务器（910B4）、300I A2 推理卡，整体对标 A100 世代&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2025&lt;/td&gt;
&lt;td&gt;910C 与超节点&lt;/td&gt;
&lt;td&gt;910C 采用双 die 封装（约 800 TFLOPS FP16）；CloudMatrix 384 超节点以 384 颗 910C 组成紧耦合逻辑节点，实现全域可寻址的统一内存池；9 月发布三年路线图&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;理解这张表对选型很关键：&lt;strong&gt;vNPU 能力只存在于推理形态的芯片上&lt;/strong&gt;。310P 系列（300I Duo、300I Pro）与 910B4 代推理（300I A2、800I A2）有驱动切分模板；训练卡（910A、910B2/B3）没有。910C 目前以超节点整卡调度为主，HAMi v2.9.0 为其 SuperPod 场景加入了模块对分配，但同样没有切分模板。&lt;/p&gt;
&lt;h2 id="从-gpu-到-npu架构与生态差异"&gt;从 GPU 到 NPU：架构与生态差异&lt;/h2&gt;
&lt;h3 id="为什么叫-npu"&gt;为什么叫 NPU&lt;/h3&gt;
&lt;p&gt;NPU（Neural-network Processing Unit，神经网络处理器）这个名字传达的是&lt;strong&gt;领域专用&lt;/strong&gt;：整颗芯片为张量计算设计，而不是像 GPU 那样从图形处理演化成通用并行处理器。GPU 的计算主力是流式多处理器里的 SIMT CUDA Core 加 Tensor Core；昇腾 &lt;a href="https://www.hiascend.com/" target="_blank" rel="noopener"&gt;NPU&lt;/a&gt; 采用达芬奇（Da Vinci）架构，每个 AI Core 由三部分组成：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Cube 单元&lt;/strong&gt;：专用矩阵乘引擎，一个时钟周期完成固定规模的乘加阵列，是卷积与 GEMM 的绝对主力&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Vector 单元&lt;/strong&gt;：激活函数与逐元素运算&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Scalar 单元&lt;/strong&gt;：标量与控制逻辑&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;AI Core 之外还有两类“陪跑”单元：&lt;strong&gt;AI CPU&lt;/strong&gt; 承接未被 AI Core 加速的算子，&lt;strong&gt;DVPP&lt;/strong&gt; 媒体引擎负责图像编解码。连管理工具的命名都在强调差异：NVIDIA 是 &lt;code&gt;nvidia-smi&lt;/code&gt;，昇腾是 &lt;code&gt;npu-smi&lt;/code&gt;。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;GPU（NVIDIA）&lt;/th&gt;
&lt;th&gt;NPU（昇腾）&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;定位&lt;/td&gt;
&lt;td&gt;通用并行处理器，图形血统&lt;/td&gt;
&lt;td&gt;面向神经网络的专用处理器（达芬奇架构）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;计算单元&lt;/td&gt;
&lt;td&gt;流式多处理器：SIMT CUDA Core 加 Tensor Core&lt;/td&gt;
&lt;td&gt;AI Core：Cube 矩阵引擎加 Vector 加 Scalar&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;算子兜底&lt;/td&gt;
&lt;td&gt;CUDA 库，跑在同样的核心上&lt;/td&gt;
&lt;td&gt;AI CPU，与 AI Core 并列的独立单元&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;媒体引擎&lt;/td&gt;
&lt;td&gt;编解码模块，不是 MIG 的切分维度&lt;/td&gt;
&lt;td&gt;DVPP 引擎，vNPU 模板的显式切分维度&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;显存&lt;/td&gt;
&lt;td&gt;GDDR 或 HBM&lt;/td&gt;
&lt;td&gt;310P 用 LPDDR4X，910B 起用 HBM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;芯片间互连&lt;/td&gt;
&lt;td&gt;NVLink 与 NVSwitch&lt;/td&gt;
&lt;td&gt;HCCS；910C 超节点升级为统一总线与统一内存&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;软件栈&lt;/td&gt;
&lt;td&gt;CUDA（加上十余年的库与工具积累）&lt;/td&gt;
&lt;td&gt;CANN、MindSpore、MindIE，兼容 PyTorch（torch-npu）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="生态差异是比算力更深的鸿沟"&gt;生态差异是比算力更深的鸿沟&lt;/h3&gt;
&lt;p&gt;CUDA 生态是 NVIDIA 真正的护城河：算子库、调试器、profiler、框架后端经过十余年积累。昇腾的对策是 CANN 提供 aclRuntime 与算子库，通过 torch-npu 适配 PyTorch 生态，同时自研 MindSpore 与推理引擎 MindIE。实际工程里这意味着两点：模型迁移需要验证算子覆盖与精度（部分算子会落到 AI CPU 上拉低性能），版本配套也更严格（驱动、CANN、框架、容器镜像常常要求成对匹配，本书实验中 libvnpu 与驱动版本必须匹配就是同一逻辑的缩影）。&lt;/p&gt;
&lt;h3 id="差异如何决定能切什么"&gt;差异如何决定“能切什么”&lt;/h3&gt;
&lt;p&gt;把架构差异投影到虚拟化上，就能解释两条生态各自的切分维度：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;NVIDIA 的 &lt;a href="../mig/"&gt;MIG&lt;/a&gt; 切的是 SM 与显存（连同 L2 缓存），编解码引擎不在切分维度里。&lt;/li&gt;
&lt;li&gt;昇腾的驱动模板切的是 &lt;strong&gt;AI Core、AI CPU、显存、DVPP&lt;/strong&gt; 四个维度，模板名直接编码了切法：&lt;code&gt;vir04_3c_ndvpp&lt;/code&gt; 表示 4 个 AI Core、3 个 AI CPU、不含 DVPP。&lt;/li&gt;
&lt;li&gt;软切分同理：GPU 侧拦截 CUDA 调用（HAMi 的 &lt;code&gt;libvgpu.so&lt;/code&gt;），NPU 侧拦截 CANN/DCMI 调用（&lt;code&gt;libvnpu.so&lt;/code&gt; 与 &lt;code&gt;libvruntime.so&lt;/code&gt;）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;本章真机验证用的 310P3 报告 8 个 AI Core、7 个 AI CPU、21525 MB 可见显存。这组数字就是 vNPU 世界的“切分库存”：模板 &lt;code&gt;vir01&lt;/code&gt; 到 &lt;code&gt;vir04&lt;/code&gt; 分配 1 到 4 个 AI Core，HAMi 配置里的 &lt;code&gt;aiCore&lt;/code&gt;、&lt;code&gt;aiCPU&lt;/code&gt;、&lt;code&gt;memoryAllocatable&lt;/code&gt; 字段对应的也是同一份清单。&lt;/p&gt;
&lt;h3 id="什么是-vnpu"&gt;什么是 vNPU&lt;/h3&gt;
&lt;p&gt;vNPU（虚拟 NPU）是 NPU 世界里的 vGPU：一张小于物理卡的逻辑 NPU，容器拿到它就像拿到一整颗设备。它有两种诞生方式，这个区别正是本章的主线：由昇腾驱动把硬件&lt;strong&gt;静态分区&lt;/strong&gt;成模板大小的 vNPU（硬切分），或者由运行时拦截库在用户态&lt;strong&gt;改写设备视图&lt;/strong&gt;并按容器强制配额（软切分）。下面依次展开三条路径。&lt;/p&gt;
&lt;h2 id="路径一驱动级模板硬切分"&gt;路径一：驱动级模板硬切分&lt;/h2&gt;
&lt;h3 id="机制模板就是静态分区表"&gt;机制：模板就是静态分区表&lt;/h3&gt;
&lt;p&gt;昇腾驱动（npu-smi）提供 vNPU 切分能力：按“虚拟化实例模板”把一张物理 NPU 的 &lt;strong&gt;AI Core、AI CPU、显存和编解码引擎（VPC/VENC/VDEC/JPEGD/JPEGE/PNGD）&lt;/strong&gt; 一次性静态分区，每个 vNPU 拿到独占的硬件份额，边界由驱动强制执行。这与 &lt;a href="../mig/"&gt;MIG&lt;/a&gt; 在谱系上完全同构：离散资源单位、强隔离、切分粒度受模板集合约束。&lt;/p&gt;
&lt;p&gt;模板命名规则为 &lt;code&gt;vir&amp;lt;AI Core 数&amp;gt;_&amp;lt;AI CPU 数&amp;gt;c_&amp;lt;显存&amp;gt;&lt;/code&gt;。以华为官方硬切分参考实践（2025 年 12 月发布，配套 Ascend HDK 25.5.0）列出的模板为例：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;硬件&lt;/th&gt;
&lt;th&gt;可用模板&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Atlas 300I Duo 96G（310P3 芯片，单卡双芯）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vir01&lt;/code&gt;、&lt;code&gt;vir02&lt;/code&gt;、&lt;code&gt;vir02_1c&lt;/code&gt;、&lt;code&gt;vir04&lt;/code&gt;、&lt;code&gt;vir04_3c&lt;/code&gt;、&lt;code&gt;vir04_3c_ndvpp&lt;/code&gt;、&lt;code&gt;vir04_4c_dvpp&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Atlas 300I A2 / 800I A2 32G（910B4 代推理）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vir05_1c_8g&lt;/code&gt;、&lt;code&gt;vir10_3c_16g&lt;/code&gt;、&lt;code&gt;vir10_3c_16g_nm&lt;/code&gt;、&lt;code&gt;vir10_4c_16g_m&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Atlas 300I A2 / 800I A2 64G&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vir05_1c_16g&lt;/code&gt;、&lt;code&gt;vir10_3c_32g&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;裸机操作命令：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npu-smi info -t template-info &lt;span class="c1"&gt;# 查询本机支持的模板&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npu-smi &lt;span class="nb"&gt;set&lt;/span&gt; -t create-vnpu -i &amp;lt;id&amp;gt; -c &amp;lt;chip&amp;gt; -f &amp;lt;模板名&amp;gt; &lt;span class="c1"&gt;# 创建 vNPU&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npu-smi &lt;span class="nb"&gt;set&lt;/span&gt; -t destroy-vnpu -i &amp;lt;id&amp;gt; -c &amp;lt;chip&amp;gt; -v &amp;lt;vnpu_id&amp;gt; &lt;span class="c1"&gt;# 销毁&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npu-smi &lt;span class="nb"&gt;set&lt;/span&gt; -t vnpu-cfg-recover -d mode &lt;span class="c1"&gt;# 重启后恢复切分配置&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;容器挂载有两种方式：原生 Docker 直接挂 &lt;code&gt;/dev/vdavinci&amp;lt;id&amp;gt;&lt;/code&gt;；或通过 Ascend Docker Runtime，用 &lt;code&gt;ASCEND_VISIBLE_DEVICES=&amp;lt;vNPU id&amp;gt;&lt;/code&gt; 加 &lt;code&gt;ASCEND_RUNTIME_OPTIONS=VIRTUAL&lt;/code&gt; 注入，也可以用 &lt;code&gt;ASCEND_VISIBLE_DEVICES=&amp;lt;物理卡号&amp;gt;&lt;/code&gt; 加 &lt;code&gt;ASCEND_VNPU_SPECS=&amp;lt;模板&amp;gt;&lt;/code&gt; 在容器启动时按需切分。&lt;/p&gt;
&lt;h3 id="硬约束"&gt;硬约束&lt;/h3&gt;
&lt;p&gt;参考实践明确列出的限制，选型前必须知道：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;仅支持推理场景&lt;/strong&gt;。训练卡（如 800T A2 训练整机）没有 vNPU 模板能力。&lt;/li&gt;
&lt;li&gt;物理 NPU 与 vNPU 不能混用，已切分的卡不能再整卡挂载。&lt;/li&gt;
&lt;li&gt;同一台服务器必须插同规格卡（48G 与 96G 不可混插）。&lt;/li&gt;
&lt;li&gt;一个推理服务只能绑定一个 vNPU。&lt;/li&gt;
&lt;li&gt;容器重启后 vNPU 仍在（&lt;code&gt;vnpu-cfg-recover&lt;/code&gt;），但调整切分布局属于破坏性操作，需要业务侧配合。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="kubernetes-集成静态与动态两条入口"&gt;Kubernetes 集成：静态与动态两条入口&lt;/h3&gt;
&lt;p&gt;手动 &lt;code&gt;npu-smi&lt;/code&gt; 切分再挂载的方式对应华为云文档里的“静态虚拟化”。生产上更有价值的是&lt;strong&gt;动态虚拟化&lt;/strong&gt;：Pod 调度到节点后，由设备插件按调度决策实时创建 vNPU，Pod 销毁后回收。这条路径依赖华为 &lt;a href="https://gitcode.com/Ascend/mind-cluster" target="_blank" rel="noopener"&gt;mind-cluster&lt;/a&gt; 全家桶：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ascend-device-plugin&lt;/strong&gt;：发现并上报物理与虚拟设备，故障时换卡重建任务&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ascend Docker Runtime&lt;/strong&gt;：设备与库文件注入&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NodeD / ClusterD / Ascend Operator&lt;/strong&gt;：节点与集群级运维&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Volcano&lt;/strong&gt;：批量调度（MindCluster 模式即由此而来）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Volcano v1.14 起，MindCluster 的核心调度逻辑被原生集成进 &lt;code&gt;deviceshare&lt;/code&gt; 插件（&lt;code&gt;deviceshare.AscendMindClusterVNPUEnable: true&lt;/code&gt;），需要把初始化参数 &lt;code&gt;presetVirtualDevice&lt;/code&gt; 设为 &lt;code&gt;&amp;quot;false&amp;quot;&lt;/code&gt; 开启动态虚拟化。Pod 通过标签声明需求：&lt;code&gt;ring-controller.atlas: ascend-310P&lt;/code&gt;、&lt;code&gt;vnpu-level: low/high&lt;/code&gt;、&lt;code&gt;vnpu-dvpp: yes/no&lt;/code&gt;，并请求 &lt;code&gt;huawei.com/npu-core&lt;/code&gt; 资源；调度器按 AI Core 数、档位与 dvpp 维度匹配 &lt;code&gt;vir&lt;/code&gt; 模板（&lt;code&gt;high&lt;/code&gt; 档资源不足时可降级）。&lt;/p&gt;
&lt;p&gt;按 Volcano 官方文档，MindCluster 模式&lt;strong&gt;当前只支持昇腾 310 系列&lt;/strong&gt;，910 系列在计划中。这与其代码路径一致：Volcano 源码中 MindCluster 的 vNPU 实现位于 &lt;code&gt;pkg/scheduler/api/devices/ascend/mindcluster/ascend310p/&lt;/code&gt;，模板常量正是上面 300I Duo 的 &lt;code&gt;vir01&lt;/code&gt; 到 &lt;code&gt;vir04_4c_dvpp&lt;/code&gt; 那一组。&lt;/p&gt;
&lt;h2 id="路径二官方软切分-vcann-rt"&gt;路径二：官方软切分 vCANN-RT&lt;/h2&gt;
&lt;p&gt;华为在 2026 年发布的软切分参考实践中给出了第二条路径：vCANN-RT。它来自 openEuler 的 ubs-virt 仓库（&lt;code&gt;ubs-virt-enpu/vcann-rt&lt;/code&gt;），核心是两个产物：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;libvruntime.so&lt;/code&gt;：通过 &lt;code&gt;ld.so.preload&lt;/code&gt; 预加载进业务容器，拦截昇腾 runtime 调用&lt;/li&gt;
&lt;li&gt;&lt;code&gt;enpu-monitor&lt;/code&gt;：监控工具&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;机制要点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;算力按时间片轮转&lt;/strong&gt;，每个时间片默认 100ms。申请 20% 算力的容器在每个轮转周期获得 20ms 使用权。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;粒度极细&lt;/strong&gt;：AI Core 配额 1 到 100（整数百分比），显存最小 1MB。&lt;/li&gt;
&lt;li&gt;三种调度策略：&lt;code&gt;fixed-share&lt;/code&gt;（严格按配比，空闲也不让出）、&lt;code&gt;elastic&lt;/code&gt;（推荐，跳过空闲容器的时间片）、&lt;code&gt;best-effort&lt;/code&gt;（利用率最高，无 QoS 保证）。&lt;/li&gt;
&lt;li&gt;每容器一份 &lt;code&gt;npu_info.config&lt;/code&gt;，声明物理 NPU id、vNPU id、配额、共享内存 id 与调度策略。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;支持范围与定位也很明确：面向 &lt;strong&gt;Atlas 300I A2 / 800I A2&lt;/strong&gt;，要求 Ascend HDK 25.5.0、CANN 8.5.0 或 9.1.0、MindCluster 组件 26.0.0.0，节点需先执行 &lt;code&gt;npu-smi set -t device-share&lt;/code&gt; 开启容器共享模式。单卡最多 63 个容器，单容器限一张物理 NPU，不支持特权容器。官方给的目标场景是&lt;strong&gt;成本敏感的教育实训&lt;/strong&gt;，单卡同时跑至少 8 个实训任务，而不是生产多租户。&lt;/p&gt;
&lt;p&gt;部署上，Ascend Deployer 工具提供 &lt;code&gt;--install-scene=softshare&lt;/code&gt;（K8s 场景）和 &lt;code&gt;--install-scene=vcannrt&lt;/code&gt;（纯 Docker 场景）一键安装；K8s 路径同样依赖 device plugin、Volcano、ClusterD、Ascend Operator 与 Ascend Docker Runtime，节点打 &lt;code&gt;chip1softsharedev&lt;/code&gt; 标签。&lt;/p&gt;
&lt;p&gt;注意这份参考实践声明“仅供用户参考使用”，不可直接用于商用产品。定位介于社区方案与正式产品之间。&lt;/p&gt;
&lt;h2 id="路径三hami-路径"&gt;路径三：HAMi 路径&lt;/h2&gt;
&lt;p&gt;HAMi 是 CNCF Sandbox 项目 &lt;a href="https://github.com/Project-HAMi/HAMi" target="_blank" rel="noopener"&gt;Project-HAMi/HAMi&lt;/a&gt;（仓库创建于 2021 年 9 月，前身是 k8s-vgpu-scheduler），覆盖 NVIDIA、昇腾、寒武纪等十余类加速器。它在昇腾上实际提供两个子模式，容易混淆：&lt;/p&gt;
&lt;h3 id="hami-模板模式换调度器不换数据面"&gt;HAMi 模板模式：换调度器，不换数据面&lt;/h3&gt;
&lt;p&gt;HAMi 的 ascend 设备插件（&lt;a href="https://github.com/Project-HAMi/ascend-device-plugin" target="_blank" rel="noopener"&gt;Project-HAMi/ascend-device-plugin&lt;/a&gt;）读取 &lt;code&gt;hami-scheduler-device&lt;/code&gt; ConfigMap 中的自定义模板，Pod 请求 &lt;code&gt;huawei.com/Ascend310P&lt;/code&gt; 加 &lt;code&gt;huawei.com/Ascend310P-memory&lt;/code&gt;。显存请求会自动对齐到最近的可满足模板（例如卡上有 1/4 和 1/2 档模板时，请求 1024MB 会按 1/4 档对齐）。&lt;strong&gt;数据面仍然是驱动级 vNPU&lt;/strong&gt;：插件最终通过 &lt;code&gt;ASCEND_VNPU_SPECS&lt;/code&gt; 让 Ascend Docker Runtime 按模板切分。所以 HAMi 模板模式与路径一的区别只在控制面（调度器、模板治理、异构集群支持），隔离强度相同。&lt;/p&gt;
&lt;h3 id="hami-core-软切分社区版的运行时拦截"&gt;HAMi-core 软切分：社区版的运行时拦截&lt;/h3&gt;
&lt;p&gt;HAMi v2.9.0（2026 年 5 月）引入 HAMi-core 模式，软切分引擎是 &lt;a href="https://github.com/Project-HAMi/hami-vnpu-core" target="_blank" rel="noopener"&gt;Project-HAMi/hami-vnpu-core&lt;/a&gt;，以子模块形式内嵌在 ascend-device-plugin 中，由其 CI 在 CANN 环境里编译出 ARM64 的 &lt;code&gt;libvnpu.so&lt;/code&gt;。机制与 vCANN-RT 高度同构，细节上有自己的实现：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;插件 DaemonSet 把 &lt;code&gt;libvnpu.so&lt;/code&gt; 与 &lt;code&gt;ld.so.preload&lt;/code&gt; 放到宿主机 &lt;code&gt;/usr/local/hami-vnpu-core/&lt;/code&gt;，由 Ascend Docker Runtime 注入容器。&lt;/li&gt;
&lt;li&gt;显存配额通过环境变量 &lt;code&gt;NPU_MEM_QUOTA&lt;/code&gt; 下发，&lt;code&gt;npu-smi&lt;/code&gt; 等设备查询被改写为配额视图。&lt;/li&gt;
&lt;li&gt;算力通过共享内存注册表（&lt;code&gt;/hami-shared-region/0_global_registry&lt;/code&gt;）上的 Global Manager 协调。真机日志中的 &lt;code&gt;Compute limit: 1, Memory limit: 8192, FixedShare: false&lt;/code&gt; 与 vCANN-RT 的 fixed-share 与 elastic 策略显然处在同一设计空间。&lt;/li&gt;
&lt;li&gt;Prometheus 指标暴露在插件 Pod 的 &lt;code&gt;:9395&lt;/code&gt;，含每容器显存上限、用量与利用率。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;约束：软切分仅支持 ARM 平台，要求 Ascend 驱动不低于 25.5、节点上有 &lt;code&gt;npu-smi&lt;/code&gt;，且需 &lt;code&gt;huawei.com/vnpu-mode: hami-core&lt;/code&gt; 注解显式开启。&lt;/p&gt;
&lt;p&gt;2026 年 8 月 14 日在昇腾 310P3 ARM 服务器上的真机验证（麒麟 V10、驱动 25.5.1、Kubernetes 1.28、Volcano master）给出了完整证据链：申请 8192MB 切片的容器内 &lt;code&gt;npu-smi&lt;/code&gt; 显示 &lt;code&gt;0 / 8192&lt;/code&gt;，宿主机同卡显示 &lt;code&gt;1848 / 21525&lt;/code&gt;；两个 Pod 以 binpack 落到同一张物理卡（同 Bus-Id），各自独立 8192MB 窗口；指标端点上报的 &lt;code&gt;hami_vgpu_memory_limit_bytes&lt;/code&gt; 精确等于 8192MiB。完整过程见 &lt;a href="https://project-hami.io/blog/volcano-ascend-vnpu-soft-slicing" target="_blank" rel="noopener"&gt;HAMi 网站的博客&lt;/a&gt;与&lt;a href="https://project-hami.io/tutorials/labs/volcano-ascend-vnpu" target="_blank" rel="noopener"&gt;实验 13&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id="volcano-里的-hami-模式"&gt;Volcano 里的 HAMi 模式&lt;/h3&gt;
&lt;p&gt;Volcano v1.14（2026 年 1 月）同样原生集成了 HAMi 模式：&lt;code&gt;deviceshare.AscendHAMiVNPUEnable: true&lt;/code&gt;，配合 &lt;code&gt;deviceshare.SchedulePolicy: binpack|spread&lt;/code&gt; 与指向 &lt;code&gt;hami-scheduler-device&lt;/code&gt; ConfigMap 的 &lt;code&gt;KnownGeometriesCMName&lt;/code&gt;。与 MindCluster 模式的差异：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;MindCluster 模式&lt;/th&gt;
&lt;th&gt;HAMi 模式&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Volcano 开关&lt;/td&gt;
&lt;td&gt;&lt;code&gt;AscendMindClusterVNPUEnable&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;AscendHAMiVNPUEnable&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;设备插件&lt;/td&gt;
&lt;td&gt;华为 mind-cluster ascend-device-plugin&lt;/td&gt;
&lt;td&gt;Project-HAMi ascend-device-plugin&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;芯片覆盖&lt;/td&gt;
&lt;td&gt;仅 310 系列（910 计划中）&lt;/td&gt;
&lt;td&gt;310P、910A/B2/B3/B4/C，支持异构集群&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;资源名&lt;/td&gt;
&lt;td&gt;&lt;code&gt;huawei.com/npu-core&lt;/code&gt; 加档位标签&lt;/td&gt;
&lt;td&gt;&lt;code&gt;huawei.com/Ascend310P&lt;/code&gt; 加 &lt;code&gt;-memory&lt;/code&gt;（及可选 &lt;code&gt;-core&lt;/code&gt;）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;切分方式&lt;/td&gt;
&lt;td&gt;驱动模板（动态虚拟化）&lt;/td&gt;
&lt;td&gt;模板模式为驱动模板；加注解后为 libvnpu 软切分&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;软切分支持&lt;/td&gt;
&lt;td&gt;无&lt;/td&gt;
&lt;td&gt;有（&lt;code&gt;vnpu-mode: hami-core&lt;/code&gt;，需 Volcano 1.16 及以上）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;若同一 Volcano 集群同时跑 vGPU（NVIDIA）与 vNPU，需要把两边的模板 ConfigMap 合并为一个再供 &lt;code&gt;KnownGeometriesCMName&lt;/code&gt; 引用。&lt;/p&gt;
&lt;h2 id="按芯片看支持矩阵"&gt;按芯片看支持矩阵&lt;/h2&gt;
&lt;p&gt;路径层面的对比之外，选型时更常卡住的是“我这批卡到底支持什么”。把谱系、官方路径与 HAMi 支持历史合并成一张按芯片的矩阵（以 2026 年 8 月的公开信息为准）：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;芯片&lt;/th&gt;
&lt;th&gt;代表产品&lt;/th&gt;
&lt;th&gt;驱动硬切分模板&lt;/th&gt;
&lt;th&gt;vCANN-RT 软切分&lt;/th&gt;
&lt;th&gt;HAMi 模板模式&lt;/th&gt;
&lt;th&gt;HAMi-core 软切分&lt;/th&gt;
&lt;th&gt;Volcano MindCluster&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;310P3&lt;/td&gt;
&lt;td&gt;Atlas 300I Duo / 300I Pro&lt;/td&gt;
&lt;td&gt;有（&lt;code&gt;vir01&lt;/code&gt; 到 &lt;code&gt;vir04_4c_dvpp&lt;/code&gt;）&lt;/td&gt;
&lt;td&gt;无&lt;/td&gt;
&lt;td&gt;有（v2.4.0 起）&lt;/td&gt;
&lt;td&gt;有（2026-08 真机验证）&lt;/td&gt;
&lt;td&gt;有（唯一支持的系列）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;910A&lt;/td&gt;
&lt;td&gt;Atlas 800 训练服务器&lt;/td&gt;
&lt;td&gt;无&lt;/td&gt;
&lt;td&gt;无&lt;/td&gt;
&lt;td&gt;有（整卡与显存调度）&lt;/td&gt;
&lt;td&gt;未标注支持&lt;/td&gt;
&lt;td&gt;无&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;910B2 / 910B3&lt;/td&gt;
&lt;td&gt;Atlas 800T A2 训练整机&lt;/td&gt;
&lt;td&gt;无&lt;/td&gt;
&lt;td&gt;无&lt;/td&gt;
&lt;td&gt;有（v2.6.0 起）&lt;/td&gt;
&lt;td&gt;未标注支持&lt;/td&gt;
&lt;td&gt;无&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;910B4 / 910B4-1&lt;/td&gt;
&lt;td&gt;Atlas 800I A2、300I A2 推理&lt;/td&gt;
&lt;td&gt;有（&lt;code&gt;vir05&lt;/code&gt;、&lt;code&gt;vir10&lt;/code&gt; 系列）&lt;/td&gt;
&lt;td&gt;有&lt;/td&gt;
&lt;td&gt;有&lt;/td&gt;
&lt;td&gt;有（官方标注 910B 验证）&lt;/td&gt;
&lt;td&gt;无（计划中）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;910C&lt;/td&gt;
&lt;td&gt;CloudMatrix 384 超节点&lt;/td&gt;
&lt;td&gt;无&lt;/td&gt;
&lt;td&gt;无&lt;/td&gt;
&lt;td&gt;模块对分配（v2.9.0）&lt;/td&gt;
&lt;td&gt;未标注支持&lt;/td&gt;
&lt;td&gt;无&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;读表的方式：训练芯片（910A、910B2/B3）在数据平面上只有整卡分配，多租户要靠队列与配额在控制面解决；推理芯片是三条路径的主战场；910C 走的是“超节点统一内存池”的另一条扩展路线，切分不是它的重点。&lt;/p&gt;
&lt;h2 id="支持历史与成熟度时间线"&gt;支持历史与成熟度时间线&lt;/h2&gt;
&lt;p&gt;这套生态的分工不是设计出来的，而是近两年加速演化出来的。把芯片历史与虚拟化支持史放在同一条轴上看：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;时间&lt;/th&gt;
&lt;th&gt;事件&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;2018-10&lt;/td&gt;
&lt;td&gt;昇腾 310 发布，910 预告（HC2018）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2019-08&lt;/td&gt;
&lt;td&gt;昇腾 910 商用（FP16 256 TFLOPS），MindSpore 同场发布&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2019 至 2020&lt;/td&gt;
&lt;td&gt;实体清单与代工限制重塑路线&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2021-09&lt;/td&gt;
&lt;td&gt;HAMi 仓库创建（前身 k8s-vgpu-scheduler），初期聚焦 NVIDIA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2021 至 2023&lt;/td&gt;
&lt;td&gt;MindX DL 私有化套件时代，昇腾虚拟化主要经华为云 CCE 等产品化路径交付&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2022&lt;/td&gt;
&lt;td&gt;310P 世代推理产品（300I Duo / 300I Pro）落地&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2023&lt;/td&gt;
&lt;td&gt;910B 家族与 Atlas A2 整机上市&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2024-09&lt;/td&gt;
&lt;td&gt;HAMi v2.4.0：昇腾 310P 支持 GA，加入 NPU 虚拟化自定义配置；同月 ascend-device-plugin 独立仓库创建（2024-09-11，初建于 dynamia-ai 组织）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2024 至 2025&lt;/td&gt;
&lt;td&gt;华为将 MindX DL 各组件“代码仓归一”为开源的 mind-cluster 仓库&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2025-02 / 2025-06&lt;/td&gt;
&lt;td&gt;HAMi v2.5.0 补齐 910B4 配置；v2.6.0 支持 910B2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2025&lt;/td&gt;
&lt;td&gt;910C 与 CloudMatrix 384 超节点发布；9 月公布三年路线图&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2025-12&lt;/td&gt;
&lt;td&gt;华为发布 NPU 硬切分参考实践（HDK 25.5.0 基线）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026-01&lt;/td&gt;
&lt;td&gt;HAMi v2.8.0：ascend-device-plugin 迁入 Project-HAMi，同时服务 HAMi 与 Volcano；Volcano v1.14.0 原生集成两种 vNPU 模式（PR #4656、#4717）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026-05&lt;/td&gt;
&lt;td&gt;HAMi v2.9.0：HAMi-core 用户态虚拟化上线，增加 &lt;code&gt;Ascendxxx-core&lt;/code&gt; 资源与 910C SuperPod 模块对分配&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026 年&lt;/td&gt;
&lt;td&gt;华为发布 vCANN-RT 软切分参考实践；Volcano 1.16（alpha）为 HAMi 模式补上软切分调度支持&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026-08&lt;/td&gt;
&lt;td&gt;310P3 真机全链路验证源码编译部署（HAMi 博客与实验 13）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;三条曲线的成熟度判断：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;驱动硬切分&lt;/strong&gt;最成熟，经由 CCE 与 MindX DL 商用多年，参考实践只是把既有能力文档化。短板是芯片与场景覆盖（仅推理系列）以及模板粒度固定。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;vCANN-RT&lt;/strong&gt; 最新也最不成熟，参考实践定位非商用，且绑定 MindCluster 26.0.0 与 openEuler 环境。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HAMi 路径&lt;/strong&gt;介于两者之间：模板模式与华为路径同源同强度；HAMi-core 软切分已真机验证，但依赖 Volcano 1.16（尚未正式发布）且 ARM-only。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="支持程度对比"&gt;支持程度对比&lt;/h2&gt;
&lt;p&gt;把三条路径放回本书的决策轴：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;决策轴&lt;/th&gt;
&lt;th&gt;驱动硬切分（模板）&lt;/th&gt;
&lt;th&gt;vCANN-RT 软切分&lt;/th&gt;
&lt;th&gt;HAMi 软切分（hami-core）&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;资源单位&lt;/td&gt;
&lt;td&gt;离散模板（核数、显存、编解码引擎组合）&lt;/td&gt;
&lt;td&gt;连续：算力 1%、显存 1MB&lt;/td&gt;
&lt;td&gt;连续：任意显存 MB，算力按比例&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;隔离强度&lt;/td&gt;
&lt;td&gt;强，驱动级硬件分区&lt;/td&gt;
&lt;td&gt;软件拦截，时间片调度&lt;/td&gt;
&lt;td&gt;软件拦截，时间片调度&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;性能可预测性&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;td&gt;中（elastic 策略下依赖邻居负载）&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;重配置成本&lt;/td&gt;
&lt;td&gt;高，创建或销毁 vNPU 是驱动级操作&lt;/td&gt;
&lt;td&gt;低，改配额即可&lt;/td&gt;
&lt;td&gt;低，改 Pod 申请即可&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;芯片覆盖&lt;/td&gt;
&lt;td&gt;310P3、910B4 代推理系列，仅推理&lt;/td&gt;
&lt;td&gt;300I A2、800I A2&lt;/td&gt;
&lt;td&gt;310P、910A/B2/B3/B4/C&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;算力平台&lt;/td&gt;
&lt;td&gt;无限制&lt;/td&gt;
&lt;td&gt;ARM&lt;/td&gt;
&lt;td&gt;仅 ARM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;依赖栈&lt;/td&gt;
&lt;td&gt;Ascend Docker Runtime 与驱动&lt;/td&gt;
&lt;td&gt;mind-cluster 26.0.0、openEuler 组件&lt;/td&gt;
&lt;td&gt;ascend-device-plugin 与 Ascend Docker Runtime&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;监控&lt;/td&gt;
&lt;td&gt;整卡粒度（npu-smi）&lt;/td&gt;
&lt;td&gt;enpu-monitor&lt;/td&gt;
&lt;td&gt;插件内嵌 Prometheus 端点（:9395）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;商用许可&lt;/td&gt;
&lt;td&gt;随驱动与 CCE 商用&lt;/td&gt;
&lt;td&gt;参考实践声明非商用&lt;/td&gt;
&lt;td&gt;Apache 2.0 开源&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="使用场景选型"&gt;使用场景选型&lt;/h2&gt;
&lt;p&gt;结合决策轴与支持矩阵给出可操作的建议：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;生产推理多租户，隔离优先&lt;/strong&gt;：选驱动硬切分。它有最强的边界与最长的商用历史。已有华为栈的集群直接走 mind-cluster 加 Volcano MindCluster 模式（或 CCE）；模板粒度够用就不必引入软切分。注意先对照支持矩阵确认你的卡是 310P 或 910B4 推理形态。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;教育实训与高倍超卖&lt;/strong&gt;：vCANN-RT 是华为官方为此场景设计的答案，1% 算力粒度和 63 容器每卡的上限远超模板切分。接受其平台绑定与非商用声明的前提下可用。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;异构集群统一管理，或需要任意显存粒度&lt;/strong&gt;：HAMi 路径。一个调度器同时治理 NVIDIA 与昇腾，软切分可以精确申请 8192MB 这类非模板值。接受其较新的成熟度曲线。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;已被 Volcano 约束的批量调度场景&lt;/strong&gt;：两种模式都可与 gang 调度和队列组合。芯片是 310 系列且要强隔离选 MindCluster 模式；要 910 系列覆盖、binpack 共卡或软切分选 HAMi 模式。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;训练集群&lt;/strong&gt;：认清现实，数据平面没有切分选项。多租户靠整卡分配加队列配额（Volcano 队列、Kueue）解决，这正是&lt;a href="../../control-plane/"&gt;控制面&lt;/a&gt;几章的主题。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;一个务实的混合策略同样成立：核心付费推理流量跑硬切分保隔离，内部弹性与开发测试跑 HAMi 软切分保利用率，两者可以在同一集群不同节点池并存（注意一个节点同一时间只被一条设备插件路径管理）。&lt;/p&gt;
&lt;h2 id="开放问题"&gt;开放问题&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;训练场景仍然缺席&lt;/strong&gt;：三条路径都只覆盖推理。训练卡的多租户目前只有整卡分配加调度层配额（队列、gang），没有数据平面切分选项。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;两套软切分长期并存&lt;/strong&gt;：vCANN-RT 与 libvnpu 机制同构、生态独立，是否同源没有公开说明。用户面临的是事实上的双栈，监控、配置与升级路径互不兼容。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Volcano 1.16 尚未发布&lt;/strong&gt;：HAMi 模式的软切分调度依赖 1.16，当前只能用 alpha chart 或源码编译（实验 13 采用后者），生产采用需等正式发布。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MindCluster 模式覆盖窄&lt;/strong&gt;：仅 310 系列，910 系列用户在 Volcano 里实际只有 HAMi 模式可选。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;实现细节的坑&lt;/strong&gt;：HAMi ascend-device-plugin v1.3.1 不注册 &lt;code&gt;-core&lt;/code&gt; 扩展资源、libvnpu 版本必须与驱动匹配（不匹配的表现是 &lt;code&gt;npu-smi&lt;/code&gt; 卡死而非报错），这类问题在实验 13 的踩坑记录里有完整清单。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;在中国厂商的加速器生态中，昇腾是谱系最完整、虚拟化路径最多的一条：芯片上从 2018 年的 310/910 演进到 2025 年的 910C 超节点，架构上用达芬奇的 Cube 矩阵引擎走领域专用路线，与 NVIDIA 的 SIMT 加 CUDA 生态形成从硬件到软件栈的全面差异。这些差异直接决定了 vNPU 的切分维度（AI Core、AI CPU、显存、DVPP）与软切分的拦截对象（CANN 而非 CUDA）。&lt;/p&gt;
&lt;p&gt;三路径格局则是数据平面谱系的一次完整重演：驱动硬切分对应 MIG 的位置（强隔离、离散单位、高重配置成本），vCANN-RT 与 HAMi 软切分共同对应 HAMi 式运行时拦截的位置（连续粒度、低重配置成本、软件隔离）。选型因此可以完全复用谱系框架的判断方式：先问隔离边界要放哪里，再问粒度与重配置频率，最后才是生态与许可。&lt;/p&gt;
&lt;p&gt;对平台工程师的实际建议：不要把“昇腾支持 vNPU”当作一个开关来评估，而是对照支持矩阵把它拆成“我这代芯片加这三条路径”分别评估。华为官方路径胜在边界与商用历史，HAMi 路径胜在异构统一治理与粒度自由，vCANN-RT 胜在教育场景的超卖倍数。真要做决策时，用与本书实验章一致的验收方法（容器内设备视图、越界分配行为、监控指标）去验证你选的那条路径，而不是依赖任何一方的宣传材料。&lt;/p&gt;
&lt;h2 id="参考资料"&gt;参考资料&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://e.huawei.com/cn/products/computing/ascend" target="_blank" rel="noopener"&gt;昇腾计算官网 - 华为&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.hiascend.com/developer/techArticles/20251212-1" target="_blank" rel="noopener"&gt;昇腾 NPU 虚拟化硬切分参考实践 - 昇腾社区&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.hiascend.com/developer/techArticles/20260310-1" target="_blank" rel="noopener"&gt;昇腾 NPU 虚拟化软切分参考实践（vCANN-RT）- 昇腾社区&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.huaweicloud.com/usermanual-cce/cce_10_0994.html" target="_blank" rel="noopener"&gt;手动实现 NPU 静态虚拟化 - 华为云 CCE 文档&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://doc.hcs.huawei.com/zh-cn/usermanual/cce/cce_10_1009.html" target="_blank" rel="noopener"&gt;NPU 算力切分概述 - 华为云 HCS 文档&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.eet-china.com/news/201908301019.html" target="_blank" rel="noopener"&gt;破解华为达芬奇架构的密码 - 电子工程专辑&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stcn.com/article/detail/3345926.html" target="_blank" rel="noopener"&gt;华为昇腾 AI 芯片三年路线图 - 证券时报&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://m.36kr.com/p/3322025045829894" target="_blank" rel="noopener"&gt;一文看懂华为昇腾芯片 - 36 氪&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://volcano.sh/docs/latest/UserGuide/user_guide_how_to_use_vnpu" target="_blank" rel="noopener"&gt;Ascend vNPU 用户指南 - Volcano 官方文档&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://volcano.sh/blog/volcano-1.14.0-release/" target="_blank" rel="noopener"&gt;Volcano v1.14.0 发布博客（Ascend vNPU Scheduling 一节）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gitcode.com/Ascend/mind-cluster/tree/master/component/ascend-device-plugin" target="_blank" rel="noopener"&gt;mind-cluster ascend-device-plugin - GitCode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Project-HAMi/HAMi" target="_blank" rel="noopener"&gt;Project-HAMi/HAMi - GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Project-HAMi/ascend-device-plugin" target="_blank" rel="noopener"&gt;Project-HAMi/ascend-device-plugin - GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Project-HAMi/hami-vnpu-core" target="_blank" rel="noopener"&gt;Project-HAMi/hami-vnpu-core - GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Project-HAMi/HAMi/releases" target="_blank" rel="noopener"&gt;HAMi v2.4.0 / v2.8.0 / v2.9.0 Release Notes - GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://project-hami.io/blog/volcano-ascend-vnpu-soft-slicing" target="_blank" rel="noopener"&gt;Soft-Slicing Ascend vNPU with Volcano and HAMi-core - HAMi 网站&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://project-hami.io/tutorials/labs/volcano-ascend-vnpu" target="_blank" rel="noopener"&gt;实验 13：用 Volcano 与 HAMi-core 软切分昇腾 310P3 vNPU - HAMi 网站&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item></channel></rss>