跳到主要内容

sGPU 使用指南

摩尔线程 sGPU 服务通过自研的内核驱动为容器提供虚拟的 GPU 设备,在保证性能的前提下隔离显存和算力,为充分利用 GPU 硬件资源进行训练和推理提供有效保障。 本文介绍如何在容器环境下启用 sGPU 并进行设置。在 Kubernetes 集群中如何通过 GPU Operator 使用 sGPU 请参考 GPU Operator 使用指南。

运行 sGPU 服务​

sGPU 功能将会与 MT Container Runtime 一起提供服务,因此需要一起使用。创建容器时,通过环境变量 MTHREADS_QOS_MEMORY_LIMIT 指定容器内可用的显存大小,即可使用 sGPU 服务:

# 如果要设置自定义的算力权重,可增加 -e MTHREADS_QOS_COMPUTING_POWER_WEIGHT=<<uint64>> 设置,默认值为 1
$ docker run -it \
-e MTHREADS_VISIBLE_DEVICES=0 \
-e MTHREADS_QOS_MEMORY_LIMIT=1000 \
sh-harbor.mthreads.com/cloud/opencl \
bash

环境变量​

影响 sGPU 服务的环境变量如下表所示,您可以在创建容器时指定环境变量的值,控制容器可以通过 sGPU 服务获得的能力。

环境变量取值类型描述示例
MTHREADS_VISIBLE_DEVICESInteger 或 UUID指定容器内可见的GPU0,1:分配第 1、2 张卡
UUID:分配指定卡
MTHREADS_QOS_MEMORY_LIMITInteger设置容器内可用显存大小,不指定或为 0 时不使用 sGPU。
默认单位 bytes,根据设置值向上对齐到以下档位:
512MiB,1/2/4/8/16/32/48/64/80GiB
设500000000则分配 512MiB。
设40GiB则分配 48GiB。
MTHREADS_QOS_COMPUTING_POWER_WEIGHTInteger设置容器算力权重,默认 1。范围 1 ~ 99999无

使用示例​

下面演示两个容器共用一张显卡。gpu_test1 分配 2 GiB 显存,gpu_test2 分配 4 GiB 显存。

  1. 执行以下命令,创建容器并设置容器内可见的显存:
$ docker run -d \
--name gpu_test1 \
-e MTHREADS_VISIBLE_DEVICES=0 \
-e MTHREADS_QOS_MEMORY_LIMIT=2147483648 \
sh-harbor.mthreads.com/cloud/opencl \
sleep 10000

$ docker run -d \
--name gpu_test2 \
-e MTHREADS_VISIBLE_DEVICES=0 \
-e MTHREADS_QOS_MEMORY_LIMIT=4294967296 \
sh-harbor.mthreads.com/cloud/opencl \
sleep 10000
  1. 进入容器 gpu_test1,执行 mthreads-gmi,查看显存等 GPU 信息:
Fri Sep 16 09:21:33 2022
--------------------------------------------------------------
mthreads-gmi:2.3.2 Driver Version:3.3.5-server
--------------------------------------------------------------
ID Name |PCIe |%GPU Mem
|Pcie Lane Width | Temp
+------------------------------------------------------------+
0 MTT S5000 |N/A |0% 9MiB(2048MiB)
|N/A | 48C
--------------------------------------------------------------

容器内 procfs 节点设置​

sGPU 服务运行时会在 /proc/sgpu_km 下生成并自动管理多个 procfs 节点,可以通过 procfs 节点查看和配置 sGPU 服务相关的信息。下面介绍各 procfs 节点的用途。

查看节点信息​

执行以下命令,查看节点信息:

$ ls /proc/sgpu_km/

执行结果如下所示:

0 cores dev_map inst_ctl major misc_major mknod version

节点信息说明如下表所示:

节点读写类型描述
0读写sGPU 服务会针对 GPU 实例中的每张显卡生成一个目录,并使用数字作为目录名称,例如 0、1、2。本示例中只有一张显卡,对应的目录 ID 为 0。
cores读写当前可用的显卡 ID。
dev_map只读当前可用显卡设备映射关系。
inst_ctl只写控制节点。
major只读sGPU DRM 设备的主设备号。
misc_major只读sGPU MISC 设备的主设备号。
mknod只写控制 sGPU 设备创建和删除。
version只读sGPU 的版本。

