Содержание курса 29 / 33

29 / 33 · Диффузионные модели

Латентная диффузия и Stable Diffusion

Диффузия в латентном пространстве автоэнкодера вместо пикселей: перцептивное и семантическое сжатие, автоэнкодер, обусловливание на текст через перекрёстное внимание, classifier-free guidance, более быстрые сэмплеры и инструменты редактирования на той же модели (image-to-image, инпейнтинг, LoRA, textual inversion).

На этой странице 12

Заметки о DDPM и score matching описывают одну модель, которая шаг за шагом очищает изображение от шума. Каждый шаг прогоняет сеть по каждому пикселю, а сэмплу нужны десятки и сотни шагов. Большая часть этой работы уходит на детали, которых никто не видит: точную текстуру травы или шум матрицы камеры. Латентная диффузия (latent diffusion, Rombach et al., 2022) делит задачу надвое. Автоэнкодер один раз убирает незаметные детали; диффузионная модель работает только с оставшимся маленьким латентом и тратит свою ёмкость на то, что изображение показывает. Stable Diffusion — это такая схема с присоединённым текстовым энкодером.

Какая Stable Diffusion. Константы ниже относятся к конкретным чекпойнтам, а не к латентной диффузии вообще. Числа для 512×512512 \times 512, масштаб латента 0.18215 и текстовые энкодеры на 77 токенов — это Stable Diffusion 1.x и 2.x, а масштаб guidance 7.5 — значение по умолчанию в их конвейере Diffusers. У SDXL, более поздней модели, U-Net больше и два текстовых энкодера (Podell et al., 2023); её опубликованный автоэнкодер использует масштаб латента 0.13025, а её конвейер Diffusers — guidance 5.0 по умолчанию.

Обозначения. Изображение x∈RH×W×3x \in \mathbb R^{H \times W \times 3}, энкодер E\mathcal E и декодер D\mathcal D с z=E(x)∈Rh×w×cz = \mathcal E(x) \in \mathbb R^{h \times w \times c}, коэффициент уменьшения f=H/h=W/wf = H/h = W/w. Условие yy (запрос) и его энкодер τ(y)\tau(y). Величины диффузии ztz_t, αˉt\bar\alpha_t, εθ\varepsilon_\theta — те же, что в заметках о DDPM, только применённые к zz вместо xx.

Два вида сжатия#

Обученная модель изображений сжимает в двух смыслах. Перцептивное сжатие выбрасывает высокочастотные детали, которые меняют много битов изображения и почти ничего из того, что воспринимает человек. Семантическое сжатие схватывает компоновку и содержание изображения: какие объекты, где, в каком стиле. Модель правдоподобия в пространстве пикселей платит за каждый бит, а статья показывает, что большинство этих битов относится к перцептивной части. Латентная диффузия отдаёт каждую часть подходящей ей модели: первую — автоэнкодеру, обученному с перцептивной и состязательной функциями потерь, вторую — диффузионной модели.

Выигрыш велик. Stable Diffusion при 512×512512 \times 512 использует f=8f = 8 и c=4c = 4: в изображении 512⋅512⋅3=786 432512 \cdot 512 \cdot 3 = 786\,432 числа, а в латенте 64⋅64⋅4=16 38464 \cdot 64 \cdot 4 = 16\,384 — в 48 раз меньше. Внимание растёт ещё быстрее. Самовнимание по сетке 64×6464 \times 64 сравнивает 40962≈1.7⋅1074096^2 \approx 1.7 \cdot 10^7 пар; по пикселям 512×512512 \times 512 оно сравнивало бы 262 1442≈6.9⋅1010262\,144^2 \approx 6.9 \cdot 10^{10} — в 4096 раз больше, поэтому модели в пространстве пикселей применяют внимание только на грубых разрешениях. Память важна не меньше времени: одна карта внимания 4096×40964096 \times 4096 уже содержит 1.7⋅1071.7 \cdot 10^7 элементов — 67 МБ в 32-битных числах с плавающей точкой — для каждой головы и каждого изображения батча. Библиотеки умеют вычислять внимание по частям (slicing), по нескольку голов или изображений за раз: результат тот же, пиковое потребление памяти ниже, а скорость немного меньше.

Автоэнкодер#

