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.1).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

모델 커스터마이징

Transformers 모델은 커스터마이징을 위해 설계되었습니다. 모델의 코드는 Transformers 저장소의 model 하위 폴더에 완전히 포함되어 있습니다. 각 폴더에는 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. PreTrainedConfig의 __init__는 모든 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)

custom-resnet 폴더에 save_pretrained()를 사용하여 구성을 JSON 파일로 저장합니다.

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 모델을 생성합니다. 하나는 hidden states를 출력하는 기본 ResNet 모델이고, 다른 하나는 이미지 분류 헤드가 포함된 ResNet 모델입니다.

ResnetModel
ResnetModelForImageClassification

block_types와 클래스 간의 매핑을 정의합니다. 나머지는 설정 클래스를 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와 호환됩니다. 다른 출력 형식의 경우, 학습을 위해 자체 학습 루프 또는 다른 라이브러리가 필요합니다.

configuration로 커스텀 모델 클래스를 인스턴스화합니다.

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

AutoClass API는 주어진 모델에 대해 올바른 아키텍처를 자동으로 로드하는 단축 방법입니다. 사용자 정의 모델을 로드하는 사용자에게 이 기능을 활성화하는 것이 편리합니다.

구성 클래스에 model_type 속성(기존 모델 유형과 달라야 함)과 모델 클래스에 config_class 속성이 있는지 확인하세요. register() 메서드를 사용하여 사용자 정의 구성과 모델을 AutoClass API에 추가합니다.

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)

사용자의 커스텀 모델 코드는 이제 AutoClass API와 호환됩니다. 사용자는 AutoModel 또는 AutoModelForImageClassification 클래스로 모델을 로드할 수 있습니다.

업로드

사용자가 쉽게 로드하고 사용할 수 있도록 Hub에 커스텀 모델을 업로드합니다.

아래와 같이 모델 디렉터리가 올바르게 구조화되어 있는지 확인하세요. 디렉터리에는 다음이 포함되어야 합니다:

  • modeling.py: ResnetModel과 ResnetModelForImageClassification의 코드를 포함합니다. 이 파일은 같은 디렉토리에 있는 다른 파일에 대해 상대적 가져오기를 사용할 수 있습니다.

Transformers의 모델 파일을 복사할 때, modeling.py 파일 상단의 모든 상대적 import를 Transformers에서 가져오도록 교체하세요.

  • configuration.py: ResnetConfig에 대한 코드를 포함합니다.
  • __init__.py: 비워둘 수 있으며, 이 파일은 Python에서 resnet_model을 모듈로 사용할 수 있게 합니다.
.
└── 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")

모델에 여러 작업을 매핑하려면 구성 JSON 파일에서 auto_map을 직접 편집하세요.

"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
노트북
hf auth login

모델에 push_to_hub()를 호출하여 모델을 Hub에 업로드합니다.

resnet50d.push_to_hub("custom-resnet50d")

사전 학습된 가중치, 구성, modeling.py 및 configuration.py 파일은 모두 이제 네임스페이스 아래 저장소에 업로드되어야 합니다.

커스텀 모델은 Transformers의 모델과 동일한 모델링 코드를 사용하지 않으므로, 로드하려면 from_pretrained()에 trust_remote_code=True를 추가해야 합니다. 자세한 내용은 커스텀 모델 로드 섹션을 참조하세요.

Update on GitHub