Headerpng

Многие из вас сталкивались со Stable Diffusion и знают, что с помощью этой нейросети можно генерировать разнообразные изображения. Однако не всем интересно создавать случайные картинки с кошкодевочками, пускай даже и красивыми, и всем прочим. Согласитесь, было бы гораздо интереснее, если бы можно было обучить нейросеть создавать изображения... нас самих? Или наших любимых актёров и музыкантов? Или наших почивших родственников? Конкретных людей, в общем, а не какие-то собирательные образы из того, что было заложено при обучении нейросети. И для достижения этой цели нам потребуется обучить некую модель. Этим мы и займёмся, пытаясь определить наиболее оптимальный воркфлоу и максимально его автоматизировать.

В итоге эта задача сводится к нескольким подзадачам:

  • подготовка датасета для обучения модели;

  • непосредственно обучение модели;

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

Содержание

  1. Примечание

  2. Примеры результатов

  3. Подготовка датасета

  4. Обучение модели

    1. Основы обучения

      1. Source Model

      2. Folders

    2. Сравнение - теория

      1. Графики

      2. Сетки

    3. Сравнение - параметры

      1. Model Quick Pick | Regularisation

      2. LoRA Network Weights

      3. Batch Size

      4. Save Every N Epochs | Save Every N Steps

      5. Epoch | Total Steps | Repeats

      6. Caption Extension

      7. Precision

      8. Seed

      9. Cache Latents to Disk

      10. LR Scheduler

      11. Optimizer

      12. Optimizer Extra Arguments

      13. Learning Rate

      14. LR Warmup

      15. Max Resolution

      16. Network Rank

      17. Network Alpha

      18. Clip Skip

      19. Gradient Checkpointing

      20. CrossAttention

      21. Min SNR Gamma

      22. Don't Upscale Bucket Resolution

      23. Noise Offset

      24. Samples

    4. Сравнение - итоги

  5. Генерация изображений

    1. Установка GUI

    2. Подготовка GUI

    3. Обзор параметров

      1. Prompt

      2. Sampler

      3. CFG Scale

      4. Seed

      5. Resolution

      6. Upscaling

      7. Batching

    4. Подготовка промпта

      1. Dynamic Prompts

      2. Randomizer Keywords

      3. Checkpoint

      4. LoRA

      5. Textual Inversion

    5. X/Y/Z Plot

    6. Непосредственно генерация изображений

  6. Полезные ссылки

Примечание

Это русскоязычная и более краткая версия моего же гайда с GitHub, который там оформлен в формате wiki. Основная разница заключается в том, что в оригинале присутствует суммарно несколько сотен графиков и сеток от 1x4 до 17x21 изображений в разрешении 768x768, благодаря которым производилось сравнение разных значений разных параметров при обучении модели. Чтобы хоть кто‑то дочитал этот гайд и не умер от обилия изображений, я решил сократить часть со сравнением, оставив лишь итоги и по минимуму лишних картинок, так что самые интересующиеся могут проследовать в оригинал!

Примеры результатов

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

Примеры
Данила Поперечный | Все примеры
Данила Поперечный | Все примеры
Карина Истомина | Все примеры
Карина Истомина | Все примеры
Лана Дель Рей | Все примеры
Лана Дель Рей | Все примеры
Скриптонит | Все примеры
Скриптонит | Все примеры

Отдельно стоит отметить, что это результаты, сгенерированные уже прошлым поколением text-to-image нейросетей на базе модели Stable Diffusion 1.5 (SD1.5). Текущее поколение нейросетей на базе модели Stable Diffusion XL (SDXL) показывает совершенно другой уровень качества, однако они гораздо более требовательны к железу и алгоритмы их обучения и генерации изображений с их помощью на текущий момент и близко не оптимальны, поэтому лезть туда сейчас могу посоветовать исключительно энтузиастам. Лично я уже устал с ними бороться, так что пока занял выжидательную позицию. Тем не менее не будет лишним продемонстрировать, что могут и они.

Карина Истомина | Все примеры
Карина Истомина | Все примеры

Это результаты с применением базовой SDXL модели и LoRA модели, обученной на её основе. В то же время базовая SD1.5 модель выдаёт что-то абсолютно неприличное.

Страшно представить, что будет дальше, ведь между SD1.5 и SDXL прошло меньше года. Однако стоит отметить, что обучение моделей на базе SDXL по своей сути принципиально ничем не отличается от обучения моделей на базе SD1.5, так что всё, что мы будем разбирать дальше, применимо и к ним.

Подготовка датасета

Для обучения модели потребуются фотографии нужного человека в количестве от 10-15 штук и до бесконечности. Наиболее адекватный диапазон - 10-50 фотографий. Очень важно, чтобы на фотографиях был только один человек. Чем фотографии качественнее, тем лучше: это касается как разрешения, так и замыленности. Желательно брать максимально разнообразные фотографии: разный свет, разное окружение, разные позы, разное положение лица. Чем менее разнообразный датасет, тем более зашоренной может получиться итоговая модель. Но при этом желательно, чтобы внешность человека на фотографиях была более-менее стабильной: где-то толстый, где-то худой - нехорошо; где-то молодой, где-то старый - нехорошо; где-то есть тату на лице, где-то нет - нехорошо. Также настоятельно рекомендую обрезать фотографии до соотношения сторон 1:1, в противном случае есть вероятность, что результаты будут менее стабильными.

В общем случае, учитывая и без того некую случайность результата, на все желательные правила можно закрыть глаза и просто использовать все приличные фотографии, что у вас есть, не забыв их обрезать. Графика вроде 2D, 3D, anime, Pixar с любым датасетом получается достойно. Если же вы хотите получить что-то более-менее реалистичное и похожее на настоящие фотографии, то тут уже без качественных фотографий в датасете не обойтись, иначе лица получаются пластиковыми и мыльными.

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

Примеры
Данила Поперечный | Больше примеров
Данила Поперечный | Больше примеров
Карина Истомина | Больше примеров
Карина Истомина | Больше примеров
Лана Дель Рей | Больше примеров
Лана Дель Рей | Больше примеров
Скриптонит| Больше примеров
Скриптонит| Больше примеров

Как вы могли заметить, в половине из этих датасетов я нарушил правила, которые описывал вам, однако результаты вышли, как минимум, неплохими!

Спойлер

Так как сравнительная часть гайда будет опущена, я сразу продемонстрирую, какие результаты и на каком датасете были получены в итоге. В качестве персонажа была взята Билли Айлиш.

Результаты | Больше примеров
Результаты | Больше примеров
Датасет | Больше примеров

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

Обучение модели

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

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

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

Базовое изображение и то же изображением с применением лоры Ланы Дель Рей
Базовое изображение и то же изображением с применением лоры Ланы Дель Рей

Важный плюс, который очень сильно сыграет нам на руку, - можно обучить лору на любом чекпойнте и потом применять её ко всем чекпойнтам той же структуры. То есть обучили модель на любом чекпойнте на базе SD1.5 - можете применить ко всем чекпойнтам на базе SD1.5, аналогично для SDXL и прочих. Не на всех чекпойнтах результаты будут качественными, но технически всё будет работать.

Основы обучения

Для обучения советую использовать Kohya's GUI, который представляет из себя GUI для скриптов Kohya SS. Установка не представляет из себя ничего сложного, вы справитесь! Если у вас слабая видеокарта, то вместо локальной установки можете воспользоваться сервисами вроде Google Colab и RunPod. К сожалению, я ими не пользовался, так что помочь тут не смогу.

Пока пройдёмся по самым базовым вещам в настройках.

Source Model

Здесь вы можете загрузить и сохранить JSON конфиг для модели. В Model Quick Pick нужно выбрать чекпойнт, на котором модель будет обучаться: либо один из предложенных, который автоматически загрузится, либо custom, к которому вы можете указать путь. В каком формате сохранять результат, в целом не имеет значения, но если скачиваете модели или чекпойнты из непроверенных источников, то лучше скачивать в safetensors, так как ckpt может содержать в себе вредоносный код. Чекбоксы нужны для обучения моделей на базе SD2.0, SD2.1 и SDXL и нам не потребуются.

Folders

