Hunyuan3D 2.1 внутри Docker на Nvidia DGX Spark
Nvidia DGX Spark — компактная рабочая станция с GPU. В этой статье я расскажу о своём опыте работы с этой железкой и покажу, как запустить Hunyuan3D 2.1 в Docker на этой платформе.
Но сначала короткое вступление.
Почему DGX Spark?¶
С момента перехода Apple на процессоры Apple Silicon я полностью переключился с Windows на macOS. Чипы Apple используют унифицированную архитектуру памяти (UMA) — CPU и GPU работают с общей памятью до 128 ГБ. Однако большая часть AI-софта написана под CUDA, и не всё удаётся запустить на Mac, поскольку не все библиотеки портированы под Metal.
DGX Spark — это не замена MacBook, а дополнение. Модуль берёт на себя задачи AI/ML с CUDA-зависимыми библиотеками, не расходуя ресурсы основной машины.
Вопрос цены¶
Стоит ли это своих денег? Безусловно, это недешёвое решение. Моя конфигурация обошлась в €4180 с доставкой в Испанию за несколько дней. Но давайте сравним с альтернативами на Windows (цены в Испании на 30 ноября 2025 года из интернет-магазинов, округлены):
- PNY RTX PRO 6000 Blackwell (96 ГБ GDDR7) — около €8500
- Nvidia RTX PRO 5000 Blackwell (48 ГБ GDDR7) — около €5500
DGX Spark за €4000 с полноценной поддержкой CUDA выглядит разумным компромиссом. Я ждал эту железку с марта 2025 года — и не разочаровался.
Особенности сборки на DGX Spark¶
Запуск Hunyuan3D 2.1 на DGX Spark сопряжён с несколькими техническими особенностями:
-
Версия Python. DGX Spark поставляется с новой версией Python, но Hunyuan3D 2.1 (и Blender) требуют Python 3.10. Пакеты из deadsnakes не подошли, поэтому пришлось собирать Python 3.10.19 из исходников.
-
ARM-архитектура. DGX Spark использует ARM-процессор, и для некоторых библиотек нет готовых wheel-пакетов. В частности, Blender Python API (bpy) необходимо собирать вручную.
-
Dependency hell. Для решения проблем с зависимостями я использую небольшой форк Hunyuan3D 2.1, в котором изменены только requirements.txt.
Всё это можно делать без Docker, устанавливая зависимости прямо в систему. Я не рекомендую этот путь — придётся установить большое количество пакетов, что может привести к конфликтам.
Docker Compose¶
Конфигурация Docker Compose проста. Она пробрасывает порт 7860 для Gradio UI и предоставляет контейнеру доступ ко всем GPU:
services:
hy3d:
build: .
container_name: hy3d
ports:
- "7860:7860"
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
environment:
NVIDIA_VISIBLE_DEVICES: all
NVIDIA_DRIVER_CAPABILITIES: compute,utility
working_dir: /workspace/Hunyuan3D-2.1
tty: true
stdin_open: true
После запуска интерфейс будет доступен по адресу http://spark-XXNN.local:7860/ (где XXNN — идентификатор вашего DGX Spark).
Пошаговая сборка образа¶
Базовый образ¶
Для работы с CUDA используем официальный образ Nvidia с CUDA 13.0 и Ubuntu 24.04:
Образ nvcr.io/nvidia/cuda:13.0.1-devel-ubuntu24.04 содержит CUDA toolkit и development-инструменты. DEBIAN_FRONTEND=noninteractive отключает интерактивные запросы при установке пакетов.
Зависимости для сборки Python¶
Устанавливаем базовые инструменты и библиотеки, необходимые для сборки Python 3.10.19 из исходников:
apt-get update && apt-get install -y --no-install-recommends \
git ca-certificates curl wget build-essential \
libssl-dev zlib1g-dev libbz2-dev libsqlite3-dev libffi-dev liblzma-dev \
&& rm -rf /var/lib/apt/lists/*
Эти библиотеки обеспечивают поддержку SSL, сжатия и других базовых функций Python. Они необходимы для работы Hunyuan и сборки bpy.
Библиотеки для OpenGL и X11¶
Для работы с 3D-моделями и headless-рендеринга устанавливаем OpenGL и X11, переменная окружения QT_QPA_PLATFORM=offscreen переключает Qt в режим без графического интерфейса:
apt-get update && apt-get install -y --no-install-recommends \
libopengl0 libgl1 libglx0 libglu1-mesa \
libx11-6 libxext6 libxrender1 libxi6 \
libxxf86vm1 libxfixes3 libxkbcommon0 libxcb1 \
&& rm -rf /var/lib/apt/lists/*
ENV QT_QPA_PLATFORM=offscreen
Сборка Python 3.10.19¶
Загружаем исходники Python 3.10.19 и собираем с оптимизациями:
cd /opt
wget https://www.python.org/ftp/python/3.10.19/Python-3.10.19.tgz
tar -xvf Python-3.10.19.tgz
cd Python-3.10.19
./configure --enable-optimizations
make -j"$(nproc)"
make altinstall
make altinstall устанавливает Python в /usr/local/bin/python3.10 без перезаписи системного Python. После установки очищаем временные файлы:
Виртуальное окружение¶
Создаём виртуальное окружение в /opt/py310 и обновляем pip, Делаем это окружение окружением по умолчанию:
/usr/local/bin/python3.10 -m venv /opt/py310
/opt/py310/bin/python -m ensurepip --upgrade
/opt/py310/bin/python -m pip install --upgrade pip setuptools wheel
ENV PATH="/opt/py310/bin:${PATH}"
Зависимости для Blender¶
Blender требует множество библиотек для работы с аудио, изображениями и 3D:
apt-get update && apt-get install -y --no-install-recommends \
cmake autoconf automake bison libtool yasm tcl ninja-build meson patchelf \
libopenal-dev libsndfile1-dev libjack-dev libpulse-dev \
libjpeg-dev libpng-dev libtiff-dev libopenexr-dev \
libepoxy-dev libfreetype6-dev libopenimageio-dev libboost-all-dev \
pkg-config libpugixml-dev libfftw3-dev \
libembree-dev libvulkan-dev libshaderc-dev \
libglib2.0-dev libcurl4-openssl-dev subversion \
&& rm -rf /var/lib/apt/lists/*
Перед сборкой Blender устанавливаем NumPy — он нужен для генерации Python API:
Сборка Blender Python API¶
Клонируем репозиторий Blender версии 4.0.2:
mkdir -p /workspace/blender_dev
cd /workspace/blender_dev
git clone https://projects.blender.org/blender/blender.git
cd blender
git fetch --all --tags
git checkout v4.0.2
git submodule update --init --recursive
Конфигурируем сборку через CMake для создания Python-модуля без GUI:
mkdir -p /workspace/blender_dev/build_bpy
cd /workspace/blender_dev/build_bpy
cmake ../blender \
-DWITH_PYTHON_MODULE=ON \
-DWITH_PYTHON_INSTALL=OFF \
-DWITH_HEADLESS=ON \
-DWITH_OPENAL=OFF \
-DWITH_LIBS_PRECOMPILED=OFF \
-DWITH_SYSTEM_GLIB=ON \
-DWITH_SYSTEM_CURL=ON \
-DPYTHON_EXECUTABLE=/opt/py310/bin/python \
-DCMAKE_BUILD_TYPE=Release
make -j"$(nproc)"
Ключевые параметры:
- WITH_PYTHON_MODULE=ON — собираем bpy как Python-модуль
- WITH_HEADLESS=ON — без GUI
- PYTHON_EXECUTABLE — указываем путь к нашему Python 3.10
Добавляем bpy в PYTHONPATH:
ENV BLENDER_SYSTEM_SCRIPTS="/workspace/blender_dev/blender/scripts"
ENV BLENDER_SYSTEM_DATAFILES="/workspace/blender_dev/blender/release/datafiles"
ENV PYTHONPATH="${PYTHONPATH}:/workspace/blender_dev/build_bpy/bin"
Клонирование проекта¶
Клонируем форк Hunyuan3D 2.1 с исправленными зависимостями, либо можете исправить зависимости сами я убрал версию у pymeshlab и xatlas, там доступна единственная версия, не та что в оригинале. А также убрал bpy тк мы его будем собирать сами.
Установка PyTorch¶
Устанавливаем PyTorch с поддержкой CUDA 13.0:
Для ускорения загрузки моделей с Hugging Face используем расширение hf_xet:
Зависимости проекта¶
Далее все похоже на инструкцию в репозитории.
Устанавливаем остальные зависимости из requirements.txt:
Настройка CUDA¶
Создаём симлинк на python3-config, необходимый для компиляции CUDA-расширений. Это важный шаг,
без него differentiable renderer не собертся:
Настраиваем переменные окружения для CUDA:
ENV CUDA_HOME=/usr/local/cuda-13.0
ENV PATH="$CUDA_HOME/bin:${PATH}"
ENV LD_LIBRARY_PATH="$CUDA_HOME/lib64:${LD_LIBRARY_PATH}"
ENV TORCH_CUDA_ARCH_LIST="12.1+PTX"
TORCH_CUDA_ARCH_LIST="12.1+PTX" указывает архитектуру GPU для компиляции CUDA-кода.
Если собираете без докера - вам это не понадобится, тк архитектура определится автоматически
Компиляция CUDA-модулей¶
Собираем custom rasterizer:
Компилируем differentiable renderer:
Загрузка весов ESRGAN¶
Загружаем предобученные веса для апскейлинга текстур:
mkdir -p hy3dpaint/ckpt
wget https://github.com/xinntao/Real-ESRGAN/releases/download/v0.1.0/RealESRGAN_x4plus.pth -P hy3dpaint/ckpt
Запуск приложения¶
Пробрасываем порт для Gradio UI:
Запускаем приложение с предзагрузкой необходимых библиотек для ARM-архитектуры:
LD_PRELOAD="/usr/lib/aarch64-linux-gnu/libgobject-2.0.so.0:/usr/lib/aarch64-linux-gnu/libcurl.so.4:/usr/lib/aarch64-linux-gnu/libnghttp2.so.14" \
python gradio_app.py --host 0.0.0.0 --port 7860
LD_PRELOAD решает проблемы с загрузкой зависимостей.
Это костыль, как и многое другое в этом гайде. Но избавиться от него у меня пока не получилось.
Когда мы собирали блендер он использовал одну версию либ, а растеризатор другую.
Итоговый Dockerfile¶
Полный Dockerfile со всеми шагами:
FROM nvcr.io/nvidia/cuda:13.0.1-devel-ubuntu24.04
ARG DEBIAN_FRONTEND=noninteractive
# PYTHON SETUP
## 1) Install build dependencies for Python 3.10.19 and helper utilities
RUN apt-get update && apt-get install -y --no-install-recommends \
git ca-certificates curl wget build-essential \
libssl-dev zlib1g-dev libbz2-dev libsqlite3-dev libffi-dev liblzma-dev \
&& rm -rf /var/lib/apt/lists/*
## 2) OpenGL/X11 libraries required for pymesh3d (PLY) and headless rendering
# Note: For arm64 (aarch64) Ubuntu/Debian, package names are the same.
RUN apt-get update && apt-get install -y --no-install-recommends \
libopengl0 \
libgl1 \
libglx0 \
libglu1-mesa \
libx11-6 \
libxext6 \
libxrender1 \
libxi6 \
libxxf86vm1 \
libxfixes3 \
libxkbcommon0 \
libxcb1 \
&& rm -rf /var/lib/apt/lists/*
ENV QT_QPA_PLATFORM=offscreen
## 3) Build and install Python 3.10.19 from source (altinstall -> /usr/local/bin/python3.10)
# Reason: Blender build and Hunyuan3D 2.1 target Python 3.10.
RUN set -eux; \
cd /opt; \
wget https://www.python.org/ftp/python/3.10.19/Python-3.10.19.tgz; \
tar -xvf Python-3.10.19.tgz; \
cd Python-3.10.19; \
./configure --enable-optimizations; \
make -j"$(nproc)"; \
make altinstall; \
/usr/local/bin/python3.10 --version; \
cd /; \
rm -rf /opt/Python-3.10.19 /opt/Python-3.10.19.tgz
## 4) Install NumPy (required to build Blender/bpy)
RUN /usr/local/bin/python3.10 -m pip install --no-cache-dir numpy
## 5) Create a virtual environment and upgrade pip/setuptools/wheel
RUN /usr/local/bin/python3.10 -m venv /opt/py310 \
&& /opt/py310/bin/python -m ensurepip --upgrade \
&& /opt/py310/bin/python -m pip install --upgrade pip setuptools wheel
## 6) Use the virtual environment (/opt/py310) by default
ENV PATH="/opt/py310/bin:${PATH}"
# BLENDER BUILD
## 1) Install packages for building Blender and its dependencies
RUN rm -rf /var/lib/apt/lists/* \
&& apt-get update -o Acquire::Retries=5 -o Acquire::http::No-Cache=true \
&& apt-get -y upgrade \
&& apt-get install -y --no-install-recommends \
cmake autoconf automake bison libtool yasm tcl ninja-build meson patchelf \
libopenal-dev libsndfile1-dev libjack-dev libpulse-dev \
libjpeg-dev libpng-dev libtiff-dev libopenexr-dev \
libepoxy-dev libfreetype6-dev \
libopenimageio-dev libboost-all-dev \
pkg-config libpugixml-dev libfftw3-dev \
libembree-dev libvulkan-dev libshaderc-dev \
libglib2.0-dev libcurl4-openssl-dev \
subversion \
&& rm -rf /var/lib/apt/lists/*
## 2) Install NumPy in the current venv (headers required to build bpy)
RUN pip install --no-cache-dir numpy
## 3) Clone Blender 4.0.2 and initialize submodules
RUN mkdir -p /workspace/blender_dev \
&& cd /workspace/blender_dev \
&& git clone https://projects.blender.org/blender/blender.git \
&& cd blender \
&& git fetch --all --tags \
&& git checkout v4.0.2 \
&& git submodule update --init --recursive
## 4) Build bpy (headless) using Python 3.10 from the venv
## Debug tip: verbose output is enabled; for troubleshooting, rebuild with make -j1 to surface the first real error.
RUN mkdir -p /workspace/blender_dev/build_bpy \
&& cd /workspace/blender_dev/build_bpy \
&& cmake ../blender \
-DWITH_PYTHON_MODULE=ON \
-DWITH_PYTHON_INSTALL=OFF \
-DWITH_HEADLESS=ON \
-DWITH_OPENAL=OFF \
-DWITH_LIBS_PRECOMPILED=OFF \
-DWITH_SYSTEM_GLIB=ON \
-DWITH_SYSTEM_CURL=ON \
-DPYTHON_EXECUTABLE=/opt/py310/bin/python \
-DCMAKE_VERBOSE_MAKEFILE=ON \
-DCMAKE_BUILD_TYPE=Release \
&& make -j"$(nproc)"
## 5) Make bpy available in all container sessions
ENV BLENDER_SYSTEM_SCRIPTS="/workspace/blender_dev/blender/scripts"
ENV BLENDER_SYSTEM_DATAFILES="/workspace/blender_dev/blender/release/datafiles"
ENV PYTHONPATH="${PYTHONPATH}:/workspace/blender_dev/build_bpy/bin"
# END OF BLENDER BUILD
# PROJECT SETUP AND BUILD
## 1) Clone the repository (DGX fork)
RUN git clone -b DGX-Spark https://github.com/dr-vij/Hunyuan3D-2.1-DGX /workspace/Hunyuan3D-2.1
WORKDIR /workspace/Hunyuan3D-2.1
## 2) Install Python dependencies (PyTorch CUDA 13.0 build first)
RUN pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu130
## 3) Speed up model downloads (Hugging Face with xet)
RUN pip install --no-cache-dir -U "huggingface_hub[hf_xet]"
## 4) Install project dependencies
RUN pip install -r requirements.txt
## 5) Ensure python3-config symlink in the venv (required for custom_rasterizer/DifferentiableRenderer)
# Create/update: /opt/py310/bin/python3-config -> /usr/local/bin/python3.10-config
RUN ln -sf /usr/local/bin/python3.10-config /opt/py310/bin/python3-config
## 6) Set CUDA environment (adjust CUDA version and arch as needed)
# DGX Spark uses CUDA 13.0 and arch "12.1+PTX".
ENV CUDA_HOME=/usr/local/cuda-13.0
ENV PATH="$CUDA_HOME/bin:${PATH}"
ENV LD_LIBRARY_PATH="$CUDA_HOME/lib64:${LD_LIBRARY_PATH}"
ENV TORCH_CUDA_ARCH_LIST="12.1+PTX"
## 7) Build and install hy3dpaint custom rasterizer
RUN bash -lc "cd hy3dpaint/custom_rasterizer && pip install -e . --no-build-isolation"
## Note: If this fails, verify that python3.10-config is correct.
## 8) Compile the differentiable renderer
RUN bash -lc "cd hy3dpaint/DifferentiableRenderer && bash compile_mesh_painter.sh"
## 9) Download ESRGAN weights
RUN mkdir -p hy3dpaint/ckpt \
&& wget https://github.com/xinntao/Real-ESRGAN/releases/download/v0.1.0/RealESRGAN_x4plus.pth -P hy3dpaint/ckpt
# RUNTIME
## 1) Expose port for the Gradio UI
# You can connect to your Spark later via http://spark-XXNN.local:7860/ (replace XXNN with your Spark ID)
EXPOSE 7860
## 2) Start the Gradio application on container startup
# Assumes gradio_app.py is located at /workspace/Hunyuan3D-2.1
# LD_PRELOAD is added for correct dependency loading on aarch64
CMD bash -lc "cd /workspace/Hunyuan3D-2.1 && \
LD_PRELOAD=\"/usr/lib/aarch64-linux-gnu/libgobject-2.0.so.0:/usr/lib/aarch64-linux-gnu/libcurl.so.4:/usr/lib/aarch64-linux-gnu/libnghttp2.so.14\" \
python gradio_app.py --host 0.0.0.0 --port 7860"
# I spent 8+ hours setting this up, with help from Google Search and JetBrains Junie
LABEL authors="dr-vij (Viktor Grigorev)"
Соберите и запустите контейнер:
Откройте интерфейс в браузере: http://spark-XXNN.local:7860/ (замените XXNN на ваш Spark ID)
Ссылки¶
Полный код, включая Docker Compose и Dockerfile, доступен в репозитории: Hunyuan3D-2.1-DGX-Docker