После Hunyuan3D 2.5 mesh с PBR-текстурами — следующая ступенька. Hunyuan даёт нормальный triangle mesh для редактирования в Blender, но «человек» там получается как любой другой объект, без anatomical prior. Для virtual influencer мне нужен именно animatable human avatar — модель, у которой есть SMPLX skeleton под капотом и которая отдаёт 3D Gaussians, прибитые к skinning rig. Это LHM (Tongyi Lab, ICCV 2025) — Large Animatable Human Reconstruction Model.

LHM++ (March 2026) уже на горизонте, но его dependency-стек жёстко прибит к torch 2.3 / cu121, что не работает на Blackwell. Так что начал с оригинального LHM, который удалось завести на нашем cu128 / sm_120.

Что в LHM-500M

  • Input: одна картинка человека.
  • Output: 40000 Gaussian Splats (.ply), параметризованных под SMPLX skeleton — то есть anim-ready.
  • Encoder stack: Dinov2-ViT-L/14 (1.13 GB) + Sapiens-1B + face-ID + BiRefNet (sam2-fork) для parsing.
  • Pose estimator: MultiHMR + ViTPose под капотом.
  • Pipeline: image → BG-mask → pose → encoder fusion → cross-attention DiT-like transformer (5 layers, 1024 dim) → SMPLX-conditioned Gaussian regressor.

Архитектура feed-forward, без diffusion — поэтому такой быстрый inference.

Шаг 1: распаковка весов

Скачал ещё на старте 44 GB tar-архивов с HF (3DAIGC/LHM):

cd ~/code/LHM
tar xf ~/models/lhm/LHM_prior_model.tar       # 18 GB → human_model_files, gagatracker, sapiens, BiRefNet, sam2
tar xf ~/models/lhm/LHM-0.5B.tar              #  8.6 GB → human-lrm-500M/step_060000/
tar xf ~/models/lhm/LHM-1B.tar                # 11 GB → human-lrm-1B/step_060000/

Дополнительно huggingface_hub потом сам скачал config’и под pretrained_models/huggingface/models--3DAIGC--LHM-500M/.

Шаг 2: зависимости на cu128

Использовал существующий ~/comfy/.venv (там уже Blackwell-built torch 2.11/cu128, xformers 0.0.35+ca6d2aa, pytorch3d 0.7.9, torch_scatter 2.1.2+pt211cu128). Установил недостающие LHM Python-пакеты, не трогая torch/xformers:

pip install roma smplx gradio gsplat loguru lpips megfile pyrender decord taming-transformers-rom1504
pip install --no-deps git+https://github.com/XPixelGroup/BasicSR     # фикс torchvision-incompat
pip install gfpgan
pip install pip && pip install --no-build-isolation chumpy           # chumpy 0.70 не объявляет pip как build dep

CUDA-extensions для sm_120 — собрал из source, TORCH_CUDA_ARCH_LIST=12.0, --no-build-isolation:

cd diff-gaussian-rasterization && pip install --no-build-isolation .   # ashawkey fork
cd simple-knn                  && pip install --no-build-isolation .   # camenduru fork
cd sam2                        && pip install --no-build-isolation .   # hitsz-zuoqi modified

Все три собрались чисто, без warning’ов на sm_120.

Шаг 3: серия патчей старого Python кода

LHM требует Python 3.10 в README, но я хочу 3.12 (наш comfy.venv) — в 3.12 удалены/изменены вещи, которые часть LHM-стека ещё использует. Три патча:

1. PyTorch 2.6+ weights_only дефолт (engine/pose_estimation/model.py:51):

- ckpt = torch.load(ckpt_path, map_location=device)
+ ckpt = torch.load(ckpt_path, map_location=device, weights_only=False)

mhmr-checkpoint содержит argparse.Namespace — без weights_only=False PyTorch 2.6+ откажется грузить.

2. chumpy 0.70 — inspect.getargspec удалён в Python 3.11+ (chumpy/ch.py:1203,1246):

- inspect.getargspec(func)
+ inspect.getfullargspec(func)

Нашёл по traceback’у при загрузке FLAME pickle через smplx.

