【大模型系列篇】GPU资源容器化访问使用指南

news2025/1/11 9:48:08

在当今的高性能计算和机器学习领域,GPU(图形处理单元)因其卓越的并行计算能力而扮演着至关重要的角色。随着容器化技术如 Docker 的普及,越来越多的数据科学家和开发者选择将他们的应用和工作负载封装到 Docker 容器中,以实现更便捷的开发、测试和部署流程。然而,默认情况下,Docker 容器是无法自动识别或利用宿主机上的 NVIDIA GPU 资源的。这一限制可能会导致那些依赖于 GPU 加速的工作负载性能大幅下降,甚至完全无法运行。

为了打破这种隔离,使得容器内的应用程序可以像在裸机上一样使用 GPU,接下来我们一起来探索,开启容器对 NVIDIA GPU 的访问之旅。

1.安装 NVIDIA 驱动程序

Nvidia官网下载驱动程序: https://www.nvidia.cn/drivers/lookup/

wget https://cn.download.nvidia.com/XFree86/Linux-x86_64/550.120/NVIDIA-Linux-x86_64-550.120.run

安装过程中会出现:

  • he distribution-provided pre-install script failed! Are you sure you want to continue? 选择 yes 继续。

  • Would you like to register the kernel module souces with DKMS? This will allow DKMS to automatically build a new module, if you install a different kernel later? 选择 no 继续。

  • Would you like to run the nvidia-xconfigutility to automatically update your x configuration so that the NVIDIA x driver will be used when you restart x? Any pre-existing x confile will be backed up。选择 yes 继续。

安装成功后,reboot 重启,输入nvidia-smi 查看。

2.安装 CUDA Toolkit

CUDA Toolkit 是 NVIDIA 提供的一套全面的开发工具,旨在帮助开发者创建、优化和部署基于 CUDA 的应用程序。它为利用 GPU 进行加速计算提供了必要的基础设施和支持,使得开发者可以充分利用 NVIDIA GPU 的并行处理能力来加速各种计算密集型任务。

 https://developer.nvidia.com/cuda-toolkit-archive

NVIDIA驱动版本与CUDA版本对应关系查看: https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html 

3.安装 NVIDIA Container Toolkit

NVIDIA Container Toolkit 是一个专为构建和运行利用 GPU 加速的容器而设计的强大工具集。它通过集成到 Docker 引擎中,自动配置容器以支持 NVIDIA GPU,从而简化了 GPU 支持的容器化应用的部署与管理。

该工具包包括一个容器运行时库和一系列实用程序,能够自动处理与 NVIDIA GPU 交互的复杂性。当启动一个配置了 --gpus 选项的容器时,NVIDIA Container Toolkit 会自动将必要的 GPU 设备文件挂载到容器内,并设置相应的环境变量,使应用程序可以直接访问 GPU 资源。

Make sure you have installed the NVIDIA driver for your Linux Distribution Note that you do not need to install the CUDA Toolkit on the host system, but the NVIDIA driver needs to be installed。

https://github.com/NVIDIA/nvidia-container-toolkit

截至 2024/04/08 ,nvidia-container-runtime 已经废弃了,现在叫 nvidia-container-toolkit

https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html

依赖关系如下,version 是指 NVIDIA Container Toolkit 版本:

 例如下面是官方文档的图,它是如何和 docker 工作的。

3.1.安装容器工具包
curl -s -L https://nvidia.github.io/libnvidia-container/stable/rpm/nvidia-container-toolkit.repo | \
  sudo tee /etc/yum.repos.d/nvidia-container-toolkit.repo
sudo yum install -y nvidia-container-toolkit  
 3.2.配置容器运行时
  • 使用 nvidia-ctk 命令配置:

sudo nvidia-ctk runtime configure --runtime=docker

