开源vGPU方案 HAMi实现细粒度GPU切分——筑梦之路

前言

为什么需要 GPU 共享、切分等方案?

在使用GPU的过程中我们会发现,直接在裸机环境使用,都可以多个进程共享 GPU,怎么到 k8s 环境就不行了?

1. 资源感知

在 k8s 中资源是和节点绑定的,对于 GPU 资源,我们使用 NVIDIA 提供的 device-plugin 进行感知,并上报到 kube-apiserver,这样我们就能在 Node 对象上看到对应的资源。

kubectl describe node gpu01|grep Capacity -A 7
Capacity:cpu:                128ephemeral-storage:  879000896Kihugepages-1Gi:      0hugepages-2Mi:      0memory:             1056457696Kinvidia.com/gpu:     8pods:               110

该节点除了基础的 cpu、memory 之外,还有一个nvidia.com/gpu: 8 信息,表示该节点上有 8 个 GPU 。

2. 资源申请

apiVersion: v1
kind: Pod
metadata:name: gpu-pod
spec:containers:- name: gpu-containerimage: nvidia/cuda:11.0-base   # 一个支持 GPU 的镜像resources:limits:nvidia.com/gpu: 1          # 申请 1 个 GPUcommand: ["nvidia-smi"]         # 示例命令,显示 GPU 的信息restartPolicy: OnFailure

kube-scheduler 在调度该 Pod 时就会将其调度到一个拥有足够 GPU 资源的 Node 上。同时该 Pod 申请的部分资源也会标记为已使用,不会再分配给其他 Pod。

总结一下:

1)device-plugin 感知到节点上的物理 GPU 数量,上报到 kube-apiserver

2)kube-scheduler 调度 Pod 时会根据 pod 中的 Request 消耗对应资源

即:Node 上的 GPU 资源被 Pod 申请之后,在 k8s 中就被标记为已消耗了,后续创建的 Pod 会因为资源不够导致无法调度。

实际上:可能 GPU 性能比较好,可以支持多个 Pod 共同使用,但是 k8s 中的调度限制导致多个 Pod 无法正常共享。因此,我们才需要 GPU 共享、切分等方案。

什么是 HAMi?

https://github.com/Project-HAMi/HAMi

HAMi 全称是:Heterogeneous AI Computing Virtualization Middleware,HAMi 给自己的定位或者希望是做一个异构算力虚拟化平台。原第四范式 k8s-vgpu-scheduler, 这次改名 HAMi 同时也将核心的 vCUDA 库 libvgpu.so 也开源了。但是现在比较完善的是对 NVIDIA GPU 的 vGPU 方案,因此我们可以简单认为他就是一个 vGPU 方案。

整体架构

特性

使用 HAMi 最大的一个功能点就是可以实现 GPU 的细粒度的隔离,可以对 core 和 memory 使用 1% 级别的隔离。

apiVersion: v1
kind: Pod
metadata:name: gpu-pod
spec:containers:- name: ubuntu-containerimage: ubuntu:18.04command: ["bash", "-c", "sleep 86400"]resources:limits:nvidia.com/gpu: 1 # 请求1个vGPUsnvidia.com/gpumem: 3000 # 每个vGPU申请3000m显存 (可选,整数类型)nvidia.com/gpucores: 30 # 每个vGPU的算力为30%实际显卡的算力 (可选,整数类型)----------------------
nvidia.com/gpu:请求一个 GPU
nvidia.com/gpumem:只申请使用 3000M GPU Memory
nvidia.com/gpucores:申请使用 30% 的 GPU core,也就是该 Pod 只能使用到 30% 的算力

设计

HAMi 实现 GPU core 和 memory 隔离、限制是使用的 vCUDA 方案

 HAMi 使用的是软件层面的 vCUDA 方案,对 NVIDIA 原生的 CUDA 驱动进行重写(libvgpu.so),然后挂载到 Pod 中进行替换,然后在自己的实现的 CUDA 驱动中对 API 进行拦截,实现资源隔离以及限制的效果。

