허깅페이스 트랜스포머 : 다양한 트랜스포머 모델들을 통일된 인터페이스로 지원하는 라이브러리
허깅페이스 허브 : 사전 학습 모델, 데이터셋을 공개 및 테스트 해볼 수 있는 스페이스를 제공
from transformers import AutoTokenizer, AutoModel, AutoModelForSequenceClassification
text = "What is Huggingface Transformers?"
# BERT 모델 바디 활용
bert_model = AutoModel.from_pretrained("bert-base-uncased")
bert_tokenizer = AutoTokenizer.from_pretrained('bert-base-uncased')
encoded_input = bert_tokenizer(text, return_tensors='pt')
bert_output = bert_model(**encoded_input)
# GPT-2 모델 바디 활용
gpt_model = AutoModel.from_pretrained('gpt2')
gpt_tokenizer = AutoTokenizer.from_pretrained('gpt2')
encoded_input = gpt_tokenizer(text, return_tensors='pt')
gpt_output = gpt_model(**encoded_input)
model_id = 'SamLowe/roberta-base-go_emotions'
# 헤드가 포함된 RoBERTa 모델 활용
classification_model = AutoModelForSequenceClassification.from_pretrained(model_id)
# 분류 헤드로 사전학습
robert_tokenizer = AutoTokenizer.from_pretrained(model_id)
text_ko = ['이 영화는 좀..?', '연기가 좋았어.']
# 텍스트를 토큰으로 나누고 각 토큰을 토큰 아이디로 변환
# input_ids : 토큰이 몇 번째 항목인지
# attention_mask : 실제 텍스트인지 아니면 길이를 맞추기 위해 추가한 패딩인지 구분 (1이 실제)
# token_type_ids = 토큰이 속한 문장의 아이디
encoded_input = robert_tokenizer(text_ko)
print(robert_tokenizer.batch_decode(encoded_input['input_ids']))
print(robert_tokenizer.batch_decode(encoded_input['input_ids'], skip_special_tokens=True))
트레이닝 실습
from transformers import AutoTokenizer, AutoModelForSequenceClassification, Trainer, TrainingArguments
from datasets import load_dataset
import numpy as np
klue_tc_train = load_dataset('klue', 'ynat', split='train').remove_columns(['guid', 'url', 'date'])
klue_tc_eval = load_dataset('klue', 'ynat', split='validation').remove_columns(['guid', 'url', 'date'])
klue_tc_label = klue_tc_train.features['label']
def make_str_label(batch):
batch['label_str'] = klue_tc_label.int2str(batch['label'])
return batch
klue_tc_train = klue_tc_train.map(make_str_label, batched=True, batch_size=1000)
print(klue_tc_train[0])
# {'title': '유튜브 내달 2일까지 크리에이터 지원 공간 운영', 'label': 3, 'label_str': '생활문화'}
# seed를 특정 값으로 설정하면 항상 같은 결과를 보장함
train_dataset = klue_tc_train.train_test_split(test_size=10000, shuffle=True, seed=42)['test']
dataset = klue_tc_eval.train_test_split(test_size=1000, shuffle=True, seed=42)
test_dataset = dataset['test']
valid_dataset = dataset['train'].train_test_split(test_size=1000, shuffle=True, seed=42)['test']
def tokenize_function(examples):
return tokenizer(examples["title"], padding="max_length", truncation=True)
model_id = "klue/roberta-base"
model = AutoModelForSequenceClassification.from_pretrained(model_id, num_labels=len(train_dataset.features['label'].names))
tokenizer = AutoTokenizer.from_pretrained(model_id)
train_dataset = train_dataset.map(tokenize_function, batched=True)
valid_dataset = valid_dataset.map(tokenize_function, batched=True)
test_dataset = test_dataset.map(tokenize_function, batched=True)
# output_dir="./results": 모델과 체크포인트가 저장될 디렉토리
# num_train_epochs=1: 전체 데이터셋에 대해 1번 학습
# per_device_train_batch_size=8: 학습 시 GPU/CPU당 배치 크기 8
# per_device_eval_batch_size=8: 평가 시 GPU/CPU당 배치 크기 8
# evaluation_strategy="epoch": 각 에폭이 끝날 때마다 모델 평가
# learning_rate=5e-5: 옵티마이저의 학습률 설정
# push_to_hub=False: 학습된 모델을 Hugging Face Hub에 업로드하지 않음
training_args = TrainingArguments(
output_dir="./results",
num_train_epochs=1,
per_device_train_batch_size=8,
per_device_eval_batch_size=8,
eval_strategy="epoch",
learning_rate=5e-5,
push_to_hub=False
)
# eval_pred : (logits, labels) 형태의 튜플
# logits : 모델의 원시 출력(각 클래스에 대한 점수)
# np.argmax(logits, axis=-1) : 가장 높은 점수의 클래스 인덱스를 예측값으로 선택
# (predictions == labels).mean() : 정확도(맞은 예측의 비율)를 계산
# 계산된 정확도를 딕셔너리 형태로 반환
def compute_metrics(eval_pred):
logits, labels = eval_pred
predictions = np.argmax(logits, axis=-1)
return {"accuracy": (predictions == labels).mean()}
trainer = Trainer(
model=model, # 앞서 불러온 사전 훈련된 모델(klue/roberta-base)
args=training_args, # 훈련 설정(에폭, 배치 크기 등)
train_dataset=train_dataset, # 토큰화된 훈련 데이터셋
eval_dataset=valid_dataset, # 토큰화된 검증 데이터셋
tokenizer=tokenizer, # 텍스트 처리를 위한 토크나이저
compute_metrics=compute_metrics, # 평가 메트릭 계산 함수
)
trainer.train()
print(trainer.evaluate(test_dataset))