Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🌐 [i18n-KO] Translated Chapter 3 to Korean #572

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions chapters/ko/_toctree.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,23 @@
title: 단원 마무리 ν€΄μ¦ˆ
quiz: 2

- title: 3. μ‚¬μ „ν•™μŠ΅λœ λͺ¨λΈμ„ λ―Έμ„Έμ‘°μ •ν•˜κΈ°
sections:
- local: chapter3/1
title: 단원 μ†Œκ°œ
- local: chapter3/2
title: 데이터 처리 μž‘μ—…
- local: chapter3/3
title: Trainer API λ˜λŠ” (λ²ˆμ—­μ€‘)Kerasλ₯Ό μ΄μš©ν•œ λͺ¨λΈ λ―Έμ„Έ μ‘°μ •
local_fw: { pt: chapter3/3, tf: chapter3/3_tf }
- local: chapter3/4
title: 전체 ν•™μŠ΅
- local: chapter3/5
title: 단원 정리
- local: chapter3/6
title: (λ²ˆμ—­μ€‘) 단원 마무리 ν€΄μ¦ˆ
quiz: 3

- title: 5. πŸ€— Datasets 라이브러리
sections:
- local: chapter5/1
Expand Down
26 changes: 26 additions & 0 deletions chapters/ko/chapter3/1.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<FrameworkSwitchCourse {fw} />

# 단원 μ†Œκ°œ[[introduction]]

<CourseFloatingBanner
chapter={3}
classNames="absolute z-10 right-0 top-0"
/>

