top of page

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サーバとしてどこまで使い物になるかを試してみる予定です。続きはまた別の記事で。

最後まで読んでいただき、ありがとうございました。同じ構成で詰まっている方の参考になれば嬉しいです。

最新記事

すべて表示
LLMのモデルによる応答性の比較

目的 前回の検証では、OPSNOTE(当社開発中の手順書 SaaS)におけるAzure上の自社ホストAIモデルに対して、性能比較を行い、現時点ではqwen2.5:14bとClaude Haikuでは、勝負にならないことまではわかりました。 今回は、同じローカルLLMに対して、Macbook Pro M2 16GBのモデル上で、ollama経由での応答を比較したいと思います。 先に結論 どのモデルも

 
 
 

コメント


bottom of page