余っていた Radeon RX 7900 XT で、画像1枚から色付きの 3D(GLB)を作る Pixal3D(TencentARC)が ROCm で使えるかを技術検証しました。ただ本家の Python 版には NVIDIA 前提の依存があり、AMD の GPU ではそのままでは動かせません。そこで C++/GGML への移植版 trellis.cpp を HIP でビルドし、重みも自分で GGUF にして動かしました。

結論

  • 本家の Python 版は使いませんでした。NATTEN に ROCm 版が無く、テクスチャの焼き込みに使う nvdiffrast は NVIDIA Source Code License(非商用)だからです。依存とライセンスを調べて決めたことで、実際には動かしていません。
  • trellis.cpp v0.8.1 を -DGGML_HIP=ON -DGGML_HIP_GRAPHS=OFF -DGPU_TARGETS=gfx1100 -DTRELLIS_WEBP=OFF でビルドしました。CPU だけで1分半(218 段)です。
  • 重みは公式の safetensors を取り、trellis.cpp の tools/convert.py で GGUF にしました。GPU を使わず 38 秒で、一式は 14 GB です。
  • RX 7900 XT で、1024・色付き・12 ステップが 105.6〜161.8 秒(5本、平均 125.5 秒)でした。VRAM の最大は 7,763〜8,518 MiB です。

試した環境

  • GPU: Radeon RX 7900 XT(gfx1100、VRAM 20 GB)。NVIDIA の GPU はありません
  • Ubuntu、ROCm 7.2.4。ROCm の開発用ライブラリ(hip・hipBLAS・hipBLASLt・rocBLAS・rocWMMA の CMake 設定とヘッダ)は amdgpu-install --usecase=rocm で入れてあります
  • モデル: Pixal3D(TencentARC)。TRELLIS.2 を画素に揃えて条件づけした fine-tune です

本家の Python 版をやめた理由

本家の Python 版は、AMD で動かせるかの点と、非商用のライセンスの部品がある点で詰まりました。

  • NATTEN に ROCm 版がありません。
  • テクスチャの焼き込みに使う nvdiffrast が、非商用のライセンスです。
  • ComfyUI の組み込み版も、AMD で動いたという報告が見つかりませんでした。
倒木でふさがれた道の脇に架けた新しい橋を、旅人が渡っていく

trellis.cpp は、nvdiffrast の部分を CPU の UV ラスタライザに置き換えています。ビルドしたプログラムと、変換した重みの流れは次のとおりです。

ビルドしたプログラムと変換した重みが合わさる所

trellis.cpp を HIP でビルドする

サーバには cmake と ninja が入っていませんでした。apt は使わず、PyPI の wheel をビルド専用の venv に入れています。

umask 002
python3 -m venv $HOME/venvs/build                 # ビルドの道具だけ
$HOME/venvs/build/bin/pip install --no-cache-dir cmake==3.31.10 ninja==1.13.0

git clone --branch v0.8.1 --depth 1 --recurse-submodules --shallow-submodules \
  https://github.com/pwilkin/trellis.cpp trellis.cpp
export PATH=$HOME/venvs/build/bin:/opt/rocm/bin:/opt/rocm/llvm/bin:$PATH ROCM_PATH=/opt/rocm HIP_PATH=/opt/rocm
cmake -S trellis.cpp -B trellis.cpp/build-hip -G Ninja -DCMAKE_BUILD_TYPE=Release \
  -DGGML_HIP=ON -DGGML_HIP_GRAPHS=OFF -DGPU_TARGETS=gfx1100 \
  -DCMAKE_C_COMPILER=/opt/rocm/llvm/bin/clang -DCMAKE_CXX_COMPILER=/opt/rocm/llvm/bin/clang++ \
  -DCMAKE_HIP_COMPILER=/opt/rocm/llvm/bin/clang++ -DCMAKE_PREFIX_PATH=/opt/rocm -DTRELLIS_WEBP=OFF
cmake --build trellis.cpp/build-hip --target trellis-cli trellis-test-pixal3d trellis-devices -j 16
trellis.cpp/build-hip/trellis-test-pixal3d        # 画角と投影を本家の値と照らす(CPU だけ)