Output Folder - путь к папке, в которую будет сохраняться результат. Logging Folder - путь к папке, куда будут сохраняться логи обучения. В отличие от многих логов, это действительно полезные логи, которые вы сможете посмотреть, нажав на кнопку Start Tensorboard, после чего откроется окно с графиками различных параметров вашей модели. Model Output Name - название файла с моделью, по которому вы сможете использовать её при генерации изображений.

Image Folder - путь к папке с папками с изображениями для обучения. Regularisation Folder - путь к папке с папками с изображениями для регуляризации, по поводу их назначения пока не задумывайтесь. Последние две папки не такие простые, как кажется. Рассмотрим их отдельно, воспользовавшись встроенным инструментарием для подготовки папок. В дальнейшем вы можете делать это вручную.

Class Prompt - это класс сущности, на которой будет обучаться модель (man, woman, cat). Тогда как Instance Prompt - это уникальный токен модели. Очень важно, чтобы это было какое-то сочетание символов, не имеющее смысла в английском языке, иначе вместо обучения нейросети чему-то новому вы попытаетесь перезаписать её понимание указанного слова, что, скорее всего, приведёт к непредвиденным результатам. Я использую разные сочетания из 3-4 букв для каждой модели, но можно также использовать и цифры. Многие люди используют сочетание ohwx, одинаковое для всех моделей.

Вместе Instance Prompt и Class Prompt образуют своеобразный Trigger Prompt, который необходимо добавлять в промпт при генерации изображений с применением обученной лоры.

Training Images - путь к папке с изображениями для обучения модели. Repeats - это количество изучений одного изображения в ходе одной эпохи обучения. За одну эпоху обучения все изображения изучаются Repeats раз. Математика здесь простая.

Epoch\ Steps= Image\ Count * Image\ Repeats / Batch\ Size

При использовании регуляризационных изображений общее количество шагов увеличивается в 2 раза. Batch Size - это количество изображений, обрабатываемых одновременно в ходе одной эпохи.

Destination Training Directory - путь к папке, куда по нажатии кнопки Prepare Training Data будут скопированы все тренировочные и регуляризационные изображения, также там будет создана папка для логов. Кнопка Copy Info to Folders Tab скопирует пути к этим папкам во вкладку Folders, откуда мы изначально и пришли. Если теперь вы откроете папку img по указанному пути, то увидите внутри неё папку с названием вида <repeats>_<instance prompt> <class prompt>, а в reg - папку с названием вида <repeats>_<class prompt>.

Сравнение - теория

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

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

Мы пробежимся по большинству параметров из GUI: некоторые из них участвовали в сравнении и они так или иначе влияют на результат, некоторые не участвовали, потому что либо нужны не всегда, либо их достаточно задать один раз и больше не менять. Оставшиеся нерассмотренными параметры вам вряд ли потребуется трогать, однако обо всех-всех параметрах вы можете почитать в документации Kohya's GUI.


Учитывая комплексность темы и взаимосвязанность практически всех терминов и параметров, сначала обсудим основные из них.

Мы будем обучать стандартную LoRA модель, она же LoRA for Linear Layers, однако есть и другие типы этих моделей, разработанные проектом LyCORIS. Некоторые из них больше подходят для обучения конкретному стилю, а не персонажу, другие подходят для более специфичных задач. В моих опытах и гайдах, которые я читал, они не превосходили по качеству стандартные модели. Учитывая, что все они также требуют разной настройки, для упрощения сравнения они были опущены.

Следующим важным параметром, который также требует собственной настройки и напрямую влияет на качество результата, является оптимайзер. Оптимайзер отвечает за поиск наилучших значений параметров обучаемой модели. В общих словах оптимайзеры различаются алгоритмами поиска этих наилучших значений. Также есть две большие группы оптимайзеров: адаптивные и неадаптивные. Первые динамически меняют Learning Rate (LR) на основе разных параметров, тогда как вторые используют постоянный LR. Сам же LR, грубо говоря, отвечает за силу обучения модели. Если провести параллель с жизнью, то с низким LR вы можете весь семестр готовиться к экзамену, постепенно изучая тему за темой, а с высоким LR можете за ночь перед экзаменом выучить всё. В теории результат в обоих случаях будет один. В итоге, чтобы явно не задавать этот критически важный параметр руками, за основу был взят адаптивный оптимайзер DAdaptAdam, который как хорошо показывал себя в моих предыдущих экспериментах, так и в целом часто рекомендуется.

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


Раз я не могу показать вам сами сравнения целиком, давайте хоть объясню, что в них происходило. Сравнения проводились с использованием графиков из Tensorboard, которые находятся в логах, и сеток из изображений в разрешении 768x768 непосредственно из Stable Diffusion.

Графики

DLR(step)

Как выяснилось, несмотря на отсутствие необходимости вручную задавать LR, в адаптивных оптимайзерах всё равно необходимо следить за динамическим LR (DLR). Его начальное значение задаётся параметром оптимайзера d0, то есть обучение во всех случаях начинается с этого значения DLR. По умолчанию оно равно 1e-6, или 0.000001.

Step - это проход по Batch Size изучаемых изображений один раз.

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

Loss(epoch)

Loss - это неточность воспроизведения изучаемых изображений.

Epoch - это проход по всем изучаемым изображениям Repeats раз.

Таким образом, этот график показывает, как меняется схожесть с персонажем в процессе обучения. Однако его не имеет смысла оценивать вне контекста, так как изменение loss не обязательно имеет явное позитивное или негативное влияние на результат, так что он учитывался лишь при формировании вывода по параметру.

Сетки

Изображения для сеток генерировались при помощи чекпойнтов Dreamshaper 8 (DS) и Epic Realism - Pure Evolution V1 (ER). Первый отвечает за графику, а второй - за реализм.

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

Итак, большую часть времени на каждом из чекпойнтов получалось 3 сетки:

  • фиксированный сид, простой промпт - по 1 изображению на моделях, сохранённых через каждые 10% обучения;

  • фиксированный сид, сложный промпт - по 1 изображению на моделях, сохранённых через каждые 10% обучения;

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

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

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

Простой промпт - это (masterpiece:1.3), portrait, closeup. С таким промптом модель просто попытается скопировать внешность персонажа без лишней отсебятины. Этот промпт одинаковый для обоих чекпойнтов.

ER
ER
DS
DS

Сложный промпт - это (masterpiece:1.3), portrait, closeup, lavander field, sunrise, pink shirt для ER и (masterpiece:1.3), portrait, closeup, green mountains background, japan street, black hoodie для DS. С подобным промптом можно проанализировать, как модель воспроизводит персонажа в контексте, который не присутствует в изначальном датасете.

ER
ER
DS
DS

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

Длинная картинка
DS
DS

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

Сравнение - параметры

Итак, теперь, когда вы примерно понимаете, как я проводил сравнения, можем перейти непосредственно к итогам сравнений и обзору основных параметров. Мы пойдём по ним в том порядке, в котором они расположены в Kohya's GUI.

Model Quick Pick | Regularisation

Итак, Model Quick Pick - это параметр из вкладки Source model, он же путь до чекпойнта, на котором обучается модель. Если с его назначением всё ещё более-менее понятно, то что за регуляризация? В общем, во вкладке Folders нужно указать Regularisation Folder, то есть путь к папке с подпапками с регуляризационными изображениями. Я их заботливо сделал для вас. Нужно указывать путь к корневой папке man или woman в зависимости от того, чью модель вы обучаете.

И всё же что это такое и как оно работает? Честно говоря, я так и не смог найти более-менее понятное и достаточно техническое объяснение. Но суть сводится к тому, что вместе с нашими изображениями из датасета модель изучает и изображения с классом того, что изучается. То есть обучаем модель на фотографиях нашей woman - условной Билли Айлиш, а параллельно кормим её фотографиями случайных woman. В итоге она лучше понимает, что такое woman в принципе, а потому лучше генерирует и Билли Айлиш.

Раньше считалось, что в качестве регуляризационных изображений лучше использовать изображения, созданные на том же чекпойнте, на котором модель обучается. Зачастую это ужасно кривые и страшные изображения. Просто посмотрите на эту жесть. Однако не так давно стала мелькать мысль о том, что лучше использовать настоящие фотографии. Я экспериментатор, я собрал фотографии с бесплатной лицензией на Unsplash и использовал их в качестве регуляризационных изображений наряду с изображениями из разных чекпойнтов, включая SDXL. Собственно, модель с настоящими фотографиями с Unsplash субъективно победила в сравнении. Рекомендую!

