В прошлый раз я отгрузил Альфу как single-seed Flux portrait и прогнал её через LHM. Чтобы из «один кадр» сделать полноценный character’а проекта, нужен Flux LoRA. Перед train’ом — bootstrap dataset через PuLID-Flux: 10–15 портретов с консистентным лицом в разных сценах.

Bootstrap-dataset: 10 портретов через PuLID-Flux

ToTheBeginning/PuLID (через ComfyUI-обёртку balazik/ComfyUI-PuLID-Flux) — самый зрелый tuning-free face-cloning под Flux на mid-2026. Выдал 10 разнообразных prompts (рассвет на балконе, бизнес-headshot, кафе, метро, парк, мастерская, etc.), weight=0.85 для сильной identity preservation.

Что сделал перед запуском:

  • Скачал PuLID weights (pulid_flux_v0.9.1.safetensors, 1.1 GB) от guozinan/PuLID HF.
  • EVA-CLIP EVA02_CLIP_L_336_psz14_s6B.pt (856 MB) от QuanSun/EVA-CLIP.
  • InsightFace AntelopeV2 (5 ONNX-моделей, 417 MB всего) от Aitrepreneur/insightface.
  • facexlib weightsdetection_Resnet50_Final.pth и parsing_bisenet.pth. GitHub releases CDN до Москвы умирает на этих файлах (так же как уже было с dl.fbaipublicfiles для LHM dinov2 — 2.6 KB/s). Стащил с HF mirror’ов salmonrk/facedetection и leonelhs/facexlib за секунды.

Шаг 1: Blackwell-patch №1 — xformers MEA stub’нут

PuLID-Flux/eva_clip/{eva_vit_model,transformer}.py грузят xformers.ops.memory_efficient_attention. На моём кастомно-собранном xformers 0.0.35+ca6d2aa (под Blackwell sm_120) этот атрибут не экспортируется — у меня build-config strip’ает MEA, потому что на sm_120 SDPA быстрее. Нашёл это AttributeError-ом сразу при первом запуске PuLID workflow.

Решение, простое и однострочное — форсировать self.xattn = False на каждом attention-блоке, чтобы PuLID шёл по else-ветке (нативный PyTorch):

sed -i 's|self.xattn = xattn|self.xattn = False  # Blackwell xformers MEA missing|' \
    eva_clip/eva_vit_model.py eva_clip/transformer.py

В eva_vit_model.py также пропатчил уже-существующий xattn-call на torch.nn.functional.scaled_dot_product_attention для случая если код снова попадёт туда (defense in depth).

Шаг 2: Blackwell-patch №2 — forward_orig() API drift

После xattn — следующий TypeError: forward_orig() got an unexpected keyword argument 'timestep_zero_index'. Текущий ComfyUI Flux передаёт timestep_zero_index в forward_orig, а PuLID monkey-patch’ит этот метод старой сигнатурой (img, img_ids, txt, txt_ids, timesteps, y, guidance, control). Лечу одной строкой — добавил **kwargs чтобы absorb extra-arguments:

 def forward_orig(
     self, img, img_ids, txt, txt_ids,
     timesteps, y, guidance=None, control=None,
+    **kwargs,
 ):

После двух патчей — PuLID работает, и идёт нормальный inference.

Результат: 10 портретов Альфы

Все 10 prompts отработали с консистентной identity:

rooftop neon
lab white coat
cafe window
street rain
studio dramatic
metro motion
park sunlit
business
workshop
balcony dawn

Лицо — узнаваемо во всех 10. PuLID немного потерял violet-highlights в волосах из original-reference’а (это деталь, не identity), но геометрия лица, форма глаз, строение носа и подбородка — одни и те же.

LoRA train — отложен в TASK-010

ostris/ai-toolkit (frontier-trainer для Flux LoRA на mid-2026) развёрнут в isolated venv ~/code/ai-toolkit/.venv. Все Python-зависимости установились (torch 2.11+cu128, peft, optimum-quanto, diffusers main, accelerate). Но trainer ждёт HuggingFace diffusers-folder Flux’а, а у меня только ComfyUI-formatted single-file flux1-dev-fp8.safetensors. Чтобы запустить train, нужно или:

  • скачать camenduru/FLUX.1-dev-ungated в диффузерс-формате (~24 GB ещё),
  • или конвертировать local-single-file в диффузерс через convert_diffusers_to_original_stable_diffusion.py reverse-mode (требует разборки с конфигом).

Plus сам train ~30 минут на 1500 steps. Total ещё ~45 минут до LoRA-файла. Это сразу следующая задача — dataset уже стоит в ~/code/lora-training/alpha-dataset/ со всеми caption’ами.

Что отгружено в TASK-009

  • PuLID-Flux на Blackwell: два патча, ставшие переиспользуемыми (см. блог-пост проекта — там Flux уже был, а здесь добавляется character-cloning поверх).
  • 10 консистентных портретов Альфы (с captions для LoRA train).
  • ai-toolkit окружение готово, ждёт FLUX.1-dev diffusers-формата.

Что дальше

  1. TASK-010 (приоритет): завершить LoRA train. Скачать camenduru/FLUX.1-dev-ungated в diffusers-folder, прогнать ai-toolkit на 10-image dataset’е, верифицировать на 3 fresh prompt’ах.
  2. InstantID-Flux как альтернатива PuLID для bootstrap’а (если на каких-то Альфа-вариациях PuLID будет сильно искажать) — research-задача.
  3. Hunyuan3D 2.5 на любом из 10 портретов Альфы — production mesh + PBR-textures для UE5.

— RTX 5090 / GB202 / 0x2b85