錯(cuò)排查指南:關(guān)鍵環(huán)境參數(shù)與依賴匹配全解析)
1. 先從最坑的地方說(shuō)起裝包報(bào)錯(cuò)八成是環(huán)境參數(shù)沒(méi)對(duì)上我在社區(qū)里混了這么多年發(fā)現(xiàn)一個(gè)特別普遍的現(xiàn)象不少人拿到一個(gè) Python 項(xiàng)目第一步就是pip install xxx然后一連串報(bào)錯(cuò)撲面而來(lái)。什么ERROR: Could not find a version that satisfies the requirement什么No matching distribution found還有RuntimeError: Python version mismatch之類。這時(shí)候大多數(shù)人會(huì)去百度復(fù)制報(bào)錯(cuò)逐行搜折騰半天最后可能重裝了 Python、換了 pip 源、清了緩存問(wèn)題還在。其實(shí)這些報(bào)錯(cuò)里九成都是同一個(gè)原因本機(jī)環(huán)境和這個(gè)包不匹配。環(huán)境不匹配不是說(shuō)你的電腦不行而是你沒(méi)先搞清楚自己這臺(tái)機(jī)器的參數(shù)到底是多少。就像你買內(nèi)存條之前要先看主板支持 DDR4 還是 DDR5裝 pip 包也一樣得先搞清楚 Python 版本、操作系統(tǒng)位數(shù)、pip 工具本身還健不健康、依賴有沒(méi)有沖突然后再?zèng)Q定裝哪個(gè)版本、用哪種方式裝。這篇文章要講的就是怎么把本機(jī)適合裝什么 pip 包這件事從玄學(xué)變成科學(xué)。我會(huì)把需要檢查的參數(shù)一個(gè)個(gè)列出來(lái)每個(gè)參數(shù)為什么重要、用什么命令查、輸出怎么讀全給你捋清楚。不管你是在 Windows 上還是在 Linux 服務(wù)器上跟著這套思路走至少能少踩一半裝包的坑。這篇文章適合誰(shuí)剛?cè)腴T Python 的新手還有那些已經(jīng)被各種報(bào)錯(cuò)折磨了一下午的準(zhǔn)老手。全文不談復(fù)雜的底層原理只講一個(gè)合格開(kāi)發(fā)者日常裝包時(shí)一定會(huì)用到的排查方法和決策邏輯看完你就能自己判斷這個(gè)包到底適不適合我這臺(tái)機(jī)器。2. 決定裝包成敗的關(guān)鍵參數(shù)到底有哪些2.1 Python 解析器版本一切匹配的基石Python 版本是第一位的硬性參數(shù)。很多包在發(fā)布時(shí)會(huì)明確聲明支持哪些 Python 版本比如Requires-Python: 3.8, 3.12。如果你本機(jī)的 Python 是 3.13那這個(gè)包大概率裝不上或者裝上了也會(huì)在導(dǎo)入時(shí)報(bào)語(yǔ)法錯(cuò)誤或二進(jìn)制不兼容。查看本機(jī) Python 版本最直接的方式是python --version在 Windows 上如果用了 py 啟動(dòng)器也可以py -0p后者會(huì)列出機(jī)器上安裝的所有 Python 版本和對(duì)應(yīng)路徑這個(gè)命令在排查多版本共存問(wèn)題時(shí)特別好用。實(shí)際操作中我還遇到過(guò)一種很隱蔽的情況終端里明明顯示的 Python 版本沒(méi)問(wèn)題但pip install裝的卻是另一個(gè) Python 環(huán)境。這是因?yàn)橄到y(tǒng) PATH 里同時(shí)存在多個(gè) Python而python和pip指向的未必是同一個(gè)解釋器。要確認(rèn)這點(diǎn)有兩個(gè)命令可以交叉驗(yàn)證python -c import sys; print(sys.executable) pip --versionpip --version輸出里會(huì)帶一個(gè)路徑比如pip 23.2.1 from C:\Python311\Lib\site-packages\pip (python 3.11)。如果這個(gè)路徑和你python --version對(duì)應(yīng)的路徑不是一個(gè)說(shuō)明你的pip和python已經(jīng)分家了。這種情況在 macOS 和 Linux 上更常見(jiàn)因?yàn)橄到y(tǒng)自帶的 Python 和后來(lái)裝的 Python 經(jīng)常打架。2.2 操作系統(tǒng)類型和 CPU 架構(gòu)決定你裝哪個(gè) wheel第二個(gè)關(guān)鍵參數(shù)是操作系統(tǒng)和 CPU 架構(gòu)。pip 在安裝包的時(shí)候如果源里面有編譯好的二進(jìn)制包wheel它會(huì)根據(jù)平臺(tái)標(biāo)簽來(lái)挑選匹配的文件。這些標(biāo)簽長(zhǎng)這樣win_amd64Windows 64 位win32Windows 32 位manylinux2014_x86_64Linux 64 位glibc 版本較新macosx_10_9_x86_64macOS 10.9 及以上Intel 芯片查看本機(jī)平臺(tái)信息一條命令搞定python -c import platform; print(platform.platform()); print(platform.machine())我的實(shí)際經(jīng)驗(yàn)是platform.machine()對(duì)大多數(shù)場(chǎng)景夠用了。x86_64和AMD64都是一回事都是 64 位 x86 架構(gòu)。如果是arm64或者aarch64說(shuō)明你用的是 ARM 芯片比如 Apple Silicon 或者云服務(wù)器上的 ARM 實(shí)例這時(shí)候不少流行庫(kù)的 wheel 可能是缺失的處理方式會(huì)完全不一樣。特別注意很多人在 Windows 上分不清 32 位和 64 位。一個(gè)常見(jiàn)場(chǎng)景是你下載了一個(gè) Python 3.11 的 32 位版本裝在 64 位 Windows 上然后去裝numpy它會(huì)嘗試去找win32的 wheel?,F(xiàn)在的 numpy 已經(jīng)很少提供 32 位版本了于是就開(kāi)始報(bào)找不到匹配版本。這不是你的問(wèn)題是 32 位 Python 的問(wèn)題。解決辦法是重新裝 64 位的 Python。2.3 pip 工具本身的狀態(tài)最容易被忽略的隱形殺手很多報(bào)錯(cuò)其實(shí)不是包的問(wèn)題是 pip 本身出了問(wèn)題。我見(jiàn)過(guò)最多的是這兩個(gè)第一個(gè)是no module named pip。這個(gè)錯(cuò)誤很無(wú)語(yǔ)尤其是當(dāng)你用python -m pip install的時(shí)候突然蹦出來(lái)。常見(jiàn)原因包括Python 安裝時(shí)沒(méi)勾選 pip 組件或者你換了一個(gè)環(huán)境比如從系統(tǒng) Python 切到虛擬環(huán)境虛擬環(huán)境里沒(méi)裝 pip或者 pip 被手賤刪了。修復(fù)方式也比較固定python -m ensurepip --upgrade或者用你所在操作系統(tǒng)對(duì)應(yīng)的方式重新引導(dǎo) pip。在某些 Linux 發(fā)行版上還要注意系統(tǒng)自帶的 Python 是受保護(hù)的直接用apt install python3-pip才能裝到系統(tǒng)級(jí)環(huán)境而不是用pip去裝 pip。第二個(gè)常見(jiàn)問(wèn)題是 pip 版本太舊。pip 本身一直在更新用來(lái)適配新的打包協(xié)議和索引接口。舊版 pip 在解析某些包依賴時(shí)會(huì)用老的邏輯導(dǎo)致解析失敗。建議定期檢查python -m pip --version如果版本低于 21.x我建議先升級(jí)再裝其他包python -m pip install --upgrade pip升級(jí)完再看報(bào)錯(cuò)是不是自動(dòng)消失了。這個(gè)先升級(jí) pip 再排查的動(dòng)作雖然簡(jiǎn)單但在實(shí)際排障里成功率特別高因?yàn)檫@個(gè)操作成本低而且能排除掉一大類解析器層面的問(wèn)題。2.4 安裝路徑、權(quán)限和虛擬環(huán)境的狀態(tài)這個(gè)參數(shù)很多人不重視但它的影響力被嚴(yán)重低估。pip install的包最終會(huì)落到某個(gè)站點(diǎn)目錄site-packages這個(gè)位置受當(dāng)前 Python 環(huán)境、用戶權(quán)限和虛擬環(huán)境三方面共同影響。查看當(dāng)前包的安裝路徑python -c import site; print(site.getsitepackages())如果你在虛擬環(huán)境里可以用python -c import sys; print(sys.prefix)如果sys.prefix指向的是一個(gè)虛擬環(huán)境的目錄那你確實(shí)在虛擬環(huán)境里如果指向系統(tǒng) Python 的安裝目錄那就是系統(tǒng)級(jí)環(huán)境。很多人裝包時(shí)遇到的PermissionError: [Errno 13] Permission denied就是因?yàn)樵谙到y(tǒng)級(jí)環(huán)境里直接pip install而系統(tǒng) Python 的 site-packages 不在當(dāng)前用戶可寫范圍。這時(shí)候要么加--user參數(shù)裝到用戶目錄要么切換到虛擬環(huán)境要么用管理員權(quán)限裝。我的建議永遠(yuǎn)是優(yōu)先用虛擬環(huán)境而不是去硬剛系統(tǒng) Python 的權(quán)限。虛擬環(huán)境的創(chuàng)建我已經(jīng)說(shuō)了無(wú)數(shù)次還要再說(shuō)一次python -m venv venvWindows 下激活venv\Scripts\activateLinux/macOS 下激活source venv/bin/activate激活后你會(huì)發(fā)現(xiàn)python --version還是同一個(gè)版本但sys.prefix已經(jīng)指向了虛擬環(huán)境目錄。這時(shí)候所有pip install的包都會(huì)隔離在這個(gè)虛擬環(huán)境里既不影響系統(tǒng) Python也不怕不同項(xiàng)目的依賴互相沖突。2.5 依賴沖突裝了不代表能跑最后一項(xiàng)參數(shù)是你當(dāng)前環(huán)境里已經(jīng)有什么包。有時(shí)候報(bào)錯(cuò)不是沒(méi)裝成功而是裝好后導(dǎo)入時(shí)崩了原因是新包依賴的某個(gè)庫(kù)和已有庫(kù)版本沖突。這屬于環(huán)境參數(shù)的動(dòng)態(tài)部分。查看已安裝的所有包pip list查看某個(gè)特定包的信息pip show numpypip show輸出里能看到Requires字段告訴你這個(gè)包依賴什么。這個(gè)功能在排查為什么裝 A 會(huì)把 B 破壞掉的時(shí)候特別有用。比如 A 依賴numpy1.25而你環(huán)境里的 numpy 是 1.26pip 在解析依賴時(shí)可能會(huì)自己去裝一個(gè)舊版 numpy——如果你沒(méi)加--no-deps的話。這個(gè)過(guò)程有時(shí)候會(huì)靜默執(zhí)行你甚至沒(méi)注意到 numpy 已經(jīng)被悄悄降級(jí)了然后其他依賴新 numpy 的模塊就開(kāi)始崩潰。要避免這種災(zāi)難我有兩個(gè)小習(xí)慣裝包前先pip list拍個(gè)快照裝完遇到問(wèn)題時(shí)可以對(duì)比差異。慎重使用--upgrade它會(huì)把依賴一起升級(jí)升級(jí)后有可能會(huì)引入不兼容。3. 從參數(shù)到?jīng)Q策判斷一個(gè) pip 包適不適合本機(jī)3.1 先看包名和版本號(hào)判斷發(fā)布時(shí)間和兼容性當(dāng)你決定安裝某個(gè)包的時(shí)候第一步先到 PyPI 上查一下這個(gè)包的信息。PyPI 頁(yè)面會(huì)展示最新版本號(hào)、發(fā)布?xì)v史、依賴項(xiàng)、支持的 Python 版本等內(nèi)容。雖然很多人習(xí)慣直接pip install xxx但我更推薦先看一下包的元數(shù)據(jù)尤其是在裝一些比較小眾的包時(shí)。一個(gè)比較實(shí)用的命令是pip index versions numpypip index versions能快速列出當(dāng)前源里所有可用的版本號(hào)并且它會(huì)標(biāo)注你本機(jī) Python 版本能匹配哪些版本。如果某個(gè)版本后面沒(méi)有標(biāo)識(shí)說(shuō)明它可能不適合當(dāng)前環(huán)境pip 會(huì)在安裝時(shí)把這個(gè)版本過(guò)濾掉。如果你指定pip install numpy1.23.0而本機(jī) Python 版本不支持就會(huì)報(bào)ERROR: Could not find a version that satisfies the requirement numpy1.23.0。判斷一個(gè)包適不適合最重要的一行信息是它的Requires-Python聲明。在 PyPI 的項(xiàng)目頁(yè)面或者通過(guò)pip show可以查到。這個(gè)東西意味著包的作者明確測(cè)試過(guò)哪些 Python 版本絕對(duì)不是隨便寫的。我自己就遇到過(guò)很多次包的Requires-Python卡在3.7,3.11而本機(jī)是 Python 3.12硬裝上去后代碼能導(dǎo)入但運(yùn)行特定的重計(jì)算功能時(shí)直接段錯(cuò)誤。這種問(wèn)題是最難排查的因?yàn)閳?bào)錯(cuò)和包本身沒(méi)有直接關(guān)系。3.2 用平臺(tái)標(biāo)簽判斷二進(jìn)制輪子是否存在平臺(tái)標(biāo)簽這個(gè)東西很多人在裝包時(shí)根本不會(huì)去看但它決定了你能否以下載即用的方式裝上包。如果你看到一個(gè)包只有源代碼包sdist而沒(méi)有對(duì)應(yīng)平臺(tái)的 wheel那么 pip 會(huì)嘗試從源代碼編譯安裝。編譯意味著需要編譯器、構(gòu)建工具、依賴庫(kù)頭文件等一大堆東西。在 Windows 上這意味著需要 Visual C Build Tools在 Linux 上意味著需要 gcc 和一堆-dev包。那怎么判斷某個(gè)包到底有沒(méi)有適配你平臺(tái)的 wheel兩條路第一直接訪問(wèn) PyPI 頁(yè)面看Download files區(qū)域里面會(huì)列出所有文件文件名的后半部分就是平臺(tái)標(biāo)簽。比如numpy-1.26.4-cp311-cp311-win_amd64.whl這表示 CPython 3.11、Windows 64 位專用。第二用一個(gè)命令去探測(cè)pip install --only-binary :all: numpy加上--only-binary :all:之后pip 強(qiáng)制只使用二進(jìn)制 wheel。如果它成功裝上了說(shuō)明這個(gè)包有適配你平臺(tái)的 wheel如果報(bào)No matching distribution found那就說(shuō)明沒(méi)有你得準(zhǔn)備處理源碼編譯了。這個(gè)判斷在實(shí)際項(xiàng)目里太有用了。我舉個(gè)例子在樹(shù)莓派或各種 ARM 單板機(jī)上跑 Python 項(xiàng)目時(shí)小到一個(gè)pycryptodome大到tensorflow經(jīng)常會(huì)遇到?jīng)]有 ARM wheel 的情況。這時(shí)候你必須接受源碼編譯那就要檢查你的構(gòu)建工具鏈齊全不齊全。在 Debian 系的 Linux 上至少要把這些裝上sudo apt install build-essential python3-devpython3-dev尤其重要因?yàn)樗?Python.h 頭文件很多 C 擴(kuò)展庫(kù)在編譯時(shí)必須要用到。你要是沒(méi)裝這個(gè)編譯過(guò)程會(huì)在fatal error: Python.h: No such file or directory這一行停下來(lái)特別典型。3.3 解析依賴鏈一個(gè)包背后往往牽著一串包現(xiàn)代 Python 項(xiàng)目基本都有依賴。你在pip install一個(gè)包時(shí)pip 會(huì)先去解析它的所有依賴然后逐個(gè)安裝。這個(gè)過(guò)程像系鞋帶一樣一個(gè)節(jié)點(diǎn)出了問(wèn)題整條鏈路都不通。我建議在裝包之前先做一個(gè)計(jì)劃演練看看 pip 打算干什么pip install --dry-run some-package--dry-run不會(huì)真正安裝任何東西它只負(fù)責(zé)解析依賴并展示將要執(zhí)行的操作。這樣你可以提前知道這個(gè)包會(huì)引入哪些新的包、會(huì)升級(jí)哪些已有的包、會(huì)不會(huì)動(dòng)到某個(gè)關(guān)鍵庫(kù)的版本。如果發(fā)現(xiàn)它要升級(jí)你正在用的某個(gè)庫(kù)你就有機(jī)會(huì)在動(dòng)手前評(píng)估影響。我一直強(qiáng)烈推薦大家用這個(gè)參數(shù)因?yàn)樗某杀緲O低卻能避免大量的裝完以后其他東西跑不起來(lái)的問(wèn)題。在pip的 20.3 版本以后--dry-run的行為已經(jīng)非常穩(wěn)定了它不僅能列出要裝的包還會(huì)像解謎一樣告訴你哪些條件滿足、哪些條件被忽略。另一個(gè)好用的參數(shù)是--tree或者上面提到的pip show用來(lái)查看一個(gè)包已經(jīng)裝好的依賴樹(shù)pip show flask這樣能看到 Flask 下面依賴的 Werkzeug、Jinja2 等包以及它們各自是否滿足版本要求。如果某個(gè)依賴版本不對(duì)你會(huì)在pip check里看到警告。說(shuō)到pip check這也是我每次調(diào)試依賴問(wèn)題必跑的一條命令pip check它檢查當(dāng)前環(huán)境里所有包的依賴是否完整。如果在pip check的輸出里出現(xiàn)了任何一行沖突信息不需要懷疑你的環(huán)境必然存在問(wèn)題。它會(huì)明確告訴你哪個(gè)包依賴的什么庫(kù)不滿足。有了這個(gè)線索再去定位就快多了。3.4 配置鏡像源讓安裝更快更穩(wěn)很多人在國(guó)內(nèi)環(huán)境安裝包時(shí)會(huì)遇到一個(gè)很頭疼的現(xiàn)象pip install卡在Downloading那一步不動(dòng)或者下載到一半就超時(shí)斷開(kāi)。這是網(wǎng)絡(luò)鏈路的典型癥狀解決辦法是換鏡像源。鏡像源本質(zhì)上就是 PyPI 的同步副本國(guó)內(nèi)常見(jiàn)的包括清華、中科大、阿里云等。第一次配置鏡像源時(shí)我建議用命令行參數(shù)試試速度pip install some-package -i https://pypi.tuna.tsinghua.edu.cn/simple如果速度可以接受就寫進(jìn)全局配置省得每次敲那么長(zhǎng)一串。配置文件位置在 Windows 上是%APPDATA%\pip\pip.ini在 Linux/macOS 上是~/.pip/pip.conf或~/.config/pip/pip.conf。沒(méi)有就自己創(chuàng)建一個(gè)內(nèi)容示例[global] index-url https://pypi.tuna.tsinghua.edu.cn/simple trusted-host pypi.tuna.tsinghua.edu.cntrusted-host這一項(xiàng)在早期一些舊版 pip 或者沒(méi)有正式 SSL 證書的鏡像上需要加進(jìn)去現(xiàn)在清華源已經(jīng)配了正常的證書一般不用。如果改完配置后 pip 報(bào)WARNING: The repository located at xxx is not a trusted or secure host那就把這行加上再去安裝。鏡像源的作用不只是快還有一個(gè)隱性好處有些第三方源會(huì)同步一些 PyPI 上存在但索引更新滯后的包或者對(duì)一些包的元數(shù)據(jù)做了增強(qiáng)處理。不過(guò)這種情況很少大部分場(chǎng)景下鏡像源就是為了速度穩(wěn)定加省略超時(shí)煩惱。3.5 安裝方式的取舍普通安裝、可編輯安裝、指定 wheel 文件同樣是pip install不同的參數(shù)組合對(duì)安裝結(jié)果的影響差別巨大。我先列幾種最常見(jiàn)的pip install package默認(rèn)安裝從源站拉取對(duì)應(yīng)平臺(tái) wheel或退回到源碼編譯。pip install package1.2.3指定版本安裝主要用于鎖定版本或者回滾到舊版。pip install -e .可編輯安裝editable install多用于本地開(kāi)發(fā)項(xiàng)目代碼改動(dòng)即時(shí)生效不用重裝。pip install /path/to/package.whl直接安裝一個(gè)本地 wheel 文件常用于離線環(huán)境或者使用自定義構(gòu)建的包。每種方式的背后都有其適用場(chǎng)景。我特別想提的是 wheel 文件安裝這個(gè)模式。當(dāng)你下載了一個(gè).whl文件之后直接pip install xxx.whlpip 會(huì)跳過(guò)遠(yuǎn)程查找和下載的環(huán)節(jié)直接從本地解析安裝。這不僅省時(shí)間關(guān)鍵是它能繞過(guò)很多網(wǎng)絡(luò)問(wèn)題也能讓你手動(dòng)控制包的版本。比如你要裝的包的最新版在你的平臺(tái)有問(wèn)題你可以去 PyPI 手動(dòng)下載舊一點(diǎn)的 wheel 安裝。還有一點(diǎn)pip install -e .這種開(kāi)發(fā)模式很多新手不理解它和普通安裝的區(qū)別。普通安裝會(huì)把代碼復(fù)制到 site-packages 目錄你修改源碼之后原樣代碼不會(huì)變運(yùn)行的程序還是舊版本??删庉嫲惭b會(huì)在 site-packages 里生成一個(gè)指向你項(xiàng)目目錄的鏈接你本地改代碼跑程序就是新代碼。在后端項(xiàng)目開(kāi)發(fā)中這個(gè)東西特別常用。如果你是在做一個(gè)需要反復(fù)改代碼的 Python 項(xiàng)目別用普通安裝直接用-e模式就對(duì)了。4. 實(shí)戰(zhàn)案例三個(gè)典型場(chǎng)景的完整排查路線4.1 場(chǎng)景一裝 numpy 時(shí)找不到匹配版本報(bào)錯(cuò)信息長(zhǎng)這樣ERROR: Could not find a version that satisfies the requirement numpy ERROR: No matching distribution found for numpy我的排查順序是固定的第一步確認(rèn) Python 版本和架構(gòu)python --version python -c import platform; print(platform.machine())如果機(jī)器架構(gòu)是arm64好原因就清楚了大部分 numpy 歷史版本沒(méi)有提供 ARM 平臺(tái)的 wheel。這種情況直接從 PyPI 看看有沒(méi)有新版本提供了 ARM 支持然后指定版本安裝。如果架構(gòu)是x86_64再看 Python 是 32 位還是 64 位。Windows 上可以用python -c import struct; print(struct.calcsize(P) * 8)輸出 32 就是 32 位64 就是 64 位。32 位 Python 在 2023 年以后的 numpy 中基本沒(méi)法用。第二步確認(rèn) pip 源里有沒(méi)有這個(gè)包pip index versions numpy如果輸出正常說(shuō)明源沒(méi)問(wèn)題如果這個(gè)命令本身報(bào)錯(cuò)那可能是你的 pip 源配置有問(wèn)題先pip config list看看配了什么源。第三步強(qiáng)制走二進(jìn)制模式測(cè)試pip install --only-binary :all: numpy如果報(bào)找不到匹配版本確認(rèn)問(wèn)題就是該平臺(tái)沒(méi)有預(yù)編譯 wheel需要源碼編譯或者選其他版本。如果安裝成功了說(shuō)明之前是依賴解析邏輯出了問(wèn)題嘗試升級(jí) pip 再裝。4.2 場(chǎng)景二裝 torch 等大型框架時(shí)來(lái)回失敗裝 torch 這類重量級(jí)框架失敗原因和裝 numpy 完全不一樣。它的 wheel 文件特別大動(dòng)輒幾百 MB 甚至上 GB最容易出問(wèn)題的環(huán)節(jié)是網(wǎng)絡(luò)中斷和磁盤空間不足。我的建議是不要直接用pip install torch從默認(rèn)源拉而是提前到官網(wǎng)找到對(duì)應(yīng)你 CUDA 版本和系統(tǒng)平臺(tái)的安裝命令。這里涉及一個(gè)額外參數(shù)CUDA 版本。查看本機(jī) CUDA 版本nvidia-smi如果沒(méi)安裝 nvidia-smi也可以在 Python 里查 PyTorch 的構(gòu)建版本python -c import torch; print(torch.version.cuda)確認(rèn) CUDA 版本后到 PyTorch 官網(wǎng)選擇對(duì)應(yīng)的安裝命令通常形如pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118--index-url這個(gè)參數(shù)允許你為單次安裝指定一個(gè)完全不同的包索引源比修改全局 pip 配置范圍小得多也安全得多。如果你在裝包過(guò)程中出現(xiàn)了ReadTimeoutError可以加上超時(shí)參數(shù)pip install --timeout 600 torch另外還要注意磁盤空間。torch 全家桶動(dòng)輒幾十 GB不要盲目的把臨時(shí)緩存目錄放在系統(tǒng)盤。你可以用PIP_CACHE_DIR環(huán)境變量把緩存挪到其他盤避免 C 盤塞滿導(dǎo)致安裝失敗set PIP_CACHE_DIRD:\pipcache4.3 場(chǎng)景三本地項(xiàng)目代碼 compile 報(bào)錯(cuò)這一類問(wèn)題的根源往往是包本身沒(méi)有 wheelpip 正在從源碼構(gòu)建。報(bào)錯(cuò)信息里如果出現(xiàn)了gcc、g、cl.exe、Python.h等字樣就說(shuō)明它開(kāi)始編譯了。這時(shí)需要檢查的參數(shù)就不再是 Python 版本那么簡(jiǎn)單而是構(gòu)建工具鏈。Windows 上需要 Visual Studio Build Tools并且安裝時(shí)需要勾選C 桌面開(kāi)發(fā)工作負(fù)載。Linux 上需要build-essential和python3-dev。macOS 上需要 Xcode Command Line Toolsxcode-select --install編譯類的報(bào)錯(cuò)最讓人頭疼因?yàn)樾畔⒘繕O大而且噪音多。我的經(jīng)驗(yàn)是先把報(bào)錯(cuò)信息完整保存下來(lái)搜第一行或者最后一行不要搜中間。中間通常會(huì)有一大堆編譯器的日志輸出都是無(wú)關(guān)信息。第一行和最后一行才是真正的原因。如果你不想折騰編譯工具鏈還有一個(gè)思路是尋找社區(qū)構(gòu)建的 wheel。有些非官方組織會(huì)為各平臺(tái)構(gòu)建 PyPI 上沒(méi)有的 wheel比如 Gohlke 的構(gòu)建倉(cāng)庫(kù)雖然現(xiàn)在不少人不推薦了、conda-forge 等。作為一種退路不要排斥用 conda 裝那些編譯難度很大的包。Conda 本身就是為二進(jìn)制分發(fā)設(shè)計(jì)的很多你在 pip 里編譯到崩潰的包在 conda 里一條命令就裝好了。5. 常見(jiàn)報(bào)錯(cuò)速查看到這幾個(gè)信息直接對(duì)號(hào)入座報(bào)錯(cuò)關(guān)鍵字常見(jiàn)原因首選排查動(dòng)作典型解決方案No matching distribution found平臺(tái)無(wú)對(duì)應(yīng) wheel 或 Python 版本不滿足查看 Python 版本和 platform.machine()換 Python 版本、源碼編譯、用 condaPython.h: No such file or directory缺少 Python 開(kāi)發(fā)頭文件檢查python3-dev是否安裝Linux 上安裝python3-devPermissionError: [Errno 13]系統(tǒng)級(jí) site-packages 不可寫查看sys.prefix指向用虛擬環(huán)境或--userno module named pippip 組件缺失或環(huán)境損壞運(yùn)行python -m ensurepip --upgrade重新引導(dǎo) pip 或重建虛擬環(huán)境ReadTimeoutError與源站網(wǎng)絡(luò)連接不穩(wěn)定配置鏡像源或加大 timeout用-i指定鏡像源deps resolution error依賴版本沖突運(yùn)行pip check按提示調(diào)整相關(guān)包版本Failed building wheel當(dāng)前平臺(tái)無(wú)法編譯依賴檢查編譯工具鏈裝構(gòu)建工具或找替代 wheelValueError: check_hostname requires server_hostname代理或網(wǎng)絡(luò)環(huán)境異常查看代理環(huán)境變量清理代理配置或檢查網(wǎng)絡(luò)這個(gè)表里我按報(bào)錯(cuò)的特征詞分類了大部分情況下你只需要看到報(bào)錯(cuò)里的某一個(gè)關(guān)鍵字就能定位到對(duì)應(yīng)的原因區(qū)域。但也要注意報(bào)錯(cuò)的同一種表現(xiàn)形式背后可能完全不同的原因。就拿No matching distribution found來(lái)說(shuō)可能是網(wǎng)絡(luò)問(wèn)題源里沒(méi)有、可能是版本問(wèn)題Python 太新、也可能是平臺(tái)問(wèn)題沒(méi)有對(duì)應(yīng) wheel。所以光看這句報(bào)錯(cuò)只能知道沒(méi)找到合適的包真正的原因一定要組合其他參數(shù)一起判斷。6. 點(diǎn)一下我踩過(guò)的那些坑幫你省點(diǎn)時(shí)間裝了這么多年包多少攢了一點(diǎn)血淚教訓(xùn)。這里挑幾條我覺(jué)得最有價(jià)值的分享出來(lái)。第一pip install前面永遠(yuǎn)用python -m。也就是python -m pip install xxx而不是直接pip install xxx。后者的pip命令是從 PATH 里找的你無(wú)法保證它和你正在用的python是同一個(gè)版本的配套工具。用python -m pip就能精確地把 pip 綁定到當(dāng)前解釋器上避免裝是裝上了但導(dǎo)入時(shí)找不到的詭異問(wèn)題。第二pip的高版本自動(dòng)解析雖然好但別亂升級(jí)。我現(xiàn)在固定用 23.x 到 24.x 這個(gè)大版本區(qū)間不去追最新。原因很簡(jiǎn)單新版 pip 對(duì)舊包元數(shù)據(jù)的兼容性有時(shí)候會(huì)有變化可能導(dǎo)致某些老項(xiàng)目的依賴解析方式和以前不一樣。如果項(xiàng)目長(zhǎng)期穩(wěn)定運(yùn)行就別輕易動(dòng) pip 工具鏈。第三裝包之前先檢查依賴而不是裝完再查。用pip install --dry-run提前看影響面能避免非常多的售后問(wèn)題。這個(gè)習(xí)慣我向所有人推薦。第四在多環(huán)境并存的時(shí)候給每個(gè)項(xiàng)目配獨(dú)立的虛擬環(huán)境名字起得有辨識(shí)度一點(diǎn)比如venv_tf、venv_web。這樣你看到終端提示符就知道當(dāng)前在哪個(gè)環(huán)境里不串臺(tái)。為這個(gè)教訓(xùn)我花過(guò)不止一個(gè)下午的時(shí)間排錯(cuò)很痛。第五遇到疑難雜癥不要賭。先把pip list復(fù)制一份存到文本文件里然后清理緩存再逐個(gè)試探。遇到解釋不了的問(wèn)題寧可重置虛擬環(huán)境重新來(lái)也別嘗試在壞環(huán)境里反復(fù)修補(bǔ)。重建虛擬環(huán)境的成本遠(yuǎn)低于排查成本。