Контракты интеграции моделей Transformers
30 июля 2026 года Transformers включил масштабируемое скалярное произведение внимания (SDPA) для T5. Побочным эффектом стало то, что декодер UMT5 мог обращаться к будущим токенам. Во время обучения он мог заглянуть в ответ, который должен был предсказывать. Ничего не завершилось с ошибкой, и баг оставался в ветке main почти два месяца.
Позже, когда мы повторно воспроизвели эти коммиты, небольшая модель UMT5, работавшая на CPU, обнаружила проблему в каждом из них. Этот пост посвящён данной модели и созданным вокруг неё тестам.
Почему баги достигают main
Transformers поддерживает более 750 типов моделей, а набор тестов огромен: более 88 000 тестов на CPU в main и более 200 000 тестов на GPU при ежедневном запуске. Тесты моделей — лишь часть этого набора: мы также тестируем пайплайны, обучение, распределённое выполнение, квантизацию и ядра внимания.
Интеграционные тесты загружают реальные чекпойнты и проверяют API модели на реальном оборудовании. Запускать всё это при каждом PR означало бы держать множество GPU занятыми весь день, что непрактично. К тому времени, когда плановый запуск обнаружит регрессию, она уже может попасть в main.
Наш подход заключается в уменьшении модели. Мы создаём фикстуру: небольшую модель, созданную на основе конфигурации реального чекпойнта, с меньшим числом и размером слоёв, но со всеми имеющимися в нём типами слоёв, а также с неизменёнными файлами токенизатора и процессора. Она публикуется один раз, а затем используется повторно. Мы запускаем на ней «быстрые интеграционные тесты» на недорогом CPU-раннере. В нашем исследовании на CPU экспериментальная фикстура UMT5 использовала 66 МБ весов; исходный чекпойнт занимает 1 227 МБ.
Это также позволяет работать с очень большими моделями: некоторые из них не помещаются на наших стандартных GPU-раннерах, но их фикстуры запускаются на CPU.
Интеграторы моделей уже создают небольшие тестовые модели (чекпойнты
Transformers tiny-random-*). Мы хотели получить единый рецепт и проверки,
выходящие за рамки загрузки модели и выполнения прямого прохода. Баг UMT5
без проблем прошёл бы прямой проход.
Фикстуры не заменят полноценные интеграционные тесты, но на PR они дают нам возможность обнаружить баги до того, как те попадут в main.
Представляем контракты интеграции моделей
transformers-mic — это предлагаемый стандарт упаковки таких тестов. Контракт интеграции модели (MIC) состоит из трёх частей:
- фикстура: описанная выше уменьшенная модель, опубликованная один раз и закреплённая
- сценарий использования: запускаемый пример в Markdown того, что люди делают с моделью, например генерируют текст или выполняют шаг обучения
- базовые результаты: результаты, записанные при выполнении этого примера и проверенные человеком
Контракт считается действующим, если выполнение сценария использования на фикстуре по-прежнему выдаёт базовые результаты.
Контракт охватывает архитектуру и сценарий использования, а не отдельный чекпойнт: совместимые чекпойнты могут использовать одну фикстуру, сохраняя собственные ожидаемые результаты. Мы публикуем их в huggingface-mic.
Например, контракт SmolLM генерирует текст по подсказкам вроде «Столица Франции —» и сравнивает идентификаторы токенов с записанным ответом. После загрузки модели и токенизатора код генерации для одной подсказки выглядит упрощённо так:
inputs = tokenizer("The capital of France is", return_tensors="pt")
outputs = model.generate(**inputs, max_new_tokens=4, do_sample=False)
new_tokens = outputs[:, inputs["input_ids"].shape[1]:]
print(tokenizer.batch_decode(new_tokens, skip_special_tokens=True))
Он также сравнивает потери при обучении, проверяет конечность градиентов и убеждается, что шаг оптимизатора изменяет веса. См. полный файл usage.md.
Датасет fleet на Hub закрепляет каждый MIC за замороженной ревизией вместе с версиями пакетов, использованными для записи его базовых результатов. Каждый запуск CI записывает использованную ревизию fleet, поэтому мы можем позднее воспроизвести его.
Для PR мы выбираем MIC на основе файлов, изменённых в патче.
Регрессия UMT5
Мы воспроизвели замороженные MIC на протяжении пяти месяцев коммитов Transformers. Небольшая фикстура UMT5 обнаруживала регрессию с момента её появления в 30 июля 2026 года до исправления в 28 сентября. Логарифмические вероятности меток отличались от проверенного базового результата на 1,22, а потери при обучении — примерно на 0,20.
Важной оказалась одна деталь: контракт использовал SDPA, путь внимания по умолчанию. Запуск только варианта с жадным вниманием не обнаруживал баг. Фикстура помогает лишь в том случае, если проходит через тот же код, что и реальный чекпойнт.
Затем мы отменили исправление в тестовой ветке Transformers CI. Проверка завершилась с ошибкой и показала те же различия, а шаг запуска выбранного контракта T5 занял на CPU 13,4 секунды без учёта настройки.
Результаты воспроизведения и демонстрация CI содержат измерения и подробности воспроизведения.
Как уменьшаются модели
Первый рецепт был простым: уменьшить размерности и оставить меньше слоёв. Этого оказалось недостаточно для смешанных архитектур. Нет смысла оставлять два слоя, если оба используют скользящее внимание, а слои с полным вниманием исчезают.
Теперь рецепт состоит из четырёх шагов:
- Уменьшить конфигурацию. Начать с реального чекпойнта и уменьшить
размеры скрытых представлений, количество голов внимания и глубину. Сохранить
различные типы слоёв, включая сочетания скользящего и полного внимания или
плотных слоёв и MoE. Для некоторых архитектур нужны дополнительные правила,
чтобы их компоненты оставались совместимыми. Мы также изучаем собственные
тесты Transformers для модели:
ModelTesterвtest_modeling_<model>.pyуже вручную выбирает небольшую конфигурацию, поэтому берём из неё размеры для любой ширины, название которой неизвестно нашему общему правилу. - Сохранить предобработку неизменной. Сохранить словарь, специальные токены и размерности входных данных, а файлы токенизатора и процессора скопировать побайтно. Загрузка и предобработка — часть того, что мы хотим тестировать.
- Создать и проверить веса. Попробовать веса со случайной инициализацией и фиксированным seed, а также изменять входные данные, чтобы проверить реакцию модели. Если она не реагирует, попробовать обучить её на небольшом пакете примеров контракта. Повторно загрузить сохранённую модель и проверить конечность выходов, потерь и градиентов. Неудачные сборки отклонить.
- Заморозить и записать. Сохранить принятые веса и измерить воспроизводимые выходы на заведомо исправной сборке Transformers. Проверить базовые результаты для каждой поддерживаемой платформы и точности, затем опубликовать закреплённый снимок. CI использует его повторно и не пересобирает фикстуру для каждого PR.
Мы также сохраняем исходный формат файла весов. В противном случае мы пропустили бы код преобразования, который выполняется при загрузке реального чекпойнта пользователем. Полный рецепт содержит дополнительные сведения.
Отчёт об уменьшении Llama 4 Scout показывает, как это выглядит на большой модели. 108,6 миллиарда параметров превращаются в 44,7 миллиона. Зрительный стек уменьшается с 34 слоёв до 2, а языковой — с 48 до 4, при этом сохраняются проверенные типы слоёв и стиль маршрутизации MoE.
Создание MIC с помощью агентов
Наш CLI tmic создаёт контракт и собирает фикстуру. Для новой модели
LLM составляет черновик кода использования и манифеста, а запуски на CPU
и GPU измеряют предполагаемые базовые результаты. LLM создаёт черновик, но
не утверждает его. Изменения ожидаемых результатов требуют проверки человеком.
Чтобы попробовать это на своей машине, подставьте свой исходный чекпойнт
вместо org/model:
pip install "transformers-mic[runtime]" "hf-doc-builder @ git+https://github.com/huggingface/doc-builder.git"
hf auth login
tmic run org/model --local-only --fixtures-only --no-history --bill-to ''
Команда создаёт черновик контракта, собирает фикстуру и записывает её
базовые результаты на вашей машине, предлагая вам проверить каждый шаг, а
затем останавливается до загрузки каких-либо данных. Для новой модели черновик
создаётся LLM через Inference Providers, а оплата списывается с вашего
собственного аккаунта (--bill-to ''). В
документации CLI
описаны отдельные шаги.
Мы использовали агентов для создания MIC для разных семейств моделей. Когда они сталкивались с особым случаем, мы исправляли сам рецепт, а не отдельную фикстуру, с помощью экспертов по моделям. Опубликованные модели и оставшиеся пробелы перечислены в пространстве покрытия.
Случайные веса и переобучение
Со случайными весами наша фикстура Whisper почти не реагировала на изменения аудио. Она запускалась, но это делало её плохим тестом аудиотракта.
Поэтому мы обучили её на нескольких тонах, сопоставленных со словами вроде «красный» и «зелёный». Мы не обучали её распознаванию речи, а лишь делали изменения аудио заметными в её выходах. В нашем исследовании инициализации весов фикстуры Whisper со случайными весами обнаружили 18 из 24 внедрённых неисправностей. Переобученные фикстуры обнаружили все 24.
Таким образом, у нас есть два способа создать веса:
- Начать со случайных весов и фиксированного seed.
- Переобучить модель на нескольких примерах, например «Столица Франции —» => «Париж».
Результат для Whisper не позволяет однозначно сказать, какой способ лучше. Это были синтетические неисправности, и мы не нашли реальной регрессии, которую обнаружила бы только переобученная версия. Обе версии не обнаружили баг с управляемым декодированием, выявленный реальным чекпойнтом Whisper.
Поэтому мы сохраняем случайные веса, если они проходят проверки, и используем переобучение, когда нам нужна более высокая чувствительность или понятные ответы. Обучение занимает секунды, но это ещё один шаг, который может не сойтись, и ещё один элемент, который нужно поддерживать. В сравнении приведены результаты для обоих вариантов.
Открытые вопросы
По состоянию на 1 ноября 2026 года задание MIC в Transformers CI сообщает об ошибках, но не блокирует PR. Следует ли ему блокировать PR, зависит от того, что мы пока не измерили:
- Сколько реальных багов оно обнаруживает в PR, а не только при воспроизведении?
- Как часто оно заставляет нас искать причины ложных тревог?
- Сколько времени занимают проверки базовых результатов?
Мы также не знаем, сколько багов, подобных багу управляемого декодирования Whisper, проявляются только на реальных весах, и обнаруживает ли переобучение реальные баги, которые пропускают случайные веса.
Покрытие по-прежнему неполное — как среди семейств моделей, так и среди используемых людьми API. Если регрессия всё же проскользнёт, мы можем добавить отсутствующий сценарий использования и воспроизвести его на сломанной и исправленной версиях. Мы будем сохранять существующие тесты, пока не учтём их покрытие.
Наконец, мы хотели бы связать исходные страницы моделей на Hub с их MIC, чтобы разработчик или агент, использующий чекпойнт, мог начать с примера, протестированного на этом чекпойнте, в его окружении и с его ожидаемыми выходами.
Хотите помочь? Выберите непокрытую модель в пространстве покрытия, попробуйте рабочий процесс tmic и добавьте сценарий использования или проверьте сгенерированный контракт.
Модели, упомянутые в этой статье 1
Датасеты, упомянутые в этой статье 1
Пространства, упомянутые в этой статье 1
Сообщество
· Зарегистрируйтесь или войдите, чтобы прокомментировать
Модели, упомянутые в этой статье 1
Датасеты, упомянутые в этой статье 1
Пространства, упомянутые в этой статье 1
Переведено автоматически с английского. Оригинал статьи — по ссылке ниже.