본문 바로가기
자연어 처리(NLP)

12. PLM을 이용한 실습

by 곽정우 2024. 7. 8.

1. NLI(Natual Language Inference) 실습

  • 두 개의 문장(전제와 가설) 사이의 논리적 관계를 결정하는 자연어 처리 문제
!pip install transformers
# pipeline: 자연어 처리 작업을 간단한 코드로 여러 작업을 한번에 지원
# AutoTokenizer: 자동으로 적절한 토크나이저를 선택하여 모델의 토큰화를 수행

from transformers import pipeline, AutoTokenizer
classifier = pipeline(
    'text-classification',
    model='Huffon/klue-roberta-base-nli',
    return_all_scores=True
)

tokenizer = AutoTokenizer.from_pretrained('Huffon/klue-roberta-base-nli')
tokenizer.sep_token

# ENTAILMENT: 첫 번째 문장이 두 번째 문장을 내포하거나 함축한 경우 
# NEUTRAL: 두 문장의 관계가 특별히 긍정적이거나 부정적이지 않을 때(모순 관계가 없을 때)
# CONTRADICTION: 명백한 모순 관계가 있을 때

classifier(f'나는 게임을 너무 좋아해 {tokenizer.sep_token} 나는 게임이 너무 싫어')

classifier(f'여러 남성들이 축구를 즐기고 있어요 {tokenizer.sep_token} 어떤 남자들은 공을 차고 있어요')

 

2. 문장 요약, 번역, 텍스트 생성 실습

  • BART(Sequential Bidirectional AutoRegressive Transformers)
  • 허깅페이스에서 개발한 자연어 처리 모델
  • 자연어 생성 및 이해 작업을 위한 사전 훈련된 언어 모델
  • 트랜스포머 아키텍처를 기반으로 양방향 인코더-디코더 구조를 가지고 있음
  • 문장 요약, 번역, 텍스트 생성에 뛰어난 성능을 보여주는 모델
!pip install -U transformers datasets scipy scikit-learn
import torch
from transformers import PreTrainedTokenizerFast
from transformers import BartForConditionalGeneration
# PreTrainedTokenizerFast: 허깅페이스에서 개발한 Rust 기반의 고성능 토크나이저

tokenizer = PreTrainedTokenizerFast.from_pretrained('digit82/kobart-summarization')
tokenizer

model = BartForConditionalGeneration.from_pretrained('digit82/kobart-summarization')

text = """
기후 관련 신기록들이 나오고 있다. 지난 6월 5일 '세계기상기구'(WMO)는 향후 5년간 산업혁명 전 대비 지구표면 온도가 1.1℃에서 1.9℃까지 상승할 수 있다고 발표했다. 기후위기의 마지노선인 1.5℃ 상승이 앞으로 5년간 계속될 확률도 47%라고 한다. 1.5℃ 상승제한을 결정했던 2015년 유엔 파리기후협정 당시만 해도 2030년까지 1.5℃ 오를 가능성은 0%였다. 10년도 안 되어 사실상 기후 관련 국제사회의 결정이 무너지고 있다.
지난 6월 28일 발생해 시속 270km의 강풍을 동반, 최고등급인 5등급으로 발달한 허리케인 '베릴'(Beryl)이 중남미 카리브해의 나라들을 파괴했다. 7월 3일 영국 BBC방송은 베릴에 대해 지난 100년간의 허리케인 기록을 깼고, 현재 진행되는 기후변화의 위험성이 집중 조명된 사례로 보도했다. 지금까지 허리케인은 해수면 온도가 높아진 8월 말부터 발생했는데, 6월에 발생한 허리케인 베릴은 기후위기가 만든 최초 기록이라는 것이다.
"""
text = text.replace('\n',' ')
raw_input_ids = tokenizer.encode(text)
print(raw_input_ids)

input_ids = [tokenizer.bos_token_id] + raw_input_ids + [tokenizer.eos_token_id]
print(input_ids)

summary_ids = model.generate(torch.tensor([input_ids]),  num_beams=4,  max_length=512,  eos_token_id=1)
summary_ids

tokenizer.decode(summary_ids.squeeze().tolist(), skip_special_tokens=True)

 

3. KLUE(Korean Language Understanding Evaluation)

  • 한국어 자연어 이해 평가 데이터셋
  • 한국어 언어모델의 공정한 평가를 위한 목적으로 8개의 종류가 포함된 공개 데이터셋
    • 뉴스 헤드라인 분류
    • 문장 유사도 비교
    • 자연어 추론
    • 개체명 인식
    • 관계 추출
    • 형태소 및 의존 구문 분석
    • 기계 독해 이해
    • 대화 상태 추적
  • 광범위한 주제와 다양한 스타일을 포괄하기 위해 다양한 출처에서 공개적으로 사용 가능한 한국어 말뭉치를 수집
  • 약 62GB 크기의 최종 사전 학습 코퍼스 구축
  • MODU(국립국어원), CC-100-Kor(CC-Net을 사용한 다국어 웹 크롤링), 나무위키(웹 기반 백과사전), 뉴스스크롤(뉴스 집계 플랫폼), 청원(청와대 국민청원의 기사) 등
  • ['ynat', 'sts', 'nli', 'ner', 're', 'dp', 'mrc', 'wos']
    • ynat: 유튜브 비디오 댓글에서 자연스럽게 발생하는 대화 데이터를 이용한 태스크, 주어진 문장에 대해 답변하는 작업
    • sts: 두 텍스트의 의미적 유사성을 평가하는 태스크
    • nil: 전제와 가설이라는 두 문장 간의 논리적 관계를 판별하는 태스크(참, 거짓, 중립)
    • ner: 문장에서 인명, 지명, 기관면 등 특정 개체명을 식별하고 분류하는 태스크
    • re: 문장 또는 텍스트에서 개체들 간의 관계를 추출하는 태스크
      • 예) "스티브잡스는 애플의 공동 창립자이다" -> 스티브잡스와 애플을 뽑아내고 그 관계를 알려줌
    • dp: 문장 내 단어들 간의 문법적 관계를 파악하는 태스크. 각 단어가 어떻게 다른 단어들과 연결되어 있는지(종속성)를 구조적으로 분석
    • mrc: 주어진 텍스트와 질문에 대해 답을 추출하거나 생성하는 태스크. 모델이 텍스트를 읽고 이해햐여 질문에 답할 수 있도록 함
    • wos: Web of Science: 데이터베이스에서 추출한 데이터를 활용하는 태스크. 특정 태스크보다는 데이터의 출처를 나타냄
