法不净空,觉无性也。

第7章 GPU板卡级算力调度技术

2025.12.07

在第六章中,我们成功地为GPU集群构建了强大的多平面网络,将成百上千个GPU节点连接成一个统一的整体。现在,我们拥有了一个巨大的、原始的GPU算力池。然而,如何高效、公平、灵活地将这个算力池中的资源分配给众多的用户和任务,成为了我们面临的下一个核心挑战。

想象一下,一个拥有1000张A100 GPU的集群,如果每个用户每次申请任务都必须独占一张完整的物理GPU卡,会发生什么?

对于只需要少量算力进行模型调试、小规模推理或数据探索的用户来说,这是一种巨大的资源浪费。一张A100在大部分时间里可能只有10%的利用率,而其他用户却在排队等待空闲的GPU。

对于需要进行大规模分布式训练的用户,他们虽然需要多张卡,但在任务的不同阶段,对算力的需求是波动的。

多用户之间的任务无法有效隔离,一个用户的错误代码可能导致整个GPU卡甚至服务器崩溃,影响到其他用户。

为了解决这些问题,我们必须引入GPU算力调度技术。本章,我们将聚焦于单张物理GPU板卡内部的算力切分与共享技术,我们称之为“板卡级算力调度”。其核心目标是打破物理GPU卡的刚性边界,将一张昂贵的、高性能的GPU,像CPU和内存一样,转化为一种可以被细粒度切分、隔离和动态调度的虚拟资源。

我们将从两种主流的技术路线来探讨这个问题:

  1. 基于虚拟化技术的GPU调度:我们将深入研究如何将物理GPU直通(Pass-through)给虚拟机(VM),以及更高级的vGPU(虚拟GPU)技术是如何实现对单一GPU在硬件层面的、具备强隔离性的多租户共享。
  2. 基于容器技术的GPU调度:这是当前云原生AI平台中最主流的方式。我们将探讨容器技术是如何与NVIDIA的设备插件(Device Plugin)、CDI(Container Device Interface)等机制结合,实现对GPU资源的发现、分配和隔离,并分析其在共享调度方面(如时间分片、MIG)的实现原理。

通过本章的学习,你将深刻理解GPU虚拟化和容器化调度的核心原理、技术演进和各自的优缺点。你将能够根据不同的应用场景——是需要强隔离的多租户公有云,还是追求灵活高效的私有AI平台——来选择最合适的算力调度方案。这将为我们在后续章节中探讨更宏观的集群级调度(如Kubernetes与Volcano)和更细粒度的虚拟化方案(如cGPU、qGPU)奠定坚实的基础。

7.1 基于虚拟化技术的GPU调度

虚拟化技术(Virtualization)是云计算的基石。它通过在物理硬件之上引入一个Hypervisor(虚拟机监控器)层,能够将一台物理服务器虚拟成多台相互隔离的虚拟机(Virtual Machine, VM)。每个VM都拥有自己独立的虚拟硬件(vCPU, vMEM, vNIC)和完整的客户机操作系统(Guest OS)。将GPU能力赋予这些虚拟机,是实现GPU资源虚拟化调度最直接的路径。

7.1.1 方法一:GPU直通(PCIe Pass-through)

GPU直通是最早也是最简单的一种GPU虚拟化方式。

核心原理:Hypervisor(如KVM, VMware ESXi)将一整张物理GPU卡的PCIe设备控制权,完全、独占地“直通”给某一个特定的虚拟机。从这个虚拟机的视角看,它就像是物理上独占了这张GPU卡一样,可以直接加载NVIDIA的物理驱动,并获得接近裸金属的性能。

实现机制:这需要CPU和主板芯片组支持I/O虚拟化技术,即Intel VT-d或AMD-V (IOMMU)。IOMMU(输入/输出内存管理单元)能够在物理PCIe设备和虚拟机之间建立一个安全的、独立的DMA地址映射,从而实现了硬件层面的隔离。

优点:

性能最高:由于虚拟机几乎是直接与物理GPU对话,中间几乎没有Hypervisor的性能开销,计算密集型负载下通常可获得接近裸金属的性能(一般报告在九成以上,具体取决于I/O模式与驱动版本)。

兼容性最好:虚拟机内部可以使用标准的NVIDIA物理驱动,所有CUDA应用、框架和工具都无需任何修改即可运行。

