TRELLIS.2 auf Turing-GPUs: Image-to-3D mit Quadro RTX 6000

Veröffentlicht: 7. Februar 2026

Microsofts TRELLIS.2 ist aktuell eines der besten Open-Source-Modelle für die Generierung von 3D-Meshes aus einzelnen Bildern. In der 4B-Variante erzeugt es texturierte, UV-gemappte GLB-Dateien in beeindruckender Qualität.

Das Problem: TRELLIS.2 wurde für Ampere-GPUs (SM 8.0+) entwickelt. Turing-GPUs wie die Quadro RTX 6000 (SM 7.5) werden nicht unterstützt — die mitgelieferten CUDA-Kernels crashen mit “no kernel image is available for execution on the device”.

Dieser Artikel dokumentiert, wie ich im Rahmen einer Evaluierung das Modell trotzdem auf meiner RTX 6000 zum Laufen gebracht habe — in einem Podman-Container mit ComfyUI, über zwei Tage und etliche Kernel-Rebuilds hinweg.

Hardware & Ausgangslage

  • Host: HP Z640 Workstation
  • CPU: 2× Intel Xeon E5-2699 v3 @ 2,30 GHz (36 Cores / 72 Threads)
  • RAM: 128 GB ECC DDR4 (2133 MHz)
  • SSD: Samsung 960 Pro NVMe – 512 GB
  • GPU: Quadro RTX 6000, 24 GB VRAM (Turing, SM 7.5)
  • Container: YanWenKun/ComfyUI-Docker, Image cu128-megapak-pt29 (CUDA 12.8 + PyTorch 2.9.1)
  • Custom Node: visualbruno/ComfyUI-Trellis2
  • Modell: TRELLIS.2-4B + DINOv3

ComfyUI-Trellis2 liefert vorgebaute Python-Wheels für die CUDA-Extensions mit. Diese Wheels sind allerdings nur für SM 8.0+ (Ampere) bzw. SM 12.0 (Blackwell) kompiliert. Auf einer Turing-GPU bleiben genau zwei Optionen: neue GPU kaufen — oder die Kernels selbst rebuilden.

Das Problem im Detail

TRELLIS.2 nutzt sechs CUDA-Extension-Pakete, die jeweils als vorgebaute .so-Dateien ausgeliefert werden:

PaketFunktionSM im Wheel
nvdiffrastDifferentiable RenderingSM 8.6+
cumeshMesh-Operationen + BVHSM 12.0
nvdiffrec_renderRender UtilitiesSM 12.0
o_voxelVoxel-Operationen, HashmapSM 12.0
flex_gemmSparse Convolution, Grid SamplingSM 12.0
spconvSparse Convolution BackendSM 8.0+

Keine einzige davon läuft auf SM 7.5. Ein cuobjdump --list-elf auf den .so-Dateien zeigt das deutlich:

ELF file 1: cumesh._C.cpython-312.1.sm_120.cubin

Kein sm_75 — kein Start.

Die Lösung: 6 CUDA-Kernel-Rebuilds

Schritt 1: Container-Setup

Die podman-compose.yaml nutzt das cu128-megapak-pt29-Image, das PyTorch 2.9.1 mit CUDA 12.8 mitbringt — exakt die Version, gegen die auch die Trellis2-Wheels gebaut sind:

services:
  comfyui:
    image: docker.io/yanwk/comfyui-boot:cu128-megapak-pt29
    container_name: comfyui
    devices:
      - nvidia.com/gpu=all
    ports:
      - "8188:8188"
    volumes:
      - ./storage:/root
      - ./storage-models/models:/root/ComfyUI/models
      - ./storage/sm75-overrides:/run/sm75-overrides:ro
    environment:
      CLI_ARGS: "--listen 0.0.0.0 --preview-method auto"
      SPARSE_CONV_BACKEND: "flex_gemm"
    restart: unless-stopped
    shm_size: "32g"

Wichtig: SPARSE_CONV_BACKEND: "flex_gemm" — dazu später mehr.

Schritt 2: pre-start.sh — Dependencies & Patches

Das ComfyUI-Docker-Image führt beim Start automatisch storage/user-scripts/pre-start.sh aus. Hier passiert die gesamte Trellis2-Konfiguration:

Die wichtigsten Schritte:

bf16 → fp16 Mapping: Turing hat keine native bfloat16-Unterstützung. Ein einfacher sed-Patch im Trellis2-Quellcode mappt alle bf16-Operationen auf fp16:

