Апскейл через sd_upscale в AUTOMATIC1111

Гайд предназначен для самой последнии версии автоматика на момент обновления рентри (см. внизу)

torch: 1.13.1
xformers: 0.0.16rc425



Проблема

Самая главная проблема - наличие поехавших фурфагов в /nai/.

Иногда хочется иметь картинки в высоком разрешении и с большой детализацией, но в наличии имеются исходные картинки только с небольшим разрешением (от 1-2 мегапикселя, после хайрез фикса). Большой детализации позволяет добиться скрипт sd_upscale.py, встроенный в webui AUTOMATIC1111.

Количество мегапикселей = Высота * Ширина / 1 000 000

Принцип работы sd_upscale

Всю работу sd_upscale глобально можно разделить на два этапа:

  1. Исходное изображение подается на ввод какому-либо апскейлеру (прескейлеру) на выбор пользователя. Прескейлер возвращает новую, проапскейленную картинку.
  2. Результат прескейла передается в img2img, где уже хайрезная картинка улучшается, и на выходе получается готовая картинка.

Поскольку у нас не бесконечно много видеопамяти и не бесконечно производительные видеокарты для работы SD, а разрешения нам нужны опизденительные, чисто-технически пункт с img2img можно разделить ещё на три подпункта. Подробнее

  1. Изображение разбивается на тайлы.
  2. Каждый тайл обрабатывается независимо друг от друга через img2img.
  3. Обработанные тайлы склеиваются и получается новое изображение.

Подготовка & Установка прескейлеров в webui

Здесь описаны некоторые важные этапы, которые необходимо выполнить перед попытками в апскейл.

Правим конфиги

Если размер VRAM у имеющейся видеокарты менее или 6 ГБ, то этот пункт можно пропускать, для такого случая он не актуален.

Но можно попытать удачу прописыванием --lowvram или --medvram.

Для апскейла с максимальным качеством (одним тайлом) стандартного ограничения ползунков в img2img по высоте (2048) не хватает.

  1. Открываем файл /ui-config.json (он лежит в одном каталоге с webui-start.bat) и ищем в нём (Ctrl+F) две строчки:
    • "img2img/Width/maximum":
    • "img2img/Height/maximum":
  2. Меняем числовые значения в этих строчках на любые по вкусу, в зависимости от количества видеопамяти. Для 12 ГБ неплохо начать с 3072.
  3. Запускаем автоматик или читаем дальше.

Апскейлеры (прескейлеры)

Встроенные в автоматик прескейлеры по какой-то причине не очень популярны, а LDSR (который тоже встроен вообще-то), сыпет ошибками при первой попытке его выбрать и начать использовать.

Следует различать нейронные апскейлеры изображений и обычные, алгоритмические, такие как Lanczos, Linear, Bicubic, Nearest, и другие.

После установки любого из прескейлеров необходимо перезапустить webui.

LDSR

  1. Нужно скачать два файла:
  2. Обязательно переименовываем их как нужно и кладём в /models/LDSR.

  3. Запускаем автоматик или читаем дальше.

Valar, UltraSharp, Remacri, тысячи их

Valar, UltraSharp, Remacri, всё это - не что иное как разновидности моделей для апскейлера обычных растровых изображений ESRGAN.

  1. Идём на вики, не пугаемся огромной страницы https://upscale.wiki/wiki/Model_Database.
  2. Ctrl+F <прескейлернейм>, например Ctrl+F valar. Скачиваем, разархивируем (если модель лежит в архиве), кладём файл с расширением .pth в /models/ESRGAN/.
  3. Запускаем автоматик.

РРЯЯЯЯЯЯ МНОГАБУКАФ А КАК АПСКЕЙЛИТЬ-ТО?!?!!??

Сначала разберёмся, как вообще включить скрипт.

Необходимо выбрать в выпадающем списке как на картинках выше пункт SD upscale. Появится дополнительное меню.

Параметры Height и Width при выбранном sd_upscale начинают управлять размерами тайла, в котором проводится img2img. Теперь это не размеры выходного файла, несмотря на то, что вроде бы ничего не поменялось.

Апскейл с максимально возможным качеством, но с относительно низким разрешением (одним тайлом)

Чем больше объем VRAM, тем большее выходное разрешение можно поставить. Для 12 ГБ максимум - около 4.4 мегапикселей.

