WSL2使用Nvidia-Docker实现CUDA版本自由切换
众所周知,深度学习的环境往往非常麻烦,经常不同的项目所依赖的 torch、tensorflow 包对 CUDA 的版本也有不同的要求,Linux 下进行 CUDA 的管理比较麻烦,是一个比较头疼的问题。
随着 WSL2 对物理机显卡的支持,Nvidia-Docker 也提供了对容器显卡的支持。我们可以通过拉取不同的 Docker 镜像的方式来实现对容器内 CUDA、CUDNN 的自由切换,操作非常简易。
1. Win11 显卡驱动的安装
注意:WSL2中是不需要且不能安装任何显卡驱动的,它的显卡驱动完全依赖于 Win11 中的显卡驱动,因此我们只需要安装你显卡对应的 Win11 版本显卡驱动版本(必须是 Win11 版本的驱动),这个已经有很多教程了,这里就不赘述。如果你安装成功,可以在 Win11 的 cmd 中输入 nvidia-smi可以看到下图。

因为 WSL2 中的显卡驱动完全依赖于 Win11 的显卡驱动,因此在 WSL2 中输入 nvidia-smi 也可以看到相同驱动版本的输出。
请注意:这里的 nvidia-smi 能作用的范围,只作用于你 Win11 安装显卡驱动时所登录的那个用户名对应到 WSL2 中的用户名。比如我是在 Win11 (guosongyuan) 用户上安装的显卡驱动,那么我只能在 WSL2 的 gsy 用户状态下才能执行该 nvidia-smi 指令,root 用户执行该命令是不能生效的。

2. 安装 Docker 和 Nvidia-Docker
- 安装 Docker 引擎可以参考文档:Docker 引擎官方安装教程;
- 安装 Docker 引擎之后,就可以在其基础上安装 Nvidia-Docker 组件:Nvidia-Docker 安装教程。
这两个步骤非常简单,如果看不懂英语的话直接用谷歌翻译就好。
3. 选择合适的 CUDA 和 CUDNN 的镜像
使用 Nvidia-Docker 的好处就在于,你不需要真的在 WSL 中安装 CUDA 和 CUDNN,这样就可以避免在配置不同项目环境时遇到的很麻烦的环境切换问题。我们只要每次遇到一个新的项目,拉取对应的 CUDA 和 CUDNN 版本即可,即插即用,不想用了直接删除对应的镜像和容器即可,跟删除软件一样方便。
这里以安装 CUDA 11.2.0 版本为例,我们来到 Docker 镜像市场:Docker HUB,在其中搜索关键字 nvidia/cuda,如下图。

点进入,在 Tags 中搜索对应的 CUDA 版本,注意同一个版本下对应三种不同的类型(devel、runtime、base),我们推荐安装 devel 版本,因为它的环境更齐全,我们这里因为 WSL2 是 Ubuntu 20.04 版本的,所以我们选择镜像的时候选择 ubuntu20.04 后缀的。
这里以 nvidia/cuda:11.2.0-cudnn8-devel-ubuntu20.04 镜像为例,通过 sudo docker pull nvidia/cuda:11.2.0-cudnn8-devel-ubuntu20.04 将镜像拉取下来。
拉取镜像之后,我们可以查看当前镜像中的显卡驱动、CUDA版本和 CUDNN 的版本。
- 查看显卡驱动版本:
sudo docker run --rm --gpus all nvidia/cuda:11.2.0-cudnn8-devel-ubuntu20.04 nvidia-smi - 查看 CUDA 版本:
sudo docker run --rm --gpus all nvidia/cuda:11.2.0-cudnn8-devel-ubuntu20.04 nvcc -V - 查看 CUDNN 版本,因为镜像官方将 CUDA 和 CUDNN 进行了解耦合,因此我们需要分两步进行查询操作。首先通过
sudo docker run --rm --gpus all nvidia/cuda:11.2.0-cudnn8-devel-ubuntu20.04 whereis cudnn,看到 cudnn.h 所在路径cudnn: /usr/include/cudnn.h。我们根据这个输出结果,把 cudnn.h 之前的 include 路径记住,查询该 include 下的 cudnn_verseion.h 文件:sudo docker run --rm --gpus all nvidia/cuda:11.2.0-cudnn8-devel-ubuntu20.04 cat /usr/include/cudnn_version.h | grep CUDNN_MAJOR -A 2,这样就能看到 CUDNN 的版本号了。

