環(huán)境:CUDA 與 PyTorch 配置實戰(zhàn))
1. 為什么我最終把 AI 開發(fā)環(huán)境整體搬進了 WSL21.1 從雙系統(tǒng)到 WSL2 的折騰史最早做深度學(xué)習(xí)那會兒我的方案是 Windows 加 Ubuntu 雙系統(tǒng)。每次要跑訓(xùn)練就得重啟切到 Linux 下面調(diào)代碼調(diào)完想查個資料又得切回 Windows一天下來光重啟就浪費不少時間。后來試過純 Linux 主機顯卡驅(qū)動、桌面環(huán)境、輸入法各種小毛病不斷日常辦公體驗確實不如 Windows 順手。再后來虛擬機也試過VMware 和 VirtualBox 都跑過但 GPU 直通要么不支持要么配置極其折騰性能損耗也大跑個小模型都費勁。直到 WSL2 成熟之后我才真正找到了一個平衡點。WSL2 本質(zhì)上是跑在輕量級虛擬化層上的完整 Linux 內(nèi)核不是以前 WSL1 那種系統(tǒng)調(diào)用翻譯層。這意味著它兼容原生 Linux 的 ELF 二進制文件Docker 能跑CUDA 也能跑。微軟和 NVIDIA 合作把 GPU 直通做進了 WSL2 的內(nèi)核里Windows 主機上的 NVIDIA 顯卡驅(qū)動可以直接被 WSL2 里的 Linux 發(fā)行版調(diào)用不需要在 Linux 里再單獨裝一遍驅(qū)動。這一點是質(zhì)變。我現(xiàn)在的主力方案就是Windows 11 負責日常辦公、瀏覽器、微信、OfficeWSL2 里的 Ubuntu 22.04 負責所有 AI 開發(fā)工作包括 PyTorch 訓(xùn)練、CUDA 編譯、數(shù)據(jù)處理腳本。兩邊文件系統(tǒng)互通剪貼板共享VS Code 直接遠程連進 WSL2 寫代碼體驗幾乎和原生 Linux 一樣但省去了雙系統(tǒng)切換的所有麻煩。1.2 這套方案到底適合誰如果你符合下面任意一條這套方案大概率能幫你省下大量時間主力機器是 Windows但需要 Linux 環(huán)境跑 PyTorch、TensorFlow 等框架有 NVIDIA 顯卡想讓 WSL2 里的代碼直接調(diào)用 GPU 做訓(xùn)練或推理不想折騰雙系統(tǒng)也不想忍受傳統(tǒng)虛擬機的性能損耗和 GPU 配置難題需要同時用 Windows 辦公軟件和 Linux 開發(fā)工具鏈想用 VS Code 或 Cursor 這類編輯器直接連進 Linux 環(huán)境寫代碼反過來說如果你用的是 AMD 顯卡想做 ROCm 開發(fā)或者需要特定的 Linux 桌面環(huán)境做圖形界面開發(fā)WSL2 目前的支持還不算完美這種情況可能還是原生 Linux 更合適。但對于絕大多數(shù)做深度學(xué)習(xí)、CUDA 編程、Python 開發(fā)的人來說WSL2 已經(jīng)是相當成熟的方案了。1.3 整體架構(gòu)一句話說清Windows 主機裝好 NVIDIA 驅(qū)動WSL2 里裝 Ubuntu 22.04Ubuntu 里裝 CUDA Toolkit 和 PyTorch代碼通過 VS Code Remote 連接編寫訓(xùn)練時 GPU 直接由 Windows 驅(qū)動接管。整個鏈路里WSL2 負責提供 Linux 用戶空間和內(nèi)核Windows 負責硬件驅(qū)動和 GPU 調(diào)度兩者通過微軟的 GPU 虛擬化層通信。理解這個架構(gòu)后面所有配置步驟的邏輯就都通了。2. 環(huán)境準備從零開始的完整配置流程2.1 Windows 側(cè)的前置檢查與 WSL2 啟用在動手之前先確認幾件事。第一Windows 版本必須是 Windows 10 版本 2004 及以上或者 Windows 11。第二確認 CPU 支持虛擬化在任務(wù)管理器性能標簽頁里看“虛擬化”是否顯示“已啟用”。如果沒啟用需要進 BIOS 打開 Intel VT-x 或 AMD-V。確認無誤后以管理員身份打開 PowerShell執(zhí)行下面這條命令wsl --install這條命令會自動完成幾件事啟用“適用于 Linux 的 Windows 子系統(tǒng)”可選功能、啟用“虛擬機平臺”功能、下載并安裝 WSL2 內(nèi)核更新包、把 WSL2 設(shè)為默認版本、安裝 Ubuntu 發(fā)行版。執(zhí)行完重啟電腦即可。如果你之前已經(jīng)裝過 WSL想確認版本可以運行wsl --list --verbose輸出里 VERSION 列顯示 2 就對了。如果顯示 1用wsl --set-version 發(fā)行版名 2轉(zhuǎn)換。注意有些機器上wsl --install會因為組策略或系統(tǒng)精簡原因失敗這時候需要手動在“啟用或關(guān)閉 Windows 功能”里勾選“適用于 Linux 的 Windows 子系統(tǒng)”和“虛擬機平臺”重啟后再執(zhí)行安裝命令。2.2 Ubuntu 22.04 的安裝與初始化我選 Ubuntu 22.04 LTS 而不是 24.04原因是 22.04 的 CUDA 和 PyTorch 生態(tài)兼容性經(jīng)過大量驗證踩坑最少。安裝命令wsl --install -d Ubuntu-22.04安裝完成后會提示創(chuàng)建用戶名和密碼這個用戶名和密碼是 Linux 系統(tǒng)內(nèi)的和 Windows 賬戶無關(guān)。創(chuàng)建完成后就進入了 Ubuntu 的終端。第一件事是更新軟件源sudo apt update sudo apt upgrade -y然后裝一些基礎(chǔ)工具后面編譯和調(diào)試都會用到sudo apt install -y build-essential git curl wget vim python3-pip python3-venv這里有個經(jīng)驗WSL2 默認的 apt 源在國內(nèi)訪問速度一般可以換成國內(nèi)鏡像源。編輯/etc/apt/sources.list把archive.ubuntu.com和security.ubuntu.com替換成清華或阿里的鏡像地址更新速度能從幾十 KB 提升到幾 MB。2.3 Windows 顯卡驅(qū)動的確認這一步是 GPU 直通的關(guān)鍵。WSL2 里的 CUDA 不依賴 Linux 側(cè)的 NVIDIA 驅(qū)動而是直接調(diào)用 Windows 主機上的驅(qū)動。所以你要做的是在 Windows 上安裝最新版的 NVIDIA 顯卡驅(qū)動而不是在 WSL2 里裝驅(qū)動。去 NVIDIA 官網(wǎng)下載對應(yīng)你顯卡型號的 Game Ready 或 Studio 驅(qū)動安裝完成后在 Windows 命令行運行nvidia-smi能看到顯卡信息和驅(qū)動版本就說明 Windows 側(cè)沒問題。記住這個驅(qū)動版本號后面裝 CUDA Toolkit 時要參考它支持的 CUDA 版本上限。注意千萬不要在 WSL2 里執(zhí)行apt install nvidia-driver-xxx這會把 Linux 側(cè)的驅(qū)動裝進去和 Windows 驅(qū)動沖突導(dǎo)致 GPU 無法調(diào)用。WSL2 里只需要裝 CUDA Toolkit不需要裝驅(qū)動。2.4 驗證 GPU 是否已經(jīng)直通進 WSL2在 WSL2 終端里運行nvidia-smi如果輸出和 Windows 側(cè)一致說明 GPU 直通已經(jīng)生效。如果提示 command not found說明 CUDA Toolkit 還沒裝但驅(qū)動層面其實已經(jīng)通了裝完 Toolkit 就能用。如果提示找不到設(shè)備檢查 Windows 驅(qū)動版本是否太舊或者 WSL2 內(nèi)核是否需要更新運行wsl --update。這一步是整個方案的地基地基沒打好后面全是坑。我見過太多人卡在這里反復(fù)在 WSL2 里裝驅(qū)動結(jié)果越裝越亂。3. CUDA 與 PyTorch 的安裝版本匹配是核心3.1 CUDA Toolkit 的版本選擇邏輯CUDA 版本選擇不是越新越好而是要看三個東西的交叉點Windows 驅(qū)動支持的最高 CUDA 版本、PyTorch 官方支持的 CUDA 版本、你的顯卡算力是否被支持。先看 Windows 驅(qū)動支持的最高版本運行nvidia-smi右上角會顯示CUDA Version: 12.x這是驅(qū)動能支持的上限。然后去 PyTorch 官網(wǎng)看當前穩(wěn)定版支持的 CUDA 版本通常有 11.8、12.1、12.4 幾個選項。取兩者的交集再選一個較新的穩(wěn)定版本。以我目前的配置為例驅(qū)動支持到 CUDA 12.4PyTorch 2.4 支持 CUDA 12.1 和 12.4我選 12.1因為生態(tài)兼容性更好很多第三方庫對 12.1 的支持更成熟。安裝 CUDA Toolkit 推薦用 NVIDIA 官方倉庫的方式比 runfile 更干凈wget https://developer.download.nvidia.com/compute/cuda/repos/wsl-ubuntu/x86_64/cuda-keyring_1.1-1_all.deb sudo dpkg -i cuda-keyring_1.1-1_all.deb sudo apt update sudo apt install -y cuda-toolkit-12-1注意這里用的是wsl-ubuntu倉庫不是普通的ubuntu2204倉庫這是專門為 WSL2 準備的包依賴關(guān)系不一樣。3.2 環(huán)境變量的配置細節(jié)裝完之后需要配置環(huán)境變量編輯~/.bashrc在末尾加上export PATH/usr/local/cuda-12.1/bin:$PATH export LD_LIBRARY_PATH/usr/local/cuda-12.1/lib64:$LD_LIBRARY_PATH然后source ~/.bashrc生效。驗證nvcc --version能輸出版本信息就說明 CUDA Toolkit 裝好了。注意LD_LIBRARY_PATH這一行很多人會漏掉導(dǎo)致編譯時找不到 CUDA 動態(tài)庫。另外如果你裝了多個 CUDA 版本通過修改 PATH 里的路徑來切換不要用update-alternatives在 WSL2 里那個方式容易出問題。3.3 PyTorch 安裝的三種方式對比PyTorch 安裝方式主要有三種pip 直接裝、conda 裝、源碼編譯。我的建議是優(yōu)先用 pip 配合虛擬環(huán)境原因如下表安裝方式優(yōu)點缺點適用場景pip venv輕量、版本可控、官方 wheel 直接下載需要手動管理虛擬環(huán)境絕大多數(shù)場景conda依賴管理強、科學(xué)計算包全體積大、有時和系統(tǒng) CUDA 沖突需要大量科學(xué)計算庫源碼編譯可定制、支持最新特性耗時長、容易失敗需要特定優(yōu)化或最新功能我一般用 venvpython3 -m venv ~/venvs/torch source ~/venvs/torch/bin/activate pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121這里的cu121對應(yīng) CUDA 12.1必須和前面裝的 CUDA Toolkit 版本一致否則會出現(xiàn)版本不匹配的警告甚至運行錯誤。3.4 驗證 PyTorch 能否調(diào)用 GPU裝完后寫個最簡單的驗證腳本import torch print(PyTorch version:, torch.__version__) print(CUDA available:, torch.cuda.is_available()) print(CUDA version:, torch.version.cuda) print(GPU count:, torch.cuda.device_count()) print(GPU name:, torch.cuda.get_device_name(0))如果CUDA available輸出 True說明整條鏈路打通了。如果輸出 False按下面順序排查先確認nvidia-smi在 WSL2 里能跑再確認 PyTorch 版本和 CUDA 版本是否匹配最后檢查是不是裝成了 CPU 版本的 PyTorch用pip list | grep torch看版本號后面有沒有cu121后綴。4. 開發(fā)工作流的搭建與優(yōu)化4.1 VS Code Remote 連接 WSL2這是我認為 WSL2 方案里體驗最好的部分。在 Windows 上裝好 VS Code然后裝一個叫 WSL 的官方擴展。裝完后按 F1輸入WSL: Connect to WSLVS Code 就會在 WSL2 里啟動一個服務(wù)端界面還是 Windows 的但終端、文件系統(tǒng)、Python 解釋器全部是 WSL2 里的。這意味著你可以在 Windows 的 VS Code 里寫代碼代碼實際存在 Linux 文件系統(tǒng)里運行時用的是 Linux 的 Python 和 CUDA。調(diào)試、斷點、變量查看全部正常。而且因為文件在 Linux 側(cè)IO 性能比放在/mnt/c/下好很多。注意項目文件一定要放在 WSL2 的 Linux 文件系統(tǒng)里比如~/projects/不要放在/mnt/c/Users/xxx/下??缥募到y(tǒng)訪問的 IO 性能差距在大量小文件讀寫時非常明顯訓(xùn)練時加載數(shù)據(jù)集能差出好幾倍。4.2 數(shù)據(jù)集與模型文件的存放策略WSL2 的磁盤空間默認是動態(tài)擴展的但上限受 Windows 磁盤剩余空間限制。數(shù)據(jù)集大的話建議單獨掛載一塊 Windows 磁盤到 WSL2 里或者用wsl --mount掛載物理磁盤。我自己的做法是代碼和虛擬環(huán)境放在 WSL2 默認的 ext4 文件系統(tǒng)里數(shù)據(jù)集放在 Windows 的 D 盤通過/mnt/d/datasets/訪問。雖然跨文件系統(tǒng)有性能損耗但數(shù)據(jù)集通常是大文件順序讀取損耗可以接受而且方便在 Windows 側(cè)用工具管理和備份。如果數(shù)據(jù)集特別大且讀取頻繁可以考慮在 WSL2 里單獨掛一塊虛擬磁盤VHD格式化成 ext4性能接近原生。4.3 終端與 Shell 的個性化配置WSL2 默認的終端是 Windows Terminal體驗已經(jīng)不錯。我一般會做幾件事裝 zsh 和 oh-my-zsh配置一些常用別名裝 tmux 做會話管理。常用別名示例alias gsgit status alias llls -alF alias nvnvidia-smi alias actsource ~/venvs/torch/bin/activatetmux 在跑長時間訓(xùn)練時特別有用SSH 斷開或者終端關(guān)閉后訓(xùn)練進程不會中斷。配合nohup或者直接tmux new -s train開一個會話訓(xùn)練跑起來后 detach隨時可以 reattach 查看進度。4.4 性能調(diào)優(yōu)的幾個關(guān)鍵點WSL2 默認會占用較多內(nèi)存可以在 Windows 用戶目錄下創(chuàng)建.wslconfig文件限制資源[wsl2] memory32GB processors16 swap8GB這個配置根據(jù)你機器的實際內(nèi)存調(diào)整一般給 WSL2 分配總內(nèi)存的一半到三分之二比較合適。內(nèi)存給太少訓(xùn)練時容易 OOM給太多 Windows 側(cè)會卡。GPU 方面WSL2 的 CUDA 性能損耗在 5% 到 10% 左右主要來自虛擬化層的通信開銷。對于大多數(shù)訓(xùn)練任務(wù)來說可以接受。如果追求極致性能可以考慮用--gpu-support相關(guān)的優(yōu)化參數(shù)但實際提升有限。磁盤 IO 是 WSL2 相對薄弱的環(huán)節(jié)尤其是跨文件系統(tǒng)訪問。如果訓(xùn)練時數(shù)據(jù)加載是瓶頸可以考慮把數(shù)據(jù)集預(yù)處理成單個大文件比如 LMDB 或 HDF5 格式減少小文件隨機讀取。5. 常見問題與排查實錄5.1 GPU 相關(guān)問題的排查思路問題一nvidia-smi在 WSL2 里提示找不到命令這通常是因為 CUDA Toolkit 沒裝或者 PATH 沒配好。先確認 Windows 側(cè)nvidia-smi能跑然后在 WSL2 里檢查/usr/local/cuda-12.1/bin是否在 PATH 里。如果 CUDA 裝了但命令找不到多半是.bashrc沒 source 或者路徑寫錯了。問題二PyTorch 顯示 CUDA available 為 False按這個順序排查第一nvidia-smi在 WSL2 里能不能跑第二PyTorch 版本是不是 CPU 版第三CUDA Toolkit 版本和 PyTorch 編譯版本是否匹配第四Windows 驅(qū)動版本是否太舊。我遇到過最常見的原因是裝成了 CPU 版 PyTorch用pip list一看版本號沒有cu后綴就知道了。問題三訓(xùn)練時報 CUDA out of memoryWSL2 里 GPU 顯存是直接透傳的和 Windows 側(cè)共享。如果 Windows 側(cè)有程序占著顯存比如瀏覽器硬件加速、游戲WSL2 里能用的顯存就會減少。訓(xùn)練前關(guān)掉不必要的 GPU 占用程序。另外.wslconfig里可以設(shè)置gpuMemoryLimit但一般不需要。5.2 網(wǎng)絡(luò)與下載速度問題WSL2 的網(wǎng)絡(luò)是 NAT 模式默認走 Windows 主機的網(wǎng)絡(luò)。pip 和 apt 下載慢的話換國內(nèi)源是最直接的方案。pip 換源pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simpleapt 換源前面提過編輯 sources.list 替換域名即可。如果遇到 WSL2 里 DNS 解析異??梢詸z查/etc/resolv.conf有時候需要手動指定 DNS 服務(wù)器。不過較新版本的 WSL2 已經(jīng)自動處理了這個問題一般不用管。5.3 文件系統(tǒng)與權(quán)限問題WSL2 里訪問 Windows 文件時權(quán)限顯示為 777這是正常的因為 NTFS 和 ext4 的權(quán)限模型不同。如果某些程序?qū)?quán)限敏感可以把文件復(fù)制到 Linux 文件系統(tǒng)里再操作。另一個常見問題是 Git 在跨文件系統(tǒng)時的換行符處理。建議在 WSL2 里配置git config --global core.autocrlf input這樣提交時統(tǒng)一轉(zhuǎn)成 LF避免 Windows 和 Linux 協(xié)作時的換行符混亂。5.4 常見問題速查表現(xiàn)象可能原因解決方法nvidia-smi 找不到CUDA Toolkit 未裝或 PATH 未配裝 CUDA Toolkit檢查 .bashrcCUDA available FalsePyTorch 是 CPU 版重裝 GPU 版 PyTorch訓(xùn)練 OOMWindows 側(cè)占用顯存關(guān)閉占用 GPU 的程序pip 下載慢默認源在國外換清華或阿里源文件讀寫慢跨文件系統(tǒng)訪問項目文件放 Linux 側(cè)WSL2 啟動失敗虛擬化未啟用或內(nèi)核舊檢查 BIOS運行 wsl --update內(nèi)存占用過高默認無限制配置 .wslconfig 限制6. 我踩過的幾個坑和最終建議6.1 驅(qū)動和 Toolkit 的版本陷阱我最早犯的錯是在 WSL2 里裝 NVIDIA 驅(qū)動結(jié)果和 Windows 驅(qū)動沖突GPU 完全用不了。后來才明白 WSL2 的 GPU 直通是 Windows 驅(qū)動負責硬件層Linux 側(cè)只需要 CUDA Toolkit 提供編譯和運行時庫。這個分工一定要搞清楚。另一個坑是 CUDA 版本和 PyTorch 版本不匹配。有次我裝了 CUDA 12.4但 PyTorch 當時只支持到 12.1結(jié)果torch.cuda.is_available()一直是 False。后來降級 CUDA 到 12.1 就正常了。所以版本匹配這件事寧可花十分鐘查清楚也不要憑感覺裝。6.2 磁盤空間和性能的平衡WSL2 的虛擬磁盤文件ext4.vhdx會隨著使用不斷增長但不會自動收縮。刪了大文件后vhdx 文件在 Windows 側(cè)看還是那么大??梢杂脀sl --manage 發(fā)行版 --set-sparse true開啟稀疏模式或者手動用 diskpart 壓縮。不過壓縮有風(fēng)險操作前備份重要數(shù)據(jù)。性能方面我的經(jīng)驗是代碼和虛擬環(huán)境放 Linux 側(cè)數(shù)據(jù)集放 Windows 側(cè)用/mnt/訪問模型 checkpoint 存 Linux 側(cè)。這樣兼顧了 IO 性能和磁盤空間管理。6.3 日常使用的幾個小技巧第一用 Windows Terminal 的標簽頁功能一個標簽跑訓(xùn)練一個標簽寫代碼一個標簽看日志切換很方便。第二VS Code 的 Remote WSL 模式下Python 解釋器要選 WSL2 里的 venv 路徑不要選 Windows 的 Python。第三訓(xùn)練腳本用tmux或者nohup跑避免終端關(guān)閉導(dǎo)致訓(xùn)練中斷。第四定期用wsl --shutdown完全關(guān)閉 WSL2 再重啟可以釋放一些緩存和僵尸進程尤其是長時間運行后。第五如果要用 DockerWSL2 里裝 Docker Engine 比用 Docker Desktop 更輕量性能也更好。裝完后配置 GPU 支持容器里也能直接用 CUDA。這套環(huán)境我從去年用到現(xiàn)在跑了十幾個訓(xùn)練項目穩(wěn)定性很好。唯一需要注意的是 Windows 更新后偶爾會重置 WSL2 的網(wǎng)絡(luò)配置遇到網(wǎng)絡(luò)問題時先wsl --shutdown重啟一下大部分情況都能解決。