sed -i "s/'bf16': torch.bfloat16/'bf16': torch.float16/" \
  /root/ComfyUI/custom_nodes/ComfyUI-Trellis2/trellis2/modules/utils.py

OpenCV-Konflikt: open3d installiert opencv-python-headless, das mit der Containerversion kollidiert. Die Lösung ist opencv-contrib-python-headless — es bringt alle Module mit (inklusive cv2.inpaint für die Textur-Nachbearbeitung) und hat keine Qt-Abhängigkeiten. Entscheidend: die Installation muss nach allen anderen pip-Installationen erfolgen.

SM 7.5 Kernel-Overrides: Die selbst gebauten .so-Dateien werden beim Start aus einem Read-Only-Volume in die Site-Packages kopiert.

Schritt 3: CUDA-Kernels rebuilden

Das ist der aufwändige Teil. Jedes Paket hat eigene Besonderheiten.

nvdiffrast

Am einfachsten — hat ein sauberes setup.py:

git clone https://github.com/NVlabs/nvdiffrast.git /tmp/nvdiffrast_src
cd /tmp/nvdiffrast_src
TORCH_CUDA_ARCH_LIST="7.5" pip install . --force-reinstall --no-deps --no-build-isolation

Achtung: nvdiffrast installiert zwei .so-Dateien — torch/_C.so und _nvdiffrast_c.so (C-Backend). Beide müssen ersetzt werden.

cumesh

Braucht einen kleinen Patch in der setup.py — die nvcc-Flags --expt-relaxed-constexpr und --extended-lambda fehlen für den cubvh-Submodule:

git clone --recursive https://github.com/JeffreyXiang/CuMesh.git /tmp/CuMesh
cd /tmp/CuMesh
# In setup.py nach "-std=c++17" einfügen:
#   "--expt-relaxed-constexpr", "--extended-lambda"
TORCH_CUDA_ARCH_LIST="7.5" pip install . --force-reinstall --no-deps --no-build-isolation

nvdiffrec_render

Der Quellcode liegt im nvdiffrec-Repository unter render/renderutils. Ein Mini-setup.py mit CUDAExtension reicht:

git clone https://github.com/NVlabs/nvdiffrec.git /tmp/nvdiffrec
cd /tmp/nvdiffrec/render/renderutils
TORCH_CUDA_ARCH_LIST="7.5" python3 setup.py build_ext --inplace

o_voxel — der knifflige Teil

Die Quelle liegt nicht im ComfyUI-Trellis2-Repository, sondern im offiziellen TRELLIS.2-Repo von Microsoft:

git clone --depth 1 https://github.com/microsoft/TRELLIS.2.git /tmp/TRELLIS.2
cd /tmp/TRELLIS.2/o-voxel
git clone --depth 1 https://gitlab.com/libeigen/eigen.git third_party/eigen
TORCH_CUDA_ARCH_LIST="7.5" pip install . --force-reinstall --no-deps --no-build-isolation

Fallstrick: Die TRELLIS.2-Repo-Version von o_voxel ist älter als die im ComfyUI-Wheel. Ihr fehlt die Funktion tiled_flexible_dual_grid_to_mesh. Die Lösung: erst das originale Wheel installieren (für die Python-Dateien), dann nur die .so überschreiben:

# 1. Original-Wheel installieren (Python-Dateien)
pip install /root/ComfyUI/custom_nodes/ComfyUI-Trellis2/wheels/Linux/Torch291/o_voxel-*.whl
# 2. Nur die .so ersetzen
cp /tmp/TRELLIS.2/o-voxel/build/lib.*/o_voxel/_C*.so \
   /usr/local/lib64/python3.12/site-packages/o_voxel/

flex_gemm — Header-Rekonstruktion

Der härteste Brocken. Das flex_gemm-Wheel liefert die .cu-Quelldateien mit, aber keine Header-Dateien. Ohne api.h, hash.cuh, grid_sample.h und neighbor_map.h kann man nicht kompilieren.

Die Lösung: Header aus zwei Quellen rekonstruieren:

  1. hash/api.h und hash/hash.cuh — identisch mit den Dateien im o_voxel-Quellcode (gleiche Codebasis)
  2. grid_sample/api.h, spconv/api.h — aus den Funktionssignaturen in den .cu-Dateien abgeleitet