4. 利用拉取的镜像构建自己的镜像
我们拉取的镜像中只有最基础的 CUDA 和 CUDNN,还没有配置 Anaconda、换源、git 、pip 等常用工具,因此我们将这些可能用到的常用工具将其打包好。
为了构建镜像,我们在用户目录下创建一个名为 mkimage 的目录,在其中放入我们需要的三个内容: Anaconda3-5.2.0-Linux-x86_64.sh、Dockerfile、sources.list,其中 sources.list 是用来给 Ubuntu apt 换源用的。
sources.list 内容如下:
######################################
###### CONTENT for sources.list ######
######################################deb http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiversedeb http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiversedeb http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiversedeb http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiversedeb http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse
Dockerfile内容如下:
####################################
###### CONTENT for Dockerfile ######
##################################### Extends from father image [CHANGE WITH YOUR NEED]
FROM nvidia/cuda:11.2.0-cudnn8-devel-ubuntu20.04# Set locale
ENV DEBIAN_FRONTEND noninteractive# Change anaconda source
# ADD means copy file from host machine to containers
ADD sources.list /etc/apt/
ENV PATH /opt/conda/bin:$PATH# Install basic dependencies
RUN rm /etc/apt/sources.list.d/cuda.list && \rm /etc/apt/sources.list.d/nvidia-ml.listRUN apt-get update && apt-get install -y --no-install-recommends \bzip2 \g++ \git \vim \python-dev \python3-pip \build-essential \wget && \rm -rf /var/lib/apt/lists/*# Install Anaconda for python 3.6
ADD Anaconda3-5.2.0-Linux-x86_64.sh /home/anaconda.sh
RUN /bin/bash /home/anaconda.sh -b -p /opt/conda && \ln -s /opt/conda/etc/profile.d/conda.sh /etc/profile.d/conda.sh && \rm /home/anaconda.sh# Change sources for conda, add tsinghua sources and remove defaults
RUN conda config --add channels http://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ && \conda config --add channels http://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/ && \conda config --add channels http://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/ && \conda config --add channels http://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch/ && \conda config --add channels http://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/pro/ && \conda config --remove channels defaults# Change sources for pip3
RUN mkdir ~/.pip && \echo "[global]\nindex-url = http://mirrors.aliyun.com/pypi/simple/\n[install]\ntrusted-host = mirrors.aliyun.com" > ~/.pip/pip.conf# Initialize workspace
RUN mkdir /workspace
WORKDIR /workspaceCMD ["/bin/bash"]
其中,Anaconda3-5.2.0-Linux-x86_64.sh 可以在 Anaconda Archive 中找到。
然后,我们可以通过下列指令制作镜像 my-nvidia/cuda:11.2。
cd ~/mkimage
sudo docker build -f Dockerfile -t my-nvidia/cuda:11.2 .
经过漫长的等待,我们可以看到一个 Successfully 提示消息,证明我们镜像打包成功。

构建完成后,我们可以通过下面这个指令进行容器的创建:
sudo docker run -it --gpus all --name cuda_11.2 my-nvidia/cuda:11.2 /bin/bash
进入容器之后,我们可以通过 nvidia-smi 、nvcc -V 、conda info 查看当前的显卡驱动、CUDA版本和 conda 源信息。
如果使用 conda 安装包的时候出现了conda Malformed version string ‘~’: invalid character(s)报错,可以使用下面的命令更新一下 conda。
conda upgrade -n base -c defaults --override-channels conda
conda update --all
我这里从 PyTorch 官网中下载了一个对应 CUDA 版本的 torch(我创建了一个名为 pytorch 的 conda 虚拟环境),可以看到在容器中 GPU 资源是可以正常被访问的。这样我们以后就可以随时切换 CUDA 版本了,是不是很方便?

相关文章:
WSL2使用Nvidia-Docker实现CUDA版本自由切换
众所周知,深度学习的环境往往非常麻烦,经常不同的项目所依赖的 torch、tensorflow 包对 CUDA 的版本也有不同的要求,Linux 下进行 CUDA 的管理比较麻烦,是一个比较头疼的问题。 随着 WSL2 对物理机显卡的支持,Nvidia-…...
pygame9 扫雷游戏2
一、响应鼠标左键事件 pygame.MOUSEBUTTONDOWN 表示鼠标事件发生, pygame.mouse.get_pressed()[0] 确认是鼠标左键被按下 pygame.mouse.get_pos() 获取到鼠标按下时的坐标值。 因此,我们可以在事件逻辑中例用此三个函数判断鼠标事件及对应的坐标&#x…...
逻辑电路代数运算(上)
逻辑代数L是一个封闭的代数系统,由一个逻辑变量集K,常量0和1,以及与或非三种基本运算构成。 参与逻辑运算的变量叫逻辑变量,用字母A,B……表示。每个变量的取值非0 即1。 0、1不表示数的大小,而是代表两种不…...
Rabbit快速入门
入门案例 需求:使用简单模式完成消息传递 步骤: 创建工程(生成者、消费者) 分别添加依赖 编写生产者发送消息 编写消费者接收消息 3.1.2. 添加依赖 往heima-rabbitmq的pom.xml文件中添加如下依赖: <dependenc…...
【react+ts- forwardRef】
reactts- forwardRef1. 学习资料2. 普通input透传2.1 TS版本2.2 JS版本3. TS-Antd-Form组价透传引用传递(Ref forwading)是一种通过组件向子组件自动传递 引用ref 的技术。对于应用者的大多数组件来说没什么作用。但是对于有些重复使用的组件,…...
计算机网络-- 网络层(day06)
文章目录网络层思维导图IPv4地址的应用规划定长的子网掩码变长的子网掩码VLSMIP数据报的发送和转发过程主机发送IP数据报路由器转发IP数据报静态路由选择动态路由选择路由选择协议概述常见的路由选择协议路由器的基本结构路由信息协议RIP的基本工作原理开放最短路径优先OSPF的基…...
docker 镜像
一、介绍 镜像:是一种轻量级、可执行的独立软件包,它包含运行某个软件所需的所有内容,我们把应用程序和配置依赖打包好形成一个可交付的运行环境(包括代码,运行时需要的库,环境变量和配置文件等)这个打包好的运行环境就是image镜像文件。 只有通过这个镜…...
JUC并发编程与源码分析笔记11-Java对象内存布局和对象头
先从阿里及其它大厂面试题说起 你觉得目前面试,你还有那些方面理解的比较好,我没问到的,我说了juc和jvm以及同步锁机制那先说juc吧,说下aqs的大致流程cas自旋锁,是获取不到锁就一直自旋吗?cas和synchronized区别在哪…...
JavaSE之集合篇
文章目录前言一、集合概述集合继承结构图二、Collection接口中常用方法2.1Collection中存放什么元素?2.2常用方法2.3迭代器三、List接口中常用的方法四、ArrayList初始化容量及扩容五、Vector六、Map接口常用方法七、Properties前言 由于在刷题过程中,经…...
LeetCode分类刷题-----贪心算法
贪心算法贪心455.分发饼干376.摆动序列53.最大子序和122.买卖股票的最佳时机||55.跳跃游戏45.跳跃游戏||1005.K次取反后最大化的数组和134.加油站135.分发糖果860.柠檬水找零406.根据身高重建队列452.用最少数量的箭引爆气球,提供两种解决方案。首先,SiteWhere 的社区版 (CE) 是在 CPAL 许可下提供的。对于此解…...
【unity】rts engine 6 放置并建造建筑;
一 放置并建造建筑 GameManager -> Essential -> BuildingExtension 查看 building placement building position y offset Y轴偏移,建筑离地距离,可0.1 terrain max distance 放置建筑与允许地形的最大距离,可1 placable terrain …...
华为OD机试题 - 任务调度(JavaScript)| 含思路
更多题库,搜索引擎搜 梦想橡皮擦华为OD 👑👑👑 更多华为OD题库,搜 梦想橡皮擦 华为OD 👑👑👑 更多华为机考题库,搜 梦想橡皮擦华为OD 👑👑👑 华为OD机试题 最近更新的博客使用说明本篇题解: 任务调度题目输入输出描述示例一输入输出Code解题思路华为OD其…...
《Spring源码深度分析》第4章 自定义标签的解析
目录标题前言一、自定义标签使用二、自定义标签解析1、代码入口2、parseCustomElement【BeanDefinitionParserDelegate】2.1 resolve【DefaultNamespaceHandlerResolver】3、parse【NamespaceHandlerSupport】4、parse【AbstractBeanDefinitionParser】4.1 parseInternal【Abst…...
MATLAB绘制椭圆形相关系矩阵图
数据/代码准备 数据及代码下载: 下载专区-《MATLAB统计分析与应用:40个案例分析》程序与数据 绘图函数: matrixplot(data, PARAM1,val1, PARAM2,val2, ...) 案例 数据如下: MATLAB代码如下: clc close all clear …...
「SQL面试题库」 No_1 员工薪水中位数
🍅 1、专栏介绍 「SQL面试题库」是由 不是西红柿 发起,全员免费参与的SQL学习活动。我每天发布1道SQL面试真题,从简单到困难,涵盖所有SQL知识点,我敢保证只要做完这100道题,不仅能轻松搞定面试ÿ…...
Python机器学习17——极限学习机(ELM)
本系列基本不讲数学原理,只从代码角度去让读者们利用最简洁的Python代码实现机器学习方法。 背景: 极限学习机(ELM)也是学术界常用的一种机器学习算法,严格来说它应该属于神经网络,应该属于深度学习栏目,但是我这里把它…...
二分查找与判定树
二分查找的算法思想二分查找也称“折半查找”,要求查找表为采用顺序存储结构的有序表。本例一律采用升序排列。二分查找每一次都会比较给定值与序列[low,high]的中间元素,该元素的下标为mid (lowhigh)/2,若两者相等,则返回元素的下标为mid;如…...
反转链表(精美图示详解哦)
全文目录引言反转链表题目描述与思路实现总结引言 在学习了单链表的相关知识后,尝试实现一些题目可以帮助我们更好的理解单链表的结构以及对其的使用。 从这篇文章开始,将会介绍一些编程题来帮助我们更好的掌握单链表: 分别是反转链表、链表…...
深入理解多线程
一、线程基本概念 1、概述 线程是允许应用程序并发的一种机制。线程共享进程内的所有资源。 线程是调度的基本单位。 每个线程都有自己的 errno。 所有 pthread 函数均以返回 0 表示成功,返回一个正值表示失败。 编译 pthread 程序需要添加链接库(…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...
基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...
(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...
家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...
linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...
全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...
