
如果你在某個開源社區(qū)或技術(shù)群里搜 OpenRig大概率會得到一堆含混的結(jié)果有人拿它指模擬賽車駕駛艙有人拿它指多顯卡整機架還有人只是隨手給電腦主機起了個名字。我這兒說的 OpenRig是我自己整理的一套多GPU開源工作站方案——用開放式鋁型材支架、普通臺式機部件和一套清一色開源軟件拼出一臺能同時扛住渲染、AI訓(xùn)練、視頻轉(zhuǎn)碼的機器。這臺 Rig 在我桌子下面嗡嗡轉(zhuǎn)了半年多八張卡常年 75 度上下中間只因為一次插拔順序失誤掉過一卡整體穩(wěn)定得讓我意外。之所以把整套東西的搭建過程寫出來是因為我發(fā)現(xiàn)很多人被多卡工作站嚇住了總覺得非得上品牌服務(wù)器或者去找云廠商租實例。實際上只要把幾個關(guān)鍵點想清楚——PCIe通道分配、電源線纜規(guī)劃、散熱風(fēng)道、驅(qū)動版本、遠程調(diào)度——個人完全能自己裝出一臺風(fēng)險可控的多卡設(shè)備。下面就把我從零搭建 OpenRig 的完整經(jīng)歷、選型思路和踩坑記錄攤開聊。1. 為什么我需要一臺 Rig而不是一臺服務(wù)器1.1 單卡工作站被渲染任務(wù)壓垮之后我前半年靠一臺單卡工作站做建筑動畫渲染一張卡跑一幀就要幾分鐘一個鏡頭序列常常掛著幾十個小時。中間只要軟件崩一次、顯存溢出一回前面十幾個小時的計算量全白費心態(tài)崩了好幾次。后來開始接輕量AI推理和批量轉(zhuǎn)碼單卡更是捉襟見肘GPU 占用率長期 100%排隊隊列越拖越長。我看了一圈品牌服務(wù)器雙路至強幾百G內(nèi)存企業(yè)級硬盤背板動不動六位數(shù)的報價。我只需要算力不需要那么豪華的存儲和冗余電源。再一看云GPU實例按小時計價短期用很香長期掛著跑渲染算法成本比想象中高得多。于是自己動手攢一臺多GPU設(shè)備就成了最自然的選擇。OpenRig 說白了就是一臺沒有機箱的多GPU電腦按任務(wù)需求自由加卡壞了哪塊換哪塊不被品牌綁死。1.2 Rig 的本質(zhì)是模塊化不是廉價服務(wù)器很多人問Rig 和服務(wù)器到底差在哪我的理解是服務(wù)器追求的是可靠性、集中管理和可預(yù)測的交付形態(tài)所以它用專用主板、專用固件接口、熱插拔硬盤籠而 Rig 追求的是模塊化的自由度它把整機服務(wù)器拆成可以自由拼裝的零件主板、CPU、內(nèi)存、顯卡、電源、支架各自獨立壞了哪個換哪個。打個比方品牌服務(wù)器像精裝房——省心但每個細節(jié)都是開發(fā)商定的想改格局很費勁Rig 像用宜家家具自己組裝的房間——便宜、靈活、改起來方便但你需要自己懂一點尺寸兼容和承重知識。后面我選開放式鋁型材支架也是這個思路不買成品機箱直接用 4040 鋁型材搭框架長度、層高隨時可以調(diào)整。1.3 一臺典型 OpenRig 長什么樣我的第二版 OpenRig 配置如下表給想抄作業(yè)的人一個參考。核心思路是主板和電源選當(dāng)前能買到的最穩(wěn)妥方案顯卡按需插滿支架和散熱自己搭。部件型號/規(guī)格數(shù)量備注主板X99 二手工作站板或 C621 平臺1看重 PCIe 通道數(shù)至少 7 條 x16CPUXeon 或線程撕裂者入門款1渲染、模擬多線程依賴內(nèi)存DDR4/DDR5 128GB4 條渲染緩存和并行任務(wù)吃內(nèi)存系統(tǒng)盤NVMe SSD 1TB1裝系統(tǒng)和容器鏡像數(shù)據(jù)盤企業(yè)級 SATA/SAS 8TB2素材和渲染輸出顯卡RTX 4070 Ti SUPER 16GB8顯存大、功耗可控電源1600W 鈦金電源2雙電源同步供電支架4040 鋁型材 T型螺母1 套開放式三層結(jié)構(gòu)風(fēng)扇12038 風(fēng)扇8機后統(tǒng)一向外排風(fēng)這套下來峰值功耗大約 2200 瓦到 2500 瓦比一臺同樣規(guī)模的品牌服務(wù)器便宜一半以上而且核心部件全是普通市場件壞了隨手能換。2. 硬件選型從一張卡到八張卡的平衡點2.1 先數(shù) PCIe 通道再下單主板這是整個 OpenRig 最容易翻車的地方。很多人看到一塊板子上有四個 PCIe x16 插槽就以為可以插四張卡實際上決定帶寬的不是插槽數(shù)量而是 CPU 能提供多少條 PCIe 通道。普通家用平臺比如 LGA1700一個 CPU 也就 20 條 PCIe 通道插一張卡正好用滿 x16插兩張卡就有一張只能跑 x8 或者 x4再往上直接就是共享總線多卡通信性能會很難看。我一開始用消費級平臺插三張卡跑分布式推理的時候發(fā)現(xiàn)互聯(lián)帶寬嚴重拖后腿。后來換到工作站平臺選了一顆能拆出 64 條 PCIe 通道的處理器才真正做到 8 張卡全部 x16 直連。選板子的時候別只看插槽數(shù)去官網(wǎng)查 CPU 的 PCIe Lan 數(shù)再數(shù)數(shù)幾個插槽是否由獨立通道引出這是多卡機器的第一道命門。如果不確定可以跑lspci -vvv看每張卡的 Link Speed 和 Widthx8 和 x16 的差距在顯存交換、分布式梯度同步時非常明顯。2.2 CPU、內(nèi)存和系統(tǒng)盤配角不能省既然核心是 GPUCPU 選個夠用的就行不用頂配。但兩個點務(wù)必留意一是內(nèi)存容量二是系統(tǒng)盤剩余空間。我們做 3D 渲染和 AI 訓(xùn)練時很多中間數(shù)據(jù)會先落內(nèi)存顯存不夠就溢到內(nèi)存內(nèi)存不夠系統(tǒng)直接開始換頁整機卡成幻燈片。我這邊 128GB 內(nèi)存是起步機器上跑 4 個容器的時候經(jīng)常吃到 90GB 以上。系統(tǒng)盤建議單獨一塊 1TB NVMe只放系統(tǒng)、驅(qū)動、Docker 鏡像不要混著放素材。因為 CUDA 容器鏡像動輒幾個 GB再加 pip/conda 緩存500GB 很容易就滿了。緩存堵死之后最容易出現(xiàn)的怪問題就是容器啟動特別慢GPU 利用率忽高忽低看 dmesg 全是一堆 io 超時。2.3 電源功率不是簡單相加還得看線纜電源這塊我踩過一個大跟頭。最早用一只 1200W 電源帶 4 張卡按 TDP 算富余得很結(jié)果一跑高負載就重啟。后來才明白顯卡瞬時功耗可以沖到 TDP 的 1.5 倍以上一張 300W 的卡瞬間能拉到 450W如果幾顆核心里多個電壓轉(zhuǎn)換器同時抽風(fēng)電源過流保護立刻觸發(fā)。我現(xiàn)在的計算方式是所有 GPU TDP 總和 CPU TDP 主板/內(nèi)存/風(fēng)扇預(yù)估 150W再乘以 1.3 的瞬時余量系數(shù)。比如 8 張 250W 的卡加一顆 200W CPU算出來大概是 8×250 200 150 2350W乘 1.3 就是 3055W所以兩臺 1600W 電源是必需的。另外一個容易被忽略的點是 PCIe 供電線一條模組線通常只能穩(wěn)定供給一張 300W 級別的顯卡絕對不要用一條線去分接兩張卡。因為 12V 端子電流上限在那擺著分接最容易燒的是端子本身燒完線不一定會立刻斷電但驅(qū)動會莫名其妙報Xid錯誤。2.4 開放式鋁型材支架便宜、好散熱、好改線成品服務(wù)器機箱對顯卡的兼容性和風(fēng)道限制很大。一張顯卡長度 300mm 很正常很多機箱裝進去以后理線空間為零長時間運行積熱嚴重。OpenRig 我直接用 4040 鋁型材搭了一個三層框架底層放電源和硬盤中間放主板最上層給顯卡預(yù)留 2U 高度的散熱空腔。鋁型材配合 T 型螺母和角碼能隨心所欲調(diào)整橫梁位置這是成品機箱完全做不到的。散熱風(fēng)道設(shè)計要點是單一方向把支架進風(fēng)側(cè)朝房間空調(diào)冷氣方向出風(fēng)側(cè)掛一排 12038 風(fēng)扇統(tǒng)一向外排。顯卡在開放式支架里直接暴露溫度反而比悶罐機箱低 8 到 12 度。缺點也不是沒有灰大我在進風(fēng)口貼了一層可清洗的防塵棉每兩周抽出來水沖一次。3. 系統(tǒng)環(huán)境與開源軟件棧速配3.1 Ubuntu Server 與驅(qū)動版本穩(wěn)定大于最新系統(tǒng)我選了 Ubuntu Server 長期支持版原因無非三點NVIDIA 驅(qū)動和 CUDA 對 Ubuntu 的適配最早Docker 原生支持最好遇到問題能搜到大量現(xiàn)成解法。驅(qū)動不要追最新版用官方推薦的和 CUDA 版本配套的穩(wěn)定分支。我的經(jīng)驗是CUDA 12.4 配 550 或 555 驅(qū)動CUDA 12.6 配 560 驅(qū)動基本不會翻車。特別提醒別裝那種一鍵安裝的開源腳本換個內(nèi)核版本后驅(qū)動掛了都不知道去哪找日志。驅(qū)動裝完第一件事不是跑應(yīng)用而是開nvidia-persistenced。這是多卡機器的必備服務(wù)它讓驅(qū)動在無人訪問時也保持初始化狀態(tài)。沒有它偶爾會出現(xiàn)某張卡進入低功耗后下一次任務(wù)提交時找不到設(shè)備的問題。啟動命令很簡單sudo systemctl enable nvidia-persistenced sudo systemctl start nvidia-persistenced之后輸入nvidia-smi如果能看到全部 8 張卡且 Perf 狀態(tài)列不是 P8 而是正常范圍說明驅(qū)動和顯卡通訊沒問題。3.2 Docker Compose 統(tǒng)一跑 CUDA 容器驅(qū)動裝好后我不在宿主機上直接裝 Python 環(huán)境所有任務(wù)都走 Docker。這樣做的好處是環(huán)境隔離A 任務(wù)要 PyTorch 2.1B 任務(wù)要 TensorFlow 2.15C 任務(wù)要 CUDA 11.8三個容器可以共存互不干擾刪掉也就是一條命令的事。我維護了一份 docker-compose 文件每張卡分配獨立容器方便單獨重啟services: gpu-1: image: nvidia/cuda:12.4.1-runtime-ubuntu22.04 runtime: nvidia environment: - NVIDIA_VISIBLE_DEVICES0 - NVIDIA_DRIVER_CAPABILITIEScompute,utility volumes: - /data:/workspace command: sleep infinity restart: unless-stopped這里面的NVIDIA_VISIBLE_DEVICES0就是指定容器只使用物理編號 0 的顯卡。后面接任務(wù)的時候只要確認哪幾張卡空閑就docker exec進對應(yīng)容器跑對應(yīng)進程天然完成最簡單的任務(wù)到卡的綁定。3.3 GPU 監(jiān)控Prometheus 加 exporter 看每一張卡多卡機器最怕的就是某張卡悄悄降頻或者顯存被占滿而人渾然不知。我用 Prometheus node_exporter nvidia_gpu_exporter Grafana 搭了一套最簡單的監(jiān)控面板每 15 秒采集一次數(shù)據(jù)??窗迳嫌兴膫€關(guān)鍵指標GPU 使用率、顯存占用、核心溫度、風(fēng)扇轉(zhuǎn)速。如果某項任務(wù)提交后某張卡顯存一直上不去很可能是顯存分配碎片化或者驅(qū)動把任務(wù)排到了別的設(shè)備上。裝 nvidia_gpu_exporter 不需要編譯官方容器一條命令就能跑起來docker run -d --name nvidia-gpu-exporter --runtimenvidia -p 9400:9400 nvidia/dcgm-exporter:3.3.5-1.0然后在 Prometheus 的scrape_configs里加一個 job 指向這臺機器的 9400 端口即可。手動看當(dāng)前狀態(tài)用nvidia-smi dmon輸出是字符表能看到每張卡每秒鐘的功耗和溫度波動排查問題時比 Grafana 更直接。3.4 無頭管理不接顯示器也能干活多卡機器通常塞在桌子底下或者機房角落沒有顯示器鼠標鍵盤。我的做法是BIOS 里打開通電自啟動 網(wǎng)絡(luò)喚醒機器插電后自己起來我遠程 SSH 進去。需要重啟某個容器就docker restart需要重啟機器就systemctl reboot全程無頭化。有個小坑是主板需要打開Resume On AC Power Loss選項不然斷電后機器不會自動恢復(fù)遠程根本沒法救。另一個建議是裝tailscale或同類內(nèi)網(wǎng)穿透工具這樣人不在同一個局域網(wǎng)也能直接 SSH 回去。我試過在出差路上連回家里的 Rig 提交一批渲染任務(wù)體驗和在公司內(nèi)網(wǎng)差別不大。之后再談安全問題必開防火墻白名單只暴露自己設(shè)備能訪問的端口。4. 多卡調(diào)度與共享存儲把 Rig 變成生產(chǎn)力4.1 先用拓撲命令摸清卡間關(guān)系8 張卡不是說插上就能均勻分配卡間通信效率差距很大。裝好驅(qū)動和 CUDA 后第一步跑nvidia-smi topo -m它會輸出一張矩陣用距離碼標出每張卡和相鄰卡之間的連接方式。比如 NV 表示兩張卡之間有 NVLink帶寬最高PHB 表示一個 PCIe 根控制器下的連接稍慢PIX 表示卡在同一 PCIe Switch 下速度也不錯PXB 表示跨根控制器會吃延遲SYS 則表示走了系統(tǒng)總線速度很慢。我實際跑下來發(fā)現(xiàn)GPU0 和 GPU1 因為同在一個 PCIe Switch 下梯度同步速度快過 GPU4 和 GPU5 不少。分布式訓(xùn)練框架一般會自動選擇最佳通信路徑但自定義任務(wù)里如果手動把數(shù)據(jù)切給多卡一定要參考這張拓撲矩陣規(guī)劃卡組別讓差路徑成為瓶頸。4.2 沒有 Slurm 也能排隊跑任務(wù)有人一聽說多卡調(diào)度就想到 Slurm但單機多卡小團隊真沒必要裝集群調(diào)度維護成本高配置還得學(xué)一堆概念。我目前的方案是一個不到 100 行的腳本它掃描 8 張卡的顯存利用率找到空閑卡后執(zhí)行任務(wù)命令任務(wù)結(jié)束釋放標記然后繼續(xù)掃隊列。核心邏輯類似for job in ${QUEUE[]}; do while true; do gpu_id$(nvidia-smi --query-gpuindex,memory.used --formatcsv,noheader | \ awk -F, $2 512 {print $1; exit}) [ -n $gpu_id ] break sleep 30 done run_job_with_gpu $job $gpu_id done缺點是沒有優(yōu)先級和資源預(yù)留但勝在透明、可控、不引入新系統(tǒng)。如果哪天確實需要排隊、優(yōu)先級、日志回溯都完整的能力可以把這套機子接入 Slurm但那是后話了。小團隊在起步階段先用簡單隊列把卡用滿比先上重型系統(tǒng)實在得多。4.3 數(shù)據(jù)同步素材本地放一份輸出集中收OpenRig 上跑的大任務(wù)素材動輒幾百 GB。我最初犯的錯是讓所有機器直接遠程掛載 NAS 上的素材局域網(wǎng)千兆跑 4K 序列I/O 等待直接拉垮 CPU?,F(xiàn)在的策略是每臺 Rig 都會在本地數(shù)據(jù)盤保留一份常用素材副本通過 rsync 增量同步渲染輸出統(tǒng)一寫到一臺存儲服務(wù)器跑完一批就同步過去。另外給容器內(nèi)的/tmp和緩存目錄掛載到內(nèi)存盤會有奇效。比如把渲染臨時緩存放到/dev/shm速度比 SSD 快一個數(shù)量級。需要注意內(nèi)存盤容量是內(nèi)存的一半別掛太大目錄小心 OOM。我把一個 32GB 內(nèi)存的節(jié)點單獨留出 8GB 給臨時文件視頻轉(zhuǎn)碼速度肉眼可見提升。5. 實測中的坑掉卡、過熱和掉電5.1 顯卡從系統(tǒng)里消失的完整排查鏈路多卡機器用得越久越可能遇見任務(wù)跑到一半報CUDA error: an illegal memory access再一看nvidia-smi原來 8 張卡只剩 7 張掉的那張徹底不見了。這種問題第一反應(yīng)別盲目重啟按順序查dmesg | tail -100看有沒有 NVRM、Xid、PCIe 相關(guān)的錯誤行l(wèi)spci | grep -i nvidia確認 PCIe 總線上還能不能識別到這張卡斷電把這張卡拔下來檢查金手指和 PCIe 槽位是否有污垢和氧化痕跡換一個 PCIe 槽位重新插入開機能識別再去跑壓力測試我遇到過最典型的情況是機箱共振導(dǎo)致顯卡輕微松動插槽觸點虛接。重新插拔后頂住卡尾部問題消失。另外注意插拔順序一定要先斷電等電源指示燈完全熄滅再動硬件否則帶電插拔極大概率燒板卡。5.2 風(fēng)扇策略別讓顯卡被動降頻開放式支架雖然散熱比機箱好但核心溫度和顯存溫度是兩回事。有些顯卡風(fēng)扇默認策略在開放環(huán)境下并不激進核心 60 度時風(fēng)扇還是低速顯存卻已經(jīng) 90 度。我跑了半年后給一套監(jiān)控腳本加了溫度巡檢每 30 秒檢查一次任意一張卡顯存溫度超過 92 度就調(diào)高整排風(fēng)扇轉(zhuǎn)速。用 nvidia-smi 直接鎖功耗墻也可行比如把每張卡功耗限制在 TDP 的 70%跑推理和轉(zhuǎn)碼這類我認為不太敏感的負載性能損失很小溫度卻能壓到 65 度左右nvidia-smi -pm 1 nvidia-smi -pl 210有一點要特別注意不同驅(qū)動版本下-pl支持的范圍不一樣鎖定前先用nvidia-smi -q -d POWER查看當(dāng)前和最大功率上限。如果鎖過頭任務(wù)因為供電不足反而更慢那就得不償失了。5.3 供電和噪音住宅環(huán)境的隱形天花板機器跑到滿載時我用功率計實測整機功耗大約 2300W這意味著普通五孔插座很容易過載。一個 10A 的插座規(guī)格也才 2200W 左右長時滿載一定會跳閘。我給 Rig 單獨走了 16A 的空調(diào)豎線而且一個回路只接這一臺設(shè)備斷路器在測試中承受住了滿載 2 小時不發(fā)熱。噪音則是另一道坎。8 張卡滿載加排風(fēng)扇聲音大約在 60 到 70dB基本是正常談話聲水平偏上。我自己后來把機器放到一個通風(fēng)良好但離辦公區(qū)較遠的角落人耳感受好很多。如果你住公寓建議要么鎖功耗墻降噪要么給支架三面貼隔音棉要有防火等級否則晚上渲染任務(wù)開著你根本睡不著覺。6. 再往后OpenRig 的模塊化進化方向6.1 從手工搭建到配置即代碼第一次搭 OpenRig 我純靠手記筆記后來重裝系統(tǒng)才發(fā)現(xiàn)一堆細節(jié)沒記錄BIOS 里開了哪些選項、驅(qū)動用的哪個版本、Docker daemon 改了什么參數(shù)、crontab 里定時同步腳本怎么寫的?,F(xiàn)在我把這些都收進了 Ansible playbook 里裝完系統(tǒng)一條命令拉起來就是一套可復(fù)現(xiàn)環(huán)境。好處是以后哪塊硬件壞了重裝時間從一整天縮到半小時。這套方法我也推薦給想抄作業(yè)的人比截圖備忘和聊天記錄可靠得多。核心是把以下幾件事寫成代碼維護驅(qū)動安裝、nvidia-persistenced 服務(wù)、Docker 和 compose 工程、監(jiān)控 exporter、同步腳本、SSH 密鑰。6.2 雙電源同步的正確打開方式8 卡 Rig 基本繞不開雙電源。最穩(wěn)妥的做法是買一個雙電源同步轉(zhuǎn)接板或者帶有雙 ATX 啟動同步功能的主板讓兩顆電源在開機的瞬間同時上電。別用那種簡單并聯(lián) 12V 的改裝線電流分配不均燒電源的風(fēng)險極高。我的接法電源 A 給主板、CPU、系統(tǒng)盤、4 張顯卡供電電源 B 給另外 4 張顯卡供電。這樣兩邊的負載相對均衡如果一個電源掛了至少系統(tǒng)盤不直接斷電有機會安全關(guān)機。注意電源 A 的風(fēng)扇信號線不能省否則主板會誤認為 CPU 風(fēng)扇故障而不給啟動。6.3 讓 Rig 變成團隊共享資源OpenRig 的優(yōu)勢是便宜、可拆、擴展靈活缺點是管理界面粗糙。如果想讓團隊其他人也能用我給容器加了一個簡單的 token 驗證并向局域網(wǎng)開放了 SSH 端口和渲染端口的訪問權(quán)限。安全起見綁定端口只監(jiān)聽到內(nèi)網(wǎng)地址再用防火墻限制來源 IP。我后來把任務(wù)隊列腳本和監(jiān)控面板暴露在一個簡單的 Web 頁面上組員們打開頁面就能看到當(dāng)前哪張卡空閑、哪個任務(wù)在跑點一下就可以提交新任務(wù)。這個頁面的技術(shù)含量很低就是一個 Python Flask 服務(wù)加一套回調(diào)腳本但實用度確實高。今后如果再買一臺新 Rig只要把它接入同樣的軟件棧整個團隊算力就從一臺機器變成了一組可編排的GPU節(jié)點OpenRig 才真正算得上開源可復(fù)制。最后再分享一個我的個人體會多卡 Rig 說白了就是個體力活加細心活硬件本身并不神秘真正決定成敗的是通道規(guī)劃、供電余量和散熱風(fēng)道這三件事。第一次組裝時多花點時間畫清楚接線圖后面少折騰一百回。如果哪天你的 OpenRig 突然掉卡了別急著滿世界找驅(qū)動先斷電把那張卡從槽里拔出來重新插緊大概率它又活蹦亂跳了。