Models
이번 섹션에서는 모델을 생성하고 사용하는 방법에 대해 자세히 알아보겠습니다. 체크포인트에서 모델을 인스턴스화하는 데 유용한 AutoModel
클래스를 사용할 것입니다.
이 AutoModel
클래스와 관련 클래스들은 실제로 라이브러리에 있는 다양한 모델들을 감싸고 있는 간단한 래퍼입니다. 이 래퍼는 체크포인트에 적합한 모델 아키텍처를 자동으로 추측하고, 이 아키텍처를 가진 모델을 인스턴스화하는 것도 똑똑하게 처리합니다.
하지만, 만약 모델의 아키텍처를 직접 정의하고 싶다면, 해당 모델의 클래스를 사용할 수 있습니다. BERT 모델을 예로 들어보겠습니다.
Creating a Transformer (Transformer 생성하기)
BERT 모델을 초기화 하기 위해서는 먼저 모델의 환경설정을 로드해야 합나다.
from transformers import BertConfig, BertModel
# Building the config
config = BertConfig()
# Building the model from the config
model = BertModel(config)
이 환경설정은 모델을 구축하는데 사용되는 많은 속성들을 포함하고 있습니다:
print(config)
BertConfig {
[...]
"hidden_size": 768,
"intermediate_size": 3072,
"max_position_embeddings": 512,
"num_attention_heads": 12,
"num_hidden_layers": 12,
[...]
}
아직 이 속성들이 무엇을 의미하는지는 모르겠지만, 몇몇은 익숙할 것입니다: hidden_size
속성은 hidden_states
벡터의 크기를 정의하고, num_hidden_layers
는 Transformer 모델이 가지고 있는 레이어의 수를 정의합니다.
Different loading methods (다른 로딩 방법)
무작위 값을 통한 기본 환경설정으로 모델 생성
from transformers import BertConfig, BertModel
config = BertConfig()
model = BertModel(config)
# Model is randomly initialized!
이 모델은 무작위로 초기화되어 있기 때문에, 아직은 아무런 유용한 정보를 포함하고 있지 않습니다. 이 모델을 훈련시키기 위해서는, 먼저 훈련 데이터를 준비해야 합니다. 우리가 바닥부터 학습을 할 수 있지만, 이 과정은 Chapter 1에서 확인 했듯이, 많은 시간과 많은 데이터가 필요하며, 학습 환경에도 큰 영향을 미칩니다.
이러한 불필요한 중복된 노력을 피하기 위해서, 이미 훈련된 모델을 공유하고 재사용할 수 있어야 합니다.
훈련된 Transformer 모델을 불러오는 것은 매우 간단합니다 - from_pretrained
메소드를 사용하면 됩니다.
from transformers import BertModel
model = BertModel.from_pretrained("bert-base-cased")
이전에 봤듯이, BertModel
대신 AutoModel
클래스를 사용할 수도 있습니다. 이제부터는 체크포인트에 독립적인 코드를 생성하기 위해 AutoModel
를 사용하겠습니다. 만약 코드가 한 체크포인트에서 잘 동작한다면, 다른 체크포인트에서도 잘 동작해야 합니다. 이는 체크포인트의 아키텍처가 다르더라도, 비슷한 작업(예를 들어, 감성 분석 작업)을 위해 훈련된 경우에도 적용됩니다.
이 코드 샘플에서는 BertConfig
를 사용하지 않았고, 대신 bert-base-cased
식별자를 통해 사전 훈련된 모델을 불러왔습니다. 이는 BERT의 저자들이 직접 훈련시킨 체크포인트입니다. 자세한 내용은 모델 카드에서 확인할 수 있습니다.
이 모델은 체크포인트의 모든 가중치로 초기화되었습니다. 이 모델은 체크포인트에서 훈련된 작업에 대해 직접 추론에 사용할 수 있으며, 새로운 작업에 대해 미세 조정할 수도 있습니다. 사전 훈련된 가중치로부터 학습을 진행하면, 빈 상태에서 훈련을 시작하는 것보다 빠르게 좋은 결과를 얻을 수 있습니다.
모델을 불러오는 또 다른 방법은 from_pretrained()
메서드를 사용하는 것입니다. 이 메서드는 체크포인트를 다운로드하고, 캐시에 저장합니다(이후 from_pretrained()
메서드를 호출할 때 다시 다운로드하지 않습니다). 캐시 폴더는 기본적으로 ~/.cache/huggingface/transformers에 저장됩니다. 캐시 폴더를 사용자 정의하려면 HF_HOME
환경 변수를 설정하면 됩니다.
모델을 불러오는 식별자는 BERT 아키텍처와 호환되는 경우 모델 허브의 모든 모델의 식별자가 될 수 있습니다. BERT 체크포인트의 전체 목록은 여기에서 확인할 수 있습니다.
Saving methods (저장 방법)
모델을 저장하는 방법은 불러오는 방법처럼 쉽습니다. save_pretrained()
메서드를 사용하면 됩니다. 이 메서드는 from_pretrained()
메서드와 유사합니다.
model.save_pretrained("directory_on_my_computer")
이는 2가지 파일을 저장하게 됩니다:
ls directory_on_my_computer
config.json pytorch_model.bin
config.json 파일은 모델 아키텍처를 구축하는 데 필요한 속성을 알려줍니다. 이 파일에는 체크포인트가 어디에서 생성되었는지, 마지막으로 체크포인트를 저장할 때 사용한 🤗 Transformers 버전 등의 메타데이터도 포함되어 있습니다.
The pytorch_model.bin file is known as the state dictionary; it contains all your model’s weights. The two files go hand in hand; the configuration is necessary to know your model’s architecture, while the model weights are your model’s parameters.
Using a Transformer model for inference (Transformer 모델을 추론에 사용하기)
Now that you know how to load and save a model, let’s try using it to make some predictions. Transformer models can only process numbers — numbers that the tokenizer generates. But before we discuss tokenizers, let’s explore what inputs the model accepts.
이제 모델을 불러오고 저장하는 방법을 알았으니, 모델을 사용하여 예측을 만들어 보겠습니다. Transformer 모델은 토크나이저가 생성하는 숫자만 처리할 수 있습니다. 그러나 토크나이저에 대해 논의하기 전에 모델이 받는 입력에 대해 알아보겠습니다.
토크나이저는 입력을 적절한 프레임워크의 텐서로 변환할 수 있지만, 이해도를 높이기 위해 모델에 입력을 보내기 전 무엇을 반드시 해야 하는지 간단히 살펴보겠습니다.
우리가 여러 시퀀스들이 있다고 가정해 봅시다:
sequences = ["Hello!", "Cool.", "Nice!"]
토크나이저는 이를 단어 인덱스로 변환합니다. 이를 input IDs라고 합니다. 각 시퀀스는 이제 숫자 목록입니다! 결과는 다음과 같습니다:
encoded_sequences = [
[101, 7592, 999, 102],
[101, 4658, 1012, 102],
[101, 3835, 999, 102],
]
이는 인코딩된 시퀀스의 목록입니다. 텐서는 정사각형 모양만 받을 수 있습니다 (행렬을 생각해 보세요). 이 “배열”은 이미 정사각형 모양이므로 텐서로 변환하는 것은 쉽습니다:
This is a list of encoded sequences: a list of lists. Tensors only accept rectangular shapes (think matrices). This “array” is already of rectangular shape, so converting it to a tensor is easy:
import torch
model_inputs = torch.tensor(encoded_sequences)
Using the tensors as inputs to the model (텐서를 모델의 입력으로 사용하기)
모델의 텐서를 사용하는 것은 매우 간단합니다. 모델에 입력을 넣기만 하면 됩니다:
output = model(model_inputs)
모델이 다양한 어규먼트를 받는 중에, 입력은 input IDs 만 필요합니다. 나머지 어규먼트들은 언제 필요한지, 어떤 역할을 하는지는 나중에 설명하겠습니다. 먼저 토크나이저에 대해 좀 더 자세히 알아보겠습니다.