일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- fastapi
- 1유형
- gradio
- streamlit
- 실기
- K최근접이웃
- 딥러닝
- 캐글
- Kaggle
- pytorch
- 공간분석
- 2유형
- DASH
- QGIS설치
- 공간시각화
- GPU
- Ai
- 성능
- webserving
- ml 웹서빙
- CUDA
- 머신러닝
- qgis
- 3유형
- KNN
- 예제소스
- 인공지능
- ㅂ
- dl
- 빅데이터분석기사
- Today
- Total
에코프로.AI
[HuggingFace] Fine-tuning - 2(Fine-tuning a model with the Trainer API) 본문
[HuggingFace] Fine-tuning - 2(Fine-tuning a model with the Trainer API)
AI_HitchHiker 2025. 1. 6. 14:30Fine-tuning a model with the Trainer API (Trainer API 로 모델 미세 조정하기)
🤗 트랜스포머는 데이터 세트에 대해 미리 학습된 모델을 미세 조정할 수 있도록 Trainer(트레이너) 클래스를 제공합니다. 마지막 섹션에서 모든 데이터 전처리 작업을 완료했다면 이제 트레이너를 정의하는 몇 단계만 남았습니다. 가장 어려운 부분은 CPU에서 매우 느리게 실행되므로 Trainer.train()을 실행할 환경을 준비하는 것입니다. GPU가 설정되어 있지 않은 경우 Google Colab에서 무료 GPU 또는 TPU에 액세스할 수 있습니다.
아래 코드 예제는 이전 섹션의 예제를 이미 실행한 것으로 가정합니다. 다음은 필요한 사항을 간략하게 요약한 것입니다:
from datasets import load_dataset
from transformers import AutoTokenizer, DataCollatorWithPadding
raw_datasets = load_dataset("glue", "mrpc")
checkpoint = "bert-base-uncased"
tokenizer = AutoTokenizer.from_pretrained(checkpoint)
def tokenize_function(example):
return tokenizer(example["sentence1"], example["sentence2"], truncation=True)
tokenized_datasets = raw_datasets.map(tokenize_function, batched=True)
data_collator = DataCollatorWithPadding(tokenizer=tokenizer)
Training (학습)
트레이너를 정의하기 전 첫 번째 단계는 트레이너가 훈련과 평가에 사용할 모든 하이퍼파라미터를 포함하는 TrainingArguments 클래스를 정의하는 것입니다. 제공해야 하는 유일한 인수는 학습된 모델이 저장될 디렉터리와 학습 과정의 체크포인트뿐입니다. 나머지는 기본값을 그대로 두면 기본적인 미세 조정에 적합합니다.
from transformers import TrainingArguments
training_args = TrainingArguments("test-trainer")
※ 위의 "test-trainer" 폴더이름 기준, 현재의 경로 + "test_trainer" 전체 경로에서 한글이 있으면, 아래의 trainer.train() 실행 시, " FailedPreconditionError: test-trainer is not a directory" 오류 발생합니다.
두 번째 단계는 모델을 정의하는 것입니다. 이전 장에서와 마찬가지로 두 개의 레이블이 있는 AutoModelForSequenceClassification 클래스를 사용합니다:
from transformers import AutoModelForSequenceClassification
model = AutoModelForSequenceClassification.from_pretrained(checkpoint, num_labels=2)
2장에서와 달리 이 사전 학습된 모델을 인스턴스화한 후 경고가 표시되는 것을 볼 수 있습니다. 이는 BERT가 문장 쌍 분류에 대해 사전 학습되지 않았기 때문에 사전 학습된 모델의 헤드를 삭제하고 대신 시퀀스 분류에 적합한 새 헤드를 추가했기 때문입니다. 경고는 일부 가중치(삭제된 사전 학습 헤드에 해당하는 가중치)가 사용되지 않았고 일부 가중치(새 헤드에 해당하는 가중치)가 임의로 초기화되었음을 나타냅니다. 이 경고는 모델을 훈련하도록 권장하는 것으로 마무리되며, 이것이 바로 지금 우리가 할 일입니다.
모델이 완성되면 모델, training_args, 훈련 데이터셋 (training datasets) 및 검증 데이터셋 (validation datasets) , data_collator , tokenizer 등 지금까지 구축한 모든 객체를 전달하여 트레이너를 정의할 수 있습니다:
from transformers import Trainer
trainer = Trainer(
model,
training_args,
train_dataset=tokenized_datasets["train"],
eval_dataset=tokenized_datasets["validation"],
data_collator=data_collator,
tokenizer=tokenizer,
)
여기서처럼 tokenizer를 전달하면 트레이너가 사용하는 기본 data_collator 는 앞서 정의한 대로 DataCollatorWithPadding이 되므로 이 호출에서 data_collator=data_collator 줄을 건너뛸 수 있다는 점에 유의하세요. 섹션 2에서 처리의 이 부분을 보여주는 것이 여전히 중요했습니다!
데이터 세트에서 모델을 미세 조정하려면 트레이너의 train() 메서드를 호출하기만 하면 됩니다:
trainer.train()
그러면 미세 조정이 시작되고(GPU에서 몇 분 정도 소요됨) 500단계마다 학습 손실이 보고됩니다. 그러나 모델이 얼마나 잘 수행되고 있는지(또는 얼마나 잘못 수행되고 있는지)는 알려주지 않습니다. 그 이유는 다음과 같습니다:
- 트레이너에게 evaluation_strategy(평가_전략) 을 "steps"(모든 평가_단계 평가) 또는 "epoch"(각 에포크 종료 시 평가)로 설정하여 훈련 중에 평가하도록 지시하지 않았습니다.
- 평가 중에 메트릭을 계산하는 compute_metrics() 함수를 트레이너에게 제공하지 않았습니다(그렇지 않으면 평가가 직관적이지 않은 숫자만 출력했을 것입니다).
Evaluation (평가)
유용한 compute_metrics() 함수를 작성하여 다음에 학습할 때 사용하는 방법을 살펴보겠습니다. 이 함수는 EvalPrediction 객체( predictions (예측) 필드와 label_ids 필드가 있는 명명된 튜플)를 취해야 하며 문자열을 부동 소수점으로 매핑하는 사전을 반환합니다(문자열은 반환되는 메트릭의 이름이고 부동 소수점은 그 값입니다). 모델에서 몇 가지 예측을 얻으려면 Trainer.predict() 명령을 사용할 수 있습니다:
predictions = trainer.predict(tokenized_datasets["validation"])
print(predictions.predictions.shape, predictions.label_ids.shape)
결과 값
(408, 2) (408,)
predict() 메서드의 출력은 predictions (예측), label_ids, metrics의 세 가지 필드가 있는 또 다른 명명된 튜플입니다. metrics 필드에는 전달된 데이터 세트의 손실과 일부 시간 메트릭(예측에 걸린 총 시간 및 평균 시간)만 포함됩니다. compute_metrics() 함수를 완료하고 트레이너에 전달하면 해당 필드에는 compute_metrics()에서 반환한 메트릭도 포함됩니다.
보시다시피, 예측은 408 x 2 모양의 2차원 배열입니다(408은 우리가 사용한 데이터 집합의 요소 수입니다). 이는 predict() 에 전달한 데이터 집합의 각 요소에 대한 로짓입니다(이전 장에서 보았듯이 모든 Transformer 모델은 로짓을 반환합니다). 이를 레이블과 비교할 수 있는 예측값으로 변환하려면 두 번째 축에 최대값이 있는 인덱스를 가져와야 합니다:
import numpy as np
preds = np.argmax(predictions.predictions, axis=-1)
이제 이러한 예측값을 레이블과 비교할 수 있습니다. compute_metric() 함수를 빌드하기 위해 🤗 Evaluate 라이브러리의 메트릭을 사용하겠습니다. 이번에는 evaluate.load() 함수를 사용하여 데이터 집합을 로드한 것처럼 MRPC 데이터 집합과 관련된 메트릭을 쉽게 로드할 수 있습니다. 반환된 객체에는 메트릭 계산을 수행하는 데 사용할 수 있는 compute() 메서드가 있습니다:
※ 먼저 evaluate 라이브러리를 설치해 준다.
pip install evaluate
import evaluate
metric = evaluate.load("glue", "mrpc")
metric.compute(predictions=preds, references=predictions.label_ids)
{'accuracy': 0.8578431372549019, 'f1': 0.8996539792387542}
모델 헤드의 무작위 초기화로 인해 달성한 지표가 변경될 수 있으므로 정확한 결과는 달라질 수 있습니다. 여기에서는 검증 세트에서 모델의 정확도가 85.78%이고 F1 점수가 89.97점인 것을 볼 수 있습니다. 이 두 가지 지표는 GLUE 벤치마크에 대한 MRPC 데이터 세트의 결과를 평가하는 데 사용되는 지표입니다. BERT 논문의 표에 따르면 기본 모델의 F1 점수는 88.9점입니다. 이는 대소문자가 없는 모델이었지만 현재는 대소문자가 있는 모델을 사용하고 있으므로 더 나은 결과를 설명할 수 있습니다.
모든 것을 종합하면 compute_metrics() 함수를 얻을 수 있습니다:
def compute_metrics(eval_preds):
metric = evaluate.load("glue", "mrpc")
logits, labels = eval_preds
predictions = np.argmax(logits, axis=-1)
return metric.compute(predictions=predictions, references=labels)
각 에포크가 끝날 때마다 메트릭을 보고하는 데 실제로 사용되는 것을 보려면 이 compute_metrics() 함수를 사용하여 새 트레이너를 정의하는 방법을 확인하세요:
training_args = TrainingArguments("test-trainer", evaluation_strategy="epoch")
model = AutoModelForSequenceClassification.from_pretrained(checkpoint, num_labels=2)
trainer = Trainer(
model,
training_args,
train_dataset=tokenized_datasets["train"],
eval_dataset=tokenized_datasets["validation"],
data_collator=data_collator,
tokenizer=tokenizer,
compute_metrics=compute_metrics,
)
evaluation_strategy(평가_전략)이 "epoch"으로 설정된 새 TrainingArguments와 새 모델을 생성합니다. 그렇지 않으면 이미 학습한 모델의 학습을 계속할 뿐입니다. 새 훈련 실행을 시작하려면 실행합니다:
trainer.train()
이번에는 훈련 손실 외에 각 에포크가 끝날 때마다 검증 손실과 메트릭을 보고합니다. 다시 말하지만, 모델의 무작위 헤드 초기화 때문에 정확한 정확도/F1 점수는 우리가 찾은 것과 약간 다를 수 있지만, 같은 범위 내에 있을 것입니다.
Trainer 는 여러 GPU 또는 TPU에서 즉시 작동하며 혼합 정밀도 훈련(훈련 인수에 fp16 = True 사용)과 같은 다양한 옵션을 제공합니다. 10장에서 지원하는 모든 기능을 살펴보겠습니다.
이것으로 트레이너 API를 사용한 미세 조정에 대한 소개를 마칩니다. 가장 일반적인 NLP 작업에 대해 이 작업을 수행하는 예제는 7장에서 제공되지만, 지금은 순수한 PyTorch에서 동일한 작업을 수행하는 방법을 살펴 보겠습니다.
참고사이트 : https://huggingface.co/learn/nlp-course/chapter3/3?fw=pt
끝~
