일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 오블완
- streamlit
- ai캠프
- finpilot
- 로컬 런타임
- mysql
- pandas
- 정치기 필기
- ollama
- aws
- ML
- mifare
- Python
- chromeextention
- 파이썬
- djangorestframework
- Jupyterlab
- Github
- ai_캠프
- 머신러닝
- seaborn
- sLLM
- 티스토리챌린지
- lightsail
- team_project
- EC2
- pytorch
- ai 캠프
- conda
- django
- Today
- Total
greatsangho의 이야기
캠프56일차 - 파인튜닝된 LLM 모델의 성능 평가 방법 본문
- 파인튜닝
- LLM 모델에 소수의 데이터 또는 어떤 목적을 달성하기 위해서 기존 모델을 전체학습 하는게 아니라 해당 데이터만 학습해서 적용하는 방법
- 성능평가
- 감정분석의 경우 분류문제 - Accuracy
- 문장요약
- 원본과 요약문의 유사도 측정과 같은 방법
- 측정지표
- ROUGE(Recall-Oriented Understudy for Gisting Evaluation)
- 사용된 어휘 단어의 중복을 체크
- n-gram의 겹치는 비율
- Recall(재현율)에 중점을 둔 방법, 참조 텍스트의 중요한 내용을 얼마나 많이 포함하고 있는지 중점
- 장점 : 문장의 유사성을 측정 가능
- 단점 : 문맥상 맞지 않는 문장, 의미상 맞는 문장에 대한 오판 가능성
- BLEU(Billingual Evaluation Understudy)
- Precision(정밀도)에 중점을 둔 방식
- 생성된 텍스트의 n-gram의 일치여부의 비율 측정
- n-gram
- 연속된 n개의 단어 단위로 나누어진 텍스트 조각
- 1-gram : 단어 하나로 이루어진 조각
- 2-gram : 2개의 단어가 연속적으로 이루어진 조각
- 'I love natural language processing'
- 1-gram
- "I" "love" "natural" ...
- 2-gram
- "I love" "love natural" ...
- Bench Marking
- lm-eval-harness : 성능평가를 위한 벤치마킹 툴
이진 분류 모델의 평가
kogpt2 영화 리뷰
!pip install -q datasets
!pip install -q evaluate
!pip install -q rouge_score
!git clone https://github.com/e9t/nsmc nsmc
import torch
from transformers import GPT2LMHeadModel, TFGPT2Model, GPT2ForSequenceClassification
model_name = 'skt/kogpt2-base-v2'
model = GPT2ForSequenceClassification.from_pretrained(model_name,num_labels=2)
# 이진 분류를 위한 모델 로딩에 유의
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained(model_name, bos_token='</s>', eos_token='</s>', unk_token='<unk>',
pad_token='<pad>', mask_token='<mask>')
import pandas as pd
train_data = pd.read_csv('nsmc/ratings_train.txt', sep='\t').loc[:,'document':].dropna()
test_data = pd.read_csv('nsmc/ratings_test.txt', sep='\t').loc[:,'document':].dropna()
train_data.drop_duplicates(inplace=True)
test_data.drop_duplicates(inplace=True)
# 전처리
# 정규식을 이요해서 한글만 추출
import re
def clean_text(text):
text = re.sub('[^가-힣ㄱ-ㅎㅏ-ㅣ0-9a-zA-Z\\s]', '', text)
return text
train_data['document'] = train_data['document'].apply(clean_text)
test_data['document'] = test_data['document'].apply(clean_text)
# 토큰의 길이를 결정
import numpy as np
MAX_LENGTH = int(np.percentile(train_data['document'].apply(lambda x: len(x.split())), 95))
MAX_LENGTH
# 데이터셋으로 변경
from datasets import Dataset
train_dataset = Dataset.from_pandas(train_data)
test_dataset = Dataset.from_pandas(test_data)
train_dataset = train_dataset.map(lambda x: tokenizer(x['document'], truncation=True, padding='max_length', max_length=MAX_LENGTH),batched=True)
test_dataset = test_dataset.map(lambda x: tokenizer(x['document'], truncation=True, padding='max_length', max_length=MAX_LENGTH),batched=False)
데이터를 불러와 전처리를 진행한 뒤 모델을 학습시키기 위한 데이터셋으로 변환한다.
# 학습
from transformers import TrainingArguments, Trainer
training_args = TrainingArguments(
output_dir='./results', # output directory
num_train_epochs=3, # total number of training epochs
per_device_train_batch_size=128, # batch size per device during training
per_device_eval_batch_size=128, # batch size for evaluation
warmup_steps=200, # number of warmup steps for learning rate scheduler
weight_decay=0.01, # strength of weight decay
logging_dir='./logs', # directory for storing logs
logging_steps=500,
save_steps=1000,
save_strategy='no',
load_best_model_at_end=True,
)
def compute_metrics(eval_pred):
logits, labels = eval_pred
predictions = np.argmax(logits, axis=-1)
return {"accuracy": (predictions == labels).mean()}
trainer = Trainer(
model=model, # the instantiated 🤗 Transformers model to be trained
args=training_args, # training arguments, defined above
train_dataset=train_dataset, # training dataset
eval_dataset=test_dataset, # evaluation dataset
compute_metrics=compute_metrics,
)
#학습
trainer.train()
# 평가
results = trainer.evaluate()
print("Evaluation results:", results)
모델 학습은 다음과 같이 학습을 진행할 파라미터를 설정한 뒤, 모델을 학습 및 평가한다.
문장요약 평가
- ROUGE : datasets load_metrix('rouge')
https://aihub.or.kr/aihubdata/data/view.do?currMenu=115&topMenu=100&aihubDataSe=realm&dataSetSn=90
AI-Hub
샘플 데이터 ? ※샘플데이터는 데이터의 이해를 돕기 위해 별도로 가공하여 제공하는 정보로써 원본 데이터와 차이가 있을 수 있으며, 데이터에 따라서 민감한 정보는 일부 마스킹(*) 처리가 되
aihub.or.kr
AI 허브에서 논문자료 요약 데이터를 받아 진행해본다.
파일 중 training_논문.zip과 validation_논문.zip을 사용한다.
import json
import pandas as pd
with open('/content/training_논문/논문요약20231006_0.json', 'r', encoding='utf-8') as f:
train_data0 = json.load(f)
with open('/content/validation_논문/논문요약20231006_Validation.json', 'r', encoding='utf-8') as f:
test_data = json.load(f)
def extract_data(data):
summary_data = []
for item in data[0]['data']:
for section in item['summary_section']:
summary_data.append({
'original_text': section['orginal_text'],
'summary_text': section['summary_text']
})
df = pd.DataFrame(summary_data)
return df
train_df0 = extract_data(train_data0)
test_df = extract_data(test_data)
train_df0.to_csv('train0.csv', index=False)
test_df.to_csv('test.csv', index=False)
train_df = pd.read_csv('/content/train0.csv')
test_df = pd.read_csv('/content/test.csv')
train_df.dropna(inplace=True)
test_df.dropna(inplace=True)
train_df.drop_duplicates(inplace=True)
test_df.drop_duplicates(inplace=True)
train_df.reset_index(drop=True, inplace=True)
test_df.reset_index(drop=True, inplace=True)
import re
def remove_special_characters(text):
pattern = r'[^\wㅏ-ㅣㄱ-ㅎ가-힣\s]'
return re.sub(pattern, '', text)
train_df = train_df.map(remove_special_characters)
test_df = test_df.map(remove_special_characters)
train_df.shape, test_df.shape
json 형식이므로 다음과 같이 with open으로 불러온다. 불러온 데이터의 전처리를 진행한다. 데이터의 크기는 ((39998, 2), (17994, 2))이다.
import matplotlib.pyplot as plt
plt.figure(figsize=(12, 5))
train_df['original_text'].apply(lambda x: len(x.split())).hist(bins=50)
plt.xlabel('Length of Text')
plt.ylabel('Number of Text')
plt.title('Text Length Distribution')
# 데이터셋-문자길이
import numpy as np
MAX_LENGTH = int(np.percentile(train_df['original_text'].apply(lambda x: len(x.split())),90))
MAX_LENGTH # 189
해당 데이터를 시각화 하면 다음과 같다. 대략 80% 이상에 해당하는 범위에서 잘라준다.
# 모델로드
import torch
from transformers import GPT2LMHeadModel
model = GPT2LMHeadModel.from_pretrained('skt/kogpt2-base-v2')
# 토크나이져 로드
from transformers import PreTrainedTokenizerFast
tokenizer = PreTrainedTokenizerFast.from_pretrained("skt/kogpt2-base-v2",
bos_token='</s>', eos_token='</s>', unk_token='<unk>',
pad_token='<pad>', mask_token='<mask>')
# 평가지표 로드
import evaluate
import rouge_score
rouge = evaluate.load('rouge')
# 평가지표 함수
def complete_metrics(eval_pred):
# 모델 예측과 실제 레이블을 받음
predictions, labels = eval_pred
# 예측값에서 가장 높은 확률을 가진 인덱스 선택 후, 리스트로 변환
# 가장 높은 확률을 가진 인덱스를 선택하는 이유
# 가능성이 가장 높은 단어를 선택해서 최종 예측값으로 사용
predictions = np.argmax(predictions, axis=-1).tolist()
labels = labels.tolist()
# 예측과 레이블을 디코딩하여 텍스트로 변환
decoded_preds = tokenizer.batch_decode(predictions, skip_special_tokens=True)
decoded_labels = tokenizer.batch_decode(labels, skip_special_tokens=True)
# ROUGE 점수계산
result = rouge.compute(predictions=decoded_preds, references=decoded_labels, use_stemmer=True)
return {
"rouge1": result["rouge1"]*100,
"rouge2": result["rouge2"]*100,
"rougeL": result["rougeL"]*100,
"rougeLsum": result["rougeLsum"]*100,
}
# 입력 데이터에 labels 추가하는 함수
def preprocess_function(examples):
# text를 토큰화하고 길이 맞추기
inputs = tokenizer(examples['original_text'], truncation=True, padding='max_length', max_length=MAX_LENGTH)
# labels에 input_ids를 그대로 복사
inputs["labels"] = inputs["input_ids"].copy()
return inputs
# dataset
from datasets import Dataset
train_dataset = Dataset.from_pandas(train_data)
test_dataset = Dataset.from_pandas(test_data)
train_dataset = train_dataset.map(preprocess_function, batched=True)
test_dataset = test_dataset.map(preprocess_function, batched=True)
# 학습
from transformers import TrainingArguments, Trainer
training_args = TrainingArguments(
output_dir='./results', # output directory
num_train_epochs=3, # total number of training epochs
per_device_train_batch_size=128, # batch size per device during training
per_device_eval_batch_size=128, # batch size for evaluation
warmup_steps=200, # number of warmup steps for learning rate scheduler
weight_decay=0.01, # strength of weight decay
logging_dir='./logs', # directory for storing logs
logging_steps=500,
save_steps=1000,
save_strategy='no',
load_best_model_at_end=True,
)
trainer = Trainer(
model=model, # the instantiated 🤗 Transformers model to be trained
args=training_args, # training arguments, defined above
train_dataset=train_dataset, # training dataset
eval_dataset=test_dataset, # evaluation dataset
compute_metrics=complete_metrics,
)
#학습
trainer.train()
# 평가
results = trainer.evaluate()
print(f'Evaluation results: {results}')
이와 같은 방법으로 평가할 수 있다.
'프로그래밍 > SK AI 캠프' 카테고리의 다른 글
SK AI 캠프 13주차 후기 (4) | 2024.11.16 |
---|---|
캠프57일차 - 특정 LLM 모델 (BERT)을 Foundation 모델로 선택하여 도메인 특화 데이터로 파인튜닝 (1) | 2024.11.15 |
캠프55일차 - PEFT, LoRA 등 다양한 파인튜닝 기법에 대한 심화 학습 (0) | 2024.11.13 |
캠프54일차 - LLM 파인튜닝 개념과 기본 준비 (2) | 2024.11.12 |
캠프53일차 - 프롬프트 엔지니어링 응용 (Chain of Thought(CoT), Tree of Thought(ToT), Automatic Prompt Engineer(APE)) (8) | 2024.11.11 |