ARTICLE DETAIL

资讯详情

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

Anaconda+PyCharm+PyTorch GPU环境搭建避坑指南

Anaconda+PyCharm+PyTorch GPU环境搭建避坑指南 1. 为什么这套组合能成为深度学习入门的默认答案几乎每个刚进这个圈子的人第一次装环境都会撞上 Anaconda、PyCharm、PyTorch 这三个名字。看起来是三个独立的东西实际上它们各自解决的是完全不同层次的问题拼在一起刚好凑成一条从管理依赖到写代码再到跑模型的完整链路。先说结论这套组合不是唯一解但它对新手的容错率最高出错之后能查到答案的概率也最大这一点在深度学习的头三个月里比什么都重要。我把这套东西推荐给别人的时候从来不说它最好我只说它最省心。conda 帮你把 Python 解释器和一堆科学计算库捆成一个可扔可换的独立环境PyCharm 给你一个能跳转定义、能调试、能看变量、能管多环境的代码编辑器PyTorch 则是真正干活的框架。GPU 版本的意义在于把矩阵运算从 CPU 挪到显卡上几十倍的加速是常态。这篇内容面向三类人完全没搭过深度学习环境的纯新手、以前用 CPU 版本跑过小模型现在想上显卡的人、以及环境莫名其妙崩了想重新来一遍的人。我会把每一步为什么这么做讲清楚也会把那些官方文档不会提、但实际操作中必然会撞上的坑全部摊开说。1.1 Anaconda、PyCharm、PyTorch 各自在做什么很多人一开始分不清这三者的边界导致装完也不知道自己在装什么。用一句话掰开Anaconda 是环境与依赖管理器PyCharm 是代码编辑器PyTorch 是计算框架。它们之间没有强绑定关系你完全可以用 conda 管环境、用 VS Code 写代码、用 PyTorch 跑模型跑得好好的。Anaconda 的核心价值不是它预装了 NumPy、Pandas、Matplotlib 这些包而是 conda 这套环境隔离机制。深度学习项目对版本极度敏感一个项目要 PyTorch 1.12 配 Python 3.8另一个项目要 PyTorch 2.3 配 Python 3.11如果没有环境隔离你只能在卸载重装之间反复横跳。conda 让你为每个项目建一个独立目录互不干扰删掉整个文件夹就等于把这个环境彻底清除不留任何残留。PyCharm 的价值在于工程化。当你从写个脚本试试进化到维护一个几十个文件的项目时代码补全、跳转、重构、断点调试、Git 集成这些东西会成倍提升效率。它对 conda 环境的识别做得比较顺配置一次之后基本不用再管。写深度学习代码时经常要盯着一堆张量的形状PyCharm 的变量查看器能直接展开张量结构这个体验比在终端里 print 强太多。PyTorch 则是真正决定你能跑什么模型的那个东西。它的动态图机制让调试变得直观代码执行到哪一步出错一眼就能看出来这也是它在研究圈子里快速铺开的原因。而 GPU 版本和 CPU 版本的区别本质上就是同一个框架链接了不同的底层计算库。1.2 GPU 版和 CPU 版的实际差距到底有多大我拿一个具体的场景说明。训练一个中等规模的卷积网络在 CPU 上跑一个 epoch 要 8 分钟换到一块主流的中端显卡上同一个 epoch 大概 20 秒到 40 秒。整整一个数量级的差距意味着你在 CPU 上需要跑一整夜的实验在 GPU 上喝两杯咖啡就出结果了。这种差距会直接改变你的学习方式——你会更愿意尝试不同的超参数因为试错成本低。不过也要泼一盆冷水不是所有任务都吃 GPU。小规模的全连接网络、数据量几千条的表格任务、大量依赖 Python 循环的预处理逻辑这些场景下 GPU 的加速比可能只有一两倍甚至因为数据传输开销反而更慢。数据从内存搬到显存是有成本的如果计算量不够大搬运的时间就白白浪费了。判断标准很粗糙但很实用如果你的模型里主要是矩阵乘法、卷积、注意力计算且数据量在万级以上那就值得上 GPU。如果只是跑跑 sklearn 那种算法或者模型参数量只有几万那 CPU 版本完全够用装 GPU 环境纯粹是给自己找麻烦。还有一个容易被忽略的点GPU 版本的环境体积会大很多。CPU 版的 PyTorch 安装包大概两三百 MBGPU 版加上 CUDA 运行库和 cuDNN轻松上到 2GB 以上。下载慢、占硬盘这是实实在在的成本。1.3 你的机器值不值得折腾 GPU 环境动手之前先花三分钟确认硬件条件能省掉后面几个小时的无效折腾。需要确认的就三件事显卡是不是 NVIDIA 的独立显卡AMD 和 Intel 的核显在 PyTorch 生态里支持度完全不同走的是另一套路径不在这次讨论范围内显存有多大4GB 是能跑起来的最低门槛6GB 算舒适8GB 以上做大部分入门到中阶任务都没问题系统是 Windows 还是 Linux两者的坑点分布不一样Windows 上更多是路径和 DLL 的问题Linux 上更多是权限和驱动的问题。如果你用的是笔记本还要额外注意一点带独显的笔记本通常有核显和独显两块显卡系统默认可能把 Python 进程分配给核显。这时候需要到显卡控制面板里把 Python 解释器和 PyCharm 都手动指定为使用高性能独显。这个设置不做的结果就是你环境装得好好的torch.cuda.is_available()也返回 True但一看任务管理器显卡占用一直是 0计算全在核显上磨蹭。还有一种情况值得提前说如果你的机器显存只有 2GB 或者显卡非常老与其硬上 GPU 环境不如老老实实用 CPU 版本把算法逻辑跑通。环境搭不通带来的挫败感比训练慢十分钟严重得多很多人就是在这一步放弃的。2. 动手之前的硬件与版本盘点环境搭建失败的原因里超过一半是版本没对上。这不是危言耸听驱动版本、CUDA 版本、PyTorch 版本、Python 版本这四个东西之间存在硬性的依赖关系任何一个错位都会导致装了跑不起来或者跑起来偷偷退回 CPU 计算。这一章把版本关系彻底捋清楚后面装的时候就能一次成功。我先讲一个几乎所有人都会搞混的概念。你敲nvidia-smi看到的那行 CUDA Version: 12.4说的不是你机器上装了 CUDA 12.4而是你的驱动最高能支持到 CUDA 12.4 的运行时。你实际安装的 CUDA 工具包版本可能是 11.8两者完全不冲突也不需要一致。这个误解导致很多人拼命去官网下载 CUDA 安装包其实对 PyTorch 来说根本没必要。2.1 三步确认显卡和驱动状态在 Windows 上按 WinR 输入 cmd或者直接打开 Anaconda Prompt依次执行三个命令。第一步看驱动和显卡基本信息nvidia-smi正常情况下会输出一个表格包含驱动版本号、CUDA 支持版本、显卡型号、当前显存占用等。如果这个命令提示不是内部或外部命令说明显卡驱动没装或者装得不对这时候别急着装 PyTorch先去官网把驱动装上再说。如果表格能出来但看不到进程信息那是权限问题用管理员身份重开终端就行。第二步看 CUDA 工具包情况nvcc --version这个命令如果报错不用慌说明你没单独装 CUDA Toolkit这在 conda 安装路线下是完全正常的。因为 conda 安装 PyTorch 时会自动把需要的 CUDA 运行库作为依赖装进环境里你不需要在系统层面单独装一套。这恰恰是 conda 路线比 pip 路线省心的地方。第三步在系统信息里确认显卡型号和显存。Windows 上可以用dxdiagLinux 上用lspci | grep -i nvidia。重点记住显存大小后面装模型和调 batch size 都要参考这个数。提示三条命令里nvidia-smi是最关键的一条。它不通后面的步骤全部没有意义先把驱动问题解决掉。2.2 驱动、CUDA、PyTorch 三者的版本对应关系这层关系用一句话概括PyTorch 官方为特定的 CUDA 版本编译了预构建包你的驱动版本必须不低于这个 CUDA 版本所要求的最低驱动。注意是不低于高版本驱动可以向下兼容低版本的 CUDA 运行时。举个具体的例子。当前主流的几个组合大致是这样的CUDA 11.8 需要驱动版本 450.80.02 以上CUDA 12.1 需要 525.60.13 以上CUDA 12.4 需要 550.54.14 以上。只看大版本号基本不会错驱动是 5xx 系列的11.8 和 12.x 都能跑驱动还是 4xx 系列的就只能选 11.8 或者更早的 CUDA 版本。实际选择的时候我的建议是跟着 PyTorch 官网给的命令走不要自己拍脑袋选 CUDA 版本。打开 PyTorch 官网的安装页面上面有个下拉框让你选 PyTorch 版本、操作系统、包管理工具、计算平台选完之后它直接给你一行命令。这行命令就是经过官方验证的组合照着敲就行比自己算版本号靠谱一万倍。有一个坑必须单独拎出来说conda 和 pip 安装的包来源不同。conda 走的是pytorch和nvidia这两个 channelpip 走的是download.pytorch.org的 whl 索引。这两条路装的包在文件结构上有差异混着装很容易出现DLL load failed这类玄学错误。一旦决定用 conda整个环境里的 torch 相关包就都用 conda 装决定用 pip就都用 pip。2.3 Anaconda 与 PyCharm 的版本选择Anaconda 的版本更新比较快但说实话对普通用户而言用哪个版本差别不大因为它主要提供的是 conda 这个包管理器。下载的时候去官网选对应操作系统的安装包Windows 上选 64 位版本Linux 上选 shell 脚本版本。安装时有一个选项值得特别注意Add Anaconda to my PATH environment variable。官方默认是不勾选的理由是这样可以和系统里其他 Python 冲突。但实际使用中不勾选的话你就必须通过 Anaconda Prompt 来使用 conda 命令普通终端里敲 conda 会找不到命令。我的建议是勾上同时在安装前确认系统里没有其他 Python 需要共存能省掉不少麻烦。至于 PyCharm社区版免费且功能已经足够写深度学习代码专业版多了远程开发、数据库工具、科学模式这些功能。初学者用社区版完全没有问题后面如果需要在服务器上跑代码再考虑升级。安装过程中会问你一些偏好设置比如是否创建桌面快捷方式、是否关联 .py 文件这些按自己的习惯来就行。装 Anaconda 的时间会比你预期长尤其是机械硬盘上解压几万个小文件可能要十几分钟。这期间不要手贱去点取消装到一半中断会导致环境残缺后面排查起来非常痛苦。3. 用 Conda 建一个干净的 PyTorch GPU 环境准备工作做完正式进入安装环节。这一章的命令我是逐条拆开讲的包括每个参数的含义这样你后面出问题的时候能自己判断该改哪里而不是机械地复制粘贴。我见过太多人所有项目都装在 base 环境里装了半年之后 base 里堆了七十多个包某天更新一个包把另一个项目搞崩了然后整个人都懵了。这种事故完全可以通过环境隔离避免而建一个独立环境只多花三分钟。3.1 为什么不建议在 base 里装东西base 是 conda 的根环境里面装着 conda 自己运行所需的核心依赖。你可以把它理解成操作系统的系统盘能不动就不动。一旦在 base 里装了大量项目依赖会出现几个后果conda 自身的升级可能被依赖冲突挡住导致你连 conda 都用不了不同项目的依赖互相牵扯装 A 项目要降级的包会把 B 项目跑得好好的版本覆盖掉环境出问题后无法直接删除重建因为 base 删了整个 conda 就废了。独立环境的好处是它就是一个普通文件夹路径在 Anaconda 安装目录的envs下面。环境崩了直接conda remove -n 环境名 --all删掉重建五分钟的事不影响任何其他东西。这个操作可逆性是它最大的价值。命名上也有讲究。别用test、myenv这种没信息量的名字过两个月你自己都忘了里面装的是什么。用pt2-gpu、yolo-train、nlp-exp这类能看出用途和关键版本的名字以后conda env list一眼就能认出来。3.2 创建环境与安装命令逐行拆解先创建环境。PyTorch 2.x 系列建议配 Python 3.9 到 3.11我一般用 3.10兼容性最好conda create -n pt2-gpu python3.10这条命令拆开看create是动作-n pt2-gpu指定环境名叫 pt2-gpu-n是--name的缩写python3.10指定要装的 Python 版本。conda 会自动解析出一批待安装的包列出来问你确认敲y回车。创建完之后激活它conda activate pt2-gpu激活成功的标志是命令行提示符前面多了一对括号里面是你的环境名。Windows 上如果提示 CommandNotFoundError说明你的终端没有做 conda 初始化解决方案是执行conda init cmd.exe或者对应你的终端类型然后重开终端。接下来装 PyTorch。这一步强烈建议去官网复制命令。以较新的 CUDA 12.1 版本为例conda 路线的命令大致长这样conda install pytorch torchvision torchaudio pytorch-cuda12.1 -c pytorch -c nvidia逐段解释pytorch是核心框架torchvision提供视觉相关的数据集和预训练模型torchaudio处理音频pytorch-cuda12.1是让 conda 去装对应版本的 CUDA 运行库。后面两个-c是 channel 指定告诉 conda 优先从 pytorch 和 nvidia 这两个源里找包。如果你的显卡驱动比较老只支持到 CUDA 11.8那就把pytorch-cuda12.1换成pytorch-cuda11.8命令结构完全一样。注意pytorch-cuda这个参数只在 conda 路线里存在。如果你用 pip对应的是--index-url https://download.pytorch.org/whl/cu121这样的参数。两条路线的命令别混着用。3.3 下载慢、卡住的解决办法下载这一步是新手最容易卡住的地方。PyTorch 的 GPU 包体积大从境外源直接拉速度可能只有几十 KB/s下两个小时都是常事中途断流还得重来。针对 conda 的下载配置国内镜像源能明显提速。配置文件的位置在用户目录下的.condarc文件Windows 上是C:\Users\用户名\.condarc。内容大致如下channels: - 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 - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2 custom_channels: conda-forge: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud配完之后执行conda clean -i清一下索引缓存再重新装。但这里有个矛盾点需要说明PyTorch 官方包pytorch channel 里的镜像站同步往往有延迟最新的版本可能在镜像上还没跟上。所以如果配了镜像还是找不到包把-c pytorch -c nvidia这两个参数加上让它回官方源去找只是速度会慢一些。另一个思路是用 pip 装。pip 可以直接指定官方 whl 索引PyTorch 的官方 CDN 在国内访问速度其实还行pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121我实测下来同样网络条件下pip 从官方索引拉包经常比 conda 快而且体积更小conda 包会附带一些额外的元数据。如果你不介意用 pip 管理 torch 相关包这条路更干脆。只是记住一个环境里选定一种方式之后不要来回换。3.4 安装完成后的三项验证装完之后别急着关终端一定要验证而且要验证到底层。很多人只看import torch不报错就以为成功了结果训练的时候才发现一直在用 CPU。第一项确认版本和 CUDA 编译信息import torch print(torch.__version__) print(torch.version.cuda) print(torch.backends.cudnn.version())torch.__version__应该能看到cu121这样的后缀如果是cpu说明你装的根本就是 CPU 版本。torch.version.cuda显示的编译时用的 CUDA 版本。torch.backends.cudnn.version()能打印出版本号说明 cuDNN 也装好了。第二项确认 CUDA 可用性print(torch.cuda.is_available()) print(torch.cuda.device_count()) print(torch.cuda.get_device_name(0))这三个输出分别是 True、显卡数量、显卡型号。如果第一个是 False先别急着重装往下翻第六章的排查表八成是版本不匹配或者装了 CPU 包。第三项做一次真实的 GPU 计算import torch a torch.randn(1000, 1000).cuda() b torch.randn(1000, 1000).cuda() c a b print(c.device) print(c.sum().item())最后打印出来的 device 应该是cuda:0。这一步是关键它证明的不只是检测到了显卡而是计算真的在显卡上执行了。有些环境is_available()返回 True但实际运算会报 Torch not compiled with CUDA enabled就是这个验证能抓出来的问题。4. PyCharm 接入 Conda 环境的关键设置环境建好了命令行里也验证通过了接下来是让 PyCharm 用上这个环境。这一步的操作本身不复杂但有几个位置选错了会导致 PyCharm 用的是一个环境、终端里用的是另一个环境出现我在终端里 pip 装了包PyCharm 里却 import 不到这种诡异现象。4.1 把项目解释器指向新环境打开 PyCharm新建或者打开一个项目。然后进File Settings Project: 项目名 Python InterpreterMac 上是PyCharm Preferences。右上角有个齿轮图标点开选Add Interpreter再选Add Local Interpreter。弹出的窗口左侧有几种解释器类型选Conda Environment。右边有两个选项New environment和Existing environment。因为你已经用命令行建好了所以选第二个然后在Interpreter那一栏点右边的...按钮。这里的关键是找到你刚建的那个环境的 python.exe 的完整路径。Windows 上路径大致是C:\Users\你的用户名\anaconda3\envs\pt2-gpu\python.exeLinux 和 Mac 上是~/anaconda3/envs/pt2-gpu/bin/python。如果记不清具体路径可以在 Anaconda Prompt 里先激活环境再敲where pythonWindows或者which pythonLinux/Mac它会直接打印出来。选中之后下面的包列表会刷新你应该能在里面看到 torch、torchvision、numpy 这些包并且能看到版本号。这一步是判断有没有选对环境的直接证据——如果列表里一个包都没有说明你选到空环境或者 base 去了。提示路径里不要有中文和空格。C:\Program Files\...这种带空格的路径在某些库加载动态链接库时会出问题。如果是这种情况换个安装位置重装一次最省事。4.2 让终端、Jupyter、运行配置都走同一个环境解释器配好之后还有个经常被忽略的地方PyCharm 内置的 Terminal。默认情况下这个终端用的可能是系统默认的 Python而不是你刚配的 conda 环境。后果就是你在终端里pip install一个包装到了系统环境里PyCharm 运行代码时却找不到。检查方式很简单在 PyCharm 的 Terminal 里敲python -c import sys; print(sys.executable)看打印出来的路径是不是你配的那个环境。如果不是进Settings Tools Terminal把Shell path改一下或者在Environment variables里加上 conda 的初始化。更省事的做法是在项目根目录建一个.idea之外的配置文件直接让 conda 的激活脚本被加载。不过最通用的方案还是确保 conda 已经做了全局初始化Windows 上执行conda init powershell或conda init cmd.exeLinux/Mac 上执行conda init bash或 zsh重开终端之后PyCharm 的终端也会自动带上激活逻辑。如果你用 Jupyter Notebook 写代码还需要单独注册内核否则 Notebook 里用的还是系统 Pythonconda activate pt2-gpu pip install ipykernel python -m ipykernel install --user --name pt2-gpu --display-name Python (pt2-gpu)--name是内部标识--display-name是你在 Jupyter 界面里看到的名字可以写成PyTorch GPU 环境这种更好认的。4.3 几处容易忽略的工程化设置几个小设置配一次能省很多事。第一个是运行配置里的工作目录。PyCharm 默认把工作目录设成项目根目录但如果你代码里用了相对路径读数据而脚本在子目录里就很容易报文件找不到。在Run Edit Configurations里把Working directory明确设成项目根目录这样不管脚本在哪一层相对路径的基准都是固定的。第二个是File Settings Build, Execution, Deployment Console Python Console把这里的解释器也切到 conda 环境。Python Console 是快速测试代码片段的地方如果它的解释器不对你测出来的结果和实际运行的不一样会被误导。第三个是利用 PyCharm 的科学模式或者变量查看器。跑深度学习代码时在断点处停下来可以展开查看张量的形状、数据类型、设备位置。检查一个张量是不是在 GPU 上看它的 device 属性就知道了比在代码里到处插 print 优雅得多。这个功能对调试形状不匹配的报错特别有用。5. 一套能复用的环境体检脚本环境搭好之后我习惯把验证代码写成一个脚本留在项目里以后换机器、装新包、出现异常直接跑一遍就知道问题出在哪。这个脚本比手动敲命令靠谱因为它会一次性输出所有关键信息方便对比。5.1 打印全部软硬件信息我用的诊断脚本大致是这样的import sys import platform import torch def env_report(): print( * 50) print(Python 版本:, sys.version) print(Python 路径:, sys.executable) print(操作系统:, platform.platform()) print(- * 50) print(PyTorch 版本:, torch.__version__) print(编译时 CUDA:, torch.version.cuda) print(cuDNN 版本:, torch.backends.cudnn.version()) print(- * 50) print(CUDA 是否可用:, torch.cuda.is_available()) if torch.cuda.is_available(): print(显卡数量:, torch.cuda.device_count()) for i in range(torch.cuda.device_count()): print(f显卡 {i}:, torch.cuda.get_device_name(i)) props torch.cuda.get_device_properties(i) print(f 显存: {props.total_memory / 1024**3:.2f} GB) print(f 计算能力: {props.major}.{props.minor}) print( * 50) if __name__ __main__: env_report()这段代码有几个细节值得说。sys.executable打印的是当前 Python 解释器的绝对路径这一行能直接确认 PyCharm 有没有用对环境。props.major和props.minor是你显卡的计算能力比如 8.6 对应 RTX 30 系列8.9 对应 RTX 40 系列这个数字决定了你能用哪些精度优化特性。计算能力这个数字很关键。如果你打算用 bf16 混合精度训练需要计算能力 8.0 以上如果要用 Flash Attention 这类优化要求更高。老显卡上跑新框架很多加速特性是用不了的这不是环境问题是硬件限制。5.2 跑一次真实的 GPU 计算诊断信息只能说明环境配置对了不能说明计算性能正常。加一段基准测试用矩阵乘法测一下实际速度import time import torch def gpu_benchmark(size4096, iters20): if not torch.cuda.is_available(): print(CUDA 不可用跳过测试) return a torch.randn(size, size, devicecuda) b torch.randn(size, size, devicecuda) # 预热让显卡进入满频状态 for _ in range(5): c a b torch.cuda.synchronize() start time.perf_counter() for _ in range(iters): c a b torch.cuda.synchronize() elapsed time.perf_counter() - start tflops 2 * size**3 * iters / elapsed / 1e12 print(f矩阵规模 {size}x{size}, 迭代 {iters} 次) print(f耗时 {elapsed:.3f} 秒, 算力约 {tflops:.2f} TFLOPS) if __name__ __main__: gpu_benchmark()这段代码里有两个容易写错的点。一是torch.cuda.synchronize()GPU 计算是异步下发的Python 代码执行完 for 循环不代表计算完成不加同步的话测出来的时间会严重偏小。二是预热循环显卡在低负载时频率会被压下来第一轮计算会明显偏慢预热几轮之后频率拉上去测出来的才是稳态性能。这个测试的意义在于建立基线。比如你的显卡理论 FP32 算力是 30 TFLOPS实测跑出 20 左右算正常说明环境没问题如果只跑出 3那就要查是不是掉到 CPU 上算了或者显卡被其他程序占着。5.3 显存与利用率的观察方法性能测试之外还要养成观察显存的习惯。PyTorch 提供了几个查询接口print(torch.cuda.memory_allocated() / 1024**2, MB) # 当前张量占用 print(torch.cuda.memory_reserved() / 1024**2, MB) # 缓存池占用 print(torch.cuda.max_memory_allocated() / 1024**2, MB) # 峰值memory_allocated是真正被张量占着的显存memory_reserved是 PyTorch 向显卡申请下来、暂时没还给系统的缓存池。这个缓存机制是故意的避免频繁申请释放显存带来的开销。所以你会看到删除张量之后memory_allocated降下来了memory_reserved却没变这是正常的不是显存泄漏。另一个观察窗口是nvidia-smi。Linux 上加-l 1参数可以每秒刷新一次方便实时观察利用率。Windows 上没有这个刷新功能用nvidia-smi dmon也能看到滚动输出。判断是不是真的在用 GPU看GPU-Util这一列长时间在 0% 附近跳基本可以确定计算没走显卡。6. 踩坑实录那些文档里不会写的问题这一章是这篇内容的重点。前面所有步骤都顺利的话你大概二十分钟就能搭完环境。但实际情况是大部分人会在某个环节卡住然后花几个小时搜索。下面这些是我这些年遇到过、也帮别人解决过的高频问题整理成可以直接对照的清单。6.1 版本不匹配报错速查表报错信息根本原因处理方式Torch not compiled with CUDA enabled装的是 CPU 版 torch卸载重装 GPU 版确认命令里带 cuda 参数CUDA out of memory显存不够降低 batch size或用torch.cuda.empty_cache()DLL load failed while importing _C动态库路径冲突检查 conda 的 Library\bin 是否在 PATH 里或重装环境no kernel image is available显卡计算能力低于编译目标换用支持该架构的 PyTorch 版本Found no NVIDIA driver驱动没装或版本过低更新显卡驱动到对应版本undefined symbol: xxx包之间 ABI 不兼容同一个环境里统一用 conda 或统一用 pip表里第一行和第三行是最常见的。第一行的成因通常是你在 conda 环境里用了 pip 装 torch而 pip 默认拿的是 CPU 版本除非你显式指定了--index-url。第三行在 Windows 上特别多本质是系统里存在多个版本的 CUDA 相关 DLL加载的时候拿错了。处理 DLL 问题有个笨办法但很有效把 conda 环境的Library\bin目录加到系统 PATH 的最前面让它优先被搜索到。不过这个操作有副作用可能影响系统里其他依赖 CUDA 的软件所以更稳妥的做法还是保持环境干净不要混装。6.2 显存不释放、利用率低、卡在 0%显存不释放是我被问得最多的问题之一。现象是训练脚本跑完nvidia-smi里还能看到 Python 进程占着几个 G 的显存。这种情况多数不是泄漏而是 PyTorch 的缓存池没释放或者是进程还没完全退出。如果是同一进程内反复跑可以手动清缓存import gc import torch del model, optimizer, loss gc.collect() torch.cuda.empty_cache()顺序很重要先del掉引用再gc.collect()触发垃圾回收最后torch.cuda.empty_cache()把缓存池还给显卡。少了gc.collect()这一步很多时候empty_cache()是无效的因为对象还没被真正回收。利用率低到 0% 或者一直在 20% 以下通常是数据加载拖了后腿。GPU 算完一批数据要等下一批等待期间利用率就掉下来了。解决办法是把 DataLoader 的num_workers调大让 CPU 端并行准备数据loader DataLoader(dataset, batch_size32, num_workers8, pin_memoryTrue, prefetch_factor2)pin_memoryTrue让数据放在锁页内存里从内存拷贝到显存会更快。num_workers一般设成 CPU 核心数的一半到三分之二设太大反而会因为进程调度开销变慢。Windows 上num_workers设大于 0 有时会出问题需要把主逻辑包在if __name__ __main__:里面这是多进程启动机制导致的不是 bug。还有一种情况是显卡被别的进程占着。用nvidia-smi看进程列表找到占显存的 PID 干掉就行。Jupyter Notebook 里跑崩的代码经常留下僵尸进程这种情况很常见。6.3 环境损坏、迁移与复现环境用久了总会出问题可能是某个包的自动升级破坏了依赖也可能是硬盘上的文件损坏。判断环境是否健康跑一遍第五章的诊断脚本就够了。真要重建的时候先把当前环境里的包列表导出来别直接删conda activate pt2-gpu conda env export environment.yml这个 yml 文件记录了所有包和版本重建的时候conda env create -f environment.yml就能一键还原。不过默认导出的文件里带prefix字段记录了原机器的绝对路径换机器的时候需要手动删掉这一行或者导出时加--no-builds参数只保留版本号。有个坑要提醒conda env export只导出 conda 装的包用 pip 装的包虽然会出现在文件末尾的 pip 段落里但还原时如果版本锁得太死容易因为平台差异装不上。跨平台迁移的时候我一般把 pip 段落里的精确版本号删掉只留包名。环境迁移的另一个思路是用 Docker把整个环境打包成镜像在任何装了 Docker 的机器上都能一键跑起来。这个方案更适合团队协作和部署个人学习阶段用 conda 的 yml 文件就足够了。7. 让环境可复现导出、迁移与多环境管理单个环境搭通只是开始。真正的项目里你会同时维护好几个环境还要在几台机器之间来回切怎么让这套东西可复现、可迁移是迟早要面对的问题。这一章讲的都是我在实际项目里验证过的做法。7.1 导出 environment.yml 与 pip 依赖合并一个规范的依赖文件应该包含三层信息环境名、conda 通道、以及 conda 装不了的包通过 pip 补足。conda env export生成的默认文件已经涵盖这些但需要人工整理一下。我一般的做法是手动维护一个requirements.txt记录项目直接依赖然后定期用conda env export --no-builds生成一份完整快照作为备份。前者用于日常协作后者用于环境灾难恢复。原因很直接完整快照把间接依赖的版本全部锁死虽然精确但换平台之后经常会因为某个底层包平台不兼容而装不上。而手动维护的直接依赖列表让 conda 去解析具体版本反而成功率更高。手动维护的那个文件大概长这样# requirements.txt torch2.1.0 torchvision0.16.0 numpy1.24 pandas2.0 matplotlib3.7 tqdm tensorboard注意 torch 不要写死到小版本号也不要写那种从特定索引下载的完整 URL那会导致换环境时完全没法用。7.2 换机器、换队友时的复现流程拿到一份依赖文件和一份代码在新机器上的标准流程是conda create -n 项目名 python3.10 -y conda activate 项目名 conda install pytorch torchvision torchaudio pytorch-cuda12.1 -c pytorch -c nvidia -y pip install -r requirements.txt python -c import torch; print(torch.cuda.is_available())注意最后一行验证不要省。有些人在新机器上装完直接开始跑训练跑到一半才发现用的是 CPU白白浪费几个小时。还有一点torch 相关包优先用 conda 装其余包用 pip 装。这个顺序是有讲究的conda 装的 torch 会带上配套的 CUDA 运行库和 cuDNN依赖关系由 conda 统一解析出问题的概率更低。而其他纯 Python 包用 pip 装速度更快、更新更及时。如果反过来先用 pip 装了 torchconda 后面再装其他包时可能因为依赖冲突把 torch 降级或替换掉这就麻烦了。7.3 多版本共存时的切换策略做对比实验的时候经常需要同时维护 PyTorch 1.x 和 2.x 两套环境。这时候有几件事要注意。第一环境名要能体现版本。pt112-cu113、pt23-cu121这种命名一眼就能看出对应的版本组合比env1、env2强太多。第二不要试图用 conda 的--clone来做版本降级。克隆环境只是复制文件不会重新解析依赖改版本号之后很容易出问题。要新版本就新建环境重装时间成本比排查依赖冲突低得多。第三磁盘空间要提前规划。一个 GPU 环境的体积在 5GB 到 8GB 之间装三四个环境就是二十多个 G。如果用的是固态硬盘容量紧张可以在创建环境时用--prefix参数把环境放到其他盘上conda create --prefix D:\conda_envs\pt2-gpu python3.10 conda activate D:\conda_envs\pt2-gpu用--prefix建的环境激活时要用完整路径PyCharm 里配置解释器时也直接指向这个路径下的 python.exe用起来和普通环境没区别。第四平时的维护习惯。每个月跑一次conda clean --all清理下载缓存和废弃包这个命令能释放出好几个 G 的空间。清理之前确认一下没有正在进行的安装任务不然后面还得重新下载。这套环境我自己搭过不下二十次从最早的 CUDA 8 时代到现在工具链换了好几轮但核心逻辑一直没变先把版本关系理清楚再动手装装完必须验证到底层。这三个原则记住能避开九成以上的问题。分享一个小技巧收尾。我在每个新环境建好之后都会把第五章那个诊断脚本存成env_check.py放在项目根目录然后在 PyCharm 里给它配一个固定的运行配置。以后不管换了什么机器、装了什么新包、遇到什么奇怪的报错第一件事就是跑它。输出的那几行信息比在搜索引擎里翻半小时有用得多。环境这东西能自己诊断就永远不会被别人牵着走。
返回列表