NVIDIA Jetson AGX Thor 從開箱到可交付:效能、環境、網路的完整設定與驗收流程。適用 L4T R39 Rev 2.0(JetPack 7.2)。文件版本 v2.2(對外正名版),2026年10月1日,云碩科技股份有限公司。
這份指南寫給第一次接手MIC-743設備的工程師。目標是把一台剛開箱、或剛重新燒錄完BSP的MIC-743,設定到可以交付的狀態。
每一章都是「為什麼要做、怎麼做、怎麼驗證」三段。所有指令都在節點A與節點B兩台實機、以及L3網管交換機上實際執行並驗證過,不是照抄官方文件。第十一章的踩坑紀錄每一條都是真的踩過才寫進來的,建議先掃一遍再動手。
設定順序有相依性,請由第三章往後依序執行。
| 項目 | 數值 |
|---|---|
| 10G單流吞吐量 | 7.48 Gbits/sec |
| 10G四流吞吐量 | 8.92 Gbits/sec |
| 32條並行連線 | 7.30 Gbits/sec |
| 小封包(512 bytes) | 3.41 Gbits/sec |
| 延遲 | 0.69 ms |
| 滿載時CPU閒置率 | 92% |
本文件不載入任何實際網路位址。指令中以角括號標示的欄位,請依貴單位的網路規劃填入:
| 佔位符 | 填什麼 |
|---|---|
<主機名> | 這台機器要用的主機名,只能用英文字母、數字與連字號 |
<廠區網段> | 機器所屬的網段(含遮罩) |
<本機主要位址> | 本機10G介面的位址 |
<本機備援位址> | 本機1G管理介面的位址 |
<閘道位址> | 該網段的預設閘道 |
<遮罩> | 子網路遮罩位元數 |
<對外測試位址> | 對外連通性測試用的任一公開位址 |
<直連網段> | 兩台機器直連專用的獨立網段 |
<甲機直連位址>、<乙機直連位址> | 直連兩端各自的位址 |
<對端位址> | 測試時的另一端位址 |
127.0.0.1、127.0.1.1、0.0.0.0為指令的固定字面值,不是場域資訊,照抄即可。
文中的「節點A」「節點B」是兩台機器的稱呼,不是主機名,指令中不可直接使用。
從零到可交付共七個階段。每個階段都要驗證通過再進下一個。
| 階段 | 項目 | 為什麼要做 | 需重開機 |
|---|---|---|---|
| 1 | 主機名與時區 | 多台同名無法辨識;UTC時間讓log判讀困難 | 否 |
| 2 | 電源模式MAXN | 出廠預設是120W,GPU被限制在1386 MHz | 否 |
| 3 | 鎖定時脈 | MAXN只放開上限,實際頻率仍會浮動 | 否 |
| 4 | CUDA與Docker | 開發與部署的基礎環境 | 否 |
| 5 | 交換機拆分設定 | 10G埠預設是單一100G,與MIC-743談不攏 | 否 |
| 6 | MIC-743網路設定 | 10G埠預設不會自己啟用 | 否 |
| 7 | 驗收檢查 | 確認前六項都生效且能跨重開機 | 是 |
MIC-743出廠的主機名一律是ubuntu。同時管理兩台以上時,SSH進去完全分不出是哪一台,這在遠端操作時很容易改錯機器。請依貴單位的命名規則取名,只能用英文字母、數字與連字號,系統不接受中文主機名。
sudo hostnamectl set-hostname <主機名> sudo sed -i "s/\bubuntu\b/<主機名>/g" /etc/hosts
第二行不能省。只改hostnamectl而沒有同步 /etc/hosts的話,127.0.1.1仍指向舊名稱,部分程式在解析自己的主機名時會逾時。
驗證:
hostnamectl --static grep 127 /etc/hosts
出廠預設是Etc/UTC。台灣現場使用時,所有log、journalctl、訓練進度的時間戳都要自己加八小時,很容易看錯。
sudo timedatectl set-timezone Asia/Taipei
驗證應顯示Asia/Taipei (CST, +0800):
timedatectl | grep -E "Local time|Time zone"
MIC-743的nvpmodel有四個模式。出廠預設是ID 1(120W),不是最高效能:
| 模式ID | 名稱 | GPU上限 | NVDEC上限 | CPU上限 |
|---|---|---|---|---|
| 0 | MAXN | 1575 MHz | 1692 MHz | 2601 MHz |
| 1 | 120W(出廠預設) | 1386 MHz | 1557 MHz | 2601 MHz |
| 2 | 90W | 較低 | 較低 | 較低 |
| 3 | 70W | 最低 | 最低 | 最低 |
CPU上限在MAXN與120W之間沒有差別,差的是GPU與影像解碼單元,120W模式的GPU上限比MAXN低約12%。跑推論或影像管線時這個差距會直接反映在吞吐量上。
這是最容易做半套的地方。nvpmodel -m 0只寫入執行期狀態檔/var/lib/nvpmodel/status,開機時由nvpmodel.service讀取。但如果那支檔被清除、或系統做過還原,就會退回設定檔裡的PM_CONFIG DEFAULT,而出廠值是1。
sudo nvpmodel -m 0 sudo cp -a /etc/nvpmodel/nvpmodel_p3834_0008.conf /etc/nvpmodel/nvpmodel_p3834_0008.conf.bak sudo sed -i "s/^< PM_CONFIG DEFAULT=1 >/< PM_CONFIG DEFAULT=0 >/" /etc/nvpmodel/nvpmodel_p3834_0008.conf
設定檔名稱依板型而異,MIC-743採用的Jetson AGX Thor模組為nvpmodel_p3834_0008.conf,實際檔名可用readlink -f /etc/nvpmodel.conf確認。
nvpmodel -q cat /var/lib/nvpmodel/status grep "^< PM_CONFIG" /etc/nvpmodel/nvpmodel_p3834_0008.conf
三者應分別顯示MAXN / pmode:0000 / DEFAULT=0。
nvpmodel決定的是頻率上限。實際運作時CPU governor仍是schedutil,會依負載動態調頻,GPU也會在閒置時降頻。做效能量測、或需要穩定延遲的即時應用時,這種浮動會造成數據不可重現。
jetson_clocks的作用是把CPU、GPU、EMC的最小頻率拉到等於最大頻率,等於鎖死在上限。
jetson_clocks必須在nvpmodel之後執行。順序顛倒的話會鎖到舊模式的上限,得到一台「顯示MAXN但實際跑120W頻率」的機器,而且很難察覺。
jetson_clocks不會自己記得原本的值。要能還原,必須在第一次鎖頻之前先存檔:
sudo jetson_clocks --store /etc/l4t_dfs.conf
這一步只能做一次。已經鎖頻後再執行,存下來的就是鎖頻後的狀態,還原功能等於失效。
jetson_clocks的效果不會跨重開機,必須做成systemd服務。建立/etc/systemd/system/jetson-clocks.service:
[Unit] Description=Lock Jetson clocks to max frequency (jetson_clocks) After=nvpmodel.service Wants=nvpmodel.service [Service] Type=oneshot RemainAfterExit=yes ExecStartPre=/bin/sleep 20 ExecStart=/usr/bin/jetson_clocks ExecStop=/usr/bin/jetson_clocks --restore /etc/l4t_dfs.conf [Install] WantedBy=multi-user.target
三個欄位的用意:
After=nvpmodel.service保證排序正確,這是5.2節的要求。
ExecStartPre=/bin/sleep 20是緩衝。nvpmodel是oneshot服務,systemd認定它完成之後,SoC端仍需要數秒才會穩定套用新的電源模式。沒有這段等待時,偶發會鎖到過渡狀態的頻率。
RemainAfterExit=yes讓oneshot服務執行完仍保持active狀態,這樣systemctl stop才會觸發ExecStop的還原動作。
啟用:
sudo systemctl daemon-reload sudo systemctl enable jetson-clocks.service sudo jetson_clocks
鎖定成功的判準是MinFreq等於MaxFreq:
sudo jetson_clocks --show | grep -E "^cpu0:|gpu-gpc-0|^EMC" cpu0: MinFreq=2601000 MaxFreq=2601000 gpu-gpc-0 MinFreq=1575000000 MaxFreq=1575000000 EMC MinFreq=4266000000 MaxFreq=4266000000
GPU若停在1386000000,代表nvpmodel沒生效或順序錯了,回頭檢查第四章。
鎖頻後系統會持續維持高頻,待機功耗與發熱都明顯上升。MIC-743的風扇由nvfancontrol服務以close_loop模式自動調節,預設cool曲線,正常散熱環境下不需人工介入。但機殼進出風口必須淨空,且應定期確認溫度:
paste <(cat /sys/class/thermal/thermal_zone*/type) <(cat /sys/class/thermal/thermal_zone*/temp)
數值單位為千分之一度,48250即48.25度。閒置時約45至50度屬正常。
要暫時解除鎖頻:sudo systemctl stop jetson-clocks.service
這是本次最大的軟體坑。直覺會執行sudo apt install nvidia-jetpack,但在R39 Rev 2.0上會直接失敗:
The following packages have unmet dependencies: nvidia-l4t-kernel-openrm : Depends: nvidia-l4t-init-openrm but it is not going to be installed nvidia-l4t-kernel-partitions : Depends: nvidia-l4t-bootloader-utils but it is not going to be installed
原因是nvidia-jetpack這個meta套件會連kernel與bootloader套件一起拉,與已經燒錄在裝置上的BSP版本衝突。
正確做法是只裝需要的CUDA工具鏈:
sudo apt update sudo apt install -y cuda-toolkit-13-2
BSP本身已內含GPU驅動與L4T執行期(約59個nvidia套件),缺的只有開發工具鏈。
nvcc預設不在PATH中,建立/etc/profile.d/cuda.sh:
export PATH=/usr/local/cuda/bin:$PATH export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH
Ubuntu內建的docker.io版本較舊,且與NVIDIA Container Toolkit的搭配較不穩定。使用Docker官方apt來源:
sudo apt install -y ca-certificates curl sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc sudo chmod a+r /etc/apt/keyrings/docker.asc echo "deb [arch=arm64 signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu noble stable" | sudo tee /etc/apt/sources.list.d/docker.list sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
注意arch=arm64。MIC-743是aarch64架構,寫成amd64會找不到套件。
沒有這一步,容器內看不到GPU。
sudo apt install -y nvidia-container-toolkit sudo nvidia-ctk runtime configure --runtime=docker sudo systemctl restart docker sudo usermod -aG docker $USER
加入docker群組需要重新登入才會生效。
docker info | grep -iE "Runtimes|Default Runtime"
Runtimes那一行必須看到nvidia,否則容器拿不到GPU。
MIC-743的QSFP連接器不是一個40G或100G埠,而是四條各自獨立的10GbE。這寫死在device tree裡:
ethernet@a808a10000 if-name=mgbe0_0 instance=0 uphy-gbe-mode=1 fixed-link speed=10000 ethernet@a808b10000 if-name=mgbe1_0 instance=1 uphy-gbe-mode=1 fixed-link speed=10000 ethernet@a808d10000 if-name=mgbe2_0 instance=2 uphy-gbe-mode=1 fixed-link speed=10000 ethernet@a808e10000 if-name=mgbe3_0 instance=3 uphy-gbe-mode=1 fixed-link speed=10000
四個介面的MAC位址是連號的(例如aa:bb:cc:dd:ee:01到04),代表它們共用同一顆實體連接器的四條lane。
MIC-743沒有40G或100G模式可選,也不能靠軟體改。因此對端交換機埠必須拆分成4×10G,否則一邊講100G、一邊講4×10G,模組讀得到但協商不出可用速率,兩端都會顯示Down。
show interface Ethernet1/49 capabilities
必須看到這兩行:
Speed: 1000,10000,25000,40000,50000,100000 Breakout capable: yes
速率清單裡要有10000。另外注意Port Group Members這一欄,如果同一組內有多個埠,拆分時可能會互相影響。
configure terminal interface breakout module 1 port 49-50 map 10g-4x end copy running-config startup-config
這是全域組態指令,不是進到interface底下打的,這點很常搞錯。
套用後埠會變成Eth1/49/1到Eth1/49/4、Eth1/50/1到Eth1/50/4,共八個10G子介面。原本Eth1/49、Eth1/50上的設定會被移除,必須重新套用到子介面上:
configure terminal interface Ethernet1/49/1-4, Ethernet1/50/1-4 switchport no shutdown end copy running-config startup-config
新建的子介面預設是shutdown且為routed模式,不下這段的話八個埠會停在disabled。
show interface status | include 1/49|1/50 show running-config | include breakout
八個子介面應全部顯示connected / full / 10G。
要還原拆分:no interface breakout module 1 port 49-50 map 10g-4x
MIC-743端每條lane跑10G NRZ。線材必須能承載四條NRZ lane。
| 線材 | 可用 | 說明 |
|---|---|---|
| 40G QSFP+ 被動DAC | 可 | 4 lane × 10G NRZ,規格完全吻合 |
| 100G QSFP28被動DAC | 可 | 4 lane × 25G NRZ,降速跑10G在電氣上沒問題 |
| 200G QSFP112 DAC | 不可 | 4 lane × 50G PAM4,調變方式不同,無法降到NRZ |
本次實際使用並驗證可行的是ONTi的ONT-DAC-QS28-1(1公尺QSFP28被動銅纜),交換機讀到的EEPROM型號為QSFP100G-4SFP25G-CU1M。
第三方模組在多數交換機上預設會被擋,必要時開放:
configure terminal service unsupported-transceiver
L3網管交換機的Eth1/1-48是10GBASE-T(RJ45銅線),不是SFP+。
show module Mod Ports Module-Type Model 1 54 48x10GT + 6x40G/100G Ethernet Module <交換機型號>
48x10GT的T代表twisted copper。這表示無法使用「QSFP轉4×SFP+ 破線接到前48埠」這種常見做法,10G光纖只能走Eth1/49-54那六個QSFP埠。採購線材前務必先用show module確認介質型別。
| 介面 | 速度 | 角色 | 預設狀態 |
|---|---|---|---|
| enP2p1s0 | 1 GbE | 管理備援 | 已設定,可用 |
| mgbe0_0至mgbe3_0 | 10 GbE | 對外主要 | 未啟用 |
四個10G埠在device tree中被宣告為fixed-link,這帶來三個必須理解的限制:
第一,沒有PHY,也沒有SFP管理框架。ethtool -m mgbe0_0會回Operation not supported,代表核心到光模組之間沒有I2C通道。系統看不到模組型號、看不到收光功率,也無法判斷模組是否插著。排查實體問題時軟體端幫不上忙,只能靠交換機端。交換機的show interface transceiver details可以補上這塊盲區。
第二,不做自動協商。ethtool顯示的Auto-negotiation: on在fixed-link模式下沒有實際意義,因為沒有PHY可以協商。
第三,ethtool顯示的Speed: 10000Mb/s是device tree寫死的值,不是協商結果。看到10000不代表線路已通,要看Link detected。
接手既有設備時務必先檢查這支檔:
cat /etc/NetworkManager/conf.d/99-unmanage-mgbe.conf
本次在節點A上發現此檔存在,內容將三個10G埠標為NetworkManager不管理:
[keyfile] unmanaged-devices=interface-name:mgbe0_0;interface-name:mgbe2_0;interface-name:mgbe3_0
被列入的介面開機後連admin up都不會做,nmcli顯示unmanaged,且任何連線設定都無法套用,錯誤訊息也完全不會提到這支檔。要使用該埠必須先將它移出清單或整支刪除。
10G埠未接上線材時NetworkManager會判定為unavailable,不會套用IP設定。建立/etc/NetworkManager/conf.d/10-mgbe-ignore-carrier.conf:
[device-mgbe] match-device=interface-name:mgbe* ignore-carrier=yes
這樣IP會先掛上,線路一通即可使用,不必再登入機器操作。
10G承載對外主要位址,1G降為管理備援。兩者都在同一個VLAN 1與同一個<廠區網段>。
| 介面 | IP | 閘道 | route-metric | |
|---|---|---|---|---|
| 對外主要 | mgbe0_0(10G) | <本機主要位址> | <閘道位址> | 100 |
| 管理備援 | enP2p1s0(1G) | <本機備援位址> | <閘道位址> | 700 |
兩張網卡都設預設路由,靠metric決定優先序。 正常情況全部走10G;10G斷線時該路由自動消失,1G的metric 700立刻接手,機器不會失聯也不需人工介入。此行為已實測驗證。
要留意的取捨是:10G斷線時<本機主要位址>這個位址會整個消失,因為它只存在於10G網卡上。機器本身靠1G保持連線,但任何以該位址定址的服務會中斷,需改連管理位址。
sudo nmcli con add type ethernet ifname mgbe0_0 con-name mgbe0_0-10g \ ipv4.method manual \ ipv4.addresses <本機主要位址>/<遮罩> \ ipv4.gateway <閘道位址> \ ipv4.dns <對外測試位址> \ ipv4.route-metric 100 \ ipv4.dad-timeout 0 \ ipv6.method disabled \ connection.autoconnect yes sudo nmcli con mod "Wired connection 1" \ ipv4.addresses <本機備援位址>/<遮罩> \ ipv4.gateway <閘道位址> \ ipv4.route-metric 700
ipv6.method disabled是刻意的。資料傳輸埠只走IPv4,關閉IPv6可避免介面掛上不必要的link-local位址,也減少介面up時多餘的鄰居探詢封包干擾排查判讀。
必須先讓1G放掉對外位址,10G才拿得到。 順序顛倒會失敗:
Error: Connection activation failed: IP configuration could not be reserved
原因是NetworkManager的位址衝突偵測(ACD)會發現該位址仍在同一台機器的另一張網卡上。正確順序是:
nmcli con up "Wired connection 1"讓1G換到管理位址,釋放對外位址nmcli con up mgbe0_0-10g讓10G接手另外在10G的profile上設ipv4.dad-timeout 0關閉ACD探測,可避免殘留的ARP快取造成誤判。
強烈建議把整套動作寫成腳本,用setsid nohup脫離SSH執行,並內建回滾:套用後自動ping閘道驗證,若干秒內驗不過就自動還原。搬移IP的瞬間必然斷線,沒有回滾機制的話一旦出錯就要進機房接螢幕。本次第一輪就是靠這個機制自動還原,全程沒有失聯。
這一節很重要,因為預設的測試方式會給出假的成功結果。
當10G埠與1G埠在同一網段時,即使10G完全沒有連線,從外部ping 10G的IP仍然會有回應,因為Linux預設會用任何一張可用介面回應本機所有IP。
| 測試方式 | 是否可信 | 說明 |
|---|---|---|
ping <10G的IP> | 不可信 | 由1G埠代為回應 |
ping -I <10G的IP> <目標> | 不可信 | 綁的是IP,核心仍會改走1G |
ping -I mgbe0_0 <目標> | 可信 | 綁實體介面,強制由10G送出 |
檢查rx_packets增量 | 最可信 | 硬體計數器不會說謊 |
判斷連線狀態的唯一可靠依據:
cat /sys/class/net/mgbe0_0/carrier ethtool -S mgbe0_0 | grep link_connect_count
carrier回1代表實體層已連線。link_connect_count是硬體計數器,只要曾經link up過一次就會累加,數值為0表示從未連線成功。
同網段測試的陷阱:兩台機器互相ping時,回程封包會依route metric選擇介面,可能從1G回來,而ping -I綁定的socket不會接受從其他介面進來的封包,導致明明線路正常卻顯示100%逾時。做效能或連通性驗證時,建議在10G上另外加一個獨立網段(例如<直連網段>)避開這個干擾。
10G無法連線時,依此順序排查:
第一步,確認NetworkManager沒有停用該介面(8.3節)。
第二步,在交換機上執行show interface status,區分兩種Reason:XCVR not inserted是沒插線材,Link not connected是插了、讀得到、但協商不起來。後者代表實體存在無虞,問題在設定或規格。
第三步,確認交換機埠已拆分為4×10G(第七章)。這是最常見的原因。
第四步,用show interface EthX/Y transceiver details確認線材規格,特別是PAM4的200G線材無法用於10G。
第五步,將兩台MIC-743以一條線直接對接。連線成功代表MIC-743與線材都正常,問題在交換機端;仍失敗則問題在模組或線材。這個測試能一次把範圍縮小一半,不需要交換機的管理權限。
四個10G埠的MTU預設是 1466,不是標準的1500。開機訊息說明了原因:
nvethernet a808a10000.ethernet: Macsec: Reduced MTU: 1466 Max: 9000
MACsec(IEEE 802.1AE鏈路層加密)在這些埠上是啟用的。它會在每個frame插入SecTAG與ICV完整性檢查碼,驅動為此保留34 bytes。硬體與device tree的nvidia,max-platform-mtu都是9000,但MACsec一開就被壓到1466。
MACsec保護的是「一條實體線路上兩個相鄰設備之間」的通訊,防的是有人在實體層接分光器或竊聽線路。它是逐跳加密而非端到端,封包進到交換機裡仍是明文,因此與TLS、VPN解決的是不同層次的問題。
典型使用場合是線路經過無法控制的實體空間:機房對機房的租用光纖、跨棟跨樓層的園區網路、電信商基地台回傳、金融專線。
MACsec引擎來自Jetson AGX Thor模組的車用平台定位。 車內ECU之間走Automotive Ethernet,攻擊情境是有人拆開門板接進線束、注入假的感測器資料或控制指令,ISO/SAE 21434這類車輛資安規範會要求車內網路做鏈路層加密。把車用晶片用於機房邊緣運算時,就繼承了這個為汽車設計的預設值。
實測確認兩台機器都沒有任何MACsec工作階段:
ip macsec show → 沒有任何 MACsec 介面 NM 連線類型 → 802-3-ethernet(不是 macsec) /etc/wpa_supplicant.conf → 沒有任何 macsec 設定
系統上執行中的wpa_supplicant是Ubuntu預設實例,沒有帶MKA金鑰協商設定。
另外,交換機端也不支援:
show interface Ethernet1/49 capabilities MACSEC capable: no
因此驅動保留了34 bytes,給一個從未建立過工作階段、且對端也不支援的功能。
實測結果比預期溫和,不必急著處理。
| 情境 | 實際影響 | 嚴重度 |
|---|---|---|
| 容器內TCP | PMTUD自動學習,路由快取記錄mtu 1466,代價是首次一個RTT(0.6 ms) | 可忽略 |
| LLM推論、RAG查詢 | 封包遠小於1466,完全碰不到上限 | 無影響 |
| 多人連線 | MTU與連線數無關 | 無影響 |
| 大檔傳輸吞吐量 | 標頭佔比多約2.3% | 可忽略 |
| UDP超過1438 bytes | 靜默丟棄,不會自癒 | 潛在風險 |
| 跨越會過濾ICMP的設備 | PMTUD黑洞,小封包通、大檔卡死 | 潛在風險 |
實測數據:容器(docker0為1500)對外送1500 bytes DF封包會被丟,但核心回的ICMP讓容器立即把PMTU學成1466,路由快取顯示cache expires 596sec mtu 1466。因為ICMP在同一台機器內部產生不會被過濾,此自癒機制可靠。
結論:改動的理由不是效能,而是消除未來的地雷。 非標準MTU會在加入UDP服務、流量跨越防火牆、或他人接手時炸出極難查的問題。不建議為此單獨安排停機,排到下次因其他原因重開機時順手處理即可。
編輯/boot/extlinux/extlinux.conf,在APPEND行尾加入參數:
sudo cp -a /boot/extlinux/extlinux.conf /boot/extlinux/extlinux.conf.bak sudo sed -i '/^ *APPEND .*root=PARTUUID/ s/$/ nvethernet.macsec_enable=0/' /boot/extlinux/extlinux.conf
重新開機後生效。這只是加一個模組參數而非更換核心,即使參數無效核心也只會忽略,不影響開機。
驗證四項:
cat /proc/cmdline | tr " " "\n" | grep nvethernet # 應顯示 macsec_enable=0 cat /sys/module/nvethernet/parameters/macsec_enable # 應為 N journalctl -k -b | grep -i macsec # Reduced MTU 訊息應消失 cat /sys/class/net/mgbe0_0/mtu # 應為 1500
實測結果:MTU自動從1466變為標準1500,服務與既有10G鏈路完全不受影響。
關閉MACsec後MTU上限解到9000。實測可設定範圍:
| 設定值 | 結果 |
|---|---|
| 1500 | 成功 |
| 4000 | 成功 |
| 9000 | 成功 |
| 9216 | 被拒(超過硬體上限) |
MIC-743的硬體上限是9000,不是交換機慣用的9216。 交換機端設9216沒問題(那是上限值),MIC-743端只能設9000。
要啟用jumbo frame必須全鏈路一致:MIC-743兩端設9000、交換機設system jumbomtu 9216並在八個子介面設mtu 9216、Docker設9000。漏掉任何一環都會出現「小封包通、大檔卡住」的症狀,而且極難診斷。
主機對外介面是1466但docker0與自訂bridge預設是1500。雖然TCP會自行學習,仍建議在/etc/docker/daemon.json明確設定:
{ "mtu": 1466 }既有的自訂bridge網路需重建才會套用新值。
重新開機後逐項執行。全部通過才算完成設定。
| 編號 | 檢查項目 | 指令 | 預期結果 |
|---|---|---|---|
| 1 | 主機名 | hostnamectl --static | 非ubuntu,且各台不同 |
| 2 | 時區 | timedatectl | grep "Time zone" | Asia/Taipei (CST, +0800) |
| 3 | 電源模式 | nvpmodel -q | MAXN |
| 4 | 模式持久化 | cat /var/lib/nvpmodel/status | pmode:0000 |
| 5 | 設定檔預設值 | grep "^< PM_CONFIG" /etc/nvpmodel/nvpmodel_p3834_0008.conf | DEFAULT=0 |
| 6 | 鎖頻服務 | systemctl is-enabled jetson-clocks | enabled |
| 7 | CPU鎖頻 | jetson_clocks --show | grep ^cpu0: | MinFreq 等於 MaxFreq(2601000) |
| 8 | GPU鎖頻 | jetson_clocks --show | grep gpu-gpc-0 | MinFreq 等於 MaxFreq(1575000000) |
| 9 | 還原檔存在 | ls -l /etc/l4t_dfs.conf | 檔案存在 |
| 10 | CUDA | /usr/local/cuda/bin/nvcc --version | 顯示13.2 |
| 11 | Docker | docker --version | 29.7.2或更新 |
| 12 | GPU容器支援 | docker info | grep Runtimes | Runtimes 含 nvidia |
| 13 | 交換機拆分 | show interface status | include 1/49 | 八個子介面 connected / full / 10G |
| 14 | 10G實體連線 | cat /sys/class/net/mgbe0_0/carrier | 1 |
| 15 | 10G曾連線 | ethtool -S mgbe0_0 | grep link_connect_count | 大於 0 |
| 16 | 對外IP在10G上 | ip -4 -br addr show mgbe0_0 | 顯示對外位址 |
| 17 | 管理IP在1G上 | ip -4 -br addr show enP2p1s0 | 顯示管理位址 |
| 18 | 路由優先序 | ip route | grep ^default | 兩筆:mgbe0_0 metric 100、enP2p1s0 metric 700 |
| 19 | 對外走10G | ip route get <對外測試位址> | dev mgbe0_0 |
| 20 | 故障切換 | 關閉10G後測對外連線 | 自動改走enP2p1s0 |
| 21 | 吞吐量 | iperf3 -c <對端> -P 4 | 約8.9 Gbits/sec |
| 22 | 溫度 | 見5.6節 | 閒置時低於60度 |
第18項要特別留意。若出現兩筆metric相同的預設路由,代表設定有誤,重開機後可能無法預期地選錯介面。
以下每一項都是本次實際遇到並排除的問題。
nvpmodel -m 0做半套。 只改執行期狀態而未改設定檔預設值,狀態檔一旦遺失就退回120W,而且外觀上完全看不出來。兩個地方都要改。jetson_clocks在nvpmodel之前執行。 會鎖到舊模式的上限,得到「顯示MAXN但實際跑較低頻率」的機器。systemd服務必須加After=nvpmodel.service。--store就鎖頻。 原始設定就此遺失,--restore還原不回動態調頻,只能重新開機。nvidia-jetpack整包。 在R39 Rev 2.0上必定失敗於kernel與bootloader套件的相依性衝突。只裝cuda-toolkit-13-2。arch=arm64。ping得通就是10G通了。 同網段下1G埠會代為回應。務必用ping -I <介面名>並檢查rx_packets增量。ping -I <10G的IP>逾時就是線路不通。 回程封包依route metric走了1G,而綁定介面的socket不接受它,造成線路正常卻顯示100%逾時。應改用獨立網段測試,或直接看硬體計數器。99-unmanage-mgbe.conf。 介面被NetworkManager排除後,任何設定都不會生效,且錯誤訊息完全不會提到這支檔。接手既有設備時必須先檢查。PCS block lock SUCCESS代表已收到光訊號。 經對照實驗確認,該訊息來自驅動的lane bring-up流程,不能作為實體連線的判斷依據。唯一可信的是carrier與link_connect_count。48x10GT,全部為RJ45銅線埠,無法插光纖模組。採購線材前務必用show module確認介質。switchport與no shutdown。/sys/class/net/<介面>/mtu確認。ggml-rpc-server綁在公網位址上。 RPC協定沒有認證,等於對外開放無認證的遠端執行介面。必須在10G上另掛私有位址並只綁該位址。rpc-server。 實際檔名是ggml-rpc-server,舊版文件與網路文章多寫成前者。--tensor-split 50,50。 兩台可用記憶體不同時會造成單邊OOM。llama.cpp依可用記憶體自動配比更可靠,不要手動干預。GGML_RPC:BOOL=OFF,不重新編譯無法使用RPC。另外MIC-743出廠映像不含cmake與編譯工具鏈,白機需先安裝。本章內容已於節點A與節點B實機驗證完成,實際跑起151 GB的Q8量化大型模型,數據皆為實測值。
單台MIC-743的可用記憶體上限實測為 125,810 MiB(約123 GB),由ggml-rpc-server啟動時回報。超過這個數字的模型單機放不下,必須跨機。
兩台合計約246 GB,扣掉作業系統與其他服務,實務上約200 GB可用於模型權重。
兩種平行化對網路的要求差了三個數量級:
| 方式 | 每個token跨機傳輸量 | 10G夠不夠 |
|---|---|---|
| 層切分(pipeline parallel) | 只傳一份hidden state | 綽綽有餘 |
| 張量切分(tensor parallel) | 每層都要all-reduce完整張量 | 完全不夠 |
llama.cpp的RPC模式採用的是層切分。以hidden dimension 8192、fp16估算,每個token跨機一次僅傳輸16 KB,解碼階段30 tokens/秒約需3.8 Mbps,只佔10G頻寬的0.04%。
兩台都必須重新編譯。節點B原有的建置是GGML_RPC:BOOL=OFF,不能直接用。
sudo apt install -y cmake build-essential git ccache git clone --depth 1 https://github.com/ggml-org/llama.cpp.git cd llama.cpp export PATH=/usr/local/cuda/bin:$PATH cmake -B build-rpc -DGGML_CUDA=ON -DGGML_RPC=ON \ -DCMAKE_BUILD_TYPE=Release -DCMAKE_CUDA_ARCHITECTURES=110 cmake --build build-rpc --config Release -j 12
CMAKE_CUDA_ARCHITECTURES=110對應Jetson AGX Thor的運算能力11.0,可用nvidia-smi --query-gpu=compute_cap --format=csv確認。建議建置到獨立的build-rpc/目錄,不影響既有的build/。
MIC-743出廠映像不含cmake與編譯工具鏈,白機需先安裝。
ggml-rpc-server啟動時會自行警告:
WARNING: Host is != '127.0.0.1' Never expose the RPC server to an open network! This is an experimental feature and is not secure!
RPC協定沒有任何認證機制,允許遠端配置記憶體與執行運算。若10G網段承載的是可路由的公網位址,直接綁上去等於對外開放一個無認證的遠端執行介面。
正確做法是在10G介面上另外掛一組私有位址,RPC只綁私有位址:
sudo nmcli con mod mgbe0_0-10g +ipv4.addresses <甲機直連位址>/<遮罩> sudo nmcli con up mgbe0_0-10g
兩台分別使用<甲機直連位址>與<乙機直連位址>。這組位址已寫入NetworkManager設定,可跨重開機。設定後確認監聽位址:
ss -tlnp | grep 50052 LISTEN <乙機直連位址>:50052
必須是私有位址,不可以是0.0.0.0或公網位址。
執行檔名是ggml-rpc-server,不是rpc-server。
在worker端啟動(此例為節點B):
cd ~/llama.cpp/build-rpc/bin ./ggml-rpc-server -H <乙機直連位址> -p 50052 -c
-c啟用本地檔案快取,避免每次載入都重新傳輸權重,強烈建議加上。
在主控端執行(此例為節點A,模型檔放這裡):
cd ~/llama.cpp/build-rpc/bin ./llama-cli -m <模型第一個分片>.gguf \ --rpc <乙機直連位址>:50052 \ -ngl 999 --no-mmap -c 4096 -n 64 --single-turn \ -p "你的提示詞"
多分片模型只需指定第一個分片,其餘會自動載入。
只有主控端需要模型檔。 主控端載入GGUF之後,透過RPC把該由遠端負責的張量推送過去,worker端不需要有模型檔。
本次實測151 GB的模型中約有 67 GB經10G傳到節點B。以實測8.9 Gbps計算約需60秒。這是10G真正不可取代的地方——同樣的載入若走1G約需9分鐘。
ggml-rpc-server -c的本地快取可讓重複載入省去這段傳輸。
llama.cpp會依各裝置的可用記憶體自動配比,這比手動指定可靠。
本次實測時節點B有14個容器佔用34 GB,可用記憶體只有88 GB,而節點A有118 GB。自動配比的結果是 91 GB / 67 GB,剛好避開OOM。若照直覺手動設--tensor-split 50,50(各75 GB),節點B會因記憶體不足而失敗。
151 GB的Q8量化模型(5分片)跨兩台MIC-743
| 項目 | 數值 |
|---|---|
| 模型大小 | 151 GB |
| 載入時間 | 約6分鐘(含磁碟讀取與67 GB網路傳輸) |
| Prompt處理 | 18.0 tokens/秒 |
| 文字生成 | 10.7 tokens/秒 |
| 節點A記憶體用量 | 91 GB |
| 節點B記憶體用量 | 101 GB(含既有容器34 GB) |
跨機開銷對照(Gemma-4-26B Q4,16 GB,此模型單機跑得動故可對照)
| 項目 | 單機 | 跨機 | 差異 |
|---|---|---|---|
| Prompt處理 | 153.9 t/s | 86.7 t/s | −44% |
| 文字生成 | 52.5 t/s | 48.5 t/s | −7.6% |
生成速度只掉7.6%,證實層切分對頻寬需求極低,主要成本是往返延遲(實測0.69 ms)。Prompt處理掉44%較多,因為預填階段要一次搬移大量activation,且兩台是輪流工作而非同時運算。
| 模型 | 量化後大小 | 單機(123 GB) | 雙機(約200 GB) |
|---|---|---|---|
| gpt-oss-120b MXFP4 | 59 GB | 可 | 不需要 |
| Llama-70B Q8 | 70 GB | 可 | 不需要 |
| 151 GB級Q8量化模型 | 151 GB | 不可 | 已實測可行 |
| Llama-405B Q4_K_M | 約230 GB | 不可 | 超出,需更低量化 |
單機放得下就不要拆。 層切分是兩台輪流工作而非同時運算,本質上是序列化的,一定比單機慢。只有在模型真的塞不進一台時才值得拆。
目前只用了mgbe0_0一條lane。四條可做LACP聚合(802.3ad),頻寬上看約35 Gbps,交換機端八個子介面已具備條件。
但對解碼階段沒有幫助(本來就只用0.04%頻寬),只會改善模型載入時的權重傳輸時間(本次約60秒,聚合後可降至約20秒)與長提示詞預填。以一次性成本換取多一層設定與故障點,除非要做分散式訓練的梯度同步,否則不建議。
mic743-init.sh涵蓋第三章至第六章的所有設定,可重複執行,已完成的項目會自動略過。主機名請依貴單位的命名規則自訂:
sudo bash mic743-init.sh <主機名>
腳本最後會印出驗收摘要,涵蓋主機名、時區、電源模式、鎖頻、CUDA、Docker與10G埠連線狀態。10G網路的位址因現場網段而異,腳本只做介面啟用與前置處理,位址請依8.5與8.6節設定。
驗證流量是否真的走10G,依8.8節的方式檢查。判準是接收封包數的增量必須大於0,其他現象都可能是1G代為回應:
cat /sys/class/net/mgbe0_0/statistics/rx_packets ping -I mgbe0_0 -c 5 <對端位址> cat /sys/class/net/mgbe0_0/statistics/rx_packets
搬移對外位址的順序與回滾做法見8.7節。搬移的瞬間必然斷線,務必以setsid nohup脫離SSH執行,並先備妥自動回滾。
本文所有指令皆於兩台實機與 L3 網管交換機實際執行驗證。技術問題來信 service@cloudinfo.com.tw。