Hugging Face 사용
Hugging Face – The AI community building the future.
The Home of Machine Learning Create, discover and collaborate on ML better. We provide paid Compute and Enterprise solutions. We are building the foundation of ML tooling with the community.
huggingface.co
1. 환경 설정 및 데이터 이해
from google.colab import drive
drive.mount('/content/drive')
# install datasets 라이브러리
!pip install -qq datasets
import os
import numpy as np
import pandas as pd
from tqdm.auto import tqdm
import torch
import torch.nn.functional as F
from tqdm.auto import tqdm
from datasets import load_dataset
from transformers import (AutoTokenizer,
AutoModelForSequenceClassification,
TrainingArguments,
Trainer)
WORKSPACE = '경로지정'
!mkdir {WORKSPACE}/data
!ls {WORKSPACE}
dataset = load_dataset("e9t/nsmc")
dataset
dataset['train'].features
dataset['train'].num_rows
for i in range(10):
print(dataset['train'][i])
2. token 사용법
# Hugging Face Hub에서 tokenizer 다운로드
tokenizer = AutoTokenizer.from_pretrained("klue/roberta-base")
# 동작 확인을 위한 문장
sentence1 = "지미 카터: 제임스 얼 지미 카터 주니어(1924년 10월 1일~)는 민주당 출신 미국의 제39대 대통령 (1977-81)이다."
sentence2 = "수학: 수학(math)은 수, 양, 구조, 공간, 변화 등의 개념을 다루는 학문이다."
# tokenizer tokens 확인
tokens = tokenizer.tokenize(sentence1)
# tokens to ids
token_ids = tokenizer.convert_tokens_to_ids(tokens)
# [CLS], tokens ids, [SEP] 형식으로 변환
token_ids = tokenizer.encode(sentence1)
# 실제 모델에 입력형식으로 변환
# 배열에 미니배치 형식으로 여러 문장을 넣을 수 있음
inputs = tokenizer([sentence1, sentence2],
padding=True, # 길이가 짧은 문장에 PAD를 붙여서 길이를 맞춤
truncation=True, # 길이가 너무 긴 문장을 잘라서 버림
max_length=256, # 최대 token 길이
return_tensors="pt") # pytorch 형식으로 값 리턴
inputs
3. 모델 사용법
# Hugging Face Hub에서 tokenizer 다운로드
tokenizer = AutoTokenizer.from_pretrained("klue/roberta-base")
# Hugging Face Hub에서 model 다운로드
model = AutoModelForSequenceClassification.from_pretrained("klue/roberta-base",
num_labels=2) # 예측할 class 개수
# 입력 생성
inputs = tokenizer([sentence1,
sentence2],
padding=True, # 길이가 짧은 문장에 PAD를 붙여서 길이를 맞춤
truncation=True, # 길이가 너무 긴 문장을 잘라서 버림
max_length=256, # 최대 token 길이
return_tensors="pt") # pytorch 형식으로 값 리턴
inputs
# 추론
# 미세조정(finetuning)을 하지 않았기 때문에 현재는 답변을 신뢰 할 수 없음)
results = model(**inputs)
# logits 확인
results.logits
- PLM finetuning
# TODO: Hugging Face Hub에서 dataset 다운로드
dataset = load_dataset("e9t/nsmc")
# TODO: Hugging Face Hub에서 tokenizer 다운로드
tokenizer = AutoTokenizer.from_pretrained("klue/roberta-base")
# TODO: Hugging Face Hub에서 model 다운로드
model = AutoModelForSequenceClassification.from_pretrained("klue/roberta-base",
num_labels=2)
# dataset 선언
class NSMCDataset(torch.utils.data.Dataset):
def __init__(self, dataset):
super().__init__()
self.dataset = dataset
def __len__(self):
return len(self.dataset)
def __getitem__(self, idx):
return self.dataset[idx]['document'], self.dataset[idx]['label']
train_dataset = NSMCDataset(dataset['train'])
test_dataset = NSMCDataset(dataset['test'])
# collator 선언
class NSMCCollator:
def __init__(self, tokenizer, max_length=256):
self.tokenizer = tokenizer
self.max_length = max_length
def __call__(self, batch):
texts, labels = zip(*batch)
inputs = self.tokenizer(
texts,
padding=True,
truncation=True,
max_length=self.max_length,
return_tensors="pt",
)
return_value = {
"input_ids": inputs["input_ids"],
"attention_mask": inputs["attention_mask"],
"labels": torch.tensor(labels, dtype=torch.long),
}
return return_value
nsmc_collator = NSMCCollator(tokenizer)
# epoch 당 step 수 계산
steps_per_epoch = int(np.ceil(len(dataset['train']) / 128))
steps_per_epoch
# Train arguments 선언
training_args = TrainingArguments(
output_dir=f"{WORKSPACE}/checkpoint/klue-roberta-base",
overwrite_output_dir=True,
per_device_train_batch_size=128,
per_device_eval_batch_size=128,
gradient_accumulation_steps=1,
eval_accumulation_steps=1,
learning_rate=5e-5,
weight_decay=0.01,
lr_scheduler_type='linear',
warmup_steps=1000,
num_train_epochs=3,
logging_strategy="epoch",
evaluation_strategy="epoch",
save_strategy="epoch",
save_total_limit=5,
# bf16=config.fp16,
# bf16_full_eval=config.fp16,
fp16=True,
fp16_full_eval=True,
half_precision_backend=True,
load_best_model_at_end=True,
report_to="none"
)
# trainer 선언
trainer = Trainer(
model=model,
args=training_args,
train_dataset=train_dataset,
eval_dataset=test_dataset,
tokenizer=tokenizer,
data_collator=nsmc_collator,
)
# train
trainer.train()
- 평가하기
# TODO: Hugging Face Hub에서 dataset 다운로드
dataset = load_dataset("e9t/nsmc")
# 저장된 결과 확인
!ls {WORKSPACE}/checkpoint/klue-roberta-base
# TODO: 가장 성능이 좋은 경로를 입력하세요.
best_fn = f"{WORKSPACE}/checkpoint/klue-roberta-base/성능좋은 경로"
# TODO: 저장된 tokenizer 로드
tokenizer = AutoTokenizer.from_pretrained(best_fn)
# TODO: 저장된 model 로드
model = AutoModelForSequenceClassification.from_pretrained(best_fn,
num_labels=2)
# dataset 선언
class NSMCDataset(torch.utils.data.Dataset):
def __init__(self, dataset):
super().__init__()
self.dataset = dataset
def __len__(self):
return len(self.dataset)
def __getitem__(self, idx):
return self.dataset[idx]['document'], self.dataset[idx]['label']
train_dataset = NSMCDataset(dataset['train'])
test_dataset = NSMCDataset(dataset['test'])
# collator 선언
class NSMCCollator:
def __init__(self, tokenizer, max_length=256):
self.tokenizer = tokenizer
self.max_length = max_length
def __call__(self, batch):
texts, labels = zip(*batch)
inputs = self.tokenizer(
texts,
padding=True,
truncation=True,
max_length=self.max_length,
return_tensors="pt",
)
return_value = {
"input_ids": inputs["input_ids"],
"attention_mask": inputs["attention_mask"],
"labels": torch.tensor(labels, dtype=torch.long),
}
return return_value
nsmc_collator = NSMCCollator(tokenizer)
# test loader 생성
test_loader = torch.utils.data.DataLoader(
test_dataset,
batch_size=128,
shuffle=False,
collate_fn=nsmc_collator
)
# gpu 사용 가능 여부 확인
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# 맞은거 확인
total_correct_cnt = 0
total_sample_cnt = 0
model.to(device)
model.eval()
with torch.no_grad():
for batch in tqdm(test_loader):
output = model(
input_ids=batch["input_ids"].to(device),
attention_mask=batch["attention_mask"].to(device),
)
probs = torch.functional.F.softmax(output.logits, dim=-1)
prob, pred = torch.max(probs, dim=-1)
correct_cnt = (pred.cpu() == batch["labels"]).sum().item()
sample_cnt = len(batch["labels"])
total_correct_cnt += correct_cnt
total_sample_cnt += sample_cnt
print(f"Test Accuracy: {total_correct_cnt / total_sample_cnt * 100:.2f}%")
print(f"Correct / Total: {total_correct_cnt} / {total_sample_cnt}")
# idx -> label
idx2label = {0: '부정', 1: '긍정'}
# 랜덤하게 10개 셈플 결과 확인
idxs = np.random.randint(0, dataset['test'].num_rows, 10)
with torch.no_grad():
for idx in idxs:
document = dataset['test'][int(idx)]['document']
# inputs 생성
inputs = tokenizer(
document,
truncation=True,
max_length=256,
return_tensors="pt",
).to(device)
# 추론
logit = model(**inputs).logits[0]
prob = F.softmax(logit, dim=-1)
# 가장 높은 확률을 정답으로 예측
y = prob.argmax(dim=-1)
# 출력
print(f"{idx2label[y.item()]}\t{prob[y].item():.4f}\t{document}")
# 직접 입력을 받아서 긍정/부정 예측
while True:
print("input> ", end="")
document = str(input())
if len(document) == 0:
break
# TODO: inputs 생성
inputs = tokenizer(
document,
truncation=True,
max_length=256,
return_tensors="pt",
).to(device)
# TODO: 추론
logit = model(**inputs).logits[0]
prob = F.softmax(logit, dim=-1)
# TODO: 가장 높은 확률을 정답으로 예측
y = prob.argmax(dim=-1)
# 출력
print(f"{idx2label[y.item()]}\t{prob[y].item():.4f}\t{document}")
'KT AIVLE School > 언어지능 딥러닝' 카테고리의 다른 글
LLM (4) | 2024.11.08 |
---|---|
인공지능 신경망 (0) | 2024.11.07 |
영화 리뷰 가져오기 (2) | 2024.11.05 |
RSS로 전자신문 검색기능 만들기 (5) | 2024.11.05 |
언어지능 (2) | 2024.11.04 |