Двадцать лет назад убрать мусорный бак из кадра — это была целая история, требующая виртуозно владеть Photoshop. Чем дальше шло развитие «умных» инструментов, тем проще решалась эта задача, но поведение всё же не было до конца предсказуемым.
И вот мы пришли к полноценному ИИ, который нам этот бак уберёт одним щелчком, не обязательно даже его полностью выделять. Так и хочется сказать: «Будущее!» А потом заметить, что заодно перерисовался бордюр в другом конце кадра. Который вообще не надо было трогать.
В этом небольшом цикле статей мы поговорим об обработке настоящих, реальных фотографий с помощью ИИ. И нет, это не будет сборник типа «десять нейросетей для фотографа». Мы с вами полезем куда глубже, в самые основы, чтобы понять, как именно нейронка (а точнее, диффузионка) видит и обрабатывает фото.
Разговор пойдёт по нарастающей. Сначала пройдёмся по методам ретуши. Потом погрузимся в то, как диффузионка вообще работает с картинкой — целиком, от промпта до пикселей. Потом — как из такой генерации сделали редактор. Дальше — что модель несёт с собой из обучения, что ломается на стыке с фотографическим рабочим процессом, что до сих пор быстрее делать по-старому. И под конец — вопрос про то, чему теперь вообще верить, мы его затронем по касательной.
Предупреждаю сразу: примерно две трети текста — это про ограничения. Про достоинства вам и без меня расскажут в любом рекламном ролике, а вот про то, где именно эта штука спотыкается, обычно молчат.

Термин inpainting (метод обработки изображения, при котором части реального фото заменяются сгенерированным содержимым) в цифровую обработку принесла статья 2000 года. Авторы — Бертальмио, Сапиро, Кайеллес и Байестер, конференция SIGGRAPH.
Слово авторы взяли не с потолка: они честно писали, что пытаются воспроизвести приёмы профессиональных реставраторов. Дырка в холсте, утрата красочного слоя, царапина на фотоотпечатке — существуют целые школы методик, как бороться с этими проблемами.
Для примера. В Риме есть Центральный институт реставрации, ICR. Между 1945 и 1950 годом там разработали технику, которая называется tratteggio, в просторечии rigatino: заполнение утраченной части не мазком, а частой вертикальной штриховкой, тонкими линиями чистого цвета, наложенными слоями. Издалека штриховка сливается, и глаз читает картину целиком, без раздражающих провалов. А вблизи сразу видно, где работал художник, а где реставратор.
Придумали это не от бедности и не потому, что не умели попадать в тон. Это была осознанная позиция, сформулированная Чезаре Бранди в его теории реставрации: всё, что реставратор добавил, должно быть узнаваемо. Не мимикрировать под мазок автора, а оставаться отличимым.

К штриховке прилагалось второе правило, даже более жёсткое: обратимость. Реставрационные вставки делают акварелью, гуашью, лаковыми красками — тем, что можно снять растворителем, не тронув оригинал. Потому что через пятьдесят лет придут другие люди с другими методами и другими представлениями о том, как эта фреска выглядела.
Отличимость и обратимость — важнейшие правила. Нейросетевой инпэйнтинг взял от своего прародителя только термин и идею. Оба правила сознательно игнорируются. Вся индустрия нейросетевой генерации изображений сознательно соревнуется в том, чтобы быть неотличимой от настоящих фото. И с обратимостью там тоже беда.
Опасности реставрацииЧеловеку, далёкому от мира искусства, может показаться, что «ошибка реставратора» — это когда кто-то случайно повредит произведение искусства или некрасиво восстановит его, развеяв всю визуальную магию. Но в истории есть куда более неприятный пример. Раскопки города Кносса на Крите, которыми руководил Артур Эванс, превратились в настоящую фальсификацию. По найденным крошечным кусочкам и отдельным фрагментам реставраторы в начале XX века восстанавливали то, что даже близко не было похоже на оригинал. Например, фреска «Сборщик шафрана»: ранняя реконструкция сделала из сохранившейся фигуры человека, хотя последующие исследования показали, что там была обезьяна.
Многие исследователи считают, что Эванс делал это сознательно, раскручивая свою находку и создавая ей образ чего-то большего, чем просто ещё одна археологическая раскопка. Но фальсификация вскрылась.
Эту историю держат в уме многие реставраторы. Нельзя дорисовывать и долепливать того, чего не было. А вот диффузионки пожали бы мистеру Эвансу руку, если бы могли.

