searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

共享GPU调度实现方法

2023-07-24 07:03:56
224
0

背景和目标

随着科研和商业领域对于高性能计算的需求日益增长,GPU作为一种提供了大量并行处理能力的硬件设备,得到了广泛应用。然而,GPU设备通常价格昂贵,且可能并非全时段都在进行高负载的运算,因此如何提高GPU的利用率,减小浪费,是一大挑战。
 
此外,有很多场景下,一个用户的应用可能并不需要占用整个GPU,或者同一时段有多个用户或任务需要使用GPU资源。如果每个用户或任务独占一个GPU,可能会导致资源浪费和效率低下。相反,如果可以让多个任务共享同一个GPU,则可以大大提高GPU的使用效率。
 
由此可见,GPU共享调度的目标主要有以下几点:
  • 提高资源利用率:让多个任务或用户可以共享同一GPU,而不是每个任务或用户都需要独占一个GPU。
  • 降低成本:提高GPU利用率可以帮助降低单位任务的计算成本。
  • 提高性能:通过合理的调度策略,可以减少任务之间的冲突,提高整体性能。
  • 提供公平性:在多用户或多任务的环境下,需要保证每个用户或任务都能公平地获取到GPU资源。
  • 保证任务的隔离性:虽然让多个任务共享一个GPU可以提高资源利用率,但也需要保证任务之间的隔离性,防止一个任务影响到其他任务的运行。

技术介绍

共享

要在k8s集群中实现GPU共享调度,即多个Pod共享使用同一张显卡,需要集群拥有细粒度分配GPU资源的机制,将整卡的资源拆分成多份,并分配给Pod。要做到这一点,一般是通过扩展资源的方式将GPU注册到节点信息中,调度器根据这些扩展资源信息分配资源,达到共享调度的目的。

下面是英伟达Time-Slicing的例子,查看节点的资源信息,gpu资源会以扩展资源的形式注册:
...
Labels:
                  nvidia.com/gpu.count=4
                  nvidia.com/gpu.product=Tesla-T4-SHARED
                  nvidia.com/gpu.replicas=4
Capacity:
  nvidia.com/gpu: 16
  ...
Allocatable:
  nvidia.com/gpu: 16
  ...
从上面例子看到,整卡资源扩展成16份。工作负载申请资源的时候可以申请gpu扩展资源,从而达到共享的目的。

隔离

目前GPU隔离主要分为三种:

  • 显存隔离:指将 GPU 的显存资源进行隔离,按部署服务的配置文件中所声明的资源定义分配给对应服务,每个服务所分配的显存资源之间互不影响。
  • 算力隔离:指将 GPU 的计算能力进行隔离,按比例分配给共享 GPU 的任务上。
  • 故障隔离:fatal exception发生时会影响其他应用。

技术方案

英伟达方案

NVIDIA GPU 硬件结合 CUDA 编程模型,提供了许多不同的并发机制,以提高 GPU 的利用,用户可以根据自身需求选择不同的技术方案。

Figure showing the various concurrency mechanisms supported by NVIDIA GPUs, ranging from programming model APIs, CUDA MPS, time-slicing, MIG and NVIDIA vGPU.

CUDA 多进程服务

MPS —— 它通过将多个进程的 CUDA Context,合并到一个 CUDA Context 中,省去了 Context Switch 的开销,也在 Context 内部实现了算力隔离。如前所述,MPS 的致命缺陷,是把许多进程的 CUDA Context 合并成一个,从而导致了额外的故障传播。所以尽管它的算力隔离效果极好,但长期以来工业界使用不多,多租户场景尤其如此。

Time Slicing

英伟达的Time Slicing是一种基于时间片的GPU共享调度策略,这种策略能让多个任务在同一个GPU上进行,而不是每个任务都独占一个GPU。这种策略的核心原理就是将时间分割成一系列的小片段,然后将这些时间片轮流分配给不同的任务。

多实例 GPU ( MIG )

迄今为止讨论的机制要么依赖于使用 CUDA 编程模型 API (如 CUDA 流)对应用程序的更改,要么依赖于 CUDA 系统软件(如时间切片或 MPS )。

使用 MIG ,基于 NVIDIA 安培体系结构的 GPU ,例如 NVIDIA A100 ,可以为 CUDA 应用程序安全划分多达七个独立的 GPU 实例,为多个应用程序提供专用的 GPU 资源。这些包括流式多处理器( SMs )和 GPU 引擎,如复制引擎或解码器,为不同的客户端(如进程、容器或虚拟机( VM ))提供定义的 QoS 和故障隔离。

当对 GPU 进行分区时,可以在单个 MIG 实例中使用之前的 CUDA 流、 CUDA MPS 和时间切片机制。

vGPU

NVIDIA vGPU 使具有完全输入输出内存管理单元( IOMMU )保护的虚拟机能够同时直接访问单个物理 GPU 。除了安全性之外, NVIDIA v GPU 还带来了其他好处,如通过实时虚拟机迁移进行虚拟机管理,能够运行混合的 VDI 和计算工作负载,以及与许多行业虚拟机监控程序的集成。值得注意的是,使用vGPU需要license,购买license的费用需要考虑在技术选型里面。

