動安裝全流程及常見故障排查)
1. 項目背景與環(huán)境預(yù)檢搞GPU服務(wù)器的朋友肯定都有體會CentOS 7系統(tǒng)穩(wěn)是穩(wěn)但裝驅(qū)動這件事稍不留神就黑屏、卡死、循環(huán)登錄甚至內(nèi)核直接崩潰。我給一臺某高校實驗室的深度學(xué)習(xí)服務(wù)器裝機時就折騰了整整一下午這里把完整流程和踩過的坑都記錄下來。先說清楚這臺設(shè)備的配置CPU是Intel至強系列顯卡是某型號的NVIDIA專業(yè)卡系統(tǒng)是CentOS 7.9內(nèi)核版本3.10.0機器上有兩塊機械硬盤一塊裝系統(tǒng)一塊純做數(shù)據(jù)盤內(nèi)存64G。整個流程的目標很簡單裝上NVIDIA官方驅(qū)動讓nvidia-smi能正常輸出GPU計算能跑起來后續(xù)跑深度學(xué)習(xí)框架不報錯。動手之前這四件事必須先做少一件都容易翻車。1.1 確認顯卡型號和系統(tǒng)環(huán)境這一步很多人會跳過但偏偏最容易踩坑。驅(qū)動不是越新越好顯卡型號不同、顯存大小不同對應(yīng)能裝的驅(qū)動版本差異很大。我遇到過有人拿著老掉牙的卡硬裝最新驅(qū)動結(jié)果編譯直接報錯報錯信息看著像內(nèi)核頭文件缺失其實是驅(qū)動壓根不支持老架構(gòu)。lspci | grep -i nvidia cat /etc/redhat-release uname -rlspci顯示的是硬件層面的顯卡型號比如NVIDIA GeForce GTX 1080或者NVIDIA Tesla V100。這一步確認了實際硬件后去NVIDIA官網(wǎng)查對應(yīng)驅(qū)動版本的適配表。這里有個原則優(yōu)先選擇NVIDIA官網(wǎng)提供的對應(yīng)顯卡型號的長期支持版本Long Lived Branch不要追新。實驗室那臺服務(wù)器最終選的驅(qū)動版本是530.41.03適配Tesla系列和部分GeForce系列CUDA 12.2配套也穩(wěn)定。系統(tǒng)環(huán)境主要看內(nèi)核版本CentOS 7默認是3.10.0如果自己編譯過內(nèi)核或者升級過版本會更高。NVIDIA驅(qū)動需要對應(yīng)版本的內(nèi)核頭文件和源碼包這兩個東西必須和當(dāng)前內(nèi)核完全匹配。我見過有人裝完驅(qū)動后重啟系統(tǒng)起不來排查半天發(fā)現(xiàn)是內(nèi)核頭文件版本不對驅(qū)動模塊編譯出來加載不上。1.2 確認nouveau開源驅(qū)動占用情況CentOS 7默認帶著開源的nouveau驅(qū)動這個驅(qū)動和NVIDIA官方驅(qū)動沖突一起加載必出問題。裝官方驅(qū)動前必須把nouveau徹底禁用掉否則你在nvidia-installer時它會提示nouveau正在使用然后直接退出。檢查nouveau的狀態(tài)lsmod | grep nouveau只要輸出里有nouveau字樣就說明它已經(jīng)加載到內(nèi)核里了。禁用它的做法是在/etc/modprobe.d/下新建一個配置文件寫入黑名單設(shè)置然后重建initramfs讓系統(tǒng)啟動時不再加載nouveau模塊。禁用操作本身不難但要注意改完initramfs之后必須重啟系統(tǒng)而且重啟前要確認配置寫對了。我見過有人改了配置沒重啟就急著裝驅(qū)動裝到一半卡死然后一頭霧水。另一個坑是某些系統(tǒng)鏡像預(yù)裝了圖形界面拿nouveau做桌面顯示的這種機器要進入純字符模式再操作否則圖形界面會占用GPU設(shè)備驅(qū)動安裝時訪問/dev/nvidia0失敗。1.3 確認內(nèi)核頭文件和gcc等編譯環(huán)境NVIDIA官方驅(qū)動的run包是現(xiàn)場編譯內(nèi)核模塊的需要內(nèi)核頭文件包和gcc、make、glibc-devel等基礎(chǔ)工具。缺少任何一個裝驅(qū)動時都會在編譯階段報錯而編譯報錯的類型很多看著嚇人但原因往往就是環(huán)境不全。yum install -y gcc make kernel-devel-$(uname -r) epel-release上面這條命令的關(guān)鍵在于kernel-devel-$(uname -r)的動態(tài)匹配。很多人分不清kernel-headers和kernel-devel的區(qū)別前者只提供頭文件后者才包含完整的聲名和部分源碼連接是鏈接到/usr/src/kernels/目錄下的內(nèi)容NVIDIA驅(qū)動編譯時需要的是kernel-devel。如果裝完后執(zhí)行l(wèi)s /usr/src/kernels/沒看到對應(yīng)版本目錄那就是裝錯了。個別情況下yum源里找不到匹配內(nèi)核版本的kernel-devel這時候要么換一個可用的源要么手動去某軟件倉庫下載對應(yīng)RPM包安裝。1.4 規(guī)劃驅(qū)動安裝方式驅(qū)動安裝主要有四種方式不同方式適配不同場景我這里簡單對比一下后續(xù)章節(jié)會詳細講其中兩條路線安裝方式適用場景優(yōu)點缺點官方run包絕大多數(shù)生產(chǎn)環(huán)境、服務(wù)器最穩(wěn)定、可選參數(shù)多、可控性強需要編譯環(huán)境、操作繁瑣ELRepo kmod-nvidiaCentOS/RHEL官方社區(qū)源安裝快、自動更新版本滯后、某些特定卡不支持CUDA toolkit捆綁驅(qū)動跑深度學(xué)習(xí)框架一次搞定CUDA版本綁定后續(xù)升級驅(qū)動麻煩系統(tǒng)自帶gnome軟件有圖形桌面的場景圖形化簡單兼容性差服務(wù)器一般不碰我最終選了官方run包方式原因很簡單這臺機器是給深度學(xué)習(xí)用的CUDA版本要自己控制驅(qū)動版本也要和CUDA做匹配run包方式可以精準控制這些變量。ELRepo雖然簡單快速但它的驅(qū)動版本通常滯后幾個月新卡支持往往跟不上CUDA toolkit捆綁的驅(qū)動則存在互相覆蓋的問題后續(xù)想單獨換驅(qū)動版本時會比較繞。2. 驅(qū)動安裝方案的完整流程CentOS 7下裝NVIDIA驅(qū)動選官方run包是相對最靠譜的一條路。這里我把每一步操作和背后的邏輯都拆開講清楚。2.1 禁用nouveau驅(qū)動的完整操作先創(chuàng)建一個黑名單配置文件vim /etc/modprobe.d/blacklist-nouveau.conf寫入以下內(nèi)容blacklist nouveau options nouveau modeset0第一行告訴內(nèi)核不要加載nouveau第二行關(guān)閉它的模式設(shè)置功能。寫完保存后需要重新生成initramfs鏡像mv /boot/initramfs-$(uname -r).img /boot/initramfs-$(uname -r).img.bak dracut /boot/initramfs-$(uname -r).img $(uname -r)注意這里不是直接用dracut -f強制覆蓋而是先備份原文件這樣萬一新生成的initramfs有問題還能回滾。重新生成鏡像的過程大概十幾秒輸出會顯示/boot/initramfs-3.10.0-1160.99.1.el7.x86_64.img之類的字樣后面跟一串模塊列表看到nouveau出現(xiàn)在其中也不用慌黑名單配置早就寫好了它不會再被加載。改完后重啟系統(tǒng)重啟后再次執(zhí)行l(wèi)smod | grep nouveau這條命令不輸出任何內(nèi)容就對了。如果還有輸出大概率是黑名單配置文件沒生效檢查一下文件權(quán)限和路徑拼寫。順便說一下有時候/etc/modprobe.d/里已經(jīng)有別的文件寫入了nouveau相關(guān)內(nèi)容比如某些云鏡像生成的blacklist.conf這種需要仔細檢查不要一個文件沒生效就急著繼續(xù)。2.2 進入純命令行模式安裝RPM系發(fā)行版在安裝NVIDIA驅(qū)動時通常建議停掉圖形界面因為X Server會占用GPU設(shè)備。服務(wù)器有圖形界面的情況雖然不多見但還是提一下CentOS 7如果裝了GNOME桌面要先把默認運行級別切到多用戶模式。systemctl get-default systemctl set-default multi-user.target如果是臨時切換可以用systemctl isolate multi-user.target或者直接init 3進入字符界面。切換之前注意保存工作因為圖形界面會直接殺掉。還有一種情況是SSH遠程連接安裝根本不需要圖形界面直接按命令行操作就行但如果機器上裝了X Server且正在運行建議還是先停掉。跑安裝腳本前需要把驅(qū)動run包上傳到服務(wù)器比如放到/tmp目錄下然后加上執(zhí)行權(quán)限chmod x NVIDIA-Linux-x86_64-530.41.03.run ./NVIDIA-Linux-x86_64-530.41.03.run --silent --no-opengl-files--no-opengl-files這個參數(shù)很關(guān)鍵OpenGL文件會和系統(tǒng)已有的GL庫沖突有時會導(dǎo)致圖形界面起不來。如果純計算服務(wù)器不需要桌面顯示直接帶上這個參數(shù)最保險。2.3 處理Secure Boot和內(nèi)核模塊簽名問題現(xiàn)在的服務(wù)器主板基本都默認開啟Secure Boot這會給NVIDIA驅(qū)動安裝帶來額外麻煩。CentOS 7內(nèi)核如果是在Secure Boot模式下啟動的加載第三方內(nèi)核模塊時會要求模塊有合法簽名否則直接被拒。安裝時如果沒注意這個裝完驅(qū)動重啟后會看到類似這樣的提示Loading /var/lib/dkms/nvidia/530.41.03/build/nvidia.ko Error: Module nvidia not foundnvidia-smi執(zhí)行時報Failed to initialize NVML: Driver/library version mismatch也是這個原因的一種表現(xiàn)。解決方法有幾個最簡單的就是進BIOS把Secure Boot關(guān)掉。但有些服務(wù)器是托管的BIOS密碼都在機房管理員手里改不了。這種情況可以走模塊簽名流程生成自簽名密鑰然后用mokutil導(dǎo)入系統(tǒng)Linux內(nèi)核啟動時會按MOK列表驗證模塊簽名。生成簽名密鑰的流程openssl req -new -x509 -newkey rsa:2048 -keyout MOK.priv -outform DER -out MOK.der -nodes -days 36500 -subj /CNNVIDIA-MODULE-SIGN/然后用mokutil --import MOK.der導(dǎo)入密鑰重啟后系統(tǒng)會進入MOK管理界面按提示完成密碼確認和密鑰加載。之后再用/usr/src/kernels/$(uname -r)/scripts/sign-file對編譯好的nvidia.ko、nvidia-modeset.ko等一堆內(nèi)核模塊逐一簽名。這個操作比較繁瑣但卻是唯一的正規(guī)路線。我分享一個經(jīng)驗簽名腳本要對lib/modules/$(uname -r)/extra/nvidia下所有.ko文件執(zhí)行不要只簽主模塊。漏簽一個對應(yīng)的功能就會受限比如nvidia-modeset.ko沒簽顯示器驅(qū)動就加載不上nvidia-uvm.ko沒簽CUDA統(tǒng)一內(nèi)存就不可用。2.4 DKMS方式的替代方案CentOS 7里還可以通過DKMS框架來管理NVIDIA驅(qū)動模塊。DKMS的好處是當(dāng)內(nèi)核升級時驅(qū)動模塊會自動重編譯不用每次升級內(nèi)核后手動重裝驅(qū)動。yum install -y dkms裝好DKMS框架后在安裝NVIDIA run包時加上--dkms參數(shù)模塊文件會交給DKMS維護。裝完后每次系統(tǒng)通過yum升級內(nèi)核DKMS都會檢測到新內(nèi)核在重啟前自動把NVIDIA模塊編譯好避免升級內(nèi)核后驅(qū)動失效的尷尬。我在生產(chǎn)環(huán)境里更推薦這種方式因為服務(wù)器總要打安全補丁升級內(nèi)核的不會自動重編驅(qū)動的話每次升級都要心驚膽戰(zhàn)。DKMS方式有幾個注意點第一kernel-devel必須和當(dāng)前運行內(nèi)核完全一致DKMS編譯就是依賴它第二導(dǎo)入MOK密鑰的頻率也要跟上內(nèi)核升級后簽名密鑰不會自動變但模塊會重新編譯所以建議保留MOK密鑰文件方便重新簽名。第三NVIDIA驅(qū)動run包在DKMS安裝模式下會往/usr/src/nvidia-530.41.03/寫入源碼不要手動刪否則DKMS無從編譯。2.5 設(shè)置環(huán)境變量和持久化配置驅(qū)動裝完后還需要設(shè)置CUDA相關(guān)的環(huán)境變量。雖然NVIDIA驅(qū)動本身不依賴CUDA但跑深度學(xué)習(xí)框架時需要讓系統(tǒng)找到nvcc編譯器和CUDA運行庫。在/etc/profile.d/下新建一個文件vim /etc/profile.d/cuda.sh寫入export PATH/usr/local/cuda-12.2/bin:$PATH export LD_LIBRARY_PATH/usr/local/cuda-12.2/lib64:$LD_LIBRARY_PATH保存后source /etc/profile生效。這里要注意/usr/local/cuda是一個軟鏈接指向?qū)嶋H安裝的CUDA版本目錄。系統(tǒng)里如果之前裝過別的版本軟鏈接指向可能不是你想要的需要確認一下。ls -l /usr/local/ | grep cuda看清楚鏈接目標別配了個幽靈路徑。還要處理電源管理問題GPU服務(wù)器功耗這塊需要配置持久化模式否則每次重啟NVIDIA驅(qū)動都會恢復(fù)到默認的非持久化模式GPU工作頻率管理混亂而且在某些虛擬化環(huán)境下會隨機掉卡。nvidia-smi -pm 1這條命令的意義是讓NVIDIA驅(qū)動服務(wù)在后臺常駐管理GPU狀態(tài)。它會把電源管理配置寫入/etc/nvidia/目錄下的配置文件中SDK服務(wù)隨開機自動啟動不用每次手動開。順便說一下加了-pm 1后nvidia-smi每次查詢GPU狀態(tài)的速度會明顯變快算是個意外之喜。3. 簡單測試與性能驗證裝完驅(qū)動最要緊的就是立刻驗證這一步能確認驅(qū)動是否真的對系統(tǒng)所有組件都兼容而不是僅僅“裝上沒報錯”。3.1 nvidia-smi基礎(chǔ)信息檢查剛裝完驅(qū)動先跑一下nvidia-smi這是判斷驅(qū)動安裝是否成功的最直接手段。正常輸出會顯示顯卡名稱、驅(qū)動版本、CUDA版本、顯存使用情況等。常見的問題場景是驅(qū)動版本顯示出來了但CUDA Version顯示N/A或者顯示版本號但和預(yù)期不一致。如果是N/A說明CUDA toolkit沒有裝或者系統(tǒng)環(huán)境變量沒配對驅(qū)動本身沒問題。根據(jù)經(jīng)驗先檢查/usr/local/cuda軟鏈接是否存在再檢查LD_LIBRARY_PATH里的路徑是否正確大多數(shù)情況是環(huán)境變量配置漏了。nvidia-smi下方會有一個進程列表顯示當(dāng)前占用GPU的進程。正常狀態(tài)下這里是空的但如果之前有過別的進程運行會看到殘留這個不用管如果顯示錯誤進程名或者PID異??梢杂胒user -v /dev/nvidia*查具體占用者。供電方面nvidia-smi -q -d POWER可以查看當(dāng)前功耗注意如果是老平臺的PCIe 2.0插槽供電限制可能導(dǎo)致GPU性能跑不滿但這類問題一般不是驅(qū)動故障是硬件槽位約束。3.2 檢查內(nèi)核模塊加載狀態(tài)lsmod | grep nvidia正常情況下至少會有nvidia、nvidia_uvm、nvidia_drm、nvidia_modeset這幾個模塊輸出。其中nvidia_drm是顯示輸出模塊純計算場景下有沒有它不太影響CUDA計算但如果有桌面顯示需求它必須存在且正確加載。模塊加載情況的順序也值得注意。nvidia_modeset和nvidia_drm依賴nvidia父模塊如果父模塊沒加載成功后面這幾個也會顯示不可用。用dmesg | grep nvidia查看內(nèi)核日志能看到模塊加載的具體錯誤信息。我遇到過nvidia_uvm模塊加載失敗的情況nvidia-smi能正常顯示但跑CUDA程序時統(tǒng)一內(nèi)存初始化報錯。原因是有個特定的內(nèi)核參數(shù)匹配問題重新加載一次模塊就正常了modprobe -r nvidia_uvm nvidia_modeset nvidia_drm nvidia modprobe nvidia_uvm3.3 圖形渲染能力測試Ubuntu桌面用戶或者有大規(guī)模可視化需求的朋友可以在裝有圖形界面的CentOS 7機器上運行g(shù)lxinfo查看OpenGL渲染器信息。如果顯示的是NVIDIA型號說明硬件加速已經(jīng)生效如果顯示的是llvmpipe或者Mesa說明還在用軟件模擬渲染性能會差太多。glxinfo | grep OpenGL renderer軟件渲染通常是因為沒裝glxinfo工具或者X Server沒有正確加載NVIDIA的GLX模塊。如果顯示libGL error: failed to load driver: swrast那就是GL庫文件路徑混亂了常見的解決辦法是用--no-opengl-files參數(shù)重新跑一遍安裝流程把OpenGL文件的選擇權(quán)交給系統(tǒng)本身。3.4 計算能力測試與CUDA基礎(chǔ)驗證如果CUDA toolkit已經(jīng)裝好最簡單的計算測試就是寫一段CUDA的向量加法或者直接跑deviceQuery示例。這里有個更簡單的方法用Python加PyTorch來驗證import torch print(torch.__version__) print(torch.cuda.is_available()) print(torch.cuda.get_device_name(0)) print(torch.cuda.get_device_capability(0)) a torch.randn(10000).cuda() b torch.randn(10000).cuda() c a b assert torch.allclose(c, a b, rtol1e-5) print(CUDA runtime test passed)PyTorch能正確輸出顯卡名稱和計算能力說明CUDA驅(qū)動部分已經(jīng)工作正常。向量加法的結(jié)果驗證能確保顯存讀寫沒有異常。在實驗室機器上實測輸出計算能力是(7,5)一張Tesla V100級別的卡跑起來單精度乘加運算快得出奇幾毫秒的運算根本沒必要用性能計數(shù)器去測損耗直接用torch.cuda.synchronize()卡一下時間就能測出大致水平。真實場景中跑深度學(xué)習(xí)計算測試時要注意顯存占用torch.randn(10000).cuda()這種小規(guī)模計算占不了多少顯存但如果是大模型的加載測試顯存不夠時PyTorch會拋出CUDA out of memory錯誤這個錯誤和驅(qū)動故障無關(guān)是要調(diào)batch size。3.5 用NVIDIA自帶工具做壓力測試驅(qū)動包自帶的nvidia-bug-report.sh和nvidia-smi diag這些工具可以更深入地檢測GPU健康狀態(tài)。nvidia-smi -q -d PERFORMANCE nvidia-smi -q -d TEMPERATURE nvidia-smi -q -d MEMORY跑一次完整的顯存壓力測試可以用nvidia-smi -q -d ECC查看ECC糾錯計數(shù)在深度學(xué)習(xí)訓(xùn)練環(huán)境中ECC計數(shù)如果持續(xù)增長說明顯存有硬件問題需要立刻排查。另一個方法是編譯驅(qū)動包里的NVIDIA CUDA Sample里面的bandwidthTest和deviceQuery示例非常適合驗證計算和帶寬。make -C /usr/local/cuda/samples/1_Utilities/bandwidthTest ./bandwidthTest輸出結(jié)果中Host to Device和Device to Host的帶寬值如果遠低于理論峰值或者波動很大就要檢查PCIe通道是不是沒跑在滿速狀態(tài)。我遇到過一次顯卡插在PCIe 3.0 x4槽位上帶寬只有x16的五分之一裝驅(qū)動時一切正常但訓(xùn)練速度非常慢。最后發(fā)現(xiàn)是主板上第二根PCIe插槽實際只有x4通道換槽后性能大幅提升。4. 常見問題與故障排查實錄驅(qū)動裝多了總會遇到各種問題這一節(jié)我把遇到的典型故障和排查路徑整理成速查表也把幾條重要的排查思路單獨講清楚。4.1 安裝完成后啟動卡在登錄界面或黑屏現(xiàn)象重啟后無法進入系統(tǒng)顯示器黑屏或者卡在登錄界面循環(huán)跳轉(zhuǎn)。在CentOS 7這種以X Server為主的系統(tǒng)里最常見的原因是OpenGL庫被覆蓋。解決辦法分兩種路徑如果是已經(jīng)裝好了驅(qū)動系統(tǒng)起不來進單用戶模式重裝驅(qū)動加上--no-opengl-files參數(shù)如果驅(qū)動還沒裝只是預(yù)先配置了nouveau黑名單導(dǎo)致桌面起不來那就進字符模式把/etc/modprobe.d/blacklist-nouveau.conf里內(nèi)容注釋掉先恢復(fù)系統(tǒng)再重新規(guī)劃安裝。新老司機都要記住純計算服務(wù)器上完全沒必要裝OpenGL相關(guān)的文件顯存計算和OpenGL沒有任何關(guān)系驅(qū)動包帶的那份OpenGL庫是針對桌面Linux用戶寫的服務(wù)器上加了它反而容易出事。4.2 NVIDIA-SMI報錯Failed to initialize NVMLFailed to initialize NVML: Driver/library version mismatch是頻率最高的報錯。原因通常是驅(qū)動/內(nèi)核模塊和用戶態(tài)庫的版本不一致比如內(nèi)核里還是老版本的nvidia.ko而用戶態(tài)的libnvidia-ml.so已經(jīng)被更新到新版了。排查思路nvidia-smi --version cat /proc/driver/nvidia/version兩者版本對不上就要用lsmod | grep nvidia看內(nèi)核模塊狀態(tài)用modprobe -r nvidia卸載再重新加載。如果重新加載后直接被拒絕需要重啟系統(tǒng)進入新內(nèi)核后用干凈的方式重新加載模塊。另一種類似報錯是NVML library version mismatch這種多數(shù)是驅(qū)動run包重裝但沒有徹底清理舊文件導(dǎo)致的。裝新版本前建議用nvidia-uninstall卸載一遍或者手動刪掉/usr/lib64/libnvidia*下的舊庫文件再重裝。4.3 內(nèi)核升級后驅(qū)動失效CentOS 7如果通過yum update升級了內(nèi)核重啟后往往發(fā)現(xiàn)nvidia-smi無法運行因為新內(nèi)核需要重新編譯NVIDIA內(nèi)核模塊。這就是前面提到DKMS價值的活案例沒配DKMS就要手動把驅(qū)動run包重新執(zhí)行一遍。重新執(zhí)行的方法很簡單./NVIDIA-Linux-x86_64-530.41.03.run --silent如果沒勾DKMS記得先檢查kernel-devel版本是否匹配新內(nèi)核不匹配先裝kernel-devel-$(uname -r)。升級內(nèi)核這個操作還有個大坑CentOS 7的yum update默認會保留多個內(nèi)核版本重啟時如果不小心選錯了舊內(nèi)核nvidia-smi也會報版本不匹配錯誤。所以升級完內(nèi)核重啟時最好確認一下當(dāng)前啟動的是哪個內(nèi)核版本uname -r一查便知。4.4 編譯錯誤Kernel header not found安裝run包時在編譯階段報Kernel header not found這個錯誤很多新手看到就慌。排查方向很簡單yum list installed | grep kernel-devel ls /usr/src/kernels/kernel-devel沒裝或者版本和uname -r不一致。有時候yum install kernel-devel會自動裝一個最新版本的內(nèi)核頭文件但這個最新版本和當(dāng)前運行的內(nèi)核不是同一個這就會導(dǎo)致問題。解決方法是明確指定版本號安裝yum install -y kernel-devel-$(uname -r)如果當(dāng)前運行的內(nèi)核版本在yum源里找不到對應(yīng)的kernel-devel包極大概率是機器內(nèi)核被手動升級過了而CentOS 7的基礎(chǔ)yum源沒有新到那個內(nèi)核版本的開發(fā)包需要額外添加源或者直接去官網(wǎng)鏡像站點找那個版本的RPM文件。4.5 CUDA版本與驅(qū)動版本不匹配CUDA運行時對驅(qū)動版本有下限要求比如CUDA 12.2要求驅(qū)動版本530.30.0。驅(qū)動版本太老時運行CUDA程序會報CUDA driver version is insufficient for CUDA runtime version。NVIDIA官方有個CUDA兼容矩陣表格列出每個CUDA版本要求的最低驅(qū)動版本。查這張表再決定是升級驅(qū)動還是降級CUDA不要憑感覺來。我遇到過CUDA庫版本和驅(qū)動版本都滿足要求但運行程序仍報這個錯的情況最后發(fā)現(xiàn)是LD_LIBRARY_PATH里混入了多個CUDA版本的路徑系統(tǒng)優(yōu)先加載了舊CUDA運行庫。用ldd檢查當(dāng)前程序的動態(tài)庫依賴就能發(fā)現(xiàn)ldd /path/to/your_binary | grep libcuda正常應(yīng)顯示libcuda.so.1如果是libcuda.so.530.41.03這類帶完整驅(qū)動版本號的庫文件說明庫路徑混亂了需要調(diào)整LD_LIBRARY_PATH。4.6 顯卡掉卡與PCIe鏈路異常有些雙卡甚至四卡服務(wù)器會遇到某張卡間歇性檢測不到nvidia-smi里卡的數(shù)量時多時少。這個問題在虛擬化環(huán)境下特別常見宿主機的PCIe拓撲隔離不徹底會出現(xiàn)物理服務(wù)器通常沒那么容易掉卡但PCIe插槽接觸不良仍然可能。排查分兩步lspci | grep -i nvidia nvidia-smi -L第一句看系統(tǒng)是否識別了所有卡第二句看驅(qū)動是否管理了所有卡。如果lspci能看到但驅(qū)動管理不到可以用nvidia-smi -r重置這張卡或者用nvidia-smi --gpu-reset強制重置指定GPU。物理接觸不良的情況關(guān)機斷電重新插拔顯卡和供電線才是終極辦法這個問題在密集機架環(huán)境中出現(xiàn)概率不小移動服務(wù)器后經(jīng)常遇到裝了再好的驅(qū)動也解決不了接觸不良。5. 實戰(zhàn)心得與后續(xù)優(yōu)化建議跑了這么多年Linux服務(wù)器裝NVIDIA驅(qū)動像是每個運維都要走過的獨木橋。這里把后續(xù)值得做的事情和最終的體會寫一下給新接觸GPU服務(wù)器的朋友一個落地的收尾。5.1 單卡與多卡環(huán)境的差異單卡服務(wù)器裝驅(qū)動相對簡單多卡環(huán)境在多卡互聯(lián)、中斷路由、PCIe帶寬分配上會有更多需要檢查的點。多卡環(huán)境裝好驅(qū)動后nvidia-smi topo -m可以查看GPU之間的拓撲關(guān)系是NVLink直連還是走PCIe交換。運行深度學(xué)習(xí)任務(wù)時盡量讓通信頻繁的進程跑在同一根PCIe交換機下的GPU組合上延遲會低不少。雙卡環(huán)境還有一個常見問題系統(tǒng)默認的MMIO映射空間不夠兩塊卡共用一個中斷分組會導(dǎo)致性能異常。這種問題一般通過內(nèi)核參數(shù)pcirealloc解決配置到/etc/default/grub的CMDLINE_LINUX里執(zhí)行g(shù)rub2-mkconfig -o /boot/grub2/grub.cfg后重啟生效。5.2 驅(qū)動程序占用的顯存和MIG配置nvidia-smi啟動后每個GPU會預(yù)留一部分顯存給驅(qū)動上下文顯存越大預(yù)留比例越高。初步估算驅(qū)動預(yù)留顯存通常是數(shù)十到兩三百MB的量級對訓(xùn)練任務(wù)只占用個位數(shù)GB顯存的時候影響不明顯但如果是小顯存卡跑模型這個開銷不能忽視。預(yù)留的顯存可以在nvidia-smi輸出里看到分成FB Memory Usage的used項。新一代專業(yè)卡支持MIG多實例GPU可以把一塊物理GPU切成多個獨立分區(qū)每個分區(qū)擁有獨立的顯存和計算單元。配置MIG后面向多租戶場景非常有用但要注意MIG開啟后驅(qū)動必須在root權(quán)限下運行nvidia-smi -mig 1啟用并且CUDA版本要支持MIG特性。跑深度學(xué)習(xí)多任務(wù)分片時這種方式能大幅提升單卡資源利用率。5.3 推薦自動監(jiān)控腳本方案生產(chǎn)環(huán)境建議寫一個簡單的Shell腳本監(jiān)控GPU的功耗、溫度和顯存使用出現(xiàn)異常自動重啟驅(qū)動或記錄日志。分享一個簡化版的監(jiān)控思路#!/bin/bash GPU_TEMP$(nvidia-smi --query-gputemperature.gpu --formatcsv,noheader | awk {sum$1} END {print sum/NR}) if [ $GPU_TEMP -gt 85 ]; then echo $(date) GPU temperature $GPU_TEMP 85, please check cooling /var/log/gpu_monitor.log fi腳本思路很簡單做不做取決于現(xiàn)場環(huán)境。個人建議如果機器放在機房里散熱沒把握或者跑的是長時間訓(xùn)練任務(wù)這類監(jiān)控一定不能省。至少每周看一眼nvidia-smi的功耗和溫度走勢花不了兩分鐘能省掉不少半夜被叫起來處理故障的麻煩。5.4 安裝之后需要養(yǎng)成的習(xí)慣裝機完成不是終點日常維護才是重點。根據(jù)個人經(jīng)驗裝機后會再養(yǎng)成的習(xí)慣包括工具鏈全家桶保持干凈kernel-devel和gcc這些編譯組件不要隨便卸載指不定哪天升級內(nèi)核就要用。安裝驅(qū)動時生成的各種備份文件不要急著刪比如initramfs的bak文件留著占不了多少空間關(guān)鍵時刻能救命。涉及/etc/modprobe.d/和/etc/profile.d/的修改記得寫注釋表明改了什么和原因不然三個月后你再回來看自己寫的配置文件多半會一頭霧水。更重要的一點CentOS 7已經(jīng)在逐步進入維護末期如果新裝機項目還在規(guī)劃階段建議同步評估新版系統(tǒng)的遷移路徑。NVIDIA驅(qū)動在新系統(tǒng)上裝機流程更順因為新版系統(tǒng)自帶的內(nèi)核模塊簽名機制和DKMS管理更成熟不用像CentOS 7里這樣費勁手動管理模塊。但如果短期跑的是存量CentOS 7環(huán)境這套流程穩(wěn)定用幾年是沒問題的。5.5 回歸一下裝驅(qū)動這件事的心態(tài)把驅(qū)動裝上nvidia-smi能打印出來訓(xùn)練能跑起來這只是起步。真正的價值在于通過這次折騰把系統(tǒng)底層、顯卡硬件、內(nèi)核模塊之間的關(guān)系理清楚了后續(xù)再遇到類似問題就不再是黑盒試探而是有思路可循的排查過程。我個人在實際操作中的體會是裝NVIDIA驅(qū)動這件事情最大的敵人不是復(fù)雜的技術(shù)難點而是心急。每一步都驗證過了再往前走比一口氣跑完所有命令要穩(wěn)妥得多。尤其是重啟這個環(huán)節(jié)每次重啟前想清楚要不要備份、要不要改啟動項、確認哪些服務(wù)會受影響這些習(xí)慣能省掉的麻煩遠超你的想象。