Количество мегапикселей = Высота * Ширина / 1 000 000

  1. Вставляем нужную картинку в обычный img2img, изменяем по желанию промт (можно скопировать всё из txt2img, это же img2img как-никак).
  2. Запоминаем или записываем на бумажку/в текстовый файл/на лоб разрешение изображения, которое требуется проапскейлить.
  3. Определяемся с размерами итогового изображения.

    • Например, у нас есть картинка размерами 896x1280. Мы хотим увеличить её в 2 раза.
    • Устанавливаем Scale Factor на то число, в которое мы хотим увеличить картинку, то есть на 2.

    • Умножаем ширину в то число раз, в которое желаем увеличить картинку (2), получаем 1792. Поступаем аналогично с высотой и получаем 2560. Лучше подбирать высоту и ширину так, чтобы числа делились на 8 без остатка.
    • Записываем размеры уже в старые поля (над скриптом), высоту - в Height, ширину - в Width. Поскольку размер единственного тайла совпадает с размером итоговой картинки, в данном случае Height и Width в какой-то мере всё же являются размером выходного файла.

  4. Выбираем прескейлер что по душе.

  5. Выбираем семплер что по душе. Если семплера по душе не имеется, то DDIM с 20-40 шагов.
  6. Выбираем CFG Scale что по душе (7 по умолчанию нормально).
  7. Пока что забиваем хуй на Tile overlap, оно при единственном тайле ничего не делает.
  8. Выбираем Seed равным -1, Batch count на 1, Batch size на 1.
  9. Выбираем Denoising strength равным 0.4. То же, что и в img2img - чем больше, тем больше изменится генерация.
  10. Генерируем.
  11. Вы великолепны. Если результат не устраивает, можно поиграться с очком с семплером, CFG, с количеством шагов, с денойзом, ну и прескейлером.

Проверяем, что в консоли вывелось SD upscaling will process a total of 1 images tiled as 1x1 per upscale in a total of 1 batches. Если это не так, написано 2x2 per upscale, 1x2, 3x3, 5x4 или ещё что-нибудь - значит настройки размера тайла выставлены неправильно.

Если получаем OutOfMemoryError: CUDA out of memory - принимаем мои поздравления и возвращаемся к пункту с выбором размера картинки и уменьшаем число, во сколько раз хотим увеличить картинку. Или пробуем --medvram/--lowvram.

Апскейл с плавающим качеством, максимальной производительнсотью и требованию по VRAM (множество тайлов)

WIP: пока что можно посмотреть пункт выше, добавить к Height и Width число в Tile overlap (64 по умолчанию), загрузив предварительно уже заапскейленную вышеуказанным способом картинку. Но нужно понизить денойз, скажем до 0.2.
В консоли должно быть SD upscaling will process a total of 4 images tiled as 2x2 per upscale in a total of 4 batches.

Если требуется апскейлить дальше, то Height и Width, как и Tile overlap можно не трогать, можно просто загрузить только что проапскейленную картинку и начать процесс генерации.


Особенности апскейла с тайлами

Тема сложная и многогранная, да и применима только если тайлов больше одного. Тем кому нужно ПРОСТО увеличить картинку, читать здесь всё скорее всего не обязательно.

Повторимся, видеопамять у нас ограничена. Из-за этого мы не можем проводить img2img в огромных разрешениях вроде 32768x18432. А если бы нужная память у нас и имелась, то тут вступил бы другой не менее важный фактор: производительность.

Для решения первой проблемы существует очевидное решение - разбить картинку (после прескейла) на кусочки меньшего разрешения, которые мы можем обрабатывать без проблем, обработать каждый по отдельности и затем склеить всё обратно. Такие кусочки называются тайлами.

(картинка украдена с форча до лучших времен)

Но у этого решения есть как свои преимущества, так и недостатки...

Размер тайла и производительность

Далее пока что будем считать, что Tile overlap = 0, для простоты.

График (без lowvram/medvram) Аппроксимация функции в WolframAlpha

На первом графике показано, сколько секунд требуется на один квадартный тайл в зависимости от размера его стороны (синяя линия). На втором графике можно пронаблюдать, как количество секунд, требуемых для обработки одного тайла, возрастает кубически. Что это значит? Поскольку количество пикселей в тайле при росте размера стороны тайла возрастает квадратично, а не кубически (O^3 > O^2), можно говорить, что

Размер тайла играет принципиальную роль в скорости обработки. Чем меньше - тем быстрее, но не менее 512x512.