Первая ступень обучается один раз и затем замораживается. Её функция потерь объединяет слагаемое восстановления, перцептивную функцию потерь (perceptual loss), сравнивающую глубокие признаки восстановления и изображения, как это делает LPIPS, и состязательную функцию потерь по фрагментам (patch-based adversarial loss), чей дискриминатор судит маленькие фрагменты, чтобы восстановления оставались чёткими, а не усреднялись до размытости. Латент держится близко к простому распределению одним из двух способов: слабым штрафом KL к N(0,I)\mathcal N(0, I), как в VAE с очень маленьким весом слагаемого KL, или слоем векторного квантования, как в VQ-VAE. В отличие от VAE, используемого как генератор, от этого автоэнкодера не требуют, чтобы сэмплы из априорного распределения выглядели хорошо: априорное распределение даёт диффузионная модель.

Коэффициент уменьшения задаёт разделение труда. При f=1f = 1 диффузионная модель по-прежнему делает всю перцептивную работу и обучается медленно; при f=32f = 32 автоэнкодер теряет информацию, которую декодер не может восстановить, и качество перестаёт расти. Статья находит, что ff от 4 до 16 даёт хороший баланс, а лучшие — f=4f = 4 и f=8f = 8. Поскольку штраф KL слаб, у латентов Stable Diffusion дисперсия не равна 1; код умножает их на фиксированный масштаб, 0.18215 для версий 1.x и 2.x, чтобы диффузия начиналась с данных примерно единичной дисперсии.

Диффузия в латенте#

Обучение — это целевая функция DDPM с zz вместо xx:

L=Ez0=E(x), ε, t[∥ε−εθ(αˉt z0+1−αˉt ε, t, τ(y))∥2].\mathcal L = \mathbb E_{z_0 = \mathcal E(x),\ \varepsilon,\ t}\Big[\big\lVert \varepsilon - \varepsilon_\theta\big(\sqrt{\bar\alpha_t}\, z_0 + \sqrt{1 - \bar\alpha_t}\,\varepsilon,\ t,\ \tau(y)\big)\big\rVert^2\Big] .

Генерация берёт zT∼N(0,I)z_T \sim \mathcal N(0, I), проходит обратную цепочку в латентном пространстве и один раз в конце декодирует, x^=D(z0)\hat x = \mathcal D(z_0). Сеть — U-Net, свёрточная, со слоями внимания на низких разрешениях.

Рисунок

Латентная диффузия: Stable Diffusion при 512×512

Обучение и генерация в латентном пространствеОбучение: изображение 512×512 кодируется энкодером в латент 64×64×4, к нему добавляется шум, и U-Net учится предсказывать этот шум, получая текст через перекрёстное внимание. Генерация: латент из нормального шума проходит 20–50 шагов U-Net с шедулером и classifier-free guidance, а декодер переводит результат в изображение.изображение512×512×3энкодер E÷8 по сторонелатент z₀64×64×4шумдо шага tU-Netпредсказывает шумзапростекстэнкодер текста77 векторовчистый шумN(0, I), шаг TU-Net + шедулер20–50 шагов, CFGz₀64×64×4декодер D×8 по сторонеизображение512×512×3перекрёстное вниманиеобучениегенерацияОбучение и генерация в латентном пространствеОбучение: изображение 512×512 кодируется энкодером в латент 64×64×4, к нему добавляется шум, и U-Net учится предсказывать этот шум, получая текст через перекрёстное внимание. Генерация: латент из нормального шума проходит 20–50 шагов U-Net с шедулером и classifier-free guidance, а декодер переводит результат в изображение.изображение512×512×3энкодер E÷8 по сторонелатент z₀64×64×4шумдо шага tU-Netпредсказывает шумзапростекстэнкодер текста77 векторовчистый шумN(0, I), шаг TU-Net + шедулер20–50 шагов, CFGz₀64×64×4декодер D×8 по сторонеизображение512×512×3перекрёстное вниманиеобучениегенерация
Сверху — обучение. Энкодер замороженного автоэнкодера сжимает изображение в 8 раз по каждой стороне, в латент из 4 каналов, к нему добавляется шум шага t, и U-Net учится предсказывать этот шум; текст приходит в U-Net через перекрёстное внимание. Снизу — генерация: латент из нормального шума проходит 20–50 шагов, на каждом из которых шедулер обновляет его по предсказанию U-Net с classifier-free guidance, и лишь в конце декодер переводит его в пиксели. Диффузия видит 16 384 числа вместо 786 432.

Обусловливание через перекрёстное внимание#

Условие входит через перекрёстное внимание (cross-attention, заметка о внимании): запросы берутся из признаков U-Net для ztz_t, ключи и значения — из закодированного условия,

Attention(Q,K,V)=softmax(QK⊤d)V,Q=WQ φ(zt),K=WK τ(y),V=WV τ(y),\mathrm{Attention}(Q, K, V) = \mathrm{softmax}\Big(\frac{Q K^\top}{\sqrt d}\Big) V, \qquad Q = W_Q\, \varphi(z_t), \quad K = W_K\, \tau(y), \quad V = W_V\, \tau(y),