Важно понимать, что до появления диффузионных нейросетей все методы по обработке фотографий опирались на три идеи:
Воспроизвести кусок фото по каким-то его существующим частям. Скажем, если нам нужно вырезать мусорный бак на фоне кирпичной стены, то мы по видимым паттернам кирпича можем достроить стену.
Замылить ту часть фото, где восстановление невозможно. Если сделать это грамотно, то глаз человека сам дорисует необходимое.
Взять недостающую часть с другого фото. К примеру, ту же стену можно отдельно отснять по всей её длине и найти нужную заплатку на другом фото, разумеется, приведя в соответствие светотеневой рисунок. Это уже монтаж, но это тоже выход.
Диффузионка стала первым методом, который может взять заплатку из ниоткуда и наложить её так качественно, что разницы почти не будет заметно. Почти.
Про работу диффузионной нейросети при генерации изображений принято рассказывать через метафору проявки: сначала пятно шума, из которого с каждой итерацией проявляется нужное фото.
Это в целом верно, но очень упрощённо и не объясняет, как вообще модель может что-то восстановить из шума. А для понимания, как диффузионка редактирует фото, нам важно понимать, как она в принципе работает. Значит, начинаем с самого низа.
Диффузионная модель — это шумодав. Буквально тот самый шумодав, которым вы чистите вечерние кадры на ISO 6400.
Диффузионку обучают следующим образом. Берут фотографию из выборки, добавляют к ней немного гауссова шума. Потом ещё немного. Потом ещё. Через тысячу шагов от исходной картинки не остаётся почти ничего, равномерный телевизионный снег. Это называется прямым процессом, и он не требует никакого обучения: это просто арифметика.
А теперь берут нейросеть и учат её на одной-единственной задаче: вот тебе зашумлённая картинка и номер шага, скажи, какой именно шум сюда подмешали. Всё, это вся задача. Никаких «нарисуй кота». Предскажи шум.