Что же касается чекпойнта... Вы можете подумать, что лучше всего обучать модель и генерировать изображения на одном и том же чекпойнте. К сожалению, это практически всегда не так. Вы также можете подумать, что тогда лучше всего для обучения использовать базовый чекпойнт - SD1.5. И хотя это неплохо работает в случае с SDXL, но в случае SD1.5 результаты получаются слишком неоднозначными. Хотя выходят самые сочные цвета и самая высокая совместимость со всеми прочими чекпойнтами, сходство с обучаемым человеком присутствует лишь поверхностно. Результат получается таким, как будто мы обучили плохого близнеца. Я даже вам покажу!

Вроде бы, поверхностное сходство есть, волосюшки там и всё такое, но на самом деле получается другой человек.

А самые хорошие результаты получаются на других чекпойнтах. Один из них - это Realistic Vision 2.0. Именно 2.0, а не какая-то более поздняя версия. Изображение с примением модели на его основе как раз и представлено на картинке слева. И если я ещё могу предположить, почему он даёт такие хорошие результаты, то вот в случае со вторым чекпойнтом у меня нет практически никаких предположений. Второй - это 2.8D STABLE BEST VERSION. Фактически это какой-то нонейм чекпойнт, который почти случайно я добавил в сравнение, но он уничтожил почти всех. Опять же, добавлю немного примеров! Он везде крайний справа.

Примеры

Не везде он выдал идеальные результаты, но в сравнении это выглядит практически идеально. Изначально сравнение состояло почти из 20 чекпойнтов, так что пришлось постараться.

Итак, обязательно используйте регуляризационные изображения! И обязательно используйте в качестве них настоящие фотографии! Их тоже для пущего спокойствия лучше обрезать до соотношения сторон 1:1. Несмотря на то, что их использование увеличивает время обучения модели в 2 раза, вы в итоге всё равно выигрываете во времени, потому что из результатов вместо 95% брака вам придётся отсеивать 75% брака. Количество качественных результатов растёт в разы!

Что же касается чекпойнта, то я рекомендую натренировать по модели на каждом из них. В таком случае с помощью этих двух моделей вы сможете генерировать изображения практически на всех существующих чекпойнтах. Модели на Realistic Vision 2.0 лучше совместимы с чекпойнтами, которые также генерируют реализм, тогда как модели на 2.8D STABLE BEST VERSION лучше совместимы с чекпойнтами, которые генерируют графику. Но некоторые совместимы с обоими типами, а некоторые совместимы наоборот. В общем, однозначной логики здесь нет, так что тренируйте по модели на каждом!

LoRA Network Weights

Если ваша модель вышла недоученной или по какой-то причине обучение прервалось, здесь вы можете указать модель, которая будет выступать отправной точкой при текущем обучении. Отдельно отмечу, что обучить модель на 10 эпохах и обучить модель на 5 эпохах, потом дообучив ещё на 5 эпохах, - это почти всегда не одно и то же.

Batch Size

Этот параметр определяет количество изображений, изучаемых одновременно, как следствие уменьшая общее количество шагов обучения в Batch Size раз и сокращая общее время обучения. Желательно, чтобы он был кратен количеству изображений в датасете.

Вот как его изменение влияет на время обучения и потребление VRAM:

  • 1 - 26 min, 8.2 Gb;

  • 3 - 17 min, 9.2 Gb;

  • 11 - 15 min, 13.3 Gb.

Повышение на 1 повышает потребление VRAM примерно на 0.5 Gb. Однако повышать до упора, пока не упрётесь в предел по VRAM, нет смысла, так как в один момент наступает точка, после которой время обучения уже не падает, а потребление VRAM всё так же растёт, и если у вас много VRAM, то эта точка может наступить относительно рано.

Бытуют мнения, что при использовании значения больше 1 результат получается сравнительно хуже. В определённых случаях так и есть, однако в нашем случае умный оптимайзер подкручивает DLR таким образом, чтобы модель всегда успешно училась, из-за чего разница в качестве результатов получается минимальная.

DLR(step)
DLR(step)
Loss(epoch)
Loss(epoch)

Как итог, следует начать с 1 и поэтапно увеличивать, определив ту самую точку, начиная с которой повышение скорости обучения пропадает. Скорее всего, это будет значение в диапазоне от 2 до 5. Я использую 3.

Save Every N Epochs | Save Every N Steps

По умолчанию сохраняется только полностью обученная модель. С помощью этих параметров вы можете сохранять модель каждые N эпох или шагов. Это удобно, потому что в итоге можно выбрать лучшую из нескольких моделей. И если модель переучилась, вы можете взять более старую. Я рекомендую сохранять модель каждые 10% обучения.

Epoch | Total Steps | Repeats

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

Напомню формулу.

Total\ Steps = Epoch\ Count * Image\ Count * Repeats

Также там формально есть ещё Batch Size, а ещё нужно учесть наличие регуляризационных изображений, но нас интересует лишь чистое количество шагов.

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

Сделаем вид, что с одним числом мы немного определились. Теперь пробежимся чуть назад. Как я уже сказал, обязательно нужно использовать регуляризационные изображения. Однако необходимое их количество определяется по формуле Image Count * Repeats. И чем их больше, тем лучше. В разумных количествах. Я насобирал 330 этих изображений, так что это наш воображаемый предел. Получается, если у нас в датасете 33 изображения, то выходит, что нам нужно 10 изучений каждого, чтобы покрыть все регуляризационные изображения. И в итоге нужно будет порядка 10 эпох, чтобы набить нужное количество шагов. 10 - это в целом красивое и удобное число.

Приведу больше примеров:

  • 10 изображений в датасете, 30 изучений, 10 эпох - 3000 шагов;

  • 15 изображений в датасете, 20 изучений, 10 эпох - 3000 шагов;

  • 30 изображений в датасете, 10 изучений, 10 эпох - 3000 шагов;

  • 50 изображений в датасете, 10 изучений, 10 эпох - 5000 шагов.

В общем, на мой взгляд, с ростом датасета лучше несколько увеличивать общее количество шагов. В целом вы можете увеличить общее количество шагов в любом случае, однако учтите, что лучше это делать, увеличивая количество эпох, а не повторений. Иначе если в одной эпохе у вас будет слишком много шагов, то эпоха N может быть недоученной, а эпоха N+1 - переученной. От300 до 600 шагов на одну эпоху вполне достаточно. Но важно, чтобы шагов было не больше количества регуляризационных изображений, в нашем случае 330. А если у вас 1000 регуляризационных изображений, но при этом всего 100 шагов в эпохе, то будут использоваться только 100 из этих изображений, а не все, но каждую эпоху разные. А что будет, если шагов в эпохе больше, чем регуляризационных изображений, проверьте сами, но вряд ли что-то хорошее!

Caption Extension

Для каждого из изображений в датасете вы можете подготовить файл с ключевыми словами, в теории это должно помочь модели понять, что стоит изучать, а что нет. На практике в этом есть смысл только в том случае, если вы хотите обучить модель определённому стилю или обучить несколько разных персонажей за раз. В случае с одним персонажем модель и так прекрасно справляется.

В общем, по умолчанию это расширение .caption. Если у вас нет таких файлов рядом с изображениями в датасете, то и использоваться ничего не будет.

Mixed Precision | Save Precision

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

Числа с плавающей точкой состоят из 3 частей: знак, экспонента и мантисса. В зависимости от формата числа на экспоненту и мантиссу отводится разное количество бит:

  • fp32 - 8E, 23M;

  • fp16 - 5E, 10M;

  • bf16 - 8E, 7M.

При выборе формата bf16 или fp16 обучение модели проводится на смеси 32-битных и 16-битных данных, однако можно обучать модель исключительно на 16-битных данных, включив настройку Full fp16 Training или Full bf16 Training в зависимости от выбранного формата.

По итогам выяснилось, что использовать fp32 нет абсолютно никакого смысла, так как это очень сильно замедляет время обучения, также увеличивая потребление VRAM, но при этом никак видимо не улучшая результат. Что касается оставшихся двух вариантов, то bf16 поддерживается не на всех видеокартах. Если ваша видеокарта его поддерживает и при старте обучения не возникают ошибки, то советую использовать его. Если нет, то используйте fp16, разница всё равно практически нулевая. Также в случае bf16 можете включить Full bf16 Training, что слегка сократит потребление VRAM, однако, если её у вас с запасом, спокойнее этого не делать. Аналогичная настройка для fp16 почему-то не работает, полностью выключая обучение модели.