Dabei ist Präzision gefragt: torch::Tensor vs. torch::Tensor& vs. const torch::Tensor& muss exakt stimmen, sonst gibt es undefined symbol-Fehler beim Linken.

# Header von o_voxel kopieren
cp /tmp/TRELLIS.2/o-voxel/src/hash/api.h $FGSRC/hash/
cp /tmp/TRELLIS.2/o-voxel/src/hash/hash.cuh $FGSRC/hash/

# grid_sample/api.h manuell erstellen (Signaturen aus grid_sample.cu)
cat > $FGSRC/grid_sample/api.h << 'EOF'
#pragma once
#include <torch/extension.h>
torch::Tensor hashmap_build_grid_sample_3d_nearest_neighbor_map(
    torch::Tensor& hashmap_keys, torch::Tensor& hashmap_vals,
    const torch::Tensor& coords, const torch::Tensor& grid,
    const int W, const int H, const int D);
// ... weitere Signaturen
EOF

# Bauen
TORCH_CUDA_ARCH_LIST="7.5" python3 setup.py build_ext --inplace

Die vollständigen Build-Anweisungen für flex_gemm stehen als Kommentar in der pre-start.sh.

Schritt 4: Overrides persistieren

Alle gebauten .so-Dateien werden auf dem Host gesichert:

storage/sm75-overrides/
├── cumesh_C.so
├── cumesh_cubvh.so
├── flex_gemm_cuda.so
├── nvdiffrast_c.so
├── nvdiffrec_render_C.so
└── o_voxel_C.so

Das Verzeichnis wird als Read-Only-Volume in den Container gemountet. Beim Start kopiert pre-start.sh die Dateien an die richtigen Stellen in site-packages.

flex_gemm vs. spconv

TRELLIS.2 unterstützt zwei Sparse-Convolution-Backends: flex_gemm (Standard) und spconv. Anfangs hatte ich auf spconv gewechselt, weil flex_gemm SM 7.5 nicht unterstützte. Das führte zu fragmentierten Meshes — Punktwolken statt zusammenhängender Oberflächen.

Nach dem erfolgreichen flex_gemm-Rebuild konnte ich zum Original-Backend zurückkehren. Seitdem sind die Meshes sauber.

Fazit: flex_gemm ist das bessere Backend für TRELLIS.2. Wenn eure GPU es nicht von Haus aus unterstützt, rebuildet es — wechselt nicht auf spconv.

Empfohlene Workflow-Settings

Für Turing-GPUs mit 24 GB VRAM empfehle ich diese Einstellungen im ComfyUI-Workflow:

Parameter~2 Min
pipeline_type512
sparse_structure_resolution32
sparse_structure_steps10
shape_steps10
texture_steps10
max_views4
target_face_num300.000
texture_size2048
dual_contouring_resolution1024

Von 1024_cascade als pipeline_type rate ich auf Turing ab — der doppelte Sampling-Pass dauert extrem lang und die fp16-Approximation verursacht Qualitätsverluste.

Ergebnis

Nach zwei Tagen Debugging, 6 Kernel-Rebuilds und einer Header-Rekonstruktion generiert TRELLIS.2-4B jetzt texturierte 3D-Meshes auf der Quadro RTX 6000, je nach Settings in einem Zeitrahmen zwischen etwa 2 und 30 Minuten. Nicht schnell, aber es funktioniert — und die Mesh-Qualität ist überraschend gut für fp16 auf einer 7 Jahre alten Architektur.

Dateien

Die beiden zentralen Konfigurationsdateien:

  • podman-compose.yaml — Container-Setup mit GPU-Zugriff und SM 7.5 Override-Volume
  • pre-start.sh — Dependencies, bf16-Patch, OpenCV-Fix und CUDA-Kernel-Override-Logik, inklusive vollständiger Rebuild-Anleitung als Kommentar

Fazit

Mit etwas Geduld und einem C++-Compiler lässt sich aktuelle KI-Software auch auf älterer Hardware zum Laufen bringen. Die Quadro RTX 6000 mit ihren 24 GB VRAM ist nach wie vor eine brauchbare Karte für lokale AI-Workloads — man muss nur bereit sein, ein paar Kernel selbst zu kompilieren.

Die größte Erkenntnis: Prebuilt Wheels sind bequem, aber sie schließen Hardware aus. Wer die Quellen hat, kann fast alles portieren. Und wenn die Header fehlen, liest man halt die Funktionssignaturen aus den .cu-Dateien.

 Weitere Posts