当前位置: 首页 > 软件库 > 云计算 > >

vGPU device plugin for Kubernetes

虚拟化 GPU 内存
授权协议 Apache
开发语言 Google Go
所属分类 云计算
软件类型 开源软件
地区 国产
投 递 者 程吕恭
操作系统 跨平台
开源组织
适用人群 未知
 软件概览

vGPU device plugin基于NVIDIA官方插件(NVIDIA/k8s-device-plugin),在保留官方功能的基础上,实现了对物理GPU进行切分,并对显存和计算单元进行限制,从而模拟出多张小的vGPU卡。在k8s集群中,基于这些切分后的vGPU进行调度,使不同的容器可以安全的共享同一张物理GPU,提高GPU的利用率。此外,插件还可以对显存做虚拟化处理(使用到的显存可以超过物理上的显存),运行一些超大显存需求的任务,或提高共享的任务数,可参考性能测试报告

使用场景

  1. 显存、计算单元利用率低的情况,如在一张GPU卡上运行10个tf-serving。
  2. 需要大量小显卡的情况,如教学场景把一张GPU提供给多个学生使用、云平台提供小GPU实例。
  3. 物理显存不足的情况,可以开启虚拟显存,如大batch、大模型的训练。

性能测试

在测试报告中,我们一共在下面五种场景都执行了ai-benchmark 测试脚本,并汇总最终结果:

测试环境 环境描述
Kubernetes version v1.12.9
Docker version 18.09.1
GPU Type Tesla V100
GPU Num 2
测试名称 测试用例
Nvidia-device-plugin k8s + nvidia官方k8s-device-plugin
vGPU-device-plugin k8s + VGPU k8s-device-plugin,无虚拟显存
vGPU-device-plugin(virtual device memory) k8s + VGPU k8s-device-plugin,高负载,开启虚拟显存

测试内容

test id 名称 类型 参数
1.1 Resnet-V2-50 inference batch=50,size=346*346
1.2 Resnet-V2-50 training batch=20,size=346*346
2.1 Resnet-V2-152 inference batch=10,size=256*256
2.2 Resnet-V2-152 training batch=10,size=256*256
3.1 VGG-16 inference batch=20,size=224*224
3.2 VGG-16 training batch=2,size=224*224
4.1 DeepLab inference batch=2,size=512*512
4.2 DeepLab training batch=1,size=384*384
5.1 LSTM inference batch=100,size=1024*300
5.2 LSTM training batch=10,size=1024*300

测试结果: img

img

测试步骤:

  1. 安装nvidia-device-plugin,并配置相应的参数
  2. 运行benchmark任务
$ kubectl apply -f benchmarks/ai-benchmark/ai-benchmark.yml
  1. 通过kubctl logs 查看结果
$ kubectl logs [pod id]

功能

  • 指定每张物理GPU切分的vGPU的数量
  • 限制vGPU的显存
  • 限制vGPU的计算单元
  • 对已有程序零改动

实验性功能

  • 虚拟显存

    vGPU的显存总和可以超过GPU实际的显存,这时候超过的部分会放到内存里,对性能有一定的影响。

产品限制

  • 分配到节点上任务所需要的vGPU数量,不能大于节点实际GPU数量

已知问题

  • 开启虚拟显存时,如果某张物理GPU的显存已用满,而这张GPU上还有空余的vGPU,此时分配到这些vGPU上的任务会失败。
  • 目前仅支持计算任务,不支持视频编解码处理。

开发计划

  • 支持视频编解码处理
  • 支持Multi-Instance GPUs (MIG)

安装要求

  • NVIDIA drivers >= 384.81
  • nvidia-docker version > 2.0
  • docker已配置nvidia作为默认runtime
  • Kubernetes version >= 1.10

快速入门

GPU节点准备

以下步骤要在所有GPU节点执行。这份README文档假定GPU节点已经安装NVIDIA驱动和nvidia-docker套件。

注意你需要安装的是nvidia-docker2而非nvidia-container-toolkit。因为新的--gpus选项kubernetes尚不支持。安装步骤举例:

# 加入套件仓库
$ distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
$ curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
$ curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list

$ sudo apt-get update && sudo apt-get install -y nvidia-docker2
$ sudo systemctl restart docker