英伟达各技术对比

 

内核劫持

实现GPU共享调度的隔离性,还可以通过劫持内核驱动的方式实现。需要一个内核态的GPU共享模块,它位于Nvidia驱动层之上,这样在公有云环境中相对更加安全。cGPU的资源隔离是通过劫持对驱动的调用实现的,并通过设置任务占用的时间片长度来调控任务占用的计算能力。具体如何精确控制上下文切换的时间细节不明。由于Nvidia驱动不是开源的,要获取驱动相关的方法名和ioctl参数结构,需要进行一些逆向工程。这种实现方式对用户来说是无感知的。

vCUDA

劫持CUDA API同样是一种可行的方案,比如开源的vCUDA项目。其系统架构与NVIDIA的GRID架构相似,通过引入一个负责管理GPU的Manager组件,该组件能够调控容器的GPU计算能力和显存资源,确保用户无法超出其申请的显存使用,同时保持GPU的平均使用率在申请值范围内。这一设计仅涉及CUDA层的改动,因此,用户的程序无需重新编译,就能运行在基于vCUDA的GPU共享环境中。但是它也有一些问题,一是需要替换CUDA库,并确保版本一致,二是在部分使用场景下,可能会出现兼容性问题。

 

技术示例

实现共享调度最简单的方式是使用英伟达的time-slicing技术。要使用该技术提交time-slicing配置configmap

apiVersion: v1
kind: ConfigMap
metadata:
  name: time-slicing-config
data:
  any: |-
    version: v1
    flags:
      migStrategy: none
    sharing:
      timeSlicing:
        renameByDefault: false
        failRequestsGreaterThanOne: false
        resources:
          - name: nvidia.com/gpu
            replicas: 4

将gpu扩展成4个副本。然后安装GPU operator

$ helm install gpu-operator nvidia/gpu-operator \
    -n gpu-operator \
    --set devicePlugin.config.name=time-slicing-config

最后验证节点信息是否生效

kubectl describe node <node-name>

最后可看到扩展后的GPU资源

...
Labels:
                  nvidia.com/gpu.count=4
                  nvidia.com/gpu.product=Tesla-T4-SHARED
                  nvidia.com/gpu.replicas=4
Capacity:
  nvidia.com/gpu: 16
  ...
Allocatable:
  nvidia.com/gpu: 16
  ...
 
0条评论
作者已关闭评论
钟****聪
2文章数
0粉丝数
钟****聪
2 文章 | 0 粉丝
钟****聪
2文章数
0粉丝数
钟****聪
2 文章 | 0 粉丝
原创

共享GPU调度实现方法

2023-07-24 07:03:56
224
0

背景和目标

随着科研和商业领域对于高性能计算的需求日益增长,GPU作为一种提供了大量并行处理能力的硬件设备,得到了广泛应用。然而,GPU设备通常价格昂贵,且可能并非全时段都在进行高负载的运算,因此如何提高GPU的利用率,减小浪费,是一大挑战。
 
此外,有很多场景下,一个用户的应用可能并不需要占用整个GPU,或者同一时段有多个用户或任务需要使用GPU资源。如果每个用户或任务独占一个GPU,可能会导致资源浪费和效率低下。相反,如果可以让多个任务共享同一个GPU,则可以大大提高GPU的使用效率。
 
由此可见,GPU共享调度的目标主要有以下几点:
  • 提高资源利用率:让多个任务或用户可以共享同一GPU,而不是每个任务或用户都需要独占一个GPU。
  • 降低成本:提高GPU利用率可以帮助降低单位任务的计算成本。
  • 提高性能:通过合理的调度策略,可以减少任务之间的冲突,提高整体性能。
  • 提供公平性:在多用户或多任务的环境下,需要保证每个用户或任务都能公平地获取到GPU资源。
  • 保证任务的隔离性:虽然让多个任务共享一个GPU可以提高资源利用率,但也需要保证任务之间的隔离性,防止一个任务影响到其他任务的运行。

技术介绍

共享

要在k8s集群中实现GPU共享调度,即多个Pod共享使用同一张显卡,需要集群拥有细粒度分配GPU资源的机制,将整卡的资源拆分成多份,并分配给Pod。要做到这一点,一般是通过扩展资源的方式将GPU注册到节点信息中,调度器根据这些扩展资源信息分配资源,达到共享调度的目的。

下面是英伟达Time-Slicing的例子,查看节点的资源信息,gpu资源会以扩展资源的形式注册:
...
Labels:
                  nvidia.com/gpu.count=4
                  nvidia.com/gpu.product=Tesla-T4-SHARED
                  nvidia.com/gpu.replicas=4
Capacity:
  nvidia.com/gpu: 16
  ...
Allocatable:
  nvidia.com/gpu: 16
  ...
从上面例子看到,整卡资源扩展成16份。工作负载申请资源的时候可以申请gpu扩展资源,从而达到共享的目的。

隔离

