7.3. HAMi

HAMi (Heterogeneous AI Computing Virtualization Middleware),原又称 k8s-vGPU-scheduler,是一个 “all-in-one” Chart,用于管理 k8s 集群中的异构 AI 计算设备。 它提供了共享异构 AI 设备的能力,并在任务之间提供资源隔离。

HAMi 致力于提高 Kubernetes 集群中异构计算设备的使用率,并为不同类型的异构设备提供统一的复用接口。 更多相关信息,参见 HAMi官方文档

7.3.1. 部署HAMi

备注

  • 部署HAMi之前,请确保已安装可用的Kubernetes集群,且Kubernetes版本≥1.23。

  • 部署的HAMi版本需≥2.6.0。

在线部署操作步骤参见通过 Helm 在线安装(推荐)。 如果集群无法直接访问外部网络,可以使用离线部署,操作步骤参见离线安装

7.3.2. 使用sGPU

备注

使用sGPU前,请确保已部署 GPU Operator 并正确配置sGPU,详情参见 4.4.3.5 配置sGPU

使用sGPU可以共享GPU设备资源:可以为任务分配一部分GPU,而不是完整的GPU。 sGPU支持以下参数以共享GPU,参数含义参见下表。

表 7.7 参数列表

选项

类型

描述

metax-tech.com/sgpu

integer/string

sGPU数量。值不可大于节点GPU数量,该参数不可缺省

metax-tech.com/vcore

integer/string

每张sGPU使用完整GPU的算力百分比。取值范围为1~100,缺省时表示使用GPU完整的算力

metax-tech.com/vmemory

integer/string

每张sGPU使用完整GPU的显存大小。默认单位为Gi,可指定单位为Mi或Gi,缺省时表示使用GPU完整的显存

调度策略

用户可以为任务配置调度策略以影响调度决策,HAMi支持的调度策略参见下表。

表 7.8 HAMi调度策略列表

选项

类型

描述

hami.io/node-scheduler-policy

string

节点调度策略,可选 binpackspreadbinpack 表示尽量将任务分配到同一GPU节点, spread 表示尽量将任务分配到不同的GPU节点

hami.io/gpu-scheduler-policy

string

GPU调度策略,可选 binpackspreadbinpack 表示尽量将任务分配到同一GPU, spread 表示尽量将任务分配到不同的GPU

Qos Policy

用户可以为任务配置Qos Policy参数以指定sGPU使用的调度策略。Qos Policy参数说明参见下表。

表 7.9 Qos Policy参数

选项

类型

描述

metax-tech.com/sgpu-qos-policy

string

Qos Policy,对应sGPU使用的调度策略。可选 best-effortfixed-shareburst-share, 缺省时为 best-effort

具体的sGPU调度策略说明参见下表。

表 7.10 sGPU调度策略

选项

描述

best-effort

sGPU不限制算力

fixed-share

sGPU有固定的算力配额,且无法超过固定配额使用

burst-share

sGPU有固定的算力配额,若GPU卡还有空闲算力,就可以被sGPU使用

分配特定GPU

若期望任务运行(或禁止运行)在特定的GPU上,用户可以为任务配置以下参数控制分配的GPU,参数说明参见下表。

表 7.11 分配特定GPU参数列表

选项

类型

描述

metax-tech.com/use-gpuuuid

string

期望分配的GPU UUID列表。支持多个GPU UUID,以逗号分隔。调度器将尝试分配在该列表中的GPU

metax-tech.com/nouse-gpuuuid

string

禁止分配的GPU UUID列表。支持多个GPU UUID,以逗号分隔。调度器将不会分配在该列表中的GPU

拓扑感知调度

当用户为任务申请完整GPU算力时,系统将分配整张GPU设备,以利用GPU间的物理拓扑加速通信。

调度器支持拓扑感知调度:针对申请完整算力的任务,根据GPU物理拓扑为其分配性能最优的GPU组合。

用户可以为任务配置是否启用拓扑感知调度,参数说明参见下表。部署HAMi时也可通过指定 --set metaxsGPUTopologyAware=true 参数启用全局拓扑感知调度。

表 7.12 拓扑感知参数

选项

类型

描述

metax-tech.com/sgpu-topology-aware

string

是否启用拓扑感知调度。可选 "true""false", 缺省时为 "false"。若启用,调度器将根据GPU物理拓扑为任务分配性能最优的GPU组合

在离线任务调度

不同 GPU 计算任务的运行特点和重要性有很大差异:如实时推理要求低延迟,需要尽快拿到 GPU 资源进行计算;模型训练对延迟敏感度较低,可以忍受一定时间的抑制。

根据业务属性将任务分为以下类型:

表 7.13 任务类型

选项

描述

在线任务

高优先级任务。当集群 GPU 算力资源无法满足在线任务时,将抢占离线任务所占用的 GPU 算力资源

离线任务

低优先级任务。当在线任务调度到离线任务所在的 GPU 设备上时,离线任务将被挂起直到在线任务运行结束

普通任务

普通优先级任务。不会发生抢占与被抢占行为

用户可以为任务配置以下参数以指定任务类型,参数说明参见下表。

表 7.14 任务类型参数

选项

类型

描述

metax-tech.com/sgpu-app-class

string

任务类型。可选 "online""offline"。若不指定则为普通任务

在线任务的抢占行为:当集群 GPU 资源无法满足在线任务时,调度器会将在线任务调度到运行有离线任务的 GPU 设备上,此时离线任务将被挂起以释放 GPU 资源直到在线任务运行结束。

在离线及普通任务调度策略如下:

  • 在线任务使用 spread 策略尽量调度到在线任务少的 GPU 设备上,且尽量不调度到仅运行离线任务的 GPU 设备上

  • 离线任务与普通任务的调度策略跟随 HAMi 的调度策略

