Transformers documentation

Настройка моделей

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

and get access to the augmented documentation experience

to get started

Настройка моделей

Модели Transformers спроектированы так, чтобы их можно было настраивать. Код модели полностью содержится в подпапке model репозитория Transformers. Каждая папка содержит файлы modeling.py и configuration.py. Скопируйте эти файлы, чтобы начать настраивать модель.

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

В этом руководстве показано, как настроить модель ResNet, включить поддержку AutoClass и опубликовать её на Hub.

Конфигурация

Конфигурация, задаваемая базовым классом PreTrainedConfig, содержит всю необходимую информацию для построения модели. Именно здесь вы настраиваете атрибуты пользовательской модели ResNet. Различные атрибуты определяют разные типы моделей ResNet.

Основные правила настройки конфигурации:

  1. A custom configuration must subclass PreTrainedConfig. This ensures a custom model has all the functionality of a Transformers’ model such as from_pretrained(), save_pretrained(), and push_to_hub().
  2. Метод __init__ класса PreTrainedConfig должен принимать любые kwargs, и их необходимо передавать в метод __init__ родительского класса. У PreTrainedConfig больше полей, чем тех, которые вы задаёте в своей конфигурации, поэтому при загрузке конфигурации с помощью from_pretrained() эти поля должны приниматься вашей конфигурацией и передаваться в родительский класс.

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

Добавьте model_type в класс конфигурации, чтобы включить поддержку AutoClass.

from transformers import PreTrainedConfig
from typing import List

class ResnetConfig(PreTrainedConfig):
    model_type = "resnet"

    def __init__(
        self,
        block_type="bottleneck",
        layers: list[int] = [3, 4, 6, 3],
        num_classes: int = 1000,
        input_channels: int = 3,
        cardinality: int = 1,
        base_width: int = 64,
        stem_width: int = 64,
        stem_type: str = "",
        avg_down: bool = False,
        **kwargs,
    ):
        if block_type not in ["basic", "bottleneck"]:
            raise ValueError(f"`block_type` must be 'basic' or bottleneck', got {block_type}.")
        if stem_type not in ["", "deep", "deep-tiered"]:
            raise ValueError(f"`stem_type` must be '', 'deep' or 'deep-tiered', got {stem_type}.")

        self.block_type = block_type
        self.layers = layers
        self.num_classes = num_classes
        self.input_channels = input_channels
        self.cardinality = cardinality
        self.base_width = base_width
        self.stem_width = stem_width
        self.stem_type = stem_type
        self.avg_down = avg_down
        super().__init__(**kwargs)

Сохраните конфигурацию в файл JSON в вашей папке с кастомной моделью, custom-resnet, с помощью save_pretrained().

resnet50d_config = ResnetConfig(block_type="bottleneck", stem_width=32, stem_type="deep", avg_down=True)
resnet50d_config.save_pretrained("custom-resnet")

Модель

С помощью пользовательской конфигурации ResNet теперь можно создавать и настраивать модель. Модель является подклассом базового класса PreTrainedModel. Как и в случае с PreTrainedConfig, наследование от PreTrainedModel и инициализация суперкласса с конфигурацией расширяет функциональность Transformers, такую как сохранение и загрузка, для пользовательской модели.

Модели Transformers следуют конвенции, согласно которой метод __init__ принимает объект config. Это позволяет передавать весь объект config в подслои модели, а не разбивать объект config на несколько аргументов, которые передаются в подслои по отдельности.

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

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

ResnetModel
ResnetModelForImageClassification

Определите соответствие между типами блоков и классами. Всё остальное создаётся путём передачи класса конфигурации в класс модели ResNet.

Добавьте config_class в класс модели, чтобы включить поддержку AutoClass.

from transformers import PreTrainedModel
from timm.models.resnet import BasicBlock, Bottleneck, ResNet
from .configuration_resnet import ResnetConfig

BLOCK_MAPPING = {"basic": BasicBlock, "bottleneck": Bottleneck}

class ResnetModel(PreTrainedModel):
    config_class = ResnetConfig

    def __init__(self, config):
        super().__init__(config)
        block_layer = BLOCK_MAPPING[config.block_type]
        self.model = ResNet(
            block_layer,
            config.layers,
            num_classes=config.num_classes,
            in_chans=config.input_channels,
            cardinality=config.cardinality,
            base_width=config.base_width,
            stem_width=config.stem_width,
            stem_type=config.stem_type,
            avg_down=config.avg_down,
        )

    def forward(self, tensor):
        return self.model.forward_features(tensor)

