- BrainTools - https://www.braintools.ru -
Я больше двадцати лет отработала ретушёром и четвёртый год пытаюсь натянуть сову на глобус, заставить диффузионки нормально работать с профессиональными кадрами на 40+ мегапикселей. Все эти годы любой подход крутится вокруг тайлов. Это первая статья из цикла. Три идеи, ресерч, предварительные тесты.
Мир ретуши не сводится к картинкам в 2048 пикселей по стороне. Профессиональные камеры до сих пор делают огромные файлы. Сорок мегапикселей, шестьдесят, сто, иногда сто пятьдесят. И весь этот объём всё так же требует ретуши, кожа, волосы, цвет, свет, чистка фона. Как было десять лет назад, так и сейчас. Никуда задача не ушла. Подход к этим кадрам везде один и тот же. Режем картинку на тайлы, обрабатываем по кусочку, склеиваем обратно. Кто-то делает это аккуратнее, кто-то нет. Но проблема одна на всех, границы между тайлами и модель которая не понимает что она видит. Перед моделью при генерации кусочек чего-то. Чего именно? Никто не знает. И вот это – настоящая проблема. Хочется чтобы тайлы шли гладко, без видимых швов. И чтобы модель понимала, с чем она вообще имеет дело, что вот тут кожа, тут волосы, тут небо, тут металл с отражением. Не «обработай 512×512 пикселей». А «обработай вот эту часть портрета, рядом, щека, выше, волосы». В этой статье я хочу выложить три идеи. Я сделала несколько ресерч-сессий и не нашла, чтобы кто-то системно смотрел в эту сторону. То ли я плохо искала. То ли действительно дыра в литературе. Возможно и то, и другое. Сейчас, теория, ресерч, предварительные тесты. Давайте приступим.
Сразу про термин. Дальше по тексту я буду называть «фото-моделью» обычную image-to-image диффузионку, SDXL, FLUX, Klein, SANA, что угодно из стандартного набора. Технически это reverse-diffusion с UNet’ом или DiT’ом. Договорились, “фото-модель”, поехали. В видео-диффузии решают похожую задачу. Только там «соседние сущности», это кадры, у нас это тайлы рядом стоящие. Когда видео-модель генерирует, скажем, восемнадцатый кадр, она видит не только восемнадцатый. Она помнит про семнадцатый, шестнадцатый, какие-то ключевые ранние, иногда самый первый. Эта память [1] живёт внутри архитектуры, в форме self-attention поверх временной оси, в форме accumulated state, в форме KV-cache между чанками. И благодаря ей у нас на видео не дёргается фон, не плывёт цвет, не меняется освещение между кадрами. У нашей фото-модели в момент обработки тайла (3, 5) этой памяти нет. Она получает свой кусок пикселей и текстовый prompt. Всё. Ни соседнего тайла слева, ни тайла сверху, ни общего понимания, что это вообще одна картинка. Если перенести механизм памяти из видео-генерации на пространственный тайлинг, теоретически можно решить и швы (тайлы помнят цвет соседей и не уходят в свою сторону), и часть семантики (тайл с волосами знает, что под ним началась шея, а не шерсть). Звучит как простая ассоциация [2]. Но если зайти внутрь, там восемь архитектурных классов памяти, и не все они переносимы на плоскость изображения.
Прежде чем нырять в таблицу классов, что мы вообще ищем. Архитектура памяти должна делать несколько вещей сразу.
Дёшево по числу тайлов. Сразу прикинем масштаб. Размер тайла мы берём в диапазоне 1024-2048 пикселей, это нативное разрешение современных моделей. SDXL и SANA нативно сидят на 1024 (SANA в дополнение тренировали и до 4K). FLUX и Klein приемлемо работают на 2048. Опускаться ниже 1024 нет смысла – качество просаживается а количество тайлов растет.
Профессиональная съёмка сегодня, это файлы от 8K до 15K пикселей по длинной стороне. Phase One IQ4, 14200×10600. Hasselblad H6D-100c, 11600×8700. Полнокадровая Canon R5, 8192×5464. Sony A7R V легко за 12K. На этих файлах при 1024 с небольшим перекрытием получается: 60 MP → ~75-80 тайлов 100 MP → ~130 тайлов 150 MP → ~190 тайлов
И тут вылазит ещё один параметр, overlap, перекрытие между соседними тайлами. Без него швы видно крайне сильно. Обычно швы прячутся блендингом, но число тайлов растёт. На том же 150-мегапиксельном файле при tile=1024: overlap 25%, это уже ~270 тайлов, overlap 50%, около 540. И тут ещё один минус блендинга, который сразу видно. Он по-разному работает на разных частотах картинки. На гладком (низкие частоты неба, тон кожи, плавный градиент в отражении металла) стык можно скрыть неплохо, цветовой переход замаскируется. А вот на высоких частотах (текстура волос, фактура камня, шум, мелкие царапины) либо вылезает драматический перепад на границе тайлов, либо, наоборот, верхняя частота размазывается из-за блюра смешивания соседей. Одной ручкой обе оси не починишь: чем агрессивнее блендим, тем мягче цветовой шов на гладком, но тем хуже текстура.
При tile=2048 (если работаешь на FLUX или Klein) количество тайлов меньше в 4 раза, но всё равно набегают десятки даже на средних файлах. То есть 150+ тайлов на одну картинку – это нормальный рабочий случай. Любая архитектурная стоимость, квадратичная по числу тайлов, на таких сетках просто не запустится, ни в 80 ГБ VRAM, ни в 192 ГБ. Full 3D attention отсюда выпадает сразу.
Если механизм хотя бы частично работает inference-only, это огромный плюс для нашей затеи.
Pixel-precise output. Мы ретушируем текстуру, не генерируем эстетику. Discrete-token модели типа Cosmos с FSQ-словарём на 64K квантизируют HF и съедают тонкие детали. Не подойдет.
Мне в принципе хотелось бы вот что. Apache 2.0 (чтобы можно было в продукт без переговоров), простую архитектуру и без лишнего груза. Современные топовые видео-модели, Wan 2.1 на 14 миллиардов параметров, HunyuanVideo на 13, CogVideoX, Open-Sora 2.0, слишком много в себе несут. Длинное видео, motion control, audio sync, multi-shot композиция. Половина функциональности, решение задач, которых у нас вообще нет. А VRAM и время загрузки весов платим за неё в полном объёме. Спасибо, не надо.
Нужен рабочий примитив, механизм памяти между соседями, отделимый от родительской модели и переносимый на свою фото-модель. SANA-Video, AnimateDiff, SVD, FramePack, каждая из этих работ изолирует такой примитив, он живёт отдельно от своей обвески. Wan и Hunyuan – нет, у них всё интегрировано в один стек, ничего не отделишь.
Естественный вопрос с места. А нельзя ли по ходу обработки выкидывать из памяти то, что уже сделали? Чтобы 200 тайлов не лежали все одновременно в VRAM, со всеми своими K/V-тензорами и attention-картами.
Можно. И это, по сути, главная ось по которой я выбираю архитектуру. Есть три способа разной степени радикальности:
Естественный вопрос с места. А нельзя ли по ходу обработки выкидывать из памяти то, что уже сделали? Чтобы 200 тайлов не лежали все одновременно в VRAM, со всеми своими K/V-тензорами и attention-картами.
Можно. И это, по сути, главная ось по которой я выбираю архитектуру. Есть три способа разной степени радикальности:
Слайдинг. Держим в памяти только последние W тайлов (скажем, 8), всё что дальше, забываем [3]. Просто. Минус, не работает для далёких связей: если в правом верхнем углу зеркальное отражение того, что было в левом нижнем, мы это уже не увидим. Это тип C в таблице ниже. Геометрическая компрессия. Соседей держим в полном разрешении, диагональных, downsample’им в 2 раза, далёких, в 4 раза, и так далее. Total memory сходится к константе, не зависит от размера фото. Это тип F (FramePack). Аккумуляция в state. Самое радикальное. Тайлы вообще не храним. Держим только два маленьких тензора-сумматора S и Z, которые «помнят» всё что прошло, без хранения деталей. Это тип B (BCLA из SANA-Video).
Все три, primary-кандидаты в таблице ниже.
Восемь архитектурных классов памяти
|
Тип |
Механизм |
Где встретить |
На тайлы |
Что переносим |
|---|---|---|---|---|
|
A. Full 3D attention |
Все токены space+time видят всех, 3D RoPE |
Wan 2.1 [4], HunyuanVideo [5], CogVideoX [6] |
Drop |
O((T·H·W)²), для 64+ тайлов не запустится |
|
B. Block Causal Linear (BCLA) ★★★ |
S = Σ KᵀV, Z = Σ Kᵀ. Константная state O(D²) |
SANA-Video [7], MiraMo [8] |
Primary |
~380 МБ суммарного state на 1.6B модель (по всем слоям, fp16), не зависит от числа тайлов |
|
C. Sliding window |
Attend к последним W кадрам |
CausVid [9], Self-Forcing [10] |
Backup |
Хорошо для local consistency, плохо для далёких тайлов |
|
D. Factored S+T ★★ |
Temporal attn после каждого spatial. Reshape (B·T, C, H, W) → (B·H·W, T, C) |
SVD [11], AnimateDiff [12], Latte [13] |
Direct map |
«Для каждой пиксельной позиции attend через все кадры» = «через все тайлы» |
|
E. Anchor frame |
Все кадры обязательно attend к frame 0 |
Rolling Forcing [14] |
Augment |
Анкор-тайл (угловой/центральный) выравнивает цвет |
|
F. Geometric compression ★★★ |
Близкие = full, далёкие = compressed. Total CONVERGES |
Primary |
Соседи = full, диагональ = 2×, далёкие = 4× |
|
|
G. Cache sharing |
KV-cache при t=0 переиспользуется на всех denoising steps |
Augment |
Compute neighbor features once, reuse N_steps × |
|
|
H. Discrete tokens |
FSQ vocab=64K, Llama-style next-token |
Cosmos [19] |
Drop |
Несовместимо с continuous pixel editing |
|
Ключевые в нашем переносе, B, D, F. Дальше про каждый по абзацу. |
|
|
|
|
Type B, BCLA из SANA-Video. Linear attention с causal mask: каждый блок (каждый кадр = тайл) аккумулирует state в виде двух тензоров, S = Σ KᵀV размером D×D и Z = Σ Kᵀ размером D. Когда новый блок приходит, он cross-attend’ит не ко всем предыдущим токенам, а к этим двум аккумуляторам. Стоимость: O(D²) на блок, не растёт с числом блоков. Для нас это значит что 100 тайлов стоят столько же, сколько 10. На SANA 1.6B при D ≈ 2304 и ~28 слоях суммарный state по всем слоям выходит около 380 МБ в fp16. Очень привлекательно.
Type D, Factored S+T (SVD). Stable Video Diffusion добавил поверх SDXL UNet temporal-блок после каждого spatial, 656M доп. параметров, 43% всей модели. Архитектурно делается через reshape: тензор формы (B·T, C, H, W) после spatial блока перевзят как (B·H·W, T, C), прогоняется через temporal attention, возвращается обратно. На тайлы переводится дословно: B·T → B·N_tiles, T → N_tiles. Temporal attention становится cross-tile attention для каждой пиксельной позиции. Самый прямой 1:1 перенос. Но кажется что самый хрупкий в реализации.
Type F, FramePack. Lvmin Zhang (тот же автор, что ControlNet) сделал гениальную штуку. Близкие кадры пакуются в context на максимальной плотности, далёкие, на сжатой, ещё более далёкие, ещё сжатее. Total context CONVERGES, то есть он не растёт с числом кадров, а сходится к фиксированному пределу. Для нас идеально: тайл (3, 5) видит соседей (2, 5), (3, 4), (3, 6), (4, 5) на полной плотности, диагональных (2, 4), (4, 6) на 2×-сжатии, дальних (1, 1), на 4×. Total context = const, не зависит от размера фото. Можно работать на сетках 16×16 и больше без квадратичного взрыва.
Что выкидываем явно. Type A (full 3D attention), у Wan 2.1 это 14 миллиардов параметров и квадратичная стоимость по числу тайлов; для сетки 10×10 просто не запустится. Type H (discrete), Cosmos на FSQ-токенах с vocab=64K, для editing нужен continuous pixel-level выход. Большие модели вроде LTX-2 22B и HunyuanVideo 13B, слишком тяжёлые для нашего бюджета.
Какие модели уже на сцене, и кто что забрал В видео-диффузии 2024-2026 годов опубликовано около тридцати моделей с разными типами памяти. Не буду гнать через все, главное:
SANA-Video (arxiv 2509.24695 [7]), primary кандидат на BCLA. Linear attention, NVFP4 quantization из коробки. Это видео-расширение базовой SANA, и именно оттуда мы забираем механизм BCLA.
AnimateDiff (arxiv 2307.04725 [12]), primary кандидат на factored S+T при условии 32 тайлов или меньше. Главное, motion modules уже обучены, можно использовать инференсом.
SVD (arxiv 2311.15127 [11]), наследие, но reshape pattern хорошо документирован.
FramePack (arxiv 2504.12626 [15]), для больших сеток, реализация на DiT-моделях.
StreamingT2V (arxiv 2403.14773 [20]), CAM (cross-attn skip-connection от соседей) и APM (CLIP-anchor для всех кадров). Оба механизма устроены так, что их можно прикрутить к pretrained backbone’у без ретренинга основной модели, обучается только сам адаптер. Для нашего случая это значит, что часть механизмов можно пробовать без полного обучения [21] с нуля.
Прецедент в обратную сторону, но всё-таки не наша идея. PatchVSR [22] (CVPR 2025) уже взял видео-модель и приделал к ней dual-stream адаптер для патчей. Но они сохранили временное внимание [23] внутри патча (по кадрам этого патча), не между патчами. То есть переносили видео в патчи, но память между патчами не пробовали. STA, Sliding Tile Attention [24] (ICML 2025) применил sliding-tile внимание к видео-генерации на HunyuanVideo и получил ускорение 2.8-17× over FlashAttention2 на end-to-end inference. Это про скорость в видео, не про seam coherence в фото, но идея sliding-tile внимания пришла оттуда. FrescoDiffusion [25] (Mar 2026), самый близкий кузен моей идеи, делает tiled denoising для 4K I2V с prior-regularized fusion, но генерирует видео а не редактирует фото.
Системного эксперимента «temporal attention из видео-моделей как cross-tile attention для статичной картинки на разных backbones», я не нашла. Если кто-то знает, дайте ссылку, порадуюсь.
Карта переноса видео → горизонталь Если коротко, каждому из ключевых видео-механизмов есть прямой пространственный аналог:
BCLA (SANA-Video) → S/Z аккумуляция между соседями, O(D²) const, тип B
FramePack compression → близкие тайлы full, диагональ 2×, далёкие 4×, тип F
SVD factored reshape → (B·N_tiles, C, H, W) → (B·H·W, N_tiles, C), тип D
AnimateDiff motion modules → те же modules как cross-tile attention, тип D
StreamingT2V CAM → cross-attn от уже обработанных соседей, тип E
Ca2-VDM cache reuse → compute neighbor KV at t=0, reuse 28 denoising steps, тип G
Про датасет почти никто не пишет. А это половина задачи. Если мы хотим обучать модель помнить соседние тайлы, это значит датасет должен подавать ей не одиночные тайлы, а последовательности соседей. Несколько разрешений и несколько overlap-режимов. Иначе модель ничему не научится, у неё в train data просто нет «вот тайл и его сосед слева».
В моём рабочем сетапе:
На радость у меня завалялся небольшой датасет на 53 000 картинок ювелирных украшений. Собственно про объём датасета. На одну ювелирную фотку при tile=1024 и стандартном overlap’е выходит порядка 30-50 пересекающихся тайлов. Strip-последовательность, это одна прямая (горизонтальная или вертикальная) сквозь эти тайлы; их ~10-15 на фотку на одной scale. С тремя scale’ами (512, 768, 1024) и двумя хранимыми направлениями (LtR + TtB, остальные генерируются на лету через np.flip()) на одну картинку выходит ≈70 strip-последовательностей. На 53 000 картинок, порядка 3-4 миллионов сэмплов.
Планируется четыре направления обхода, слева-направо, справа-налево, сверху-вниз, снизу-вверх. На диске хранятся только LtR + TtB, остальные генерируются на лету через np.flip().
Идея механики BCLA-аккумуляции в одном предложении: два внешних аккумулятора S (D×D) и Z (D), переживают между тайлами; каждый новый тайл cross-attend’ит к этим двум тензорам и в конце дописывает в них свой KᵀV и K.
Идея SVD-style reshape так же в одном предложении: после spatial-блока тензор (B·N_tiles, C, H, W) перевзят как (B·H·W, N_tiles, C), прогоняется через cross-tile attention (для каждой пиксельной позиции attend через все тайлы), потом reshape обратно.
Главное в обоих случаях, что cross-tile attention видит для каждой пиксельной позиции (h, w) все её копии в N_tiles тайлах. То есть «как этот же угол выглядит в соседнем тайле». Это и есть тот самый перенос с видео, там было «как этот пиксель выглядит во всех кадрах», стало «во всех тайлах».
Только на SANA. Большое нативное разрешение радует меня как ни что другое. SANA тренировали на 512 → 1024 → 2K → 4K. То есть тайл размером 4096пикселей для нее как родной.
Плюс ещё одно архитектурное совпадение, внутри SANA уже стоит linear attention. Тип B из таблицы выше. Примитив для cross-tile памяти у неё встроен прямо в backbone, отдельно прикручивать не надо.
Что сделала. Запустила небольшое обучение на тестовом датасете strip-последовательностей с tile=1024. Цель простая: проверить две вещи: сходится ли loss и переносится ли вообще механизм с временной оси видео на пространственную плоскость фото.
Что вышло. Loss сходится. Перенос temporal → spatial на SANA реально работает, модель учится согласовывать соседние тайлы так же, как раньше училась согласовывать соседние кадры в видео. Цифры пока не публикую (это всё-таки тестовый прогон), но направление подтверждается.
Идея 1 закрывает горизонтальные связи, как тайлы помнят друг друга. Но есть ещё одно очевидное упущение в стандартном тайлинге: тайлу не дают общую картинку и положение в ней. И это, пожалуй, ещё более грубый промах.
Если у тебя есть фото 6000×4000, и ты его режешь на тайлы 512×512, у тебя на руках вся картинка целиком. Не использовать её, это, ну, странно. Можно сделать downscaled-версию в латентном пространстве. И эту downscaled-версию подать модели дополнительно к каждому тайлу. Channel concat в первый conv-слой, самый прямой способ.
Плюс позиция тайла. Координаты. Два дополнительных канала, (x, y) ∈ [-1, 1]. Тайл (3, 5) знает, что он именно (3, 5) из сетки, а не «какой-то 512×512 пикселей в воздухе».
PaDIS [26] (NeurIPS 2024) сделал простую штуку и получил совсем не простой результат. Идея такая: к входным RGB-каналам модели добавляются ещё два, координатные. В каждом пикселе записано его положение в большой картинке, нормализованное от -1 до 1. Модель в момент обработки конкретного патча видит не только сами пиксели, но и «где я нахожусь в полной фотке: левый верхний угол, центр, низ».
Дальше та же модель, датасет, гиперпараметры. В одной версии координатные каналы есть, в другой нет. Без координат PSNR падает с 33.57 до 23.25 дБ. Минус 10.3 децибел. Цитата авторов: «все восстановленные результаты были очень низкого качества». То есть это не разница между «хорошо» и «нормально», а между «работает» и «вообще ничего не работает».
Что происходит без позиции. Модель пытается одной общей функцией восстановить все патчи сразу. Без подсказки «где я» она не может привязать своё знание к месту: «здесь обычно лицо, здесь ноги, здесь градиент неба, здесь фон». В результате выдаёт усреднённый шум, не похожий ни на что конкретное. С координатами эта привязка работает: модель учится «в этом регионе картинки обычно такая статистика», и появляется patch-prior, её локальное ожидание для конкретной точки.
Стоит это дёшево. Два числа на пиксель добавить к трём RGB-каналам. Копейки в общей стоимости. При этом в современных тайловых пайплайнах координат почти никто не подаёт. Я не очень понимаю почему. Возможно потому, что у pretrained-моделей вход фиксированной размерности, и любое расширение требует ретренинга.
Если разложить «что должна знать модель про тайл», выходит три ортогональных оси.
|
Уровень |
Что значит |
Где это уже умеют |
|---|---|---|
|
Геометрический |
«Я тайл (3, 5) из сетки 8×8» |
PaDIS [26], два канала |
|
Визуальный |
«Вся картинка целиком выглядит так» |
DemoFusion [27], FreeScale [28], DC-VSR [29], ResMaster [30] |
|
Семантический |
«Я обрабатываю кожу, рядом, волосы, не выдумай ухо» |
AccDiffusion v2 [31], per-tile prompt через VLM |
Tiled VAE из коробки даёт только нулевой уровень: пиксели и общий prompt. Все три оси, на стороне «что добавить».
Геометрический уровень, выше уже разобран, PaDIS-каналы.
Визуальный уровень. Тут два рабочих варианта и один тупиковый. Рабочий №1, кинуть в первый conv-слой downscaled VAE-латент полной картинки. Сохраняет пространственную структуру, цвет, освещение. Рабочий №2, добавить компактный 64-мерный вектор глобальных свойств (mean color, exposure, white balance), модулировать им AdaLN-Zero на каждом блоке. Похожие приёмы global-context conditioning описаны в работах вроде Simple ISP with Global Context Guidance [32] (ICIP 2024). Дешевле латента, но без пространственной информации.
Тупиковый, CLIP image embedding (IP-Adapter [33]). Для style transfer, окей, для ретуши, теряет пиксельную точность. 768-мерный вектор без spatial axes не даёт сигнал «у этого тайла верхний край на тёмно-синем небе, нижний, на голубоватом». Это я отдельно проверила, ниже расскажу.
Кто эту ось уже умеет, кроме PaDIS: FreeScale [28] (Alibaba, ICCV 2025) фьюзит low-frequency глобального self-attention с high-frequency локального, UltraGen [34] формализует «локальные окна + LR-глобал», DC-VSR [29] делает Spatial Attention Propagation, subsample всей картинки пропихивает в локальные тайлы через attention, ResMaster [30] выравнивает low-frequency патчей с LR-референсом на каждом denoising step. Все они про визуальный уровень. Третий, нетронутый.
Семантический уровень. Тут либо текстовый prompt на тайл через VLM, либо segmentation mask conditioning. AccDiffusion v2 [31] генерирует отдельный prompt на каждый тайл через VLM (Florence-2 [35], Qwen2-VL [36] и подобные), что-то вроде upper-left corner of glass with droplets. В моём случае это значит: тайл с плечом и волосами получает явный текстовый сигнал skin and hair, no fur. И галлюцинация «шерсть» становится физически невозможной, она противоречит prompt’у. Цена, один VLM-pass на полную картинку плюс короткий prompt-запрос на тайл (Florence-2 справляется за ~50 ms на тайл).
В одной фразе: на вход тайла идёт concat из его собственного латента + двух coord-каналов + downscaled-латента полной картинки + опциональной seg-маски. Первый conv-слой делает zero-init проекцию обратно в нужную размерность каналов. Дополнительно, 64-мерный вектор глобальных color/exposure/WB-статистик через AdaLN-Zero модуляцию на каждом блоке. И per-tile text prompt из одного VLM-pass’а на полную картинку.
Один важный нюанс. Zero-init у first_conv критичен. Иначе на t=0 модель видит свой обычный input + случайные веса, и pretrained функционал ломается с первого forward pass’а. Zero-init = на t=0 эффективная архитектура та же, что у backbone’а; обучение постепенно увеличивает влияние новых каналов. Этот трюк описан в ControlNet, AnimateDiff motion adapter, миллионе других работ, стандарт.
IP-Adapter global preview, слабый сигнал на SDXL. Гипотеза была: подадим в IP-Adapter downscaled-версию полной картинки, тайл получит «общую визуальную подсказку». Counterfactual probe: real preview vs random-noise preview. Diff_mean между двумя случаями, 0.0066 на пиксель. При threshold 0.02 (ниже которого мы считаем сигнал «декоративным»). То есть IP-Adapter технически работает (image_encoder вызывается, 120 cross-attention calls на тайл), но влияние на финальный output пренебрежимое. Гипотеза почему, IP-Adapter обучали на bigG-ViT image embedding, у нас стандартная SDXL пара CLIP-L + CLIP-G. Encoder mismatch съедает сигнал. Для production нужен либо bigG, либо native SDXL conditioning.
Идеи 1 и 2, это про то, как сделать тайлинг умнее. Третья идея в другую сторону, а что если тайлинг сократить в количестве? Не делать его на каждом denoising-шаге, а только там, где он реально нужен.
Эта идея пока чисто архитектурная. Не тестировала. Но логика [37] следующая.
Detail Demon (он же Detail Daemon), sampler-патч для диффузионных моделей, который изменяет sigma-schedule так, чтобы поздние шаги денойза давали больше детализации при том же количестве вычислений. Берётся типичный schedule, и в области малых sigm, там где как раз генерируется HF-текстура, добавляется extra «детальный» отрезок. Без переобучения модели.
В практике StableDiffusion это значит: при том же числе шагов получаешь картинку с более чёткой текстурой, более тонкими переходами, без overshoot’а CFG. Для генерации: чуть больше резкости и много деталей. Для апскейла: намного больше детализации без видимого «AI-сглаживания».
Стандартный диффузионный upscale (SDXL upscale, RealESRGAN+SD pipeline, X-to-1024, что угодно) сегодня делается так. Берёшь маленькую картинку, например 512×512. Поднимаешь её bicubic’ом до 1024×1024. Дальше прогоняешь это через диффузию с большим количеством шагов и существенным conditioning’ом на исходную картинку, чтобы она «дорисовала» детали.
Если картинка уже большая, например 2048 на сторону, этого делать в одном запуске нельзя. Не лезет в VRAM. Поэтому снова режем на тайлы, апскейлим каждый отдельно, склеиваем. Со всеми соответствующими швами, дублированиями, цветовыми сдвигами. То есть проблема та же самая, что в начале статьи, только теперь поверх ещё и upscale-логика.
Гипотеза: первая половина denoising-шагов работает с низкочастотной структурой. Грубое распределение цвета, общая композиция, крупные элементы. Это можно делать без тайлов, на downscaled версии, целиком в одном forward pass’е. Маленькая картинка лезет в VRAM.
Вторая половина шагов работает с высокочастотной детализацией, текстура, кромки, тонкие переходы. Здесь Detail Demon как раз и помогает: он делает HF-добавление через sampler-схему, не через рекурсивный re-denoise. И теоретически, это можно сделать на уже апскейленной картинке без re-tile, потому что Detail Demon не требует full denoising loop. Он работает локально по sigma-schedule, добавляет HF в малых sigma-зонах, не пересчитывая всю траекторию.
Что выигрывается. Половина шагов делается на маленькой версии, быстро, без тайлов, без швов на LF-уровне. Вторая половина: Detail Demon на полном разрешении. В идеале пайплайн без тайлинга вообще, или с тайлингом только в HF-фазе.
Detail Demon на больших фото, вопрос VRAM. Sample-шаги на полном разрешении 4096×4096 в attention map не лезут даже в 80 ГБ. Поэтому, скорее всего, чистый «без тайлов» получится только до какого-то предела разрешения, наверное, 2048 на сторону. Дальше всё равно нужна форма тайлинга в HF-фазе. А проблему стыковки тайлов тоже решит контекст.
Это гипотеза для тестирования. Возможно, Часть 3 цикла. Если попадётся бесплатное окно на H100, может и в Часть 2 попробую.
Антирезультаты честнее позитивных. Вот чего я не могу утверждать по preliminary тестам:
Полная aбляция ещё не сделана. Я подтвердила сходимость и базовую переносимость механизма на тестовом прогоне SANA, но это не полное обучение и не полная aбляция против baseline’ов. До цифр seam_PSNR / deltaE_ratio / HF-SSIM мы дойдём только в будущем.
Не знаю, какая из трёх архитектур в итоге даст лучший seam_PSNR. SANA-BCLA должен быть лучшим по памяти (O(D²) const), Klein-cache, по качеству (DC-AE 32-канальный латент сохраняет цвет лучше SD 4-канального), SVD-factored, самый прямой архитектурный перенос. Какой выиграет на real ablation, не знаю и врать не буду.
Не знаю, как масштабируется на сетки 16×16 и больше. Все probe’ы гонялись на 3×3-7×7 тайлов. Для 100-тайловой сетки нужен FramePack или sliding window.
Семантический уровень (Florence-2 per-tile prompts), не тестировала. Отдельная вариация под этой темой, которую тоже хочется попробовать, описание делать один раз на всю картинку (один VLM-pass), а на каждом тайле просто понижать вес токенов, которых на этом тайле физически нет. То есть в тайле «небо» в cross-attention приглушаются токены про лицо, волосы, металл, а на тайле с украшением, наоборот, приглушаются токены про небо. Получается единый prompt + per-tile attention masking, без 200 отдельных VLM-генераций. Формально похожий приём делает AccDiffusion v2 [31] через token attention masking по региональным маскам; в коммьюнити похожее знают по Regional Prompter / Latent Couple для sd1.5 в связке с ControlNet-Tile.
Detail Demon + апскейл, чисто гипотеза. Архитектурный sketch без единого прогона. Возможно сломается на VRAM, возможно даст другой набор артефактов.
Автор: Sonia_Black
Источник [38]
Сайт-источник BrainTools: https://www.braintools.ru
Путь до страницы источника: https://www.braintools.ru/article/29411
URLs in this post:
[1] память: http://www.braintools.ru/article/4140
[2] ассоциация: http://www.braintools.ru/article/621
[3] забываем: http://www.braintools.ru/article/333
[4] Wan 2.1: https://arxiv.org/abs/2503.20314
[5] HunyuanVideo: https://arxiv.org/abs/2412.03603
[6] CogVideoX: https://arxiv.org/abs/2408.06072
[7] SANA-Video: https://arxiv.org/abs/2509.24695
[8] MiraMo: https://arxiv.org/abs/2508.07246
[9] CausVid: https://arxiv.org/abs/2412.07772
[10] Self-Forcing: https://arxiv.org/abs/2506.08009
[11] SVD: https://arxiv.org/abs/2311.15127
[12] AnimateDiff: https://arxiv.org/abs/2307.04725
[13] Latte: https://arxiv.org/abs/2401.03048
[14] Rolling Forcing: https://arxiv.org/abs/2509.25161
[15] FramePack: https://arxiv.org/abs/2504.12626
[16] MAG: https://arxiv.org/abs/2512.18741
[17] Ca2-VDM: https://arxiv.org/abs/2411.16375
[18] TempCache: https://arxiv.org/abs/2602.01801
[19] Cosmos: https://arxiv.org/abs/2501.03575
[20] arxiv 2403.14773: https://arxiv.org/abs/2403.14773
[21] обучения: http://www.braintools.ru/article/5125
[22] PatchVSR: https://arxiv.org/abs/2509.26025
[23] внимание: http://www.braintools.ru/article/7595
[24] STA, Sliding Tile Attention: https://arxiv.org/abs/2502.04507
[25] FrescoDiffusion: https://arxiv.org/abs/2603.17555
[26] PaDIS: https://arxiv.org/abs/2406.02462
[27] DemoFusion: https://arxiv.org/abs/2311.16973
[28] FreeScale: https://arxiv.org/abs/2412.09626
[29] DC-VSR: https://arxiv.org/abs/2502.03502
[30] ResMaster: https://arxiv.org/abs/2406.16476
[31] AccDiffusion v2: https://arxiv.org/abs/2412.02099
[32] Simple ISP with Global Context Guidance: https://arxiv.org/abs/2404.11569
[33] IP-Adapter: https://arxiv.org/abs/2308.06721
[34] UltraGen: https://arxiv.org/abs/2510.16325
[35] Florence-2: https://arxiv.org/abs/2311.06242
[36] Qwen2-VL: https://arxiv.org/abs/2409.12191
[37] логика: http://www.braintools.ru/article/7640
[38] Источник: https://habr.com/ru/articles/1028252/?utm_campaign=1028252&utm_source=habrahabr&utm_medium=rss
Нажмите здесь для печати.