
最近帮一位朋友排查 Windows 10 上飞桨PaddlePaddle跑不动的问题发现显卡占用一直是 0%nvidia-smi里连个 python 进程都看不到。折腾半天才确认他装的其实一直是 CPU 版——因为pip install paddlepaddle默认装出来的就是 CPU 包GPU 版要单独指定包名和安装源。如果你也准备在自己的 Win10 电脑上搭建本地 GPU 版飞桨这篇文章就是按我实际动手的顺序写的把驱动检查、Python 环境、安装命令、验证手段和常见坑一次讲透。先说结论这篇内容适合手头有一块 NVIDIA 显卡、想在 Windows 10 上跑飞桨训练或推理但又容易被各种教程里的 CUDA 版本号搞晕的人。整个流程本身不复杂真正复杂的是版本对应关系以及那些看起来特别玄学的 DLL 报错。下面的内容我会尽量说得直接一点每一步都告诉你为什么要这么做。1. 动手之前想清楚CPU版和GPU版差在哪1.1 你是不是真的需要GPU版如果只是用飞桨做最基础的文本分类、线性回归 demo或者模型非常小CPU 版其实完全够用而且安装省心得多。但如果你的目标是跑图像分类、OCR、目标检测或者训练一个稍微像样一点的神经网络GPU 版带来的收益是数量级的。我自己第一次在 GPU 上跑 ResNet 推理的时候单张图片的处理时间从 CPU 的几百毫秒掉到几毫秒。这种差距不是靠优化代码能追回来的因为 CPU 和 GPU 在并行计算能力上的硬件差异就在那里。有一点必须先确认飞桨的 GPU 支持依赖 NVIDIA 显卡Intel、AMD 的 GPU 目前不在官方支持范围内。所以第一步是打开设备管理器看一眼有没有 NVIDIA 的独立显卡。如果没有后面所有内容对你来说都暂时不适用老老实实用 CPU 版就好。显存大小也需要心里有数。图片分类这类任务 2GB 显存也能跑但 batch size 会被卡得很死目标检测、OCR 这类任务建议至少 4GB 以上。显存不足通常不会直接报“装不了”而是训练到一半突然给你一个 Out of memory所以提前知道自己显卡的显存容量能省很多麻烦。1.2 CPU版和GPU版的命令差异值得先说清楚很多人绕弯路根源就在“包名”上。默认执行pip install paddlepaddle拿到的只有 CPU 推理功能压根不包含 CUDA 相关代码。要获得 GPU 支持必须安装paddlepaddle-gpu这个包。就算到了飞桨 3.x 时代官方依然保留了 CPU 包和 GPU 包分开发布的策略。为什么会有人踩坑因为两个包安装之后在 Python 里导入的模块名都叫paddle。也就是说你先装 CPU 版跑通了再装 GPU 版如果旧包没有卸载干净跑起来之后可能是 CPU 版和新 GPU 版的文件混在一起。此时import paddle不会报错但paddle.is_compiled_with_cuda()返回False整个环境看起来一切正常其实一直没调用 GPU。这里列一张对比表方便你判断自己缺的到底是什么对比项CPU版GPU版pip包名paddlepaddlepaddlepaddle-gpu是否支持CUDA计算否是paddle.is_compiled_with_cuda()FalseTrue安装复杂度低中需选对CUDA通道和显卡驱动典型用途小型模型、CPU环境部署训练模型、OCR、检测、分割最容易碰到的问题几乎没有DLL报错、显存不足、CUDA版本不匹配1.3 搭建之前需要准备的三样东西一台有 NVIDIA 显卡的 Windows 10 电脑建议显存 4GB 以上。一个能正常访问包源的环境。国内用户如果下载慢用飞桨官方源或国内镜像源就行这部分后面会细说。一个干净的 Python 环境。强烈建议用 conda 或 venv 单独建环境不要直接装在系统 Python 里。为什么强调独立环境因为后续你可能还要装 PaddleOCR、PaddleX 这类套件它们会连带安装 opencv、shapely 等一堆依赖。所有东西堆在同一个环境里很容易出现“装完一个套件之前跑得好好的项目突然挂了”的情况。分开建环境看着麻烦实际上是最省时间的方式。2. 最容易翻车的一步显卡驱动、CUDA、cuDNN的版本关系2.1 nvidia-smi能查到什么查不到什么打开 CMD 或 PowerShell输入nvidia-smi你会看到一个有点像任务管理器的界面。这里有三个信息需要会看第一行是显卡驱动版本比如 555.99。右上角写着 CUDA Version比如 12.5。注意这只是当前驱动能够支持的最高 CUDA 版本不代表你的系统里已经装过 CUDA Toolkit。下方是当前显存占用和正在使用 GPU 的进程列表。不少人看到右上角写着 CUDA 12.5就以为自己装好了 CUDA其实不是。驱动和 CUDA Toolkit 是两码事。飞桨运行 GPU 程序时是通过 CUDA Runtime API 和驱动交互的驱动版本如果太老就会在加载阶段直接失败。判断方法很简单驱动右上角的 CUDA Version 必须不低于你将要安装的飞桨 GPU 包所要求的 CUDA 版本。比如你打算装官方 cu126 渠道的飞桨包驱动右上角至少得是 12.x。如果显着写了 11.4那就先更新驱动。2.2 飞桨GPU包自带运行库很多时候不用手动装CUDA这是网上教程最容易误导人的地方。很多 PyTorch 时代的教程都会让人先去官网下载 CUDA Toolkit再去下载 cuDNN然后解压后复制到指定目录。这套流程放在飞桨上绝大多数情况是多余的。飞桨官方发布的paddlepaddle-gpupip 包里面通常已经打包好了编译时对应的 CUDA 运行库和 cuDNN 动态库。你真正需要保证的只有显卡驱动不要太老。换句话说只要驱动版本达标装完 pip 包直接就能跑。我见过一个反例有人手动装了 CUDA 11.8 Toolkit又跑去找 cuDNN 的 DLL 复制到系统目录然后回头安装飞桨 cu123 版本结果 import 直接报 DLL 加载失败。原因就是 PATH 里多个 CUDA 版本的动态库互相干扰加载到了不匹配的版本。所以我的建议是除非你是用 conda-forge 渠道或源码编译飞桨否则尽量别手动折腾 CUDA Toolkit。2.3 飞桨GPU包、CUDA、cuDNN的版本对应速查飞桨官网安装页面会让用户选择 CUDA 版本对应关系大致如下飞桨安装源对应CUDA对应cuDNN驱动要求cu118CUDA 11.8cuDNN 8.x驱动支持CUDA 11.8及以上cu123CUDA 12.3cuDNN 8.x/9.x驱动支持CUDA 12.xcu126CUDA 12.6cuDNN 9.x较新驱动支持CUDA 12.x这里的打包细节会随飞桨版本调整但大方向不会变。你只需要保证nvidia-smi右上角显示的 CUDA 版本不低于你选的渠道就行。近两年更新的驱动一般都能覆盖。提示一定不要凭感觉猜版本。最稳的做法是打开飞桨官网安装页面选择“Windows pip CUDA 12.6”复制它生成的那条命令。如果页面默认版本太新、你的驱动支持不了再往下降一档选 cu123 或 cu118。3. Python环境与安装命令选对版本、选对源3.1 Python版本和虚拟环境怎么选飞桨官方对 Python 3.10 的支持最成熟跑起来最省心。3.12 在飞桨 3.x 版本上也能用但某些第三方依赖可能需要花时间等编译包Python 3.13 目前不建议尝试很容易遇到没有预编译轮子的问题。所以直接选 3.10 就好。虚拟环境建议二选一# conda 方式 conda create -n paddle python3.10 -y conda activate paddle # venv 方式 python -m venv paddle_env paddle_env\Scripts\activate注意 Windows 下 venv 的激活脚本在Scripts目录里不是 Linux 那套bin。激活成功后命令行提示符前面会出现环境名称说明你已经在独立环境里了。为什么一定要这一步因为我见过太多人直接拿系统 Python 装飞桨装完 PaddleOCR 时又拉进来一堆 opencv 相关依赖结果系统里其他项目的 pandas、numpy 版本全被牵连。虚拟环境隔离的成本极低后患却非常少。3.2 安装命令的几种写法与镜像源选择进入虚拟环境之后安装 GPU 版推荐优先使用飞桨官方源python -m pip install paddlepaddle-gpu -i https://www.paddlepaddle.org.cn/packages/stable/cu126/如果你的驱动支持的是 CUDA 12.x这条命令是最省心的。如果官方源速度不太理想也可以用清华源python -m pip install paddlepaddle-gpu -i https://pypi.tuna.tsinghua.edu.cn/simple清华源的问题是同步可能滞后有时候最新版本的 GPU 包还没同步过去。如果镜像源里找不到你想要的那个版本回官方源安装即可。还有一件必须做的事如果之前装过 CPU 版或者旧版 GPU 包先卸载干净再装新的。pip uninstall -y paddlepaddle paddlepaddle-gpu这里再强调一次paddlepaddle和paddlepaddle-gpu安装后都提供同名模块paddle。不卸载旧包直接装pip 可能会让你得到一个文件残留混杂的环境导致后面各种奇怪问题。宁可多敲一条卸载命令也别省这一步。3.3 安装后先做的两项检查装完之后不要急着跑模型先确认两件事python -c import paddle; print(paddle.__version__)能输出版本号说明基本安装没大问题。然后再跑python -c import paddle; print(paddle.is_compiled_with_cuda())如果打印True恭喜你装的确实是 GPU 版。如果打印False说明你安装的还是 CPU 包回到前面重看包名。到这一步为止环境只是“看着正常”。真正要确认 GPU 在干活需要做下一节的验证。4. 拿三个检查方法验证GPU真的工作4.1 run_check和关键属性飞桨自带一个环境检查工具直接在命令行执行python -c import paddle; paddle.utils.run_check()如果一切正常会看到类似PaddlePaddle is installed successfully!的输出。但仅凭这行文字还不够因为你装 CPU 版的时候它也会这么提示。所以要配合属性检查一起看import paddle print(飞桨版本:, paddle.__version__) print(编译CUDA:, paddle.version.cuda()) print(编译cuDNN:, paddle.version.cudnn()) print(是否CUDA版:, paddle.is_compiled_with_cuda()) print(GPU数量:, paddle.device.cuda.device_count()) if paddle.device.cuda.device_count() 0: print(GPU名称:, paddle.device.cuda.get_device_name(0))paddle.version.cuda()返回的是飞桨编译时用的 CUDA 版本比如12.6paddle.is_compiled_with_cuda()返回True才能说明这个包是 GPU 版。通过device_count()能看到几张卡多卡机器这里会显示实际数量。4.2 用矩阵乘法做个直观的耗时对比属性检查通过之后我习惯再跑一段矩阵乘法做时间对比。看着 GPU 和 CPU 的耗时差异比自己骗自己说“应该能用”踏实得多。import paddle import time def matmul_speed(device): paddle.set_device(device) a paddle.randn([4096, 4096]) b paddle.randn([4096, 4096]) for _ in range(10): paddle.matmul(a, b) t0 time.time() for _ in range(50): paddle.matmul(a, b) if device.startswith(gpu): paddle.device.cuda.synchronize() return time.time() - t0 print(CPU耗时(秒):, matmul_speed(cpu)) print(GPU耗时(秒):, matmul_speed(gpu))如果你的 CPU 比较弱可以把矩阵尺寸从 4096 改成 2048循环次数从 50 改成 10对比效果依然明显。正常情况下 GPU 耗时应该只有 CPU 的一个零头。这里用了paddle.set_device来切换计算设备也就是说代码里如果没有显式指定设备飞桨会根据这个设置把算子放到对应硬件上执行。4.3 用nvidia-smi确认Python进程占用GPU这是最“眼见为实”的一步。开一个终端跑训练或对着上面代码等待时另开一个 PowerShell输入nvidia-smi看进程列表里有没有python.exe以及对应的显存占用数字。只要看到 python 进程占用了显存就说明 GPU 真的在工作而不是程序跑了但实际还在拿 CPU 凑合。想持续观察也可以加参数nvidia-smi -l 1这条命令每隔一秒刷新一次按CtrlC退出。这个方法特别适合排查“包是 GPU 版但训练就是不动”的诡异情况。5. 装完最常见的四个坑附完整排查链路5.1 坑一import就报DLL加载失败常见报错形式是ImportError: DLL load failed while importing paddle或者错误信息里直接点名cudnn64_8.dll、cudnn_ops_infer64_8.dll找不到。最可能的原因有两个一是显卡驱动太老驱动支持的 CUDA 版本低于飞桨包的要求二是手动装过 CUDA Toolkit且 PATH 或系统目录里有多个版本的 CUDA 动态库加载时发生了冲突。处理顺序是打开 CMD输入nvidia-smi看驱动版本和右上角 CUDA Version。如果右上角 CUDA 版本太低去 NVIDIA 官网更新显卡驱动重启电脑。如果手动装过多个 CUDA Toolkit整理一下 PATH 里的 CUDA 路径避免多个版本同时生效。在干净的虚拟环境里执行pip install paddlepaddle-gpu重装一次。这里特别提醒不要去网上下载单个 DLL 塞进 System32。飞桨 GPU 包本身自带全套运行库重装环境通常就能解决。手动改系统目录后续只会带来更多莫名其妙的问题。5.2 坑二is_compiled_with_cuda()返回False有的朋友安装过程格外顺利run_check()也显示成功但is_compiled_with_cuda()偏偏返回False。这种情况九成是装了 CPU 版。处理方式pip uninstall -y paddlepaddle python -m pip install paddlepaddle-gpu -i https://www.paddlepaddle.org.cn/packages/stable/cu126/安装完再验证一次python -c import paddle; print(paddle.is_compiled_with_cuda())这一版输出True问题就解决了。类似的问题我也在别人机器上见过先装了 CPU 版跑通后面想装 GPU 版时直接敲了一条pip install paddlepaddle-gpu没有卸载旧包。两个包都提供paddle模块最终环境里残留的还是旧 CPU 版文件表面上看安装成功了实际上没有替换干净。所以先卸载再装永远是最稳妥的。5.3 坑三能检测到GPU但训练时报显存不足症状是device_count()返回正常代码一跑就报 Out of memory。原因一般是显存真的不够用或者飞桨默认会把显存申请得比较多。处理办法有三个方向调小 batch size或者把输入图片尺寸缩小。限制飞桨单卡可占用的显存上限import paddle paddle.set_flags({FLAGS_gpu_memory_limit_mb: 2048})用nvidia-smi检查是否还有其他进程占用了显存。如果开着别的深度学习程序或浏览器硬件加速先把不用的进程关掉。显存不够这个问题比较现实不建议硬扛。如果模型本身比较大降 batch size 是最直接的方式如果训练数据量大可以顺便熟悉一下飞桨的 AMP 混合精度训练用低精度浮点数把显存压力降下来。5.4 坑四PaddleX / PaddleOCR装完后环境冲突很多人装完飞桨 GPU 版之后下一步就是装 PaddleOCR 做文字识别或者装 PaddleX 做全套模型工具。这时候很容易遇到 pip 提示依赖冲突或者装完之后之前跑好好的项目突然 import 失败。原因多半是 PaddleOCR、PaddleX 会额外引入 opencv-python、shapely、pyclipper 等一堆依赖。如果环境里原本就有 opencv-contrib-python 或特定版本的 numpy这些包之间就可能打起来。我的做法是给不同任务分开建环境conda create -n paddle-ocr python3.10 -y conda activate paddle-ocr python -m pip install paddlepaddle-gpu -i https://www.paddlepaddle.org.cn/packages/stable/cu126/ python -m pip install paddleocr基础训练环境用一套套件环境用另外一套。这样互相之间完全隔离哪个出问题了直接删环境重建不会影响其他项目。下面把四个坑汇总成一张速查表问题典型症状最可能原因处理办法DLL加载失败import直接报错驱动太老、多CUDA冲突更新驱动、整理PATH、重装环境CUDA返回Falserun_check成功但无GPU实际装了CPU包卸载后重装paddlepaddle-gpu显存不足训练中途OOM显存不够、占用过多调小batch、限制显存、关进程依赖冲突装套件后环境异常opencv等依赖打架分开建虚拟环境5.5 一个百试百灵的排查顺序如果你已经被报错搞晕别乱试按下面顺序来确认包类型python -c import paddle; print(paddle.is_compiled_with_cuda())。查编译版本print(paddle.version.cuda(), paddle.version.cudnn())。查驱动CMD 里运行nvidia-smi看右上角 CUDA Version 是否满足要求。运行paddle.utils.run_check()看是否有 GPU 相关提示。运行一段小代码比如矩阵乘法确认设备切换后耗时差异明显。仍不行新建一个干净的虚拟环境卸载全部 paddle 相关包按官方命令重装。这个顺序的本质是“先确认你手里是什么包再看系统能不能让这个包跑起来最后才考虑重装”。很多人一上来就重装驱动、重装系统其实是跳过前两步在不知情的状态下瞎试效率很低。6. 环境稳定运行之后我一般会保持的几个习惯6.1 新开终端先跑run_check再干活每次新开终端准备干活之前我习惯先跑一行python -c import paddle; paddle.utils.run_check(); print(paddle.is_compiled_with_cuda())输出顺手扫一眼确认 GPU 状态正常再写代码。这个习惯看起来有点随意却能明显减少“跑半天才发现忘了激活环境、用的是 CPU 版”的乌龙。尤其是电脑上同时存在多个虚拟环境的时候这条命令能快速告诉你在哪个环境、当前是什么状态。6.2 用paddle.device相关接口控制设备和显存代码里我一般会在开头写清楚设备import paddle paddle.set_device(gpu:0)这样能避免代码在别的机器上跑时默认落到 CPU。训练代码里如果因为显存不够想切回 CPU 调试也可以改成paddle.set_device(cpu)设备切换用代码表达出来比依赖配置文件更直观。需要限制显存时再配合paddle.set_flags一起用。6.3 版本冻结与依赖隔离的基本做法环境稳定之后第一件事就是把依赖列表导出来pip freeze requirements.txt有了这份清单就算以后环境不小心弄坏了也能用最快速度重建。升级飞桨版本前尽量先看官方发布说明不要随手pip install -U paddlepaddle-gpu因为大版本之间 API 可能有调整升级后原本的代码未必完全兼容。我在 Windows 10 上搭飞桨 GPU 环境的整体感受是大部分问题根本不是飞桨本身出的而是“驱动、CUDA、pip 包”这条链路里的版本对应关系没理顺。一旦把这条链路吃透后面再学其他深度学习框架的 GPU 安装也能举一反三因为它们面对的是同一套 Windows 下的硬件环境逻辑。