Transformers documentation

Tùy chỉnh mô hình

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

Tùy chỉnh mô hình

Các mô hình Transformers được thiết kế để có thể tùy chỉnh. Mã của một mô hình được chứa hoàn toàn trong thư mục con model của kho Transformers. Mỗi thư mục chứa một tệp modeling.py và một tệp configuration.py. Sao chép các tệp này để bắt đầu tùy chỉnh một mô hình.

Việc bắt đầu từ đầu có thể dễ dàng hơn nếu bạn đang tạo một mô hình hoàn toàn mới. Nhưng đối với các mô hình rất giống với một mô hình hiện có trong Transformers, việc tái sử dụng hoặc kế thừa cùng một lớp cấu hình và lớp mô hình sẽ nhanh hơn.

Hướng dẫn này sẽ cho bạn thấy cách tùy chỉnh một mô hình ResNet, bật hỗ trợ AutoClass và chia sẻ nó trên Hub.

Cấu hình

Một cấu hình, được cung cấp bởi lớp cơ sở PreTrainedConfig, chứa tất cả thông tin cần thiết để xây dựng một mô hình. Đây là nơi bạn sẽ cấu hình các thuộc tính của mô hình ResNet tùy chỉnh. Các thuộc tính khác nhau sẽ tạo ra các kiểu mô hình ResNet khác nhau.

Các quy tắc chính để tùy chỉnh cấu hình là:

  1. Một cấu hình tùy chỉnh phải kế thừa từ PreTrainedConfig. Điều này đảm bảo một mô hình tùy chỉnh có đầy đủ các chức năng của một mô hình Transformers như from_pretrained(), save_pretrained() và push_to_hub().
  2. PreTrainedConfig __init__ phải chấp nhận bất kỳ kwargs nào và chúng phải được truyền đến __init__ của lớp cha. PreTrainedConfig có nhiều trường hơn so với các trường được đặt trong cấu hình tùy chỉnh của bạn, do đó khi bạn tải một cấu hình bằng from_pretrained(), các trường đó cần được cấu hình của bạn chấp nhận và truyền đến lớp cha.

Việc kiểm tra tính hợp lệ của một số tham số là hữu ích. Trong ví dụ dưới đây, một phép kiểm tra được triển khai để đảm bảo block_type và stem_type thuộc về một trong các giá trị được định nghĩa trước.

Thêm model_type vào lớp cấu hình để bật hỗ trợ 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)

Lưu cấu hình vào một tệp JSON trong thư mục mô hình tùy chỉnh của bạn, custom-resnet, bằng save_pretrained().

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

Mô hình

Với cấu hình ResNet tùy chỉnh, bạn giờ có thể tạo và tùy chỉnh mô hình. Mô hình kế thừa từ lớp cơ sở PreTrainedModel. Giống như PreTrainedConfig, việc kế thừa từ PreTrainedModel và khởi tạo siêu lớp với cấu hình sẽ mở rộng các chức năng của Transformers như lưu và tải lên mô hình tùy chỉnh.

Các mô hình của Transformers tuân theo quy ước chấp nhận một đối tượng config trong phương thức __init__. Điều này truyền toàn bộ config đến các lớp con của mô hình, thay vì tách đối tượng config thành nhiều tham số riêng lẻ để truyền từng cái đến các lớp con.

Việc viết model theo cách này tạo ra mã đơn giản hơn với một nguồn sự thật rõ ràng cho bất kỳ siêu tham số nào. Nó cũng giúp dễ dàng tái sử dụng mã từ các model khác của Transformers.

Bạn sẽ tạo hai mô hình ResNet, một mô hình ResNet cơ bản chỉ xuất ra các trạng thái ẩn và một mô hình ResNet có đầu phân loại hình ảnh.

ResnetModel
ResnetModelForImageClassification

Định nghĩa ánh xạ giữa các kiểu khối và các lớp. Mọi thứ khác được tạo ra bằng cách truyền lớp cấu hình vào lớp mô hình ResNet.

Thêm config_class vào lớp mô hình để bật hỗ trợ 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)

Một model có thể trả về bất kỳ định dạng đầu ra nào. Việc trả về một dictionary (như ResnetModelForImageClassification) chứa losses khi có labels sẽ giúp model tùy chỉnh tương thích với Trainer. Đối với các định dạng đầu ra khác, bạn sẽ cần một training loop riêng hoặc một thư viện khác để huấn luyện.