Seed

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

Cache Latents to Disk

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

LR Scheduler

Scheduler определяет функцию изменения LR в процессе обучения. Вот как это может выглядеть.

Здесь вы можете наблюдать функции cosine, constant и polynomial. Какие-то более изысканные включать в сравнение я не стал. В общем, cosine и polynomial оказались практически идентичными, хотя вторую можно сконфигурировать и сделать не просто линейной.

Если взглянуть на график DLR(step), то можно заметить, что DLR сначала постепенно нарастает, а потом следует функции, определённой Scheduler.

И тут же мы можем увидеть важный, казалось бы, плюс constant - в этом случае модель стабильно учится с одинаковой силой на протяжении почти всего обучения, тогда как в случае двух других функций обучение плавно затухает под конец. Можно подумать, что в этом случае результат получится лучше, однако на практике выходит иначе. И к тому же мы делаем наш оптимайзер глупее, фактически превращая его из адаптивного в неадаптивный. В общем, cosine выдаёт более стабильные и качественные результаты.

Optimizer

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

Optimizer Extra Arguments

Здесь мы можем указать дополнительные параметры оптимайзера. Посмотреть возможные параметры можно, например, в документации по оптимайзерам.

Во-первых, это параметр decouple=True. Без него модель просто-напросто не учится.

Во-вторых, это параметр use_bias_correction=True. Без него модель учится, но может выдавать вот такие артефакты.

Почему в документации эти два параметра называются иначе, вообще не понятно ¯_(ツ)_/¯.

Также можно указать параметр weight_decay, который в теории должен помочь в борьбе с переобучением модели, однако на практике оказывает довольно слабое влияние. Тем не менее, значение в диапазоне от 0.01 до 0.60 хуже не делает, а я буду использовать промежуточное значение 0.20.

Таким образом, у нас получается строка вида decouple=True use_bias_correction=True weight_decay=0.20.

Learning Rate | Text Encoder Learning Rate | UNet Learning Rate

Что такое LR, мы уже разобрались. Документация выбранного оптимайзера настойчиво рекомендует использовать значение 1, пока у нас не возникают никакие проблемы. Проблемы не возникают - мы используем 1. Такой же LR стоит указать и для Text Encoder и UNet - это два блока в архитектуре Stable Diffusion, в технический смысл которых мы не будем углубляться.

LR Warmup

Хотя документация Kohya's GUI говорит, что этот параметр влияет только на Scheduler constant_with_warmup, это не так. Если установить его в N%, тогда LR будет расти от 0 до 1 в течение N% обучения. Для 10% это будет выглядеть примерно так.

У нас умный оптимайзер, который самостоятельно разруливает всё, что связано с LR, посему не вижу смысла ему мешать. Устанавливаем в 0.

Max Resolution

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

Вот какие разрешения я сравнивал и как они влияют на время обучения и потребление VRAM:

  • 512x512 - 11 min, 8.6 Gb;

  • 768x768 - 17 min, 9.7 Gb;

  • 1024x1024 - 25 min, 10.9 Gb;

  • 1280x1280 - 39 min, 13.1 Gb.

Изначально SD1.5 был обучен на изображениях в разрешении 512x512. Многие чекпойнты на его основе были обучены на изображениях в разрешении 768x768. Так что эти два разрешения дают наиболее стабильные результаты при обучении моделей, однако 768x768 обеспечивает существенно лучшее качество и сходство с персонажем, чем 512x512, так что понижать разрешение рекомендую лишь в крайнем случае. Разрешения же выше не обеспечивают стабильный и соответствующий рост качества. Если 1024x1024 ещё может быть запасным вариантом, когда вам хочется экспериментов, хотя и периодически вызывает артефакты, то при разрешении 1280x1280 модель теряет и в сходстве с персонажем, и получает артефакты при генерации вдовесок. Также повышение разрешения при обучении далеко не значит, что вы сможете генерировать изображения в разрешении выше 768x768. Тут уж как повезёт.

В общем, не советую существенно вылезать за 768x768. Более высокие разрешения оставьте для SDXL.

Network Rank

Этот параметр условно отвечает за то, сколько информации модель может запомнить. Его изменение не сильно влияет на время обучения, но сильно влияет на потребление VRAM и вес файла модели:

  • 32 - 7.7 Gb, 37 Mb,

  • 64 - 8.0 Gb, 74 Mb,

  • 128 - 8.6 Gb, 148 Mb

  • 192 - 9.5 Gb, 221 Mb,

  • 256 - 10.0 Gb, 295 Mb,

  • 512 - 12.5 Gb, 590 Mb.

Получается, что повышение NR на 32 приводит к повышению VRAM примерно на 300 Mb и увеличению файла модели на 37 Mb.

Так как этот параметр часто вызывает споры, приведу графики.

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

Что приводит к практически идентичным графикам схожести.

Однако на практике при NR, равном 32 и 64, модель, по-моему, теряет в схожести с персонажем, а вот в остальных случаях существенной разницы я не увидел. Значения из диапазона от 128 до 256 выглядят наиболее оправданными.

Network Alpha

Этот параметр условно отвечает за то, как легко модель запоминает информацию. Однако это значение имеет смысл не само по себе, а в соотношении с NR. Другими словами, сила запоминания модели изменяется в NA/NR раз.

Однако фактически это изменение, опять же, нивелирует наш умный оптимайзер, подкручивая DLR. В итоге получается так, что, чем хуже модель запоминает, тем сильнее она учится.

Поэтому разница между возможными значениями оказывается минимальной и в теории, и на практике. В силу этого проще использовать стандартное значение 1.

Clip Skip

Этот параметр отвечает за то, с какого слоя CLIP модели векторы будут отправлены в U-Net, причём отсчёт идёт с конца. Задать его можно как при обучении модели, так и при генерации изображений. Всего этих слоёв 12, по умолчанию векторы отправляются с последнего слоя, то есть стандартное значение 1. Однако в некогда слитом Novel AI чекпойнте они отправлялись с предпоследнего слоя. Из-за того, что этот чекпойнт объединили со многими другими, нестандартное значение 2 пошло по миру.

Так говорят гайды, документация и Google. Однако даже если мы на базовом SD1.5 чекпойнте попробуем покрутить этот параметр, то он всё равно будет оказывать влияние на результат генерации, хотя, казалось бы, не должен.

Примеры

При прямом сравнении выяснилось, что разница между его комбинациями не такая сильная, однако лично мне спокойнее использовать 2 и при обучении модели, и при генерации изображений.

Gradient Checkpointing

По умолчанию в процессе обучения чекпойнт целиком загружается во VRAM. Если включить этот параметр, то чекпойнт загружается и используется постепенно, что экономит просто гигантское количество VRAM. И это совершенно не влияет на результат. Честно говоря, не понимаю, почему по умолчанию этот параметр выключен.

CrossAttention

Здесь мы можем выбрать дополнительные алгоритмы оптимизации.

xFormers - это библиотека, разработанная Meta AI. Она позволяет ускорить обучение и уменьшить потребление памяти, реализуя алгоритмы memory-efficient attention и Flash Attention. SDPA - это Scaled Dot Product Attention оптимизация. Это нативная имплементация тех же алгоритмов уже от PyTorch.

И вот как использование разных оптимизаций влияет на время обучения и потребление VRAM при использовании чекпойнта 2.8D STABLE BEST VERSION, который весит почти 7 Gb:

  • xFormers + Gradient Checkpointing - 15 min, 8.3 Gb;

  • SDPA + Gradient Checkpointing - 23 min, 8.7 Gb;

  • xFormers - 33 min, 15.6 Gb;

  • Gradient Checkpointing - Out of Memory Error.

Победитель очевиден.

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

Min SNR Gamma

Это такая техника обучения, которая должна сделать процесс обучения более стабильным.

Глазами выбрать наилучшее значение было сложно, так что предлагаю довериться документации Kohya's GUI и использовать рекомендуемое значение 5. Да и графики для него были самыми красивыми.

Don't Upscale Bucket Resolution