где φ(zt)\varphi(z_t) — вытянутые в вектор промежуточные признаки. Каждая пространственная позиция латента смотрит на токены запроса, так что разные области могут следовать разным словам. В Stable Diffusion τ\tau — замороженный текстовый энкодер, превращающий запрос в 77 векторов токенов: CLIP ViT-L/14 размерности 768 в версиях 1.x, OpenCLIP ViT-H/14 размерности 1024 в версиях 2.x. Тот же механизм принимает и другие условия — метки классов, карты сегментации, изображения низкого разрешения.

Взвешивание запроса (prompt weighting). Каждый токен попадает в U-Net своим вектором τ(y)i\tau(y)_i, поэтому понятие можно усилить или ослабить уже после кодирования, без переобучения. Распространённое правило сдвигает вектор токена дальше от вектора на той же позиции для пустого запроса или ближе к нему,

τ(y)i  ←  τ(∅)i+wi (τ(y)i−τ(∅)i),\tau(y)_i \;\leftarrow\; \tau(\varnothing)_i + w_i\,\big(\tau(y)_i - \tau(\varnothing)_i\big),

с wi>1w_i > 1, чтобы усилить понятие, и wi<1w_i < 1, чтобы ослабить. Изменение действует через перекрёстное внимание: ключ токена меняет то, насколько латент обращает на него внимание, а значение — то, что латент из него считывает. Библиотека Compel записывает веса суффиксами, каждый + — множитель 1.11.1, каждый - — множитель 0.90.9: у ball++ вес 1.12=1.211.1^2 = 1.21, у ball-- — 0.92=0.810.9^2 = 0.81, у forest--- — 0.93=0.7290.9^3 = 0.729. Для весов меньше 11 она ещё и смешивает результат с кодировкой запроса, в котором эти токены замаскированы.

Classifier-free guidance#

Условная модель, сэмплируемая как есть, следует запросу лишь приблизительно. Classifier-free guidance (Ho and Salimans, 2022) усиливает это без отдельного классификатора. При обучении условие в части шагов заменяется пустым — в статье в 10 или 20%, — так что одна сеть учит и εθ(zt,t,y)\varepsilon_\theta(z_t, t, y), и εθ(zt,t,∅)\varepsilon_\theta(z_t, t, \varnothing). При сэмплировании два предсказания экстраполируются:

ε~=εθ(zt,t,∅)+s (εθ(zt,t,y)−εθ(zt,t,∅)).\tilde\varepsilon = \varepsilon_\theta(z_t, t, \varnothing) + s\,\big(\varepsilon_\theta(z_t, t, y) - \varepsilon_\theta(z_t, t, \varnothing)\big) .

s=0s = 0 — безусловная модель, s=1s = 1 — обычная условная, а s>1s > 1 уходит дальше неё; конвейер Diffusers для Stable Diffusion 1.x и 2.x по умолчанию использует s=7.5s = 7.5. Поскольку предсказание шума — это отмасштабированный score, sθ=−εθ/1−αˉts_\theta = -\varepsilon_\theta / \sqrt{1 - \bar\alpha_t} (заметка о score matching), направленное предсказание — это score

(1−s) ∇log⁡p(z)+s ∇log⁡p(z∣y)=∇log⁡[p(z)1−s p(z∣y)s],(1 - s)\, \nabla \log p(z) + s\, \nabla \log p(z \mid y) = \nabla \log\big[p(z)^{1 - s}\, p(z \mid y)^{s}\big],

а по формуле Байеса p(z∣y)∝p(y∣z) p(z)p(z \mid y) \propto p(y \mid z)\, p(z) это ∇log⁡p(z)+s ∇log⁡p(y∣z)\nabla \log p(z) + s\, \nabla \log p(y \mid z): безусловный score плюс ss градиентов неявного классификатора.

