~/blog/nemoclaw-install-gx10-from-scratch

NemoClaw · part 2

NemoClaw 安裝踩坑:官方文件沒寫的 4 個必修修正

cat --toc

TL;DR

GX10(GB10/SM121)安裝 NemoClaw 需要四個官方文件沒寫清楚的修復:Node.js 升到 v22、安裝後手動跑 sudo npm link、從 tar.gz 安裝 OpenShell(文件裡的 binary URL 404)、在 onboard 前加 cgroupns=host 到 Docker daemon.json。修完後,nemoclaw setup-sparkNEMOCLAW_NON_INTERACTIVE=1 nemoclaw onboard 就可以跑完。

白話版:在特殊硬體上安裝 AI Agent 軟體

在一般電腦上裝軟體,通常就是按「下載」然後跟著提示走。但在 NVIDIA DGX Spark(或者用同一顆晶片的 ASUS GX10)這種專門的 AI 硬體上,事情沒那麼簡單。這台機器跑 Linux、用的是 ARM 處理器而不是一般 PC 裡的 Intel/AMD 晶片,而且出廠自帶的一些工具版本偏舊。

NemoClaw 是 NVIDIA 的 AI Agent 框架——讓 AI 助手在你的機器上跑、能讀檔案、能執行任務的軟體。官方安裝指南假設你的環境是標準的。但在 GX10 上,有四件事會出問題而且指南沒提到:預裝的 Node.js 版本太舊、一個檔案權限步驟靜默失敗、文件裡的下載連結壞了、還有一個 Linux 容器設定需要改。

這些都不難修,但前提是你知道它們存在。這篇文章照順序走過每一個問題,附上完整指令。從空白 GX10 到 AI Agent sandbox 跑起來,總共大概 30 分鐘。


Step 1:Node.js 升到 v22

NemoClaw 需要 Node.js 20+。GX10 出廠預裝是 v18.19.1,安裝腳本很早就會報錯:

Error: Node.js version 18.19.1 is not supported. Please upgrade to 20 or later.

用 NodeSource 升到 v22:

curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt-get install -y nodejs
node --version
# v22.22.1

錯誤訊息說需要 20+,裝 v22 沒問題。

Step 2:跑 NemoClaw 安裝腳本

curl -fsSL https://www.nvidia.com/nemoclaw.sh | bash

腳本以 exit code 243 結束,並印出:

nemoclaw.sh: line 47: BASH_SOURCE[0]: unbound variable

這是 set -euo pipefail 的問題:BASH_SOURCE[0]curl | bash 的 subshell 裡是 unset 的。錯誤在腳本的 cleanup block 發生——此時安裝已經完成了。馬上跑 nemoclaw --version

nemoclaw v0.1.0

CLI 裝在 ~/.nemoclaw/source。錯誤看起來很嚇人,但是假警報。

安裝腳本嘗試建立 global symlink,這步失敗了:

npm error code EACCES
npm error syscall symlink
npm error path /usr/local/lib/node_modules/nemoclaw
npm error dest /usr/local/bin/nemoclaw
npm error errno -13

在 system-managed Node.js 環境下沒有 sudo 跑 npm link 的標準問題。手動修:

cd ~/.nemoclaw/source
sudo npm link

之後 nemoclaw 就可以在任何地方呼叫了。

Step 4:安裝 OpenShell CLI

nemoclaw onboard 需要 openshell CLI。官方 spark-install.md 的安裝方式是這樣:

# 這個 URL 404,不要用
ARCH=$(uname -m)
curl -fsSL "https://github.com/NVIDIA/OpenShell/releases/latest/download/openshell-linux-${ARCH}" \
  -o /usr/local/bin/openshell

這個 URL 回傳 HTTP 404。實際上 release 的格式是 tar.gz,不是 bare binary。aarch64 Linux 的正確安裝方式:

curl -fsSL \
  "https://github.com/NVIDIA/OpenShell/releases/download/v0.0.13/openshell-aarch64-unknown-linux-musl.tar.gz" \
  -o /tmp/openshell.tar.gz
