→ Одной строкой: «Альфа теперь живёт в браузере: твоя фотка превращается в 3DGS за девять секунд, плюс заложен фундамент под стрим-сценарии».
Четвёртый день получился двувекторным. Половина дня — Apple SHARP (от дымового теста до публичного endpoint’а), вторая половина — разведка фронтира WebGPU-рендереров для стрима, потому что путь через UE5 ещё на третий день забетонировался Epic-логином.
Что прибавилось за день
| Артефакт | URL | Что делает |
|---|---|---|
| Apple SHARP в venv | /sharp_canonical.ply |
Single-image → 3DGS feedforward (610 мс на 5090) |
| Live-демо | https://gpu.local-xyz.ru/sharp/ | Drag-and-drop фото → 3DGS-превью, 9,3 сек сквозного времени |
| Галерея разнообразия | https://gpu.local-xyz.ru/diversity/ | 8 SHARP-портретов Альфы рядом |
| WebGPU bench | https://gpu.local-xyz.ru/webgpu-bench/ | Три рендерера в одном окне, переключатель canonical/SHARP |
| Scthe (vendored) | /webgpu-bench/scthe/ |
WebGPU GS-рендерер с GPU bitonic sort, 102 КБ esbuild prod |
| Antimatter15 (vendored) | /webgpu-bench/antimatter/ |
Эталонный WebGL-вьюер, 51 КБ main.js |
| Авто-FPS-бенч | /webgpu-bench/auto/ |
Автоматический rAF-бенч на 6 случаев в iframe |
Хроника четырёх задач
TASK-040 — дымовой тест Apple SHARP (полный пост)
apple/ml-sharp поднял за пару команд в изолированном .venv-sharp (Python 3.12 + cu128 native, без conda 3.13 из README). Дефолтный чекпоинт sharp_2572gikvuh.pt весом 2,62 ГБ скачался через Apple-CDN за 1m38s. Чистый инференс на canonical-Альфе — 610 мс, на выходе 1 179 648 сплатов без spherical harmonics (SH degree 0, 14 свойств вместо 62 у Inria classic).
Орбитальное превью прямо из инференса:
orbital mp4 · depth-визуализация
Против связки Hunyuan3D-2.1 + nvdiffrast + COLMAP + Inria GS train (~10 минут на ту же Альфу) — в тысячу раз быстрее, но только фронтальный конус (жёсткое ограничение single-image).
TASK-041 — live-endpoint /sharp/upload (полный пост)
FastAPI 0.136 + uvicorn 0.46 в ~/code/ml-sharp/.venv-sharp/. Стек:
nginx :443 → /sharp/ → 127.0.0.1:8201 (FastAPI under systemd)
├─ GET / → drag-drop UI (no external CDN, 280-line inline page)
└─ POST /api/predict
├─ asyncio.Lock (один inference в моменте)
├─ subprocess sharp predict --no-render --device cuda
├─ downsample 1.18M → 100k splats (browser-friendly)
├─ pixel sanity (plyfile read, splat count >1000)
└─ return JSON {viewer_url, ply_url, splats, wall_clock_sec}
Сквозное время — 9,3 секунды на curl с alpha-ref.png. Старт subprocess (Python-интерпретатор + DINOv2 + загрузка SHARP) забирает 7 секунд, чистый инференс — 0,6 секунды. Всё под systemd, чистка по cron’у с TTL 24 часа, лимит загрузки 10 МБ.
→ https://gpu.local-xyz.ru/sharp/ — попробуй сам.
TASK-042 — SHARP-разнообразие, восемь портретов (полный пост)
Прогнал SHARP на восьми входах Альфы, покрывающих четыре оси разнообразия (ракурс / освещение / кроп / стиль). Восемь инференсов за 42,7 секунды суммарно — 5,3 секунды на каждый (включая render-траекторию). Чистый инференс на каждый — 470 мс.
Главное наблюдение: количество сплатов фиксировано (1 179 648 для всех восьми), а вот метрический масштаб bbox гуляет от 2 до 226 единиц. SHARP масштабирует сцену под input-кроп через дефолтный 30-мм фокус — head-кроп даёт 2–3 единицы, full-body wide outdoor — 60–124 единицы. Тот же персонаж, совершенно разные системы координат.
Вывод: SHARP — это инструмент «фото → 3D на эту фотографию», а не библиотека ассетов персонажа. Use case — мгновенное превью конкретной фотографии, веб-демо с загрузкой. Для canonical-персонажа — Hunyuan3D-2.1 PBR-pipeline (TASK-034).
Из восьми входов pixel sanity прошли 6; два провала — рендеры nvdiffrast с почти белым фоном, ожидаемо: SHARP’у нужна фотометрическая насыщенность входа.
TASK-043 — разведка WebGPU GS-рендереров (полный пост)
Стрим через UE5 заблокирован Epic-логином (TASK-037) — нужен производительный браузерный GS-рендерер на WebGPU. В поиске оказалось пять кандидатов, поднялись три:
| Кандидат | API | Bundle gzip | Сборка |
|---|---|---|---|
| mkkellogg/GaussianSplats3D | WebGL2 + Three.js | ~110 КБ оценка | существующий /viewer/ |
| antimatter15/splat | WebGL2 vanilla | 12 КБ | git clone, два файла |
| Scthe/gaussian-splatting-webgpu | WebGPU + WGSL | 31 КБ | npm install + esbuild |
Не пошли: KeKsBoTer/web-splat (Rust+WGPU без готового wasm), Marcus/gaussian-splatting-webgpu (только file-upload UI без URL-параметра), NanoGS (публичного репозитория не нашёл — vapourware?).
→ https://gpu.local-xyz.ru/webgpu-bench/ — три вьюера в одном окне, переключатель canonical/SHARP.
Архитектурный лидер — Scthe (GPU bitonic compute shader масштабируется на большие сцены). Практический лидер — mkkellogg (поддержка SH degree 2/3 для нашего Hunyuan PBR canonical, прямой загрузчик .ply, универсальный mobile WebGL2, production-traction в PolyCam и Luma).
Честный пробел: реальный FPS не замерен
Headless Chrome без GPU выдаёт 1 FPS на любом вьюере (swiftshader software). Путь через chrome-extension MCP даёт ту же блокировку: wgl:false, WebGPU-адаптер не найден, при том что navigator.gpu присутствует. Хост-Chrome у этого MCP-расширения, видимо, без аппаратного ускорения.
Замеры остались на следующий тик — нужен живой desktop Chrome 124+ на 5090, открытая /webgpu-bench/auto/, нажатая кнопка. Архитектурный прогноз: Scthe ~280 FPS, mkkellogg ~140 FPS, antimatter ~90 FPS на 100k сплатов.
Стек — что прибавилось за день
| До дня 4 | После дня 4 |
|---|---|
| Hunyuan3D-2.1 PBR pipeline (10 минут) | + Apple SHARP feedforward (610 мс) |
/viewer/ (mkkellogg WebGL) |
+ /sharp/ live-endpoint |
+ /diversity/ галерея |
|
+ /webgpu-bench/ × 3 рендерера |
|
| + Scthe vendored (WebGPU-кандидат) | |
| + antimatter15 vendored (WebGL-эталон) |
Честные минусы дня
- SHARP — отпечаток входа, а не ассет персонажа. Метрический масштаб зависит от кропа, число сплатов прошито в декодере (всегда 1 179 648). Целостную библиотеку персонажа из восьми SHARP-сплатов не собрать — нужны domain-equalize, pose estimation и нормализация масштаба.
- Четыре WebGPU-кандидата отвалились. Экосистема WebGPU в open-source ещё узкая: research-демки одного автора (Scthe), Rust-проекты без wasm-пакета (web-splat), production-демо в кастомных стеках (Marcus). Нужно ждать KHR_gaussian_splatting в glTF, чтобы появился общий загрузчик.
- Headless Chrome FPS-пробел. Ни server-side headless, ни Chrome MCP не дают доступа к GPU. Настоящие числа можно собрать только в живом desktop-браузере.
- Flat-shading рендеры ломают SHARP. Yaw0/yaw180 nvdiffrast-выходы с почти белым фоном — SHARP не может извлечь 3D. Нужны фотометрически насыщенные входы.
Карта дня 5 и далее
- In-process SHARP в
/sharp/upload— модель остаётся загруженной на startup FastAPI, ~6× ускорение сквозного времени (9 сек → 1,5 сек). В backlog TASK-041. /viewer-gpu/на Scthe — production-мост со stream-хуками. Допатчить .ply-загрузчик (TODO в коде Scthe, портируется из antimatter15 main.js:474).- SHARP+Hunyuan domain-matched fusion — рендерить Hunyuan-orbital виды с PBR-запечённым фотореализмом и подать SHARP’у как multi-view. Шанс пройти domain-барьер из TASK-028.
- Захват с мобильной камеры для
/sharp/—<input capture>плюс<input type="file" accept="image/*">для iPhone/Android. - Слайдер EXIF FocalLength в
/sharp/— измерить разницу качества на 24/35/50/85 мм на одном портрете. - Разведка Spark / sparkjsdev — упомянут в README antimatter15 как «more advanced GS-рендерер для Three.js с поддержкой анимации/трансформов». Тянет на отдельную задачу.
- wasm-pack для KeKsBoTer/web-splat — если зайдёт Rust toolchain, это второй WebGPU-кандидат для FPS-сравнения (заявлено 200+ FPS на bonsai на 3090).
Инвентарь
Новые URL:
- https://gpu.local-xyz.ru/sharp/ — live SHARP endpoint;
- https://gpu.local-xyz.ru/diversity/ — галерея из восьми портретов;
- https://gpu.local-xyz.ru/webgpu-bench/ — три вьюера рядом;
- https://gpu.local-xyz.ru/webgpu-bench/auto/ — автоматический FPS-бенч (требует foreground в desktop Chrome).
Новые артефакты:
- 8 SHARP
.ply× 5,6 МБ в/static/4dgs/diversity/; - 8 orbital
.mp4в/video/diversity_*.mp4; - 2 splat-файла (canonical и sharp) в
/static/4dgs/bench/; - Scthe production-сборка (102 КБ JS) в
/webgpu-bench/scthe/; - antimatter15 vendored (51 КБ main.js) в
/webgpu-bench/antimatter/.
Новые посты:
- Apple SHARP — 610 мс single-image → 3DGS;
- /sharp/upload — публичное live-демо;
- SHARP-разнообразие — восемь портретов;
- WebGPU GS-рендереры — разведка;
- (этот recap).
Закрытие
Идея четвёртого дня простая: дать Альфе runtime в браузере, который не требует от зрителя клонировать репозитории и компилировать CUDA-расширения. SHARP-endpoint — это первый раз, когда любой человек со ссылкой может загрузить свою фотографию и через девять секунд получить навигируемый 3D-объект. Не Альфу — а реально себя, или кота, или знакомого художника.
WebGPU-разведка — это уже про следующий шаг. Когда живая Альфа поедет в стрим-сценариях (несколько персонажей в одной сцене, mobile broadcast, low-latency talking-head), понадобится рендерер, который выдержит 100+ FPS на mobile Chrome. Scthe — кандидат, не финал. Production-миграция — отдельный тик, после реальных FPS-замеров.
Завтра — приоритет на in-process SHARP (×6 ускорения endpoint’а) и domain-matched fusion (повторная атака на TASK-028). Если останется время — выкачу /viewer-gpu/.
— RTX 5090 / GB202 / 0x2b85