Score на каждом уровне шума, а не целевое распределение. Тождество выполняется на каждом шаге отдельно, с зашумлёнными маргинальными распределениями qtq_t вместо pp: направленное предсказание — это score плотности rt(z)∝qt(z)1−s qt(z∣y)sr_t(z) \propto q_t(z)^{1-s}\, q_t(z \mid y)^{s}. При s=0s = 0 и s=1s = 1 семейство rtr_t — зашумление одного распределения. При других ss в общем случае нет: зашумление p1−s p(⋅∣y)sp^{1-s}\, p(\cdot \mid y)^{s} не даёт rtr_t, и никакое другое отдельное распределение тоже. В разобранном ниже примере каждое rtr_t — гауссиана, и чистое распределение, из которого оно должно было бы получиться, имеет среднее 2.402.40 на последнем шаге, но 2.582.58 при t=0.2t = 0.2, если время идёт от 00 (данные) до 11 (шум). Поэтому сэмплер, которым управляет направленный score, в общем случае не приходит к p1−s p(⋅∣y)sp^{1-s}\, p(\cdot \mid y)^{s}, а стохастический сэмплер DDPM и детерминированный сэмплер DDIM из следующего раздела с одной и той же сетью приходят к разным распределениям (Bradley and Nakkiran, 2024). Тождество задаёт направление каждого шага: к областям, которые предпочитает неявный классификатор на данном уровне шума.

Разобранный пример. Возьмём безусловное p=N(0,4)p = \mathcal N(0, 4) и условное p(⋅∣y)=N(2,1)p(\cdot \mid y) = \mathcal N(2, 1). На последнем шаге направленный score — это score плотности p1−s p(⋅∣y)sp^{1-s}\, p(\cdot \mid y)^{s}, гауссианы с точностью (1−s)/4+s(1 - s)/4 + s и средним, равным 2s2s, делённому на эту точность. При s=3s = 3 точность 2.52.5, так что стандартное отклонение 0.630.63, а среднее 2.42.4; при s=7.5s = 7.5 точность 5.8755.875, стандартное отклонение 0.410.41, среднее 2.552.55. Сэмплеры приходят в другое место. С точными гауссовскими score, чтобы ошибка сети не участвовала, и непрерывной версией линейного расписания DDPM (β\beta от 0.10.1 до 2020) сэмплирование с guidance при s=3s = 3 заканчивается средним 2.632.63 и стандартным отклонением 0.520.52 у стохастического сэмплера и средним 3.003.00 и стандартным отклонением 0.250.25 у детерминированного; при s=7.5s = 7.5 — 2.672.67 и 0.310.31, а также 2.882.88 и 0.010.01. Направление совпадает с наклонённой плотностью, но выражено сильнее: guidance сужает распределение и уводит его от безусловного среднего дальше условного. Сэмплы становятся типичнее для запроса и менее разнообразны — это сторона точности в компромиссе из заметки о точности и полноте. Каждый шаг стоит двух вычислений сети — с запросом и без.

Рисунок

Направленный score на последнем шаге указывает на более узкую и сдвинутую плотность

Плотности при четырёх масштабах guidances = 0: безусловное: среднее 0.00, ст. отклонение 2.00; s = 1: условное: среднее 2.00, ст. отклонение 1.00; s = 3: среднее 2.40, ст. отклонение 0.63; s = 7.5: среднее 2.55, ст. отклонение 0.41.-6-4-20246s = 0: безусловноеs = 1: условноеs = 3s = 7.5Плотности при четырёх масштабах guidances = 0: безусловное: среднее 0.00, ст. отклонение 2.00; s = 1: условное: среднее 2.00, ст. отклонение 1.00; s = 3: среднее 2.40, ст. отклонение 0.63; s = 7.5: среднее 2.55, ст. отклонение 0.41.-6-4-20246s = 0: безусловноеs = 1: условноеs = 3s = 7.5
Игрушечный пример: безусловное распределение N(0, 4) и условное N(2, 1). На последнем шаге направленный score при масштабе s — это score плотности p(x)^(1−s) p(x | y)^s, которая для гауссиан снова гауссиана. При s = 1 получается условное распределение; при s = 3 стандартное отклонение 0.63, среднее 2.40; при s = 7.5, значении по умолчанию для Stable Diffusion 1.x и 2.x, — 0.41 и 2.55. Эта плотность уже условной и сдвинута дальше от безусловного среднего: более «типичные» для запроса сэмплы ценой разнообразия. Кривые показывают направление guidance, а не распределение сэмплов: сэмплеры с guidance в этом примере дают ещё более узкие распределения, разные для DDPM и DDIM (см. текст).

Меньше шагов#

DDPM сэмплирует за столько шагов, сколько использовалось при обучении, — 1000, потому что каждый шаг отменяет один малый гауссовский шаг. Быстрые сэмплеры исходят из детерминированного описания той же модели. В непрерывном времени прямой процесс — стохастическое дифференциальное уравнение, и Song et al. (2021) показывают, что ОДУ потока вероятности (probability flow ODE)

dzdt=−12 β(t) [z+∇zlog⁡qt(z)]=−12 β(t) [z−εθ(z,t)1−αˉt]\begin{aligned} \frac{dz}{dt} &= -\tfrac12\,\beta(t)\,\big[z + \nabla_z \log q_t(z)\big] \\ &= -\tfrac12\,\beta(t)\,\Big[z - \frac{\varepsilon_\theta(z, t)}{\sqrt{1 - \bar\alpha_t}}\Big] \end{aligned}