Когда сеть научилась предсказывать шум, её можно запустить задом наперёд. Берём чистый снег, просим сеть сказать, что тут шум, вычитаем предсказанное, добавляем чуть-чуть свежего шума поменьше, повторяем. Через несколько десятков шагов из снега вылезает картинка, которой не было.
Это не поэтическое преувеличение, а буквальное описание. И вот отсюда все ограничения, о которых пойдёт речь дальше. Инструмент, чья единственная задача — убирать шум и додумывать сигнал, физически не умеет ничего сохранять. Он умеет только пересобирать.
Короткая родословная диффузионокИдея впервые сформулирована в 2015 году в работе Соль-Дикштейна и коллег с названием «Глубокое обучение без учителя с использованием неравновесной термодинамики». Идею прямо позаимствовали из физики, из описания того, как капля чернил расплывается в стакане воды. Расплывается она необратимо, но, если знать статистику процесса, можно попробовать посчитать обратный ход.
Пять лет о работе почти никто не вспоминал. В 2019-м Сон и Эрмон подошли с другой стороны, через оценку градиента плотности данных, так называемый score matching. В 2020-м Хо, Джайн и Аббель выпустили DDPM (Denoising Diffusion Probabilistic Models — обратите внимание на первое слово в названии), и вот тут стало понятно, что штука работает.
В 2022-м Ромбах с коллегами добавили главный трюк: перенесли всю диффузию в сжатое латентное пространство. Это сделало модель в разы дешевле и породило Stable Diffusion. Про латентное пространство — следующий раздел, и там же будет главная неприятность.
Ваша нейросеть никогда не видела вашего файла. Мне кажется, это самое важное обстоятельство во всей теме, поэтому разберу подробно.
Гонять диффузию по пикселям дорого. Картинка 512 на 512 в трёх каналах (RGB) — это 786 432 числа, и по ним надо пройтись каким-то числом шагов семплирования, обычно в районе 20–50. Поэтому в латентных моделях перед диффузией стоит отдельная сетка-кодировщик, вариационный автоэнкодер. Он ужимает картинку по каждой стороне в восемь раз и раскладывает результат по нескольким служебным каналам.
В классических Stable Diffusion и SDXL таких каналов четыре. Считаем: 64 на 64 на 4 — это 16 384 числа. Скалярных значений становится в 48 раз меньше.
И это не сжатие в смысле JPEG, где вы теряете мелкие детали, но структура файла остаётся картинкой. Это, по сути, пересказ картинки своими словами. Конспект, если хотите.
Дальше диффузия работает с конспектом, никакого доступа к вашим пикселям у неё нет. В конце декодер, вторая половина автоэнкодера, разворачивает конспект обратно в изображение — тоже своими словами, по мере понимания.
Отсюда, кстати, растут ноги у половины претензий к генеративным моделям. Каша вместо мелкого текста, странные пальцы, смазанные лица на общем плане: это очень часто не денойзер накосячил, а автоэнкодер не смог упаковать такую мелкую деталь в конспект. Если информация потерялась на входе, никакая генерация её потом не вернёт.
Индустрия это поняла и начала расширять горлышко. В Stable Diffusion 3 и во FLUX латентных каналов стало шестнадцать, сжатие упало с 48 до 12 раз. В FLUX.2 их уже тридцать два, сжатие шестикратное. Разработчики Emu (семейство генеративных нейросетей) прямо писали, что переход с четырёх каналов на шестнадцать больше всего помог именно с мелкими лицами и с буквами. Разница на порядок по потерям, и это только за счёт того, что конспект стали писать подробнее.
Что такое вариационный автоэнкодер, если совсем на пальцахПредставьте, что вам надо передать по телефону содержание фотографии человеку, который её потом нарисует. Вы не можете диктовать по пикселям, это часы. Вы говорите: «портрет девушки в профиль, тёплый свет слева, размытый зелёный фон, тёмная одежда».
Это кодировщик, он сжимает картинку в компактное описание.
Представьте, что вам надо передать по телефону содержание фотографии человеку, который её потом нарисует. Вы не можете диктовать по пикселям — это часы. Вы говорите: «портрет девушки в профиль, тёплый свет слева, размытый зелёный фон, тёмная одежда».
Автоэнкодер устроен ровно так, только «описание» у него не словесное, а числовое, и обе половинки обучались вместе, чтобы результат сходился как можно точнее. Слово «вариационный» означает, что кодировщик выдаёт не одну точку, а небольшое облако вокруг неё — это делает латентное пространство более гладким и предсказуемым для генерации.
Это кодировщик: он сжимает картинку в компактное описание.
Тут внимательный читатель должен меня остановить. Мы разобрали, как модель убирает шум. Мы разобрали, что работает она не с фотографией, а с конспектом. Но во всей этой схеме нет ни одного места, куда можно было бы вставить слово «асфальт».
И правда нет. Сеть, которую мы описали, умеет ровно одно: предсказывать шум. Ей всё равно, что под этим шумом — асфальт, кошка или чей-то свадебный портрет.
Значит, нужен отдельный механизм, который донесёт до неё ваш промпт. Механизмов там на самом деле три, и они работают последовательно.
Шаг первый: текст надо превратить в числа. Этим занимается токенизатор — он режет вашу фразу на кусочки. Не на слова: кусочек может быть корнем, приставкой, куском длинного слова. Дальше каждый кусочек получает свой номер по словарю.
Тут же вылезает первое ограничение, о которое спотыкались все, кто писал длинные промпты. В классических Stable Diffusion за раз обрабатывается 77 позиций, из которых две служебные. Семьдесят пять кусочков — это примерно пятьдесят-шестьдесят английских слов.
Всё, что вы написали сверх этого, либо отрезается, либо разбивается на порции и скармливается отдельно. Да, так бывает. Вы наваяли промпт в полтора абзаца эпитетов, а модель половину даже не увидела.
Шаг второй, самый интересный: номера надо превратить в смысл. Этим занимается текстовый энкодер, обычно CLIP.
CLIP — отдельная модель, обученная на сотнях миллионов пар «картинка плюс подпись под ней». Её натаскивали на одной задаче: расположить описание и картинку в общем пространстве так, чтобы правильная пара оказалась рядом, а неправильная — далеко. Слово «закат» и фотография заката должны оказаться близко друг к другу по смыслу.
После обучения текстовая половинка CLIP умеет брать вашу фразу и выдавать набор векторов — по вектору на каждый кусочек текста. И векторы эти живут в том же пространстве, что и картинки.
Отсюда, кстати, растёт свойство, которое многих раздражает. Модель понимает не слова, а то, как эти слова употребляли в подписях к фотографиям в интернете. Если формулировка в подписях встречалась редко, модель её не поймёт, как бы точно она ни звучала по-русски или по-английски.
Шаг третий: полученные векторы надо как-то влить в процесс шумоподавления. Этим занимается кросс-аттеншен, механизм перекрёстного внимания.
Работает он так. Латентный конспект поделён на клеточки. На каждом слое сети каждая клеточка задаёт вопрос: «а из того, что человек написал, ко мне имеет отношение хоть что-нибудь?» И получает ответ в виде взвешенной смеси — от каких кусочков текста ей взять побольше, от каких поменьше. Клетка, в которой формируется дорожное покрытие, тянется к слову «асфальт». Клетка на месте неба на него не реагирует вообще.
Тут важна одна деталь. Это происходит не один раз в начале, а на каждом слое сети и на каждом шаге семплирования. То есть промпт — не инструкция, выданная перед стартом. Это бумажка с техзаданием, приколотая к стене, на которую ретушёр косится каждые тридцать секунд всю смену.
Осталось сказать, как устроена сама сеть, которая всё это перемалывает. Потому что дальше по тексту нам это понадобится минимум дважды.
Классическая архитектура тут называется U-Net. Сначала картинка (а точнее, конспект) последовательно сжимается: каждый следующий блок работает с вдвое меньшим разрешением, но с бо́льшим числом каналов. Дошли до самого низа — разворачиваемся и начинаем расширять обратно, до исходного размера. Если нарисовать это схемой, получается буква U.

