Отбор на проекты Controllable GenAI (AIRI) и BayesGroup (ВШЭ) 2024-2025

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

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

Все детали по заданию, данным, формату сдачи и критериям оценивания находятся ниже. Не пугайтесь большому условию, оно скорее нацелено на качественное оформление кода. Адекватные результаты можно получить даже обучая небольшие модели в Google Collab (проверено). Любые вопросы можно оставлять в Issues к этому репозиторию.

Дедлайн по сдаче задания: 27.10.2024 23:59 МСК. Дедлайн жесткий — работы, присланные после этого времени, не принимаются.

Удачи!

Оглавление

Задание

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

  • Обучить GAN.
  • Обучить диффузионную модель.

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

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

Выбор архитектуры

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

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

Ограничения

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

  • Файнтюнинг чекпойнта обученной генеративной модели
  • Прунинг
  • Дистилляцию
  • И прочие техники использующие предобученный чекпойнт

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

Разрешено пользоваться кодом из открытых источников. Например:

  • Взять код из открытых репозиториев.
  • Использовать архитектуры из библиотеки diffusers.
  • Использовать LLM.

Однако, если вы берёте чужой код:

  1. В отчете нужно указать все заимствования с ссылками на источник, даже если это LLM (см. раздел "Отчет").
  2. Необходимо переписать код так, чтобы он соответствовал шаблону из следующего раздела.

При невыполнении любого из этих пунктов мы оставляем за собой право аннулировать вашу работу.

Формат кода

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

Ещё один примермер хорошего шаблона можно найти по ссылке.

Конфиги

Для удобного управления конфигами мы используем библиотеку OmegaConf и кастомный класс ClassRegistry. Объект ClassRegistry представляет собой словарь, где ключи -- это строки, а значения -- классы (не объекты, а именно классы).

Чтобы добавить класс в ClassRegistry <registry_name>, нужно использовать декоратор @<registry_name>.add_to_registry(name=<key>). Пример:

some_registry = ClassRegistry()
 
@some_registry.add_to_registry(name="some_name")
class A:
    def __init__(self, b):
        self.b = b
 
a_class = some_registry["some_name"]
a_obj = a_class(b=2)
print(a_obj.b)  # Выведет "2"

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

Сами конфиги хранятся в директории configs/ в формате .yaml. Предполагается, что любой скрипт (например, train.py для обучения или inference.py для инференса) запускается командой:

python3 {file.py} exp.config_path=path/to/config.yaml

Дополнительными аргументами можно менять параметры конфига. Например, train.steps=100000 изменит значение config["train"]["steps"] на 100000.

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

Обучение должно воспроизводиться командой:

python3 train.py exp.config_path=path/to/train/config.yaml

Инференс:

python3 inference.py exp.config_path=path/to/inference/config.yaml train.checkpoint_path="path/to/ckpt"

Логирование

Для корректного сравнения результатов экспериментов важно их визуализировать: Сравнивать кривые лоссов, отслеживать метрики и смотреть на получаемые изображения. Для этих целей мы используем сервис Weights & Biases.

В шаблоне кода уже есть небольшой логер для wandb в training/loggers.py. Вам нужно заполнить пропуски и использовать его. Минимум, что нужно логировать:

  • Лоссы.
  • Метрики.
  • Набор сгенерированных изображений.

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

Окружение

Не забудь заполнить файл requirements.txt всеми необходимыми библиотеками. Для проверки вашей работы будет создано новое conda-окружение с указанной версией Python (обязательно укажи ее), куда установятся все зависимости из requirements.txt. Если метод не удастся запустить в этом окружении (отсутствуют библиотеки, несовместимость и т.п.), это повлечет штраф.

Данные

Вам предстоит генерировать фотографии еды: мы взяли датасет Food-101 и немного его изменили для удобства работы.

Исходный датасет содержит 101 класс еды по 1000 изображений в каждом. Оригинальные картинки находсятя в разных разрешениях, поэтому мы отфильтровали и обрезали их, чтобы все изображения имели разрешение 64×64 (после этого их стало чуть меньше). Мы разделили датасет на обучающую и тестовую выборки таким образом, что в тестовых данных для каждого класса представлено 20 изображений, а все отсальные данные в трейне.

Скачать обработанный датасет можно по ссылке.

Для удобства данные уже распределены по классам — в каждой папке изображения соответствующего класса. Однако из-за автоматической разметки небольшая часть меток может быть перепутана — считайте это своего рода аугментацией 😉.

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

Метрики

Чтобы оценить качество генерируемых моделью изображений, недостаточно нескольких примеров — нужно численно измерить, насколько хорошо она работает на больших объемах данных. Для этого мы будем использовать метрику FID (Fréchet Inception Distance). Реализовывать FID с нуля не нужно — можно использовать пакет pytorch-fid.

Нюансы подсчета FID

  1. Количество данных:

    • Для реальных изображений нужно использовать все данные из тестовой выборки.
    • Для сгенерированных данных нужно генерировать столько же изображений, сколько в тестовом наборе.
  2. Распределение меток:

    • Если модель генерирует конкретные метки, распределение классов в сгенерированном датасете должно совпадать с оригинальным.
    • Например, если класс A занимает 10% в оригинальном датасете, то и в сгенерированном он должен занимать 10%, иначе сравнение будет некорректным.

Отчет

Одна из самых важных частей задания — отчет о проделанной работе. В нем нужно кратко описать все проведенные эксперименты:

  • Что проверяет эксперимент?
  • Какие модификации были внесены?
  • Какой получился результат?

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

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

В отчете также необходимо указать:

  • Лучшую модель, ее FID и параметры обучения.
  • Отдел с заимстованиями кода: что и откуда.

В отчет можно добавить:

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

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

Оценивание

Оценка будет основана на трех критериях:

  1. Качество отчета:

    • Какие гипотезы были поставлены, и как они проверялись
    • Оформление отчёта (есть графики, картинки, по которым можно делать выводы и т.п.)
  2. Структура кода:

    • Разбиение кода на отдельные модули
    • Логирование
    • Работа с конфигами
    • Не обязательно строго следовать шаблону, досаточно придерживаться общих парадигм озвученных выше
  3. Качество финальной модели:

    • Хороший FID -- хорошая оценка
    • Красивыке картинки -- хорошая оценка

Конкретной системы баллов не даём, но гарантируем: если было приложено достаточно усилий и сделано все, как описано выше -- работа будет оценена по достоинству!

Успехов в выполнении задания!