в каждый момент времени имеет то же маргинальное распределение qtq_t, что и процесс зашумления. Здесь β(t)\beta(t) — интенсивность шума в непрерывном времени, причём βt≈β(t) Δt\beta_t \approx \beta(t)\,\Delta t для одного дискретного шага и dαˉt/dt=−β(t) αˉtd\bar\alpha_t/dt = -\beta(t)\,\bar\alpha_t, а score заменён отмасштабированным предсказателем шума (заметка о score matching). Интегрирование ОДУ от zT∼N(0,I)z_T \sim \mathcal N(0, I) до t=0t = 0 отображает каждый латент шума в один сэмпл, и решателю, который делает большие шаги, нужно немного вычислений сети.

DDIM — это метод Эйлера в подходящих координатах. Разделим латент на его коэффициент сигнала и будем измерять время отношением шум/сигнал,

zˉ=zαˉt,σt=1−αˉtαˉt,\bar z = \frac{z}{\sqrt{\bar\alpha_t}}, \qquad \sigma_t = \sqrt{\frac{1 - \bar\alpha_t}{\bar\alpha_t}},

так что zˉ=z0+σt ε\bar z = z_0 + \sigma_t\,\varepsilon. Если продифференцировать zˉ\bar z с учётом dαˉt/dt=−β(t) αˉtd\bar\alpha_t/dt = -\beta(t)\,\bar\alpha_t, члены с zz сокращаются, а dzˉ/dtd\bar z/dt и dσt/dtd\sigma_t/dt содержат один и тот же множитель β(t)/(2αˉt(1−αˉt))\beta(t)/\big(2\sqrt{\bar\alpha_t(1 - \bar\alpha_t)}\big). ОДУ превращается в dzˉ/dσ=εθd\bar z/d\sigma = \varepsilon_\theta (Song, Meng and Ermon, 2021, §4.3, формула 14) с точным решением от σt\sigma_t к более раннему, меньшему σs\sigma_s

zˉs=zˉt+∫σtσsεθ dσ.\bar z_s = \bar z_t + \int_{\sigma_t}^{\sigma_s} \varepsilon_\theta\, d\sigma .

Метод Эйлера держит εθ\varepsilon_\theta на всём шаге равным значению в σt\sigma_t. Умножение обратно на αˉs\sqrt{\bar\alpha_s} даёт обновление DDIM (их формула 12 без добавленного шума):

zs=αˉs  z^0+1−αˉs  εθ(zt,t),z^0=zt−1−αˉt  εθ(zt,t)αˉt.\begin{gathered} z_s = \sqrt{\bar\alpha_s}\;\hat z_0 + \sqrt{1 - \bar\alpha_s}\;\varepsilon_\theta(z_t, t), \\ \hat z_0 = \frac{z_t - \sqrt{1 - \bar\alpha_t}\;\varepsilon_\theta(z_t, t)}{\sqrt{\bar\alpha_t}} . \end{gathered}

Предсказываем чистый латент, затем снова зашумляем его до уровня шага ss тем же предсказанным шумом. Шагом ss может быть любой более ранний шаг, поэтому расписание из 50 шагов просто проходит каждый двадцатый tt. Сэмплер Эйлера в диффузионных библиотеках, построенный по Karras et al. (2022), делает то же обновление со своим выбором уровней шума; его вариант «ancestral» добавляет новый шум после каждого шага. DDIM детерминирован и отображает каждый латент шума в одно изображение. Если выполнять его обновление в обратную сторону, от изображения к шуму, получается приближённое обращение (inversion): идеальное ОДУ можно интегрировать в обе стороны, но каждый шаг Эйлера вычисляет εθ\varepsilon_\theta в начале шага, поэтому обратный проход не отменяет прямой в точности. Ошибка уменьшается с числом шагов и растёт с ошибкой модели и с guidance.

Разобранный пример. Одномерные данные N(0,0.52)\mathcal N(0, 0.5^2), точный предсказатель шума, линейное расписание DDPM, zTz_T из его точного распределения и шаги DDIM, равномерно расставленные по tt. У сэмплов должно быть стандартное отклонение 0.50.5. С 1 шагом оно равно 0.0020.002, с 10 шагами — 0.3700.370, с 50 — 0.4710.471, с 1000 — 0.49850.4985. Один шаг из чистого шума возвращает z^0\hat z_0 — апостериорное среднее E[z0∣zT]\mathbb E[z_0 \mid z_T], близкое к среднему всех данных; слишком малое число шагов первого порядка стягивает сэмплы к этому среднему. Та же постановка показывает, что обращение приближённое даже с точным предсказателем шума: если обратить точку 0.80.8 шагами DDIM и сгенерировать обратно, получится 0.420.42 при 10 шагах, 0.710.71 при 50 и 0.800.80 при 1000.