А между левой и правой половинками протянуты перемычки — на каждом уровне выход сжимающей части напрямую передаётся в разжимающую.
Зачем такая конструкция? Затем, что шум надо убирать одновременно на всех масштабах. На самом верху, в полном разрешении, сеть видит мелкую фактуру, но не понимает, что вообще изображено. Внизу, в сжатом виде, она видит общую композицию, но никаких деталей там уже нет. Перемычки позволяют сложить одно с другим: понять внизу, что это лицо, и применить это понимание наверху, где рисуются поры.
И вот тут ключевая особенность свёрточных сетей, к которой мы ещё вернёмся. Один свёрточный слой смотрит на крошечную окрестность — три пикселя на три, пять на пять. Чтобы сеть увидела кадр целиком, ей надо прогнать данные через много слоёв с последовательным уменьшением. Это называется рецептивным полем, и растёт оно медленно.
Запомните эту фразу. В главе про то, что делать по-старому, она выстрелит.
Кросс-аттеншен, к слову, вставлен не в одно место, а в блоки на разных уровнях этой буквы U. То есть текст влияет и на общую компоновку, и на мелкую фактуру — просто на разных уровнях по-разному.
Соберём цепочку целиком. Ваша фраза режется на кусочки, кусочки превращаются в векторы смысла, векторы через перекрёстное внимание подмешиваются в сеть, сеть на каждом шаге предсказывает шум с оглядкой на эти векторы, шум вычитается из конспекта, конспект в конце разворачивается декодером в пиксели.
Обратите внимание, чего в этой цепочке нет. В ней нет ни одного места, где можно сказать «а вот это не трогай».
Вообще ни одного. Промпт влияет на весь кадр разом, потому что перекрёстное внимание доступно каждой клеточке конспекта. Именно поэтому редактирование фотографий пришлось строить отдельными костылями поверх этой схемы — масками, отдельными каналами, внешними картами. Про них и пойдёт речь дальше.
Осталась одна деталь, без которой картинка не получится. Ей пользуются все, и почти никто не понимает, что она делает.
Речь про CFG scale. В интерфейсах она обычно подписана как «guidance scale» или просто «сила промпта», стоит по умолчанию на семёрке.
На самом деле там происходит вот что. На каждом шаге модель считает предсказание дважды. Один раз с вашим промптом. Второй раз с пустым, то есть отвечая на вопрос «а что бы ты нарисовала, если бы тебе ничего не говорили». Дальше берётся разница между этими двумя ответами, умножается на число из ползунка и прибавляется к безусловному предсказанию.
Прочитайте это ещё раз. Разница умножается на семь.
То есть вы не просите модель слушать внимательнее, вы берёте направление «в сторону промпта» и делаете шаг в семь раз длиннее того, который модель сама считает правильным. Это экстраполяция, а экстраполяция, если её тянуть достаточно далеко, всегда куда-нибудь улетает.
Улетает она предсказуемо: в контраст и в насыщенность. Ставите CFG 15 — получаете кислотные цвета, залепленные тени и выбитые света. Есть работа про расписания шума, к которой мы вернёмся; её авторы этот эффект тоже описали и предложили лечение: масштабировать результат guidance обратно, приводя его к разбросу яркостей исходного предсказания. В интерфейсах это иногда встречается как CFG rescale.
Для нас важно вот что: для генеративной заливки в фотографии CFG почти всегда надо ставить ниже дефолта. Три, четыре, пять. Да, модель будет меньше слушать промпт. Зато вставка не будет орать контрастом на фоне остального кадра.
Высокий CFG нужен, когда вы делаете картинку с нуля и хотите, чтобы в ней было ровно то, что вы написали. Когда вы латаете дырку в фотографии, вам нужно обратное: чтобы заплатка была максимально незаметной.
Небольшое отступление, которое сэкономит кому-нибудь пару часов.
Между обученной моделью и картинкой стоит ещё одна деталь: семплер. Это алгоритм, который решает, как именно идти по шагам от шума к результату. Их много, называются они пугающе, и в интерфейсах их обычно десятка два. Делятся они на два типа, и разница принципиальная.
Первый тип — обычные, детерминированные. DDIM, Euler, DPM++ 2M и прочие. Они идут от шума к картинке, ничего по дороге не добавляя. Увеличиваете число шагов — результат становится точнее, но остаётся тем же изображением глобально. Двадцать шагов и пятьдесят шагов дадут разные детали и даже некоторые различия композиции. Но революционных изменений не будет.
Второй тип — так называемые предковые, ancestral. Узнаются по букве «a» в названии: Euler a и родственные ему варианты с SDE. Эти на каждом шаге подмешивают свежую порцию шума, то есть траектория никуда не сходится, она всё время немножко сбивается в сторону.
И вот что из этого следует. Вы получили отличный результат на двадцати шагах, обрадовались, решили перегенерировать на пятидесяти для качества — и получили другую картинку. Тот же промпт, тот же сид, всё то же самое. Другая картинка.
Так что, если результат надо будет воспроизводить или уточнять, берите детерминированный семплер. Предковые хороши для перебора вариантов, когда вы ещё не знаете, чего хотите, и вам нужно разнообразие; как только вариант найден, переключайтесь.
И записывайте сид. Всегда записывайте сид.
На этом с устройством всё. Мы прошли путь от вашей текстовой строчки до готовых пикселей и по дороге собрали почти все понятия, которые понадобятся ниже: конспект, шаги, промпт, CFG, семплер, сид.
Но пока у нас в руках генератор картинок из ничего. А нам нужен редактор — машина, которой можно сказать не «нарисуй закат», а «оставь всё как было, поменяй вот здесь». Это, как ни странно, задача посложнее.
Способов заставить генератор редачить придумали три, и они разные по степени влияния:
Можно подпортить исходник, но внести туда то, что хотелось.
Можно показать модели, что вот тут трогать надо, а вокруг не надо.
Можно приставить к ней внешнего надсмотрщика. Разберём по очереди. Кстати, в конце выяснится неприятная вещь: ни один из трёх не решает главную проблему.
Начнём с метода image-to-image, потому что механику его работы часто трактуют неверно.
Скрытый текстImage-to-image, или для краткости i2i, — это когда вы даёте нейросети не только текстовое описание, но и готовую картинку, от которой надо оттолкнуться. Модель берёт ваш кадр, портит его шумом — частично или полностью: это вы решаете ползунком, — а потом восстанавливает по своему разумению и по вашему промпту. Чем слабее испортили, тем ближе результат к оригиналу: поменяются фактуры и мелочи. Чем сильнее, тем больше отсебятины: от исходника останется только общая раскладка светлых и тёмных пятен, а всё остальное модель придумает заново. Никаких масок и выделений тут нет, изменения расходятся равномерно по всему кадру. Поэтому i2i хорош, когда надо перекрасить сцену целиком — сделать из дневного кадра вечерний, из фотографии рисунок, — и плохо годится для точечной правки.
Формально всё описано в работе SDEdit 2021 года — Мэн с коллегами, полное название про синтез и редактирование изображений через стохастические дифференциальные уравнения (не запоминайте эту фразу, не надо).
В реальности же мы делаем так: у нас есть картинка, мы её загружаем, крутим ползунок «сила» или denoising strength, пишем промпт, жмём кнопку.
Что происходит под капотом? Помните прямой процесс, тысячу шагов зашумления? Модель умеет запускаться не с последнего шага, а с любого. Вот ползунок ровно это и задаёт: насколько глубоко в шум мы погружаем вашу картинку, прежде чем начать её оттуда доставать.
Ставите 0,3 — картинку зашумили слегка, модель отобразила почти то же самое, поменялись фактуры и мелочи. Ставите 0,75 — от исходника осталась только общая композиция и раскладка пятен, всё остальное модель придумала заново. Ставите 1,0 — исходник уничтожен полностью, и вы получаете чистую генерацию по промпту: картинка на входе уже ничего не значит.
То есть это никакая не «сила эффекта». Это «сколько процентов вашей фотографии мы уничтожаем перед началом работы».
Что это значит? У image-to-image нет режима «поправь вот тут аккуратно». Любое значение ползунка, кроме нуля, разрушает часть исходной информации, и разрушает её равномерно по всему кадру. Нельзя разрушить только фон и не тронуть лицо, маски в чистом i2i нет.
Поэтому для реальной ретуши i2i почти бесполезен, а вот для стилизации и для «перепридумать сцену» отличный инструмент. Надо убрать провод — это инпейнтинг с маской. Надо превратить дневной кадр в вечерний — это i2i. Если вы пытаетесь убрать провод через i2i, вы получите другой кадр без провода, и лицо модели на нём будет чужое.
Как мы уже знаем, обычная модель Stable Diffusion принимает на вход четыре латентных канала — тот самый конспект. А специальная модель для инпейнтинга принимает девять. И там не просто больше каналов: в этой девятке живут три разные сущности.
Первые четыре — рабочий холст. Тот самый конспект, который модель на каждом шаге чистит от шума. Он переменный: на старте это шум, в конце — результат, и каждый шаг его переписывает.
Следующие четыре — конспект оригинала с вырезанной дыркой. Берём вашу фотографию, заливаем область под маской нейтральным серым, прогоняем через кодировщик. Получается описание сцены без того, что вы собрались менять. Этот конспект константный: он посчитан один раз перед стартом и до конца работы не меняется ни разу.
Разница между двумя конспектами принципиальная, хотя называются они одинаково. Первый — то, что рисуется прямо сейчас. Второй — образец, на который поглядывают.
Аналогия из той же работы реставратора, раз уж мы с неё начали. У реставратора на столе две вещи: сам холст, который он правит, и фотография этого холста до начала работ, приколотая к стене. Холст меняется с каждым мазком. Фотография не меняется никогда — на неё смотрят, чтобы не уйти слишком далеко от оригинала.
Ну и девятый канал. Маска.
Маска тут — не картинка и не слой в Photoshop. Это одноканальная карта того же размера, что и латент, где на каждую клеточку записано одно число: трогать или не трогать. Единица — перерисовать, ноль — оставить как есть. Никакого содержимого, только «где».
Причём через кодировщик её не гоняют. Её просто уменьшают интерполяцией до латентного размера — с 512 на 512 до 64 на 64. Помните разговор про блоки восемь на восемь? Вот он, вид сбоку.
Тут напрашивается вопрос: а зачем маска отдельным каналом, если дырка и так видна во втором конспекте? Она же залита серым, её не перепутаешь.
Ещё как перепутаешь.
Во-первых, после сжатия в восемь раз граница выреза размазывается. Кодировщик свёрточный, он смотрит на окрестность каждой точки, и в клетки на краю дырки попадает смесь из служебной заливки и настоящей картинки. Чёткой границы в конспекте просто нет.
Во-вторых, серый — совершенно легальное содержимое фотографии. Асфальт, бетонный забор, пасмурное небо, стена в подъезде. Без отдельного указания модель не отличит вашу дырку от снятой серой стены.
Маска и есть это указание. Одно число на клетку, зато без разночтений. Делали это так: взяли готовую модель, добавили пять входных каналов с нулевыми весами (чтобы на старте ничего не сломать) и дообучили. Для sd-1.5-inpainting это 440 тысяч шагов дообучения поверх обычной модели. Маски при обучении генерировали случайные, причём в четверти случаев закрывали кадр целиком.
Что это значит? Если вы делаете инпейнтинг обычной моделью, а половина популярных чекпойнтов с сайтов сделана без инпейнтинг-дообучения, то у вас нет этих пяти каналов. Программа как-то выкрутится, но модель будет дорисовывать область, толком не понимая, что вокруг. Отсюда вставки, которые не бьются с окружением ни по свету, ни по перспективе.
Проверяется просто: если в названии файла модели нет слова inpainting, скорее всего, каналов там четыре.
Пока всё звучит так, будто модель делает что хочет, а мы только смотрим. Это не совсем так, и стоит рассказать про инструмент, который вернул нам управление.
Проблема была очевидна с самого начала: промпт — ужасно неточный способ объяснить, что должно быть на картинке. Словами не передашь ни геометрию, ни перспективу, ни позу. Можно написать «человек стоит вполоборота», а получить что угодно.
В 2023 году Чжан, Рао и Агравала предложили ControlNet, и это, на мой взгляд, самая прорывная идея во всей теме.
Работает так. Берём обученную модель и замораживаем её, не трогаем вообще. Делаем копию её кодирующей части, и вот эту копию будем обучать. А соединяем копию с оригиналом через специальные слои, которые авторы назвали нулевыми свёртками: обычные свёртки один на один, у которых все веса на старте выставлены в ноль.