tar xzf /tmp/openshell.tar.gz -C /tmp
sudo mv /tmp/openshell /usr/local/bin/openshell
openshell --version
# openshell 0.0.13

x86_64 的話,把 aarch64-unknown-linux-musl 換成 x86_64-unknown-linux-musl

用這個方式取得最新版本號:

curl -s https://api.github.com/repos/NVIDIA/OpenShell/releases/latest \
  | python3 -c "import sys,json; r=json.load(sys.stdin); print(r['tag_name'])"
# v0.0.13

Step 5:修 Docker 的 cgroup v2 問題

Ubuntu 24.04 預設用 cgroup v2(cgroup2fs)。OpenShell 的 gateway container 在裡面跑 k3s,k3s 嘗試建立 cgroup v1 風格的路徑,但這些路徑在 cgroup v2 下不存在。沒有修的話,onboard 會報錯:

K8s namespace not ready
openat2 /sys/fs/cgroup/kubepods/pids.max: no such file or directory
Failed to start ContainerManager: failed to initialize top level QOS containers

先確認 cgroup 版本:

stat -fc %T /sys/fs/cgroup/
# cgroup2fs   ← 需要修
# tmpfs       ← cgroup v1,不需要修

如果是 cgroup2fs,把 cgroupns=host 加進 Docker daemon config:

sudo python3 -c "
import json, os
path = '/etc/docker/daemon.json'
d = json.load(open(path)) if os.path.exists(path) else {}
d['default-cgroupns-mode'] = 'host'
json.dump(d, open(path, 'w'), indent=2)
"
sudo systemctl restart docker

這讓所有 container 使用 host 的 cgroup namespace,k3s 需要這個。GX10 上原有的 container(open-webuipipelines 等)在 Docker 重啟後都正常運作。

Step 6:取得 NVIDIA API Key

nemoclaw setup-sparknemoclaw onboard 都需要一個 NVIDIA API key,從 build.nvidia.com/settings/api-keys 取得。Key 以 nvapi- 開頭,免費試用 30 天。

Key 可以用環境變數傳入,跳過互動提示:

export NVIDIA_API_KEY=nvapi-...

Step 7:跑 setup-spark

NVIDIA_API_KEY=nvapi-... nemoclaw setup-spark

輸出:

>>> User 'coolthor' already in docker group
>>> Docker daemon already configured for cgroupns=host

>>> DGX Spark Docker configuration complete.
>>> Next step: run 'nemoclaw onboard' to set up your sandbox.

setup-spark 檢查 Docker group 和 daemon config,然後結束。在 GX10 上——按照上面手動修完之後——幾乎秒完,因為所有條件都已滿足。在全新的 DGX Spark 上它會自動套用這些修復。

Step 8:跑 onboard

預設的 nemoclaw onboard 是互動式的,會詢問 sandbox 名稱、模型選擇等。透過 SSH 跑沒有 TTY,互動模式會卡住。用 NEMOCLAW_NON_INTERACTIVE=1 讓它全程使用預設值:

NVIDIA_API_KEY=nvapi-... NEMOCLAW_NON_INTERACTIVE=1 nemoclaw onboard

輸出分 7 個階段:

[1/7] Preflight checks
  ✓ Docker is running
  ✓ openshell CLI: openshell 0.0.13
  ✓ Port 8080 available (OpenShell gateway)
  ✓ NVIDIA GPU detected: 1 GPU(s), 122502 MB VRAM

[2/7] Starting OpenShell gateway
  Gateway nemoclaw ready.
  ✓ Active gateway set to 'nemoclaw'

[3/7] Creating sandbox
...

[7/7] Done

Stage 2 啟動 k3s 的過程會印出幾百行 Kubernetes reconciler log,看起來很嚇人,但不是錯誤。整個流程完成後確認:

nemoclaw status
# Sandboxes:
#   my-assistant * (nvidia/nemotron-3-super-120b-a12b)

nemoclaw my-assistant status
# Phase: Ready

Sandbox 起來了,policy enforcement 啟動,agent 連到 NVIDIA 雲端的 nvidia/nemotron-3-super-120b-a12b