Аппроксимация времени работы для моей 3060 с моими параметрами без --medvram, где x - это размер стороны тайла: 5e-8*(x)**3 - 85e-6*(x)**2 + 0.065*x - 14.7

Например, у нас есть исходное изображение - 1024x1024, апскейлим в 2048x2048. Рассмотрим два случая:

  1. Тайл 512x512. По формуле выше тайл будет обрабатываться 3 секунды. По высоте нужно обработать 2048/512 = 4 тайла, по ширине аналогично 2048/512 = 4 тайла. На апскейл идут 4x4 тайла.
  2. Тайл 1024x512. Будем считать, что то же самое, что и тайл размером 724x724 (sqrt(1024*512) ~ 724), чтобы можно было подставить в формулу выше. Подставив, получаем 6.78 секунд. По высоте нужно 2048/512 = 4 тайла, по ширине 2048/1024 = 2 тайла. На апскейл идут 4x2 тайла.
    Нетрудно посчитать, что (4x4) * 3 = 48 и (4x2) * 6.78 = 54.24 дают разный результат, а значит для скорости (и меньшего потребления видеопамяти) следует апскейлить маленькими тайлами.

(512x512 медленнее, но это связано с тем, что 2048x2048 без --medvram в 12 ГБ не лезет, и c тем, что у меня включено превью)

Оригинал Тайл 512x512, 89.93 секунд Тайл 1024x512, 81.19 секунд Тайл 2048x2048, 209.66 секунд
3.1 ГБ --medvram 3.1 ГБ --medvram 10.5 ГБ --medvram

Про ускорение обсчета маленьких тайлов см. Batch size.

Нахлест тайлов (Tile overlap)

Как можно заметить, на всех апскейленных пиках выше (кроме однотайловых), есть швы. Они появляются, потому что каждый тайл считается полностью отдельно, они между собой не сообщаются, и ни на одном тайле нет областей из другого тайла.

Чтобы частично побороть это проблему, был придуман оверлап тайлов. То есть тайлы как бы частично накладываются друг на друга, а не всё время следуют друг за другом строго по очереди.

Здесь отлично проиллюстрировано, как часть первого тайла наезжает на второй тайл. Второй - на третий. Пятый - вообще на все.

Оригинал (nearest) 512x512, Tile overlap 0 576x576, Tile overlap 64 2048x2048

Как можно видеть, этот метод неплохо работает для удаления швов, но он, конечно, не идеален. Надроченный глаз всё ещё сможет отличить тайлы друг от друга по неестественным цветовым переходам в местах швов и по слегка искривлённой геометрии.

Ознакомиться с непосредственно с тем, как автоматик разбивает картинку на тайлы и как делает оверлап, можно здесь: https://github.com/AUTOMATIC1111/stable-diffusion-webui/blob/master/modules/images.py#L59.

В общем-то самое полезное, что можно найти по ссылке выше - это то, что эффективная (без оверлапа) высота и ширина тайла будет всегда меньше, чем заявленная, ровно на значение Tile overlap.

Другими словами, чтобы правильно установить размер тайла с учетом оверлапа, нужно:

  1. Выставить желаемый размер тайла.
  2. Добавить к Height и Width значение Tile overlap.

Выбор подходящего значения

Tile overlap в sd_upscale контролирует размер этого самого оверлапа. Если параметр слишком маленький, то швы будут слишком сильно выделяться, и существует риск того, что нейросеть нарисует одно и то же дважды на разных тайлах.

В большинстве ситуаций значение 64 показывает себя достаточно хорошо.

528x528, Tile overlap 16 640x640, Tile overlap 128 728x728, Tile overlap 256

Здесь ничего криминального (кроме разных глаз) ни на на 256, на на 64 нет, но и кадр не особо сложный. А вот на 16 уже видно швы.

Если размер слишком большой - может набежать разница и при склейке получится мыло на месте шва вместо деталей, или, скажем, несколько замыленных очертаний одной и той же детали.

Оригинал (из треда) 784x964, Tile overlap 64 976x1156, Tile overlap 256

Не заостряя внимания на количество пальцев и на то, что в версии с оверлапом 256 почему-то SD попытался нарисовать попу, рассмотрим апскейленные пикчи поближе.

784x964, Tile overlap 64 976x1156, Tile overlap 256
Мыло

Мыло на 256.

784x964, Tile overlap 64 976x1156, Tile overlap 256
Призрак

"Призрак" на поезде на 64.

784x964, Tile overlap 64 976x1156, Tile overlap 256

