UGREEN DXP6800 Pro に eGPU + RTX 2000 Ada を載せて、Docker から Ollama を動かすまでの全記録
- ccf代表
- 5月1日
- 読了時間: 9分
はじめに
正直に言うと、最初は「NASにeGPUを繋いでDockerからGPUを使う」って、もう少し簡単に終わると思ってたんです。
でも実際にやってみたら、ブートが飛んだり、ドライバーのバージョンが噛み合わなかったり、/boot が256MBしかなくて initrd の更新で詰んだり……正直、何度か「もう諦めて素直にWindowsマシンに刺すか」と心が折れかけました。
それでも最終的には、UGREEN DXP6800 Pro 上で eGPU 接続の RTX 2000 Ada を Docker から --gpus all で叩ける状態まで持っていけたので、ハマりどころを含めて記録として残しておきます。同じ構成で詰まっている方の参考になれば嬉しいです。
最終的に到達したのはこんな環境です。
UGREEN DXP6800 Pro
UGOS Pro
Kernel: 6.12.74+deb12-amd64 (Debian backports)
NVIDIA Driver: 535.261.03
GPU: NVIDIA RTX 2000 Ada Generation (VRAM 16GB)
Docker Engine + NVIDIA Container Toolkit
Docker --gpus all 動作OK
Ollama 起動準備完了
やりたかったこと
ゴールはシンプルで、NAS本体だけでローカルLLMを動かすサーバを作ることでした。
構成イメージとしては、以下のような感じです。
UGREEN DXP6800 Pro
└ eGPU
└ NVIDIA RTX 2000 Ada Generation
└ NVIDIA Driver
└ Docker
└ NVIDIA Container Toolkit
└ Ollama
GPUが16GB VRAMあるので、7B〜14Bクラスのモデルなら余裕で乗ります。NAS自体が常時稼働しているので、推論サーバとしても都合が良い、という算段でした。
使った機材
NAS本体はこちら。
UGREEN DXP6800 Pro
UGOS Pro
GPUは Ada世代のワークステーション向け、消費電力も控えめで eGPU向きの一枚です。
NVIDIA RTX 2000 Ada Generation
VRAM 16GB
最初のつまずき:ドライバーがバージョン不一致で死ぬ
最初、軽い気持ちでSSHから NVIDIA のドライバーを入れていったら、いつの間にかAPT側が595系、カーネルモジュールが570系という、よくある最悪パターンに突入しました。
kernel module: 570.181
user space library: 595.71
この状態で nvidia-smi を叩くと、お馴染みのメッセージが返ってきます。
Failed to initialize NVML: Driver/library version mismatch
NVML library version: 595.71
「ああ、やっちまった」というやつです。これ、再起動すれば治る場合もあるんですが、今回は単純なミスマッチではなく、UGOSのカーネル側の問題も絡んでいたので根が深かったです。
まず eGPU 自体は見えているか?
落ち着いて、eGPUがそもそもPCIeデバイスとして認識されているかを確認します。
lspci | grep -Ei 'nvidia|vga|3d|display'
返ってきた結果はこうでした。
00:02.0 VGA compatible controller: Intel Corporation Alder Lake-UP3 GT2 [UHD Graphics]
03:00.0 VGA compatible controller: NVIDIA Corporation AD107GL [RTX 2000 / 2000E Ada Generation]
03:00.1 Audio device: NVIDIA Corporation AD107 High Definition Audio Controller
ハードウェアとしてはちゃんと見えている。少なくとも eGPU 接続自体は問題ないことがわかって、ここはひと安心。問題はソフトウェア側でした。
UGOS標準カーネルの罠
UGOSの初期カーネルは 6.12.30+ というカスタムカーネルでした。バージョン番号の末尾の + がもう不穏なんですが、案の定、対応するヘッダーがどこにも存在しません。
ls -ld /lib/modules/$(uname -r)/build
結果はこれ。
No such file or directory
APTでも見つからず。
apt-cache policy linux-headers-$(uname -r)
Unable to locate package linux-headers-6.12.30+
ヘッダーが無いとDKMSでNVIDIAドライバーがビルドできない、つまりこのカーネルのままだと永遠にドライバーが入らないということです。
ここで「素直にUGOS側に乗っかる戦略」は捨てて、Debian backports のカーネルに切り替える方針に変更しました。
Debian backports カーネルへの引っ越し
bookworm-backports から、ヘッダー付きの新しいカーネルを入れます。
linux-image-6.12.74+deb12-amd64
linux-headers-6.12.74+deb12-amd64
linux-headers-6.12.74+deb12-common
linux-kbuild-6.12.74+deb12
これでようやく、まともなカーネルとヘッダーのセットが揃いました。DKMSでドライバーをビルドする土台ができたわけです。
ブートが飛ぶ:UGREENの/bootは普通じゃない
ここで一度、派手にやらかしました。起動しなくなりました。
冷や汗をかきながら調べると、UGREEN DXP6800 Pro の /boot は普通のDebianとはかなり違う構成になっていました。
/boot = /dev/nvme0n1p1
FSTYPE = vfat
GRUB config = /boot/EFI/debian/grub.cfg
/boot/grub/grub.cfg ではなく、/boot/EFI/debian/grub.cfg が本体です。ここを編集しないと意味がない。気づくまでに結構な時間を使いました。
最終的には、こんな「セーフモード」的なメニューエントリを用意して落ち着きました。
set default="0"
set timeout="5"
menuentry "UGOSPRO-NAS recovery-safe" {
linux /vmlinuz-6.12.74+deb12-amd64 \
root=PARTUUID=99009e79-d999-a659-32e5-993bfb698a02 \
rootwait console=tty0 \
overlay=/dev/mmcblk0p7 overlayfs=ext4 \
net.ifnames=0 biosdevname=0 \
nomodeset i915.modeset=0 \
module_blacklist=nvidia,nouveau
initrd /initrd.img-6.12.74+deb12-amd64
}
ポイントはこの3つ。
nomodeset
i915.modeset=0
module_blacklist=nvidia,nouveau
iGPU、nouveau、NVIDIAを起動時にロードしないことで、何があってもとりあえずSSHまでは入れる構成にしました。実際、この後もう一度ブート不能を踏むんですが、GRUB編集画面からこのオプションを足して救出することができたので、この保険は本当に作っておいて良かったです。
eGPU+NVIDIAドライバーを触る人は、これに類するrecovery-safeメニューを最初に作っておくことを強くおすすめします。
いっそ工場出荷状態に戻した
トラブルシュートに次ぐトラブルシュートで環境がぐちゃぐちゃになってしまったので、覚悟を決めて一度UGOSを工場出荷状態に戻しました。
ただ面白いことに、工場出荷状態に戻してもブートパーティション側の設定は残っていました。
Debian backports kernel 6.12.74+deb12-amd64
/boot/EFI/debian/grub.cfg の recovery-safe 設定
このおかげで、初期化後もそのまま 6.12.74+deb12-amd64 で起動できました。
uname -r
6.12.74+deb12-amd64
クリーンな状態の上に、必要なカーネルだけ乗っかっている。これで仕切り直しスタートです。
DKMSとビルド環境を入れる
ドライバーをビルドするためのお約束パッケージ群です。
apt install -y dkms build-essential pkg-config
確認。
dkms status
何も出力されませんが、これは「DKMS管理下のモジュールがまだ登録されていない」だけなので問題ありません。
NVIDIA Driver 535 をインストール
色々試しましたが、最終的にはDebian標準の535系がいちばん安定しました。新しい600系を追いかけるよりも、確実に動く535を選んで正解だったと思います。
apt install -y \
nvidia-driver \
nvidia-kernel-dkms \
nvidia-kernel-support \
firmware-nvidia-gsp \
libnvidia-ml1 \
nvidia-smi
DKMSのビルドが走り終わったあとはこんな感じ。
dkms status
nvidia-current/535.261.03, 6.12.74+deb12-amd64, x86_64: installed
modinfo nvidia-current | grep ^version
version: 535.261.03
ここまで来てようやく「あ、いけそう」という感触が出てきました。
initramfs-tools が泣いた話
ところがここで、また足を取られました。initramfs-tools が更新時にエラーを吐き続けます。
原因を分解すると、ふたつありました。
原因①:/boot が vfat なので hard link が作れない
vfat は仕様としてハードリンクをサポートしません。でもDebianのdpkgは、initrd更新時にバックアップのためにhard linkを作ろうとします。これがバッティングしてエラーになっていました。
ln: failed to create hard link ... Operation not permitted
原因②:/boot が256MBしかなくて容量不足
容量を確認するとこう。
No space left on device
256MBの中にカーネル・initrd・config類を全部詰めるのはちょっと厳しい。
対応:UGOS残骸を /overlay に逃がす
/boot/boot という、UGOSが置いていったらしい一式を /overlay 配下にバックアップして退避させました。
mkdir -p /overlay/boot-backup/boot-dir
cp -a /boot/boot/* /overlay/boot-backup/boot-dir/
退避後、不要になった大物ファイルを削除。
rm -f /boot/boot/initrd.img
rm -f /boot/boot/initrd2.img
rm -f /boot/boot/vmlinuz
rm -f /boot/boot/vmlinuz2
これで /boot に余裕ができました。
df -h /boot
/dev/nvme0n1p1 256M 77M 180M 30% /boot
ついでに、作業中にうっかり消してしまったカーネルconfigを救出しておきます。
cp -a /lib/modules/$(uname -r)/build/.config /boot/config-6.12.74+deb12-amd64
これで dpkg --configure -a も無事に通るようになりました。
ついに nvidia-smi が通った瞬間
eGPUを接続し、NVIDIAモジュールを読み込ませて、おそるおそる nvidia-smi を叩きます。
nvidia-smi
NVIDIA-SMI 535.261.03
Driver Version: 535.261.03
CUDA Version: 12.2
GPU: NVIDIA RTX 2000 Ada Generation
VRAM: 16380 MiB
通った瞬間、思わず椅子の上で小さくガッツポーズしました。 ここまで本当に長かった。NASからNVIDIA RTX 2000 Adaを認識できる状態にやっとたどり着けた瞬間でした。
Docker Engine の再インストール
UGOSを初期化した影響で、Dockerはきれいに消えていました。
systemctl restart docker
Failed to restart docker.service: Unit docker.service not found.
潔く Docker Engine を入れ直します。ここはまあ、ドキュメントどおりに進むパートなので特に詰まりませんでした。
Docker on Overlay 問題:保存先を変える
ところが、GPU付きのコンテナを起動しようとしたら、また新しいエラーが顔を出しました。
failed to mount ... fstype: overlay ... err: invalid argument
調べてみると原因は、UGOSのルートファイルシステム自体が overlay になっていることでした。その上にDocker/containerdがさらにoverlayを重ねようとして、衝突していたわけです。
UGOSのストレージはこんな構成です。
/ = overlay
/overlay = /dev/nvme0n1p7 ext4
/overlay の方は普通のext4なので、Dockerとcontainerdのデータルートをここに移してあげれば解決します。
Docker側の data-root
/etc/docker/daemon.json をこう書きました。
{
"data-root": "/overlay/docker",
"runtimes": {
"nvidia": {
"args": [],
"path": "nvidia-container-runtime"
}
}
}
containerd側の root
/etc/containerd/config.toml の該当箇所を変更。
root = '/overlay/containerd'
state = '/run/containerd'
確認。
findmnt -T /overlay/containerd
/overlay /dev/nvme0n1p7 ext4
ext4の上に座らせれば、overlayが入れ子にならずDockerが動くようになります。
Docker から GPU が見えた
ここまできたら、お楽しみのGPU動作確認です。
docker run --rm --gpus all nvidia/cuda:12.2.2-base-ubuntu22.04 nvidia-smi
NVIDIA-SMI 535.261.03
Driver Version: 535.261.03
CUDA Version: 12.2
GPU: NVIDIA RTX 2000 Ada Generation
VRAM: 16380 MiB
コンテナの中からGPUが見えました。 当初の目標、「Dockerコンテナから eGPU を使えるようにする」が達成できた瞬間です。
最終構成のまとめ
最終的に手元に残った、安定動作する構成はこちらです。
UGREEN DXP6800 Pro
UGOS Pro
Kernel: 6.12.74+deb12-amd64
NVIDIA Driver: 535.261.03
GPU: NVIDIA RTX 2000 Ada Generation (VRAM 16GB)
Docker: 動作
NVIDIA Container Toolkit: 動作
Docker --gpus all: 成功
次回:Ollamaを乗せる
ここまで来れば、あとは本来の目的だったOllamaを起動するだけです。
docker volume create ollama
docker run -d \
--gpus=all \
-v ollama:/root/.ollama \
-p 11434:11434 \
--name ollama \
--restart unless-stopped \
ollama/ollama
ヘルスチェック。
docker logs ollama --tail 100
curl http://localhost:11434/api/tags
軽量モデルで動作確認。
docker exec -it ollama ollama pull llama3.2:3b
docker exec -it ollama ollama run llama3.2:3b
ここから先のOllama運用編は、また別記事にまとめたいと思います。
振り返り:今回のキモになったポイント
最後に、同じことをやろうとしている人向けに、「ここを押さえておけば自分はもっと早く終わってた」というポイントを5つ挙げておきます。
1. UGOS標準カーネルは諦めて、Debian backportsへ
6.12.30+ のような UGOS独自カーネルにはヘッダーが付いてきません。ヘッダーが無い=DKMSが使えない=NVIDIAドライバーが入らない、という詰みコースです。最初から 6.12.74+deb12-amd64(backports)に切り替えて作業した方が絶対に早いです。
2. /boot が vfat であることを忘れずに
UGREEN DXP6800 Pro の /boot は vfat、しかも 256MB しかありません。これが原因で、Debian標準のdpkg挙動と相性が悪く、
ハードリンクが作れない
initrdのバックアップが作れない
そもそも容量が足りない
という三重苦が発生します。最初に /boot の不要ファイルを退避してスペースを作っておくと、後の作業がぐっと楽になります。
3. recovery-safe な GRUB エントリを最初に作っておく
NVIDIAドライバー周りを触ると、ほぼ確実に一度はブート不能を踏みます(個人の感想です)。そのときに、
nomodeset
i915.modeset=0
module_blacklist=nvidia,nouveau
を含んだセーフメニューが用意してあると、SSHまで戻ってきて落ち着いて修正できます。保険は最初にかけるもの、という当たり前の話でした。
4. Docker と containerd は /overlay に置く
UGOSのルートが overlay なので、Docker/containerd をデフォルトの /var/lib に置くと、overlay on overlay でつまずきます。data-root と root をどちらも /overlay 配下のext4にずらしましょう。
5. ドライバーは無理せず NVIDIA 535 系で
新しいバージョンを追いかけるよりも、Debian標準で配られている535系の方が圧倒的に安定していました。「動かしたい」が目的なら、最新を追わず安定版を選ぶのが結局いちばんの近道だと思います。
おわりに
ふりかえってみると、UGREEN DXP6800 Pro は「市販のNAS」の顔をしながら中身はかなりカスタムなDebianで、普通のLinuxサーバ感覚でいると色々な所でつまずきます。
ただ、いったん勘所を押さえてしまえば、eGPUを刺してDocker経由でGPU推論サーバとして使うことは十分可能でした。NAS一台でストレージとローカルLLMが動く、というのはやっぱり夢があります。
次は、この上で実際にOllamaをまわして、ローカルLLMサーバとしてどこまで使い物になるかを試してみる予定です。続きはまた別の記事で。
最後まで読んでいただき、ありがとうございました。同じ構成で詰まっている方の参考になれば嬉しいです。



コメント