DPM-Solver: точно проинтегрировать известную часть. В переменной λ=log⁡(αˉ/1−αˉ)=−log⁡σ\lambda = \log\big(\sqrt{\bar\alpha}/\sqrt{1 - \bar\alpha}\big) = -\log\sigma, равной половине логарифма отношения сигнал/шум, то же точное решение записывается как zˉs=zˉt−∫λtλse−λ ε^θ(λ) dλ\bar z_s = \bar z_t - \int_{\lambda_t}^{\lambda_s} e^{-\lambda}\,\hat\varepsilon_\theta(\lambda)\,d\lambda (Lu et al., 2022a, формула 3.4). DPM-Solver раскладывает ε^θ\hat\varepsilon_\theta в ряд Тейлора по λ\lambda в начале каждого шага и интегрирует экспоненциальный вес точно. Его версия первого порядка — DDIM (их §4.1); версии второго и третьего порядка тратят два или три вычисления сети на шаг, но им нужно гораздо меньше шагов. DPM-Solver++ (Lu et al., 2022b) применяет ту же идею к предсказанному чистому латенту z^0\hat z_0 вместо шума и использует многошаговое обновление второго порядка, которое повторно использует вычисление сети с предыдущего шага. Более ранние решатели высокого порядка теряли устойчивость при больших масштабах guidance, типичных для моделей «текст в изображение», и работали даже медленнее DDIM; многошаговая форма уменьшает эффективный размер шага и сохраняет устойчивость.

Сколько шагов. Числа зависят от guidance. Без guidance DPM-Solver даёт качественные сэмплы за 10–20 вычислений сети, с FID 4.70 при 10 и 2.87 при 20 на CIFAR-10 (Lu et al., 2022a). С guidance, как обнаружили Lu et al. (2022b), DDIM обычно нужно 100–250 шагов, чтобы сойтись, а DPM-Solver++ даёт качественные сэмплы за 15–20 шагов — как для моделей в пространстве пикселей, так и для латентных. На Stable Diffusion с масштабом guidance 7.5 DPM-Solver++ за 15–20 шагов достигает той ошибки в латентном пространстве, которую имеет стандартный 50-шаговый сэмплер (PNDM); в том же тесте все решатели уже при 10 шагах давали FID около 15–16, потому что декодер превращает не вполне сошедшийся латент в хорошее изображение (их §7.2). Сеть не меняется; меняется только правило обновления между её вычислениями, поэтому диффузионные библиотеки позволяют заменить сэмплер (шедулер, scheduler) после обучения.

Редактирование той же моделью#

  • Image-to-image (SDEdit, Meng et al., 2022). Закодировать существующее изображение, зашумить его до промежуточного шага, zt=αˉt z0+1−αˉt εz_t = \sqrt{\bar\alpha_t}\, z_0 + \sqrt{1 - \bar\alpha_t}\,\varepsilon, и пройти оставшиеся шаги очистки с новым запросом. Сила (strength) λ∈[0,1]\lambda \in [0, 1] выбирает шаг: при 40 шагах сэмплирования и λ=0.6\lambda = 0.6 проходятся последние 24. Малая сила сохраняет композицию; сила 1 игнорирует вход.
  • Инпейнтинг (inpainting). Чтобы изменить только область под маской, на каждом шаге латент вне маски заменяется исходным латентом, зашумлённым до того же шага, и модели следует только часть под маской: zt−1←(1−m)⊙zt−1orig+m⊙zt−1∗z_{t-1} \leftarrow (1 - m) \odot z^{\text{orig}}_{t-1} + m \odot z^*_{t-1}, где mm — маска, уменьшенная до сетки латента (1 там, где изображение может меняться), zt−1orig=αˉt−1 z0+1−αˉt−1 εz^{\text{orig}}_{t-1} = \sqrt{\bar\alpha_{t-1}}\, z_0 + \sqrt{1 - \bar\alpha_{t-1}}\,\varepsilon, а zt−1∗z^*_{t-1} — обновление сэмплера. При f=8f = 8 маска применяется к блокам 8×88 \times 8 пикселей, поэтому её граница не воспроизводится точно, а сглаживается декодером. Специальные модели инпейнтинга вместо этого получают маску и замаскированное изображение как дополнительные входные каналы и обучены под эту задачу.
  • LoRA. Дообучить слои внимания низкоранговыми обновлениями W+αrBAW + \frac{\alpha}{r} B A (заметка о PEFT), чтобы научить стилю или объекту по небольшому набору данных; обновление можно влить в веса для инференса. Для матрицы весов d×kd \times k обучается r(d+k)r(d + k) чисел вместо dkdk: при d=k=1280d = k = 1280 это 0.6%0.6\% слоя для r=4r = 4 и 5%5\% для r=32r = 32.
  • Textual inversion (Gal et al., 2023). Заморозить всё и учить только эмбеддинг vv нового токена, например <S*>, минимизируя функцию потерь диффузии на трёх–пяти изображениях понятия, v∗=arg⁡min⁡vEz0,y,ε,t ∥ε−εθ(zt,t,τ(yv))∥2v^* = \arg\min_v \mathbb E_{z_0, y, \varepsilon, t}\, \lVert \varepsilon - \varepsilon_\theta(z_t, t, \tau(y_v))\rVert^2 (их формула 2), где yvy_v — шаблонный запрос вроде «a photo of <S*>», в котором вместо эмбеддинга токена стоит vv. Затем токен можно использовать в любом запросе.