Модель может возвращать любой формат вывода. Возврат словаря (как в ResnetModelForImageClassification) с потерями при наличии меток делает пользовательскую модель совместимой с Trainer. Для других форматов вывода потребуется собственный цикл обучения или другая библиотека для обучения.

Создайте экземпляр пользовательского класса модели с конфигурацией.

resnet50d = ResnetModelForImageClassification(resnet50d_config)

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

Загрузите предобученные веса из библиотеки timm, а затем перенесите их в пользовательскую модель с помощью load_state_dict.

import timm

pretrained_model = timm.create_model("resnet50d", pretrained=True)
resnet50d.model.load_state_dict(pretrained_model.state_dict())

AutoClass

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

Убедитесь, что в классе конфигурации есть атрибут model_type (он должен отличаться от существующих типов моделей), а в классе модели — атрибут config_class. Используйте метод register(), чтобы добавить пользовательскую конфигурацию и модель в API AutoClass.

Первый аргумент AutoConfig.register() должен совпадать с атрибутом model_type в пользовательском классе конфигурации, а первый аргумент AutoModel.register() должен совпадать с config_class пользовательского класса модели.

from transformers import AutoConfig, AutoModel, AutoModelForImageClassification

AutoConfig.register("resnet", ResnetConfig)
AutoModel.register(ResnetConfig, ResnetModel)
AutoModelForImageClassification.register(ResnetConfig, ResnetModelForImageClassification)

Код вашей пользовательской модели теперь совместим с API AutoClass. Пользователи могут загрузить модель с помощью классов AutoModel или AutoModelForImageClassification.

Загрузка

Загрузите собственную модель в Hub, чтобы другие пользователи могли легко её загрузить и использовать.

Убедитесь, что каталог модели структурирован правильно, как показано ниже. Каталог должен содержать:

  • modeling.py: содержит код для ResnetModel и ResnetModelForImageClassification. Этот файл может использовать относительные импорты из других файлов, если они находятся в той же директории.

При копировании файла модели Transformers замените все относительные импорты в начале файла modeling.py на импорты из Transformers.

  • configuration.py: содержит код для ResnetConfig.
  • __init__.py: может быть пустым, этот файл позволяет использовать resnet_model в Python как модуль.
.
└── resnet_model
    ├── __init__.py
    ├── configuration_resnet.py
    └── modeling_resnet.py

Чтобы поделиться моделью, импортируйте модель и конфигурацию ResNet.

from resnet_model.configuration_resnet import ResnetConfig
from resnet_model.modeling_resnet import ResnetModel, ResnetModelForImageClassification

Скопируйте код из файлов модели и конфигурации. Чтобы убедиться, что объекты AutoClass сохраняются с помощью save_pretrained(), вызовите метод register_for_auto_class(). Это изменяет JSON-файл конфигурации, добавляя в него объекты AutoClass и соответствующее отображение.

Для модели выберите подходящий класс AutoModelFor в зависимости от задачи.

ResnetConfig.register_for_auto_class()
ResnetModel.register_for_auto_class("AutoModel")
ResnetModelForImageClassification.register_for_auto_class("AutoModelForImageClassification")

Чтобы сопоставить с моделью более одной задачи, отредактируйте auto_map непосредственно в конфигурационном файле JSON.

"auto_map": {
    "AutoConfig": "<your-repo-name>--<config-name>",
    "AutoModel": "<your-repo-name>--<config-name>",
    "AutoModelFor<Task>": "<your-repo-name>--<config-name>",    
},

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

resnet50d_config = ResnetConfig(block_type="bottleneck", stem_width=32, stem_type="deep", avg_down=True)
resnet50d = ResnetModelForImageClassification(resnet50d_config)

pretrained_model = timm.create_model("resnet50d", pretrained=True)
resnet50d.model.load_state_dict(pretrained_model.state_dict())

Модель готова к публикации на Hub. Войдите в свой аккаунт Hugging Face из командной строки или ноутбука.

huggingface-CLI
notebook
hf auth login

Вызовите push_to_hub() для модели, чтобы загрузить её на Hub.

resnet50d.push_to_hub("custom-resnet50d")

Предварительно обученные веса, конфигурация, файлы modeling.py и configuration.py должны быть загружены на Hub в репозиторий в вашем пространстве имён.

Поскольку пользовательская модель не использует тот же код моделирования, что и модели Transformers, для её загрузки необходимо добавить trust_remote_code=True в from_pretrained(). Подробнее см. в разделе о загрузке пользовательских моделей.

Update on GitHub