缺点:

无法共享:这是其致命弱点。一张GPU卡在同一时间只能被分配给一个VM。这完全没有解决GPU资源细粒度共享和提升利用率的问题。它只是将物理GPU的独占,变成了虚拟机的独占。

缺乏灵活性:虚拟机与物理GPU的绑定是静态的。一旦绑定,该GPU就无法被其他VM使用,直到该VM被销毁。此外,它也无法实现虚拟机的动态迁移(Live Migration)。

适用场景:

需要运行对性能极度敏感、且需要整卡算力的单个大型HPC或AI训练任务的私有云环境。

需要为特定租户提供具备物理隔离保证的、独占GPU资源的场景。

7.1.2 方法二:SR-IOV(Single Root I/O Virtualization)

SR-IOV是一种更进一步的硬件辅助虚拟化技术,它允许一个物理PCIe设备(如网卡或GPU)在硬件层面将自己“分裂”成多个轻量级的虚拟功能(Virtual Function, VF)。

核心原理:

支持SR-IOV的物理设备被称为物理功能(Physical Function, PF)。PF拥有完整的设备配置和管理能力。

管理员可以通过PF,在硬件上创建出多个VF。每个VF都拥有自己独立的PCIe配置空间和资源(如队列、中断),看起来就像一个独立的PCIe设备。

然后,Hypervisor可以将这些VF像GPU直通一样,分别“直通”给不同的虚拟机。

在GPU中的应用:

NVIDIA从Ampere架构开始,在其部分数据中心GPU(如A100, A30)上支持SR-IOV。

管理员可以通过PF驱动,将一张A100 GPU划分为最多7个VF。每个VF都代表了GPU的一部分计算和内存资源。

每个获得VF的虚拟机,都可以加载专门的VF驱动,并将其作为一个独立的GPU设备来使用。

优点:

硬件级共享与隔离:SR-IOV在硬件层面实现了对单一GPU的切分和共享,VF之间的隔离性非常强,由硬件保证。一个VF的崩溃不会影响到其他VF。

接近裸金属的性能:由于VF也是被直接分配给VM,数据通路上Hypervisor的开销很小,性能非常接近裸金属。

缺点:

切分粒度固定:VF的资源配置(如显存大小、SM数量)通常是预先定义好的、固定的几种“规格”(Profile),不够灵活。管理员无法按需、动态地调整每个VF的资源量。

CUDA能力受限:早期的SR-IOV实现中,VF可能无法支持完整的CUDA功能集,例如P2P通信、统一内存等。

并非主流GPU虚拟化方案:尽管技术上可行,但SR-IOV在NVIDIA的GPU虚拟化生态中,更多地被其自家的vGPU技术所取代。AMD的GPU则更倾向于使用SR-IOV。

7.1.3 方法三:NVIDIA vGPU(虚拟GPU)—— API转发模型

NVIDIA vGPU是目前业界最成熟、应用最广泛的商用GPU虚拟化解决方案。它与GPU直通和SR-IOV的思路完全不同,采用了一种API转发(API Forwarding)或仲裁(Mediated Pass-through)的模型。

核心架构:vGPU技术栈由三部分组成:

  1. NVIDIA物理GPU驱动:运行在Hypervisor(Host OS)中,直接管理物理GPU硬件。
  2. NVIDIA vGPU Manager:同样运行在Hypervisor中,这是一个关键的管理软件。它负责:
    1. 将物理GPU切分成多个虚拟GPU(vGPU)实例。
    2. 负责vGPU实例的生命周期管理(创建、销毁)。
    3. 充当一个“交通警察”,仲裁和调度来自不同VM的GPU命令。
  3. NVIDIA vGPU Guest驱动:运行在每个虚拟机(Guest OS)内部。从虚拟机的应用和操作系统看来,这个Guest驱动就是一个标准的NVIDIA物理驱动。