例如:原生 libvgpu.so 在进行内存分配时,只有在 GPU 内存真的用完的时候才会提示 CUDA OOM,但是对于 HAMi 实现的 libvgpu.so 来说,检测到 Pod 中使用的内存超过了 Resource 中的申请量就直接返回 OOM,从而实现资源的一个限制。

然后在执行 nvidia-smi 命令查看 GPU 信息时,也只返回 Pod Resource 中申请的资源,这样在查看时也进行隔离。

HAMi 部署

HAMi 提供了 Helm Chart 安装

1. 部署 GPU Operator

HAMi 会依赖 NVIDIA 的那一套,因此推荐先部署 GPU-Operator

此处留着补充

部署好 GPU Operator 之后再部署 HAMi。

2. 部署 HAMi

# 添加repo仓库helm repo add hami-charts https://project-hami.github.io/HAMi/# 获取k8s版本kubectl version# 在安装过程中须根据集群服务端版本(上一条指令的结果)指定调度器镜像版本,例如集群服务端版本为 v1.27.4,则可以使用如下指令进行安装helm install hami hami-charts/hami --set scheduler.kubeScheduler.imageTag=v1.27.4 -n kube-system# 通过 kubectl get pods 指令看到 vgpu-device-plugin 与 vgpu-scheduler 两个 pod 状态为Running 即为安装成功kubectl get pods -n kube-system|grep hami
hami-device-plugin-b6mvj                          2/2     Running   0          42s
hami-scheduler-7f5c5ff968-26kjc                   2/2     Running   0          42s

 3. 自定义配置

官方文档:

HAMi-config-cn.md: https://github.com/Project-HAMi/HAMi/blob/master/docs/config_cn.md

在安装过程中,通过-set来修改以下的客制化参数,例如

helm install vgpu vgpu-charts/vgpu --set devicePlugin.deviceMemoryScaling=5 ...
  • devicePlugin.deviceSplitCount:整数类型,预设值是 10。GPU 的分割数,每一张 GPU 都不能分配超过其配置数目的任务。若其配置为 N 的话,每个 GPU 上最多可以同时存在 N 个任务。

  • devicePlugin.deviceMemoryScaling: 浮点数类型,预设值是 1。NVIDIA 装置显存使用比例,可以大于 1(启用虚拟显存,实验功能)。对于有 M 显存大小的 NVIDIA GPU,如果我们配置devicePlugin.deviceMemoryScaling参数为 S ,在部署了我们装置插件的 Kubenetes 集群中,这张 GPU 分出的 vGPU 将总共包含 S * M 显存。

  • devicePlugin.migStrategy: 字符串类型,目前支持"none“与“mixed“两种工作方式,前者忽略 MIG 设备,后者使用专门的资源名称指定 MIG 设备,使用详情请参考 mix_example.yaml,默认为"none"

  • devicePlugin.disablecorelimit: 字符串类型,"true"为关闭算力限制,"false"为启动算力限制,默认为"false"

  • scheduler.defaultMem: 整数类型,预设值为 5000,表示不配置显存时使用的默认显存大小,单位为 MB

  • scheduler.defaultCores: 整数类型(0-100),默认为 0,表示默认为每个任务预留的百分比算力。若设置为 0,则代表任务可能会被分配到任一满足显存需求的 GPU 中,若设置为 100,代表该任务独享整张显卡

  • scheduler.defaultGPUNum: 整数类型,默认为 1,如果配置为 0,则配置不会生效。当用户在 pod 资源中没有设置 nvidia.com/gpu 这个 key 时,webhook 会检查 nvidia.com/gpumem、resource-mem-percentage、nvidia.com/gpucores 这三个 key 中的任何一个 key 有值,webhook 都会添加 nvidia.com/gpu 键和此默认值到 resources limit 中。

  • resourceName: 字符串类型, 申请 vgpu 个数的资源名, 默认: "nvidia.com/gpu"

  • resourceMem: 字符串类型, 申请 vgpu 显存大小资源名, 默认: "nvidia.com/gpumem"

  • resourceMemPercentage: 字符串类型,申请 vgpu 显存比例资源名,默认: "nvidia.com/gpumem-percentage"

  • resourceCores: 字符串类型, 申请 vgpu 算力资源名, 默认: "nvidia.com/cores"

  • resourcePriority: 字符串类型,表示申请任务的任务优先级,默认: "nvidia.com/priority"

