Diffusers documentation

Философия

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v0.43.0).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Философия

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

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

Если коротко, Diffusers создан как естественное расширение PyTorch. Поэтому большинство наших проектных решений основаны на принципах проектирования PyTorch. Рассмотрим самые важные из них:

Удобство в ущерб производительности

  • Хотя Diffusers содержит множество встроенных функций для повышения производительности (см. Оптимизация и масштабирование), модели всегда загружаются с наивысшей точностью и минимальной оптимизацией. Поэтому по умолчанию диффузионные пайплайны всегда создаются на CPU с точностью float32, если пользователь не определил иное. Это обеспечивает совместимость с различными платформами и ускорителями и означает, что для запуска библиотеки не требуется сложная установка.
  • Diffusers стремится быть лёгким пакетом и поэтому имеет очень мало обязательных зависимостей, но много необязательных, которые могут улучшить производительность (например, accelerate, safetensors, onnx и т. д.). Мы стараемся сделать библиотеку максимально лёгкой, чтобы её можно было добавлять в зависимости других пакетов без лишних забот.
  • Diffusers предпочитает простой, самодостаточный код сжатому «магическому» коду. Это означает, что сокращённый синтаксис, такой как lambda-функции, и продвинутые операторы PyTorch часто нежелательны.

Просто и легко

Как утверждает PyTorch, явное лучше неявного и простое лучше сложного. Эта философия дизайна отражена в нескольких частях библиотеки:

  • Мы следуем API PyTorch, предоставляя методы вроде DiffusionPipeline.to, чтобы пользователь мог самостоятельно управлять устройствами.
  • Предпочтительнее вызывать краткие сообщения об ошибках, чем молча исправлять неверный ввод. Diffusers стремится обучать пользователя, а не делать библиотеку максимально простой в использовании.
  • Сложная логика взаимодействия модели и планировщика явно вынесена наружу, а не обрабатывается «магическим» образом внутри. Планировщики/сэмплеры отделены от диффузионных моделей и имеют минимальные взаимные зависимости. Это требует от пользователя самостоятельно написать развёрнутый цикл денойзинга. Однако такое разделение упрощает отладку и предоставляет пользователю больше контроля над адаптацией процесса денойзинга или заменой диффузионных моделей и планировщиков.
  • Отдельно обученные компоненты конвейера диффузии, например текстовый энкодер, unet и вариационный автоэнкодер, имеют собственные классы моделей. Это требует от пользователя самостоятельно управлять взаимодействием между различными компонентами модели, а формат сериализации разделяет компоненты модели на разные файлы. Однако это упрощает отладку и кастомизацию. Обучение DreamBooth или Textual Inversion очень простое благодаря возможности Diffusers разделять отдельные компоненты конвейера диффузии.

Гибкая абстракция, удобная для контрибьюторов

Во многих частях библиотеки Diffusers придерживается важного принципа проектирования, заимствованного из библиотеки Transformers: предпочтение отдаётся коду, скопированному из других мест, а не поспешным абстракциям. Этот принцип очень категоричен и резко контрастирует с популярными подходами, такими как «Не повторяйся» (DRY). Короче говоря, так же как Transformers делает это для файлов моделирования, Diffusers стремится поддерживать крайне низкий уровень абстракции и максимально самодостаточный код для пайплайнов и планировщиков. Функции, длинные блоки кода и даже классы могут дублироваться в нескольких файлах, что на первый взгляд может показаться неудачным и небрежным решением, делающим библиотеку непригодной для поддержки. Однако этот подход доказал свою высокую эффективность в Transformers и имеет большой смысл для открытых библиотек машинного обучения, развиваемых сообществом, потому что:

  • Machine Learning — это область, которая развивается чрезвычайно быстро: парадигмы, архитектуры моделей и алгоритмы постоянно меняются, что делает крайне сложным создание долговременных абстракций в коде.
  • Практики машинного обучения ценят возможность быстро вносить изменения в существующий код для генерации идей и исследований, поэтому предпочитают самодостаточный код коду с множеством абстракций.
  • Открытые библиотеки опираются на вклад сообщества, поэтому им необходимо создавать библиотеки, к которым легко вносить изменения. Чем абстрактнее код и чем больше зависимостей, тем сложнее его читать и тем труднее вносить в него изменения. Вкладчики просто перестают работать с чрезмерно абстрактными библиотеками из-за страха сломать критически важные функции. Если внесение изменений в библиотеку не может нарушить работу других фундаментальных частей кода, это не только привлекает новых потенциальных вкладчиков, но и упрощает ревью и параллельную работу над несколькими частями.