工作原理(API转发):

  1. 虚拟机中的应用程序(如一个PyTorch脚本)调用CUDA API,例如请求分配一块显存。
  2. 这个API调用被虚拟机内部的vGPU Guest驱动所截获。
  3. Guest驱动并不直接与硬件交互,而是将这个API调用请求,通过一个专门的、高性能的通信通道(VMM Channel),转发给Hypervisor中运行的vGPU Manager。
  4. vGPU Manager收到请求后,作为所有vGPU实例的“总管”,它会代表该VM,向物理GPU驱动发出真正的硬件操作指令(例如,在物理显存中为这个VM分配一块受其管理的空间)。
  5. 物理GPU执行指令,并将结果返回给物理驱动,再由vGPU Manager通过通信通道返回给VM中的Guest驱动,最终返回给应用程序。
  6. 对于计算密集型的内核(Kernel)提交,vGPU Manager会将其放入对应物理GPU的硬件调度队列中,由GPU的硬件调度器来执行。

资源共享与调度机制:

  • vGPU配置文件(Profiles):管理员在创建vGPU时,需要选择一个“配置文件”。配置文件定义了该vGPU实例能够获得的显存大小(Framebuffer size)。例如,一张32GB的V100 GPU,可以选择v100-8q配置文件,创建一个拥有8GB显存的vGPU实例。
  • 计算资源的调度:vGPU对计算资源(SM)的共享,主要采用时间分片(Time-slicing)的调度策略。
  • 尽力而为调度(Best-effort):这是默认策略。vGPU Manager会将所有活跃vGPU的命令流公平地提交给物理GPU。如果只有一个vGPU在工作,它可以占用全部的计算资源。如果有多个vGPU同时工作,它们会按时间片轮流使用物理GPU的计算核心。
  • 固定份额调度(Fixed-share):管理员可以为每个vGPU分配一个固定的计算资源份额(share),确保即使在争抢激烈时,每个vGPU也能获得一个最低的、有保障的计算性能。
  • 等额调度(Equal-share):所有活跃的vGPU平均分享计算资源。

NVIDIA vGPU的优点:

  • 高度灵活的共享:允许将一张物理GPU同时共享给多个VM使用,显著提升了GPU的利用率。切分的粒度由vGPU配置文件决定,相对灵活。
  • 强隔离性:vGPU Manager作为仲裁者,确保了每个VM的显存空间和指令流是严格隔离的。一个VM的崩溃不会影响到其他VM。
  • 完整的CUDA与图形能力:由于Guest驱动模拟了完整的物理驱动,因此vGPU可以支持几乎所有的CUDA和图形API功能。
  • 支持实时迁移(Live Migration):高级版本的vGPU软件支持在不中断VM运行和GPU应用的情况下,将其从一台物理服务器迁移到另一台,这对于实现数据中心的负载均衡和无缝维护至关重要。

NVIDIA vGPU的缺点:

  • 性能开销:由于所有GPU命令都需要经过Hypervisor中的vGPU Manager进行转发和仲裁,相比GPU直通,会引入一定的性能开销(常见评估为个位数到百分之十几,取决于具体工作负载与版本,应以实测为准)。
  • 商业授权:NVIDIA vGPU是一套商业软件,需要购买专门的许可证(如NVIDIA AI Enterprise, vPC/vApps)。

适用场景:

  • 多租户云环境:公有云或私有云提供商,需要将GPU算力作为一种服务(GPUaaS),安全、隔离地售卖给多个不同租户。
  • 虚拟桌面基础设施(VDI):为设计师、工程师等需要图形加速能力的用户提供云端的虚拟桌面。
  • 混合AI/HPC负载:在一个集群中,同时运行多个不同规模、不同类型的AI和HPC任务,需要灵活地分配和调度GPU资源。

7.1.4 虚拟化技术调度的总结

基于虚拟化技术的GPU调度,提供了一种以虚拟机为单位的、具备强隔离性的GPU资源分配和管理方案。

GPU直通追求极致性能和兼容性,但牺牲了共享能力。

SR-IOV在硬件层面实现了共享,性能好、隔离强,但灵活性不足。

NVIDIA vGPU通过API转发模型,在灵活性、共享能力、隔离性和功能完整性之间取得了最佳的平衡,成为了企业级GPU虚拟化的事实标准,但需要承担一定的性能开销和商业成本。

对于需要为多个用户或部门提供隔离、安全、可计量的GPU服务的场景,虚拟化技术是理想的选择。

7.2 基于容器技术的GPU调度

随着云原生(Cloud Native)思想的兴起,容器(Container)技术,特别是以Docker为代表的实现和以Kubernetes为代表的编排系统,已经成为现代应用部署和管理的主流范式。容器相比虚拟机,是一种更轻量级的虚拟化技术。它不是虚拟化一整个操作系统,而是共享宿主机(Host)的操作系统内核,仅将应用程序及其依赖的库和配置文件打包在一起,实现了进程级别的隔离。