Bucket - это группа изображений схожего разрешения. Если вы обучаете модель на разрешении 512x512 и Bucket Resolution Steps установлен в 64, то эти самые бакеты будут 512, 448, 384 и так далее пикселей. Бакеты раздельные для разрешения по вертикали и по горизонтали. Однако изображение со стороной 500 пикселей будет помещено в бакет 448, при этом лишние 52 пикселя будут обрезаны. Если же выключить эту настройку, то изображение будет заапскейлено до 512 пикселей. Если выбирать меньшее из зол, то лучше уж пускай апскейлится, чем обрезается. Но ещё лучше собирать в датасет изображения в разрешении выше, чем то, на котором вы собираетесь учить модель.

С этими бакетами в целом много сложностей. Именно поэтому лучше стоит и обрезать все изображения до 1:1, и подбирать Batch Size кратный количеству изображений в датасете, и подбирать в датасет изображения в высоком разрешении.

Noise Offset

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

Чем больше шума мы добавляем, тем сильнее учится модель.

Однако даже это может не спасти от казусов при высоком уровне шума.

Вот как эти казусы выглядят непосредственно на результатах.

Длинная картинка

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

Samples

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

Генерировать образцы, как и сохранять модель, можно каждые N эпох или шагов. Советую точно так же делать образцы каждые 10% обучения.

В промпте для образца должен быть задействован такой контекст, который не присутствует в датасете. Например, такой промпт использую я - masterpiece, best quality, (<instance prompt> <class prompt>:1.2), green t-shirt, beach, ocean, upper body, looking at viewer --n low quality, worst quality, bad anatomy, bad composition, poor, low effort --w 768 --h 768 --l 3.5 --s 50 --d 1. Не забудьте заменить плейсхолдеры.

Сравнение - итоги

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

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

Покажу самые колоритные результаты.

Примеры

И промежуточные, и финальные результаты получились схожими по качеству. Фактически наибольшее влияние на результат оказало применение регуляризационных изображений, так что ещё раз повторю, как это важно!

Итак, если вам лень пошагово заполнять настройки по гайду, то можете воспользоваться моими конфигами. Тыц и тыц. Различаются они только тем, какой чекпойнт используется для обучения. Не забудьте заменить плейсхолдеры своими значениями! Если что-то не работает, то идите по списку и пошагово меняйте те параметры, где указано несколько возможных значений.

Генерация изображений

Самое сложное позади. Дело за малым.

Установка GUI

Итак, для генерации изображений нам понадобится GUI для работы со Stable Diffusion. Я буду использовать самый популярный - AUTOMATIC 1111. Вы можете использовать любой, но учтите, что у них есть как сходства, так и различия, поэтому не все методы и фичи, описанные далее, будут работать в других.

Установка и настройка находятся за рамками этого гайда и включают в себя много нюансов. Как и прежде, по желанию вы можете использовать Google Colab или RunPod. Вы можете либо установить чистый GUI по инструкции из него или использовать сторонний установщик. Я могу порекомендовать A1111 Web UI Installer, которым пользуюсь сам. Хотя указано, что он и устарел, на текущей работоспособности это никак не сказалось. Его создатели предлагают использовать Stability Matrix взамен, однако он несколько перегружен фичами, которые могут испугать незнакомого пользователя, поэтому решайте для себя.

Также обязательно почитайте про возможные настройки и особенно про оптимизацию. К сожалению, оптимизация включает в себя не только параметры запуска, но и некоторые системные настройки. Не будет лишним и обновить драйвера GPU.

Среди всех оптимизаций лично я использую параметр запуска --opt-sdp-no-mem-attention, также пришлось отключить Hardware Acceleration в Windows. Всё остальное если и давало какой-то буст, то минимальный.

Подготовка GUI

Во вкладке Settings нужно нажать на кнопку Show All Pages и через Ctrl + F найти quicksettings. В списке выбираете sd_vae и CLIP_stop_at_last_layers. После чего в шапке страницы жмите на Apply Settings и Reload UI.

После перезагрузки UI вы увидите две новые настройки в шапке страницы.

  • Clip Skip мы уже обсуждали, советую использовать 2.

  • VAE отвечает за декодирование итогового изображения. Нужно скачать vae-ft-mse-840000-ema-pruned и поместить в папку stable-diffusion-webui\models\VAE. После этого кликните на иконку справа от настройки, чтобы обновить список, и выберите скачанный VAE.

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

Обзор параметров

Prompt

Prompt (он же Positive Prompt) - это описание того, что вы хотите сгенерировать. Negative Prompt - это описание того, что вы не хотите сгенерировать. Лучше перечислять слова или словосочетания через запятую, а не писать полноценные предложения, как в Midjourney. Также вы можете обернуть любые слова в круглые скобки и задать вес, чтобы изменить влияние этих слов на результат. Например, (masterpiece:1.3) или (blue eyes:0.8) в позитивном промпте и (nswf:1.5) в негативном промпте. Чуть далее мы рассмотрим более комплексные параметры, которые также можно задавать в промпте.

Sampler

Sampling Method (он же Sampler) определяет метод преобразования шума в итоговое изображение в ходе Sampling Steps шагов. Сэмплер напрямую влияет на результат и время его генерации. Изменение количества шагов также влияет на время генерации. Более того, сэмплеры можно поделить на две группы по такому параметру, как convergence, то есть сходимость. Сходящиеся сэмплеры при увеличении количества шагов постепенно улучшают изначальное изображение, при этом существенно не изменяя общую сцену, тогда как несходящиеся при увеличении шагов могут изменить сцену целиком.

Длинная картинка

Среди всех сэмплеров лучшим долгое время считался DPM++ 2M Karras, так как он обеспечивает хорошие результаты за относительно малое количество шагов, при этом делает это быстро и вдобавок ещё и сходится. Однако в недавнем обновлении 1.6.0 в AUTOMATIC 1111 добавили довольно много новых сэмплеров, так что, возможно, победитель ещё изменится. Интересующимся могу посоветовать глянуть эти видео и статью по сэмплерам.

CFG Scale

CFG Scale определяет, как строго нейросеть будет следовать промпту. Чем выше это значение, тем меньше будет отсебятины. Оптимальное значение находится в диапазоне с 3 до 8. Значения за пределами диапазона могут вызвать артефакты.

Seed

Seed, как и в случае с моделями, позволяет воспроизвести результат. Если вы установили любое число больше 0, то при повторной генерации на тех же настройках вы получите то же самое изображение. Как и в случае с моделями, не всегда, так как несходящиеся сэмплеры и некоторые другие факторы могут повлиять на это. В общем, если использовать -1, то под капотом всегда будет генерироваться случайный сид, что будет приводить к случайным результатам.

Кнопка с игральным кубиком устанавливает сид в -1, а кнопка с иконкой переработки берёт сид из последнего сгенерированного изображения.

Resolution

Width и Height определяют разрешение итогового изображения. Максимальное разрешение, на котором SD1.5 выдаёт стабильные результаты, - это 768x768. На некоторых чекпойнтах оно повышается до 1024x1024, но их надо поискать. Риск возникновения артефактов там всё равно выше. Также можно генерировать не только квадратные изображения, но как будто квадратные получаются лучше всего.

Upscaling

Так как стабильно получать хорошие результаты в высоком разрешении проблематично, для решения этой проблемы используют апскейлинг. Hires Fix позволяет нам апскейлить изображения непосредственно в процессе генерации.

Upscaler - это модель, используемая для апскейлинга. Для их поиска советую почитать upscale.wiki, однако сразу могу посоветовать немного качественных:

Все апскейлеры необходимо помещать в stable-diffusion-webui\models\ESRGAN.

Hires Steps определяет количество шагов апскейлинга. Если указано 0, то это столько же, сколько в Upscaling Steps. Upscale By определяет коэффициент изменения разрешения. Denoising Strength определяет, как сильно изображение изменится в процессе апскейлинга.

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

Также апскейлить изображения можно не только непосредственно во время генерации, но и после. Для этого используются вкладки img2img и Extras. img2img - это большая и комплексная история, которая требует отдельного рассмотрения. Так что для начала могу посоветовать апскейлить во вкладке Extras, там всё довольно понятно. Также с апскейлингом отлично справляется Gigapixel AI.

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

Batching

Вы также можете генерировать множество изображений за один подход. Batch Size определяет, сколько изображений будет сгенерировано в одной группе, тогда как Batch Count определяет количество таких групп.

Подготовка промпта

Dynamic Prompts

