NLP Course documentation

한 번에 실행하기

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

한 번에 실행하기

Ask a Question Open In Colab Open In Studio Lab

지난 섹션에서는 대부분의 과정을 하나씩 수행해왔습니다. 토크나이저의 작동 방식을 살펴보고 토큰화, 입력 ID로의 변환, 패딩, 잘라내기 그리고 어텐션 마스크에 대해 알아봤습니다.

하지만 2장에서 보았듯이 우리는 🤗 Transformers API의 고수준 함수로 이 모든 것을 처리할 수 있습니다. 문장을 이용해 tokenizer를 호출하면 모델로 넘겨줄 수 있는 입력을 얻게 됩니다.

from transformers import AutoTokenizer

checkpoint = "distilbert-base-uncased-finetuned-sst-2-english"
tokenizer = AutoTokenizer.from_pretrained(checkpoint)

sequence = "I've been waiting for a HuggingFace course my whole life."

model_inputs = tokenizer(sequence)

이제 model_inputs 변수는 모델이 잘 동작하기 위해 필요한 모든 것을 가지고 있습니다. DistilBERT는 어텐션 마스크뿐만 아니라 입력 ID도 포함합니다. 추가적인 입력을 받는 다른 모델들도 tokenizer 객체에 의해 생기는 결과물을 가지고 있습니다.

아래의 예시를 보면 tokenizer 메서드는 매우 강력합니다. 먼저, 이 메서드는 단일 시퀀스를 토큰화할 수 있습니다.

sequence = "I've been waiting for a HuggingFace course my whole life."

model_inputs = tokenizer(sequence)

또한 API의 변경 없이 여러 개의 시퀀스를 한 번에 처리할 수 있습니다.

sequences = ["I've been waiting for a HuggingFace course my whole life.", "So have I!"]

model_inputs = tokenizer(sequences)

원하는대로 패딩을 추가할 수 있습니다.

# 가장 긴 시퀀스의 길이에 맞게 패딩을 추가합니다.
model_inputs = tokenizer(sequences, padding="longest")

# 모델이 지원하는 최대 시퀀스 길이에 맞게 패딩을 추가합니다.
# (BERT나 DistilBERT의 최대 길이는 512)
model_inputs = tokenizer(sequences, padding="max_length")

# 지정한 길이에 맞게 패딩을 추가합니다.
model_inputs = tokenizer(sequences, padding="max_length", max_length=8)

시퀀스 길이를 잘라낼 수도 있습니다.

sequences = ["I've been waiting for a HuggingFace course my whole life.", "So have I!"]

# 모델이 지원하는 최대 시퀀스 길이에 맞게 시퀀스 길이를 잘라냅니다.
# (BERT나 DistilBERT의 최대 길이는 512)
model_inputs = tokenizer(sequences, truncation=True)

# 지정한 최대 길이에 맞게 시퀀스 길이를 잘라냅니다.
model_inputs = tokenizer(sequences, max_length=8, truncation=True)

tokenizer 객체를 이용해 결과를 특정 프레임워크의 텐서로 변환할 수 있으며, 이는 모델에 바로 보내질 수 있습니다. 예를 들어 아래 코드 예시에서 토크나이저가 프레임워크에 따라 다른 텐서를 반환하게 했습니다 - "pt"는 PyTorch 텐서를 반환하고 "tf"는 TensorFlow 텐서를 반환하며, "np"는 NumPy 배열을 반환합니다.

sequences = ["I've been waiting for a HuggingFace course my whole life.", "So have I!"]

# PyTorch 텐서를 반환합니다.
model_inputs = tokenizer(sequences, padding=True, return_tensors="pt")

# TensorFlow 텐서를 반환합니다.
model_inputs = tokenizer(sequences, padding=True, return_tensors="tf")

# NumPy 배열을 반환합니다.
model_inputs = tokenizer(sequences, padding=True, return_tensors="np")

특수 토큰

토크나이저가 반환한 입력 ID를 자세히 살펴보면 이전에 봤던 결과와 조금 다르다는 것을 알 수 있습니다.

sequence = "I've been waiting for a HuggingFace course my whole life."

model_inputs = tokenizer(sequence)
print(model_inputs["input_ids"])

tokens = tokenizer.tokenize(sequence)
ids = tokenizer.convert_tokens_to_ids(tokens)
print(ids)
[101, 1045, 1005, 2310, 2042, 3403, 2005, 1037, 17662, 12172, 2607, 2026, 2878, 2166, 1012, 102]
[1045, 1005, 2310, 2042, 3403, 2005, 1037, 17662, 12172, 2607, 2026, 2878, 2166, 1012]

시작과 끝에 추가된 토큰 ID가 있습니다. 두 시퀀스의 ID가 무엇을 의미하는지 확인하기 위해 디코딩해보겠습니다.

print(tokenizer.decode(model_inputs["input_ids"]))
print(tokenizer.decode(ids))
"[CLS] i've been waiting for a huggingface course my whole life. [SEP]"
"i've been waiting for a huggingface course my whole life."

토크나이저는 문장이 시작할 떄 [CLS]라는 특별한 토큰을 붙이고, 끝날 때는 [SEP] 토큰을 붙입니다. 이런 특별한 토큰을 사용하는 이유는 모델이 사전학습될 때 이 토큰들을 사용했기 때문에 추론 시 동일한 결과를 얻기 위함입니다. 참고로 몇몇 모델은 특수 토큰을 추가하지 않아도 되고, 어떤 모델은 다른 토큰을 추가하기도 합니다. 또한, 이러한 특수 토큰을 시작 부분이나 끝 부분에만 추가하는 모델도 있습니다. 어떤 경우든 토크나이저는 토크나이저로 어떤 내용이 들어올지 알고 있고 이 내용을 처리해줄 것입니다.

마무리: 토크나이저에서 모델까지

지금까지 tokenizer 객체가 텍스트에 적용될 때 거치는 개별적인 단계를 모두 살펴보았습니다. 이제 마지막으로 이 객체가 패딩을 이용해 여러 시퀀스를 어떻게 처리하는지, 잘라내기를 통해 매우 긴 문장을 어떻게 처리하는지, 주요 API에 따라 다양한 텐서를 다루는 법을 알아봅시다.

import torch
from transformers import AutoTokenizer, AutoModelForSequenceClassification

checkpoint = "distilbert-base-uncased-finetuned-sst-2-english"
tokenizer = AutoTokenizer.from_pretrained(checkpoint)
model = AutoModelForSequenceClassification.from_pretrained(checkpoint)
sequences = ["I've been waiting for a HuggingFace course my whole life.", "So have I!"]

tokens = tokenizer(sequences, padding=True, truncation=True, return_tensors="pt")
output = model(**tokens)