如何让运行在容器中的AI应用,能够高效、便捷地使用宿主机上的GPU资源,是基于容器技术的GPU调度的核心问题。

7.2.1 早期蛮荒时代:Bind Mounting

在NVIDIA提供官方支持之前,使用容器运行GPU应用是一种非常“野路子”的做法。开发者需要手动将宿主机上与GPU相关的所有设备文件和库文件,通过docker run命令的-v(volume)参数,一一“绑定挂载”(Bind Mount)到容器内部。

例如:

docker run -it --rm \
  -v /dev/nvidia0:/dev/nvidia0 \
  -v /dev/nvidiactl:/dev/nvidiactl \
  -v /usr/lib/x86_64-linux-gnu/libnvidia-ml.so.1:/usr/lib/x86_64-linux-gnu/libnvidia-ml.so.1 \
  ... (还有几十个类似的库文件) \
  my-gpu-app

缺点:

极其繁琐和易错:需要手动找出所有依赖,挂载列表非常长。

主机与容器强耦合:容器的运行严重依赖于主机上NVIDIA驱动的版本。如果主机的驱动升级了,而容器内的应用不兼容,就会立刻崩溃。 缺乏可移植性:这个容器无法在另一台驱动版本或库路径不同的机器上运行。

不安全:将/dev下的设备文件直接暴露给容器,存在严重的安全隐患。

7.2.2 NVIDIA-Docker的出现:走向标准化

为了解决上述问题,NVIDIA推出了nvidia-docker项目(现在演进为nvidia-container-toolkit)。它通过对Docker守护进程的扩展,实现了GPU容器化的标准化。

核心原理:

  1. 运行时钩子(Runtime Hook):nvidia-docker的核心是一个OCI(Open Container Initiative)兼容的运行时钩子。当用户使用docker run --gpus all ...命令启动一个容器时,Docker守护进程会调用这个钩子。
  2. 自动注入:这个钩子程序会查询宿主机上的NVIDIA驱动版本和GPU状态,然后自动地、动态地将运行该GPU应用所需的最小设备文件集和驱动库文件,注入到即将启动的容器内部。
  3. 解耦:这样,容器镜像本身可以不包含任何NVIDIA驱动。它只需要包含CUDA工具包和应用程序即可。在运行时,nvidia-container-toolkit会确保容器内的CUDA工具包版本与宿主机上被注入的驱动版本是兼容的。

优点:

简化用户操作:用户只需一个--gpus参数,即可启动GPU容器。

解耦与可移植性:容器镜像不再与主机驱动版本强耦合,增强了可移植性。

安全性提升:只向容器暴露必要的设备和库,而不是整个文件系统。

7.2.3 集群级调度:Kubernetes与Device Plugin

当我们需要在由成百上千个节点组成的集群中管理和调度GPU容器时,就需要一个容器编排系统,而Kubernetes(K8s)是这个领域无可争议的王者。

Kubernetes的基本调度流程:

  1. 用户创建一个Pod(K8s中最小的部署单元)的YAML描述文件,在其中声明资源需求,例如cpu: "2", memory: "4Gi"
  2. 用户通过kubectl apply命令将这个YAML提交给K8s的API Server。
  3. K8s的调度器(Scheduler)会监听到这个新的Pod创建请求。
  4. 调度器会遍历集群中所有的节点(Node),检查每个节点的可用资源(CPU、内存)是否满足Pod的需求。这个过程称为“过滤”(Filtering)。
  5. 对于所有满足条件的节点,调度器会根据一系列的打分策略(如资源使用率最低、Pod分布最均匀等)对它们进行“打分”(Scoring)。
  6. 最终,调度器选择得分最高的节点,将Pod“绑定”(Binding)到该节点上。
  7. 目标节点上的Kubelet(K8s在每个节点上的代理)会监听到这个绑定事件,然后在本机上启动Pod对应的容器。

挑战:K8s如何感知GPU?

原生的K8s只认识CPU和内存这两种资源。它并不知道GPU的存在,也无法在Pod的YAML中直接声明gpu: 1

解决方案:Device Plugin框架