除此之外,容器中也有对应配置

  • GPU_CORE_UTILIZATION_POLICY: 字符串类型,"default", "force", "disable" 代表容器算力限制策略, "default"为默认,"force"为强制限制算力,一般用于测试算力限制的功能,"disable"为忽略算力限制

  • ACTIVE_OOM_KILLER: 字符串类型,"true", "false" 代表容器是否会因为超用显存而被终止执行,"true"为会,"false"为不会

4. 验证

查看 Node GPU 资源

环境中只有一个物理 GPU,但是 HAMi 默认会扩容 10 倍,理论上现在 Node 上能查看到 1*10 = 10 个 GPU。

默认参数就是切分为 10 个,可以设置

kubectl get node xxx -oyaml|grep capacity -A 7capacity:cpu: "4"ephemeral-storage: 206043828Kihugepages-1Gi: "0"hugepages-2Mi: "0"memory: 15349120Kinvidia.com/gpu: "10"pods: "110"

 验证显存和算力限制

使用以下 yaml 来创建 Pod,注意 resources.limit 除了原有的 nvidia.com/gpu 之外还新增了 nvidia.com/gpumem 和 nvidia.com/gpucores,用来指定显存大小和算力大小。

  • nvidia.com/gpu:请求的 vgpu 数量,例如 1

  • nvidia.com/gpumem :请求的显存数量,例如 3000M

  • nvidia.com/gpumem-percentage:显存百分百,例如 50 则是请求 50%显存

  • nvidia.com/priority: 优先级,0 为高,1 为低,默认为 1。

    • 对于高优先级任务,如果它们与其他高优先级任务共享 GPU 节点,则其资源利用率不会受到 resourceCores 的限制。换句话说,如果只有高优先级任务占用 GPU 节点,那么它们可以利用节点上所有可用的资源。

    • 对于低优先级任务,如果它们是唯一占用 GPU 的任务,则其资源利用率也不会受到 resourceCores 的限制。这意味着如果没有其他任务与低优先级任务共享 GPU,那么它们可以利用节点上所有可用的资源。

apiVersion: v1
kind: Pod
metadata:name: gpu-pod
spec:containers:- name: ubuntu-containerimage: ubuntu:18.04command: ["bash", "-c", "sleep 86400"]resources:limits:nvidia.com/gpu: 1 # 请求1个vGPUsnvidia.com/gpumem: 3000 # 每个vGPU申请3000m显存 (可选,整数类型)nvidia.com/gpucores: 30 # 每个vGPU的算力为30%实际显卡的算力 (可选,整数类型)
kubectl exec -it gpu-pod -- bash
root@gpu-pod:/# nvidia-smi
[HAMI-core Msg(16:139711087368000:libvgpu.c:836)]: Initializing.....
Mon Apr 29 06:22:16 2024
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 550.54.14              Driver Version: 550.54.14      CUDA Version: 12.4     |
|-----------------------------------------+------------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id          Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |           Memory-Usage | GPU-Util  Compute M. |
|                                         |                        |               MIG M. |
|=========================================+========================+======================|
|   0  Tesla T4                       On  |   00000000:00:07.0 Off |                    0 |
| N/A   33C    P8             15W /   70W |       0MiB /   3000MiB |      0%      Default |
|                                         |                        |                  N/A |
+-----------------------------------------+------------------------+----------------------++-----------------------------------------------------------------------------------------+
| Processes:                                                                              |
|  GPU   GI   CI        PID   Type   Process name                              GPU Memory |
|        ID   ID                                                               Usage      |
|=========================================================================================|
|  No running processes found                                                             |
+-----------------------------------------------------------------------------------------+
[HAMI-core Msg(16:139711087368000:multiprocess_memory_limit.c:434)]: Calling exit handler 16

最后的日志就是 HAMi 的 CUDA 驱动打印

[HAMI-core Msg(16:139711087368000:multiprocess_memory_limit.c:434)]: Calling exit handler 16

HAMi 大致实现原理

