ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

PyCharm+PyTorch+CUDA环境搭建:GPU不可用排查与验证

PyCharm+PyTorch+CUDA环境搭建:GPU不可用排查与验证 显卡插上、驱动也装好了nvidia-smi能正常出画面结果在 PyCharm 里敲下import torch再跟一句torch.cuda.is_available()回车返回一个False——这个瞬间大概是所有做深度学习的朋友都经历过的。更气人的是同样这几行代码在另一个同学机器上、甚至在你自己的另一个 conda 环境里跑得好好的。问题往往不出在 PyTorch 本身而出在前面那几步驱动版本、CUDA 运行时版本、PyTorch wheel 的编译版本、Python 解释器版本这四个东西只要有一个错位GPU 就用不上。这篇内容就是把这四个东西的对应关系捋清楚然后从零走一遍 PyCharm CUDA PyTorch 的完整搭建流程包括怎么根据自己显卡驱动反推该装哪个 CUDA 版本的 PyTorch、conda 环境怎么建、--index-url该写什么、怎么验证 GPU 真的被调用了、PyCharm 的解释器和终端为什么会打架、以及下载中断报invalid compressed data这类让人抓狂的问题怎么收尾。适合刚拿到带独显机器的同学也适合从别的框架转过来、想一次把环境理顺的人。1. 版本这盘棋先摆正驱动、CUDA、PyTorch 三者的依赖不是装最新就行很多人装机失败的第一步是默认版本越新越好。显卡驱动装最新的、CUDA Toolkit 下最新的、PyTorch 也 pip 装最新的看起来很合理实际上这三者的依赖方向是单向的PyTorch 的 wheel 决定了它需要哪个 CUDA 运行时CUDA 运行时又决定了它最低需要哪个驱动。你反过来硬凑就会出现 wheel 里内嵌的 CUDA 运行时比驱动支持的版本还高加载时直接报CUDA driver version is insufficient for CUDA runtime version。1.1 nvidia-smi 右上角那行 CUDA Version说的是驱动能力上限先跑一条命令nvidia-smi输出右上角会有一行CUDA Version: 12.4之类的字样。这里有个极容易被误读的点这行不是你装了 CUDA 12.4而是你当前这个驱动最高能支撑到 CUDA 12.4 的运行时。也就是说它是个上限值不是已安装值。你去which nvcc可能什么都找不到但nvidia-smi一样显示 CUDA Version这不矛盾。Linux 上还可以再交叉验证一下驱动本身的版本cat /proc/driver/nvidia/versionWindows 上则去 NVIDIA 控制面板的系统信息里看驱动版本号。把这个数字记下来后面选 PyTorch 版本时全靠它。1.2 同大版本内的次版本兼容到底能省多少事CUDA 从 11 开始引入了次版本兼容Minor Version Compatibility的概念同一个大版本号内低版本驱动可以运行高次版本的 CUDA 运行时。翻译成人话就是你的驱动只要支持 CUDA 12.0原则上就能跑 12.1、12.4 甚至 12.6 的运行时不需要为了每一个次版本去换驱动。但这条规则有边界别当成万能护身符只保证跑得起来不保证性能曲线和官方文档完全一致个别依赖新驱动特性的库仍可能出问题跨大版本比如驱动只支持 11.x你却要跑 12.x 的运行时不适用会直接报错如果 wheel 里带了 PTX 需要即时编译的算子旧驱动可能无法 JIT 出目标架构的代码。所以实操建议是驱动装到比目标 CUDA 大版本的最新次版本略微高一档的位置留点余量。比如你打算用 CUDA 12.4 的 PyTorch驱动版本尽量选 550 以上别卡在及格线上。1.3 一张能直接抄的版本对照表下面这张表是我自己装机时整理的常用搭配覆盖近两年主流版本。注意 PyTorch 官方的pip索引后缀cu118、cu121这种就等于它内嵌的 CUDA 运行时版本。PyTorch 版本可选 CUDA 后缀建议驱动版本下限支持的 Python 区间2.0 / 2.1cu117 / cu118 / cu121450 / 5203.8 – 3.112.2 / 2.3cu118 / cu1215203.8 – 3.122.4 / 2.5cu118 / cu121 / cu124550用 cu124 时3.9 – 3.122.6cu118 / cu124 / cu126560用 cu126 时3.9 – 3.132.7cu118 / cu126 / cu128570用 cu128 时3.9 – 3.132.8cu126 / cu128 / cu1295703.10 – 3.13注意这张表是为了让你快速定位真正下单前一定去 PyTorch 官网首页的 Get Started 选择器上核一遍。官方选择器会同时给出 conda 和 pip 两条命令并且只列出当前版本真实存在的后缀组合比自己猜靠谱。还有一个绝大多数教程没讲清楚、但极其关键的点用 pip 装 PyTorch你不需要单独安装 CUDA Toolkit也不需要单独装 cuDNN。wheel 包里已经把对应的 CUDA 运行时库和 cuDNN 一起打进去了。很多人上来先下几个 GB 的 CUDA Toolkit 安装包装完发现 PyTorch 那边一个字节都没用上——白折腾。什么时候才需要完整的 Toolkit只有你要编译自定义 CUDA 算子、或者装flash-attn、deepsparse这类需要本地 nvcc 的包时才需要。普通训练推理跳过。2. 底座环境怎么铺Python 解释器、虚拟环境与下载通道版本配对之后接下来是环境本身。这一步的坑不在技术难度而在图省事。2.1 别在系统 Python 上装 torch这是我踩过最贵的一个坑我早期做过一件蠢事直接在系统的 Python 3.9 上pip install torch当时能跑后来要换一个 CUDA 版本pip uninstall又卸不干净最后系统里一堆半残的包某个 CLI 工具直接起不来重装系统才彻底解决。正确做法是永远用独立虚拟环境。理由不只是干净还有三条很实际的版本隔离项目 A 要 CUDA 11.8 的 torch项目 B 要用 CUDA 12.4 的同一个解释器里不可能共存虚拟环境天然解决可复现换机器时导出环境文件就能重建不用回忆当初装了什么可整包删除出问题了直接conda env remove删目录不留任何后遗症。2.2 conda 建环境的具体命令与目录规划我的习惯是把所有环境集中放在一个明确目录下不要让它散落在用户目录里找不着。以 Windows 为例Anaconda 默认装在D:\Anaconda3环境目录就是D:\Anaconda3\envs。# 建环境Python 版本对齐 PyTorch 的支持区间 conda create -n torch24 python3.11 -y # 激活Windows 用 conda activate若报错需要先 conda init conda activate torch24 # 确认当前用的是哪个 python这一步千万别省 python -c import sys; print(sys.executable)最后那条命令是整个流程里最值钱的一条。后面 PyCharm 里配解释器路径就是它打印出来的这个东西。没有意外的话会输出类似D:\Anaconda3\envs\torch24\python.exe的路径。Linux 和 macOS 上命令一致环境目录通常在~/miniconda3/envs/或~/anaconda3/envs/用conda info --envs能看到所有环境及其绝对路径。如果你不喜欢 conda用标准库自带的 venv 也完全可行python -m venv D:\venvs\torch24 D:\venvs\torch24\Scripts\activatevenv 的优点是轻缺点是装某些科学计算包时要自己处理编译依赖而且没法像 conda 那样顺带装非 Python 的二进制品。做深度学习我还是推荐 conda。2.3 下载通道镜像源、缓存目录与超时重试PyTorch 的 wheel 动辄两三个 GB网络通道直接决定你这一步是十分钟还是两小时。我一般做三件事。第一给 conda 配国内镜像源改~/.condarcWindows 是C:\Users\你的用户名\.condarcchannels: - defaults show_channel_urls: true default_channels: - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r第二pip 用-i临时指定源而不是全局改配置。因为 PyTorch 官方 wheel 只在自己的索引上有全局改了源之后装 torch 又要绕回来容易搞混# 装普通包时走镜像 pip install numpy pandas -i https://pypi.tuna.tsinghua.edu.cn/simple # 装 torch 时明确走官方索引 pip install torch --index-url https://download.pytorch.org/whl/cu121第三把 pip 缓存目录设在空间充足的盘上避免 C 盘被几个 GB 的 wheel 撑爆pip config set global.cache-dir D:\pipcache提示如果下载过程中频繁超时加--timeout 120 --retries 5。这两个参数看着不起眼但在跨国链路里能把重来三次变成一次过。3. 装 PyTorch 的实操索引地址、wheel 选择与离线兜底环境准备好了真正动手装 torch。这一步最常见的结果是装上了但装错了——装成 CPU 版用的时候才发现。3.1--index-url指向哪里决定了你拿到的是 GPU 版还是 CPU 版PyTorch 的包分发机制很特殊PyPI 官方仓库上的torch默认是 CPU 版本。你如果只敲pip install torch在多数平台上下到的就是 CPU 版装完torch.cuda.is_available()必然是False而且一点报错都不会有非常隐蔽。要拿 GPU 版必须显式指定 PyTorch 自己的索引# CUDA 12.1 pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121 # CUDA 11.8 pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 # CUDA 12.4 pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124 # 纯 CPU没独显或只需要跑推理 pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cputorchvision和torchaudio的版本是跟torch绑死的三个必须一起装、一起升、一起降。我见过太多次单独pip install -U torchvision导致版本不匹配报RuntimeError: operator torchvision::nms does not exist的案例。要么三个一起走要么别动。3.2 从 wheel 文件名反推它是不是你要的那个下载时可加-v看进度详情或者直接看 pip 缓存里的 wheel 文件名。一个典型的文件名长这样torch-2.4.1cu124-cp311-cp311-win_amd64.whl拆开读torch-2.4.1—— PyTorch 版本cu124—— 内嵌 CUDA 12.4 运行时。如果这里没有cuXXX后缀就是 CPU 版cp311—— 对应 CPython 3.11。你如果是 3.12 的环境下到了cp311的包说明索引里的 Python 版本对应关系搞错了win_amd64—— Windows 64 位。Linux 上是manylinux_x86_64。记住这个命名规则你就再也不会被我到底装的是哪个版本困扰了。装完之后用一条命令复核import torch print(torch.__version__) # 2.4.1cu124 print(torch.version.cuda) # 12.4 print(torch.backends.cudnn.version()) # 例如 901003.3 下载中断报 invalid compressed data 的完整处理链路这个报错原文是gzip: stdin: invalid compressed># 只下载不安装把依赖包一起下到本地目录 pip download torch torchvision torchaudio \ --index-url https://download.pytorch.org/whl/cu121 \ -d D:\wheels然后把整个D:\wheels拷到目标机器离线安装pip install --no-index --find-linksD:\wheels torch torchvision torchaudio--no-index是关键它强制 pip 不去访问任何在线索引避免内网环境下卡在超时上。另外pip download时要保证下载机器的 Python 版本和位数跟目标机器完全一致否则下到的 wheel 标签对不上装的时候会提示 not a supported wheel on this platform。4. 装完必须验收让 GPU 真正跑起来的几个检查点装完不验证等于没装。我见过太多人在 PyCharm 里跑了一个月才发现自己一直在用 CPU只是代码里没打印过设备信息。4.1 is_available() 返回 False 的排查顺序先跑一个最小脚本import torch print(torch:, torch.__version__) print(cuda build:, torch.version.cuda) print(available:, torch.cuda.is_available()) print(count:, torch.cuda.device_count())如果available是False按下面这个顺序查别乱试检查项命令/方法判断依据是不是 CPU 版 wheel看torch.__version__有没有cuXXX没有后缀就是 CPU 版重装驱动是否正常nvidia-smi报错或看不到设备先修驱动驱动版本是否够对比第 1 节的版本表低于下限就升驱动环境里是否装了多份 torchpip list | findstr torch出现重复来源要清干净重装是否被环境变量屏蔽看CUDA_VISIBLE_DEVICES值被设成-1或空会导致不可见是不是 conda 装的 cudatoolkit 混进来了conda list | grep cudaconda 渠道和 pip 渠道别混着装第三条和第六条是最常见的两个隐形杀手。特别是混装有人先conda install pytorch cudatoolkit11.8后来又pip install torch两套东西在同一个环境里各占一半报错信息往往指向一个莫名其妙的 DLL 找不到。4.2 用一次矩阵乘法给显卡打卡is_available()为 True 只是说明驱动和运行时握手成功不代表计算真的落在 GPU 上。加一步实测import torch import time dev torch.device(cuda:0) a torch.randn(4096, 4096, devicedev) b torch.randn(4096, 4096, devicedev) torch.cuda.synchronize() # 等前面的 kernel 排空 t0 time.time() for _ in range(20): c a b torch.cuda.synchronize() # 关键不同步的话计时会把异步执行算成 0 秒 t1 time.time() print(elapsed:, round(t1 - t0, 3), s) print(device:, torch.cuda.get_device_name(0))这里的torch.cuda.synchronize()是个必须提的点CUDA 的 kernel 是异步下发的CPU 把任务丢进队列就返回了。你不加同步计时结果可能只有零点几毫秒看起来快得离谱其实是没算完。这个坑在做性能对比时特别容易踩。4.3 顺便把显存、算力和设备编号也记下来print(显存(GB):, torch.cuda.get_device_properties(0).total_memory / 1024**3) print(算力:, torch.cuda.get_device_capability(0)) # 例如 (8, 6) print(设备数:, torch.cuda.device_count())算力这个值Compute Capability后面会用到。它是显卡的硬件代号比如 8.6 对应 RTX 30 系、8.9 对应 RTX 40 系、12.0 对应更新的架构。PyTorch 的 wheel 里预编译了针对特定算力的 kernel如果你的卡算力很新而 wheel 编译时还没覆盖就可能出现 kernel 找不到、只能退回慢速路径的情况。这也是为什么新卡往往要用更新的 PyTorch 版本。顺便说一句nvcc --version显示的版本和torch.version.cuda不一致是完全正常的前者是你系统里可能装的 Toolkit 编译器版本后者是 wheel 内嵌的运行时版本。用 pip 装 torch 的场景下两者本来就不需要一致别为此去返工。5. PyCharm 侧收尾解释器、终端和运行配置里的隐形错位前面所有步骤都在命令行里做的PyCharm 这一层是很多人命令行明明可以PyCharm 里就是不行的根源。5.1 解释器路径选错前面全白干PyCharm 打开项目后第一件事是配解释器File → Settings → Project: 项目名 → Python Interpreter → Add Interpreter → Add Local Interpreter → Conda Environment → Existing environment然后手动指到第 2.2 节打印出来的那个python.exe。有个细节值得强调PyCharm 有时会自作聪明地推荐新建一个环境。如果你已经用命令行建好并装好了 torch就一定要选Existing environment不要让它新建——新建出来的环境是干净的torch 得重装一遍。我自己就中过招配完发现is_available()是 False来回查了半天版本最后发现是 PyCharm 悄悄建了个新环境。配好之后立刻在 PyCharm 底部的 Python Console 里跑一遍import sys, torch print(sys.executable) print(torch.__version__, torch.cuda.is_available())第一行输出的路径必须跟你在 Settings 里选的一致。不一致说明 PyCharm 用的还是别的解释器。5.2 PyCharm 的 Terminal 和 Run 用的可能不是同一个 Python这是最隐蔽的一类问题PyCharm 内置 TerminalAltF12 打开的那个默认会尝试激活当前项目的虚拟环境但这个激活行为在 Windows 上经常因为执行策略或者 shell 类型而失效。失效的表现是你在 Terminal 里pip install torch装到了 base 环境然后点 Run 按钮运行脚本用的却是项目环境——于是我明明装了怎么还是报 ModuleNotFoundError。处理办法在Settings → Tools → Terminal里确认Activate virtualenv是勾选状态打开 Terminal 第一件事永远是敲where pythonWindows或which pythonmacOS/Linux确认路径如果 Terminal 死活不激活就直接用绝对路径调用D:\Anaconda3\envs\torch24\Scripts\pip.exe install ...。提示装包这件事我更推荐统一在外部终端里做做完回 PyCharm 里跑代码。因为 PyCharm 的包管理界面在做大版本替换比如 torch 从 CPU 版换成 GPU 版时偶尔会出现卸载不干净的情况。5.3 运行配置里的工作目录与环境变量Run → Edit Configurations里有两个常被忽略的字段。Working directory默认是项目根目录这决定了代码里相对路径的基准。如果你的数据集路径写的是./data/train而工作目录被改到了别处就会报文件找不到。做深度学习项目时我习惯在代码里统一用Path(__file__).parent来定位资源不依赖工作目录换到哪台机器都不会错。Environment variables多卡机器上必用。指定只用第 0 号卡CUDA_VISIBLE_DEVICES0或者只用第 2、3 号卡CUDA_VISIBLE_DEVICES2,3注意这个变量是在进程启动前生效的代码运行中再改没用。另外设完之后程序里看到的卡号会被重新编号原来的 2 号卡会变成cuda:0这点在写多卡代码时容易搞混。还有一处细节PyCharm 的 Python Console 每次启动都会新开一个解释器进程如果你在 Console 里import torch之后发现显存被占着那不是内存泄漏是 Console 进程还在。关掉 Console 标签或者点停止按钮就行。5.4 几个高频报错VC 14.0、DLL load failed、cuDNN 相关下面这几个报错我在不同机器上都遇到过按报错原文整理一下处理思路。error: Microsoft Visual C 14.0 is required—— 这个通常出现在 pip 找不到预编译 wheel、转而尝试从源码编译时。Windows 上的解法有两条一是确认下的 wheel 标签匹配win_amd64 正确cpXXX能命中预编译包就不会触发编译二是确实需要编译时装 Visual Studio Build Tools勾选 使用 C 的桌面开发 工作负载装完重启终端。优先走第一条路编译一遍 torch 源码动辄半小时起步没必要。OSError: [WinError 126] 找不到指定的模块或DLL load failed—— 十有八九是环境里混了多个来源的 torch或者缺了某个运行库。先pip list看有没有重复条目conda list也看一遍确认只有一个来源然后彻底卸干净重装pip uninstall torch torchvision torchaudio -y pip cache purge pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121cuDNN 相关的版本警告—— 如果报的是 cuDNN 版本不匹配先用torch.backends.cudnn.version()看 wheel 内嵌的版本再确认自己没有手动装过一个不同版本的 cuDNN 并且把它加进了 PATH。两者冲突时以 wheel 内嵌的为准别去动它。out of memory但显存看着还剩不少—— 常见原因是碎片化加上一次性申请大块连续显存。可以先torch.cuda.empty_cache()再降低 batch size如果模型本身大用梯度累积把等效 batch 凑回来比直接砍 batch 更划算。6. 多环境共存与换机迁移别让第二台机器重来一遍单个环境搭好只是开始。真正消耗时间的是第二台机器、第三个项目、第四个 CUDA 版本。6.1 单机多套 CUDA 时路径优先级怎么排用 pip 装 torch 的话即使不装 Toolkit 也能跑训练所以多版本共存的问题其实没那么严重——每个虚拟环境里的 torch 自带自己那份运行时互不干扰。这是虚拟环境最大的价值之一。但如果你需要编译自定义算子就绕不开CUDA_HOME/CUDA_PATH这个环境变量。规则是Linux 上编译器找的是CUDA_HOME指向目录下的bin/nvcc同时动态库搜索路径由LD_LIBRARY_PATH或/etc/ld.so.conf.d/下的配置决定Windows 上CUDA_PATH决定默认版本PATH 里靠前的bin目录会覆盖靠后的多个版本共存时不要把它们都塞进全局 PATH而是按项目在虚拟环境激活脚本里临时设置conda activate torch24 export CUDA_HOME/usr/local/cuda-12.4 export PATH$CUDA_HOME/bin:$PATH这样切换环境时nvcc会自动跟着换比全局改 PATH 干净得多。6.2 环境导出与换机复现的清单导出环境我一般同时留两份因为单独一份都不够# 含构建号的完整导出同架构复现最准 conda env export environment.yml # 不含构建号跨平台兼容性更好 conda env export --no-builds environment-nobuilds.yml # pip 层级的精确版本 pip freeze requirements.txtenvironment.yml里带上--no-builds那份更适合换机因为构建号跟具体的操作系统和平台强绑定带上了在另一台机器上大概率解析失败。重建时conda env create -f environment-nobuilds.yml # 或者只重建 Python 环境再按 requirements 装包 pip install -r requirements.txt --index-url https://download.pytorch.org/whl/cu121除了环境文件我还会在一个SETUP.md里记三样东西nvidia-smi的完整输出、torch.__version__与torch.version.cuda、以及显卡的 Compute Capability。这三行信息一旦留档半年后回来重装环境能省下大半天。6.3 新显卡的算力代差问题最后一件事关于新卡。显卡架构的更新速度比 PyTorch 的发布节奏快新架构刚上市时老版本的 PyTorch wheel 里可能没有针对它预编译的 kernel。表现是能跑但速度明显不对或者某些算子在运行时报找不到实现。处理办法很直接换用更新的 PyTorch 版本配更新的 CUDA 后缀。比如 50 系显卡对应的算力代号较高需要较新的 CUDA 12.8 这一档的 wheel 才能完整覆盖。如果你已经装好了但想确认覆盖情况可以跑一个小测试把常见算子过一遍import torch x torch.randn(1024, 1024, devicecuda) _ x x.t() _ torch.nn.functional.conv2d( x.view(1, 1, 1024, 1024), torch.randn(1, 1, 3, 3, devicecuda) ) _ torch.nn.functional.softmax(x, dim-1) torch.cuda.synchronize() print(ops ok, capability:, torch.cuda.get_device_capability(0))没有异常抛出基本可以认为常用路径都能正常走通。我个人在实际操作中的体会是这套流程里最值钱的不是任何一条命令而是先确定版本再动手装这个顺序。绝大多数的环境问题本质都是版本错配而版本错配的根源是跳过了nvidia-smi那一步直接开始下安装包。把第 1 节那张表和自己机器的实际情况对一遍后面所有的命令都会顺得像走直线。另外补一句requirements.txt里记得把--index-url那一行也写进去或者单独写个安装脚本不然过几个月你自己都会忘记当初是从哪个索引装的 GPU 版。
返回列表