Смысл трюка в этом нуле. В самый первый момент обучения дополнительная сеть умножается на ноль и не влияет на результат вообще никак, то есть вы физически не можете испортить базовую модель на старте: она работает ровно как работала. А дальше нули постепенно растут, и управляющий сигнал начинает просачиваться. Обучать такую надстройку можно на скромных объёмах данных и без риска угробить исходную модель. Именно поэтому ControlNet за считанные месяцы оброс десятками вариантов.
Для нас это выглядит так. Вы берёте свой собственный кадр, извлекаете из него служебную карту — границы по алгоритму Кэнни, карту глубины, карту нормалей, скелет позы человека — и подаёте её модели как жёсткое ограничение. Модель теперь обязана рисовать вдоль ваших линий.
Для инпейнтинга это меняет очень многое. Классическая беда: вы дорисовываете кусок здания, и у него уезжает перспектива, линии не сходятся, окна не бьются с окнами. Дали модели карту границ с продолженными линиями — и она рисует по ним. То же с расширением кадра: без управления модель придумывает продолжение сцены как хочет, а с картой глубины, продлённой за границу кадра, она хотя бы понимает, где у нас передний план, а где задний.
Это не панацея: карту всё равно надо строить, а иногда и рисовать руками. Но это тот случай, когда инструмент из «нейросеть сделала что-то похожее» превращается в «нейросеть сделала то, что я попросил».
Справедливости ради скажу: у современных редактирующих моделей, которые работают по текстовой инструкции без масок, часть этой задачи решена внутри. Но своей геометрии они всё равно не знают, они её угадывают.
Надеюсь, я не слишком вас загрузил и после прочтения материала выше вам стало чуть понятнее, почему у нейроинструментов до сих пор большие проблемы с редактурой фото. Во второй части статьи мы продолжим разбирать проблемы диффузионок и методы их обхода. А заодно порассуждаем о том, как вообще отличить сгенерированные изображения от реальных фото.