Khởi tạo lớp mô hình tùy chỉnh với cấu hình.

resnet50d = ResnetModelForImageClassification(resnet50d_config)

Tại thời điểm này, bạn có thể nạp trọng số được huấn luyện trước vào mô hình hoặc huấn luyện nó từ đầu. Trong hướng dẫn này, bạn sẽ nạp trọng số được huấn luyện trước.

Tải trọng số được huấn luyện trước từ thư viện timm, sau đó chuyển những trọng số đó sang mô hình tùy chỉnh bằng 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 là một cách tắt để tự động tải đúng kiến trúc cho một mô hình nhất định. Việc bật tính năng này sẽ tiện lợi cho người dùng khi tải mô hình tùy chỉnh của bạn.

Hãy đảm bảo bạn có thuộc tính model_type (phải khác với các loại model hiện có) trong lớp cấu hình và thuộc tính config_class trong lớp model. Sử dụng phương thức register() để thêm cấu hình và model tùy chỉnh vào API AutoClass.

Đối số đầu tiên của AutoConfig.register() phải khớp với thuộc tính model_type trong lớp cấu hình tùy chỉnh, và đối số đầu tiên của AutoModel.register() phải khớp với config_class của lớp mô hình tùy chỉnh.

from transformers import AutoConfig, AutoModel, AutoModelForImageClassification

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

Mã mô hình tùy chỉnh của bạn giờ đây tương thích với API AutoClass. Người dùng có thể tải mô hình bằng các lớp AutoModel hoặc AutoModelForImageClassification.

Tải lên

Tải lên một mô hình tùy chỉnh lên Hub để cho phép các người dùng khác dễ dàng tải và sử dụng nó.

Đảm bảo thư mục mô hình được cấu trúc đúng như minh họa bên dưới. Thư mục phải chứa:

  • modeling.py: Chứa mã nguồn của ResnetModel và ResnetModelForImageClassification. Tệp này có thể dựa vào các import tương đối đến các tệp khác miễn là chúng nằm trong cùng một thư mục.

Khi sao chép tệp mô hình của Transformers, hãy thay thế tất cả các lệnh import tương đối ở đầu tệp modeling.py để import từ Transformers.

  • configuration.py: Chứa mã nguồn của ResnetConfig.
  • __init__.py: Có thể để trống, tệp này cho phép Python sử dụng resnet_model như một module.
.
└── resnet_model
    ├── __init__.py
    ├── configuration_resnet.py
    └── modeling_resnet.py

Để chia sẻ mô hình, hãy nhập mô hình và cấu hình ResNet.

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

Sao chép mã từ các tệp mô hình và cấu hình. Để đảm bảo các đối tượng AutoClass được lưu bằng save_pretrained(), hãy gọi phương thức register_for_auto_class(). Thao tác này sẽ sửa đổi tệp JSON cấu hình để bao gồm các đối tượng AutoClass và ánh xạ.

Đối với một mô hình, hãy chọn lớp AutoModelFor phù hợp dựa trên tác vụ.

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

Để ánh xạ nhiều hơn một tác vụ vào mô hình, hãy chỉnh sửa trực tiếp auto_map trong tệp cấu hình JSON.

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

Tạo cấu hình và mô hình, sau đó nạp trọng số được huấn luyện trước vào đó.

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())

Mô hình đã sẵn sàng để đẩy lên Hub. Hãy đăng nhập vào tài khoản Hugging Face của bạn từ dòng lệnh hoặc notebook.

huggingface-CLI
notebook
hf auth login

Gọi push_to_hub() trên mô hình để tải mô hình lên Hub.

resnet50d.push_to_hub("custom-resnet50d")

Trọng số được huấn luyện trước, cấu hình, các tệp modeling.py và configuration.py hiện nên được tải lên Hub trong một repository dưới namespace của bạn.

Vì một model tùy chỉnh không sử dụng mã modeling giống như model của Transformers, bạn cần thêm trust_remote_code=True trong from_pretrained() để tải nó. Xem phần tải model tùy chỉnh để biết thêm thông tin.

Update on GitHub