| <!--Copyright 2020 The HuggingFace Team. All rights reserved. | |
| Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with | |
| the License. You may obtain a copy of the License at | |
| http://www.apache.org/licenses/LICENSE-2.0 | |
| Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on | |
| an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the | |
| specific language governing permissions and limitations under the License. | |
| โ ๏ธ Note that this file is in Markdown but contain specific syntax for our doc-builder (similar to MDX) that may not be | |
| rendered properly in your Markdown viewer. | |
| --> | |
| # ์ฌ์ฉ์ ์ ์ ๋ชจ๋ธ ๊ณต์ ํ๊ธฐ[[sharing-custom-models]] | |
| ๐ค Transformers ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์ฝ๊ฒ ํ์ฅํ ์ ์๋๋ก ์ค๊ณ๋์์ต๋๋ค. | |
| ๋ชจ๋ ๋ชจ๋ธ์ ์ถ์ํ ์์ด ์ ์ฅ์์ ์ง์ ๋ ํ์ ํด๋์ ์์ ํ ์ฝ๋ฉ๋์ด ์์ผ๋ฏ๋ก, ์์ฝ๊ฒ ๋ชจ๋ธ๋ง ํ์ผ์ ๋ณต์ฌํ๊ณ ํ์์ ๋ฐ๋ผ ์กฐ์ ํ ์ ์์ต๋๋ค. | |
| ์์ ํ ์๋ก์ด ๋ชจ๋ธ์ ๋ง๋๋ ๊ฒฝ์ฐ์๋ ์ฒ์๋ถํฐ ์์ํ๋ ๊ฒ์ด ๋ ์ฌ์ธ ์ ์์ต๋๋ค. | |
| ์ด ํํ ๋ฆฌ์ผ์์๋ Transformers ๋ด์์ ์ฌ์ฉํ ์ ์๋๋ก ์ฌ์ฉ์ ์ ์ ๋ชจ๋ธ๊ณผ ๊ตฌ์ฑ์ ์์ฑํ๋ ๋ฐฉ๋ฒ๊ณผ | |
| ๐ค Transformers ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์๋ ๊ฒฝ์ฐ์๋ ๋๊ตฌ๋ ์ฌ์ฉํ ์ ์๋๋ก (์์กด์ฑ๊ณผ ํจ๊ป) ์ปค๋ฎค๋ํฐ์ ๊ณต์ ํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์ธ ์ ์์ต๋๋ค. | |
| [timm ๋ผ์ด๋ธ๋ฌ๋ฆฌ](https://github.com/rwightman/pytorch-image-models)์ ResNet ํด๋์ค๋ฅผ [`PreTrainedModel`]๋ก ๋ํํ ResNet ๋ชจ๋ธ์ ์๋ก ๋ชจ๋ ๊ฒ์ ์ค๋ช ํฉ๋๋ค. | |
| ## ์ฌ์ฉ์ ์ ์ ๊ตฌ์ฑ ์์ฑํ๊ธฐ[[writing-a-custom-configuration]] | |
| ๋ชจ๋ธ์ ๋ค์ด๊ฐ๊ธฐ ์ ์ ๋จผ์ ๊ตฌ์ฑ์ ์์ฑํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค. | |
| ๋ชจ๋ธ์ `configuration`์ ๋ชจ๋ธ์ ๋ง๋ค๊ธฐ ์ํด ํ์ํ ๋ชจ๋ ์ค์ํ ๊ฒ๋ค์ ํฌํจํ๊ณ ์๋ ๊ฐ์ฒด์ ๋๋ค. | |
| ๋ค์ ์น์ ์์ ๋ณผ ์ ์๋ฏ์ด, ๋ชจ๋ธ์ `config`๋ฅผ ์ฌ์ฉํด์๋ง ์ด๊ธฐํํ ์ ์๊ธฐ ๋๋ฌธ์ ์๋ฒฝํ ๊ตฌ์ฑ์ด ํ์ํฉ๋๋ค. | |
| ์๋ ์์์์๋ ResNet ํด๋์ค์ ์ธ์(argument)๋ฅผ ์กฐ์ ํด๋ณด๊ฒ ์ต๋๋ค. | |
| ๋ค๋ฅธ ๊ตฌ์ฑ์ ๊ฐ๋ฅํ ResNet ์ค ๋ค๋ฅธ ์ ํ์ ์ ๊ณตํฉ๋๋ค. | |
| ๊ทธ๋ฐ ๋ค์ ๋ช ๊ฐ์ง ์ ํจ์ฑ์ ํ์ธํ ํ ํด๋น ์ธ์๋ฅผ ์ ์ฅํฉ๋๋ค. | |
| ```python | |
| 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) | |
| ``` | |
| ์ฌ์ฉ์ ์ ์ `configuration`์ ์์ฑํ ๋ ๊ธฐ์ตํด์ผ ํ ์ธ ๊ฐ์ง ์ค์ํ ์ฌํญ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค: | |
| - `PretrainedConfig`์ ์์ํด์ผ ํฉ๋๋ค. | |
| - `PretrainedConfig`์ `__init__`์ ๋ชจ๋ kwargs๋ฅผ ํ์ฉํด์ผ ํ๊ณ , | |
| - ์ด๋ฌํ `kwargs`๋ ์์ ํด๋์ค `__init__`์ ์ ๋ฌ๋์ด์ผ ํฉ๋๋ค. | |
| ์์์ ๐ค Transformers ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ๋ชจ๋ ๊ธฐ๋ฅ์ ๊ฐ์ ธ์ค๋ ๊ฒ์ ๋๋ค. | |
| ์ด๋ฌํ ์ ์ผ๋ก๋ถํฐ ๋น๋กฏ๋๋ ๋ ๊ฐ์ง ์ ์ฝ ์กฐ๊ฑด์ `PretrainedConfig`์ ์ค์ ํ๋ ๊ฒ๋ณด๋ค ๋ ๋ง์ ํ๋๊ฐ ์์ต๋๋ค. | |
| `from_pretrained` ๋ฉ์๋๋ก ๊ตฌ์ฑ์ ๋ค์ ๋ก๋ํ ๋ ํด๋น ํ๋๋ ๊ตฌ์ฑ์์ ์๋ฝํ ํ ์์ ํด๋์ค๋ก ๋ณด๋ด์ผ ํฉ๋๋ค. | |
| ๋ชจ๋ธ์ auto ํด๋์ค์ ๋ฑ๋กํ์ง ์๋ ํ, `configuration`์์ `model_type`์ ์ ์(์ฌ๊ธฐ์ `model_type="resnet"`)ํ๋ ๊ฒ์ ํ์ ์ฌํญ์ด ์๋๋๋ค (๋ง์ง๋ง ์น์ ์ฐธ์กฐ). | |
| ์ด๋ ๊ฒ ํ๋ฉด ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ค๋ฅธ ๋ชจ๋ธ ๊ตฌ์ฑ๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ๊ตฌ์ฑ์ ์ฝ๊ฒ ๋ง๋ค๊ณ ์ ์ฅํ ์ ์์ต๋๋ค. | |
| ๋ค์์ resnet50d ๊ตฌ์ฑ์ ์์ฑํ๊ณ ์ ์ฅํ๋ ๋ฐฉ๋ฒ์ ๋๋ค: | |
| ```py | |
| resnet50d_config = ResnetConfig(block_type="bottleneck", stem_width=32, stem_type="deep", avg_down=True) | |
| resnet50d_config.save_pretrained("custom-resnet") | |
| ``` | |
| ์ด๋ ๊ฒ ํ๋ฉด `custom-resnet` ํด๋ ์์ `config.json`์ด๋ผ๋ ํ์ผ์ด ์ ์ฅ๋ฉ๋๋ค. | |
| ๊ทธ๋ฐ ๋ค์ `from_pretrained` ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ๊ตฌ์ฑ์ ๋ค์ ๋ก๋ํ ์ ์์ต๋๋ค. | |
| ```py | |
| resnet50d_config = ResnetConfig.from_pretrained("custom-resnet") | |
| ``` | |
| ๊ตฌ์ฑ์ Hub์ ์ง์ ์ ๋ก๋ํ๊ธฐ ์ํด [`PretrainedConfig`] ํด๋์ค์ [`~PretrainedConfig.push_to_hub`]์ ๊ฐ์ ๋ค๋ฅธ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. | |
| ## ์ฌ์ฉ์ ์ ์ ๋ชจ๋ธ ์์ฑํ๊ธฐ[[writing-a-custom-model]] | |
| ์ด์ ResNet ๊ตฌ์ฑ์ด ์์ผ๋ฏ๋ก ๋ชจ๋ธ์ ์์ฑํ ์ ์์ต๋๋ค. | |
| ์ค์ ๋ก๋ ๋ ๊ฐ๋ฅผ ์์ฑํ ๊ฒ์ ๋๋ค. ํ๋๋ ์ด๋ฏธ์ง ๋ฐฐ์น์์ hidden features๋ฅผ ์ถ์ถํ๋ ๊ฒ([`BertModel`]๊ณผ ๊ฐ์ด), ๋ค๋ฅธ ํ๋๋ ์ด๋ฏธ์ง ๋ถ๋ฅ์ ์ ํฉํ ๊ฒ์ ๋๋ค([`BertForSequenceClassification`]๊ณผ ๊ฐ์ด). | |
| ์ด์ ์ ์ธ๊ธํ๋ฏ์ด ์ด ์์ ์์๋ ๋จ์ํ๊ฒ ํ๊ธฐ ์ํด ๋ชจ๋ธ์ ๋์จํ ๋ํผ(loose wrapper)๋ง ์์ฑํ ๊ฒ์ ๋๋ค. | |
| ์ด ํด๋์ค๋ฅผ ์์ฑํ๊ธฐ ์ ์ ๋ธ๋ก ์ ํ๊ณผ ์ค์ ๋ธ๋ก ํด๋์ค ๊ฐ์ ๋งคํ ์์ ๋ง ํ๋ฉด ๋ฉ๋๋ค. | |
| ๊ทธ๋ฐ ๋ค์ `ResNet` ํด๋์ค๋ก ์ ๋ฌ๋์ด `configuration`์ ํตํด ๋ชจ๋ธ์ด ์ ์ธ๋ฉ๋๋ค: | |
| ```py | |
| 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) | |
| ``` | |
| ์ด๋ฏธ์ง ๋ถ๋ฅ ๋ชจ๋ธ์ ๋ง๋ค๊ธฐ ์ํด์๋ forward ๋ฉ์๋๋ง ๋ณ๊ฒฝํ๋ฉด ๋ฉ๋๋ค: | |
| ```py | |
| import torch | |
| class ResnetModelForImageClassification(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, labels=None): | |
| logits = self.model(tensor) | |
| if labels is not None: | |
| loss = torch.nn.functional.cross_entropy(logits, labels) | |
| return {"loss": loss, "logits": logits} | |
| return {"logits": logits} | |
| ``` | |
| ๋ ๊ฒฝ์ฐ ๋ชจ๋ `PreTrainedModel`๋ฅผ ์์๋ฐ๊ณ , `config`๋ฅผ ํตํด ์์ ํด๋์ค ์ด๊ธฐํ๋ฅผ ํธ์ถํ๋ค๋ ์ ์ ๊ธฐ์ตํ์ธ์ (์ผ๋ฐ์ ์ธ `torch.nn.Module`์ ์์ฑํ ๋์ ๋น์ทํจ). | |
| ๋ชจ๋ธ์ auto ํด๋์ค์ ๋ฑ๋กํ๊ณ ์ถ์ ๊ฒฝ์ฐ์๋ `config_class`๋ฅผ ์ค์ ํ๋ ๋ถ๋ถ์ด ํ์์ ๋๋ค (๋ง์ง๋ง ์น์ ์ฐธ์กฐ). | |
| <Tip> | |
| ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์กด์ฌํ๋ ๋ชจ๋ธ๊ณผ ๊ต์ฅํ ์ ์ฌํ๋ค๋ฉด, ๋ชจ๋ธ์ ์์ฑํ ๋ ๊ตฌ์ฑ์ ์ฐธ์กฐํด ์ฌ์ฌ์ฉํ ์ ์์ต๋๋ค. | |
| </Tip> | |
| ์ํ๋ ๊ฒ์ ๋ชจ๋ธ์ด ๋ฐํํ๋๋ก ํ ์ ์์ง๋ง, `ResnetModelForImageClassification`์์ ํ๋ ๊ฒ ์ฒ๋ผ | |
| ๋ ์ด๋ธ์ ํต๊ณผ์์ผฐ์ ๋ ์์ค๊ณผ ํจ๊ป ์ฌ์ ํํ๋ก ๋ฐํํ๋ ๊ฒ์ด [`Trainer`] ํด๋์ค ๋ด์์ ์ง์ ๋ชจ๋ธ์ ์ฌ์ฉํ๊ธฐ์ ์ ์ฉํฉ๋๋ค. | |
| ์์ ๋ง์ ํ์ต ๋ฃจํ ๋๋ ๋ค๋ฅธ ํ์ต ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ ๊ณํ์ด๋ผ๋ฉด ๋ค๋ฅธ ์ถ๋ ฅ ํ์์ ์ฌ์ฉํด๋ ์ข์ต๋๋ค. | |
| ์ด์ ๋ชจ๋ธ ํด๋์ค๊ฐ ์์ผ๋ฏ๋ก ํ๋ ์์ฑํด ๋ณด๊ฒ ์ต๋๋ค: | |
| ```py | |
| resnet50d = ResnetModelForImageClassification(resnet50d_config) | |
| ``` | |
| ๋ค์ ๋งํ์ง๋ง, [`~PreTrainedModel.save_pretrained`]๋๋ [`~PreTrainedModel.push_to_hub`]์ฒ๋ผ [`PreTrainedModel`]์ ์ํ๋ ๋ชจ๋ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. | |
| ๋ค์ ์น์ ์์ ๋ ๋ฒ์งธ ๋ฉ์๋๋ฅผ ์ฌ์ฉํด ๋ชจ๋ธ ์ฝ๋์ ๋ชจ๋ธ ๊ฐ์ค์น๋ฅผ ์ ๋ก๋ํ๋ ๋ฐฉ๋ฒ์ ์ดํด๋ณด๊ฒ ์ต๋๋ค. | |
| ๋จผ์ , ๋ชจ๋ธ ๋ด๋ถ์ ์ฌ์ ํ๋ จ๋ ๊ฐ์ค์น๋ฅผ ๋ก๋ํด ๋ณด๊ฒ ์ต๋๋ค. | |
| ์ด ์์ ๋ฅผ ํ์ฉํ ๋๋, ์ฌ์ฉ์ ์ ์ ๋ชจ๋ธ์ ์์ ๋ง์ ๋ฐ์ดํฐ๋ก ํ์ต์ํฌ ๊ฒ์ ๋๋ค. | |
| ์ด ํํ ๋ฆฌ์ผ์์๋ ๋น ๋ฅด๊ฒ ์งํํ๊ธฐ ์ํด ์ฌ์ ํ๋ จ๋ resnet50d๋ฅผ ์ฌ์ฉํ๊ฒ ์ต๋๋ค. | |
| ์๋ ๋ชจ๋ธ์ resnet50d์ ๋ํผ์ด๊ธฐ ๋๋ฌธ์, ๊ฐ์ค์น๋ฅผ ์ฝ๊ฒ ๋ก๋ํ ์ ์์ต๋๋ค. | |
| ```py | |
| import timm | |
| pretrained_model = timm.create_model("resnet50d", pretrained=True) | |
| resnet50d.model.load_state_dict(pretrained_model.state_dict()) | |
| ``` | |
| ์ด์ [`~PreTrainedModel.save_pretrained`] ๋๋ [`~PreTrainedModel.push_to_hub`]๋ฅผ ์ฌ์ฉํ ๋ ๋ชจ๋ธ ์ฝ๋๊ฐ ์ ์ฅ๋๋์ง ํ์ธํด๋ด ์๋ค. | |
| ## Hub๋ก ์ฝ๋ ์ ๋ก๋ํ๊ธฐ[[sending-the-code-to-the-hub]] | |
| <Tip warning={true}> | |
| ์ด API๋ ์คํ์ ์ด๋ฉฐ ๋ค์ ๋ฆด๋ฆฌ์ค์์ ์ฝ๊ฐ์ ๋ณ๊ฒฝ ์ฌํญ์ด ์์ ์ ์์ต๋๋ค. | |
| </Tip> | |
| ๋จผ์ ๋ชจ๋ธ์ด `.py` ํ์ผ์ ์์ ํ ์ ์๋์ด ์๋์ง ํ์ธํ์ธ์. | |
| ๋ชจ๋ ํ์ผ์ด ๋์ผํ ์์ ๊ฒฝ๋ก์ ์๊ธฐ ๋๋ฌธ์ ์๋๊ฒฝ๋ก ์ํฌํธ(relative import)์ ์์กดํ ์ ์์ต๋๋ค (transformers์์๋ ์ด ๊ธฐ๋ฅ์ ๋ํ ํ์ ๋ชจ๋์ ์ง์ํ์ง ์์ต๋๋ค). | |
| ์ด ์์์์๋ ์์ ๊ฒฝ๋ก ์์ `resnet_model`์์ `modeling_resnet.py` ํ์ผ๊ณผ `configuration_resnet.py` ํ์ผ์ ์ ์ํฉ๋๋ค. | |
| ๊ตฌ์ฑ ํ์ผ์๋ `ResnetConfig`์ ๋ํ ์ฝ๋๊ฐ ์๊ณ ๋ชจ๋ธ๋ง ํ์ผ์๋ `ResnetModel` ๋ฐ `ResnetModelForImageClassification`์ ๋ํ ์ฝ๋๊ฐ ์์ต๋๋ค. | |
| ``` | |
| . | |
| โโโ resnet_model | |
| โโโ __init__.py | |
| โโโ configuration_resnet.py | |
| โโโ modeling_resnet.py | |
| ``` | |
| Python์ด `resnet_model`์ ๋ชจ๋๋ก ์ฌ์ฉํ ์ ์๋๋ก ๊ฐ์งํ๋ ๋ชฉ์ ์ด๊ธฐ ๋๋ฌธ์ `__init__.py`๋ ๋น์ด ์์ ์ ์์ต๋๋ค. | |
| <Tip warning={true}> | |
| ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ๋ชจ๋ธ๋ง ํ์ผ์ ๋ณต์ฌํ๋ ๊ฒฝ์ฐ, | |
| ๋ชจ๋ ํ์ผ ์๋จ์ ์๋ ์๋ ๊ฒฝ๋ก ์ํฌํธ(relative import) ๋ถ๋ถ์ `transformers` ํจํค์ง์์ ์ํฌํธ ํ๋๋ก ๋ณ๊ฒฝํด์ผ ํฉ๋๋ค. | |
| </Tip> | |
| ๊ธฐ์กด ๊ตฌ์ฑ์ด๋ ๋ชจ๋ธ์ ์ฌ์ฌ์ฉ(๋๋ ์๋ธ ํด๋์คํ)ํ ์ ์์ต๋๋ค. | |
| ์ปค๋ฎค๋ํฐ์ ๋ชจ๋ธ์ ๊ณต์ ํ๊ธฐ ์ํด์๋ ๋ค์ ๋จ๊ณ๋ฅผ ๋ฐ๋ผ์ผ ํฉ๋๋ค: | |
| ๋จผ์ , ์๋ก ๋ง๋ ํ์ผ์ ResNet ๋ชจ๋ธ๊ณผ ๊ตฌ์ฑ์ ์ํฌํธํฉ๋๋ค: | |
| ```py | |
| from resnet_model.configuration_resnet import ResnetConfig | |
| from resnet_model.modeling_resnet import ResnetModel, ResnetModelForImageClassification | |
| ``` | |
| ๋ค์์ผ๋ก `save_pretrained` ๋ฉ์๋๋ฅผ ์ฌ์ฉํด ํด๋น ๊ฐ์ฒด์ ์ฝ๋ ํ์ผ์ ๋ณต์ฌํ๊ณ , | |
| ๋ณต์ฌํ ํ์ผ์ Auto ํด๋์ค๋ก ๋ฑ๋กํ๊ณ (๋ชจ๋ธ์ธ ๊ฒฝ์ฐ) ์คํํฉ๋๋ค: | |
| ```py | |
| ResnetConfig.register_for_auto_class() | |
| ResnetModel.register_for_auto_class("AutoModel") | |
| ResnetModelForImageClassification.register_for_auto_class("AutoModelForImageClassification") | |
| ``` | |
| `configuration`์ ๋ํ auto ํด๋์ค๋ฅผ ์ง์ ํ ํ์๋ ์์ง๋ง(`configuration` ๊ด๋ จ auto ํด๋์ค๋ AutoConfig ํด๋์ค ํ๋๋ง ์์), ๋ชจ๋ธ์ ๊ฒฝ์ฐ์๋ ์ง์ ํด์ผ ํฉ๋๋ค. | |
| ์ฌ์ฉ์ ์ง์ ๋ชจ๋ธ์ ๋ค์ํ ์์ ์ ์ ํฉํ ์ ์์ผ๋ฏ๋ก, ๋ชจ๋ธ์ ๋ง๋ auto ํด๋์ค๋ฅผ ์ง์ ํด์ผ ํฉ๋๋ค. | |
| ๋ค์์ผ๋ก, ์ด์ ์ ์์ ํ๋ ๊ฒ๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ๊ตฌ์ฑ๊ณผ ๋ชจ๋ธ์ ์์ฑํฉ๋๋ค: | |
| ```py | |
| 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๋ก ์ ๋ก๋ํ๊ธฐ ์ํด ๋ก๊ทธ์ธ ์ํ์ธ์ง ํ์ธํ์ธ์. | |
| ํฐ๋ฏธ๋์์ ๋ค์ ์ฝ๋๋ฅผ ์คํํด ํ์ธํ ์ ์์ต๋๋ค: | |
| ```bash | |
| huggingface-cli login | |
| ``` | |
| ์ฃผํผํฐ ๋ ธํธ๋ถ์ ๊ฒฝ์ฐ์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค: | |
| ```py | |
| from huggingface_hub import notebook_login | |
| notebook_login() | |
| ``` | |
| ๊ทธ๋ฐ ๋ค์ ์ด๋ ๊ฒ ์์ ์ ๋ค์์คํ์ด์ค(๋๋ ์์ ์ด ์ํ ์กฐ์ง)์ ์ ๋ก๋ํ ์ ์์ต๋๋ค: | |
| ```py | |
| resnet50d.push_to_hub("custom-resnet50d") | |
| ``` | |
| On top of the modeling weights and the configuration in json format, this also copied the modeling and | |
| configuration `.py` files in the folder `custom-resnet50d` and uploaded the result to the Hub. You can check the result | |
| in this [model repo](https://huggingface.co/sgugger/custom-resnet50d). | |
| json ํ์์ ๋ชจ๋ธ๋ง ๊ฐ์ค์น์ ๊ตฌ์ฑ ์ธ์๋ `custom-resnet50d` ํด๋ ์์ ๋ชจ๋ธ๋ง๊ณผ ๊ตฌ์ฑ `.py` ํ์ผ์ ๋ณต์ฌํํด Hub์ ์ ๋ก๋ํฉ๋๋ค. | |
| [๋ชจ๋ธ ์ ์ฅ์](https://huggingface.co/sgugger/custom-resnet50d)์์ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํ ์ ์์ต๋๋ค. | |
| [sharing tutorial](model_sharing) ๋ฌธ์์ `push_to_hub` ๋ฉ์๋์์ ์์ธํ ๋ด์ฉ์ ํ์ธํ ์ ์์ต๋๋ค. | |
| ## ์ฌ์ฉ์ ์ ์ ์ฝ๋๋ก ๋ชจ๋ธ ์ฌ์ฉํ๊ธฐ[[using-a-model-with-custom-code]] | |
| auto ํด๋์ค์ `from_pretrained` ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์ ์ง์ ์ฝ๋ ํ์ผ๊ณผ ํจ๊ป ๋ชจ๋ ๊ตฌ์ฑ, ๋ชจ๋ธ, ํ ํฌ๋์ด์ ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. | |
| Hub์ ์ ๋ก๋๋ ๋ชจ๋ ํ์ผ ๋ฐ ์ฝ๋๋ ๋ฉ์จ์ด๊ฐ ์๋์ง ๊ฒ์ฌ๋์ง๋ง (์์ธํ ๋ด์ฉ์ [Hub ๋ณด์](https://huggingface.co/docs/hub/security#malware-scanning) ์ค๋ช ์ฐธ์กฐ), | |
| ์์ ์ ์ปดํจํฐ์์ ๋ชจ๋ธ ์ฝ๋์ ์์ฑ์๊ฐ ์ ์ฑ ์ฝ๋๋ฅผ ์คํํ์ง ์๋์ง ํ์ธํด์ผ ํฉ๋๋ค. | |
| ์ฌ์ฉ์ ์ ์ ์ฝ๋๋ก ๋ชจ๋ธ์ ์ฌ์ฉํ๋ ค๋ฉด `trust_remote_code=True`๋ก ์ค์ ํ์ธ์: | |
| ```py | |
| from transformers import AutoModelForImageClassification | |
| model = AutoModelForImageClassification.from_pretrained("sgugger/custom-resnet50d", trust_remote_code=True) | |
| ``` | |
| ๋ชจ๋ธ ์์ฑ์๊ฐ ์ ์์ ์ผ๋ก ์ฝ๋๋ฅผ ์ ๋ฐ์ดํธํ์ง ์์๋ค๋ ์ ์ ํ์ธํ๊ธฐ ์ํด, ์ปค๋ฐ ํด์(commit hash)๋ฅผ `revision`์ผ๋ก ์ ๋ฌํ๋ ๊ฒ๋ ๊ฐ๋ ฅํ ๊ถ์ฅ๋ฉ๋๋ค (๋ชจ๋ธ ์์ฑ์๋ฅผ ์์ ํ ์ ๋ขฐํ์ง ์๋ ๊ฒฝ์ฐ). | |
| ```py | |
| commit_hash = "ed94a7c6247d8aedce4647f00f20de6875b5b292" | |
| model = AutoModelForImageClassification.from_pretrained( | |
| "sgugger/custom-resnet50d", trust_remote_code=True, revision=commit_hash | |
| ) | |
| ``` | |
| Hub์์ ๋ชจ๋ธ ์ ์ฅ์์ ์ปค๋ฐ ๊ธฐ๋ก์ ์ฐพ์๋ณผ ๋, ๋ชจ๋ ์ปค๋ฐ์ ์ปค๋ฐ ํด์๋ฅผ ์ฝ๊ฒ ๋ณต์ฌํ ์ ์๋ ๋ฒํผ์ด ์์ต๋๋ค. | |
| ## ์ฌ์ฉ์ ์ ์ ์ฝ๋๋ก ๋ง๋ ๋ชจ๋ธ์ auto ํด๋์ค๋ก ๋ฑ๋กํ๊ธฐ[[registering-a-model-with-custom-code-to-the-auto-classes]] | |
| ๐ค Transformers๋ฅผ ์์ํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์์ฑํ๋ ๊ฒฝ์ฐ ์ฌ์ฉ์ ์ ์ ๋ชจ๋ธ์ auto ํด๋์ค์ ์ถ๊ฐํ ์ ์์ต๋๋ค. | |
| ์ฌ์ฉ์ ์ ์ ๋ชจ๋ธ์ ์ฌ์ฉํ๊ธฐ ์ํด ํด๋น ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ํฌํธํด์ผ ํ๊ธฐ ๋๋ฌธ์, ์ด๋ Hub๋ก ์ฝ๋๋ฅผ ์ ๋ก๋ํ๋ ๊ฒ๊ณผ ๋ค๋ฆ ๋๋ค (Hub์์ ์๋์ ์ผ๋ก ๋ชจ๋ธ ์ฝ๋๋ฅผ ๋ค์ด๋ก๋ ํ๋ ๊ฒ๊ณผ ๋ฐ๋). | |
| ๊ตฌ์ฑ์ ๊ธฐ์กด ๋ชจ๋ธ ์ ํ๊ณผ ๋ค๋ฅธ `model_type` ์์ฑ์ด ์๊ณ ๋ชจ๋ธ ํด๋์ค์ ์ฌ๋ฐ๋ฅธ `config_class` ์์ฑ์ด ์๋ ํ, | |
| ๋ค์๊ณผ ๊ฐ์ด auto ํด๋์ค์ ์ถ๊ฐํ ์ ์์ต๋๋ค: | |
| ```py | |
| from transformers import AutoConfig, AutoModel, AutoModelForImageClassification | |
| AutoConfig.register("resnet", ResnetConfig) | |
| AutoModel.register(ResnetConfig, ResnetModel) | |
| AutoModelForImageClassification.register(ResnetConfig, ResnetModelForImageClassification) | |
| ``` | |
| ์ฌ์ฉ์ ์ ์ ๊ตฌ์ฑ์ [`AutoConfig`]์ ๋ฑ๋กํ ๋ ์ฌ์ฉ๋๋ ์ฒซ ๋ฒ์งธ ์ธ์๋ ์ฌ์ฉ์ ์ ์ ๊ตฌ์ฑ์ `model_type`๊ณผ ์ผ์นํด์ผ ํฉ๋๋ค. | |
| ๋ํ, ์ฌ์ฉ์ ์ ์ ๋ชจ๋ธ์ auto ํด๋์ค์ ๋ฑ๋กํ ๋ ์ฌ์ฉ๋๋ ์ฒซ ๋ฒ์งธ ์ธ์๋ ํด๋น ๋ชจ๋ธ์ `config_class`์ ์ผ์นํด์ผ ํฉ๋๋ค. |