[2μž₯](/course/chapter2μ—μ„œλŠ” ν† ν¬λ‚˜μ΄μ €μ™€ 사전 ν•™μŠ΅λœ λͺ¨λΈμ„ μ‚¬μš©ν•˜μ—¬ μ˜ˆμΈ‘μ„ μˆ˜ν–‰ν•˜λŠ” 방법을 μ‚΄νŽ΄λ³΄μ•˜μŠ΅λ‹ˆλ‹€. 그런데 μ—¬λŸ¬λΆ„λ“€μ΄ 가지고 μžˆλŠ” 고유의 데이터셋(dataset)을 가지고 기쑴의 사전 ν•™μŠ΅λœ λͺ¨λΈμ„ λ―Έμ„Έ μ‘°μ •(fine-tune)ν•˜λ €λ©΄ μ–΄λ–»κ²Œ ν•΄μ•Ό ν• κΉŒμš”? 이 μž₯의 λ‚΄μš©μ΄ λ°”λ‘œ κ·Έ λΆ€λΆ„μž…λ‹ˆλ‹€! μ—¬κΈ°μ„œλŠ”:

{#if fw === 'pt'}
* πŸ€— Hubμ—μ„œ λŒ€κ·œλͺ¨ 데이터셋을 가지고 μ˜€λŠ” 방법에 λŒ€ν•΄μ„œ λ°°μ›λ‹ˆλ‹€.
* κ³ κΈ‰ Trainer APIλ₯Ό μ‚¬μš©ν•˜μ—¬ λͺ¨λΈμ„ λ―Έμ„Έ μ‘°μ •(fine-tune)ν•˜λŠ” 방법을 κ³΅λΆ€ν•©λ‹ˆλ‹€.
* μ‚¬μš©μž 지정 ν•™μŠ΅ 루프(custom training loop)을 μ‚¬μš©ν•˜λŠ” 방법을 μ•Œμ•„λ΄…λ‹ˆλ‹€.
* πŸ€— Accelerate 라이브러리λ₯Ό ν™œμš©ν•˜μ—¬ λΆ„μ‚° ν™˜κ²½μ—μ„œ μ‚¬μš©μž 지정 ν•™μŠ΅ 루프(custom training loop)을 μ‰½κ²Œ μ‹€ν–‰ν•˜λŠ” 방법을 κ³΅λΆ€ν•©λ‹ˆλ‹€.

{:else}
* πŸ€— Hubμ—μ„œ λŒ€κ·œλͺ¨ 데이터셋을 가지고 μ˜€λŠ” 방법에 λŒ€ν•΄μ„œ λ°°μ›λ‹ˆλ‹€.
* Kerasλ₯Ό μ‚¬μš©ν•˜μ—¬ λͺ¨λΈμ„ λ―Έμ„Έ μ‘°μ •(fine-tune)ν•˜λŠ” 방법을 κ³΅λΆ€ν•©λ‹ˆλ‹€.
* Kerasλ₯Ό μ‚¬μš©ν•˜μ—¬ μΆ”λ‘ ν•˜λŠ” 방법을 μ•Œμ•„λ΄…λ‹ˆλ‹€.
* μ‚¬μš©μž 지정 λ©”νŠΈλ¦­μ„ μ‚¬μš©ν•˜λŠ” 방법을 κ³΅λΆ€ν•©λ‹ˆλ‹€.

{/if}

λ―Έμ„Έ μ‘°μ •λœ 체크포인트(checkpoint)λ₯Ό Hugging Face Hub에 μ—…λ‘œλ“œν•˜λ €λ©΄ huggingface.co 계정이 ν•„μš”ν•©λ‹ˆλ‹€: [계정 생성](https://huggingface.co/join)
381 changes: 381 additions & 0 deletions chapters/ko/chapter3/2.mdx

Large diffs are not rendered by default.

170 changes: 170 additions & 0 deletions chapters/ko/chapter3/3.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
<FrameworkSwitchCourse {fw} />

# Trainer APIλ₯Ό μ΄μš©ν•œ λͺ¨λΈ λ―Έμ„Έ μ‘°μ •[[fine-tuning-a-model-with-the-trainer-api]]

<CourseFloatingBanner chapter={3}
classNames="absolute z-10 right-0 top-0"
notebooks={[
{label: "Google Colab", value: "https://colab.research.google.com/github/huggingface/notebooks/blob/master/course/en/chapter3/section3.ipynb"},
{label: "Aws Studio", value: "https://studiolab.sagemaker.aws/import/github/huggingface/notebooks/blob/master/course/en/chapter3/section3.ipynb"},
]} />

<Youtube id="nvBXf7s7vTI"/>

πŸ€—TransformersλŠ” `Trainer` 클래슀λ₯Ό μ œκ³΅ν•¨μœΌλ‘œμ¨ μ—¬λŸ¬λΆ„μ˜ 데이터셋을 μ΄μš©ν•˜μ—¬ 사전 ν•™μŠ΅λœ λͺ¨λΈ(pretrained models)을 λ―Έμ„Έ μ‘°μ •(fine-tuning)ν•  수 μžˆλ„λ‘ λ„μ™€μ€λ‹ˆλ‹€. 이전 μ„Ήμ…˜μ—μ„œ μ„€λͺ…ν•œ λͺ¨λ“  데이터 μ „μ²˜λ¦¬ μž‘μ—…μ„ μ™„λ£Œν–ˆλ‹€λ©΄, `Trainer`λ₯Ό μ •μ˜ν•˜λŠ”λ° λͺ‡κ°€μ§€ λ‹¨κ³„λ§Œ 거치면 λ©λ‹ˆλ‹€. κ°€μž₯ μ–΄λ €μš΄ 뢀뢄은 `Trainer.train()`을 μ‹€ν–‰ν•  ν™˜κ²½μ„ μ€€λΉ„ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. 이 μž‘μ—… μžμ²΄κ°€ CPUμ—μ„œ 맀우 느리게 μ‹€ν–‰λ˜κΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€. GPUκ°€ μ„€μ •λ˜μ§€ μ•Šμ€ 경우, Google Colabμ—μ„œ 무료 GPU λ˜λŠ” TPU에 μ•‘μ„ΈμŠ€ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
μ•„λž˜ μ½”λ“œ μ˜ˆμ œμ—μ„œλŠ” 이전 μ„Ήμ…˜μ˜ 예제λ₯Ό λͺ¨λ‘ μ‹€ν–‰ν–ˆλ‹€κ³  κ°€μ •ν•©λ‹ˆλ‹€. 이 μ½”λ“œλŠ” 이번 μ„Ήμ…˜μ˜ 예제λ₯Ό μ‹€ν–‰ν•˜κΈ° μœ„ν•΄ ν•„μš”ν•œ 사항을 κ°„λž΅ν•˜κ²Œ μš”μ•½ν•œ κ²ƒμž…λ‹ˆλ‹€:

```py
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]]

`Trainer`λ₯Ό μ •μ˜ν•˜κΈ° 전에 λ¨Όμ € μˆ˜ν–‰ν•  λ‹¨κ³„λŠ” `Trainer`κ°€ ν•™μŠ΅ 및 평가에 μ‚¬μš©ν•  λͺ¨λ“  ν•˜μ΄νΌνŒŒλΌλ―Έν„°(hyperparameters)λ₯Ό ν¬ν•¨ν•˜λŠ” `TrainingArguments` 클래슀λ₯Ό μ •μ˜ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. μ—¬κΈ°μ„œ μš°λ¦¬κ°€ μ œκ³΅ν•΄μ•Ό ν•  μœ μΌν•œ λ§€κ°œλ³€μˆ˜λŠ” ν•™μŠ΅λœ λͺ¨λΈμ΄ μ €μž₯될 λ””λ ‰ν† λ¦¬μž…λ‹ˆλ‹€. λ‚˜λ¨Έμ§€λŠ” λͺ¨λ‘ κΈ°λ³Έκ°’(default values)을 κ·ΈλŒ€λ‘œ ν™œμš©ν•˜λ©΄ λ©λ‹ˆλ‹€. 기본적인 λ―Έμ„Έ μ‘°μ •(fine-tuning)μ—λŠ” 이 정도면 μΆ©λΆ„ν•©λ‹ˆλ‹€.

```py
from transformers import TrainingArguments

training_args = TrainingArguments("test-trainer")
```

<Tip>

πŸ’‘ λ§Œμ•½ ν›ˆλ ¨ 쀑에 λͺ¨λΈμ„ μžλ™μœΌλ‘œ Hub에 μ—…λ‘œλ“œν•˜κ³  μ‹Άλ‹€λ©΄, `TrainingArguments`에 `push_to_hub=True`λ₯Ό μ „λ‹¬ν•˜μ„Έμš”. [Chapter 4](/course/chapter4/3)μ—μ„œ 이에 λŒ€ν•΄ 더 μžμ„Ένžˆ μ•Œμ•„λ³΄κ²Œ 될 κ²ƒμž…λ‹ˆλ‹€.

</Tip>

두 번째 λ‹¨κ³„λŠ” λͺ¨λΈμ„ μ •μ˜ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. [이전 μž₯](/course/chapter2)μ—μ„œμ™€ 같이, 두 개의 λ ˆμ΄λΈ”μ΄ μžˆλŠ” `AutoModelForSequenceClassification` 클래슀λ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

```py
from transformers import AutoModelForSequenceClassification

model = AutoModelForSequenceClassification.from_pretrained(checkpoint, num_labels=2)
```

[2μž₯](/course/chapter2)κ³Ό 달리, 사전 ν•™μŠ΅λœ λͺ¨λΈμ„ μΈμŠ€ν„΄μŠ€ν™”ν•œ ν›„ κ²½κ³ (warnings)κ°€ 좜λ ₯λ˜λŠ” 것을 μ•Œ 수 μžˆμŠ΅λ‹ˆλ‹€. μ΄λŠ” BERTκ°€ λ¬Έμž₯ 쌍 λΆ„λ₯˜μ— λŒ€ν•΄ 사전 ν•™μŠ΅λ˜μ§€ μ•Šμ•˜κΈ° λ•Œλ¬Έμ— 사전 ν•™μŠ΅λœ λͺ¨λΈμ˜ ν—€λ“œ(model head)λ₯Ό 버리고 μ‹œν€€μŠ€ λΆ„λ₯˜μ— μ ν•©ν•œ μƒˆλ‘œμš΄ ν—€λ“œλ₯Ό λŒ€μ‹  μΆ”κ°€ν–ˆκΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€. 경고의 λ‚΄μš©μ€ 일뢀 κ°€μ€‘μΉ˜(weights)κ°€ μ‚¬μš©λ˜μ§€ μ•Šμ•˜μœΌλ©°(제거된 사전 ν•™μŠ΅ ν—€λ“œμ— ν•΄λ‹Ήν•˜λŠ” κ°€μ€‘μΉ˜) 일뢀 κ°€μ€‘μΉ˜κ°€ λ¬΄μž‘μœ„λ‘œ μ΄ˆκΈ°ν™”λ˜μ—ˆμŒμ„(μƒˆλ‘œμš΄ ν—€λ“œμ— λŒ€ν•œ κ°€μ€‘μΉ˜) λ‚˜νƒ€λƒ…λ‹ˆλ‹€. λ§ˆμ§€λ§‰ λΆ€λΆ„μ—μ„œ μš°λ¦¬κ°€ μˆ˜ν–‰ν•˜λŠ” λ¬Έμž₯ 쌍 λΆ„λ₯˜μ— λŒ€ν•œ λ―Έμ„Έ 쑰정을 해도 μ’‹λ‹€κ³  μ„€λͺ…ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

λͺ¨λΈ(model), `training_args`, ν•™μŠ΅μ§‘ν•© 및 검증집합, `data_collator` 및 ν† ν¬λ‚˜μ΄μ € λ“±, μ§€κΈˆκΉŒμ§€ κ΅¬μ„±λœ λͺ¨λ“  개체λ₯Ό μ „λ‹¬ν•˜μ—¬ `Trainer`λ₯Ό μ •μ˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€:

```py
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,
)
```

μœ„μ—μ„œ 보듯이, ν† ν¬λ‚˜μ΄μ €λ₯Ό 전달할 λ•Œ `Trainer`κ°€ μ‚¬μš©ν•˜λŠ” κΈ°λ³Έ `data_collator`λŠ” 이전에 μ •μ˜λœ `DataCollatorWithPadding`이 λ©λ‹ˆλ‹€. λ”°λΌμ„œ 이 ν˜ΈμΆœμ—μ„œ `data_collator=data_collator` 행을 μƒλž΅ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

λ°μ΄ν„°μ…‹μœΌλ‘œ λͺ¨λΈμ„ λ―Έμ„Έ μ‘°μ •(fine-tuning)ν•˜λ €λ©΄ `Trainer`의 `train()` λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜κΈ°λ§Œ ν•˜λ©΄ λ©λ‹ˆλ‹€:

```py
trainer.train()
```

λ―Έμ„Έ 쑰정이 μ‹œμž‘λ˜κ³ (GPUμ—μ„œ λͺ‡ λΆ„ 정도 μ†Œμš”λ¨) 500λ‹¨κ³„λ§ˆλ‹€ ν•™μŠ΅ 손싀(training loss)이 λ³΄κ³ λ©λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ λͺ¨λΈμ˜ μ„±λŠ₯이 쒋은지 ν˜Ήμ€ λ‚˜μœμ§€λŠ” μ•Œλ €μ£Όμ§€ μ•ŠμŠ΅λ‹ˆλ‹€. κ·Έ μ΄μœ λŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€:

1. ν•™μŠ΅ κ³Όμ •μ—μ„œ 평가가 μˆ˜ν–‰λ˜λ„λ‘ `Trainer`μ—κ²Œ `evaluation_strategy` λ§€κ°œλ³€μˆ˜λ₯Ό `"steps"`(맀 `eval_steps`λ§ˆλ‹€ 평가)λ‚˜ `"epoch"`(각 epoch λ§ˆμ§€λ§‰μ— 평가) λ“±μœΌλ‘œ μ§€μ •ν•˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.
2. 평가 방법 ν˜Ήμ€ 평가 척도λ₯Ό μ •μ˜ν•œ `compute_metrics()` ν•¨μˆ˜λ₯Ό `Trainer`에 μ§€μ •ν•˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€. 평가 방법 지정이 μ•ˆλœ μƒνƒœμ—μ„œλŠ” 평가 κ³Όμ •μ—μ„œ 손싀(loss)을 좜λ ₯ν–ˆμ„ κ²ƒμž…λ‹ˆλ‹€. 직관적인 값은 μ•„λ‹ˆμ§€μš”.

### 평가[[evaluation]]

μœ μš©ν•œ `compute_metrics()` ν•¨μˆ˜λ₯Ό κ΅¬ν˜„ν•˜κ³  이λ₯Ό ν•™μŠ΅ν•  λ•Œ μ‚¬μš©ν•˜λŠ” 방법을 μ‚΄νŽ΄λ³΄κ² μŠ΅λ‹ˆλ‹€. 이 ν•¨μˆ˜λŠ” `EvalPrediction` 객체(`predictions` ν•„λ“œμ™€ `label_ids` ν•„λ“œκ°€ ν¬ν•¨λœ λ„€μž„λ“œνŠœν”Œ(named tuple))λ₯Ό ν•„μš”λ‘œ ν•˜λ©° λ¬Έμžμ—΄κ³Ό μ‹€μˆ˜κ°’(floats)을 λ§€ν•‘ν•˜λŠ” λ”•μ…”λ„ˆλ¦¬λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€. μ—¬κΈ°μ„œ λ¬Έμžμ—΄μ€ λ°˜ν™˜λœ λ©”νŠΈλ¦­(metrics)의 이름이고 μ‹€μˆ˜κ°’(floats)은 ν•΄λ‹Ή λ©”νŠΈλ¦­μ— κΈ°λ°˜ν•œ 평가 κ²°κ³Όκ°’μž…λ‹ˆλ‹€. μš°μ„  λͺ¨λΈμ—μ„œ 예츑의 κ²°κ³Όλ₯Ό μ–»μœΌλ €λ©΄ `Trainer.predict()` λͺ…령을 μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€:

```py
predictions = trainer.predict(tokenized_datasets["validation"])
print(predictions.predictions.shape, predictions.label_ids.shape)
```

```python out
(408, 2) (408,)
```

`predict()` λ©”μ„œλ“œμ˜ 좜λ ₯은 3개의 ν•„λ“œ(`predictions`, `label_ids` 및 `metrics`)κ°€ μžˆλŠ” 또 λ‹€λ₯Έ λ„€μž„λ“œνŠœν”Œ(named tuple)μž…λ‹ˆλ‹€. metrics ν•„λ“œμ—λŠ” μ „λ‹¬λœ λ°μ΄ν„°μ…‹μ˜ 손싀(loss)κ³Ό μ‹œκ°„ λ©”νŠΈλ¦­(time metrics) κ°’λ§Œ ν¬ν•¨λ©λ‹ˆλ‹€. μ‹œκ°„ λ©”νŠΈλ¦­(time metrics)은 μ˜ˆμΈ‘μ— κ±Έλ¦° 전체 및 평균 μ‹œκ°„μ„ λ‚˜νƒ€λƒ…λ‹ˆλ‹€. `compute_metrics()` ν•¨μˆ˜λ₯Ό κ΅¬μ„±ν•˜κ³  `Trainer`에 μ „λ‹¬ν•˜λ©΄ ν•΄λ‹Ή ν•„λ“œμ—λŠ” `compute_metrics()`μ—μ„œ λ°˜ν™˜ν•œ λ©”νŠΈλ¦­(metrics)도 ν¬ν•¨λ©λ‹ˆλ‹€.

λ³΄μ‹œλ‹€μ‹œν”Ό `predictions`λŠ” λͺ¨μ–‘이 408 x 2인 2차원 λ°°μ—΄μž…λ‹ˆλ‹€. 408은 μš°λ¦¬κ°€ μ˜ˆμΈ‘μ— μ‚¬μš©ν•œ λ°μ΄ν„°μ…‹μ˜ μš”μ†Œ κ°œμˆ˜μž…λ‹ˆλ‹€. μ΄λŠ” μš°λ¦¬κ°€ `predict()`에 μ „λ‹¬ν•œ λ°μ΄ν„°μ…‹μ˜ 각 μš”μ†Œμ— λŒ€ν•œ λ‘œμ§“(logit)κ°’λ“€μž…λ‹ˆλ‹€. [이전 μž₯](/course/chapter2)μ—μ„œ λ³΄μ•˜λ“―μ΄ λͺ¨λ“  Transformer λͺ¨λΈμ€ λ‘œμ§“(logit)값을 λ°˜ν™˜ν•©λ‹ˆλ‹€. 이 λ‘œμ§“(logit)값듀을 λ ˆμ΄λΈ”κ³Ό 비ꡐ할 수 μžˆλŠ” 예츑 결과둜 λ³€ν™˜ν•˜λ €λ©΄ 두 번째 μΆ•(second axis)에 μ‘΄μž¬ν•˜λŠ” ν•­λͺ©μ—μ„œ μ΅œλŒ€κ°’μ΄ μžˆλŠ” 인덱슀λ₯Ό 가져와야 ν•©λ‹ˆλ‹€:

```py
import numpy as np

preds = np.argmax(predictions.predictions, axis=-1)
```

이제 `preds`λ₯Ό λ ˆμ΄λΈ”(labels)κ³Ό 비ꡐ할 수 μžˆμŠ΅λ‹ˆλ‹€. `compute_metric()` ν•¨μˆ˜λ₯Ό κ΅¬μ„±ν•˜κΈ° μœ„ν•΄ [πŸ€—Evaluate](https://github.com/huggingface/evaluate/) λΌμ΄λΈŒλŸ¬λ¦¬μ—μ„œ μ œκ³΅ν•˜λŠ” λ©”νŠΈλ¦­(metrics)을 μ‚¬μš©ν•©λ‹ˆλ‹€. `evaluate.load()` ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ 데이터셋을 λ‘œλ“œν•˜λŠ” κ²ƒμ²˜λŸΌ μ†μ‰½κ²Œ MRPC 데이터셋과 κ΄€λ ¨λœ λ©”νŠΈλ¦­(metrics)을 λ‘œλ“œν•  수 μžˆμŠ΅λ‹ˆλ‹€. λ‘œλ“œλœ κ°μ²΄μ—λŠ” λ©”νŠΈλ¦­(metrics) 계산을 μˆ˜ν–‰ν•˜λŠ” 데 μ‚¬μš©ν•  수 μžˆλŠ” `compute()` λ©”μ„œλ“œκ°€ μžˆμŠ΅λ‹ˆλ‹€:

```py
import evaluate

metric = evaluate.load("glue", "mrpc")
metric.compute(predictions=preds, references=predictions.label_ids)
```

```python out
{'accuracy': 0.8578431372549019, 'f1': 0.8996539792387542}
```

λͺ¨λΈ ν—€λ“œλ₯Ό λ¬΄μž‘μœ„λ‘œ μ΄ˆκΈ°ν™”ν•˜λ©΄ κ³„μ‚°λœ λ©”νŠΈλ¦­μ΄ 변경될 수 μžˆμœΌλ―€λ‘œ μ •ν™•ν•œ κ²°κ³ΌλŠ” λ‹€λ₯Ό 수 μžˆμŠ΅λ‹ˆλ‹€. μ—¬κΈ°μ„œλŠ” λͺ¨λΈμ΄ 검증 μ§‘ν•©μ—μ„œ 86.76%의 정확도(accuracy)와 90.69의 F1 점수λ₯Ό 가지고 μžˆμŒμ„ μ•Œ 수 μžˆμŠ΅λ‹ˆλ‹€(μ—¬λŸ¬λΆ„μ˜ κ²°κ³Όκ°’κ³ΌλŠ” λ‹€λ₯Ό μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.). μ΄λŠ” GLUE 벀치마크의 MRPC 데이터셋에 λŒ€ν•œ 예츑 κ²°κ³Όλ₯Ό ν‰κ°€ν•˜λŠ”λ° μ‚¬μš©λ˜λŠ” 두 가지 λ©”νŠΈλ¦­(metrics)μž…λ‹ˆλ‹€. [BERT λ…Όλ¬Έ](https://arxiv.org/pdf/1810.04805.pdf)의 ν…Œμ΄λΈ”μ€ κΈ°λ³Έ λͺ¨λΈμ— λŒ€ν•΄ F1 점수 88.9λ₯Ό λ³΄κ³ ν–ˆμŠ΅λ‹ˆλ‹€. ν•΄λ‹Ή λ…Όλ¬Έμ—μ„œ μ‚¬μš©λœ λͺ¨λΈμ€ μ†Œλ¬Έμž λͺ¨λΈ(`uncased` model)μ΄μ—ˆκ³  μ—¬κΈ°μ„œλŠ” λŒ€μ†Œλ¬Έμž ꡬ뢄 λͺ¨λΈ(`cased` model)을 ν™œμš©ν–ˆμœΌλ―€λ‘œ μ„±λŠ₯ 차이가 λ°œμƒν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

μ§€κΈˆκΉŒμ§€ μ„€λͺ…ν•œ λͺ¨λ“  것을 ν•¨κ»˜ μ’…ν•©ν•˜λ©΄ `compute_metrics()` ν•¨μˆ˜λ₯Ό 얻을 수 μžˆμŠ΅λ‹ˆλ‹€:

```py
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)
```

각 에포크(epoch)κ°€ 끝날 λ•Œ λ©”νŠΈλ¦­(metrics)을 좜λ ₯ν•˜λ„λ‘ ν•˜κΈ° μœ„ν•΄μ„œ, `compute_metrics()` ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ μƒˆ `Trainer`λ₯Ό μ •μ˜ν•˜λŠ” 방법을 μ•„λž˜ μ½”λ“œμ—μ„œ 보여주고 μžˆμŠ΅λ‹ˆλ‹€:

```py
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`와 λͺ¨λΈμ„ μƒμ„±ν•©λ‹ˆλ‹€. 그렇지 μ•ŠμœΌλ©΄ 이미 μ•žμ—μ„œ ν•™μŠ΅λœ(fine-tuned) λͺ¨λΈμ˜ ν•™μŠ΅μ„ κ³„μ†ν•΄μ„œ μˆ˜ν–‰ν•  κ²ƒμž…λ‹ˆλ‹€. μƒˆλ‘œμš΄ ν•™μŠ΅ 싀행을 μ‹œμž‘ν•˜κΈ° μœ„ν•΄ λ‹€μŒμ„ μ‹€ν–‰ν•©λ‹ˆλ‹€:

```py
trainer.train()
```

μ΄λ²ˆμ—λŠ” ν•™μŠ΅ 손싀(training loss) 외에 각 epochκ°€ 끝날 λ•Œ 검증 손싀(validation loss) 및 λ©”νŠΈλ¦­(metrics)을 λ³΄κ³ ν•©λ‹ˆλ‹€. λ‹€μ‹œ λ§ν•˜μ§€λ§Œ, μ •ν™•ν•œ 정확도(accuracy)/F1 μ μˆ˜λŠ” λͺ¨λΈμ˜ λ¬΄μž‘μœ„ ν—€λ“œ μ΄ˆκΈ°ν™”λ‘œ 인해 각각의 μ‹€ν–‰ κ²°κ³Όκ°€ μ•½κ°„ λ‹€λ₯Ό 수 μžˆμ§€λ§Œ μœ μ‚¬ν•œ λ²”μœ„ 내에 μžˆμ–΄μ•Ό ν•©λ‹ˆλ‹€.

`Trainer`λŠ” 닀쀑 GPU λ˜λŠ” TPUμ—μ„œ μ¦‰μ‹œ μ‚¬μš©ν•  수 있으며 ν˜Όν•© 정밀도 ν•™μŠ΅(mixed-precision training, ν•™μŠ΅ λ§€κ°œλ³€μˆ˜μ—μ„œ `fp16 = True` μ‚¬μš©ν•˜λŠ” 경우)κ³Ό 같은 λ‹€μ–‘ν•œ μ˜΅μ…˜μ„ μ œκ³΅ν•©λ‹ˆλ‹€. 10μž₯μ—μ„œ μ§€μ›ν•˜λŠ” λͺ¨λ“  μ˜΅μ…˜λ“€μ„ μ‚΄νŽ΄λ³Ό κ²ƒμž…λ‹ˆλ‹€.

μ΄κ²ƒμœΌλ‘œ `Trainer` APIλ₯Ό μ‚¬μš©ν•œ λ―Έμ„Έ μ‘°μ •(fine-tuning) 방법에 λŒ€ν•œ μ„€λͺ…을 λ§ˆμΉ©λ‹ˆλ‹€. κ°€μž₯ 자주 μˆ˜ν–‰λ˜λŠ” NLP μž‘μ—…(tasks)에 λŒ€ν•΄ 이 μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” μ˜ˆλŠ” [7μž₯](/course/chapter7)μ—μ„œ μ œκ³΅λ˜μ§€λ§Œ, λ‹€μŒ μ„Ήμ…˜μ—μ„œ 이 APIλ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šκ³  PyTorchμ—μ„œ λ™μΌν•œ μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” 방법을 μ‚΄νŽ΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

<Tip>

✏️ **직접 해보기** 2μž₯μ—μ„œ μˆ˜ν–‰ν•œ 데이터 처리λ₯Ό μ‚¬μš©ν•˜μ—¬ GLUE SST-2 λ°μ΄ν„°μ…‹μ—μ„œ λͺ¨λΈμ„ λ―Έμ„Έ μ‘°μ •(fine-tune)ν•˜μ„Έμš”.

</Tip>

Loading