你需要在节点上将nvidia runtime做为你的docker runtime预设值。我们将编辑docker daemon的配置文件,此文件通常在/etc/docker/daemon.json路径:

{
    "default-runtime": "nvidia",
    "runtimes": {
        "nvidia": {
            "path": "/usr/bin/nvidia-container-runtime",
            "runtimeArgs": []
        }
    }
    "default-shm-size": "2G"
}

如果 runtimes 字段没有出现, 前往的安装页面执行安装操作 nvidia-docker

Kubernetes开启vGPU支持

当你在所有GPU节点完成前面提到的准备动作,如果Kubernetes有已经存在的NVIDIA装置插件,需要先将它移除。然后,你能通过下面指令下载我们的Daemonset yaml文件:

$ wget https://raw.githubusercontent.com/4paradigm/k8s-device-plugin/master/nvidia-device-plugin.yml

在这个DaemonSet文件中, 你能发现nvidia-device-plugin-ctr容器有一共4个vGPU的客制化参数:

  • fail-on-init-error: 布尔类型, 预设值是true。当这个参数被设置为true时,如果装置插件在初始化过程遇到错误时程序会返回失败,当这个参数被设置为false时,遇到错误它会打印信息并且持续阻塞插件。持续阻塞插件能让装置插件即使部署在没有GPU的节点(也不应该有GPU)也不会抛出错误。这样你在部署装置插件在你的集群时就不需要考虑节点是否有GPU,不会遇到报错的问题。然而,这么做的缺点是如果GPU节点的装置插件因为一些原因执行失败,将不容易察觉。现在预设值为当初始化遇到错误时程序返回失败,这个做法应该被所有全新的部署采纳。
  • device-split-count: 整数类型,预设值是2。NVIDIA装置的分割数。对于一个总共包含N张NVIDIA GPU的Kubernetes集群,如果我们将device-split-count参数配置为K,这个Kubernetes集群将有K * N个可分配的vGPU资源。注意,我们不建议将NVIDIA 1080 ti/NVIDIA 2080 ti device-split-count参数配置超过5,将NVIDIA T4配置超过7,将NVIDIA A100配置超过15。
  • device-memory-scaling: 浮点数类型,预设值是1。NVIDIA装置显存使用比例,可以大于1(启用虚拟显存,实验功能)。对于有M​显存大小的NVIDIA GPU,如果我们配置device-memory-scaling参数为S,在部署了我们装置插件的Kubenetes集群中,这张GPU分出的vGPU将总共包含 S * M显存。每张vGPU的显存大小也受device-split-count参数影响。在先前的例子中,如果device-split-count参数配置为K,那每一张vGPU最后会取得 S * M / K 大小的显存。
  • device-cores-scaling: 浮点数类型,预设值是1。NVIDIA装置算力使用比例,可以大于1。如果device-cores-scaling​参数配置为S​ device-split-count参数配置为K,那每一张vGPU对应的一段时间内 sm 利用率平均上限为S / K。属于同一张物理GPU上的所有vGPU sm利用率总和不超过1。
  • enable-legacy-preferred: 布尔类型,预设值是false。对于不支持 PreferredAllocation 的kublet(<1.19)可以设置为true,更好的选择合适的device,开启时,本插件需要有对pod的读取权限,可参看 legacy-preferred-nvidia-device-plugin.yml。对于 kubelet >= 1.9 时,建议关闭。

完成这些可选参数的配置后,你能透过下面命令开启vGPU的支持:

$ kubectl apply -f nvidia-device-plugin.yml

运行GPU任务

NVIDIA vGPUs 现在能透过资源类型nvidia.com/gpu被容器请求:

apiVersion: v1
kind: Pod
metadata:
  name: gpu-pod
spec:
  containers:
    - name: ubuntu-container
      image: ubuntu:18.04
      command: ["bash", "-c", "sleep 86400"]
      resources:
        limits:
          nvidia.com/gpu: 2 # 请求2个vGPUs

现在你可以在容器执行nvidia-smi命令,然后比较vGPU和实际GPU显存大小的不同。

注意: 如果你使用插件装置时,如果没有请求vGPU资源,那容器所在机器的所有vGPU都将暴露给容器。

测试

  • TensorFlow 1.14.0-1.15.0/2.2.0-2.6.2
  • torch1.1.0-1.8.0
  • mxnet 1.4.0
  • mindspore 1.1.1
  • xgboost 1.0-1.4
  • nccl 2.4.8-2.9.9

