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 程序需要添加链接库(…...
XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...
2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...
Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换
目录 关键点 技术实现1 技术实现2 摘要: 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式(自动驾驶、人工驾驶、远程驾驶、主动安全),并通过实时消息推送更新车…...
为什么要创建 Vue 实例
核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...