Хоть и на 256 рука заметно лучше получилась, справа можно увидеть наложенные друг на друга очертания разных рук.

Что же касается производительности, то если задавать большой Tile overlap, то img2img придётся проделывать практически одну и ту же работу в ещё больше количестве. Придётся увеличивать размер тайла, чтобы сохранить его полезную область, а значит и обрабатываться один тайл будет дольше, и требования к видеопамяти будут серьёзнее.

Denoising strength, призраки, артефакты и прочие недостатки

Denoising strength - ключевой параметр, так же как и в img2img. Чем он ближе к 1, тем больше на изображение будет наложено шума, чтобы нейросеть пыталась его убрать, создавая тем самым новое изображение. Некоторое отличие от img2img здесь в том, что шум накладывается не сразу на всё изображение, а на каждый тайл по отдельности.

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

В целом для денойза нет какого-либо определенного значения. Для разных картинок, разных моделей, разных апскейлеров, разных параметров лучше подходят разные значения, обычно не менее 0.1 и не более 0.6. Если меньше, то ничего не меняется. Если больше, то картинка может стать уже совсем другой. Лайфхак

Списочек обычно появляющихся артефактов, вызванных именно тем, что апскейл проводится по тайлам:

  • Неравномерная стилизация картинки. Сюда относятся:
    • Разные цвета одного объекта на разных тайлах
    • Неправильное размытие фона, боке, глубина резкости
    • Неодинаковые глаза
  • "Призраки"
    Нейросеть начинает видеть лица, одежду, людей, и прочую подобную хуйню в тех местах, в которых их не было
  • "Картинка в картинке"
    Нейросеть начинает рисовать какой-то свой пейзаж со своей собственной перспективой, никак к изначальному изображению вообще не относящийся. Обычно встречается на очень высоких разрешениях с слишком большим денойзом.
  • Ещё скорее всего дохуя всего...

Призраки

В sd_upscale не существует способа задать разный промт на тайлы, то есть для всех тайлов используется один и тот же промт. В общем-то чем больше тайлов, тем сильнее эта проблема выражена.

(снова прекрасная иллюстрация с заморского гайда)

Проблема должна быть очевидна. Каждый тайл содержит в себе разную информацию, но промт подаётся на них одинаковый, что приводит к возникновению лиц или даже целых людей в траве, или просто SD начинает придумывать не относящиеся к картинке детали.

Помогите Даше посчитать кошек (картинка из шизогайда)

Основные методы борьбы с призраками (но на самом деле они подходят для практически любых артефактов):

  1. Снижение Denoise strength.
    • Можно сгенерировать несколько картинок с разным денойзом, залить их в фотошоп слоями и затереть всё ненужное, что получилось на слоях с большим денойзом. Если затирания слишком выделяются, то можно ещё раз закинуть картинку в sd_upscale, но уже с Scale Factor поставленным на 1 и Upscaler на None. А можно (аккуратно) использовать inpaint с галкой Only masked.
  2. Использование больших по размеру тайлов.
  3. Убирание из промта проблемных токенов вроде 1girl, X hair, но оставление masterpiece, official art, extremely detailed unity 8k wallpaper и прочих мастерписей.
    • ЧСХ может помочь добавление в позитив out of frame, а в негатив - full body, если размер тайлов подходит.

Намеренное размытие

При апскейле тайлами очень сложно контролировать размытие фона или depth of field. Если не хочется впустую тратить время, следует просто хуярить блюры в негатив, а размытие накладывать уже после апскейла с помощью карты глубин. Подробнее - (пока что?) в шизогайде.

Изначально размытые картинки тоже даются крайне тяжело, перед апскейлом желательно как-нибудь это размытие убрать.

Batch size

WIP: Пока что так: при маленьком размере тайла можно добиться значительного ускорения обработки (вплоть до 50%) при батч сайзе, скажем, 6 или даже 8, но для этого необходимо много видеопамяти (но не больше, чем на апскейл одним тайлом с тем же количеством пикселей).


Ссылкота

Сравнение разных апскейлеров, куча картинок (можно выбрать нужный апскейлер): https://phhofm.github.io/upscale/multimodels.html
Мегастарый, но до сих пор актуальный гайд с форча: https://rentry.org/sdupscale
Шизогайд кошкоанона: https://rentry.org/sd_upscale

Edit
Pub: 01 Feb 2023 21:38 UTC
Edit: 13 Feb 2023 01:03 UTC
Views: 24987