要所は次の3つです。

  • HIP のグラフはビルドの段で切ります(-DGGML_HIP_GRAPHS=OFF)。移植版の ROCm 版リリースと同じ設定です。こうしておけば、README にある GGML_CUDA_DISABLE_GRAPHS=1 は要りません。
  • -DTRELLIS_WEBP=OFF にすると、CMake が libwebp を GitHub に取りに行きません。テクスチャは PNG で出ます。
  • ビルドに GPU は使わず、CPU だけで1分半(218 段)でした。付属の trellis-test-pixal3d は all checks passed でした。

重みを取り、自分で GGUF にする

第三者が配っている GGUF は使わず、公式の safetensors から自分で変換しました。

物役目取り方
Pixal3D(TencentARC/Pixal3D)本体46.1 GB。リビジョンを固定して取る
DINOv3 ViT-L/16画像の読み取りMeta の公式版は手動承認のゲート付きなので、timm のミラー(timm/vit_large_patch16_dinov3.lvd1689m)から取る
BiRefNet(ZhengPeng7/BiRefNet)背景除去既定の RMBG-2.0 は非商用なので、これに替えた
NAF(valeoai/NAF)特徴の拡大GitHub のリリースから取り、sha256 で照合する

取得には 7 分かかりました(47.7 GB)。NAF は次のように照合しています。

curl -fsSL -o naf_release.pth https://github.com/valeoai/NAF/releases/download/model/naf_release.pth
echo 'c096c1ab2217a5c3ac136365f721685e2201379cb69d509cfb0261183847c98f  naf_release.pth' | sha256sum -c -

変換は、CPU 版の torch を入れた変換専用の venv で走らせます。convert.py は <dir>/dinov3 と <dir>/birefnet という並びを読むので、symlink で並べます。

python3 -m venv $HOME/venvs/gguf
$HOME/venvs/gguf/bin/pip install --no-cache-dir numpy==2.5.3 gguf==0.19.0
$HOME/venvs/gguf/bin/pip install --no-cache-dir --index-url https://download.pytorch.org/whl/cpu torch==2.9.1+cpu

L=$HOME/gguf/src-links; mkdir -p $L
ln -sfn <DINOv3 の snapshot> $L/dinov3
ln -sfn <BiRefNet の snapshot> $L/birefnet
TRELLIS_FAMILY=pixal3d PIXAL3D_MODELS=<Pixal3D の snapshot> TRELLIS_MODELS=$L \
  TRELLIS_GGUF_OUT=$HOME/gguf/trellis NAF_CKPT=<naf_release.pth の場所> \
  $HOME/venvs/gguf/bin/python trellis.cpp/tools/convert.py
  • 10 部品で 38 秒、RSS は 2.9 GiB でした。flow は f32 の 5.5 GB が、f16 の GGUF で 2.8 GB になります。一式で 14 GB です。
  • NAF の .pth は torch で読みます。torch 2.9 は既定で weights_only なので、pickle の中のコードは走りません。

動かした結果

ほかのジョブが GPU を使わないようにして、trellis-cli を直に5本回しました(1024・色付き・12 ステップ)。

5本の所要は最短 105.6 秒、平均 125.5 秒、最長 161.8 秒

所要は 105.6〜161.8 秒(平均 125.5 秒)でした。所要は、物の表面の細かさで大きく変わります。キャラクターのパーツ 7 本(16 ステップ・画角 15°)では 175〜793 秒でした。ステップ数も題材も違うので、差のうちどれだけがステップ数によるかは分けて測っていません。この5本では、VRAM の最大は 7,763〜8,518 MiB、RSS の最大は 2.9〜3.06 GiB です。

ただし、出てきた GLB はそのままでは扱いにくい点がありました。仰向けに寝ていること、外から見えない内側の殻が残ること、色が入力より暗く濃く出ることです。どれも、trellis-cli の後に Python で後始末をしています。

確かめていないこと

  • 移植版と本家との数値の突き合わせ(作者もしていないと書いています)。私たちも、本家の Python 版と出力を比べてはいません。
  • 同じ seed でも同じ形にならない理由。同じ入力・seed 42 の2回で、298,094 面と 292,042 面になりました。
  • キャッシュが冷えた状態(GGUF 14 GB の読み込みから)の所要。

おわりに

Pixal3D を AMD の GPU で動かすとき、本家の Python 版は依存とライセンスを調べた段階で使わないと決めましたが、trellis.cpp を HIP でビルドすれば動きました。重みは公式の物から自分で GGUF にすれば、どこから来た重みかを追えます。

※ 各ソフトウェアの ROCm 対応の有無、ライセンス、README の記載は執筆時点の情報で、いまは変わっている可能性があります。