The nvidia-ctk command modifies the /etc/docker/daemon.json file on the host. The file is updated so that Docker can use the NVIDIA Container Runtime.

 {
  "default-runtime": "nvidia",
  "runtimes": {
      "nvidia": {
          "path": "/usr/bin/nvidia-container-runtime",
          "runtimeArgs": []
      }
  }
  • 重启 Docker 守护进程

sudo systemctl restart docker
  • 验证配置

docker run --rm --gpus all nvidia/cuda:11.4.0-base-ubuntu20.04 nvidia-smi

4.K8S如何使用GPU

k8s 需要部署 NVIDIA 的 device plugin ,会 daemonset 起一个服务挂载宿主机 /var/lib/kubelet/device-plugins/ 目录,然后在目录下生成 socket 文件,kubelet 和这个 socket 文件按照 device plugin 要求 grpc 调用,部署去看官方的 github 部署。

kubectl apply -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.13.0/nvidia-device-plugin.yml

确保 Kubernetes 集群中已安装 NVIDIA Device Plugin。

kubectl get pods -n kube-system kubectl logs nvidia-device-plugin-daemonset-hzldk -n kube-system
  • kubectl describe node ?

  • 新建 gpu-pod.yaml 并部署

apiVersion: v1
kind: Pod
metadata:
  name: gpu-pod
spec:
  restartPolicy: OnFailure
  containers:
  - name: cuda-vector-add
    image: "nvidia/samples:vectoradd-cuda10.2"
    resources:
      limits:
         nvidia.com/gpu: 1
      requests:
        nvidia.com/gpu: "1"
kubectl apply -f gpu-pod.yaml
  • kubectl describe pod gpu-pod

  • kubectl logs gpu-pod

在 Kubernetes (K8s) 中,GPU 资源的管理通常依赖于设备插件(Device Plugin),它使得 GPU 可以作为扩展资源被调度。然而,默认情况下,Kubernetes 对于 GPU 的资源请求和限制只支持整数级别的分配,即你只能请求整个 GPU 或者不请求。这意味着如果你想要更细粒度地控制 GPU 资源,例如只分配一部分显存或计算核心给某个容器,就需要采取额外的措施。

这个简单介绍一种方法,HAMi 是一个开源的 vGPU 方案,它可以实现对 GPU core 和 memory 使用 1% 级别的隔离,确保共享同一 GPU 的各个 Pod 都能获得足够的资源。

通过 HAMi,你可以为每个 Pod 指定具体的 GPU 显存量和核心数量,从而更好地利用 GPU 资源。具体来说,你可以修改 Pod 的 YAML 文件,在 resources 字段中添加 gpu-memgpu-count 这样的扩展资源。

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: 1
        gpu-mem: "2048Mi"  # 限制显存为2GB
      requests:
        nvidia.com/gpu: 1
        gpu-mem: "2048Mi"  # 请求显存为2GB

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【力扣】409.最长回文串

问题描述 思路解析 因为同时包含大小写字母,直接创建个ASCII表大小的桶来标记又因为是要回文子串,所以偶数个数的一定可以那么同时,对于出现奇数次数的,我没需要他们的次数-1,变为偶数,并且可以标记出现过…

Linux——管理用户和用户组

一、用户有哪些 root用户 定义:root用户是Linux系统中的最高权限用户,具有对系统所有资源的完全控制权。特性:root用户可以执行系统中的任何操作,包括修改系统配置文件、安装软件、管理系统服务等。由于其拥有最高权限&#xff0c…

SIP系列七:ICE框架(P2P通话)

我的音视频/流媒体开源项目(github) SIP系列目录 目录 一、NAT 1、NAT介绍 2、NAT类型 2.1、 完全圆锥型NAT 2.2、受限圆锥型NAT 2.3、端口受限圆锥型NAT 2.4、对称NAT 3、NAT打洞 3.1、不同一NAT下 3.2、同一NAT下 二、ICE 三、ICE中的SDP 至此&#x…

Spring Boot如何实现防盗链

一、什么是盗链 盗链是个什么操作,看一下百度给出的解释:盗链是指服务提供商自己不提供服务的内容,通过技术手段绕过其它有利益的最终用户界面(如广告),直接在自己的网站上向最终用户提供其它服务提供商的…

5.内容管理模块-课程查询

搞清楚一个项目的业务流程最直接的手段,就是找一个账号登录进去,操作一遍。 3.3设计接口 接口设计分析 post在需要提交很多参数的时候使用,并且post的安全性较高。 接口分析: po包,一般存放和数据库交互的实体类。 …

网络编程 | TCP套接字通信及编程实现经验教程

1、TCP基础铺垫 TCP/IP协议簇中包含了如TCP、UDP、IP、ICMP、ARP、HTTP等通信协议。TCP协议是TCP/IP协议簇中最为常见且重要的通信方式之一,它为互联网上的数据传输提供了可靠性和连接管理。 TCP(Transmission Control Protocol,传输控制协议…

vue3组件间传值

definProps方式 子组件&#xff1a;assignSuppliers.vue const propdefineProps({fid:String}); 父组件&#xff1a;index.vue <!-- 供应商分配 --><n-drawerwidth"800"v-model:visible"drawerSupplierConfig.visible":title"drawerSuppli…

《网络安全编程基础》之Socket编程

我的代码 server.c // server.cpp : Defines the entry point for the console application. //#include "stdafx.h" #include <Winsock2.h> #pragma comment(lib,"ws2_32.lib") //添加静态链接库文件 void main(int argc,char* argv[]) {WSADATA …

不只是请求和响应:使用Fiddler解读Cookie与状态码全指南(下)

欢迎浏览高耳机的博客 希望我们彼此都有更好的收获 感谢三连支持! 不只是请求和响应&#xff1a;使用Fiddler抓包HTTP协议全指南(上)_fiddler 获取响应脚本-CSDN博客https://blog.csdn.net/Chunfeng6yugan/article/details/144005872?spm1001.2014.3001.5501 不只是请求和响…

Linx下自动化之路:Redis安装包一键安装脚本实现无网极速部署并注册成服务

目录 简介 安装包下载 安装脚本 服务常用命令 简介 通过一键安装脚本实现 Redis 安装包的无网极速部署&#xff0c;并将其成功注册为系统服务&#xff0c;开机自启。 安装包下载 redis-7.0.8.tar.gzhttp://download.redis.io/releases/redis-7.0.8.tar.gz 安装脚本 修…

第3章.垃圾收集器与内存分配策略

概述 对象已死 引用计数法 可达性分析算法 再谈引用 生存还是死亡 回收方法区 垃圾收集算法 分代收集理论 3种垃圾收集算法 HotSpot的算法细节实现 根节点枚举 安全点 安全区域 记忆集与卡表 写屏障 并发的可达性分析 误消亡问题 经典垃圾收集器 概述 简单的一些GC CMS G1 低延…

Python 类的设计(以植物大战僵尸为例)

关于类的设计——以植物大战僵尸为例 一、设计类需满足的三要素1. 类名2. 属性和方法 二、以植物大战僵尸的为例的类的设计1. 尝试分类2. 创建对象调用类的属性和方法*【代码二】*3. 僵尸的继承 三、代码实现 一、设计类需满足的三要素 1. 类名 类名&#xff1a;某类事物的名…

如何使用WinCC DataMonitor基于Web发布浏览Excel报表文档

本文介绍使用 WinCC DataMonitor 的 "Excel Workbooks" 功能&#xff0c;通过 Excel 表格显示 WinCC 项目的过程值、归档变量值和报警归档消息。并可以通过 Web 发布浏览访问数据 1&#xff0e;WinCC DataMonitor是什么 ? DataMonitor 是 SIMATIC WinCC 工厂智能中…

【Java】—— 图书管理系统

基于往期学习的类和对象、继承、多态、抽象类和接口来完成一个控制台版本的 “图书管理系统” 在控制台界面中实现用户与程序交互 任务目标&#xff1a; 1、系统中能够表示多本图书的信息 2、提供两种用户&#xff08;普通用户&#xff0c;管理员&#xff09; 3、普通用户…

记录ubuntu22.04重启以后无法获取IP地址的问题处理方案

现象描述&#xff1a;我的虚拟机网络设置为桥接模式&#xff0c;输入ifconfig只显示127.0.0.1&#xff0c;不能连上外网。&#xff0c;且无法上网&#xff0c;用ifconfig只有如下显示&#xff1a; 1、sudo -i切换为root用户 2、输入dhclient -v 再输入ifconfig就可以看到多了…

异步操作,promise、axios

一、异步操作&#xff08;异步编程&#xff09;、同步操作 异步操作是指在编程中&#xff0c;某个任务的执行不会立即完成&#xff0c;同时不会阻塞后续代码的执行。在异步操作中&#xff0c;程序可以继续运行&#xff0c;并在异步任务完成时得到通知并处理结果。这与同步操作…

第一性原理构造医疗信创域高质量发展路径应用探析

门诊电子病历录入 摘要&#xff1a; 主要介绍了第一性原理在医疗系统开发中的应用及其重要性。阐述了第一性原理的概念及发展历程&#xff0c;并指出其在各个领域的重要性和应用价值。详细分析了第一性原理在医疗系统开发中的具体影响&#xff0c;包括对医院管理和互联网医疗的…

MySQL8下载安装教程

前言 1.个人经验&#xff0c;仅供参考&#xff01;&#xff01;&#xff01; 2.如果之前有下载过MySQL&#xff0c;请检查是否有删除干净&#xff0c;在控制面板删除最好 下载网址&#xff1a;MySQL :: MySQL Community Downloads 下载步骤 进入网址选择要下载的 下一步网…

算法日记 45 day 图论(并查集基础)

并查集解决什么问题 并查集常用来解决连通性问题。 大白话就是当我们需要判断两个元素是否在同一个集合里的时候&#xff0c;我们就要想到用并查集。 原理 既然是查找是否在同一个集合中&#xff0c;那么这个集合是怎么构建的呢&#xff1f;用一维数组来表示一个有向图&…

PTA DS 6-4 带头结点的链队列的基本操作 (C补全函数)

6-4 带头结点的链队列的基本操作 分数 10 全屏浏览 切换布局 作者 黄复贤 单位 菏泽学院 实现链队列的入队列及出队列操作。 函数接口定义&#xff1a; Status QueueInsert(LinkQueue *Q,ElemType e)&#xff1b; Status QueueDelete(LinkQueue *Q,ElemType *e)&#x…