Обратный процесс: расшумление

Урок объясняет вторую, главную половину диффузии — как из чистого шума рождается картинка.

Обратный процесс (reverse / расшумление) — пошаговое удаление шума: модель начинает со случайной ряби и за много шагов превращает её в осмысленное изображение.

Генерация = обращение зашумления

Если прямой процесс умеет аккуратно портить картинку, то генерация — это пройти тот же путь назад. Мы берём чистый шум (просто случайные числа) и просим модель на каждом шаге сделать его «чуть менее шумным», приближая к правдоподобной картинке. После многих шагов из ряби проступает изображение.

генерация (обратный процесс):

[######] -> [к..t] -> [кот.] -> [кот]
чистый      сильно    немного   готово
шум         шумно     шумно

Что именно делает модель

Ключевая идея: модель не пытается сразу нарисовать финал. На каждом шаге она предсказывает шум, который, по её мнению, был подмешан, и вычитает его маленькую часть. Затем шаг повторяется. Такая «маленькими шажками» стратегия гораздо устойчивее, чем попытка угадать чистую картинку за один присест.

import random
random.seed(1)
# Старт — зашумлённый сигнал; цель восстановить [10,20,30,40]
noisy = [31.0, 5.0, 52.0, 18.0]
target = [10, 20, 30, 40]
for step in range(1, 4):
    # модель оценивает шум как разницу и убирает его часть
    noisy = [round(v - 0.5 * (v - t), 1) for v, t in zip(noisy, target)]
    print("Шаг", step, ":", noisy)

Вывод:

Шаг 1 : [20.5, 12.5, 41.0, 29.0]
Шаг 2 : [15.2, 16.2, 35.5, 34.5]
Шаг 3 : [12.6, 18.1, 32.8, 37.2]

С каждым шагом значения приближаются к цели. В настоящей модели «цель» заранее неизвестна — её роль играет выученное знание о том, как выглядят реальные картинки.

Как работает под капотом

За предсказание шума отвечает большая нейросеть — U-Net (разберём в следующем разделе). На каждом шаге ей подают текущее зашумлённое изображение и номер шага, а она выдаёт оценку шума. Сколько делать шагов и как именно вычитать шум — решает сэмплер; от него зависят скорость и качество. Эти параметры (steps, sampler) мы подробно изучим позже.

Частые ошибки

  • Думать, что модель «дорисовывает картинку целиком за шаг». Она лишь оценивает шум и убирает его часть; картинка собирается постепенно.
  • Считать, что больше шагов — всегда лучше. После некоторого числа шагов качество перестаёт расти, а время только тратится.
  • Забывать про роль старта. Разный стартовый шум (seed) ведёт к разным финальным картинкам.

Откуда берётся разнообразие

Раз старт — это случайный шум, разные seed дают разные финальные картинки даже при одинаковом промпте. Это не баг, а главный источник творческого разнообразия: меняя seed, вы как бы тянете из шляпы новую правдоподобную картинку, подходящую под описание. На практике художники генерируют целую сетку вариантов с разными seed и выбирают лучший, а затем дорабатывают именно его, зафиксировав его seed.

Любопытно, что некоторые сэмплеры на части шагов добавляют чуть-чуть нового шума обратно, а не только убирают. Это помогает «не застрять» и исследовать больше вариантов на ранних шагах. Другие сэмплеры идут строго на убывание и потому более предсказуемы. Это объясняет, почему один и тот же промпт с одним seed, но разными сэмплерами даёт похожие, но не идентичные картинки.

Итог

  • Обратный процесс превращает чистый шум в картинку, убирая шум маленькими шагами.
  • На каждом шаге модель предсказывает шум и вычитает его часть, а не рисует финал сразу.
  • Число шагов и способ их выполнения (сэмплер) влияют на качество и скорость.
Проверьте себя
1. Что модель делает на каждом шаге обратного процесса?
AРисует готовую картинку целиком
BПредсказывает добавленный шум и убирает его часть
CДобавляет ещё немного шума
DСжимает картинку в латентный код
2. Откуда берётся стартовая точка генерации?
AИз готовой картинки в базе
BИз чистого случайного шума, заданного seed
CИз текста промпта напрямую
DИз латентного кода предыдущей картинки