這次學到了什麼

花最多時間的地方: OpenShell binary URL。spark-install.md 文件裡的 URL 在當前版本是 404。實際的 asset 是 tar.gz,命名規則也不同。更麻煩的是 curl -fsSL 在 404 時預設不報錯——它會把 HTML 錯誤頁存成 binary,然後在執行時出現 Exec format error,讓人以為是架構問題而不是下載問題。加 -v flag 就能立刻看到 404。

下次遇到類似問題先想到: Binary 出現 Exec format error 時,先跑 file <binary>。如果顯示 ASCII text 而不是 ELF,就是下載到了 HTML 錯誤頁。GitHub release asset 的命名在不同版本之間不一致,不要信任文件裡寫死的 URL,直接去 release 頁面確認。

記住這一件事: curl | bash 安裝腳本在非 x86 硬體 + strict bash mode 下有兩個獨立的失敗點:下載步驟(架構不符、URL 失效)和腳本本身的 bash 相容性。兩個都可能靜默失敗,從外面看起來像全部失敗,但實際上只有一部分失敗。每個步驟後都確認 artifacts 是否存在。

安裝 Checklist

GX10 / DGX Spark(aarch64,Ubuntu 24.04,cgroup v2)上的 NemoClaw 安裝:

  1. node --version → 需要 20+。不是的話:用 NodeSource 安裝 v22
  2. curl -fsSL https://www.nvidia.com/nemoclaw.sh | bash → exit code 243 忽略
  3. cd ~/.nemoclaw/source && sudo npm link
  4. 從 GitHub releases 下載 OpenShell tar.gz(不是文件裡的 URL)
  5. 確認 stat -fc %T /sys/fs/cgroup/ → 如果是 cgroup2fs,加 cgroupns=host 到 daemon.json
  6. 從 build.nvidia.com 取得 NVIDIA API key(30 天免費)
  7. NVIDIA_API_KEY=nvapi-... nemoclaw setup-spark
  8. NVIDIA_API_KEY=nvapi-... NEMOCLAW_NON_INTERACTIVE=1 nemoclaw onboard
  9. nemoclaw status → sandbox 應該顯示 Ready

本系列其他文章:Part 1 — NemoClaw 是什麼、為什麼存在、怎麼運作的

常見問題

為什麼 NemoClaw 安裝在 DGX Spark / GX10 上會失敗?
安裝失敗有四個官方文件沒提到的原因:Node.js 必須 v20+(GX10 出廠是 v18)、npm link 在 system-managed Node 上需要 sudo、文件裡的 OpenShell binary URL 回傳 404(實際 release 是 tar.gz 格式)、Ubuntu 24.04 的 cgroup v2 需要在 onboard 前把 cgroupns=host 加進 Docker daemon.json。
怎麼在 aarch64 Linux 上安裝 OpenShell?
從 GitHub releases 下載 tar.gz(不是文件裡的 binary URL,那個 404)。aarch64 的話:curl 最新 release 的 openshell-aarch64-unknown-linux-musl.tar.gz,解壓縮,把 binary 搬到 /usr/local/bin/openshell。x86_64 用 x86_64-unknown-linux-musl 版本。
跑 openshell 出現 'Exec format error' 是什麼意思?
通常代表下載靜默失敗——curl 存了一個 HTML 錯誤頁(404 回應)而不是實際的 binary。跑 'file openshell' 確認:如果顯示 'ASCII text' 而不是 'ELF',就是下載到錯的東西了。重新從正確的 GitHub release URL(tar.gz 格式)下載。
NemoClaw onboard 時 cgroup v2 錯誤怎麼修?
Ubuntu 24.04 預設用 cgroup v2,但 OpenShell 內部的 k3s 需要 cgroup v1 的路徑。在 /etc/docker/daemon.json 加上 '"default-cgroupns-mode": "host"' 然後重啟 Docker。用 'stat -fc %T /sys/fs/cgroup/' 確認——如果顯示 'cgroup2fs' 就需要修。