Итак, нам потребуется несколько расширений. Первое из них - Dynamic Prompts. Оно потребуется для рандомизации промптов. Для установки идите во вкладку Extensions и скопируйте ссылку в Install from URL. После установки перезагрузите UI.

Это расширение позволит нам добавлять в промпт динамические части, которые будут меняться случайно. Суть сводится к тому, что в фигурных скобках через | можно указывать список вариантов, из которых будет выбран один случайный. Например, {day|night} city in {summer|winter|autumn|spring}. Также мы можем задать, как часто выпадает тот или иной вариант. Например, {9::day|night} приведёт к тому, что day будет выпадать 9 раз из 10. Если коэффициент не задан, то он равен 1. Частота рассчитывается относительно суммы всех коэффициентов. Например, в промпте {3::summer|4::winter|5::autumn|spring} вариант summer будет выпадать с частотой 3 / (3 + 4 + 5 + 1).

Также, чтобы не задавать огромные списки непосредственно в промпте, мы можем поместить их в отдельные файлы, где каждый вариант начинается с новой строки. Эти файлы необходимо помещать в stable-diffusion-webui\extensions\sd-dynamic-prompts\wildcards.

Например, вы можете создать файл season.txt со следующим содержанием.

summer
winter
autumn
spring

В итоге вместо {summer|winter|autumn|spring} вы сможете использовать __season__. Все подобные файлы вы можете посмотреть во вкладке Wildcards Manager.

Таким образом, мы можем описать множество сцен, сохранить их в один файл и потом использовать в промпте, каждый раз получая новую сцену в изображении. С генерацией подобных текстовых файлов отлично справляется ChatGPT. Но вы также можете использовать и мои сцены. Также можете воспользоваться моим списком различных творцов, если захотите ещё сильнее изменить результат.

Также с этим расширением поставляется хитрая штука, называемая Magic Prompt. Он дополняет ваш промпт случайными словами, используя для этого обученную текстовую модель. Именно дополняет, а не пишет с нуля, то есть последняя строка в промпте должна быть не пустой. В общем, тоже советую попробовать, в случае разнообразных экспериментов очень выручает.

Randomizer Keywords

Второе расширение - это Randomizer Keywords. С его помощью мы сможем указывать настройки для генерации изображения непосредственно в самом промпте. Уже представили, как прекрасно эти два расширения работают в совокупности? :) Например, <cfg_scale:{3|4|5|6|7}>. Но удобнее всего, что мы можем задать сам чекпойнт непосредственно в промпте, выбирая один из случайных!

Само расширение довольно неизвестное и на данный момент заброшенное, но всё ещё работающее. Частично. Хотя можно найти и более поддерживаемые и менее неизвестные расширения, такие как Unprompted, я всё ещё думаю, что первое расширение лучше. Я смог найти только эти два, так что если вы знаете какие-то ещё, обязательно дайте об этом знать! В общем, Unprompted перенасыщен различными сложными фичами, которые большинство людей вряд ли будет использовать, при этом ключевой функционал в нём невероятно забагован. А ещё для многих фич отсутствует документация, так что приходится копаться в коде, чтобы понять, что и как работает. И синтаксис у него отвратительный.

Однако и у Randomizer Keywords есть парочка несущественных проблем.

  1. Нельзя задавать width и height в промпте. Точнее, можно, но это перестало работать после какого-то обновления AUTOMATIC 1111.

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

В общем, проблемы гораздо менее существенные. Просто нужно иметь это в виду.

Checkpoint

А теперь самое время вернуться к выбору чекпойнта. Как я упоминал ранее, лоры по-разному работают на разных чекпойнтах: где-то результаты получаются хуже, где-то - лучше. В общем, я собрал список чекпойнтов, которые с применением обученной нами лоры дают наиболее стабильные и качественные результаты. Я разделил их на две категории: photo и graphic. Сами списки находятся здесь. Списки представляют из себя названия чекпойнтов и ссылки на их скачивание. Обязательно убедитесь, что скачиваете именно указанные в списке версии, так как более новые версии могут выдавать менее стабильные и менее качественные результаты. Суммарно все перечисленные чекпойнты весят порядка 150 Gb.

Помещать их нужно в stable-diffusion-webui\models\Stable-diffusion. Также настоятельно рекомендую для каждой категории чекпойнтов создать свою подпапку.

А теперь снова к рандомизации. Если вы поместили чекпойнты в папки photo и graphic, то в папке с шаблонами (stable-diffusion-webui\extensions\sd-dynamic-prompts\wildcards) вы можете создать подпапку checkpoints и в ней два файла: photo.txt и graphic.txt. В каждом из этих файлов нужно указать относительный путь к соответствующим чекпойнтам. Например, graphic\28DSTABLEBESTVERSION_28dv5.safetensors или photo\absolutereality_v181.safetensors. Оба этих файла для перечисленных выше категорий чекпойнтов вы можете скачать здесь.

После проделанных манипуляций мы можем задавать случайный чекпойнт в промпте: <checkpoint:{__checkpoints/photo__|__checkpoints/graphic__}>. Как и в случае со всеми случайными параметрами, здесь вы также можете задавать веса у каждого варианта, если хотите чаще получать фото или графику.

LoRA

Чтобы использовать обученную модель, нужно поместить её в stable-diffusion-webui\models\Lora и в промпт добавить конструкцию <lora:*model_filename*:*weight*>. Например, <lora:final_28d28:0.9>. Вес определяет, как сильно модель влияет на результат.

Не рекомендую выходить за диапазон от 0.8 до 1.2.

Также необходимо добавить в промпт Trigger Prompt, который мы обсуждали при подготовке папок. Например, (blh woman:1.2). Вес этого промпта тоже влияет на результат.

Так что и здесь перебарщивать не стоит.

Textual Inversion

Очередная интересная штука, которую можно указать в промпте, - это Textual Inversion модели. Эти модели фактически аккумулируют в себе знания о том, что должно или не должно быть сгенерировано. Например, вы можете обучить такую модель на изображениях плохо нарисованных рук, назвав её bad-hands. Тогда вместо того, чтобы писать в негативный промпт что-то вроде bad hands, extra fingers, mutated hands, вы сможете просто использовать название обученной модели bad-hands. Как итог, вы будете реже получать изображения плохо нарисованных рук.

Эти модели нужно поместить в stable-diffusion-webui\embeddings. Я рекомендую использовать, как минимум, эти:

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

X/Y/Z Plot

Это чертовски удобная фича для проведения разнообразных сравнений, которые я делал всё это время.

Рассмотрим её на примере выбора лучшей эпохи модели. Для начала задайте все параметры генерации, включая оба промпта, не забыв указать лору и Trigger Prompt. С этого момента начинается лёгкая магия. Допустим, у нас есть 10 моделей разных эпох. Очень важно, чтобы их названия подчинялись общему шаблону, так что вам придётся переименовать итоговую модель с model на model-000010. Теперь в промпте нам нужно указать модель первой эпохи: <lora:model-000001:0.9>.

А теперь ищем в самом низу страницы настройку Script и выбираем там X/Y/Z Plot. В поле с типом указываем Prompt S/R. S - это Search, R - это Replace. Суть его сводится к тому, что он ищет первое значение из указанного списка и с каждым последующим шагом по порядку заменяет его на указанные далее значения. Если в списке мы укажем 01,02,03,04,05,06,07,08,09,10, то в итоге у нас получится сетка из 10 изображений, к каждому из которых применена своя модель. В общем, если вы хотите заменить что-то в промпте, то используйте Prompt S/R, а если хотите заменить какой-то параметр генерации, то ищите его в списке. Одновременно вы можете изменить 3 параметра - по одному на каждую ось.

Обязательно попробуйте!

Непосредственно генерация изображений

Не забудьте выключить X/Y/Z Plot. Приступаем к автоматизации!

Итак, давайте предположим, что мы обучили по модели на обоих чекпойнтах и для каждой из них выбрали 8, 9 и 10 эпохи. Тогда итоговый промпт может выглядеть примерно так:

<lora:blh_final_{rv20|28d28} ({8|9|10}):{0.9|1.0|1.1}>
<checkpoint:{__checkpoints/graphic__|__checkpoints/photo__}>
<height:{9::768|1024}>
<width:{9::768|1024}>
{<sampler_name:Euler a><steps:50>|3::<sampler_name:DPM++ 2M Karras><steps:25>}
<cfg_scale:{3|4|5|6|7}>