import datasets
from datasets import load_dataset, ClassLabel,load_metric
import random
import pandas as pd
from IPython.display import display, HTML
from transformers import AutoTokenizer, pipeline, AutoModelForSequenceClassification, TrainingArguments, Trainer
import numpy as np
import tensorflow as tf
model_checkpoint = 'klue/roberta-base'
batch_size = 64
# ['ynat', 'sts', 'nli', 'ner', 're', 'dp', 'mrc', 'wos']
task = 'ynat'

datasets = load_dataset('klue',task)
datasets

datasets['train'][:10]

def show_rand_elements(dataset, num_examples = 10):
  picks = []

  for _ in range(num_examples):
    pick = random.randint(0,len(dataset)-1)
    while pick in picks:
      pick = random.randint(0,len(dataset)-1)

    picks.append(pick)
  df = pd.DataFrame(dataset[picks])
  return df
show_rand_elements(datasets['train'])

fake_preds = np.random.randint(0,2,size = (64,))
fake_labels = np.random.randint(0,2,size = (64,))
fake_preds, fake_labels

metric = load_metric('f1')

metric.compute(predictions=fake_preds, references=fake_labels)

 

tokenizer = AutoTokenizer.from_pretrained(model_checkpoint, use_fast = True)

tokenizer('평생 처음 주민들의 충격 증언... 대한민국 곳곳 이상징후')

print(tokenizer.cls_token_id, tokenizer.eos_token_id)
tokenizer

print(f'문장 1: {datasets["train"][0]["title"]}')

def preprocess_function(examples):
  return tokenizer(
      examples['title'],
      truncation=True, # 최대 길이를 초과할 경우 초과된 부분을 잘라냄
      return_token_type_ids=False,
  )
 
preprocess_function(datasets['train'][:5])

encoded_datasets = datasets.map(preprocess_function, batched = True)

num_labels = 7
# AutoModelForSequenceClassification
# 시퀀스 분류 작업(예: 감정분석, 텍스트 분류)
# 다양한 모델(BERT, RoBERTa 등) 지원
model = AutoModelForSequenceClassification.from_pretrained(model_checkpoint,num_labels=num_labels)

def compute_metrics(eval_pred):
  predictions, labels = eval_pred
  predictions = np.argmax(predictions, axis = 1)
  return metric.compute(predictions = predictions, references = labels, average = 'macro')
!pip install accelerate -U
!pip install transformers[torch]
metric_name = 'f1'

args = TrainingArguments(
    'test-tc',
    # 평가전략: 에폭이 끝날 때마다 평가를 수행
    evaluation_strategy='epoch',
    # 모델 체크포인트를 저장. 매 에포크마다 저장
    save_strategy='epoch',
    learning_rate = 2e-5,
    per_device_train_batch_size=batch_size,
    per_device_eval_batch_size = batch_size,
    num_train_epochs = 5,
    # 가중치 감소의 설정
    weight_decay=0.01,
    # 학습이 끝난 후 가장 좋은 성능을 보인 모델을 불러올지 결정
    load_best_model_at_end = True,
    # 최적의 모델을 결정할 때 사용할 메트릭을 지정
    metric_for_best_model = metric_name
)
trainer = Trainer(
    model,
    args,
    train_dataset=encoded_datasets['train'],
    eval_dataset=encoded_datasets['validation'],
    tokenizer=tokenizer,
    compute_metrics=compute_metrics
)
trainer.train()

trainer.evaluate()

classifier = pipeline(
    'text-classification',
    model = './test-tc/checkpoint-1428',
    return_all_scores=True
)

'''
0 (IT과학)
1 (경제)
2 (사회)
3 (생활문화)
4 (세계)
5 (스포치)
6 (정치)
'''
classifier('평생 처음 주민들의 충격 증언... 대한민국 곳곳 이상직후')

classifier('미 핵자산으로 북핵 대응” 한-미 정상 첫 명문화')

classifier('탈주 이제훈·구교환 파워 통했나…100만 관객 수 돌파')

'자연어 처리(NLP)' 카테고리의 다른 글

11. 자연어처리를 위한 모델 학습  (0) 2024.07.08
간단한 답변 랭킹 모델 만들기  (0) 2024.07.01
한국어 챗봇  (0) 2024.07.01
10. 문장 임베딩  (0) 2024.06.21
9. LSTM과 GRU  (0) 2024.06.21