在离线及普通任务支持的 Qos Policy 如下:

  • 在线任务默认以 best-effort 模式运行 , 因此在线任务无需指定 Qos Policy

  • 离线任务与普通任务相同,均支持指定 Qos Policy

备注

  • 在离线任务仅支持申请单个 GPU 资源

  • 在线任务无法抢占离线任务所占用的显存资源

  • 在离线任务与普通任务为设备级隔离,不会同时运行在同一 GPU 设备上

7.3.2.1. sGPU任务示例

用户可参考以下示例编写sGPU任务文件。 更多示例参见 sGPU示例

  • 为任务分配算力与显存

    apiVersion: v1
    kind: Pod
    metadata:
      name: sample-pod
    spec:
      containers:
        - name: ubuntu
          image: ubuntu:22.04
          imagePullPolicy: IfNotPresent
          command: ['bash', '-c']
          args: ["sleep infinity"]
          resources:
            limits:
              metax-tech.com/sgpu: 1 # requesting 1 GPU
              metax-tech.com/vcore: 60 # requesting 60% compute of full GPU
              metax-tech.com/vmemory: 4 # requesting 4 GiB device memory of full GPU
    
  • 为任务分配独占GPU

    apiVersion: v1
    kind: Pod
    metadata:
      name: sample-pod
    spec:
      containers:
        - name: ubuntu
          image: ubuntu:22.04
          imagePullPolicy: IfNotPresent
          command: ['bash', '-c']
          args: ["sleep infinity"]
          resources:
            limits:
              metax-tech.com/sgpu: 1 # requesting 1 exclusive GPU
    
  • 为任务配置调度策略

    apiVersion: v1
    kind: Pod
    metadata:
      name: sample-pod
      annotations:
        hami.io/node-scheduler-policy: "binpack" # node policy is configured as "binpack"
        hami.io/gpu-scheduler-policy: "spread"   # gpu policy is configured as "spread"
    spec:
      containers:
        - name: ubuntu
          image: ubuntu:22.04
          imagePullPolicy: IfNotPresent
          command: ['bash', '-c']
          args: ["sleep infinity"]
          resources:
            limits:
              metax-tech.com/sgpu: 1 # requesting 1 GPU
              metax-tech.com/vcore: 60 # requesting 60% compute of full GPU
              metax-tech.com/vmemory: 4 # requesting 4 GiB device memory of full GPU
    
  • 为任务配置Qos Policy

    apiVersion: v1
    kind: Pod
    metadata:
      name: sample-pod
      annotations:
        metax-tech.com/sgpu-qos-policy: "best-effort" # allocate "best-effort" qos sgpu
    spec:
      containers:
        - name: ubuntu
          image: ubuntu:22.04
          imagePullPolicy: IfNotPresent
          command: ['bash', '-c']
          args: ["sleep infinity"]
          resources:
            limits:
              metax-tech.com/sgpu: 1 # requesting 1 GPU
              metax-tech.com/vcore: 60 # requesting 60% compute of full GPU
              metax-tech.com/vmemory: 4 # requesting 4 GiB device memory of full GPU
    
  • 为任务分配特定GPU

    apiVersion: v1
    kind: Pod
    metadata:
      name: sample-pod
      annotations:
        metax-tech.com/use-gpuuuid: "GPU-36beae85-c835-6b14-6ab2-02671837a59c" # allocate specific gpu
    spec:
      containers:
        - name: ubuntu
          image: ubuntu:22.04
          imagePullPolicy: IfNotPresent
          command: ['bash', '-c']
          args: ["sleep infinity"]
          resources:
            limits:
              metax-tech.com/sgpu: 1 # requesting 1 GPU
              metax-tech.com/vcore: 60 # requesting 60% compute of full GPU
              metax-tech.com/vmemory: 4 # requesting 4 GiB device memory of full GPU
    
  • 为任务配置拓扑感知调度

    apiVersion: v1
    kind: Pod
    metadata:
      name: sample-pod
      annotations:
        metax-tech.com/sgpu-topology-aware: "true" # enable topology aware scheduling
    spec:
      containers:
        - name: ubuntu
          image: ubuntu:22.04
          imagePullPolicy: IfNotPresent
          command: ['bash', '-c']
          args: ["sleep infinity"]
          resources:
            limits:
              metax-tech.com/sgpu: 4 # requesting 4 exclusive GPU
    
  • 为任务配置在线任务类型

    apiVersion: v1
    kind: Pod
    metadata:
      name: sample-pod
      annotations:
        metax-tech.com/sgpu-app-class: "online" # online task
    spec:
      containers:
        - name: ubuntu
          image: ubuntu:22.04
          imagePullPolicy: IfNotPresent
          command: ['bash', '-c']
          args: ["sleep infinity"]
          resources:
            limits:
              metax-tech.com/sgpu: 1 # requesting 1 GPU
              metax-tech.com/vmemory: 4 # each GPU require 4 GiB device memory
    
  • 为任务配置离线任务类型

    apiVersion: v1
    kind: Pod
    metadata:
      name: sample-pod
      annotations:
        metax-tech.com/sgpu-app-class: "offline" # offline task
    spec:
      containers:
        - name: ubuntu
          image: ubuntu:22.04
          imagePullPolicy: IfNotPresent
          command: ['bash', '-c']
          args: ["sleep infinity"]
          resources:
            limits:
              metax-tech.com/sgpu: 1 # requesting 1 GPU
              metax-tech.com/vcore: 60 # each GPU use 60% of total compute cores
              metax-tech.com/vmemory: 4 # each GPU require 4 GiB device memory
    

7.3.2.2. 提交sGPU任务

在Kubernetes管理节点执行以下命令提交任务。

kubectl create -f sample.yaml