Что изменилось#

Диффузия в пикселяхЛатентная диффузия
Пространство диффузиипиксели, 512⋅512⋅3512 \cdot 512 \cdot 3латент, 64⋅64⋅464 \cdot 64 \cdot 4
Кто убирает незаметные деталидиффузионная модель, медленноавтоэнкодер, один раз
Вниманиетолько на грубых разрешенияхпосильно по всей сетке латента
Обусловливаниевозможно, но дорогоперекрёстное внимание к текстовому энкодеру
Число шагов (задаёт сэмплер, а не пространство)те же сэмплеры: около 1000 у DDPM, около 50 с DDIM на практике (100–250 до сходимости с guidance), 15–20 с DPM-Solver++так же
Цена одного шагапроход U-Net по 512⋅512⋅3512 \cdot 512 \cdot 3 числам, дважды с guidanceпроход по 64⋅64⋅464 \cdot 64 \cdot 4 числам, дважды с guidance, плюс один проход декодера на изображение
Предел детализациисетьдекодер автоэнкодера

Ограничения#

  • Декодер ограничивает детали. Мелкий текст, лица в малом масштабе и точные текстуры зависят от того, что может восстановить автоэнкодер; диффузионная модель не может добавить то, чего не выражает D\mathcal D.
  • Guidance — компромисс. Большое ss улучшает следование запросу и типичность ценой разнообразия, а начиная с какого-то значения — и качества изображения.
  • Текстовый энкодер ограничивает понимание. Замороженный энкодер типа CLIP на 77 токенов плохо справляется с подсчётом, пространственными отношениями и длинными запросами.
  • По-прежнему итеративно. Остаются десятки вычислений сети на изображение, вдвое больше с guidance, а слишком малое число шагов сэмплера первого порядка стягивает сэмплы к их среднему.
  • Память. Внимание по сетке латента требует памяти, квадратичной по числу позиций; вычисление по частям меняет скорость на память.
  • Данные. Модели обучаются на больших собранных из интернета наборах пар изображение–текст, со всеми вопросами согласия, авторских прав и смещений, которые к ним прилагаются.

Итоги#

  • Автоэнкодер один раз убирает перцептивные детали; диффузия идёт в его латенте, который для Stable Diffusion при 512×512512 \times 512 в 48 раз меньше изображения.
  • Автоэнкодер обучается с функциями потерь восстановления, перцептивной и состязательной по фрагментам и слабой регуляризацией KL или VQ; ff от 4 до 16 балансирует скорость и точность.
  • Текст входит в U-Net через перекрёстное внимание: запросы — из латента, ключи и значения — из текстового энкодера. Веса отдельных токенов сдвигают их векторы дальше от векторов пустого запроса или ближе к ним.
  • Classifier-free guidance экстраполирует от безусловного предсказания к условному. На каждом уровне шума это score плотности qt1−s qt(⋅∣y)sq_t^{1-s}\, q_t(\cdot \mid y)^s, но сэмплы в общем случае не следуют p1−s p(⋅∣y)sp^{1-s}\, p(\cdot \mid y)^s, а сэмплирование DDPM и DDIM приходит к разным распределениям; оба сужают распределение к запросу.
  • Сэмплеры интегрируют ОДУ потока вероятности той же модели: DDIM — метод Эйлера в координатах (zˉ,σ)(\bar z, \sigma), DPM-Solver точно интегрирует линейную часть и раскладывает сеть по λ\lambda; с guidance DPM-Solver++ нужно 15–20 шагов. Image-to-image, инпейнтинг, LoRA и textual inversion используют модель для редактирования.