В Hugging Face мы называем такой подход политикой одного файла, что означает: почти весь код определённого класса должен быть написан в одном самодостаточном файле. Чтобы узнать больше о философии этого подхода, посмотрите этот пост в блоге.

В Diffusers мы придерживаемся этой философии для пайплайнов, планировщиков и моделей. Некоторые старые модели предшествуют этому соглашению и сохраняются без изменений; все новые архитектуры моделей находятся в собственных самодостаточных файлах. Подробности см. в разделе Models ниже.

Отлично, теперь вы в целом понимаете, почему 🧨 Diffusers устроен именно так 🤗. Мы стараемся последовательно применять эти принципы проектирования во всей библиотеке. Тем не менее, существуют некоторые незначительные отклонения от философии или неудачные решения в дизайне. Если у вас есть отзывы о проектировании, мы будем ❤️ рады услышать их напрямую на GitHub.

Детали философии проектирования

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

Пайплайны

Пайплайны, стандартные или модульные, предназначены только для инференса. Они созданы для простоты использования (поэтому не следуют принципу Simple over easy на 100%): читаемы, самоочевидны, легко настраиваются и лучше всего воспринимаются как примеры использования моделей и планировщиков. Они не обладают полным набором функций. Чтобы создать полнофункциональные пользовательские интерфейсы на базе Diffusers, используйте Modular Diffusers.

Следуются следующие принципы проектирования:

  • Pipelines следуют политике одного файла. Все pipelines находятся в отдельных каталогах под src/diffusers/pipelines. Одна папка pipeline соответствует одной статье/проекту/релизу по диффузии. Несколько файлов pipeline могут быть собраны в одной папке pipeline, как это сделано для src/diffusers/pipelines/stable-diffusion. Если pipelines имеют схожую функциональность, можно воспользоваться механизмом # Copied from.
  • Все конвейеры наследуются от DiffusionPipeline.
  • Каждый конвейер состоит из различных компонентов модели и планировщика, которые задокументированы в файле model_index.json, доступны как атрибуты конвейера под тем же именем и могут передаваться между конвейерами с помощью функции DiffusionPipeline.components.
  • Каждый пайплайн должен быть загружаемым с помощью функции DiffusionPipeline.from_pretrained.
  • Каждый пайплайн должен иметь один и только один способ запуска через метод __call__. Именование аргументов __call__ должно быть единообразным во всех пайплайнах.
  • Pipelines следует называть по задаче, которую они предназначены для решения.

Модульные Diffusers

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

Следуются следующие принципы проектирования:

  • Модульные пайплайны следуют политике одного файла. Каждый из них находится в собственной папке под src/diffusers/modular_pipelines/, а внутри папки рабочий процесс разделён на один файл на каждый этап: encoders.py, before_denoise.py, denoise.py и decoders.py. Ещё два файла завершают пайплайн. modular_blocks_<model>.py собирает этапы, а modular_pipeline.py определяет подкласс ModularPipeline для каждой модели. Модульные пайплайны не импортируют друг друга.
  • Каждый модульный конвейер определяется как набор ModularPipelineBlocks. Блоки-листья находятся в файлах стадий (encoders.py, before_denoise.py, denoise.py, decoders.py), а modular_blocks_<model>.py собирает их в полный рабочий процесс с помощью контейнерных классов, таких как SequentialPipelineBlocks и AutoPipelineBlocks. Это разделяет два понятия, которые DiffusionPipeline combines. Блок — это чистое определение. Он объявляет входные и выходные данные, а также зависимости от компонентов, но не содержит весов и не может выполняться. ModularPipeline, создаваемый с помощью .init_pipeline(repo_id), является исполняемой частью. То, что блоки не имеют состояния и весов, делает их свободно комбинируемыми, заменяемыми и переносимыми между рабочими процессами.
  • Для поддержки новой задачи напишите специфические для неё блоки, скомбинируйте их с существующими и зарегистрируйте рабочий процесс в _workflow_map на верхнем уровне сборки блоков. Один ModularPipeline может поддерживать множество рабочих процессов, таких как генерация изображений по тексту, преобразование изображения в изображение и inpainting, тогда как DiffusionPipeline выполняет только один.

