资讯动态

离线搭建深度学习环境全攻略:从CUDA到PyTorch的依赖管理

发布时间:2026/10/15 19:51:22 来源:尧图企业网站定制
给服务器离线装上深度学习环境其实没那么难先纠正一个普遍印象离线搭建深度学习环境不是把安装包拷贝过去、点几下下一步就完事。真正让人头疼的往往不是安装本身而是你压根不知道机器上缺了什么、哪个依赖和哪个库暗地里打架、装完CUDA才发现驱动版本不匹配然后一切推倒重来。我这些年帮不同团队搭过不少离线环境从全内网科研服务器到隔离区的训练机器都碰过。这篇文章就把整个离线搭建深度学习环境的完整思路、操作步骤和踩过的坑一次性讲透适合刚接手离线机器的新手也适合已经被依赖地狱折磨过、想理顺流程的运维或算法工程师。1. 为什么离线安装环境是块硬骨头先看在线环境有多轻松装驱动、装CUDA、装PyTorchpip一条命令就把依赖链拉回来了缺什么补什么一路畅通。离线环境的难处在于你这台机器是一个被墙起来的孤岛所有东西都得靠“人肉搬运”而搬运需要你提前知道岛上缺什么。1.1 “少了一个轮子”的连锁反应我习惯把一个深度学习环境拆成四层结构从上到下依次是应用层、解释器层、加速层、驱动层。顶层是你要跑的框架和工具比如PyTorch、TensorFlow、检测某个魔改训练脚本第二层是Python解释器以及通过pip/conda装起来的第三方包第三层是CUDA Toolkit、cuDNN、NCCL这类并行计算加速组件底层是GPU驱动NVIDIA Driver它直接面对硬件。离线安装的难点在于这四层之间环环相扣CUDA版本要求驱动不低于某个版本PyTorch版本要求CUDA不低于某个版本你代码里用的某个package又要求Python不低于某个版本。任何一个“轮子”装错了整个链条就卡住而你又不能当场联网去查文档、去补包只能一遍遍试错。1.2 最反直觉的一件事内网机器比公网机器更“挑食”很多人以为离线机器只是没网络其他和普通机器一样。实际不是。内网生产机器往往被极度精简过可能连build-essential编译工具链、make、gcc都是缺的甚至lsb_release这类基础查询命令都没有。而且很多内网机器出于安全策略默认不装图形界面、不装桌面依赖这会导致你在装某些带GUI依赖的库时莫名其妙失败。我在某次部署中就遇到过目标机器连libssl-dev都没有跑pip install时总报Failed to build wheel一开始还以为是网速问题排查半天才发现是系统缺底层编译依赖。所以拿到机器第一件事不是急着拷安装包而是先全面清点系统现状。2. 动手前必须想清楚的三件事离线安装最忌讳“边装边想”。拿到机器后先花半天时间做决策远比装到一半推倒重来划算。我每次正式操作前都先解决下面三个问题。2.1 第一件事定版本基线忽略“最新”很多人在线装环境习惯了“装最新的”到了离线环境也下意识地选最新版然后被坑得体无完肤。离线环境选版本的第一原则是出过足够长时间、被社区验证过的稳定版本。这里我给一套默认保守的组合经过多次测试兼容性较好组件推荐版本保守方案说明操作系统内核要求能跑NVIDIA驱动即可不同发行版内核略有差异建议kernel版本相近的机器迁移NVIDIA驱动535系或545系对CUDA 12.x支持完整覆盖大部分训练场景CUDA Toolkit11.8或12.1二选一看框架需求不做特殊网络优化建议选11.8cuDNN8.6或8.9与CUDA Toolkit配套别混装Python3.8或3.10PyTorch和TensorFlow官方支持最稳的两档PyTorch2.x稳定版CUDA 11.8对应Linux版wheel这套组合的逻辑是NVIDIA驱动和CUDA Toolkit的绑定关系比较严格驱动决定CUDA Toolkit能跑到多高而CUDA Toolkit又决定了上层框架必须用什么版本编译。先定驱动再定CUDA最后定框架顺序不能乱。2.2 第二件事确定“宿主机器”选哪台联网机器当“下载中转站”直接影响能攒到什么包。我建议选和服务器同发行版、同架构的机器作为宿主。比如服务器是Ubuntu 20.04 x86_64那中转机最好也是Ubuntu 20.04 x86_64这样可以避免“拷过来了但grub版本对不上”之类的细节问题。如果实在没有同版本机器用Docker同样可行在联网机器上拉一个和服务器相同发行版的镜像进入容器里执行下载和打包操作产出的文件基本可复用。这一步的目的是提前获得兼容的依赖包离线机器上才能跑得起来。2.3 第三件事准备“携带介质”和传输通道硬盘、U盘、还是小规模内网共享文件夹决定了文件的组织方式。我遇到过用移动硬盘反复插拔的场景也遇到过用内网SMB共享传文件更方便的场景。这里有一个容易被忽视的点如果文件总量超过几十GB建议先在宿主机器上做一次压缩分卷比如按4GB切分或直接用高强度压缩格式。否则拷贝到中途发现U盘文件系统不支持单个大文件或者传输中断要重来非常浪费时间。另外如果服务器有多个网卡、能搭临时局域网用python -m http.server共享目录往往比插U盘还快。先确认物理条件允许哪种方案再进入下一步。3. 离线安装包从哪来一套省心的攒包流程网上教程大多只告诉你“把pip包下载下来带过去”实际上真正复杂的依赖在于CUDA、cuDNN、pip wheel集以及conda环境快照这四类东西。下面逐个说清楚。3.1 攒CUDA Toolkit和cuDNN安装包NVIDIA官网提供了.run格式的CUDA安装包和.tar.gz格式的cuDNN安装包这些是离线安装的核心。有一点要注意官方下载页面那个“Download”按钮点进去会给一个带长长参数的连接很多人复制URL时只复制主链接漏掉了查询参数导致下载到不完整的文件或不匹配的版本这个细节要仔细核对。我自己有一个习惯尽量下载runfile全集而不要只下载“本地.deb包安装方式所需的几个deb文件”。因为.run安装器会附带很多工具组件离线机器上如果缺某个依赖runfile能现场处理而deb包依赖一旦有缺失补起来非常麻烦。cuDNN则建议下载“cuDNN Library for Linux (x86_64)”的tar包而不是Debian安装包。tar包的好处是解压后手动拷到CUDA目录即可不需要处理复杂的依赖关系。3.2 攒pip安装包用pip download比手动点网页靠谱在联网机器上执行pip download torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 -d ./offline_packages这个命令会把PyTorch、torchvision、torchaudio以及它们依赖的全部wheel文件都下到offline_packages目录里。比手动去网页一个个点要靠谱得多不会漏掉依赖。但如果你的训练脚本还会import很多其他库比如transformers、scikit-learn、pandas、opencv-python、albumentations等等就用一条更长的命令pip download transformers scikit-learn pandas opencv-python albumentations \ --extra-index-url https://download.pytorch.org/whl/cu118 \ -d ./offline_packages这一步会把所有依赖打包下载。然后把整个目录拷到服务器离线机器上执行pip install --no-index --find-links./offline_packages torch torchvision torchaudio transformers注意这里我也加了--extra-index-url指向PyTorch的wheel源。原因在于transformers这类库本身不会自动依赖torch的CUDA版本你不指定源的话pip可能默认从PyPI拉一份不带CUDA的torch或CPU版这样到离线环境里就白装了。凡是有CUDA需求的包下载时一定要带上对应PyTorch索引源。3.3 攒conda环境快照先导出环境文件再导出包如果团队更习惯用conda那方法类似先在联网容器里创建一个干净环境装好所有依赖然后执行conda env export导出环境配置文件再用conda-pack把整个环境目录打包。conda-pack比逐个拷贝.conda包更省事解压后基本路径处理好就能直接使用。这里有个经验conda-pack打出来的环境依赖绝对路径。到了新机器如果安装路径和打包时一致基本免配置如果路径变了得手动改envs/*/bin/pip里的shebang行或者用conda重新安装conda-pack来修改前缀。所以最省事的做法是让目标机器上的路径和打包机器保持一致。比如统一约定都装在/home/xxx/software/python这类固定位置别每台机器换一个目录。3.4 攒系统依赖包利用apt的离线机制很多基础库是无法通过pip解决的比如libgl1、libglib2.0-0、libsm6、libxext6这些图像处理库的底层依赖还有编译工具链gcc、make、ninja-build。在有网的机器上执行apt download $(apt-cache depends --recurse --no-recommends --no-suggests \ --no-conflicts --no-breaks --no-replaces --no-enhances \ build-essential libgl1 libglib2.0-0 libsm6 libxext6 2/dev/null \ | grep ^\w | sort -u)这段命令会把所有系统级依赖的deb包都下载到当前目录然后一并拷到服务器执行dpkg -i *.deb逐个安装。实测下来跑图像类模型前先装这一坨能避免后面遇到大量“cannot find -lGL”或“libGL.so.1”缺失的报错。4. 服务器端安装实录CUDA、PyTorch与Python层的顺序问题到了服务器上安装顺序是固定的先驱动再CUDA、cuDNN后Python环境最后才是业务代码依赖。这个顺序尽量不要调换因为下层装好了上层才能验证。4.1 先确认GPU与新装驱动的匹配情况用lspci | grep -i nvidia查看显卡型号。如果是较新的卡建议选尽量新的驱动老卡则选稳定驱动避免出现“驱动太新固件不认”的情况。然后进一步确认内核版本uname -r如果服务器带网络管理工具或安全加固策略内核版本受限这会影响驱动能否加载。装驱动前最好先把nouveau开源驱动拉黑禁用否则新一代NVIDIA官方驱动和nouveau模块容易起冲突导致不亮屏或驱动加载不上。禁用nouveau的方法是在/etc/modprobe.d/blacklist-nouveau.conf里写入blacklist nouveau options nouveau modeset0然后执行update-initramfs -u并重启。缺少这一步驱动安装器往往会在检测阶段直接退出报“You appear to be running an X server”或无法加载内核模块。4.2 使用runfile方式安装驱动和CUDA先卸载旧驱动如果有apt remove --purge nvidia-*然后执行驱动runfilechmod x NVIDIA-Linux-x86_64-535.xxx.run sudo ./NVIDIA-Linux-x86_64-535.xxx.run --no-opengl-files--no-opengl-files是我强烈建议加的。这台机器如果只是做计算不接显示器加它就能避免覆盖系统OpenGL库导致图形界面启动失败。如果以后要接显示器跑可视化程序再考虑不加。接着装CUDA Toolkitsudo sh cuda_11.8.0_520.61.06_linux.run --toolkit --silenttail一段安装日志看到“Driver: Not Selected”或“Toolkit: Installed”才算成功。这个runfile同时包含了匹配的驱动但我们在前面已经单独装过最新驱动了所以在这里只选择装toolkit即可避免驱动版本被降级。装完在/etc/profile.d/cuda.sh里写入环境变量export PATH/usr/local/cuda/bin:$PATH export LD_LIBRARY_PATH/usr/local/cuda/lib64:$LD_LIBRARY_PATHCUDA Toolkit支持多版本共存安装目录通常带版本后缀比如/usr/local/cuda-11.8/usr/local/cuda只是个软链接。4.3 cuDNN解压拷贝cuDNN安装非常简单解压tar包后把相关头文件和库文件复制到CUDA目录tar -xzvf cudnn-linux-x86_64-8.9.x.x_linux.tar.xz sudo cp cudnn/include/cudnn*.h /usr/local/cuda-11.8/include/ sudo cp cudnn/lib/libcudnn* /usr/local/cuda-11.8/lib64/ sudo chmod ar /usr/local/cuda-11.8/include/cudnn*.h /usr/local/cuda-11.8/lib64/libcudnn*拷贝完后执行ldconfig这一步把新加入的动态库缓存起来避免运行时找不到.so文件。很多新手装了cuDNN却报“libcudnn_cnn.so.8 cannot open shared object file”八成就是忘了ldconfig或者拷错了目录。4.4 Python层安装优先级比想象中高不少教程把Python放到最后其实建议在装完驱动后立刻装Python环境。因为后面安装业务依赖时很多包要现场编译系统中没有合适的Python环境会导致寸步难行。如果服务器里原本没有Python 3.10有两个选择一是用conda安装二是编译源码。离线环境里编译Python源码不是特别推荐因为编译需要一堆系统依赖openssl、readline、sqlite开发包等容易越搞越复杂。所以我的建议是在有网机器上提前下载好Miniconda对应的安装脚本拷过去静默安装。bash Miniconda3-py310_24.x.x-Linux-x86_64.sh -b -p /home/xxx/miniconda3-b表示安静模式-p指定安装路径。装完以后用之前导出的环境配置或离线wheel包继续安装工作。4.5 离线pip安装的完整命令把offline_packages目录拷到服务器任意位置后inactivepip install --no-index --find-links./offline_packages torch torchvision torchaudio如果你还要安装其他业务依赖就一个一个加到命令尾部或者用-r requirements.txt批量安装。但要注意--no-index意味着pip不会去任何远程源查询所以requirements.txt里所有包必须已经提前下载到了offline_packages。如果漏了一个整个安装直接失败而不是缺哪个补哪个。4.6 一个高明的小技巧先搭好一个可复用的“干净环境”我在给多台内网机器部署的时候通常不会重复“先装驱动再装CUDA再装Python”这个流程。第一次操作时我会把装好的conda环境连同CUDA Toolkit目录一起打包存成一个tar归档。第二台机器只用驱动层重装一次Python层直接解压归档改动路径后即可使用。这个操作能省很多时间建议你也这样做。打包Python环境用conda-packCUDA Toolkit目录直接tar打包即可。5. 验证与收尾不要装完就跑装完不代表能用必须做一轮完整验证。我推荐一个固定动作清单5.1 验证驱动和CUDA层级nvidia-smi nvcc -Vnvidia-smi能看到显卡型号、驱动版本、显存占用nvcc -V能看到CUDA Toolkit版本。这两个命令一个管驱动、一个管路编译器必须都对得上才行。再验证cuDNN版本cat /usr/local/cuda/include/cudnn_version.h | grep CUDNN_MAJOR -A 2如果用的是新版cuDNN头文件可能是cudnn_version.h旧版是cudnn.h看实际情况调整。5.2 验证Python和深度学习框架版本python -c import torch; print(torch.__version__); print(torch.cuda.is_available()); print(torch.version.cuda)这一步是集体验证torch.cuda.is_available()返回True说明CUDA可用如果返回False而驱动和CUDA都正常十有八九是PyTorch的wheel选错了版本比如装成了CPU版或CUDA版本不匹配。5.3 再验证能不能跑真正的分布式训练场景我自己还会跑一段小规模矩阵乘法和一个简单CNN训练确认把数据放到GPU上能正常计算、显存能正确分配。如果机器配了多卡也顺便验证torch.distributed通信python -m torch.distributed.run --nproc_per_node2 train_test.py这一步看起来“只是验证”但实际作用很大。因为很多环境问题在import阶段是暴露不出来的真正跑到多卡通信时才会现形比如NCCL库缺失或版本不匹配。早发现早处理总比业务上线前一天炸掉好。5.4 常见故障排查参考表现象可能原因处理方向nvidia-smi正常nvcc找不到CUDA Toolkit未装或PATH未配置确认/usr/local/cuda/bin加入PATHnvcc -V正常PyTorch报CUDA不可用PyTorch为CPU版或与CUDA版本不匹配重新下载对应CUDA版本wheel包import cv2报libGL.so.1缺失缺系统图像库dpkg -i libgl1_*.deb等系统依赖pip安装时一直Failed to build wheel缺编译工具/头文件先装build-essential和对应dev包import torch报libc10_cuda.so找不到CUDA库目录未加入LD_LIBRARY_PATH确认/usr/local/cuda/lib64入库新驱动装不上报nouveau冲突未拉黑nouveau按上文blacklist步骤处理多卡通信初始化超时NCCL库缺失或版本过低单独下载NCCL库并拷贝这张表是我离线部署过程中遇到的高频问题基本上每个都踩过一遍。6. 写在最后给内网环境留一条“自我诊断”的路这次完整梳理下来其实可以发现离线安装深度学习环境的核心不复杂提前规划版本链条、备齐依赖、按层次安装、用固定命令验证。真正的难点在于两眼一抹黑——不知道机器上缺什么不知道缺的那个用什么方式补也不知道装完了到底对不对。我的习惯是在交付环境前顺手把宿主机器上能用的诊断脚本一起拷过来。比如用一个Python脚本进去直接输出torch版本、cuda版本、驱动版本、cuDNN版本、系统库缺失情况。以后任何一台新机器交接时先跑一遍脚本比人肉敲几十条命令要快得多也能把可能的隐患提前炸出来。最后再强调一句离线环境最怕的是“一次装完只验证import”。深度学习环境不是一个import就能证明可用的环境至少要让真实训练脚本跑通一个batch看到GPU利用率和显存都被真实占用后再宣布交付。这样下一次业务方找你说“环境有问题”时你至少可以底气十足地回复驱动、CUDA、cuDNN、框架我都验证过了剩下的问题大概率在业务依赖侧。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