Ноутбук#

Ноутбук о продвинутой диффузии из репозитория HSE-LAMBDA Deep Generative Models использует библиотеку Hugging Face Diffusers (номера ячеек считают все ячейки, включая текстовые, начиная с 1). Сохранённых выходов ячеек в нём нет, поэтому он описывает процедуру, а не результаты.

  • Ячейки 5–9: напоминание о DDPM и конвейере Stable Diffusion, затем генерация по тексту моделью stabilityai/stable-diffusion-2-1-base во float32, 25 шагов и масштаб guidance 7.5. enable_attention_slicing() вычисляет внимание по частям, чтобы снизить пиковое потребление памяти, как описано выше. Текст ячейки 6 даёт размер текстового эмбеддинга 77×76877 \times 768 — размер для Stable Diffusion 1.x; у используемой здесь версии 2.1 энкодер OpenCLIP размерности 1024.
  • Ячейки 10–12: шедулеры. ОДУ в тексте оставляет только слагаемое с шумом: у ОДУ потока вероятности для процесса, сохраняющего дисперсию, есть ещё слагаемое, пропорциональное ztz_t, и множитель 12\frac12. Шаг Эйлера записан с добавленным шумом, тогда как EulerDiscreteScheduler по умолчанию детерминирован (стохастический вариант — EulerAncestralDiscreteScheduler), а про DDIM сказано, что он позволяет параллельное сэмплирование, чего он не делает; он позволяет меньше шагов и приближённое обращение. Текст и README называют 10–15 шагов для DPM-Solver++ и 20–30 для сэмплера Эйлера. Статья о DPM-Solver++ сообщает о 15–20 шагах для сэмплирования с guidance, а именно так работает Stable Diffusion; около 10 шагов — это цифра для DPM-Solver без guidance; для сэмплера Эйлера статьи числа шагов не дают. README ссылается на статью о DPM-Solver, процитированную выше. В ячейке 11 swap_scheduler заменяет шедулер у того же объекта конвейера и возвращает его, так что pipe_euler и pipe_dpm — один конвейер: оба изображения в сравнении получены с DPM-Solver++.
  • Ячейки 13–16: пакетная генерация трёх запросов и взвешивание запроса с Compel: ball-- (вес 0.810.81), ball++ (1.211.21) и ball++ вместе с forest--- (0.7290.729). Текст описывает синтаксис (token:weight) другого инструмента и нормированную взвешенную сумму эмбеддингов токенов; синтаксис Compel — тот, что используется в коде, а его взвешивание действует на выход текстового энкодера.
  • Ячейки 17–20: image-to-image для картинки 768×768768 \times 768 с силой 0.6 (24 из 40 шагов) и 1.0.
  • Ячейки 21–22: инпейнтинг тем же базовым чекпоинтом, 50 шагов. У его U-Net 4 входных канала, поэтому конвейер использует замену латента, записанную выше, а не модели инпейнтинга, получающие маску на вход.
  • Ячейки 23–24: LoRA в стиле пиксель-арта, загруженная в Stable Diffusion XL и влитая с масштабом 0.8. В тексте сказано, что LoRA обучает около 0.2% параметров SD-XL. У загружаемого здесь адаптера ранг 32 и 85.1 млн параметров, все в U-Net (по заголовку файла весов), — около 3.3% от 2.6 млрд параметров U-Net SD-XL (Podell et al., 2023); 0.2% соответствовали бы рангу 2. Доля зависит от ранга и от того, какие слои адаптируются.
  • Ячейки 25–26: textual inversion с токеном понятия из sd-concepts-library, загруженным в runwayml/stable-diffusion-v1-5. Под этим именем репозиторий больше не публикуется; те же веса лежат в stable-diffusion-v1-5/stable-diffusion-v1-5, и API Hub перенаправляет туда старый идентификатор. Текст даёт целевую функцию textual inversion, записанную выше.

Дальше#

Текст, маски и сила image-to-image — грубые средства управления: они говорят, что должно появиться и примерно где, но не то, куда именно должна попасть данная точка изображения. Следующая заметка, Редактирование изображений по точкам: DragGAN и DragDiffusion, ставит задачу точных геометрических правок вида «перемести эту точку туда»: сначала через оптимизацию латентного кода GAN (DragGAN), затем через оптимизацию зашумлённого латента диффузионной модели (DragDiffusion).

Литература#