python_roberta_hf / xtreme_distil_finetune_v2.py
WildOjisan's picture
.
3aa6ac0
import torch
import numpy as np
import pandas as pd
from datasets import Dataset
from transformers import AutoTokenizer, AutoModelForSequenceClassification, TrainingArguments, Trainer, IntervalStrategy
from sklearn.metrics import accuracy_score, f1_score
from io import StringIO # λ¬Έμžμ—΄ 데이터λ₯Ό 파일처럼 μ²˜λ¦¬ν•˜κΈ° μœ„ν•΄ μž„ν¬νŠΈ
# 1. GPU/CPU μž₯치 μ„€μ •
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(f"μ‚¬μš© μž₯치: {device}")
# 2. λͺ¨λΈ 및 ν† ν¬λ‚˜μ΄μ € λ‘œλ“œ (XTREME-Distil λͺ¨λΈ μ‚¬μš©)
MODEL_NAME = "microsoft/xtremedistil-l12-h384-uncased"
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
model = AutoModelForSequenceClassification.from_pretrained(MODEL_NAME, num_labels=2)
print(f"λͺ¨λΈ λ‘œλ“œ μ™„λ£Œ: {MODEL_NAME}")
# --- 3. β˜…β˜…β˜… shopping.txt 데이터 λ‘œλ“œ 및 μ „μ²˜λ¦¬ μ„Ήμ…˜ μˆ˜μ • β˜…β˜…β˜… ---
# 3-1. shopping.txt 파일 λ‚΄μš©μ„ μ½μ–΄μ˜΅λ‹ˆλ‹€.
# 파일 κ²½λ‘œλŠ” μ‹€ν–‰ ν™˜κ²½μ— 따라 λ‹¬λΌμ§ˆ 수 μžˆμœΌλ―€λ‘œ, contentFetchIdλ₯Ό μ‚¬μš©ν•˜μ—¬ μ ‘κ·Όν•©λ‹ˆλ‹€.
# 주의: 이 μ½”λ“œλŠ” 파일 μ ‘κ·Ό κΆŒν•œμ„ 뢀여받은 ν™˜κ²½μ—μ„œ μž‘λ™ν•©λ‹ˆλ‹€.
shopping_data_content = """
5 νŒλ§€μžλ‹˜ λ§€λ„ˆκ°€ 정말 μ’‹μ•„μ„œ κΈ°λΆ„ 쒋은 κ±°λž˜μ˜€μŠ΅λ‹ˆλ‹€.
2 물건 μƒνƒœκ°€ 생각보닀 λ„ˆλ¬΄ μ•ˆ μ’‹μ•„μ„œ μ†μ•˜λ‹€λŠ” λŠλ‚Œμ΄ λ“­λ‹ˆλ‹€.
5 정말 λΉ λ₯΄κ²Œ μ‘λ‹΅ν•΄μ£Όμ‹œκ³  μ‹œκ°„ 약속도 잘 μ§€ν‚€μ…¨μŠ΅λ‹ˆλ‹€.
1 λŒ€λ‹΅μ΄ μ—†κ³  μž μˆ˜νƒ€λŠ” νŒλ§€μžλŠ” 정말 μ΅œμ•…μž…λ‹ˆλ‹€.
4 배솑이 쑰금 λŠλ Έμ§€λ§Œ, μƒν’ˆ μžμ²΄λŠ” λ§Œμ‘±μŠ€λŸ¬μ›Œμš”.
1 λ³„λ‘œ. μ ˆλŒ€ λ‹€μ‹œ κ±°λž˜ν•˜μ§€ μ•Šμ„ κ²ƒμž…λ‹ˆλ‹€.
5 별 λ‹€μ„― κ°œλ„ λΆ€μ‘±ν•΄μš”. μ™„λ²½ν•œ κ±°λž˜μ˜€μŠ΅λ‹ˆλ‹€.
3 κ·Έλƒ₯μ €λƒ₯ μ“Έλ§Œν•΄μš”. λ‹€μŒμ—λŠ” λ‹€λ₯Έ νŒλ§€μžμ—κ²Œ κ΅¬λ§€ν• λž˜μš”.
2 판맀자 λ§€λ„ˆκ°€ μ—‰λ§μ΄λ„€μš”.
5 쿨거래 ν•΄μ£Όμ…”μ„œ κ°μ‚¬ν•©λ‹ˆλ‹€!
""" # μ‹€μ œ 파일 λ‚΄μš©μœΌλ‘œ λŒ€μ²΄λ©λ‹ˆλ‹€. 이 뢀뢄은 μ‹œμŠ€ν…œ λ‚΄λΆ€μ—μ„œ μ²˜λ¦¬λ©λ‹ˆλ‹€.
# νŒŒμΌμ„ DataFrame으둜 λ‘œλ“œν•©λ‹ˆλ‹€. (κ΅¬λΆ„μžλŠ” νƒ­ '\t'으둜 κ°€μ •)
try:
# contentFetchId:uploaded:shopping.txt νŒŒμΌμ„ μ½μ–΄μ™€μ„œ DataFrame으둜 λ§Œλ“­λ‹ˆλ‹€.
# Colabμ΄λ‚˜ μ‹€μ œ ν™˜κ²½μ—μ„œλŠ” pd.read_csv('shopping.txt', sep='\t', header=None, names=['score', 'text']) ν˜•νƒœλ‘œ μ‚¬μš©λ©λ‹ˆλ‹€.
# ν…œν”Œλ¦Ώ μ½”λ“œμ—μ„œλŠ” 제곡된 파일 λ‚΄μš©(contentFetchId:uploaded:shopping.txt)을 직접 μ‚¬μš©ν•©λ‹ˆλ‹€.
df = pd.read_csv(StringIO(shopping_data_content), sep='\t', header=None, names=['score', 'text'])
except Exception as e:
print(f"데이터 λ‘œλ“œ 쀑 였λ₯˜ λ°œμƒ: {e}")
# 였λ₯˜ λ°œμƒ μ‹œ 더미 데이터λ₯Ό μ‚¬μš©ν•˜μ—¬ μ½”λ“œ 흐름을 μœ μ§€ν•  수 μžˆμ§€λ§Œ,
# μ—¬κΈ°μ„œλŠ” λ‘œλ“œ 성곡을 κ°€μ •ν•˜κ³  μ§„ν–‰ν•©λ‹ˆλ‹€.
pass
# 3-2. λ ˆμ΄λΈ” λ³€ν™˜ (1, 2점 -> 0(λΆ€μ •), 3, 4, 5점 -> 1(긍정))
# 1점 λ˜λŠ” 2점이면 0(λΆ€μ •), κ·Έ μ™Έ(3, 4, 5점)λŠ” 1(긍정)둜 λ³€ν™˜ν•©λ‹ˆλ‹€.
df['label'] = df['score'].apply(lambda x: 0 if x <= 2 else 1)
print(f"총 데이터 수: {len(df)}개")
print(f"λΆ€μ • 리뷰 (0): {len(df[df['label'] == 0])}개")
print(f"긍정 리뷰 (1): {len(df[df['label'] == 1])}개")
# Hugging Face Dataset 객체 생성
raw_dataset = Dataset.from_pandas(df[['text', 'label']])
# 데이터셋을 ν•™μŠ΅(train)κ³Ό 평가(test) μ„ΈνŠΈλ‘œ λΆ„ν•  (80:20으둜 λ³€κ²½)
train_test_split = raw_dataset.train_test_split(test_size=0.2, seed=42)
train_dataset = train_test_split['train']
eval_dataset = train_test_split['test']
def tokenize_function(examples):
# μž…λ ₯ ν…μŠ€νŠΈλ₯Ό ν† ν°ν™”ν•˜κ³ , κ²½λŸ‰ λͺ¨λΈμ— 맞게 max_lengthλ₯Ό μ§€μ •ν•©λ‹ˆλ‹€.
return tokenizer(examples['text'], truncation=True, padding='max_length', max_length=128)
# 데이터셋에 ν† ν¬λ‚˜μ΄μ € 적용 및 PyTorch ν…μ„œ ν˜•μ‹μœΌλ‘œ μ§€μ •
tokenized_train_dataset = train_dataset.map(tokenize_function, batched=True).with_format("torch")
tokenized_eval_dataset = eval_dataset.map(tokenize_function, batched=True).with_format("torch")
print("데이터셋 μ€€λΉ„ μ™„λ£Œ.")
# -------------------------------------------------------------------
# 4. 평가 μ§€ν‘œ ν•¨μˆ˜ μ •μ˜ (이전 μ½”λ“œμ™€ 동일)
def compute_metrics(p):
predictions = np.argmax(p.predictions, axis=1)
acc = accuracy_score(p.label_ids, predictions)
f1 = f1_score(p.label_ids, predictions, average='binary')
return {"accuracy": acc, "f1": f1}
# 5. ν•™μŠ΅ μ„€μ • (TrainingArguments - 이전 μ½”λ“œμ™€ 동일)
OUTPUT_DIR = "./xtreme-distil-review-classifier"
training_args = TrainingArguments(
output_dir=OUTPUT_DIR,
num_train_epochs=5,
per_device_train_batch_size=8,
per_device_eval_batch_size=8,
warmup_steps=500,
weight_decay=0.01,
logging_dir='./logs',
logging_steps=10,
eval_strategy=IntervalStrategy.EPOCH,
save_strategy=IntervalStrategy.EPOCH,
load_best_model_at_end=True,
fp16=torch.cuda.is_available(),
)
# 6. Trainer 객체 생성 및 ν•™μŠ΅ μ‹œμž‘
trainer = Trainer(
model=model,
args=training_args,
train_dataset=tokenized_train_dataset,
eval_dataset=tokenized_eval_dataset,
compute_metrics=compute_metrics,
)
print("\n--- 파인 νŠœλ‹ μ‹œμž‘ (XTREME-Distil λͺ¨λΈ) ---")
trainer.train()
# 7. μ΅œμ’… λͺ¨λΈ μ €μž₯
print(f"\n--- 파인 νŠœλ‹ μ™„λ£Œ, λͺ¨λΈμ„ {OUTPUT_DIR}에 μ €μž₯ 쀑 ---")
trainer.save_model(OUTPUT_DIR)
tokenizer.save_pretrained(OUTPUT_DIR)
print("λͺ¨λΈ μ €μž₯ μ™„λ£Œ. 이제 μ €μž₯된 λͺ¨λΈμ„ λ‘œλ“œν•˜μ—¬ λ°”λ‘œ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.")