目前GPU隔离主要分为三种:

  • 显存隔离:指将 GPU 的显存资源进行隔离,按部署服务的配置文件中所声明的资源定义分配给对应服务,每个服务所分配的显存资源之间互不影响。
  • 算力隔离:指将 GPU 的计算能力进行隔离,按比例分配给共享 GPU 的任务上。
  • 故障隔离:fatal exception发生时会影响其他应用。

技术方案

英伟达方案

NVIDIA GPU 硬件结合 CUDA 编程模型,提供了许多不同的并发机制,以提高 GPU 的利用,用户可以根据自身需求选择不同的技术方案。

Figure showing the various concurrency mechanisms supported by NVIDIA GPUs, ranging from programming model APIs, CUDA MPS, time-slicing, MIG and NVIDIA vGPU.

CUDA 多进程服务

MPS —— 它通过将多个进程的 CUDA Context,合并到一个 CUDA Context 中,省去了 Context Switch 的开销,也在 Context 内部实现了算力隔离。如前所述,MPS 的致命缺陷,是把许多进程的 CUDA Context 合并成一个,从而导致了额外的故障传播。所以尽管它的算力隔离效果极好,但长期以来工业界使用不多,多租户场景尤其如此。

Time Slicing

英伟达的Time Slicing是一种基于时间片的GPU共享调度策略,这种策略能让多个任务在同一个GPU上进行,而不是每个任务都独占一个GPU。这种策略的核心原理就是将时间分割成一系列的小片段,然后将这些时间片轮流分配给不同的任务。

多实例 GPU ( MIG )

迄今为止讨论的机制要么依赖于使用 CUDA 编程模型 API (如 CUDA 流)对应用程序的更改,要么依赖于 CUDA 系统软件(如时间切片或 MPS )。

使用 MIG ,基于 NVIDIA 安培体系结构的 GPU ,例如 NVIDIA A100 ,可以为 CUDA 应用程序安全划分多达七个独立的 GPU 实例,为多个应用程序提供专用的 GPU 资源。这些包括流式多处理器( SMs )和 GPU 引擎,如复制引擎或解码器,为不同的客户端(如进程、容器或虚拟机( VM ))提供定义的 QoS 和故障隔离。

当对 GPU 进行分区时,可以在单个 MIG 实例中使用之前的 CUDA 流、 CUDA MPS 和时间切片机制。

vGPU

NVIDIA vGPU 使具有完全输入输出内存管理单元( IOMMU )保护的虚拟机能够同时直接访问单个物理 GPU 。除了安全性之外, NVIDIA v GPU 还带来了其他好处,如通过实时虚拟机迁移进行虚拟机管理,能够运行混合的 VDI 和计算工作负载,以及与许多行业虚拟机监控程序的集成。值得注意的是,使用vGPU需要license,购买license的费用需要考虑在技术选型里面。

英伟达各技术对比

 

内核劫持

实现GPU共享调度的隔离性,还可以通过劫持内核驱动的方式实现。需要一个内核态的GPU共享模块,它位于Nvidia驱动层之上,这样在公有云环境中相对更加安全。cGPU的资源隔离是通过劫持对驱动的调用实现的,并通过设置任务占用的时间片长度来调控任务占用的计算能力。具体如何精确控制上下文切换的时间细节不明。由于Nvidia驱动不是开源的,要获取驱动相关的方法名和ioctl参数结构,需要进行一些逆向工程。这种实现方式对用户来说是无感知的。

vCUDA

劫持CUDA API同样是一种可行的方案,比如开源的vCUDA项目。其系统架构与NVIDIA的GRID架构相似,通过引入一个负责管理GPU的Manager组件,该组件能够调控容器的GPU计算能力和显存资源,确保用户无法超出其申请的显存使用,同时保持GPU的平均使用率在申请值范围内。这一设计仅涉及CUDA层的改动,因此,用户的程序无需重新编译,就能运行在基于vCUDA的GPU共享环境中。但是它也有一些问题,一是需要替换CUDA库,并确保版本一致,二是在部分使用场景下,可能会出现兼容性问题。

 

技术示例

实现共享调度最简单的方式是使用英伟达的time-slicing技术。要使用该技术提交time-slicing配置configmap

apiVersion: v1
kind: ConfigMap
metadata:
  name: time-slicing-config
data:
  any: |-
    version: v1
    flags:
      migStrategy: none
    sharing:
      timeSlicing:
        renameByDefault: false
        failRequestsGreaterThanOne: false
        resources:
          - name: nvidia.com/gpu
            replicas: 4

将gpu扩展成4个副本。然后安装GPU operator

$ helm install gpu-operator nvidia/gpu-operator \
    -n gpu-operator \
    --set devicePlugin.config.name=time-slicing-config

最后验证节点信息是否生效

kubectl describe node <node-name>

最后可看到扩展后的GPU资源

...
Labels:
                  nvidia.com/gpu.count=4
                  nvidia.com/gpu.product=Tesla-T4-SHARED
                  nvidia.com/gpu.replicas=4
Capacity:
  nvidia.com/gpu: 16
  ...
Allocatable:
  nvidia.com/gpu: 16
  ...
 
文章来自个人专栏
k8s_dance_me
2 文章 | 1 订阅
0条评论
作者已关闭评论
作者已关闭评论
0
0