HuggingFace의 Tokenizer을 사용하면 Token (Input) ID, Attention Mask를 포함한 BatchEncoding
을 출력으로 받게 된다.
이 글에서는 이러한 HuggingFace의 Model input에 대해 정리해 보고자 한다.
Tokenizer class에 대한 게시물은 여기에서 확인할 수 있다.
참고: Official Docs
Tokenizer
HuggingFace의 Tokenizer을 다음과 같이 우선 정의한다. 본 예제에서는 BertTokenizer
을 사용한다.
from transformers import BertTokenizer
tokenizer = BertTokenizer.from_pretrained("bert-base-cased")
sequence = "A Titan RTX has 24GB of VRAM"
🔖 Tokenize
tokenize
method를 이용하면, input sequence를 tokenizer vocabulary에 있는 token (word or subword)들로 쪼개어 준다.
tokenized_sequence = tokenizer.tokenize(sequence)
print(tokenized_sequence)
>> ['A', 'Titan', 'R', '##T', '##X', 'has', '24', '##GB', 'of', 'V', '##RA', '##M']
하나의 문장이 각 단어들로 쪼개진 것을 확인할 수 있다.
👉 Encode
Tokenizer에 sequence를 입력으로 주면 model에 들어갈 input encoding을 생성할 수 있다.
inputs = tokenizer(sequence)
이때 inputs
는 model에 필요한 Input ID, Token type ID, Attention mask 등을 포함한 dictionary로 구성되어 있다.
Input ID
encoded_sequence = inputs["input_ids"]
print(encoded_sequence)
>> [101, 138, 18696, 155, 1942, 3190, 1144, 1572, 13745, 1104, 159, 9664, 2107, 102]
"input_ids"는 각 token의 ID에 해당한다. 그런데 자세히 보면 tokenize
method로 얻은 tokenized_sequence
의 길이와 encoded_sequence
의 길이가 다른 것을 확인할 수 있다.
그 이유는 Tokenizer가 자동으로 "special tokens"를 앞뒤로 추가했기 때문이다.
👈 Decode
decode
method를 이용하면 encoding 된 token ID를 다시 sequence로 변환할 수 있다.
decoded_sequence = tokenizer.decode(encoded_sequence)
print(decoded_sequence)
>> [CLS] A Titan RTX has 24GB of VRAM [SEP]
이를 통해 확인해보면, encoding 과정에서 앞뒤로 [CLS] token과 [SEP] token이 추가된 것을 볼 수 있다.
Token Type IDs
일부 model의 경우, 두 문장이 이어지는 문장인지 아닌지를 판단하는 task를 수행하기도 한다.
이 경우 input의 형식은 다음과 같게 된다.
# [CLS] SEQUENCE_A [SEP] SEQUENCE_B [SEP]
이 경우 첫 번째 sequence (SEQUENCE_A)와 두 번째 sequence (SEQUENCE_B)에 서로 다른 ID를 부여해주는 것이 바로 Token type ID이다.
from transformers import BertTokenizer
tokenizer = BertTokenizer.from_pretrained("bert-base-cased")
sequence_a = "HuggingFace is based in NYC"
sequence_b = "Where is HuggingFace based?"
encoded_dict = tokenizer(sequence_a, sequence_b)
print(encoded_dict["token_type_ids"])
>> [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1]
Attention mask
Attention mask는 optional한 output으로, Tokenizer 호출 시 return 여부를 함께 argument로 줄 수 있다.
Attention mask는 model이 어떤 token에 집중 (attend)해야 할 지를 알려준다.
서로 다른 길이의 두 문장의 encoding의 길이를 맞춰주기 위해 다음과 같이 padding을 이용한다.
from transformers import BertTokenizer
tokenizer = BertTokenizer.from_pretrained("bert-base-cased")
sequence_a = "This is a short sequence."
sequence_b = "This is a rather long sequence. It is at least longer than the sequence A."
padded_sequences = tokenizer([sequence_a, sequence_b], padding=True)
print(padded_sequences["input_ids"])
>> [[101, 1188, 1110, 170, 1603, 4954, 119, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [101, 1188, 1110, 170, 1897, 1263, 4954, 119, 1135, 1110, 1120, 1655, 2039, 1190, 1103, 4954, 138, 119, 102]]
이 때 padding 된 token과 그렇지 않은 token을 알려주는 것이 attention mask이다.
Input에서 padding된 부분은 0으로, 그렇지 않은 부분을 1로 하는 mask를 return한다.
padded_sequences["attention_mask"]
>> [[1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]
'🐍 Python & library > HuggingFace' 카테고리의 다른 글
HuggingFace Space 만들기 (1) | 2023.06.10 |
---|---|
[HuggingFace] Trainer 사용법 (0) | 2022.07.23 |
[HuggingFace] Tokenizer class 알아보기 (0) | 2022.06.03 |
[HuggingFace] Pipeline & AutoClass (0) | 2022.05.31 |