(blh woman:1.2)

(masterpiece:1.3), portrait, closeup, __scene__, (by __artist__:{3::0|1.5})

Здесь мы выбираем одну из двух моделей одной из трёх эпох. Для этой модели мы задаём один из трёх весов. Выбираем случайный чекпойнт. В одном из 10 случаев увеличиваем высоту или ширину изображения до 1024 пикселей. Как я и говорил, сейчас эти две настройки не работают, так что их можно и даже нужно убрать, но вдруг однажды... Также мы случайно выбираем один из двух сэмплеров с количеством шагов, где второй вариант выпадает в 3 раза чаще. В основной части промпта мы выбираем из файла случайную сцену и с вероятностью 25% применяем стиль какого-то творца.

Также очень важно использовать Batch Size больше 1. Я рекомендую 6 или 9. Это необходимо из-за того, что расширение постоянно переключается между чекпойнтами, а во время смены тратится время на подгрузку чекпойнта во VRAM. В общем, если генерировать по одному изображению, то может получиться так, что смена чекпойнта занимает больше времени, чем генерация изображения.

Осталось лишь нажать на кнопку Generate ПКМ, выбрать Generate Forever, чтобы включить беконечную генерацию, и ждать, пока вам не надоест. Как только надоело, там же выбираете Cancel Generate Forever, никакие другие варианты не сработают. В качестве альтернативы бесконечной генерации можно просто задать большой Batch Count.

Собственно, вот и всё! Мы автоматизировали процесс генерации, как могли.

Полезные ссылки

Из гайда - посмотреть

Из гайда - посмотреть

Для саморазвития