3. chumpy 0.70 — numpy 2.x удалил bool/int/float/str/object/unicode aliases (chumpy/__init__.py:11):

- from numpy import bool, int, float, complex, object, unicode, str, nan, inf
+ from numpy import nan, inf

4. LHM engine/SegmentAPI/SAM.py:476 использует np.float:

- process_img = process_img.astype(np.float) / 255.0
+ process_img = process_img.astype(float) / 255.0

np.float deprecated с numpy 1.20 (2021), удалён давно. Линуксовый pip в LHM-репо тащит pinned numpy==1.23.0, мы на 2.x.

Шаг 4: dl.fbaipublicfiles чудовищно медленный

Первая попытка inference — повисла на 25 минут на загрузке dinov2_vitl14_reg4_pretrain.pth (1.13 GB) с dl.fbaipublicfiles.com. Замерил:

curl --range 0-50000000 dl.fbaipublicfiles.com/...
→ 2.6 KB/s

Геро-CDN от Meta до Москвы фактически заблокирован. У меня канал 10G — 1 GB должен прилетать за секунду. Перевёл на HuggingFace mirror Rayonapp/dinov2:

curl -L --range 0-50000000 https://huggingface.co/Rayonapp/dinov2/...
24 MB/s   # × 9000 быстрее

Скачал через HF\_transfer rust-ускоренный downloader (multi-stream):

pip install "hf-transfer"
HF\_HUB\_ENABLE\_HF\_TRANSFER=1 hf download Rayonapp/dinov2 \
    dinov2_vitl14_reg4_pretrain.pth --local-dir ~/.cache/torch/hub/checkpoints

1.13 GB долетел за пару секунд.

Шаг 5: первый запуск

Запустил в tmux сессии для видимого прогресса:

tmux new -d -s lhm 'cd ~/code/LHM && python -u -m LHM.launch infer.human_lrm \
    model_name=LHM-500M image_input=./test_input \
    export_mesh=True motion_seqs_dir=None motion_img_dir=None \
    vis_motion=false motion_img_need_mask=true 2>&1 | tee /tmp/lhm.log; echo DONE > /tmp/lhm.done'

Тестовая картинка — train_data/example_imgs/00000000_joker_2.jpg (Joker от Хоакина Феникса), 500×500 RGB.

Результат

Wall-clock от первого [2026-05-05 19:06:35] до финального save mesh ... joker.ply: 6 секунд (после того, как все модели уже загружены в RAM/VRAM от предыдущих неудачных запусков).

40000 Gaussian Splats, .ply binary little-endian, 2.72 MB. Формат:

property float x, y, z              # позиции
property float nx, ny, nz           # нормали
property float f_dc_0, f_dc_1, f_dc_2  # diffuse color (без SH harmonics — только DC)
property float opacity              # alpha
property float scale_0, 1, 2        # размер по 3 осям
property float rot_0, 1, 2, 3       # quaternion

Точно совместим с моим существующим viewer’ом из Apple SHARP первого 3DGS.

Скачать .ply (2.72 MB, 40k splats, formatted under SMPLX-X skeleton).

Input image:

LHM input — Joker reference

Что это даёт для virtual-influencer pipeline

Это не просто статичный 3DGS как у SHARP. Точки прибиты к SMPLX skinning rig (под капотом). То есть при наличии motion sequence (./train_data/motion_video/<...>/smplx_params/) можно скормить LHM позу и получить анимированный аватар, рендерящийся из любого ракурса. Сам этот шаг я ещё не делал — следующая задача.

Что дальше

  1. LHM motion inferenceinference.sh с motion_seqs_dir=./train_data/motion_video/mimo6/smplx_params/. Получить animated 3DGS видео.
  2. LHM++ port на Blackwell — March 2026 frontier-релиз, но его deps завязаны на torch 2.3 / cu121 и spconv-cu121. Нужно собирать spconv-cu128 из source или ждать community wheel. На отдельную задачу.
  3. Custom person input — заменить демо-кадр на реальное фото будущего character’а проекта.

— RTX 5090 / GB202 / 0x2b85