通过替换容器中的 libvgpu.so 库,实现 CUDA API 拦截,最终实现对 GPU core 和 memory 的隔离和限制。

参考资料: 

第四范式 k8s-vgpu-scheduler: https://github.com/4paradigm/k8s-vgpu-scheduler

本文搜集来自开源 vGPU 方案:HAMi,实现细粒度 GPU 切分

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/456628.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

打包方式-jar和war的区别

1、jar包 JAR包是类的归档文件,与平台无关的文件格式,其实jar包就是java的类进行编译生成的class文件进行打包的压缩包。 JAR以ZIP文件格式为基础,与ZIP不同的是,JAR不仅用于压缩和发布,还用于部署和封装库、组件和插…

R实验——logistic回归、LDA、QDAKNN

数据集介绍: mpg,miles per gallon即油耗,这个数据集来自卡内基梅隆大学维护的StatLib库。1983年美国统计协会博览会使用了该数据集。这个数据集是对StatLib库中提供的数据集稍加修改的版本。根据Ross Quinlan(1993)在预测属性“mpg”中的使…

利用飞腾派进行OpenCV开发

实验目标: 完成飞腾平台OpenCV开发。 实验大纲: Mat数据结构加载、显示、保存图像读写像素RGB图像分离彩色图转灰度图 Mat数据结构 Mat是一个类,由两个数据部分组成:矩阵头(大小,通道,数据类型等)和数据块(像素 值)。创建示例…

vue3 选中对话框时,对话框右侧出一个箭头

先看下做出的效果&#xff1a; html代码&#xff0c;其中listPlan.records是后台拿到的数据进行遍历 <template><ul class"list"><li style"height: 180px;width: 95%":key"index"v-for"(item, index) in listPlan.record…

Android 判断手机放置的方向

#1024程序员节&#xff5c;征文# 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 需求 老板&#xff1a;我有个手持终端&#xff0c;不能让他倒了&#xff0c;当他倒或者倾斜的时候要发出报警&#xff1b; 程序猿&#xff1a;我这..... 老板…

Servlet(三)-------Cookie和session

一.Cookie和Session Cookie和Session都是用于在Web应用中跟踪用户状态的技术。Cookie是存储在用户浏览器中的小文本文件&#xff0c;由服务器发送给浏览器。当用户再次访问同一网站时&#xff0c;浏览器会把Cookie信息发送回服务器。例如&#xff0c;网站可以利用Cookie记住用…

Python与MySQL

一、Python 操作 MySQL 数据库软件 我们在上一篇文章《SQL入门》中使用了图形化工具DBeaver操作MySQL数据库软件&#xff0c;除了使用图形化工具以外&#xff0c;我们也可以使用编程语言来执行 SQL 从而操作数据库&#xff0c;可以在 Python 中&#xff0c;使用第三方库 pymys…

设计师的新宠:7款不容错过的界面设计软件

在UI设计领域&#xff0c;设计师们常常需要借助各种工具来实现他们的创意。市场上众多的设计软件让设计师们有了丰富的选择&#xff0c;但同时也带来了选择困难。一个好的软件界面设计工具不仅能提升工作效率&#xff0c;还能为设计师提供丰富的资源和参考&#xff0c;帮助他们…

Python:背景知识及环境安装

一、计算机的基础概念 1.1 什么是计算机&#xff1f; 最早我们有计算器&#xff0c;但是他只能完成算数运算的功能 而计算机能完成的工作有&#xff1a; &#xff08;1&#xff09;算术运算 &#xff08;2&#xff09;逻辑判断 &#xff08;3&#xff09;数据存储 &#xff08…

使用AutoDL训练YOLO等计算机视觉网络模型(AutoDL+Xftp+VS Code),附详细操作步骤

前言 本文记录利用AutoDL云服务器&#xff0c;使用VS Code远程连接进行模型训练&#xff0c;步骤完整&#xff0c;操作简便&#xff0c;不需要使用任何命令即可快速运行&#x1f680;。 专栏目录&#xff1a;YOLOv11改进目录一览 | 涉及卷积层、轻量化、注意力、损失函数、Bac…

分享几个办公类常用的AI工具