为了支持GPU、FPGA、高性能网卡等各种硬件设备,K8s引入了设备插件(Device Plugin)框架。

NVIDIA Device Plugin:NVIDIA官方提供了针对其GPU的设备插件。它是一个以DaemonSet方式运行在集群中每个GPU节点上的程序。

工作流程:

  1. 注册:节点上的Device Plugin启动后,会首先检查本机上有多少个可用的GPU,然后通过gRPC向本节点的Kubelet进行注册,告诉Kubelet:“你好,我这台机器上有8个名为nvidia.com/gpu的资源可供调度。”
  2. 上报资源:Kubelet会将这个扩展资源信息上报给K8s的API Server。从此,K8s的调度器就知道nvidia.com/gpu是一种可调度的资源了。
  3. 用户声明:用户现在可以在Pod的YAML中像声明CPU一样,声明GPU需求:
spec:
  containers:
  - name: my-gpu-container
image: my-gpu-app
resources:
  limits:
nvidia.com/gpu: "2" # 请求2个GPU
  1. 调度:当K8s调度器处理这个Pod时,它会在过滤阶段,检查哪些节点上报的nvidia.com/gpu的可用数量大于等于2。
  2. 分配:当Pod被调度到某个节点后,该节点的Kubelet在启动容器前,会调用Device Plugin的Allocate接口,请求分配2个GPU。
  3. Device Plugin会返回需要被注入到容器中的设备ID(如NVIDIA_VISIBLE_DEVICES=0,1)和相关配置。
  4. Kubelet将这些信息传递给容器运行时(如containerd),最终由nvidia-container-toolkit完成GPU的注入。

7.2.4 GPU共享调度技术

标准的Device Plugin实现了对GPU的独占分配,即一个Pod要么分配一整张卡,要么不分配。这又回到了我们最初面临的资源浪费问题。为了在容器环境中实现GPU的细粒度共享,业界发展出了多种技术方案。

方案一:时间分片(Time-slicing)

原理:这是一种软件层面的共享方案。它允许多个容器(Pod)同时声明并“挂载”到同一张物理GPU上。一个修改版的Device Plugin或调度器,会为每个容器分配一个GPU的“算力份额”。在运行时,通过CUDA的API劫持(API Hooking)等技术,在驱动层面控制每个容器的CUDA Context在GPU硬件上的执行时间片。

代表实现:

NVIDIA MPS (Multi-Process Service):这是NVIDIA官方提供的一种轻量级时间分片技术。它通过一个MPS控制守护进程,将来自多个不同进程的CUDA Context合并,统一提交给GPU,减少了上下文切换的开销,适用于多个小计算量的推理任务共享GPU。

阿里云cGPU、腾讯云qGPU等(部分原理):许多云厂商自研的GPU共享方案,其底层也借鉴了时间分片的思想,但增加了更复杂的算力计量和隔离机制。

优点:实现相对简单,可以实现超卖(即分配出去的总份额可以超过1张卡),灵活性高。

缺点:隔离性较弱。由于共享同一个硬件执行上下文,一个容器的错误可能影响其他容器。显存没有被隔离,需要所有共享容器的显存总需求小于物理显存。

方案二:空间分片(Spatial Slicing)- NVIDIA MIG

原理:这是硬件层面的共享方案。NVIDIA从Ampere架构(A100)开始引入了多实例GPU(Multi-Instance GPU, MIG)技术。MIG允许在硬件层面,将一张物理GPU安全地、彻底地分割成最多7个独立的GPU实例(GPU Instance, GI)。

MIG的特性:

硬件隔离:每个GI都拥有自己专属的、隔离的计算引擎(SM)、L2缓存、显存控制器和显存带宽。一个GI上的工作负载(包括其崩溃)通常不会影响到其他GI;该隔离针对故障隔离与性能隔离设计,不等同于可抵御恶意侧信道攻击的安全边界,强对抗性多租户场景仍应结合上层防护评估。

固定的资源配置:MIG的切分方式和每个GI的资源量(SM数量和显存大小)是由硬件预先定义好的几种“切片(Slice)”组合而成的,例如可以将一个A100切分成1g.5gb(1/7算力,5GB显存)、2g.10gb等多种规格。

与Kubernetes的集成:

NVIDIA提供了支持MIG的Device Plugin。管理员可以在节点上预先配置好MIG模式和切分策略。

