西川和久の不定期コラム
BeelinkのミニPC「GTi13 Ultra」を、WindowsとDockerで環境構築して最後デュアルGPU化!?
2025年2月20日 06:09
メモリを64GBへ、ストレージ2TB追加
「AI PC」と言っても人によって用途はさまざま。筆者はご存じのように画像(たまに動画)生成とLLMが主な用途となるだろうか。
この場合、各モデルのファイルサイズが巨大(数十GBなんて普通)なのでストレージはたっぷり欲しい。メインメモリ(RAM)やビデオメモリ(VRAM)も同様。ただ一般的なPCだとRAMは32GB×2の64GBまでがお手頃。それ以上だといろいろコストアップする。VRAMは選ぶdGPU次第。増えると価格が……となる。今回追加で用意したのは以下の通り。
SO-DIMM 32GB×2、M.2 2280 SSD 2TB。そしてGPU補助電源の8ピンを二股にするケーブルと、GPU補助電源の8ピン×2を12VHPWRにするケーブル。
メモリとストレージは、このBeelink「GTi13 Ultra」の場合、交換が結構面倒なので先に済ます。鬼門のスピーカーからも無事音が出るのを確認。
dGPUの交換は最後にして、テストで付けたGeForce RTX 4060 Ti(16GB)のままで環境構築を行ない、仕上げにより強力なdGPUへ入れ替えるため変換ケーブルを……となる。
必要なソフトウェアのインストール
本来AI環境はUbuntuの方が有利なのだが(Windowsだとpythonのライブラリでないものや、入れるのが面倒なものが結構ある)、せっかくWindows 11 Pro(24H2)が入っているのでこれをそのまま使い、AI環境はDocker上で動かすことにした。AI関連の設定を行なう前にまずやったことは以下の通り。
- IPアドレス固定
- RemoteDesktop
- OpenSSHサーバー
- Docker Desktop
- Git for Windows
- nano for Windows
- Mini Conda
1から3まではWindows標準搭載の機能。4から7もpythonの環境としては一般的なので特に説明の必要はないだろう。主にサーバー的に扱えるようにするものだ。
WSLに関してはDocker Desktopをインストールすれば自動的に設定される(当初は違ったような……)。今回はメインのAI PCに合わせてUbuntu 22.04 LTSをチョイス。nanoはCLI用の簡単なエディタだ。CLIで操作中、GUIからnotepadを開くのが面倒な時、ちょっとした書込みはこれを使うことが多い。
次にAI関連は増設した2TB(D:ドライブ/NTFS)の方へ入れる。モデルの多くは生成
AI画像と動画用。フォーマット後容量は約1.9TBほどあるのだが、メインのAI PCから全部コピーしたら残200GBになってしまった(笑)。
Windows + Docker失敗/リカバリ編
とりあえず適当にComfyUI用のDockerfileを作り動かしたところ、動くのは動くのだがcheckpoint(モデル)の読み込みが激遅く分単位でかかる。読み込んだ後は普通の速度なので、このファイルアクセスだけ何とかしたいのだが、調べると……。
“NTFS/EXT4変換に時間がかかり遅い”
とあり、このままではどうにもならないようだ。手としては、
“SSDをEXT4でフォーマット、それをWSL側でマウントする”
となる。せっかく大量のモデルファイルをコピーしたのにまたフォーマットして入れ直しだ。Windowsの標準機能ではEXT4にフォーマットできないため、WSLのUbuntu上で処理を行なう。手順は以下の通り。
PS C:\Users\knishika> GET-CimInstance -query "SELECT * from Win32_DiskDrive"
DeviceID Caption Partitions Size Model
-------- ------- ---------- ---- -----
\\.\PHYSICALDRIVE0 HP SSD FX700 2TB 0 2048407280640 HP SSD FX700 2TB
\\.\PHYSICALDRIVE1 CT1000P3PSSD8 3 1000202273280 CT1000P3PSSD8
PS C:\Users\knishika> wsl --mount \\.\PHYSICALDRIVE0 --bare
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
loop0 7:0 0 510.9M 1 loop /mnt/wsl/docker-desktop/cli-tools
loop1 7:1 0 647.7M 1 loop
sda 8:0 0 388.4M 1 disk
sdb 8:16 0 8G 0 disk [SWAP]
sdc 8:32 0 1T 0 disk /mnt/wsl/docker-desktop/docker-desktop-user-distro
sdd 8:48 0 1T 0 disk
sde 8:64 0 1T 0 disk /mnt/wslg/distro
/
sdf 8:80 0 1.9T 0 disk
└─sdf1 8:81 0 16M 0 part
※ sdfが目的のdisk
$ sudo apt install e2fsprogs
$ sudo mkfs.ext4 /dev/sdf
mke2fs 1.46.5 (30-Dec-2021)
Found a gpt partition table in /dev/sdf
Proceed anyway? (y,N) y
Creating filesystem with 500099670 4k blocks and 125026304 inodes
Filesystem UUID: a408588a-1025-426a-80aa-247b65a8b214
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968,
102400000, 214990848
Allocating group tables: done
Writing inode tables: done
Creating journal (262144 blocks): done
Writing superblocks and filesystem accounting information: done
$ sudo mkdir /mnt/AI
$ sudo mount /dev/sdf /mnt/AI
1と2がWSL固有で、後はUbuntuでは普通の手法。特に難しいことはしていない。なおWindowsからこのEXT4のドライブにアクセス(読み書き可能)する方法があり、
\\wsl.localhost\Ubuntu-22.04\mnt\AI
とすれば良い。とりあえずここまでできたら後は大量のモデルファイルをコピー。一晩かかるので、開始後放置しておく。これでファイルアクセスが遅い=失敗編はリカバリした。
Windows+Docker+EXT4成功編
明けてモデルコピー終了したのを確認後、いよいよ環境構築となる。また今回のケースだと、C:ドライブはWindows込みの1TB、EXT4ドライブは2TB。LLM用のLM Studioは、特にpythonの環境縛りなどがないため、C:ドライブ側に入れ、画像/動画生成系のみDockerで対応する。相互でモデルファイルをアクセスすることもなく、これは問題ないだろう。
次にWSLは搭載メモリの半分を割り当てるのがデフォルトらしく64GBにした意味がない。増やす方法はホームフォルダ直下に .wslconfig ファイルを作り
[wsl2]
memory=50GB
swap=32GB
processors=8
※ 後にmemory=54GBへ変更
とする。その後、
PS C:\Users\knishika> wsl --shutdown
PS C:\Users\knishika> wsl
PS C:\Users\knishika> wsl --mount \\.\PHYSICALDRIVE0 --bare
※ 最後は管理者としてPowerSellを起動
これでOKだ。確認は、
$ free -h
total used free shared buff/cache available
Mem: 49Gi 21Gi 24Gi 190Mi 3.2Gi 27Gi
Swap: 32Gi 1.1Gi 30Gi
メモリが増えているのが分かる。
Windows側でインストールしたDockerをUbuntuでも使えるよう、Docker Desktopの設定→Resources→WSL integrationでUbuntu-22.04をオン。これで連携が可能となる。
次に通常Ubuntu版Dockerはrootを使うため、sudo docker xxxxxとなるのだが、sudoなしでdockerを起動するには
$ sudo usermod -aG docker $USER
とすれば良い。仕上げは、
$ sudo apt install net-tools
$ sudo apt install openssh-server
$ sudo systemctl enable ssh
これによりWindowsのCMD / PowerShellからUbuntuにssh接続可能になる(ifconfigでUbuntu側のIPアドレスを確認)。Windows上だけで操作するなら不要であるが、別のPC→sshでこのPCにログイン→から再度sshでUbuntuにログイン……と、ほかのPCからこのUbuntuを操作するのに便利だ。
ComfyUIのインストールは、先にUbuntu側の/mnt/AIで
$ git clone https://github.com/comfyanonymous/ComfyUI.git
$ cd ComfyUI
$ cd custom_nodes
$ git clone https://github.com/ltdrdata/ComfyUI-Manager.git
$ cd ..
$ cd ..
としておき、同一階層上に(つまり/mnt/AI)に docker-compose_comfyui.ymlを作る(docker-compose.ymlにしなかったのは、以降、この階層にいろいろ入る予定のため)。
services:
comfyui:
image: nvcr.io/nvidia/pytorch:25.01-py3
volumes:
- /mnt/AI/ComfyUI:/ComfyUI/
command:
- /bin/bash
- -c
- |
apt update
python -m pip install --upgrade pip
apt install -y git python3-pip libgl1-mesa-dev libglib2.0-0
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/nightly/cu128
cd /ComfyUI/
pip install -r requirements.txt
python main.py --listen --fast
deploy:
resources:
reservations:
devices:
- driver: nvidia
capabilities: [gpu]
ports:
- "8188:8188"
nvcr.io/nvidia/pytorch:25.01-py3は、CUDAなどNVIDIAのフレームワークが入ったイメージとなる。実はこの25.01-py3と /whl/nightly/cu128は、GeForce RTX 5090対応のもので、GeForce RTX40系は下位互換で動くだろうとテスト的に使ってみた。前者を24.12-py3、後者を/whl/cu126とすれば、Python 3.12、CUDA 12.6、PyTorch cu126が入る。
この点はDockerの便利なところで、Ubuntu本体にあるバージョンのCUDAをapt installしてしまうと、CUDAを使うすべてのアプリでCUDAやPyTorchのバージョンを合わせる必要があり大騒動となる。ところがDockerだとコンテナ単位で切り替えが可能。ディスプレイドライバだけ入れておけば良く、使い勝手が非常に良い。
起動は、WSL / Ubuntuのコンソールから
$ docker-compose -f docker-compose_comfyui.yml up
でOK。http://localhost:8188やhttp://[PCのIPアドレス]:8188で、ComfyUIが起動する。初回はいろいろライブラリなどをインストールするので時間がかかるものの、docker-compose downしない限り、2回目以降はそこそこ速く起動する。
次はSwarmUI。生成AI画像系のWebUIはAUTOMATIC1111、Forge、Fooocusなどいろいろあったが、FLUX.1登場以降、アーキテクチャが異なるモデルが乱立しており、それらの対応にまったく追いついていないのが現状だ。唯一、ComfyUIはノードの組み合わせと言う設計思想から対応できている。
その中で、何とか多くを取り込みつつ、使い勝手も良いのがこのSwarmUI。筆者は以前からロジック検証はComfyUI、普通に画像生成はSwarmUI(バックエンドはComfyUI、フロントエンドは.NET)を使っている。と言うことでこれは是非入れたいWebUIとなる。
こちらは同じく/mnt/AI下で
$ git clone https://github.com/mcmonkeyprojects/SwarmUI.git
とし、SwarmUIフォルダの中にgo.shというDocker起動用のスクリプトと、ComfyModelsフォルダを作ってある。このComfyModelsフォルダは、コンテナ内に/mnt/AI/ComfyUI/modelsをマウントして、モデルファイルを共通で使うための仕掛けだ。
SETUSER=""
POSTARG="$@"
docker run -it \
--rm \
$SETUSER \
--name swarmui \
--mount source=swarmbackend,target=/SwarmUI/dlbackend \
--mount source=swarmdata,target=/SwarmUI/Data \
--mount source=swarmdlnodes,target=/SwarmUI/src/BuiltinExtensions/ComfyUIBackend/DLNodes \
-v "$PWD/Models:/SwarmUI/Models" \
-v "$PWD/Output:/SwarmUI/Output" \
-v "/mnt/AI/ComfyUI/models:/SwarmUI/ComfyModels" \
-v "$PWD/src/BuiltinExtensions/ComfyUIBackend/CustomWorkflows:/SwarmUI/src/BuiltinExtensions/ComfyUIBackend/CustomWorkflows" \
--gpus=all -p 7801:7801 -p 7821:7821 swarmui $POSTARG
初回起動時はhttp://[PCのIPアドレス]:7801でWebUIを使ったインストーラが起動、終了後、SwarmUIが起動する。ポート7821は、バックエンドで作動するComfyUIを直接操作する用。
起動後、Server→Server Configurationで、各モデルのpathを設定/保存する。たとえば、SDModelFolder: /SwarmUI/ComfyModels/checkpointsといった感じで、/SwarmUI/ComfyModelsの後ろは、ComfyUI/modelsの該当するフォルダ名となる。
LLM用のLM Studioは、普通にWindows側(C:ドライブ)へインストールする。これで環境は整った!
仕上げは!?GeForce RTX 4090(24GB)+eGPU(USB4)接続GeForce RTX 4060 Ti(16GB)でデュアルGPU環境へ!
この状態でしばらく遊んでいたが、GeForce RTX 4060 Ti(16GB)は、VRAM容量はともかくとして、生成時間が普段使っているGeForce RTX 4090(24GB)の4倍ほどかかる(例: FLUX.1 [dev] 25steps + Tea Cache/前段のみを使い5.71秒 vs 24.43秒)。やはり……(笑)。
ということで、GeForce RTX 4090(24GB)へ入れ替えることにした。「へ?600W電源とは言え8ピン×2で大丈夫なの?」と多くの人は思うだろが、メーカーに確認したところGeForce RTX 4090(24GB)はOKとの返事。
GeForce RTX 4090(24GB)のTDPは450W。つまり8ピン×3でピーク時を除けばこと足りる。ドッキングステーションの3スロット対応もこのためだろう。ただしGeForce RTX 5090(32GB)はダメだったとのこと(原因不明)。ここで冒頭に書いた変換ケーブルの登場となる。使ったのは8ピン×2を12VHPWRにするケーブル。もう一方の普通の8ピンから二股ケーブルはもしもの時の予備とした。
OSがGeForce RTX 4090(24GB)を認識しているのを確認後、3DMark / Time Spy完走!スコアは27,598。GeForce RTX 4060 Ti(16GB)が13,284だったので約2倍速となる。
次に先の生成AI画像のPromptやパラメータをまったく同じにして6.53秒。もともと5.71秒だったので0.82秒遅くなっている。これはDockerのオーバーヘッドか?PCIe x16とPCIe x8との差なのか不明。ただ目くじら立てるほどでもない。
ここまで動いてふっと思ったのは、「USB4があるからeGPU Box付くのでは?」だ。試しに外したGeForce RTX 4060 Ti(16GB)を接続したところOK。なんととGeForce RTX 4090(24GB)とGeForce RTX 4060 Ti(16GB)のデュアルGPU環境となった。
ただし、eGPUはThunderbolt 3/40Gbpsなので、OCulink/63Gbpsより遅く、GPUの性能はフルに出ない。それでも良ければ……という感じだ。
生成AI画像(動画)時は両方足してVRAM 40GBにはならないが、たとえばLLMはGeForce RTX 4060 Ti(16GB)、生成AI画像はGeForce RTX 4090(24GB)と、処理に応じて使い分けが可能となる。
またsd-scripts(学習ツール)やLM Studioでは、2つのGPUを合体させVRAMを40GB(24+16GB)として扱うことができる。処理速度は遅い方のGPUになってしまうのが残念なところ。とは言え、LLMはVRAMに乗らないとそもそも動かないので、合算できるだけでもありがたい。
いかがだろうか?ちょっとやり過ぎ感もあるのだが(笑)、PC 1台でここまでできればいろいろ楽しめる。「GTi13 Ultra」の次バージョンは、是非OCuLinkにも対応してほしいところか!?
以上のようにBeelink「GTi13 Ultra」+「Multi-Functional EX Docking Station」を使い、dGPUとしてGeForce RTX 4090(24GB)を接続(PCIe x8)。続いてUSB4を使いeGPU Box + GeForce RTX 4060 Ti(16GB)も追加。デュアルGPUのAI PCが完成した!この原稿を書きながらいろいろ試しているがなかなか快適!
さて、元々GeForce RTX 4090(24GB)が付いていたUbuntu/AI PCは、現在、GPUがなく、単なるPCになっている。Core i7-12650H、メモリ64GB(ただしDDR4)、SSD 512GB+1GB+2TB、電源1,000WのPCを余らすのはもったいない。これに何を入れるのか!?はご想像通り(笑)。入手次第、記事にしてみたい。お楽しみに♪