Комментарии (23)


  1. Tzimie
    02.10.2023 19:27

    А вы заказы принимаете? ) моя девушка наверняка захочет такое)


    1. InfluxOW Автор
      02.10.2023 19:27

      Пытался, но так и не смог продвинуть эту услугу среди населения :) Если интересно, то TG в профиле есть, можем обсудить.


    1. RigidStyle
      02.10.2023 19:27

      ReActor, если нужно просто лицо девушки на генерацию воткнуть.
      Автор статьи пишет больше об обучении лоры на примере делающем определенное лицо, но использовать лору для лица смысла не то, что бы много, когда есть более простой способ - реактор. Лора мощный инструмент, когда нужно сделать то, что не понимает модель (ну типо если модель не видела никогда как выглядит яблоко, то она нарисует его примерно так же странно, как в страдающем средневековье рисовали заморских животных чисто по описанию словесному, никогда их не видев).
      Я лично лору использую, например, когда надо сделать какие то детали. Ну допустим модель понятия не имеет как выглядят порезы, синяки, ссадины, или как выглядит порванная одежда, разбитые машины и т.д. Тогда берется и делается лора, и модель начинает понимать, как оно выглядит.
      Автор написал что "лора встраивается межу слоями", но это не совсем так. Лора фактически добавляет к модели немного дополнительных изображений с описанием что это, что бы модель увидела то, чего никогда не видела.


      1. InfluxOW Автор
        02.10.2023 19:27

        ReActor, если нужно просто лицо девушки на генерацию воткнуть.

        Можно ссылочку? А то гугл ничего не находит. Это что-то типа roop? Если да, то лора на порядок лучше результаты выдаёт, имхо.

        Лора мощный инструмент, когда нужно сделать то, что не понимает модель

        Я лично лору использую, например, когда надо сделать какие то детали

        Это просто другой юз кейс. Фактически нейросеть точно так же не знает, как нужный нам человек выглядит, поэтому через лору мы эти знания ей прививаем.

        Автор написал что "лора встраивается межу слоями", но это не совсем так.

        Это была больше попытка втиснуть краткое техническое объяснение.


        1. Vjik
          02.10.2023 19:27

          Мой гугл нашёл такое: https://github.com/Gourieff/comfyui-reactor-node


          1. InfluxOW Автор
            02.10.2023 19:27

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


          1. InfluxOW Автор
            02.10.2023 19:27

            Всё-таки нашёл - https://github.com/Gourieff/sd-webui-reactor, это именно версия для AUTOMATIC 1111.


          1. Masonuch
            02.10.2023 19:27

            Дипфейк работает менее гибко чем LoRA, можно заменять лицо, но волосы уже нет. А с LoRA можно генерировать человека в разном возрасте даже, натренировать на прически, позы и элементы одежды, стили и так далее. Но и с Roop можно неплохо заменить лицо, если оно не сильно повернуто, и нет ярких эмоций.


      1. InfluxOW Автор
        02.10.2023 19:27
        +1

        В общем, да, погуглил и нашёл. Реактор - это форк roop.

        Микросравнение.

        База
        База
        База с лорой
        База с лорой
        Фото для переноса лица
        Фото для переноса лица
        База с roop
        База с roop
        База с reactor
        База с reactor

        В общем, на текущий момент roop и его производные и близко с лорами рядом по уровню качества не стоят. И ограничений у них слишком много.

        Например, вся графика уже точно отсекается. Выглядит, как какой-то прикол. Форма лица, волосы и все прочие особенности внешности никак не учитываются. В общем, если у вас там какое-то коллективное фото, где на расстоянии в 5 метров от объектива стоят 20 человек и тебе нужно заменить лицо одного из них, то roop справится. А если ты хочешь именно создавать какой-то более-менее уникальный контент с персонажем желаемой внешности, то тут только лоры.


        1. RigidStyle
          02.10.2023 19:27
          +1

          Если мы говорим о "лицевых" лорах, то там есть сложности. Лора так или иначе не только на лицо накладывается, но и влияет на все изображение, так как мы не знаем, что из лоры берет нейросеть, только лицо, или и что то другое (и как правило и что то другое тоже). Отсюда когда мы берем лору с лицом, то часто это может сломать генерацию, особенно если мы делаем сложную сцену (регионал промптер, маски, много КонтролНета и прочее). Что бы такого не произошло и что бы все работало нормально, лору правильней вставлять в качестве дополнительного промта в АдДетайлер, а не пихать в основной промпт, и тогда при фиксе лиц (инпейнте) при помощи АдДетайлера мы получим корректный результат, не влияющий на генерацию. Но тогда это ничем по своей сути не отличается от РеАктора.
          Повторюсь, что проблема лицевых лор не в том, что они не делают лицо, а в том, что они не дают сделать персонажа нужного, они делают персонажа таким, как в лоре (прическа и т.д.). Ну и у вас в примера тому пример. Вот сделайте вашу даму с лицом, но в таком фентезийном облачении, как на последнем кадре. Будет очень сложно, лора будет вмешиваться и уперто наряжать персонажа в зеленую футболку, немного стилизуя ее. И разница между "база" и "база с лорой" тому подтверждение. Персонаж утерян. Что бы получить такого персонажа вы будете вынуждены запихнуть лору в аддетайлер. А тогда это ничем не отличается от реактора по своей сути, просто чуть другой результат будет.

          Вот просто пример лоры лицевой. Мне надо добавить растекшуюся тушь. Персонаж - мулатка (темненькая). Но лора обучена на белых женщинах. И в итоге при добавлении лоры я получаю мулатку с высветленным лицом, которое смотрится не естественно. Я это к тому, что лора добавляет не только то, что нужно, но и все остальное, на чем она обучена. И что бы получить мулатку с растекшейся тушью, мне надо обучать лору на мулатках. И даже так, если я попытаюсь на своего конкретного персонажа добавить растекшуюся тушь, то получиться наложение лиц (усредненное лицо из лоры с растекшейся тушью) на лицо персонажа, и получиться так себе опять же. Так что с лорами довольно сложно, в том плане, что они влияют на весь кадр, и значительно, а не только на те детали, которые нужны.


          1. InfluxOW Автор
            02.10.2023 19:27
            +1

            Да, ты прав, лора сильно влияет на всю сцену целиком и ограничить область её влияния сложно. Но всё же сделать нужного персонажа мы можем, правда с некоторыми ограничениями. Например, если у нас уже есть изображение с нужным персонажем, то кидаем его в ControlNet, там включаем Canny, к нему добавляем Tile по желанию. В зависимости от весов обоих моделей получится что-то подобное тому, что ниже (я взял базу из картинок выше). По-моему, вполне аутентично: соответствует как изначальной картинке, так и внешности персонажа.

            Вот сделайте вашу даму с лицом, но в таком фентезийном облачении, как на последнем кадре.

            С этой задачей такое решение справилось отлично, я считаю, особенно с учётом того, что я потратил на него 30 секунд. Уверен, если чуть подольше повозиться, можно ещё сильнее поднять уровень сходства.

            В общем, сложно добавить лору к уже имеющемуся изображению и не похерить его. С ControlNet сделать это всё ещё не сильно просто, но уже возможно.

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


    1. Vjik
      02.10.2023 19:27

      Есть такое в виде сервиса https://www.aragon.ai/


  1. nbkgroup
    02.10.2023 19:27
    +2

    Странно, почему в "лучших каналах" отсутствует XpucT, автор Deliberate, Reliberate, LowRa, Lit и гнуснопрославленного Win10 Tweaker.

    https://www.youtube.com@XpucT

    Вот где реально толково и по-русски.


    1. InfluxOW Автор
      02.10.2023 19:27
      +1

      У меня, как и у многих людей из комьюнити, он вызывает противоречивые эмоции, так что я решил не включать его в итоговый список. Главный его плюс заключается в том, что он доносит информацию на русском языке, непосредственно же с обучением остальные люди из списка справляются лучше, как по мне.


      1. nbkgroup
        02.10.2023 19:27
        +1

        Десять минут просмотра его видео на удвоенной скорости дали больше, чем многочасовое изучение англоязычных гайдов по LORA/Textual Inversion. И дело не в языке, а в практическом опыте и понимании вопроса.


  1. iiiytn1k
    02.10.2023 19:27
    +3

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

    Скорее всего этот чекпоинт уже "знал" этот концепт, поэтому дообучить его было проще, чем обучить с нуля. Интересно было бы посмотреть на график loss в обоих случаях.

    Однако повышать до упора, пока не упрётесь в предел по VRAM, нет смысла, так как в один момент наступает точка, после которой время обучения уже не падает, а потребление VRAM всё так же растёт, и если у вас много VRAM, то эта точка может наступить относительно рано.

    Потому что упор идёт не только на объём VRAM, но и на количество CUDA ядер.

    Ещё можно отметить такие полезные опции как Color и Flip augmentation. Color augmentation случайно меняет оттенок изображения (hue) при каждой итерации (полезно при обучении лоры на стиль или если концепт персонажа это позволяет).

    Flip augmentation случайно зеркалит изображение. Некоторые искусственно увеличивают размер датасета, добавляя в него отзеркаленные копии изображений. Этот параметр позволяет избежать этого, да и даёт лучшие результаты, особенно если размер датасета небольшой.

    Один нюанс — cache latents при включении этих опций работать не будет.

    С CLIP Skip при обучении интересная вещь. В гайдах обычно пишут, что если обучаете лору на реалистичного персонажа, то ставьте этот параметр равный 1. Один раз случайно поставил CLIP Skip 2 и заметил это под конец обучения. Ну, думаю, ладно — посмотрю, что получится. И получил просто замечательные результаты. Причём эта лора прекрасно работала как с реалистичными моделями, так и с полу-реалистичными и с аниме моделями (CLIP Skip 2 при генерации), несмотря на то что она обучалась на базовой SD 1.5. Потом попробовал переобучить эту же лору с CLIP Skip 1 — результаты на полу-реалистичных и аниме моделях были гораздо хуже.


    1. InfluxOW Автор
      02.10.2023 19:27
      +1

      Скорее всего этот чекпоинт уже "знал" этот концепт, поэтому дообучить его было проще, чем обучить с нуля. Интересно было бы посмотреть на график loss в обоих случаях.

      Это график loss с применением регуляризационных изображений
      Это график loss с применением регуляризационных изображений
      Это график loss из сравнения чекпойнтов
      Это график loss из сравнения чекпойнтов

      Тут loss вообще ни о чём не говорит, так что я на него и не смотрел, делая выводы. Просто было странно, что тот же Dreamshaper показал результаты хуже. Возможно, есть ещё какие-то подобные чекпойнты, которые хорошие результаты покажут, а я лишь наткнулся на один из них. Но наткнулся вполне удачно :) Потому что я раньше всегда просто на Realistic Vision 2.0 обучал и без применения регуляризации, такая модель почти все чекпойнты сразу покрывала. А если регуляризацию к такой модели подключить, то уже не на всех графических чекпойнтах красиво получается, так что тут тот второй чекпойнт очень к месту пришёлся.

      Flip augmentation случайно зеркалит изображение. Некоторые искусственно увеличивают размер датасета, добавляя в него отзеркаленные копии изображений. Этот параметр позволяет избежать этого, да и даёт лучшие результаты, особенно если размер датасета небольшой.

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

      С CLIP Skip при обучении интересная вещь.

      У меня с Clip Skip тоже были противоречивые ситуации. В сравнениях, которые проводил в рамках гайда, существенной разницы не было, но на практике с Clip Skip 1 часто получалось хуже. Видимо, нужно было в том сравнении большую выборку чекпойнтов сделать, а не 2, как во всех остальных. Но я просто припёкся уже к некоторым настройкам, грубо говоря, так что страшно менять. С Clip Skip 2 много хороших результатов и в реализме, и в графике было, так что попытался обосновать этот выбор :)


  1. Andrey_Epifantsev
    02.10.2023 19:27

    Если у вас слабая видеокарта, то вместо локальной установки можете воспользоваться сервисами вроде Google Colab и RunPod.

    А не слабая видеокарта - это какая? Несколько месяцев назад читал статьи про переобучение нейросетей генерирующих изображения, там упоминались не то 32 гигабайта, не то 100 гигабайт памяти на борту.


    1. iiiytn1k
      02.10.2023 19:27

      Комфортно работать уже можно начиная с 2060 8Гб. Хотя я знаю человека, который работает на 1060 6Гб.


      1. RigidStyle
        02.10.2023 19:27

        Только 8 гиг мало на XL модели, а они определенно заслуживают внимания. Отсюда "комфортно" начинать с 16 гиг. А таких карт не то, что бы много. Сейчас правда нвидиа заметила что нужно рынку, и выкатывает 4060 на 16 гиг, так как стало очевидно, что все упирается не в CUDA, а в память, так что дальше будет лучше. Но до тех пор особо выбора не то, что бы много. На своем опыте, карта с 8 гигами иногда упирается в память, особенно когда начинаешь апскейлить, аутпеинтить и т.д. Это на 1.5, на XL без вариантов, XL просто не стартует. 3060 на 12 гиг полностью хватает для любой задачи на 1.5, и почти хватает на SDXL модель (иногда упирается в память все же на некоторых задачах). Но там слабовато по CUDA, на XL модели рендерит вечность картинку.


        1. iiiytn1k
          02.10.2023 19:27
          +1

          XL просто не стартует

          Когда у меня была 2060 Super на 8Гб, то с SDXL никаких проблем не испытывал — и high res. fix, и апскейл, и лоры, и контролнеты. И на автоматике и на комфи. Главное чтобы в параметрах запуска стоял xfromers и medvram. И ещё я бы рекомендовал использовать sdxl_vae_fp16_fix, благодаря которому можно генерировать без использования параметра no-half-vae (из-за которого существенно падает производительность и увеличивается расход памяти).


        1. logran
          02.10.2023 19:27
          +1

          C medvram на SDXL 3060Ti 8гб чудесно генерит 1024х1024 без каких либо трюков и почти до 2816х3584 c TiledVAE. С апскейлами, инпейнтами, контролнетами и прочим добром. А если надо еще сильнее скейлить — то там уже потайловый Ultimate SD Upscale с тайлами под 2048*2048 (с включенным tailed vae конечно) чтобы швов поменьше.


    1. InfluxOW Автор
      02.10.2023 19:27

      В идеале карточка минимум 20-ой серии от Nvidia, поддержка AMD есть не везде и не очень хорошая. У меня на 1080 Ti на одну модель уходило порядка 7 часов, но там ещё можно было оптимизировать часов до 4-5, я думаю. Потом перешёл на 4080, сейчас обучение модели, как в гайде, занимает 15-30 минут. Если смотрим именно на память, то, задавшись целью, можно обучить и на 6 Gb, но лучше иметь не меньше 8 Gb. Местами в гайде я приводил сравнения того, как тот или иной параметр влияет на рост потребления памяти, так что можно посмотреть.

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