Device Plugin会将每一种规格的GI,作为一种独立的扩展资源上报给K8s。例如:nvidia.com/mig-1g.5gb: 7, nvidia.com/mig-2g.10gb: 3

用户可以在Pod的YAML中,精确地请求所需规格的MIG设备:nvidia.com/mig-1g.5gb: "1"

优点:

最强的隔离性:提供了与虚拟机相媲美的硬件级安全隔离,是多租户共享GPU的最理想方案。

可预测的性能:每个GI拥有固定的、有保障的算力和显存带宽,性能不受“邻居”干扰。

缺点:

切分不够灵活:切分规格和数量由硬件限定,无法按需动态调整。

并非所有GPU都支持:只有特定型号的数据中心GPU(如A100, H100)支持MIG。

7.2.5 最新进展:CDI(Container Device Interface)

CDI是CNCF(云原生计算基金会)正在推进的一个新标准,旨在统一容器运行时与设备插件之间的交互方式。

目标:解决nvidia-container-toolkit这类厂商特定的运行时钩子所带来的碎片化问题。

原理:CDI定义了一种简单的JSON文件格式,设备厂商可以通过这种文件来声明将其设备注入容器所需的所有操作(如挂载设备文件、设置环境变量、注入库文件等)。容器运行时(如containerd, CRI-O)原生支持解析这些CDI文件。

未来:未来,NVIDIA Device Plugin将不再需要与特定的容器运行时钩子绑定,而是只需要生成符合CDI规范的JSON文件。这将使得GPU容器的部署和管理更加标准化、可移植和面向未来。

7.3 本章小结

在本章中,我们深入探讨了如何将一张物理GPU卡的原始算力,转化为可被精细调度和高效共享的虚拟化资源。我们沿着虚拟化和容器化这两条主流技术路线,剖析了各种板卡级算力调度技术的原理、优劣和适用场景。

在基于虚拟化技术的GPU调度中,我们学习到:

GPU直通以其接近裸金属的性能和完美的兼容性,成为对性能最敏感、需要独占整卡的任务的简单选择,但它牺牲了共享能力。

SR-IOV在硬件层面实现了对GPU的初步切分,提供了良好的性能和隔离性,但其固定的切分粒度限制了灵活性。

NVIDIA vGPU通过其创新的API转发模型,在Hypervisor中建立了一个强大的仲裁中心,实现了对GPU资源的灵活、安全、功能完备的共享。它通过时间分片来调度计算资源,通过配置文件来隔离显存,成为了企业级多租户GPU虚拟化的事实标准,尤其适用于VDI和混合负载的云环境。

在基于容器技术的GPU调度中,我们见证了云原生AI平台的演进:

我们从早期nvidia-docker的运行时钩子开始,理解了GPU容器如何从“野路子”走向标准化,实现了应用与主机驱动的解耦。

我们深入了Kubernetes的Device Plugin框架,明白了K8s是如何通过这个可扩展的机制,将GPU这种外部设备纳管为其可调度的原生资源,为大规模集群的自动化资源编排铺平了道路。

针对GPU共享的核心难题,我们对比了两种截然不同的方案:

时间分片(如MPS)是一种灵活的软件共享方案,适用于多个轻量级任务的并发,但隔离性较弱。

空间分片,以NVIDIA MIG为代表,是一种革命性的硬件共享方案。它提供了与VM相媲美的强隔离性和可预测性能,是云原生多租户场景下的理想选择,但灵活性稍逊。

最终我们认识到,选择哪种GPU调度技术,并非一个非黑即白的问题,而是一个需要根据具体业务场景、对隔离性、性能、灵活性、成本等多个维度进行综合权衡的决策。

如果你的首要目标是构建一个安全、隔离、可计量的多租户公有云平台,那么基于虚拟化技术(特别是vGPU)或容器技术与MIG的结合,将是你的不二之选。

如果你的目标是构建一个高效、灵活、服务于内部数据科学团队的私有AI平台,那么基于容器技术与时间分片或独占调度的组合,可能更具成本效益和敏捷性。

掌握了板卡级的算力调度技术,我们就拥有了将单一GPU资源池化的“显微镜”和“手术刀”。在下一章中,我们将把视野再次拉高,探讨在硬件虚拟化之外,还有哪些更具侵入性、但也可能更灵活的GPU虚拟化方案。