查看显卡对应的目录内容​

本示例中,以显卡 0 为例:

$ ls /proc/sgpu_km/0

执行结果如下所示:

0123456789ab 0123456789ac max_inst overcommit_ratio policy time_slice

目录内容说明如下表所示:

节点读写类型描述
容器对应目录读写sGPU 服务会针对运行在 GPU 实例中的每个容器生成一个目录,并使用容器 ID 作为目录名称。您可以执行 docker ps 查看已创建的容器。
max_inst读写用于设置当前卡能支持的容器最大数量,取值范围为 1~16。
overcommit_ratio读写用于设置当前卡显存申请时的超发比例,取值范围为 100~200。
policy读写用于设置当前卡的算力隔离模式,取值说明请参见调度策略。
time_slice读写用于设置当前卡的时间片大小,单位是 ms,整数。默认是 1 ms。如需算力隔离的公平性更强,请调大该值。相关说明请参见时间片长度。

注意:max_inst、policy 以及 time_slice 在有容器分配后无法修改,若要设置需要在未分配容器时设置。

查看容器对应的目录内容​

本示例中,以 0123456789ab 容器为例:

$ ls /proc/sgpu_km/0/0123456789ab

执行结果如下所示:

id meminfo memsize weight

目录内容说明如下表所示:

节点读写类型描述
id只读容器对应 GPU 的 ID。
memsize读写用于设置容器内的显存大小。sGPU 服务会根据 GPU 显存大小自动设定此值。
meminfo只读展示容器内剩余显存容量、正在使用 GPU 的进程 ID 及其显存用量,输出如下所示:
weight读写用于设置容器的时间片个数。容器在容器时间(时间片个数 × 时间片长度)内,允许发送请求至 GPU。相关说明请参见时间片个数配置。

meminfo 节点输出示例:

Free: 6730809344
PID: 19772 Mem: 200278016

注意:memsize 和 weight 在容器中有 GPU 进程在运行时无法修改。

算力设置说明​

调度策略​

sGPU 提供三种调度策略模式,您可以通过修改 policy 节点进行配置:

  • 性能模式 (policy=0):没有隔离算力,和在母机上并行跑两个任务一样。默认启动该模式。
  • 弱隔离模式 (policy=1):隔离了算力,当其他容器未使用时,只有正在使用的容器分整台 GPU。
  • 强隔离模式 (policy=2):隔离了算力,即使有容器未使用,也会参与调度,占时间片。目前强隔离模式只支持平均分,不支持容器占用不同算力比例。

配置方法如下:

  • 对 0 号卡设置性能模式:echo 0 > /proc/sgpu_km/0/policy
  • 对 0 号卡设置弱隔离模式:echo 1 > /proc/sgpu_km/0/policy
  • 对 0 号卡设置强隔离模式:echo 2 > /proc/sgpu_km/0/policy

时间片长度​

时间片长度决定了调度更加公平还是更加高效:时间片越长越公平,反之更高效。具体设置多长才能兼顾公平和效率,与运行的任务有关。默认设置 1 ms,目前最小 1 ms。时间片长度对弱隔离和强隔离两种算力隔离模式有影响,对性能模式没有影响。

配置方法,对 0 号卡设置时间片长度 10 ms:

$ echo 10 > /proc/sgpu_km/0/time_slice

最大运行实例个数​

用于设置强隔离模式下最大运行实例个数,比如一张卡均切四份,就设置为 4。

配置方法,对 0 号卡设置最大实例个数 4:

$ echo 4 > /proc/sgpu_km/0/max_inst

时间片个数配置​

用于设置弱隔离模式下容器的时间片个数,比如容器 A 设置一个,容器 B 设置两个,则容器 A 使用当前卡的 33.3% 算力,容器 B 使用 66.7% 算力。默认一个。

配置方法,对 0 号卡的 $container_id 设置 2 个时间片:

$ echo 2 > /proc/sgpu_km/0/$container_id/weight