办公类 WPS AI讯飞智文iSlideProcessOn亿图脑图ChatPPT WPS AI 金山办公推出的协同办公 AI 应用&#xff0c;具有文本生成、多轮对话、润色改写等多种功能&#xff0c;可以辅助用户进行文档编辑、表格处理、演示文稿制作等办公操作。 https://ai.wps.cn/ 讯飞智文 科大讯飞推…

博弈论 C++

前置知识 若一个游戏满足&#xff1a; 由两名玩家交替行动在游戏进行的任意时刻&#xff0c;可以执行的合法行动与轮到哪位玩家无关不能行动的玩家判负 则称该游戏为一个公平组合游戏。 尼姆游戏&#xff08;NIM&#xff09;属于公平组合游戏&#xff0c;但常见的棋类游戏&…

企业数字化转型建设方案(数据中台、业务中台、AI中台)

方案介绍&#xff1a; 企业数字化转型建设方案中的数据中台是企业数字化转型的核心基础设施&#xff0c;负责数据的整合、治理、共享和应用&#xff0c;将数据转化为资产&#xff0c;服务于业务决策和运营。业务中台是连接数据中台和技术中台的桥梁&#xff0c;负责业务的抽象…

Redis Search系列 - 第六讲 基准测试 - Redis Search VS. MongoDB VS. ElasticSearch

目录 一、引言二、Redis Search 2.x版本的性能提升三、Redis Search VS. MongoDB VS. ElasticSearch3.1 测试环境3.2 100%写 - 基准测试3.3 100%读 - 基准测试3.4 混合读/写/搜索 - 基准测试2.5 搜索延迟分析3.6 读延迟分析3.7 写延迟分析3.8 Redis Search VS. ElasticSearch3.…

DSPy:不需要手写prompt啦,You Only Code Once!

论文地址&#xff1a;https://arxiv.org/abs/2310.03714   项目地址&#xff1a;https://github.com/stanfordnlp/dspy 文章目录 1. 背景2. 签名3. 模块3.1 预测模块3.2 其他内置模块 4. 提词器5. 评估目标6. 代码分析6.1 _prepare_student_and_teacher6.2 _prepare_predicto…

985研一,转嵌入式好还是后端开发好?

有个老铁问&#xff0c;985研一&#xff0c;转嵌入式好还是后端开发好&#xff1f; 我认为&#xff0c;这学历&#xff0c;两个随便挑&#xff0c;我说的&#xff0c;从趋势来看&#xff0c;更建议嵌入式&#xff0c;走供应链上游&#xff0c;芯片原厂、新能源车企、军工或者搞…

力扣143:重排链表

给定一个单链表 L 的头节点 head &#xff0c;单链表 L 表示为&#xff1a; L0 → L1 → … → Ln - 1 → Ln请将其重新排列后变为&#xff1a; L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → … 不能只是单纯的改变节点内部的值&#xff0c;而是需要实际的进行节点交换。 示…

qt creator 转 visual stdio 项目调试

因果 大家在使用qt creator调试程序时&#xff0c;会出现未知错误&#xff0c;比如下图&#xff0c;直接release运行就没有问题。由于调试复杂程序&#xff0c;使用qt creator都感觉不如vs&#xff0c;会报未知中断。 所以有了从qt creator转换到 visual stdio来调试的想法。…

【电子元件】光通量和色温 (欧司朗LED灯珠 KW3 CGLNM1.TG命名规则)

什么是光通量&#xff1f; 光通量&#xff08;Luminous Flux&#xff09;是衡量光源在单位时间内发出的可见光总量的物理量&#xff0c;表示的是光源产生的总光能量&#xff0c;其中只考虑人眼能感知的部分。它通常以流明&#xff08;lumen&#xff0c;符号为 lm&#xff09;为…

如何使用gitlab切换分支

第一步&#xff0c;在gitlab上新建一个远程分支。选择New branch即可新建一个&#xff0c;但是注意往往是在当前分支下新建的分支&#xff0c;所以新分支里会有当前分支的内容。 第二步&#xff0c;在本地当前分支在运行这三行命令&#xff0c;即可得到一个空的新分支。 git c…