File size: 5,630 Bytes
3aa6ac0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
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("λͺ¨λΈ μ €μž₯ μ™„λ£Œ. 이제 μ €μž₯된 λͺ¨λΈμ„ λ‘œλ“œν•˜μ—¬ λ°”λ‘œ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.")