以上框架均通过测试。

日志

启动日志:在使用vGPU功能的pod中添加环境变量

LIBCUDA_LOG_LEVEL=5

获取vGPU相关的日志:

kubectl logs xxx | grep libvgpu.so

反馈和参与

  • 4paradigm/k8s-vgpu-scheduler https://github.com/4paradigm/k8s-vgpu-scheduler k8s vGPU scheduler 在保留4pd-k8s-device-plugin(4paradigm/k8s-device-plugin)插件功能的基础上,添加了调度模块,以实现多个GPU节点间的负载均衡。k8s vGPU schedule

 相关资料
  • 虚拟化 [PV_OPS] noreplace-paravirt 禁止使用内核通用的半虚拟化接口paravirt_ops,主要用于解决某些在Virtual PC上安装或运行Linux的故障。 [VMMIO] virtio_mmio.device=size@baseaddr:irq[:id] 实例化virtio-mmio设备(CONFIG_VIRTIO_MMIO)。可以多次使用以实例化多个设备。 si

  • 主要内容:虚拟内存如何工作?,按需分页,虚拟内存管理系统的快照虚拟内存是一种存储方案,为用户提供了一个拥有非常大的主内存的幻觉。 这是通过将辅助存储器的一部分作为主存储器来完成的。 在这种方案中,用户可以加载比可用主存更大的进程,因为存在内存可用于加载进程的错觉。 操作系统不是在主内存中加载一个大进程,而是在主内存中加载多个进程的不同部分。 通过这样做,多程序的程度将会增加,因此CPU利用率也会增加。 虚拟内存如何工作? 在现代语言中,虚拟内存近来变得非常普

  • 处理器的虚拟内存子系统为每个进程实现了虚拟地址空间。这让每个进程认为它在系统中是独立的。虚拟内存的优点列表别的地方描述的非常详细,所以这里就不重复了。本节集中在虚拟内存的实际的实现细节,和相关的成本。 虚拟地址空间是由CPU的内存管理单元(MMU)实现的。OS必须填充页表数据结构,但大多数CPU自己做了剩下的工作。这事实上是一个相当复杂的机制;最好的理解它的方法是引入数据结构来描述虚拟地址空间。

  • Docker 常用命令 docker pull redis #拉取镜像,默认 latest 版本 docker pull mysql:8.0 #拉取指定版本镜像 docker images #查看镜像 docker image ls #查看镜像 docker image ls -f dangling=true #查看虚悬镜像 docker image prune #删除虚悬镜像 doc

  • 在开发和线上阶段使用不同的系统运行环境的话, 经常会遇到各种各样的 BUG, 并且在团队开发的时候, 让所有成员都保持使用最新版本的软件和类库, 也是一件很让人头痛的事情. 如果你是在 Windows 下开发, 线上环境是 Linux (或者别的非 Windows 系统) 的话, 或者团队协同开发的时候, 建议使用虚拟机. 除了大家熟知的 VMware 和 VirtualBox 外, 还有很多工具

  • I/O虚拟化包括管理虚拟设备和共享的物理硬件之间I/O请求的路由选择。目前,实现I/O虚拟化有三种方式:I/O全虚拟化、I/O半虚拟化和I/O透传。 全虚拟化:宿主机截获客户机对I/O设备的访问请求,然后通过软件模拟真实的硬件。这种方式对客户机而言非常透明,无需考虑底层硬件的情况,不需要修改操作系统。 半虚拟化:通过前端驱动/后端驱动模拟实现I/O虚拟化。客户机中的驱动程序为前端,宿主机提供的与客

  • JBoss 数据虚拟化平台测试报告 JBoss 数据虚拟化平台测试报告内容包括: 功能性测试 性能指标报告 重要链接 JBoss 数据虚拟化认证配置 - https://access.redhat.com/articles/703663

  • 本文向大家介绍MySQL内存及虚拟内存优化设置参数,包括了MySQL内存及虚拟内存优化设置参数的使用技巧和注意事项,需要的朋友参考一下 mysql 优化调试命令   1、mysqld --verbose --help 这个命令生成所有mysqld选项和可配置变量的列表 2、通过连接它并执行这个命令,可以看到实际上使用的变量的值: mysql> SHOW VARIABLES; 还可以通过下面的语句看