См. документацию Modular Diffusers для полного руководства по проектированию и использованию.

Модели

Модели спроектированы как настраиваемые наборы инструментов, являющиеся естественным расширением класса Module в PyTorch. Они должны следовать политике одного файла. Некоторые старые модели предшествуют этому соглашению и сохраняются в неизменном виде. Рассматривайте их как устаревшие исключения, а не как образец для новых моделей. Например, исходный класс UNet2DConditionModel использовался для нескольких вариантов UNet.

Следуются следующие принципы проектирования:

  • Каждый тип архитектуры модели находится в собственной папке под src/diffusers/models, например transformers/, autoencoders/ или unets/. Каждая модельная семья имеет собственный файл в этой папке, например transformer_flux.py и transformer_wan.py.
  • Модели следуют политике одного файла. Каждый файл модели должен быть самодостаточным, за исключением небольшого числа стандартных модулей, которые каждая модель использует идентичным образом, таких как эмбеддинги временных шагов и слои нормализации. Импортируйте их из embeddings.py и normalization.py.
  • Модели призваны раскрывать сложность, подобно классу Module в PyTorch, и выдавать понятные сообщения об ошибках.
  • Все модели наследуются от ModelMixin и ConfigMixin.
  • Модели можно оптимизировать для повышения производительности, если это не требует существенных изменений в коде, сохраняет обратную совместимость и обеспечивает значительную экономию памяти или вычислительных ресурсов.
  • По умолчанию модели должны иметь наивысшую точность и наименьшую производительность.
  • Чтобы интегрировать новую архитектуру модели, похожую на существующую, скопируйте существующий файл в качестве отправной точки и адаптируйте его. Используйте аннотации # Copied from для слоёв, которые остаются идентичными, чтобы make fix-copies поддерживал их синхронизацию.

Планировщики

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

Следуются следующие принципы проектирования:

  • Все планировщики находятся в src/diffusers/schedulers.
  • Планировщикам запрещено импортировать из крупных файлов утилит; они должны быть максимально самодостаточными.
  • Один файл планировщика на Python соответствует одному алгоритму планировщика (как он может быть описан в научной статье).
  • Если планировщики имеют схожие функции, мы можем воспользоваться механизмом # Copied from.
  • Все планировщики наследуются от SchedulerMixin и ConfigMixin.
  • Планировщики можно легко заменить с помощью метода ConfigMixin.from_config, как подробно описано здесь.
  • Каждый планировщик должен иметь set_num_inference_steps и функцию step. set_num_inference_steps(...) необходимо вызывать перед каждым процессом удаления шума, то есть перед вызовом step(...).
  • Каждый планировщик предоставляет шаги, по которым необходимо «итерироваться», через атрибут timesteps, представляющий собой массив шагов, для которых будет вызываться модель.
  • Функция step(...) принимает предсказанный вывод модели и «текущий» образец (x_t) и возвращает «предыдущий», слегка менее зашумленный образец (x_t-1).
  • Учитывая сложность диффузионных планировщиков, функция step не раскрывает всю эту сложность и может восприниматься как «чёрный ящик».
  • В подавляющем большинстве случаев новые планировщики следует реализовывать в отдельном файле планирования.
Update on GitHub