Hugging Face - Tokenizer

dumbbelldore·2025년 1월 28일
0

zero-base 33기

목록 보기
96/97

1. Tokenizer

  • 텍스트 데이터를 토큰(token)으로 쪼개는 과정을 수행하는 도구
  • 컴퓨터는 텍스트 데이터를 직접 이해할 수 없으니, 텍스트를 수치화해서 모델의 입력으로 넣어야 하므로 중요 과정에 해당
from transformers import AutoTokenizer
from pprint import pprint

tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")
text = "I love NLP with Hugging Face!"
tokens = tokenizer(text)
pprint(tokens)
# {'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
#  'input_ids': [101, 1045, 2293, 17953, 2361, 2007, 17662, 2227, 999, 102],
#  'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}
구분설명필요 이유
input_ids텍스트를 토큰화한 뒤, 각 토큰을 정수 ID로 변환한 값모델이 텍스트를 숫자로 이해할 수 있게 함
attention_mask어떤 토큰을 실제로 처리하고, 어떤 토큰을 무시해야 하는지 지정 (1=실제 토큰, 0=패딩)패딩으로 인해 모델이 혼란스러워하지 않도록 하기 위해 필요
token_type_ids문장 쌍 입력 시, 각 토큰이 첫 번째 문장인지 두 번째 문장인지 구분 (0=문장1, 1=문장2)두 문장이 섞여 있어도 문장 경계를 구분하도록 도와줌

2. KLUE (Korean Language Understanding Evaluation)

  • 한국어 NLP를 위해 설계된 다양한 태스크와 데이터셋을 제공
  • 한국어 언어 이해 능력을 측정하는 데 표준으로 사용됨
model_id = "klue/roberta-base"
tokenizer = AutoTokenizer.from_pretrained(model_id)
tokens = tokenizer("토크나이저는 텍스트를 토큰으로 나누어요")
pprint(tokens)
# {'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
#  'input_ids': [0,
#                9157,
#                7461,
#                2190,
#                2259,
#                8509,
#                2138,
#                1793,
#                2855,
#                6233,
#                4835,
#                10283,
#                2],
#  'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}

pprint(tokenizer.convert_ids_to_tokens(tokens["input_ids"]))
# ['[CLS]',
#  '토크',
#  '##나이',
#  '##저',
#  '##는',
#  '텍스트',
#  '##를',
#  '토',
#  '##큰',
#  '##으로',
#  '나누',
#  '##어요',
#  '[SEP]']

pprint(tokenizer.decode(tokens["input_ids"]))
# '[CLS] 토크나이저는 텍스트를 토큰으로 나누어요 [SEP]'

pprint(tokenizer.decode(tokens["input_ids"], skip_special_tokens=True))
# '토크나이저는 텍스트를 토큰으로 나누어요'

3. 뉴스 데이터 분류 예제

  • 연합뉴스 데이터 다운로드
from datasets import load_dataset

klue_tc_train = load_dataset("klue", "ynat", split="train")
klue_tc_eval = load_dataset("klue", "ynat", split="validation")

klue_tc_train[100]
# {'guid': 'ynat-v1_train_00100',
#  'title': '트레이드 성사한 잠실구장 두 사령탑 불펜 투수가 필요했다',
#  'label': 5,
#  'url': 'https://sports.news.naver.com/news.nhn?oid=001&aid=0010244304',
#  'date': '2018.07.31 17:54'}

klue_tc_train.features["label"].names
# ['IT과학', '경제', '사회', '생활문화', '세계', '스포츠', '정치']
  • train 데이터 내 불필요 정보 삭제
klue_tc_train = klue_tc_train.remove_columns(["guid", "url", "date"])
klue_tc_eval = klue_tc_eval.remove_columns(["guid", "url", "date"])
  • train 데이터 내 라벨이름 정보 추가
klue_tc_label = klue_tc_train.features["label"]

def addLabels(batch):
  batch["label_str"] = klue_tc_label.int2str(batch["label"]) # 숫자 입력 시 해당하는 라벨이름 반환
  return batch

klue_tc_train = klue_tc_train.map(addLabels, batched=True, batch_size=1000)

klue_tc_train[100]
# {'title': '트레이드 성사한 잠실구장 두 사령탑 불펜 투수가 필요했다', 
#  'label': 5, 
#. 'label_str': '스포츠'}
  • train/val 데이터 일부만 추출하기
train_dataset = klue_tc_train.train_test_split(
    test_size=10_000,
    shuffle=True,
    seed=42
)["test"]

val_test_dataset = klue_tc_eval.train_test_split(
    test_size=1_000,
    shuffle=True,
    seed=42
)

val_dataset = val_test_dataset["train"].train_test_split(
    test_size=1_000,
    shuffle=True,
    seed=42
)["test"]

test_dataset = val_test_dataset["test"]
  • 기사 제목 토큰화
import torch
import numpy as np
from transformers import Trainer, TrainingArguments, AutoModelForSequenceClassification, AutoTokenizer

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)
val_dataset = val_dataset.map(tokenize_function, batched=True)
test_dataset = test_dataset.map(tokenize_function, batched=True)
  • 학습에 필요한 파라미터 및 정확도 계산 함수 정의
!mkdir results

# 모델 학습에 필요한 파라미터
training_args = TrainingArguments(
    output_dir="./results",
    num_train_epochs=1,
    per_device_train_batch_size=8,
    per_device_eval_batch_size=8,
    evaluation_strategy="epoch",
    learning_rate=5e-5,
    push_to_hub=False,
    report_to="none",
)

# 정확도 계산 함수
def compute_metrics(eval_pred):
  logits, labels = eval_pred
  predictions = np.argmax(logits, axis=-1)
  return {"accuracy": (predictions==labels).mean()}
  • 모델 학습 및 예측 실시 (85% 정확도 확인)
trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=train_dataset,
    eval_dataset=val_dataset,
    tokenizer=tokenizer,
    compute_metrics=compute_metrics,
)
trainer.train()
trainer.evaluate(test_dataset)
# {'eval_loss': 0.46416130661964417,
#  'eval_accuracy': 0.85,
#  'eval_runtime': 26.822,
#  'eval_samples_per_second': 37.283,
#  'eval_steps_per_second': 4.66,
#  'epoch': 1.0}

*이 글은 제로베이스 데이터 취업 스쿨의 강의 자료 일부를 발췌하여 작성되었습니다.

profile
데이터 분석, 데이터 사이언스 학습 저장소

0개의 댓글