器深度學習環(huán)境配置:PyTorch/TensorFlow與遠程連接排坑指南)
實驗室服務(wù)器這個東西我接手實驗室管理快三年了每年開學都能看到新同學在同一個地方栽跟頭PyTorch裝上跑不了GPUTensorFlow和CUDA版本對不上visdom啟動后瀏覽器一片空白Jupyter在服務(wù)器上起了但本地死活打不開最后還有PyCharm遠程連不上的連環(huán)坑。這篇文章就把我這些年處理過的實驗室服務(wù)器使用問題系統(tǒng)整理一遍從PyTorch、TensorFlow安裝到visdom可視化服務(wù)再到本地調(diào)用服務(wù)器的Jupyter和PyCharm遠程連接每一步的坑和正確操作都寫清楚適合所有剛進實驗室、準備在公共服務(wù)器上動手跑實驗的同學參考。先說個基本判斷這類問題百分之八十不是玄學而是環(huán)境不一致導(dǎo)致的。服務(wù)器上裝的驅(qū)動、CUDA版本、Python版本、包管理器任何一個環(huán)節(jié)和你的預(yù)期偏差一點后面就是連環(huán)報錯。所以這篇文章的核心思路是先幫你把環(huán)境基線摸清楚再逐個擊破安裝和遠程連接問題。1. 先搞清楚服務(wù)器環(huán)境的三件事能避開一半的坑1.1 服務(wù)器權(quán)限邊界你不是一個人在戰(zhàn)斗實驗室服務(wù)器通常是多用戶共享的這意味著你大概率沒有root權(quán)限系統(tǒng)級的/usr/bin/python、系統(tǒng)級的pip都不是你能隨便動的。很多安裝問題本質(zhì)上是你在沒有權(quán)限的系統(tǒng)目錄里嘗試寫文件被拒絕后又換了個奇怪的方式硬裝最后把環(huán)境搞亂。我的建議很簡單永遠優(yōu)先使用conda創(chuàng)建自己的虛擬環(huán)境。conda不需要root安裝到自己的home目錄下環(huán)境隔離干凈刪了重來也不影響別人。很多同學問我為什么我pip裝個包老是Permission denied一看就是在系統(tǒng)目錄下執(zhí)行了pip install。如果是用conda環(huán)境這類權(quán)限問題基本不會出現(xiàn)。如果你連conda都沒有先去你個人的home目錄下裝一個Miniconda安裝的時候全選默認路徑即可包管理器會自動配置到你的~/.bashrc里。裝完之后重新登錄conda -V能輸出版本號就說明環(huán)境隔離的基礎(chǔ)打好了。1.2 CUDA、顯卡驅(qū)動、深度學習框架的三角關(guān)系很多同學把安裝CUDA理解成裝一個軟件實際上服務(wù)器上的CUDA體系分成兩層驅(qū)動層NVIDIA驅(qū)動由服務(wù)器管理員安裝普通用戶不能動。用nvidia-smi看到的信息屬于這一層。CUDA Toolkit層包含了nvcc等編譯工具和CUDA運行庫可以裝多個版本也可以由conda在虛擬環(huán)境內(nèi)安裝不需要root。PyTorch和TensorFlow運行時依賴的是驅(qū)動層和它自己打包的CUDA運行庫。它們并不直接調(diào)用系統(tǒng)里的nvcc所以關(guān)鍵在于驅(qū)動版本是否支持你想要的CUDA runtime版本。用nvidia-smi看右上角的CUDA Version這里顯示的其實是驅(qū)動支持的最高CUDA版本不是當前生效的版本。只要驅(qū)動支持的CUDA版本高于你想要安裝的框架所要求的CUDA版本一般就能跑。舉個例子nvidia-smi顯示CUDA 12.2你裝PyTorch的cu121或cu118版本都沒問題因為驅(qū)動向下兼容。最煩的情況是舊驅(qū)動搭配新版框架比如驅(qū)動只支持CUDA 11.8你非裝默認的cu124版PyTorch框架一加載CUDA就報driver version is too old。遇到這個報錯不用問去裝對應(yīng)低CUDA的PyTorch版本。1.3 conda環(huán)境一套環(huán)境一套依賴別混裝我強烈建議你為每個項目單獨建一個conda環(huán)境而不是在同一個環(huán)境里既裝PyTorch又裝TensorFlow還裝一堆別的包??缈蚣艿囊蕾嚊_突是真實存在的尤其是numpy和cudatoolkit這類基礎(chǔ)庫PyTorch對numpy版本有要求TensorFlow的numpy限制更嚴格混裝之后不是你覆蓋我就是我覆蓋你最典型的就是numpy.core.multiarray failed to import這類詭異報錯?;静僮魇莄onda create -n myenv python3.9 conda activate myenv然后把該項目的所有依賴通過requirements文件一次性裝好。如果后面發(fā)現(xiàn)裝壞了直接conda env remove -n myenv重建五分鐘就能回到干凈狀態(tài)比在系統(tǒng)環(huán)境里慢慢修復(fù)高效得多。2. PyTorch安裝問題不是pip install就完事了2.1 先看驅(qū)動再選cu版本最后定安裝命令PyTorch的安裝命令官網(wǎng)會給得很清楚但問題是很多人不看官網(wǎng)直接pip install torch這通常會裝上CPU版本或者一個和你服務(wù)器驅(qū)動不匹配的GPU版本。你裝完一測torch.cuda.is_available()返回False就開始懷疑人生。正確的順序是在服務(wù)器上執(zhí)行nvidia-smi看驅(qū)動版本和它支持的CUDA版本。去PyTorch官網(wǎng)選擇你需要的CUDA版本比如cu118、cu121、cu124。復(fù)制官網(wǎng)給出的pip命令在conda環(huán)境下執(zhí)行。舉個例子驅(qū)動支持CUDA 11.8那你應(yīng)該用pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118如果你已經(jīng)在官網(wǎng)選了對應(yīng)版本它生成的命令里會帶上--index-url不要自己改。安裝完成后用三行代碼驗收import torch print(torch.__version__) print(torch.cuda.is_available()) print(torch.cuda.get_device_name(0))第一行確認版本第二行返回True說明檢測到顯卡第三行能看到你的顯卡型號。這三行都正常PyTorch的GPU支持就算通了。2.2 下載慢、超時中斷的問題怎么破實驗室網(wǎng)絡(luò)環(huán)境經(jīng)常不穩(wěn)定從官方源下載幾個GB的PyTorch包跑到一半斷掉是家常便飯。pip默認遇到超時會直接失敗所以建議加長超時時間并開啟重試pip install --timeout 120 --retries 5 torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118如果網(wǎng)絡(luò)實在太差可以試試先下載whl文件到本地再用pip安裝。找到對應(yīng)版本和平臺的wheel文件下載完成后執(zhí)行pip install ./torch-xxx.whl這種方法不依賴網(wǎng)絡(luò)持續(xù)穩(wěn)定斷了就重新下。另外pip下載的緩存在~/.cache/pip同一個包你已經(jīng)下過一次沒裝成功第二次安裝會直接用緩存速度會快很多。如果你想強制重新下載可以加--no-cache-dir但通常沒必要。2.3 裝完跑不起來先看這五個常見報錯我遇到過太多次明明裝好了但就是不能用把最常見的幾個報錯和解決辦法列成表你們可以對照自查。報錯信息原因解決方案ModuleNotFoundError: No module named torch包沒裝進當前環(huán)境檢查conda環(huán)境和pip對應(yīng)關(guān)系torch.cuda.is_available()為False裝成CPU版本或驅(qū)動不支持卸載后按CUDA版本重裝CUDA driver version is too old驅(qū)動版本太低裝對應(yīng)低CUDA版的PyTorchlibcudnn.so.8: cannot open shared object filecuDNN版本不匹配用官網(wǎng)命令重裝或安裝對應(yīng)cudnnOutOfMemoryError顯存不足減小batch size或模型規(guī)模其中第一個坑最隱蔽。你在conda環(huán)境里執(zhí)行pip install但實際安裝到了base環(huán)境或系統(tǒng)環(huán)境這是因為pip命令被別名指向了其他地方。遇到這個情況檢查which pip確認是不是指向了你當前環(huán)境的bin目錄。用python -m pip install這種寫法可以繞開路徑混亂問題。3. TensorFlow安裝的坑版本對齊比想象中難3.1 TensorFlow 2.x的CUDA要求官方說了算TensorFlow對CUDA和cuDNN的版本要求比PyTorch嚴格得多。PyTorch把CUDA運行庫打包進wheel安裝包裝完基本能跑TensorFlow則是運行時動態(tài)加載系統(tǒng)的CUDA庫版本不匹配直接給一長串warning然后告訴你Could not load dynamic library libcudnn.so.8。如果你用conda裝TensorFlow最簡單的辦法是讓conda自動解決依賴。在conda環(huán)境中執(zhí)行conda install tensorflow-gpuconda會幫你裝好匹配的cudatoolkit和cudnn。如果你堅持用pip那就必須嚴格對照官方表。比如TensorFlow 2.10.0官方對應(yīng)的是CUDA 11.2和cuDNN 8.1。TensorFlow從2.11開始Linux版的pip包默認不帶GPU支持了需要裝tensorflow[and-cuda]這個版本別搞混了。3.2 和PyTorch共存時的依賴沖突別頭鐵我在第一節(jié)提過強烈建議PyTorch和TensorFlow分環(huán)境裝。這里再補充一個真實場景如果非要在同一環(huán)境裝兩個框架最常見的沖突點是numpy。TensorFlow 2.10要求numpy1.24某個小版本而PyTorch 2.x可能要求更高的numpy。一旦numpy被更新TensorFlow直接報numpy.AxisError之類的問題。遇到這種情況不要試圖手動鎖定一個numpy版本去滿足兩邊因為根本鎖不住。最干凈的操作是conda create -n tf_env python3.9 conda create -n torch_env python3.9兩個環(huán)境各自獨立使用的時候conda activate切換互不干擾。磁盤占用多幾個GB但換來的是心平氣和。3.3 從報錯信息快速定位三分靠猜七分靠查TensorFlow的報錯信息長但關(guān)鍵信息往往在最后幾行。一個常見的錯誤模式是長長的DNN library is missing這基本就是cuDNN沒找到。另一種是tf.test.is_gpu_available()返回False需要先跑一下診斷import tensorflow as tf print(tf.config.list_physical_devices(GPU))如果列表是空的接著執(zhí)行l(wèi)dconfig -p | grep libcudnn看看服務(wù)器上裝了哪些cuDNN版本。沒有輸出說明系統(tǒng)層沒有cuDNN。如果是conda環(huán)境執(zhí)行conda list | grep cudnn看環(huán)境內(nèi)是否包含cuDNN。這兩步查下來問題出在哪一層就清楚了。4. Visdom安裝后打不開可視化服務(wù)的前世今生4.1 visdom的正確啟動方式很多人第一步就錯了visdom是Facebook開源的深度學習可視化工具在PyTorch社區(qū)很流行。它由兩部分組成Python客戶端和Web服務(wù)端。你安裝完pip install visdom之后必須單獨啟動一個服務(wù)進程瀏覽器才能看到可視化面板。很多人裝完直接跑訓練代碼然后瀏覽器訪問http://localhost:8097看到空白或者連不上就開始懷疑安裝有問題。正確啟動方式是在服務(wù)器上執(zhí)行python -m visdom.server默認監(jiān)聽8097端口??吹捷敵鯥ts Alive!之類的信息就說明服務(wù)啟動成功了。這時候再訪問http://服務(wù)器IP:8097就能看到visdom的Web界面。注意要訪問服務(wù)器的IP不是localhost除非你就在服務(wù)器本機操作。4.2 啟動報錯與端口占用最常見的兩個故障visdom啟動時最常見的報錯是端口被占用。你可以用netstat -tlnp | grep 8097查看端口占用情況如果有進程占了換個端口啟動python -m visdom.server -port 8098然后你的客戶端代碼里也要對應(yīng)修改import visdom vis visdom.Visdom(port8098)另一個高頻報錯是ConnectionRefusedError這通常是服務(wù)端沒有成功啟動。有時和網(wǎng)絡(luò)代理沖突有關(guān)項目里如果設(shè)了HTTP_PROXY之類的環(huán)境變量容易干擾本地回環(huán)連接可以試試unset HTTP_PROXY HTTPS_PROXY python -m visdom.server4.3 visdom的替代方案與遷移建議visdom本身已經(jīng)維護不太活躍如果你是新項目我建議考慮替代方案。TensorBoard其實也能看PyTorch的指標曲線配合torch.utils.tensorboard體驗更穩(wěn)定。另一個好用的工具是wandb云端記錄訓練曲線不需要自己維護服務(wù)團隊協(xié)作方便。如果只是偶爾看個損失曲線matplotlib直接畫圖存文件也比啟動一個服務(wù)省事得多。當然如果你確實需要用visdom上面的啟動方法足夠應(yīng)對。記著一點visdom的服務(wù)端進程要一直開著訓練腳本里的客戶端負責往服務(wù)端推數(shù)據(jù)兩者分開理解問題就少一半。5. 本地瀏覽器遠程調(diào)用服務(wù)器JupyterSSH隧道與端口映射5.1 遠程訪問Jupyter的原理一張白紙說清楚服務(wù)器上的Jupyter默認監(jiān)聽8888端口但服務(wù)器的8888端口通常不對公網(wǎng)開放。你需要做的是把服務(wù)器的8888端口搬到本地電腦上然后訪問http://localhost:8888數(shù)據(jù)會通過SSH加密通道傳送。這就是SSH隧道也叫端口轉(zhuǎn)發(fā)是實驗室遠程訪問Jupyter最標準的方式安全系數(shù)高配置也簡單。5.2 一條命令搞定臨時隧道在本地電腦上執(zhí)行ssh -L 8888:localhost:8888 your_usernameserver_ip這條命令的含義是把本地的8888端口通過SSH連接映射到服務(wù)器的localhost:8888。執(zhí)行后會登錄到服務(wù)器你先正常執(zhí)行jupyter notebook --port8888 --no-browser啟動Jupyter然后保持這個SSH會話不要關(guān)閉。另開一個本地瀏覽器訪問http://localhost:8888就能看到Jupyter界面。如果你想免去每次輸密碼的麻煩把本地公鑰加到服務(wù)器的~/.ssh/authorized_keys中。這樣后面的SSH連接都不用輸密碼隧道命令體驗順暢很多。5.3 用~/.ssh/config固化配置一條別名走天下如果你每次都敲一長串SSH命令很容易膩。更優(yōu)雅的做法是在本地~/.ssh/config里寫一個配置段Host labserver HostName 192.168.1.100 User your_username Port 22 LocalForward 8888 localhost:8888配置好之后本地終端只要執(zhí)行ssh labserver就會自動建立隧道并登錄服務(wù)器。然后服務(wù)器上照常啟動Jupyter本地訪問localhost:8888就能用。這種方式的額外好處是你在公司或宿舍都能用同一個別名連接IP變了就改一下配置文件。5.4 Jupyter的token與密碼問題新版Jupyter啟動時會給一個token你需要在瀏覽器里粘貼token才能登錄。如果覺得麻煩可以先在服務(wù)器上設(shè)置密碼jupyter notebook password設(shè)置完成后Jupyter會使用密碼登錄本地訪問時直接輸入密碼就行。另外Jupyter默認只允許本機訪問如果你通過SSH隧道訪問這個限制完全沒問題因為隧道在本地看來就是本機訪問。還要提醒一點不要在服務(wù)器上直接執(zhí)行jupyter notebook --ip0.0.0.0來開放所有IP訪問除非你非常清楚自己在做什么。實驗室公共網(wǎng)絡(luò)環(huán)境下裸奔式開放的Jupyter容易被掃描器盯上輕則挖礦重則數(shù)據(jù)泄露。SSH隧道是安全性和便利性最均衡的方案。6. PyCharm遠程連接服務(wù)器把編輯器搬進服務(wù)器環(huán)境6.1 遠程解釋器配置三分鐘搞定代碼編寫與運行PyCharm Professional版本支持遠程解釋器功能可以在本地寫代碼、本地調(diào)試實際運行在服務(wù)器環(huán)境。個人我用這個功能很久了配合前面說的conda虛擬環(huán)境體驗接近本地開發(fā)。配置路徑是Settings - Project - Python Interpreter - Add Interpreter - On SSH。填寫服務(wù)器的IP、用戶名、密碼后下一步會讓你選擇遠程Python解釋器路徑。如果你用的是conda環(huán)境比如環(huán)境名是myenv解釋器路徑一般是~/miniconda3/envs/myenv/bin/python選好后PyCharm會掃描遠程環(huán)境中的包并在本地顯示。你可以直接在本地新建Python文件選好解釋器后運行進程實際是在服務(wù)器上跑的。代碼可以同步到服務(wù)器的某個目錄比如~/projects/myproject。6.2 文件同步與路徑映射別讓代碼和可執(zhí)行文件分家遠程解釋器默認會把本地項目文件上傳到服務(wù)器某目錄但如果你遠程目錄和本地目錄結(jié)構(gòu)不一致會導(dǎo)致ModuleNotFoundError。我建議把遠程目錄設(shè)置成和本地項目一致的相對路徑。比如本地項目是D:/myproject遠程就設(shè)成~/myproject兩邊目錄層級一致import就很少出問題。在映射配置里PyCharm有一項Deployment你可以選擇自動上傳或手動上傳。我習慣用自動上傳模式這樣本地保存一次遠程文件就更新一次省心。6.3 調(diào)試器、終端和環(huán)境變量的聯(lián)動PyCharm遠程調(diào)試的體驗接近本地你可以打斷點、單步執(zhí)行、查看變量值關(guān)鍵是遠程解釋器必須有pydevd-pycharm這個包這個包一般在你連接解釋器時PyCharm會自動安裝到遠程環(huán)境。還有一個容易忽略的點遠程環(huán)境的環(huán)境變量。比如你的訓練腳本要讀取數(shù)據(jù)集的路徑這個路徑是服務(wù)器上的絕對路徑而你在本地運行調(diào)試時PyCharm會把當前工作目錄切換為遠程項目目錄這時候相對路徑其實不太可靠。我建議所有涉及文件路徑的地方都用絕對路徑或者從環(huán)境變量讀取避免本地和服務(wù)器之間來回踩坑。6.4 連接失敗的排查清單PyCharm遠程連接失敗的報錯通常比較直白但原因多種多樣。我按經(jīng)驗把排查順序列出來ssh: Connection refused確認服務(wù)器SSH服務(wù)在運行端口默認22。Server host key not found首次連接會詢問是否信任主機點是就行。Authentication failed密碼或用戶名錯誤檢查是否有拼寫問題。Permission denied可能是服務(wù)器限制密碼登錄需要改用密鑰認證。Interpreter not found你填的Python路徑不對在服務(wù)器上先執(zhí)行which python確認路徑。還有一個比較高發(fā)的問題服務(wù)器上Python環(huán)境是激活的conda環(huán)境但PyCharm連接時用的是.bashrc里沒有conda初始化的非交互shell導(dǎo)致解釋器找不到。這種情況可以在遠程環(huán)境的啟動腳本里加上source ~/.bashrc或者在解釋器路徑里直接把conda環(huán)境Python的絕對路徑寫死。7. 最后分享兩個我自己用下來的小技巧一個是安裝任何大型包之前先在conda環(huán)境里查一下已安裝的包版本用conda list大概了解下基礎(chǔ)環(huán)境避免裝到一半發(fā)現(xiàn)核心庫版本被改動。另一個是寫一個env_check.sh腳本把nvidia-smi、python --version、pip list這些關(guān)鍵信息一次性輸出到一個日志文件里遇到問題先看日志再解決省去反復(fù)排查的時間。這套流程我每年都會整理給實驗室的新同學照著走下來PyTorch、TensorFlow、visdom、Jupyter遠程訪問、PyCharm遠程連接這五座大山基本都能翻過去。真遇到?jīng)]見過的報錯也別慌把完整報錯貼到搜索框里先看最后三行再往上翻上下文絕大多數(shù)坑都有前人踩過。祝你在實驗室的服務(wù)器上跑得順利早點把時間留給真正要做的實驗。