境管理命令詳解:從Anaconda安裝到PyTorch項(xiàng)目實(shí)戰(zhàn))
剛把一臺(tái)閑置的筆記本翻出來裝了個(gè) Ubuntu準(zhǔn)備給新接的數(shù)據(jù)分析項(xiàng)目跑點(diǎn)東西。裝完之后第一件事就是配環(huán)境正好把一個(gè)老生常談但特別容易踩坑的話題重新梳理一遍——Anaconda 和 conda 環(huán)境命令。做 Python 開發(fā)、數(shù)據(jù)清洗、機(jī)器學(xué)習(xí)訓(xùn)練的人多少都會(huì)碰到這種尷尬項(xiàng)目 A 要 Python 3.7 PyTorch 1.13項(xiàng)目 B 要 Python 3.10 TensorFlow 2.15系統(tǒng)自帶的 Python 版本還未必合適。如果所有包都往一個(gè) Python 里塞早晚會(huì)撞車輕則我裝了這個(gè)毀了那個(gè)重則連系統(tǒng)腳本都帶崩。conda 的價(jià)值就在這它把 Python 解析器、C 庫(kù)、CUDA 相關(guān)組件、依賴包都當(dāng)成“包”來管理一個(gè)環(huán)境就是一趟自洽的列車各跑各的軌誰也不礙誰。這篇文章我打算把 conda 從安裝到日常高頻命令完整過一遍重點(diǎn)講清楚每個(gè)命令背后在做什么以及那些網(wǎng)絡(luò)上常被一句帶過的報(bào)錯(cuò)403 Forbidden、MemoryError、conda init no change、activate 不生效到底是什么原因、怎么處理。不管你是剛下載完 Anaconda 準(zhǔn)備配置 Pytorch 環(huán)境的新手還是想把手頭 Linux 環(huán)境遷到 Windows 的方案黨這篇都能拿來直接抄作業(yè)。1. 安裝與初始化讓 conda 命令先能用起來大多數(shù)人第一次翻車不是在用 conda 的時(shí)候而是在安裝和初始化環(huán)節(jié)。網(wǎng)上資料又多又雜一會(huì)兒讓你裝 Anaconda一會(huì)兒讓你裝 Miniconda還有人推薦 Miniforge。實(shí)際操作下來不同發(fā)行版差異不小選錯(cuò)了后面全是坑。1.1 發(fā)行版選型Anaconda、Miniconda、Miniforge 到底有什么區(qū)別先說結(jié)論這三個(gè)東西不是同一個(gè)維度上的“三個(gè)版本”而是“Anaconda 全家桶”和“精簡(jiǎn)版”以及“社區(qū)版”的關(guān)系。發(fā)行版體積默認(rèn) channel預(yù)裝包適合場(chǎng)景Anaconda3GB 以上defaultsAnaconda 官方自帶 250 數(shù)據(jù)科學(xué)常用包新手、離線環(huán)境、要用 spyder/navigator 圖界面Miniconda400MB 左右defaults幾乎不預(yù)裝只帶 conda、Python 和必要依賴日常開發(fā)、服務(wù)器環(huán)境、想自己按需裝包的人Miniforge500MB 左右conda-forge幾乎不預(yù)裝默認(rèn)走 conda-forge 社區(qū)源、避免商業(yè)許可限制的場(chǎng)景我自己的經(jīng)驗(yàn)是服務(wù)器上基本都裝 Miniconda輕靈活不占地方。個(gè)人筆記本上裝了 Anaconda因?yàn)榕紶栃枰蜷_ Anaconda Navigator 看看包版本、點(diǎn)點(diǎn)安裝也挺方便。至于 Miniforge如果你的項(xiàng)目要避免使用 Anaconda 官方 channel有些企業(yè)有商業(yè)授權(quán)限制或者你長(zhǎng)期只用 conda-forge 里的包那就直接上 Miniforge省得后面一直加-c conda-forge。還有一個(gè)判斷標(biāo)準(zhǔn)如果你完全不確定自己需要什么先裝 Miniconda需要哪個(gè)包再conda install哪個(gè)包。Anaconda 雖然開箱即用但預(yù)裝包版本有時(shí)會(huì)偏舊反而不如白手起家的環(huán)境干凈。1.2 下載安裝與環(huán)境變量Windows / macOS / Linux 三個(gè)平臺(tái)的差異安裝這塊最容易出問題的是兩件事環(huán)境變量沒配上或者裝的時(shí)候沒讓安裝器幫忙寫 PATH。Windows 上直接去官網(wǎng)下載安裝包或者走清華大學(xué)開源軟件鏡像站anaconda 倉(cāng)庫(kù)里有對(duì)應(yīng)的安裝包下載快很多。安裝到關(guān)鍵步驟時(shí)安裝界面會(huì)問“Add Anaconda to my PATH environment variable”這句話的意思是是否把 conda 寫進(jìn)系統(tǒng)全局 PATH。早期版本默認(rèn)不勾選我第一次裝的時(shí)候沒勾結(jié)果命令行里敲 conda 提示找不到命令折騰半天才發(fā)現(xiàn)是 PATH 的問題。建議在“僅自己使用”且確定不需要系統(tǒng)級(jí) Python 干涉的情況下勾選這一項(xiàng)如果擔(dān)心跟系統(tǒng)已有的 Python 沖突也可以不勾然后手動(dòng)加進(jìn) PATH等會(huì)講。macOS 上相對(duì)省心圖形安裝包一路下一步即可但要注意 Apple SiliconM 系列芯片要選對(duì)應(yīng)的 ARM 版安裝包否則 conda 會(huì)通過 Rosetta 轉(zhuǎn)譯雖然能跑但后面裝某些原生庫(kù)會(huì)莫名其妙地慢。Linux / Ubuntu 服務(wù)器上用不了圖形界面通常是下載Anaconda3-xxxxxxxx-Linux-x86_64.sh腳本然后執(zhí)行wget https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/Anaconda3-2024.10-1-Linux-x86_64.sh bash Anaconda3-2024.10-1-Linux-x86_64.sh安裝腳本最后會(huì)問是否執(zhí)行conda init。這里我強(qiáng)烈建議選 yes因?yàn)樗鼤?huì)自動(dòng)往.bashrc里寫入初始化代碼省掉手動(dòng)配環(huán)境變量。如果你不小心跳過了或者用的 shell 是 zsh事后手動(dòng)補(bǔ)也來得及。驗(yàn)證是否安裝成功conda --version which conda python --version如果which conda沒有輸出說明 conda 不在 PATH 里。手動(dòng)配置環(huán)境變量的方式是在/etc/profile或用戶級(jí).bashrc里追加一行export PATH/home/你的用戶名/anaconda3/bin:$PATH然后source ~/.bashrc生效。這里有個(gè)細(xì)節(jié)export PATH時(shí)要把 conda 的 bin 目錄寫在$PATH前面這樣命令行里執(zhí)行的python、pip才優(yōu)先走 conda 環(huán)境。寫反了的話你激活了環(huán)境但調(diào)用的還是系統(tǒng) Python特別容易讓你懷疑環(huán)境是不是壞了。1.3 conda init 與 activate為什么總提示 “run conda init before conda activate”裝完之后很多人下一步就是創(chuàng)建環(huán)境然后執(zhí)行conda activate xxx結(jié)果卻看到一行錯(cuò)誤CommandNotFoundError: Your shell has not been properly configured to use conda activate. To initialize your current shell, run: conda init --all這個(gè)報(bào)錯(cuò)很常見原因是 conda 的 activate 機(jī)制不只是設(shè)置一個(gè)環(huán)境變量那么簡(jiǎn)單它要往 shell 的配置文件里注冊(cè)一個(gè)函數(shù)讓conda activate成為 shell 的內(nèi)建命令。沒有執(zhí)行過conda init的話shell 不認(rèn)識(shí)這個(gè)函數(shù)自然激活不了。解決辦法就是按提示跑一次conda init bash如果你用的是 zsh就換成conda init zsh。執(zhí)行完之后務(wù)必重新打開終端或者source ~/.bashrc。Windows PowerShell 用戶還需要先執(zhí)行conda init powershell然后以管理員身份允許腳本執(zhí)行策略Set-ExecutionPolicy RemoteSigned另一個(gè)高頻問題是明明執(zhí)行了conda init終端還是顯示“conda init no change”。這個(gè)提示的意思并不是報(bào)錯(cuò)而是說你之前已經(jīng)初始化過了.bashrc里已經(jīng)有那段初始化代碼。如果這種情況下conda activate依然無效多半是你在終端里手動(dòng) source 過別的 conda 腳本或者多個(gè) shell 配置文件.bashrc、.bash_profile、.profile之間出現(xiàn)了重復(fù)/沖突??梢源蜷_.bashrc看一下里面是否有多個(gè)# conda initialize 塊有的話刪掉重復(fù)的只保留一份。這里給一個(gè)排查順序的參考grep -n conda initialize ~/.bashrc確認(rèn)初始化塊是否存在。執(zhí)行type conda看輸出是“conda is a function”還是路徑。如果輸出是路徑說明沒 init 成功重新source后再看。如果一切正常但 activate 還是報(bào)錯(cuò)檢查是不是在某個(gè)腳本里提前執(zhí)行了set -u未定義變量報(bào)錯(cuò)導(dǎo)致 conda 函數(shù)內(nèi)部變量未定義。1.4 換源把 conda 默認(rèn)源切到國(guó)內(nèi)鏡像不換源的情況下用 conda 裝包真的會(huì)等得讓人懷疑人生尤其是裝 PyTorch 這種幾個(gè) GB 的大環(huán)境。換源本質(zhì)上是修改~/.condarc配置文件把 channel 指向國(guó)內(nèi)鏡像。以清華鏡像為例執(zhí)行conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/ conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ conda config --set show_channel_urls yes然后執(zhí)行conda info查看 channels 列表確認(rèn)是否生效?;蛘咧苯泳庉媬/.condarcchannels: - defaults show_channel_urls: true default_channels: - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2 custom_channels: conda-forge: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud pytorch: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud這里一定要把默認(rèn)的defaults和鏡像里的 default 邏輯理解清楚。defaults在 conda 里是一個(gè)“虛擬 channel”它實(shí)際指向的是 Anaconda 官方倉(cāng)庫(kù)的幾個(gè)子目錄。配置里寫了default_channels之后conda 會(huì)把defaults解析成鏡像地址而不是官方地址。如果你只在channels里加了鏡像但沒寫default_channelsconda 可能還是會(huì)去官方源拉速度沒有真正變快。還有一點(diǎn)配置好鏡像后舊緩存里可能還存著之前的 channel 數(shù)據(jù)偶爾會(huì)碰到明明已換源仍然從官方源下載的詭異情況。這時(shí)候可以清理緩存conda clean -i這個(gè)命令只清理索引緩存不影響已安裝的包放心執(zhí)行。2. 環(huán)境管理命令創(chuàng)建、激活、刪除、導(dǎo)入導(dǎo)出一網(wǎng)打盡conda 的核心能力是環(huán)境管理。我把這部分單獨(dú)拿出來講因?yàn)楝F(xiàn)實(shí)中使用頻率最高、最容易含糊的就是它。2.1 環(huán)境創(chuàng)建conda create -n 名字 python3.8 拆解創(chuàng)建環(huán)境的完整命令是conda create -n 環(huán)境名 python3.8其中-n是--name的簡(jiǎn)寫后面跟的是環(huán)境名。python3.8表示在這個(gè)新環(huán)境里安裝 Python 3.8。執(zhí)行后 conda 會(huì)做依賴解析列出要安裝的包等你輸入y確認(rèn)。如果你不想交互確認(rèn)可以在命令末尾加-y表示全部同意conda create -n matanyone python3.8 -y這是我個(gè)人特別喜歡的用法。創(chuàng)建環(huán)境時(shí)可以順便把常用包一次性裝上減少后面反復(fù) install 的時(shí)間conda create -n ml python3.10 numpy pandas matplotlib jupyter -y但要注意包名后面不寫版本號(hào)的話conda 會(huì)默認(rèn)安裝當(dāng)前 channel 里的最新版如果最新版和 Python 3.10 之間有沖突conda 會(huì)自動(dòng)嘗試降級(jí)或提示沖突。為了環(huán)境穩(wěn)定我一般會(huì)給關(guān)鍵的三方庫(kù)也寫上大版本約束比如numpy1.26。這里需要專門提醒一個(gè)關(guān)鍵點(diǎn)創(chuàng)建環(huán)境時(shí)指定的 Python 版本決定了這個(gè)環(huán)境里所有依賴包的可用版本范圍。比如有些老項(xiàng)目用的依賴還只支持到 Python 3.8你非要用 Python 3.11 去建環(huán)境最后 pip 裝依賴時(shí)天天見error: command gcc failed with exit status 1根源就在編譯器兼容性上。建環(huán)境之前先翻一眼項(xiàng)目文檔要求什么版本別等到裝包裝到一半才發(fā)現(xiàn)。2.2 激活與切換環(huán)境activate / deactivate / env list環(huán)境創(chuàng)建好了緊接著就是激活。命令本身很簡(jiǎn)單conda activate 環(huán)境名激活后命令行提示符一般會(huì)變成(環(huán)境名) 用戶名主機(jī)名:~$這能直觀地告訴你當(dāng)前在哪個(gè)環(huán)境里。此時(shí)執(zhí)行python用的就是該環(huán)境對(duì)應(yīng)的解釋器執(zhí)行pip install裝的也是這個(gè)環(huán)境的包不會(huì)污染全局。退出當(dāng)前環(huán)境用conda deactivate查看當(dāng)前有哪些環(huán)境conda env list # 或者 conda info -e輸出會(huì)列出所有環(huán)境路徑帶*的表示當(dāng)前激活的環(huán)境。這個(gè)命令在管理多套環(huán)境時(shí)極其有用也是很多人第一次檢查環(huán)境是否建成功時(shí)首先敲的命令。激活環(huán)境的原理其實(shí)是通過修改PATH環(huán)境變量把當(dāng)前環(huán)境bin或Scripts目錄放到最前面。你可以自己驗(yàn)證which python # 輸出 /home/xxx/anaconda3/envs/ml/bin/python這就是為什么同一個(gè)python命令在不同的 conda 環(huán)境下會(huì)指向不同的解釋器。理解了這一點(diǎn)后面排查各種“python版本不對(duì)”“包裝錯(cuò)環(huán)境”就會(huì)快很多。Windows PowerShell 用戶執(zhí)行conda activate之前需要先運(yùn)行conda init powershell并重開終端。如果重開終端后執(zhí)行還是提示禁止運(yùn)行腳本按前面提到的Set-ExecutionPolicy RemoteSigned先放開執(zhí)行策略即可。Linux 用戶有一個(gè)易忽略的地方如果你通過ssh登錄服務(wù)器后直接conda activate有時(shí)候會(huì)提示找不到命令。這是因?yàn)榉堑卿?shell 沒有加載.bashrc。解決辦法是執(zhí)行bash --login或者在~/.bash_profile里加上source ~/.bashrc讓登錄時(shí)自動(dòng)加載。2.3 刪除與克隆環(huán)境remove / clone刪除環(huán)境同樣不復(fù)雜conda remove -n 環(huán)境名 --all加上--all才會(huì)把整個(gè)環(huán)境和里面的所有包一起刪掉不加的話只是刪某個(gè)包。刪之前建議先用conda env list確認(rèn)環(huán)境名準(zhǔn)確因?yàn)閯h除操作不可恢復(fù)環(huán)境里做過的手工配置也得重新來。conda 本身沒有直接“重命名環(huán)境”的命令但可以通過克隆實(shí)現(xiàn)conda create -n 新環(huán)境名 --clone 老環(huán)境名克隆成功后確認(rèn)沒有問題再刪除老環(huán)境。這樣做相當(dāng)于重命名而且非常穩(wěn)因?yàn)榘g的依賴關(guān)系會(huì)被 conda 重新解析一遍不會(huì)出現(xiàn)復(fù)制文件夾導(dǎo)致的硬編碼路徑問題。有很多人圖省事直接去anaconda3/envs/目錄下改文件夾名這種操作我踩過一次坑環(huán)境名是改了但環(huán)境內(nèi)部很多腳本里記錄的絕對(duì)路徑還指向舊目錄activate 之后啟動(dòng)依賴腳本頻繁報(bào)找不到路徑。老老實(shí)實(shí)用--clone是效率最高的方案。2.4 環(huán)境導(dǎo)入導(dǎo)出export / from-history環(huán)境可復(fù)現(xiàn)是 conda 最大的優(yōu)勢(shì)也是團(tuán)隊(duì)協(xié)作里最能省時(shí)間的特性。導(dǎo)出當(dāng)前環(huán)境的依賴信息conda env export environment.yml這個(gè)命令會(huì)把環(huán)境中所有包包括依賴的依賴的精確版本號(hào)和構(gòu)建號(hào)記錄下來生成一個(gè)environment.yml文件。把這個(gè)文件交給隊(duì)友對(duì)方一條命令就能還原出一模一樣的環(huán)境conda env create -f environment.yml但這里有一個(gè)跨平臺(tái)的重要坑conda env export導(dǎo)出的文件里通常帶構(gòu)建號(hào)比如numpy1.26.4py310h..._0py310這類標(biāo)簽強(qiáng)烈綁定平臺(tái)。你把 Linux 上導(dǎo)出的environment.yml拿到 Windows 上用很大概率會(huì)報(bào)錯(cuò)或解析不到包。我自己就經(jīng)歷過“l(fā)inux 離線遷移到 windows”的場(chǎng)景最后發(fā)現(xiàn)直接給environment.yml行不通。跨平臺(tái)遷移的推薦做法是conda env export --from-history environment.yml--from-history表示只導(dǎo)出你顯式安裝過的包不導(dǎo)出依賴樹。這樣還原環(huán)境時(shí)conda 會(huì)基于當(dāng)前平臺(tái)的兼容性重新解析并安裝所有依賴。代價(jià)是生成的依賴粒度粗還原出來的環(huán)境版本未必和原來完全一致但能用的概率大幅提升。如果涉及到完全離線的環(huán)境遷移兩臺(tái)機(jī)器都斷網(wǎng)最穩(wěn)妥的方案是直接打包整個(gè)環(huán)境文件夾然后在目標(biāo)機(jī)器上解壓到envs目錄下并手動(dòng)確認(rèn)環(huán)境路徑配置。這種方法受制于兩機(jī) glibc 和 CUDA 驅(qū)動(dòng)的差異實(shí)際可行但限制很多能在線同步環(huán)境的話優(yōu)先在線。2.5 虛擬環(huán)境與 IDE / Jupyter 打通創(chuàng)建了環(huán)境卻不會(huì)配合編輯器使用等于白建。實(shí)際開發(fā)中我們通常會(huì)在 IDE 里顯式指定解釋器而不是靠終端里 activate。PyCharm 里配置 conda 環(huán)境的方式是Settings - Project - Python Interpreter - Add Interpreter - Add Local Interpreter - 選擇 Conda Environment然后選擇 Existing environment在下拉列表里選中目標(biāo)環(huán)境。如果列表里沒有點(diǎn)擊 ... 手動(dòng)指定路徑Windows 一般是C:\Users\你的用戶名\.conda\envs\環(huán)境名\python.exeLinux/macOS 一般是/home/你的用戶名/anaconda3/envs/環(huán)境名/bin/python。Jupyter 里也需要“注冊(cè)”環(huán)境才能切換內(nèi)核conda activate 環(huán)境名 conda install ipykernel -y python -m ipykernel install --user --name環(huán)境名 --display-name 環(huán)境名然后重新打開 Jupyter 網(wǎng)頁(yè)新建 Notebook 時(shí)就能在下拉列表里看到這個(gè)環(huán)境。--display-name后面跟的是在 Jupyter 界面上顯示的名字可以隨便寫--name才是內(nèi)核對(duì)應(yīng)的環(huán)境標(biāo)識(shí)建議保持一致避免混亂。刪除 Jupyter 內(nèi)核時(shí)用jupyter kernelspec uninstall 環(huán)境名3. 包管理操作conda install 與 pip install 的邊界環(huán)境建好了接下來就是裝包。很多教程只教命令不講這兩個(gè)包管理器的邊界導(dǎo)致用戶經(jīng)常出現(xiàn)“conda 裝的包和 pip 裝的包相互看不見”的困惑。3.1 conda install 與 pip install 的區(qū)別conda install和pip install表面上看都是裝 Python 包但底層邏輯完全不同對(duì)比項(xiàng)conda installpip install包格式conda 自有格式會(huì)處理非 Python 依賴wheel / sdist以 Python 包為主依賴來源從 channel如 defaults、conda-forge下載從 PyPI 下載環(huán)境隔離原生支持環(huán)境需要配合 venv / conda 環(huán)境使用二進(jìn)制非 Python 庫(kù)處理能安裝 CUDA、MKL、OpenMP 等 C/C 庫(kù)通常只在 wheel 中預(yù)編譯好 Python 接口速度依賴解析較慢包較大通常更快兼容性處理會(huì)把 Python、依賴庫(kù)、二進(jìn)制庫(kù)整體解析只解析 Python 包依賴日常使用建議遵循一個(gè)原則優(yōu)先用conda install尤其當(dāng)你裝的是科學(xué)計(jì)算類、GPU 相關(guān)組件、需要 C 庫(kù)配合的包numpy、scipy、pandas、pytorch、tensorflow時(shí)因?yàn)?conda 能把 CUDA runtime、cudnn 這些非 Python 的底層庫(kù)一起管理好。而純 Python 生態(tài)里的包或者 conda channel 里沒有的包用pip install也沒問題但要確保是在激活后的正確環(huán)境里執(zhí)行的。有一個(gè)特別常見的錯(cuò)誤操作先conda activate了環(huán)境然后開了個(gè)新終端忘了激活直接pip install結(jié)果包裝到了 base 環(huán)境里。判斷當(dāng)前 pip 屬于哪個(gè)環(huán)境可以執(zhí)行pip --version輸出里會(huì)顯示 pip 的路徑如果路徑里帶了envs/環(huán)境名說明 pip 指向的是當(dāng)前環(huán)境否則就是系統(tǒng)或 base 環(huán)境。3.2 包搜索、版本指定與常見參數(shù)組合安裝之前先搜索一下可用的版本避免裝完發(fā)現(xiàn)版本不對(duì)又回滾conda search 包名 # 比如 conda search numpy1.20conda 的版本約束規(guī)則很直觀numpy1.26表示安裝 1.26.x 的最新版numpy1.20,2.0表示版本范圍numpy1.26.4是精確版本。當(dāng)然前提是這些版本存在于 channel 中。查看當(dāng)前環(huán)境下已安裝的包c(diǎn)onda list conda list -n 環(huán)境名第二條命令可以不用激活環(huán)境直接查看指定環(huán)境的包列表這在排查“到底裝哪去了”的時(shí)候特別順手。安裝時(shí)如果默認(rèn) channel 找不到包可以臨時(shí)指定 channelconda install -c conda-forge 包名-c是--channel的簡(jiǎn)寫。conda-forge 是社區(qū)維護(hù)的 channel覆蓋面廣更新也快。不過要提醒一句混用多個(gè) channel比如 defaults conda-forge雖然靈活但偶爾會(huì)導(dǎo)致依賴版本選擇不一致同一個(gè)包兩個(gè) channel 都有的情況下conda 可能會(huì)選擇默認(rèn)優(yōu)先級(jí)高的那個(gè)導(dǎo)致后續(xù)裝其它包時(shí)莫名沖突。如果長(zhǎng)期只用 conda-forge建議干脆把 conda-forge 設(shè)為第一優(yōu)先級(jí) channelconda config --add channels conda-forge conda config --set channel_priority strict批量更新環(huán)境的命令conda update --all這個(gè)命令會(huì)更新當(dāng)前環(huán)境所有包到 channel 中的最新版本。但它有個(gè)隱患更新后可能破壞已有兼容性所以一般只在新建環(huán)境折騰時(shí)執(zhí)行生產(chǎn)環(huán)境里我更傾向于指定包的顯式更新比如conda update numpy。3.3 實(shí)戰(zhàn)用 conda 快速搭建包含 PyTorch 的深度學(xué)習(xí)環(huán)境配置深度學(xué)習(xí)環(huán)境是 Anaconda/conda 的經(jīng)典場(chǎng)景網(wǎng)上相關(guān)熱度一直很高。很多人卡在版本對(duì)應(yīng)關(guān)系上其實(shí)只要理解 conda 處理 GPU 庫(kù)的邏輯一通百通。先在 NVIDIA 官網(wǎng)或系統(tǒng)驅(qū)動(dòng)工具里確認(rèn)好自己的顯卡驅(qū)動(dòng)支持的 CUDA 版本然后創(chuàng)建環(huán)境時(shí)指定 Python 版本并用-c pytorch指定 PyTorch 官方 channelconda create -n pytorch_env python3.10 -y conda activate pytorch_env conda install pytorch torchvision torchaudio -c pytorch -y此時(shí) conda 會(huì)解析并幫你自動(dòng)安裝配套的 CUDA runtime、cuDNN 等底層庫(kù)不需要手動(dòng)去顯卡驅(qū)動(dòng)層面安裝 CUDA Toolkit。這一點(diǎn)是 conda 最大的優(yōu)勢(shì)它把 GPU 相關(guān)庫(kù)當(dāng)作普通依賴整套環(huán)境自洽不會(huì)污染系統(tǒng)。如果你的機(jī)器沒有 NVIDIA GPU或者短期內(nèi)只做 CPU 推理可以安裝 CPU 版本conda install pytorch torchvision torchaudio cpuonly -c pytorch -y版本對(duì)應(yīng)關(guān)系有一個(gè)常見誤區(qū)網(wǎng)上很多圖把 conda 環(huán)境里能跑的 CUDA 版本和系統(tǒng)驅(qū)動(dòng)版本混為一談。實(shí)際上 conda 裝的是 CUDA 運(yùn)行時(shí)庫(kù)只要系統(tǒng)驅(qū)動(dòng)版本不低于它要求的最低驅(qū)動(dòng)版本就能運(yùn)行。這也是很多人發(fā)現(xiàn)不同 conda 環(huán)境可以分別裝 CUDA 11.8 和 CUDA 12.1 互不沖突的原因——它們并沒有和系統(tǒng) CUDA 綁定只是各自使用了對(duì)應(yīng)的運(yùn)行時(shí)。TensorFlow 的情況類似但有一點(diǎn)特別值得注意TensorFlow 在 2.11 之后Linux 上的默認(rèn) PyPI 包不再內(nèi)置 GPU 支持需要從nvidia的 channel 安裝額外插件或用 conda 直接安裝conda create -n tf_gpu python3.10 -y conda activate tf_gpu conda install tensorflow-gpu -y如果你照網(wǎng)上教程用pip install tensorflow-gpu大概率會(huì)收到 warning 或者裝到一個(gè)兼容層上。建議以 conda 官方 channel 為準(zhǔn)安裝后執(zhí)行一個(gè)簡(jiǎn)單 GPU 檢測(cè)import tensorflow as tf print(tf.config.list_physical_devices(GPU))輸出非空列表說明環(huán)境正常。如果輸出空列表先運(yùn)行tf.debugging.set_log_device_placement(True)看日志判斷是 CUDA 庫(kù)不匹配還是驅(qū)動(dòng)版本不足。4. 高頻報(bào)錯(cuò)與排查技巧實(shí)錄這部分是每次寫 conda 相關(guān)文章時(shí)最有價(jià)值的章節(jié)。我把這些年遇到的、以及熱搜里高頻出現(xiàn)的問題挨個(gè)整理一遍直接給結(jié)論和操作步驟省得你再去翻一堆帖子。4.1 換源之后出現(xiàn) HTTP 403 Forbidden典型報(bào)錯(cuò)長(zhǎng)這樣UnavailableInvalidChannel: HTTP 403 FORBIDDEN for channel anaconda/pkgs/main這個(gè)報(bào)錯(cuò)看起來像是被拒絕訪問絕大多數(shù)情況下和真正的“權(quán)限”無關(guān)而是 channel 地址沒寫對(duì)。常見原因是用了不存在的 channel 路徑或者鏡像站校驗(yàn)失敗。比如有人在.condarc里寫了https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main末尾漏了/conda 有時(shí)也能解析但有時(shí)就會(huì) 403。排查步驟按順序來conda config --show channels和conda config --show custom_channels檢查當(dāng)前配置。curl -I 你的鏡像地址手動(dòng)訪問看返回碼。如果地址沒問題執(zhí)行conda clean -i清理索引緩存然后重試。仍然不行把.condarc里所有內(nèi)容清空恢復(fù)默認(rèn)源確認(rèn)能裝包后再重新?lián)Q源。也有一種情況是公司/校園網(wǎng)的代理層攔截了下載請(qǐng)求??梢韵扰R時(shí)把代理環(huán)境變量去掉再試unset http_proxy https_proxy conda install 包名 -y4.2 MemoryError: conda process ran out of memory這報(bào)錯(cuò)常見于conda create或conda install時(shí)尤其是環(huán)境里要裝的包特別多或者依賴解析鏈很長(zhǎng)時(shí)。錯(cuò)誤信息會(huì)直接提示CondaMemoryError: The conda process ran out of memory. Increase system memory and/or try again.之所以會(huì)內(nèi)存溢出一個(gè)重要原因是 conda 默認(rèn)使用的依賴求解器在處理復(fù)雜依賴時(shí)占用內(nèi)存非常大。conda 從 22.11 版本開始把新的libmamba求解器作為默認(rèn)但如果你用的是帶舊配置的環(huán)境可能還停留在舊求解器上。解決思路有兩個(gè)層面。第一給 conda 顯式安裝更高效的求解器conda install -n base conda-libmamba-solver -y conda config --set solver libmamba然后重新執(zhí)行創(chuàng)建/安裝命令。libmamba 用 C 實(shí)現(xiàn)依賴求解速度和內(nèi)存占用都比舊版好很多這也是最近兩年 conda 體驗(yàn)顯著提升的核心改進(jìn)。第二如果仍然內(nèi)存不夠嘗試拆分安裝步驟。不要一次性創(chuàng)建包含幾十個(gè)包的環(huán)境可以先創(chuàng)建帶 Python 的空環(huán)境然后再往里分批安裝conda create -n big_env python3.10 -y conda activate big_env conda install numpy pandas scikit-learn -y conda install pytorch torchvision -c pytorch -y分批安裝雖然多敲幾次命令但每次依賴解析的規(guī)模小很多內(nèi)存壓力大幅下降。4.3 激活環(huán)境后提示 “warning: this Python interpreter is in a conda environment”有時(shí)候激活環(huán)境后腳本里會(huì)彈出類似下面這種 warningWarning: This Python interpreter is in a conda environment, but the environment has not been activated. Libraries may fail to load. To activate this environment, see https://conda.io/activation/這個(gè) warning 的本質(zhì)是某個(gè)腳本/可執(zhí)行文件直接調(diào)用了 conda 環(huán)境里的 Python 或動(dòng)態(tài)庫(kù)但當(dāng)前終端沒激活該環(huán)境導(dǎo)致PATH和LD_LIBRARY_PATH等環(huán)境變量沒有指向正確的 conda 環(huán)境。Python 解析器雖然在環(huán)境里但它要加載的 C 擴(kuò)展庫(kù)卻找不到。排查方向先看是誰觸發(fā)了 warning。比如你在 PyCharm 里選了環(huán)境內(nèi)的 Python 當(dāng)解釋器卻在一個(gè)未激活 conda 的終端里啟動(dòng) jupyter notebook就可能出現(xiàn)。解決辦法很簡(jiǎn)單先在終端激活環(huán)境再啟動(dòng)程序conda activate 環(huán)境名 python -m jupyter notebook如果是在 PyCharm/VS Code 里觸發(fā)那通常需要在 IDE 的終端設(shè)置里開啟“Activate conda environment”選項(xiàng)或者在 IDE 自帶的終端里手動(dòng)執(zhí)行一次激活。有時(shí)候手動(dòng)編寫 service 文件或 cron 任務(wù)也會(huì)遇到這個(gè) warning。這時(shí)可以直接在腳本頭部 source 一下 conda 配置并激活環(huán)境source /home/你的用戶名/anaconda3/etc/profile.d/conda.sh conda activate 項(xiàng)目環(huán)境 python /path/to/script.py4.4 conda 和 uv 的關(guān)系是不是新工具要取代 conda自從 uv 出現(xiàn)之后很多人開始糾結(jié)現(xiàn)在還有必要學(xué) conda 嗎我的觀點(diǎn)比較實(shí)際uv 確實(shí)在純 Python 包管理方面比 pip 快非常多但它目前主要定位還是 Python 包管理不是環(huán)境內(nèi)非 Python 二進(jìn)制庫(kù)比如 CUDA、MKL的全套管理方案。conda 更有價(jià)值的場(chǎng)景還是要看 Ubuntu 服務(wù)器上新裝 Python 環(huán)境、配置 TensorFlow/PyTorch GPU 環(huán)境這些需要和底層庫(kù)打交道的場(chǎng)景?,F(xiàn)實(shí)中也有人在 conda 環(huán)境內(nèi)部啟用 uv 來加速虛擬環(huán)境的建置和 Python 包安裝兩者并不沖突。conda 負(fù)責(zé)創(chuàng)建隔離環(huán)境和系統(tǒng)級(jí)依賴uv 負(fù)責(zé) Python 包的快速解析與安裝。如果你的項(xiàng)目對(duì)安裝速度有極致的需求可以把 uv 作為 conda 的“內(nèi)部加速器”conda create -n fast_env python3.10 -y conda activate fast_env uv pip install 包名注意uv pip install默認(rèn)工作在系統(tǒng) Python 環(huán)境里在 conda 環(huán)境內(nèi)使用時(shí)需要確保當(dāng)前環(huán)境已激活這樣 uv 會(huì)識(shí)別CONDA_PREFIX并安裝到當(dāng)前環(huán)境不會(huì)跑到別處。至于 conda 是否會(huì)被 uv 完全取代短期來看不會(huì)。conda 的優(yōu)勢(shì)在于“環(huán)境 包 系統(tǒng)依賴”全鏈路統(tǒng)一管理uv 的優(yōu)勢(shì)在于純 Python 包解析速度和磁盤占用。兩者各有適用邊界作為工程師多會(huì)一個(gè)工具總沒壞處。搜索“conda和uv”熱度高說明大家其實(shí)都有這個(gè)困惑我的結(jié)論是大環(huán)境用 conda小依賴用 uv雙管齊下效率最高。4.5 conda 環(huán)境遷移和路徑變化后的修復(fù)把 conda 從一臺(tái)機(jī)器遷到另一臺(tái)或者整個(gè) Anaconda 目錄移動(dòng)過位置之后經(jīng)常發(fā)生 Python 解釋器和 conda 環(huán)境都不能用的情況。比如熱詞里提到“conda linux離線遷移到windows”這種跨平臺(tái)遷移如果沒有在目標(biāo)平臺(tái)重建環(huán)境幾乎一定會(huì)出問題。遷機(jī)之后最先要做的是讓 conda 本身找回自己的前綴路徑conda info --base如果輸出的大本營(yíng)路徑已經(jīng)和實(shí)際位置不符可以重新設(shè)置前綴或者卸載重裝。環(huán)境目錄遷移到新機(jī)器后也可以嘗試用 conda 命令重新注冊(cè)conda config --append envs_dirs /新路徑/envs然后conda env list應(yīng)該就能看到這些環(huán)境了。需要注意的是環(huán)境內(nèi)部的腳本仍然會(huì)引用舊路徑所以如果環(huán)境特別重要我仍會(huì)推薦用conda env export/conda env create的方式重建而不是直接復(fù)制目錄。5. 日常使用的幾個(gè)小技巧除了命令本身我想把日常工作中總結(jié)的幾個(gè)小習(xí)慣也一并分享。這些內(nèi)容在幫助文檔里很難看到但對(duì)提升效率幫助很大。第一個(gè)技巧是控制 base 環(huán)境。base 是 conda 自帶的默認(rèn)環(huán)境很多人圖省事直接在 base 里裝各種包。一旦裝的東西多了base 變得臃腫后續(xù)創(chuàng)建新環(huán)境都會(huì)變慢而且一旦依賴沖突整個(gè) conda 安裝都受影響。我的習(xí)慣是 base 只維護(hù) conda 本身和少量必須的命令行工具所有的分析項(xiàng)目都單獨(dú)建環(huán)境。如果哪天 base 真弄亂了直接重裝 Miniconda 都不心疼。第二個(gè)技巧是善用環(huán)境名前綴。一臺(tái)機(jī)器上環(huán)境多了之后conda env list的輸出很容易看花眼。建議在創(chuàng)建環(huán)境時(shí)用項(xiàng)目名做前綴區(qū)分比如proj_a_tf、proj_b_torch這樣一眼就能看出環(huán)境對(duì)應(yīng)哪個(gè)項(xiàng)目、用了什么框架。環(huán)境名不要太長(zhǎng)因?yàn)榧せ詈笏鼤?huì)出現(xiàn)在命令行提示符前面太長(zhǎng)影響輸入。第三個(gè)技巧是整理.condarc時(shí)記得區(qū)分全局配置和項(xiàng)目配置。conda 支持在項(xiàng)目目錄里放一個(gè).condarc來覆蓋全局配置這在不同項(xiàng)目需要不同 channel 時(shí)很好用。比如項(xiàng)目 A 強(qiáng)制要求只用 conda-forge 一個(gè) channel你就可以在項(xiàng)目根目錄放一個(gè)channel_priority: strict channels: - conda-forge這樣進(jìn)到項(xiàng)目目錄里執(zhí)行 conda 命令使用的就是項(xiàng)目級(jí)配置不影響其他項(xiàng)目的環(huán)境管理。注意.condarc文件的優(yōu)先級(jí)是項(xiàng)目目錄 用戶目錄 conda 安裝目錄弄明白這個(gè)關(guān)系很多奇奇怪怪的 channel 行為就有了解釋。第四個(gè)技巧是緩存清理。conda 用久了之后pkgs目錄會(huì)越來越大動(dòng)輒十幾個(gè) GB。在磁盤緊張的時(shí)候執(zhí)行conda clean --all這個(gè)命令會(huì)清除所有緩存的安裝包、索引緩存和臨時(shí)文件。不過提醒一下清理后如果還要?jiǎng)?chuàng)建相同依賴的環(huán)境需要重新下載所以磁盤足夠的情況下不急著清。我一般是一個(gè)月左右清理一次只清包緩存不清環(huán)境目錄conda clean --packages寫在最后的一點(diǎn)個(gè)人體會(huì)這些年用下來我覺得 conda 最值得花時(shí)間去理解的不是命令本身而是它“環(huán)境即目錄、包即文件、依賴即解析”的三個(gè)基本模型。只要想清楚環(huán)境不過是一個(gè)目錄激活不過是在 PATH 查表時(shí)換了一個(gè)優(yōu)先路徑很多報(bào)錯(cuò)和詭異行為就都順理成章了。常見的報(bào)錯(cuò)百分之八九十逃不出四類path 沒配好、channel 地址不對(duì)、依賴求解器太老、緩存臟數(shù)據(jù)干擾。應(yīng)付這四類問題上面提供的命令和排查順序基本夠用。如果你正在配的是 GPU 版本的 TensorFlow 或 PyTorch 環(huán)境一定記得先確認(rèn)系統(tǒng)到 conda 環(huán)境的 CUDA 運(yùn)行時(shí)版本是否匹配不要只看顯卡型號(hào)看錯(cuò)一層版本后面排查編譯錯(cuò)誤能讓你熬一個(gè)通宵。最后一點(diǎn)老話重提不要在生產(chǎn)環(huán)境和日常開發(fā)環(huán)境共用一套 Python 環(huán)境。每接到一個(gè)新項(xiàng)目第一件事就建一個(gè)獨(dú)立的 conda 環(huán)境把依賴鎖進(jìn) environment.yml 提交到倉(cāng)庫(kù)里。這套習(xí)慣堅(jiān)持下來你身邊被 Python 環(huán)境折騰瘋的同事遲早也會(huì)來問你。