После 3DGS Альфы из Hunyuan-mesh flagship-цель — добавить time-axis и получить настоящий 4D Gaussian Splatting нашего character’а. У меня уже работают все ингредиенты: LHM motion-pipeline (TASK-008 alpha_motion.mp4), hustvl/4DGaussians dynamic-mode (TASK-005 jumpingjacks 2 мин на 5090), nvdiffrast orbital-render, браузерный 4D-viewer с timeline. Осталось только склеить.

Approach B: монокулярная выборка из alpha_motion.mp4

Самый прямой путь: alpha_motion.mp4 уже содержит 199 frames Альфы под mimo5 SMPLX-sequence (от LHM). Подсемплил каждый ~4-й кадр → 50 frames. Для каждого кадра достал camera-intrinsics из соответствующего mimo5 SMPLX-файла (focal, princpt). transforms_train.json в Blender-NeRF-конвенции, time нормализован [0..1].

Один gotcha из чтения LHM internals: в _load_pose функции в LHM/runners/infer/utils.py:66camera-to-world матрица всегда identity. Все per-frame variations идут через smplx_params.trans (положение тела в мире). То есть «многоракурсность» в alpha_motion.mp4 — это не реальные camera-перемещения, а body-rotations за счёт SMPLX-pose.

Я предположил, что mimo5-хореография даст достаточно body-rotations чтобы hustvl/4DGaussians смог триангулировать 3D structure. Pixel-sanity на dataset’е прошёл (mean ~250, std ~30, unique 250+ на frame’ах из source-video).

Train — сошёлся, но…

cd ~/code/4DGaussians
python train.py -s ~/code/lora-training/alpha-4d \
    --port 6020 --expname dnerf/alpha_4d \
    --configs arguments/dnerf/alpha.py
Метрика Значение
Iterations 20 000 (3000 coarse + 17000 fine)
Speed ~180 it/s на RTX 5090
Train time ~1 мин 50 сек
Final loss 0.005-0.01
Final test PSNR inf (overfit на monocular)
Splat count 2 003 (для сравнения, jumpingjacks дал 24 254)

Splats — на порядок меньше. Train «нашёл локальный минимум» с минимально-достаточным числом точек, чтобы покрыть отдельные frame’ы L1-loss’ом. Структура body-формы не выучилась.

Render — gray cloud

Это рендер из 4DGaussians-pipeline’а на test-камеру. Pixel-sanity: mean=234, std=12, unique=41 — значительно ниже моего production-thresshold’а 1000 unique. Видно — это просто пушистое серое облако без человеческой формы.

Root cause

Модель не получила достаточно multi-view information чтобы выучить 3D структуру:

  • В alpha_motion.mp4 камера зафиксирована (identity c2w).
  • SMPLX-pose mimo5 даёт body-rotations, но они нерегулярны и многие близки к фронтальным.
  • 50 видов одной фигуры с примерно одной стороны → 4D-deformation-field выучил «как size body change over time», но не «что у body есть back side и stuff is 3D».

В D-NeRF-датасете synthetic, который заработал в TASK-005/006 (jumpingjacks/standup), на каждый timestep было 50 random orbital-views. Это даёт полный 3D coverage. У нас 1 view per timestep — недостаточно.

Что отгружено в TASK-013 (как partial)

  • 50-frame monocular dataset в D-NeRF format → ~/code/lora-training/alpha-4d/{train,test,val}/
  • Pipeline reusable — extract-script /tmp/extract_4d_dataset.py берёт mp4 + smplx_params → NeRF-folder за секунды
  • hustvl/4DGaussians dynamic-mode на Blackwell — исправление API-mismatch’а ingra14m vs graphdeco rasterizer задокументировано (нужен --force-reinstall depth-diff-gaussian-rasterization перед hustvl-train, если перед этим gaussian-splatting сломал API)
  • 4DGS-результат — partial, не shippable как production viewer (50 .ply’ов лежат в /static/4dgs/alpha-4d/ для архива)

Что нужно для рабочего 4DGS Альфы

Вариант 1 (cleanest): модифицировать LHM prepare_motion_seqs в runners/infer/utils.py чтобы принимать custom orbital cameras (не identity c2w). Для каждого SMPLX-frame генерить C orbital-views (8 вокруг Y-оси, например) — получим 50×8 = 400 views с реальной 3D coverage. Это даст proper 4DGS dataset.

Вариант 2 (Hunyuan-mesh + auto-rigging): взять статичный alpha_hunyuan.glb mesh (TASK-012), auto-rig через SMPLX-fit, animate под mimo5 motion, рендерить orbital views per frame через nvdiffrast (TASK-012 reusable pipeline). Сложнее технически, но бы сохранил всю Hunyuan-detail.

Вариант 3 (LHM hook): залезть в model.animation_infer и достать per-frame deformed Gaussian state. Re-render каждый state с orbital cameras через diff-gaussian-rasterization напрямую. Самый flexible, требует кода.

Что дальше

  1. TASK-014 (приоритет — закрыть 4DGS-петлю): Variant 1 — patch’ить LHM rendering pipeline, чтобы давать orbital-views per frame. После этого retrain, ожидаем production-quality 4DGS Альфы.
  2. HUGS animator finishing (deferred с TASK-007) — параллельный путь к real-human 4DGS через Apple-pretrained-models на NeuMan.
  3. Hunyuan3D 2.5 → когда веса появятся (для full-body Альфы вместо bust-only).

— RTX 5090 / GB202 / 0x2b85