環(huán)境實戰(zhàn)指南)
1. 為什么要在 Windows 上折騰內(nèi)核級 Linux 開發(fā)環(huán)境如果你是一個長期在 Windows 上做 AI 開發(fā)的工程師大概率經(jīng)歷過這樣的糾結(jié)Windows 的桌面生態(tài)和辦公軟件確實舒服但一旦要跑訓(xùn)練腳本、裝 CUDA、配各種 Python 依賴就總感覺隔了一層。早期大家用虛擬機(jī)性能損耗大GPU 直通配置復(fù)雜到讓人想砸鍵盤后來有人干脆裝雙系統(tǒng)結(jié)果每次切換都要重啟開發(fā)效率被切得稀碎。WSL2 的出現(xiàn)基本終結(jié)了這個糾結(jié)。它不是傳統(tǒng)的虛擬機(jī)也不是簡單的兼容層而是微軟在 Windows 內(nèi)核之上跑的一個真正的 Linux 內(nèi)核。你可以在 Windows 里直接打開一個終端里面跑的是完整的 Ubuntu 用戶態(tài)同時還能調(diào)用宿主機(jī)的 NVIDIA 顯卡做 CUDA 計算。這意味著什么意味著你可以在 Windows 上寫代碼、用 Windows 的瀏覽器查文檔同時在 Linux 環(huán)境里跑 PyTorch 訓(xùn)練而且 GPU 性能幾乎不打折。這套方案特別適合幾類人一是剛?cè)腴T AI、主力機(jī)器是 Windows 筆記本的學(xué)生和開發(fā)者二是公司配了 Windows 工作站但需要 Linux 工具鏈的工程師三是想在一臺機(jī)器上同時兼顧日常辦公和模型訓(xùn)練的獨立開發(fā)者。我自己從 WSL1 時代就開始用到 WSL2 加上 GPU 直通成熟之后基本上把主力開發(fā)環(huán)境整個搬了進(jìn)來踩過的坑和總結(jié)出來的配置方法正好借這篇整理一下。需要提前說明的是本文講的是在 Windows 上搭建本地 AI 開發(fā)環(huán)境所有操作都在本機(jī)完成不涉及任何遠(yuǎn)程連接或網(wǎng)絡(luò)代理相關(guān)的內(nèi)容。下面從環(huán)境準(zhǔn)備開始一步步把整套流程講清楚。2. 環(huán)境準(zhǔn)備版本、驅(qū)動與發(fā)行版選擇的那些細(xì)節(jié)2.1 Windows 版本與 WSL2 的硬性門檻WSL2 對 Windows 版本有明確要求。你需要 Windows 10 版本 1903 及以上內(nèi)部版本 18362 以上或者 Windows 11 任意版本。但這里有個很多人忽略的點即使你的系統(tǒng)版本號夠了如果沒開啟虛擬化相關(guān)的功能WSL2 照樣跑不起來。具體來說需要在 BIOS 里確認(rèn) CPU 虛擬化Intel VT-x 或 AMD-V已經(jīng)開啟然后在 Windows 功能里勾選虛擬機(jī)平臺和適用于 Linux 的 Windows 子系統(tǒng)兩個選項。我見過不少人卡在這一步裝完 WSL 之后啟動報錯折騰半天才發(fā)現(xiàn)是 BIOS 里虛擬化沒開。操作上用管理員權(quán)限打開 PowerShell執(zhí)行dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart執(zhí)行完重啟一次然后把 WSL2 設(shè)為默認(rèn)版本wsl --set-default-version 2注意如果你之前裝過 WSL1 的發(fā)行版升級到 WSL2 需要用wsl --set-version 發(fā)行版名 2單獨轉(zhuǎn)換轉(zhuǎn)換過程會重建文件系統(tǒng)提前備份重要數(shù)據(jù)。2.2 發(fā)行版怎么選Ubuntu 是默認(rèn)答案但不是唯一答案微軟商店里能裝的發(fā)行版很多Ubuntu、Debian、Fedora、openSUSE 都有。對 AI 開發(fā)來說我的建議是直接用 Ubuntu 的 LTS 版本比如 22.04 或 24.04。原因很實際NVIDIA 的 CUDA 工具鏈、PyTorch 官方 wheel、各種深度學(xué)習(xí)框架的文檔默認(rèn)都是圍繞 Ubuntu 寫的。你用 Debian 也能跑但遇到問題時網(wǎng)上能搜到的解決方案會少一大截。安裝命令很簡單wsl --install -d Ubuntu-22.04裝完之后首次啟動會讓你設(shè)置用戶名和密碼這個用戶是 Linux 側(cè)的普通用戶不是 root。這里有個經(jīng)驗用戶名別用中文也別用帶空格的否則后面配 SSH、跑腳本時容易出各種編碼問題。2.3 顯卡驅(qū)動的正確安裝姿勢這是整個流程里最容易出錯的一環(huán)。很多人以為要在 WSL 里裝 NVIDIA 驅(qū)動結(jié)果裝完發(fā)現(xiàn) GPU 根本識別不到。正確的做法是驅(qū)動只裝在 Windows 宿主機(jī)上WSL 里不要裝任何顯卡驅(qū)動。Windows 側(cè)去 NVIDIA 官網(wǎng)下載對應(yīng)你顯卡型號的驅(qū)動安裝時選擇自定義安裝確保勾選核心驅(qū)動組件。裝完之后在 WSL 里執(zhí)行nvidia-smi如果能看到顯卡型號、驅(qū)動版本、CUDA 版本這些信息說明直通已經(jīng)生效。如果報command not found那大概率是 Windows 驅(qū)動沒裝好或者 WSL 版本不對。這里補(bǔ)充一個判斷技巧WSL 里的nvidia-smi顯示的驅(qū)動版本和 Windows 側(cè)是一致的因為它是直接調(diào)用宿主機(jī)的驅(qū)動。CUDA 版本那一欄顯示的是驅(qū)動支持的最高 CUDA 版本不代表你實際安裝的 CUDA 版本這個區(qū)別后面配 PyTorch 時會用到。3. GPU 直通背后的機(jī)制為什么它比虛擬機(jī)方案更值得用3.1 WSL2 的架構(gòu)決定了它的性能表現(xiàn)要理解 GPU 直通為什么在 WSL2 上能跑得這么好得先搞清楚它的架構(gòu)。WSL2 本質(zhì)上是一個輕量級的虛擬機(jī)微軟在里面跑了一個經(jīng)過定制的 Linux 內(nèi)核但這個虛擬機(jī)的 I/O 和硬件訪問做了大量優(yōu)化。GPU 直通是通過一個叫 GPU-PVGPU Paravirtualization的技術(shù)實現(xiàn)的它把宿主機(jī)的 GPU 以半虛擬化的方式暴露給 Linux 內(nèi)核。和傳統(tǒng)虛擬機(jī)需要配置 PCI 直通不同WSL2 的 GPU 直通是微軟和 NVIDIA 合作在驅(qū)動層面做好的你不需要手動配置任何硬件映射。這也是為什么它用起來這么簡單——裝好 Windows 驅(qū)動WSL 里就能直接用。性能上根據(jù)我自己的實測在 WSL2 里跑 PyTorch 訓(xùn)練相比原生 Linux 大概有 5% 到 15% 的性能損耗主要來自文件系統(tǒng) I/O 和部分內(nèi)核調(diào)用的開銷。但相比傳統(tǒng)虛擬機(jī)動輒 30% 以上的損耗這個數(shù)字已經(jīng)非??捎^了。對于大多數(shù)中小規(guī)模訓(xùn)練任務(wù)這個損耗完全可以接受。3.2 文件系統(tǒng)跨界的性能陷阱WSL2 有一個非常關(guān)鍵的性能特性Linux 文件系統(tǒng)和 Windows 文件系統(tǒng)之間的跨系統(tǒng)訪問非常慢。具體來說從 WSL 里訪問/mnt/c/...這樣的 Windows 路徑或者從 Windows 訪問\\wsl$\...速度都會明顯下降。這個特性對 AI 開發(fā)影響很大。因為訓(xùn)練數(shù)據(jù)往往很大如果你把數(shù)據(jù)集放在 Windows 的 D 盤然后在 WSL 里讀取數(shù)據(jù)加載會成為瓶頸。我的做法是所有和訓(xùn)練相關(guān)的代碼、數(shù)據(jù)、模型全部放在 WSL 的 Linux 文件系統(tǒng)里也就是/home/用戶名/下面。Windows 側(cè)只用來編輯代碼和查資料。如果你確實需要從 Windows 訪問 WSL 里的文件可以在文件資源管理器地址欄輸入\\wsl$\Ubuntu-22.04\home\用戶名但只建議用來查看不要用來做大量文件操作。3.3 內(nèi)存和 CPU 資源的分配策略WSL2 默認(rèn)會占用宿主機(jī)最多 50% 的內(nèi)存這個默認(rèn)值在跑大模型時經(jīng)常不夠用。你可以在用戶目錄下創(chuàng)建一個.wslconfig文件來調(diào)整[wsl2] memory32GB processors8 swap8GB這個文件放在 Windows 用戶目錄下比如C:\Users\你的用戶名\.wslconfig。改完之后執(zhí)行wsl --shutdown重啟 WSL 生效。這里有個經(jīng)驗值內(nèi)存分配不要超過物理內(nèi)存的 70%否則 Windows 側(cè)會開始頻繁使用頁面文件整體體驗反而變差。CPU 核心數(shù)同理留一兩個核心給 Windows 系統(tǒng)本身。我自己的機(jī)器是 64G 內(nèi)存 16 核分配了 40G 和 12 核跑中等規(guī)模的模型訓(xùn)練很穩(wěn)。4. CUDA 與深度學(xué)習(xí)框架的安裝實操4.1 CUDA Toolkit 到底要不要裝這個問題困擾過很多人。結(jié)論是如果你只用 PyTorch 或 TensorFlow 的官方 wheel不需要單獨裝 CUDA Toolkit。因為 PyTorch 的 wheel 里已經(jīng)打包了運行所需的 CUDA 運行時庫只要宿主機(jī)的驅(qū)動版本夠新就行。但如果你需要編譯自定義算子、用 nvcc 編譯 CUDA 代碼那就得裝完整的 CUDA Toolkit。安裝方式推薦用 NVIDIA 官方源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 cuda-toolkit-12-4注意這里的源地址是wsl-ubuntu不是普通的ubuntu這是 NVIDIA 專門為 WSL 準(zhǔn)備的源。裝完之后把 CUDA 路徑加到環(huán)境變量里export PATH/usr/local/cuda/bin:$PATH export LD_LIBRARY_PATH/usr/local/cuda/lib64:$LD_LIBRARY_PATH寫進(jìn)~/.bashrc里持久化。4.2 PyTorch 安裝的版本匹配邏輯PyTorch 安裝最容易踩的坑是版本不匹配。你需要關(guān)注三個版本驅(qū)動支持的 CUDA 版本、PyTorch 編譯時用的 CUDA 版本、以及你實際安裝的 CUDA Toolkit 版本如果裝了的話。判斷方法很簡單先跑nvidia-smi看右上角顯示的 CUDA 版本比如顯示 12.4那說明你的驅(qū)動最高支持 CUDA 12.4。然后去 PyTorch 官網(wǎng)的安裝頁面選擇不超過這個版本的 CUDA 版本。比如選 CUDA 12.1 的 wheelpip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121裝完之后驗證import torch print(torch.cuda.is_available()) print(torch.cuda.get_device_name(0))如果第一行輸出 True第二行輸出你的顯卡型號就說明 GPU 環(huán)境配好了。注意不要用pip install torch直接裝那樣裝的是 CPU 版本跑起來會發(fā)現(xiàn)cuda.is_available()返回 False白白浪費顯卡。4.3 用 Conda 還是 venv 管理環(huán)境AI 開發(fā)的環(huán)境依賴復(fù)雜強(qiáng)烈建議用虛擬環(huán)境隔離。Conda 和 venv 都能用我的建議是如果你需要裝很多非 Python 的依賴比如特定版本的 CUDA 庫、編譯工具用 Conda 更省心如果只是純 Python 項目venv 更輕量。Conda 在 WSL 里的安裝wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh bash Miniconda3-latest-Linux-x86_64.sh裝完之后創(chuàng)建環(huán)境conda create -n ai python3.10 conda activate ai這里有個細(xì)節(jié)Conda 環(huán)境里的 Python 版本要和 PyTorch 支持的版本匹配。目前 PyTorch 對 Python 3.10 和 3.11 支持最好3.12 有些庫還沒跟上建議用 3.10。5. 開發(fā)工作流的搭建從編輯器到終端5.1 VS Code 的遠(yuǎn)程開發(fā)配置在 WSL 里開發(fā)最順手的編輯器是 VS Code 配合 WSL 擴(kuò)展。裝好擴(kuò)展之后在 WSL 終端里進(jìn)入項目目錄執(zhí)行code .VS Code 會自動以遠(yuǎn)程模式打開這個目錄所有插件、終端、調(diào)試都在 Linux 側(cè)運行。這個體驗和原生 Linux 幾乎沒區(qū)別但你可以同時用 Windows 的字體渲染和窗口管理。我常用的插件組合是Python、Pylance、Jupyter、GitLens再加上一個 Remote - WSL。Jupyter 插件特別有用可以直接在 VS Code 里跑 notebook內(nèi)核選 WSL 里的 Conda 環(huán)境。5.2 終端的選擇與配置WSL 的終端我推薦用 Windows Terminal它支持多標(biāo)簽、分屏、自定義配色比默認(rèn)的控制臺好用太多。配置上把默認(rèn)啟動的 shell 設(shè)成 WSL 里的 zsh 或 bash再裝個 oh-my-zsh 提升體驗。如果你習(xí)慣用 tmux 做會話管理WSL 里也能正常跑。我一般會開三個 pane一個跑訓(xùn)練一個看 GPU 狀態(tài)watch -n 1 nvidia-smi一個用來改代碼和跑測試。這樣切換起來很順手。5.3 數(shù)據(jù)與模型的存放策略前面提過訓(xùn)練數(shù)據(jù)要放在 Linux 文件系統(tǒng)里。具體目錄結(jié)構(gòu)我一般這樣組織/home/user/ projects/ # 代碼 datasets/ # 數(shù)據(jù)集 checkpoints/ # 模型權(quán)重 envs/ # 虛擬環(huán)境數(shù)據(jù)集如果是從 Windows 下載的用cp命令從/mnt/c/...拷過來雖然拷貝過程慢但只慢一次后續(xù)讀取就快了。模型權(quán)重同理訓(xùn)練完的 checkpoint 如果要分享給 Windows 側(cè)的同事再拷回去就行。這里有個小技巧如果數(shù)據(jù)集特別大比如幾百 G拷貝過程可能很久可以用rsync帶進(jìn)度顯示rsync -avh --progress /mnt/c/Users/user/Downloads/dataset/ ~/datasets/6. 實際訓(xùn)練中的性能調(diào)優(yōu)與常見問題6.1 數(shù)據(jù)加載成為瓶頸時的排查思路訓(xùn)練時如果發(fā)現(xiàn) GPU 利用率上不去一直在 30% 以下波動大概率是數(shù)據(jù)加載拖了后腿。排查順序是先看 CPU 利用率如果某個核心跑滿說明是數(shù)據(jù)預(yù)處理的問題再看磁盤 I/O用iostat看讀寫速度。解決辦法有幾個一是把數(shù)據(jù)集轉(zhuǎn)成更高效的格式比如把大量小圖片打包成 LMDB 或 WebDataset二是增加 DataLoader 的num_workers一般設(shè)成 CPU 核心數(shù)三是用pin_memoryTrue加速 CPU 到 GPU 的數(shù)據(jù)傳輸。6.2 顯存不足的幾種應(yīng)對方案顯存不夠是訓(xùn)練大模型時的常見問題。除了換更大的顯卡還有幾個實用技巧一是用梯度累積模擬大 batch把 batch size 設(shè)小累積幾步再更新二是用混合精度訓(xùn)練torch.cuda.amp能省不少顯存三是用梯度檢查點犧牲一點速度換顯存。如果這些都不夠那就只能上模型并行或者 ZeRO 這類分布式策略了。不過在單卡 WSL 環(huán)境下前面幾招基本能覆蓋大部分場景。6.3 WSL 特有的坑與規(guī)避方法WSL2 有幾個特有的問題需要注意。一是長時間訓(xùn)練時WSL 可能會因為內(nèi)存回收機(jī)制導(dǎo)致進(jìn)程被殺解決辦法是在.wslconfig里設(shè)置swap并監(jiān)控內(nèi)存使用。二是 WSL 的時鐘可能和宿主機(jī)不同步導(dǎo)致分布式訓(xùn)練時通信超時可以用sudo hwclock -s同步。三是 WSL 重啟后 GPU 直通偶爾會失效執(zhí)行wsl --shutdown再重進(jìn)一般能解決。還有一個容易被忽略的點WSL2 的網(wǎng)絡(luò)是 NAT 模式如果你要跑 TensorBoard 或者 Jupyter需要在 Windows 側(cè)用localhost訪問因為 WSL 的端口會自動轉(zhuǎn)發(fā)到宿主機(jī)。但如果端口被占用轉(zhuǎn)發(fā)會失敗這時候換個端口就行。7. 我在這套環(huán)境里踩過的幾個真實坑第一個坑是驅(qū)動版本。有次我圖省事用 Windows 自動更新裝的顯卡驅(qū)動結(jié)果 WSL 里nvidia-smi能跑但 PyTorch 一調(diào)用 CUDA 就報錯。后來去 NVIDIA 官網(wǎng)下了最新的 Game Ready 驅(qū)動重裝才好。教訓(xùn)是AI 開發(fā)用的驅(qū)動一定要去官網(wǎng)手動裝別用系統(tǒng)自動更新的。第二個坑是文件系統(tǒng)。早期我把代碼放在 Windows 的 D 盤用 VS Code 遠(yuǎn)程打開結(jié)果每次保存文件都要等好幾秒Git 操作也慢得離譜。后來把整個項目移到 Linux 側(cè)瞬間流暢。這個坑我見很多新手都踩過本質(zhì)是沒理解 WSL2 跨文件系統(tǒng)的性能差異。第三個坑是 Conda 和系統(tǒng) Python 的沖突。有次我在沒激活 Conda 環(huán)境的情況下pip install裝到了系統(tǒng) Python 里結(jié)果和 Conda 環(huán)境里的包版本打架排查了半天?,F(xiàn)在的習(xí)慣是每次開終端先conda activate確認(rèn)環(huán)境對了再操作。第四個坑是內(nèi)存配置。默認(rèn)的 50% 內(nèi)存在跑 BERT 這類模型時不夠用訓(xùn)練到一半 OOM。后來在.wslconfig里調(diào)到 40G 才穩(wěn)定。這個值要根據(jù)自己機(jī)器的物理內(nèi)存來定沒有萬能數(shù)字。8. 關(guān)于這套環(huán)境的一些個人體會用 WSL2 做 AI 開發(fā)這幾年最大的感受是它把 Windows 和 Linux 各自的優(yōu)勢真正捏到了一起。你不需要為了跑模型去忍受 Linux 的桌面環(huán)境也不需要為了用 Windows 軟件去折騰雙系統(tǒng)。GPU 直通成熟之后性能損耗已經(jīng)小到可以忽略對于個人開發(fā)者和中小團(tuán)隊來說這是目前性價比最高的方案。當(dāng)然它也不是萬能的。如果你要做多卡訓(xùn)練、需要特定的內(nèi)核模塊、或者對 I/O 延遲極其敏感那還是得上原生 Linux。但對絕大多數(shù)日常的模型開發(fā)、調(diào)試、小規(guī)模訓(xùn)練任務(wù)WSL2 完全夠用而且省心。最后分享一個我常用的檢查清單每次配新機(jī)器時按這個順序走一遍基本不會出問題先確認(rèn) BIOS 虛擬化開啟再裝 Windows 顯卡驅(qū)動然后裝 WSL2 和 Ubuntu接著配.wslconfig調(diào)資源再裝 Conda 和 PyTorch最后用nvidia-smi和torch.cuda.is_available()雙重驗證。這套流程走下來半小時內(nèi)就能從零搭好一個可用的 AI 開發(fā)環(huán)境。