반응형
블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리


반응형

https://huggingface.co/learn/nlp-course/chapter3/5?fw=pt

 

Fine-tuning, Check! - Hugging Face NLP Course

2. Using 🤗 Transformers 3. Fine-tuning a pretrained model 4. Sharing models and tokenizers 5. The 🤗 Datasets library 6. The 🤗 Tokenizers library 9. Building and sharing demos new

huggingface.co

 

Fine-tuning, Check!

 

That was fun! In the first two chapters you learned about models and tokenizers, and now you know how to fine-tune them for your own data. To recap, in this chapter you:

 

재미있었어요! 처음 두 장에서는 모델과 토크나이저에 대해 배웠고 이제 자신의 데이터에 맞게 미세 조정하는 방법을 알게 되었습니다. 요약하면 이 장에서는 다음을 수행합니다.

 

  • Learned about datasets in the Hub 허브의 데이터 세트에 대해 배웠습니다.
  • Learned how to load and preprocess datasets, including using dynamic padding and collators
  • 동적 패딩 및 콜레이터 사용을 포함하여 데이터 세트를 로드하고 전처리하는 방법을 배웠습니다.
  • Implemented your own fine-tuning and evaluation of a model
  • 모델에 대한 자체 미세 조정 및 평가 구현
  • Implemented a lower-level training loop
  • 낮은 수준의 훈련 루프를 구현했습니다.
  • Used 🤗 Accelerate to easily adapt your training loop so it works for multiple GPUs or TPUs
  • 여러 GPU 또는 TPU에서 작동하도록 훈련 루프를 쉽게 조정하기 위해 🤗  Accelerate를 사용했습니다.
 

Hugging Face – The AI community building the future.

 

huggingface.co

 

 

 

 

 

 

 

반응형


반응형

https://huggingface.co/learn/nlp-course/chapter3/4?fw=pt

 

A full training - Hugging Face NLP Course

Now we’ll see how to achieve the same results as we did in the last section without using the Trainer class. Again, we assume you have done the data processing in section 2. Here is a short summary covering everything you will need: Before actually writi

huggingface.co

 

https://youtu.be/Dh9CL8fyG80?si=3CJkNCLDiNe4l80r

 

 

 

 

A full training

 

Now we’ll see how to achieve the same results as we did in the last section without using the Trainer class. Again, we assume you have done the data processing in section 2. Here is a short summary covering everything you will need:

 

이제 Trainer 클래스를 사용하지 않고 마지막 섹션에서와 동일한 결과를 얻는 방법을 살펴보겠습니다. 다시 한 번 섹션 2에서 데이터 처리를 완료했다고 가정합니다. 다음은 필요한 모든 내용을 다루는 간단한 요약입니다.

 

from datasets import load_dataset
from transformers import AutoTokenizer, DataCollatorWithPadding

# "glue" 데이터셋의 "mrpc" 태스크를 로드
raw_datasets = load_dataset("glue", "mrpc")

# BERT의 사전 훈련된 토크나이저를 불러오기
checkpoint = "bert-base-uncased"
tokenizer = AutoTokenizer.from_pretrained(checkpoint)

# 사용자 정의 토큰화 함수 정의
def tokenize_function(example):
    return tokenizer(example["sentence1"], example["sentence2"], truncation=True)

# 토큰화된 데이터셋 생성 (batched=True로 설정하여 배치 단위로 토큰화)
tokenized_datasets = raw_datasets.map(tokenize_function, batched=True)

# 데이터 콜레이터 생성 (패딩 추가)
data_collator = DataCollatorWithPadding(tokenizer=tokenizer)

 

이 코드는 Hugging Face Transformers 라이브러리를 사용하여 데이터셋을 로드하고 토큰화하는 과정을 나타냅니다. 코드를 단계별로 설명하겠습니다.

 

해석:

  1. load_dataset("glue", "mrpc"): Hugging Face의 datasets 라이브러리를 사용하여 GLUE 벤치마크의 MRPC(Microsoft Research Paraphrase Corpus) 태스크를 로드합니다.
  2. AutoTokenizer.from_pretrained(checkpoint): BERT 모델의 사전 훈련된 토크나이저를 불러옵니다. 여기서는 "bert-base-uncased"를 사용합니다.
  3. tokenize_function(example): 사용자 정의 토큰화 함수를 정의합니다. 이 함수는 입력으로 문장1(sentence1)과 문장2(sentence2)를 받아 토큰화한 결과를 반환합니다. truncation=True는 문장이 일정 길이를 초과할 경우 자르도록 설정한 것입니다.
  4. raw_datasets.map(tokenize_function, batched=True): 토큰화 함수를 사용하여 데이터셋을 토큰화합니다. batched=True로 설정하여 배치 단위로 토큰화합니다.
  5. DataCollatorWithPadding(tokenizer=tokenizer): 데이터 콜레이터를 생성합니다. 이 객체는 배치를 처리하여 패딩을 추가하고 동일한 길이로 만들어주는 역할을 합니다. 여기서는 BERT의 토크나이저를 사용하여 패딩을 추가하도록 설정했습니다.

이렇게 토큰화된 데이터셋과 데이터 콜레이터는 모델을 훈련하거나 평가할 때 사용됩니다. 데이터셋은 토큰화된 형태로 모델에 입력되고, 데이터 콜레이터는 배치를 처리하여 패딩을 추가하여 모델이 일관된 형태로 데이터를 처리할 수 있도록 도와줍니다.

 

 

Prepare for training

 

Before actually writing our training loop, we will need to define a few objects. The first ones are the dataloaders we will use to iterate over batches. But before we can define those dataloaders, we need to apply a bit of postprocessing to our tokenized_datasets, to take care of some things that the Trainer did for us automatically. Specifically, we need to:

 

실제로 훈련 루프를 작성하기 전에 몇 가지 객체를 정의해야 합니다. 첫 번째는 배치를 반복하는 데 사용할 데이터로더입니다. 하지만 이러한 데이터로더를 정의하기 전에 Trainer가 자동으로 수행한 일부 작업을 처리하기 위해 tokenized_datasets에 약간의 후처리를 적용해야 합니다. 구체적으로 다음을 수행해야 합니다.

 

  • Remove the columns corresponding to values the model does not expect (like the sentence1 and sentence2 columns).

  • 모델이 예상하지 않는 값(예: 문장1 및 문장2 열)에 해당하는 열을 제거합니다.

  • Rename the column label to labels (because the model expects the argument to be named labels).

  • 열 레이블의 이름을 labels  로 바꿉니다(모델에서는 인수 이름이 labels  로 지정될 것으로 예상하기 때문입니다).

  • Set the format of the datasets so they return PyTorch tensors instead of lists.

  • 목록 대신 PyTorch 텐서를 반환하도록 데이터 세트의 형식을 설정합니다.

Our tokenized_datasets has one method for each of those steps:

 

tokenized_datasets에는 각 단계에 대해 하나의 방법이 있습니다.

 

tokenized_datasets = tokenized_datasets.remove_columns(["sentence1", "sentence2", "idx"])
tokenized_datasets = tokenized_datasets.rename_column("label", "labels")
tokenized_datasets.set_format("torch")
tokenized_datasets["train"].column_names

 

이 코드는 Hugging Face의 datasets 라이브러리에서 사용되는 데이터셋 객체의 몇 가지 조작을 수행하는 부분입니다. 코드를 단계별로 설명하겠습니다.

 

해석:

  1. tokenized_datasets.remove_columns(["sentence1", "sentence2", "idx"]): "sentence1", "sentence2", 그리고 "idx" 열을 삭제합니다. 이 열들은 토큰화 이전에 원시 데이터셋에서 가져온 열일 것으로 예상됩니다.
  2. tokenized_datasets.rename_column("label", "labels"): "label" 열의 이름을 "labels"로 변경합니다. 일반적으로 Hugging Face Transformers 라이브러리에서 모델 훈련을 위해 사용되는 레이블 열의 이름은 "labels"입니다.
  3. tokenized_datasets.set_format("torch"): 데이터셋의 형식을 "torch"로 설정합니다. 이렇게 설정하면 PyTorch 텐서 형식으로 데이터셋이 변환됩니다.
  4. tokenized_datasets["train"].column_names: "train" 부분의 데이터셋에 있는 열의 이름들을 반환합니다. 이를 통해 현재 데이터셋에 어떤 열들이 있는지 확인할 수 있습니다.

따라서 최종적으로 "sentence1", "sentence2", "idx" 열이 삭제되고, "label"이 "labels"로 이름이 변경되며, 데이터셋의 형식이 PyTorch 텐서로 변경된 상태의 데이터셋이 만들어집니다.

 

We can then check that the result only has columns that our model will accept:

 

그런 다음 결과에 모델이 허용하는 열만 있는지 확인할 수 있습니다.

 

["attention_mask", "input_ids", "labels", "token_type_ids"]

 

 

 

Now that this is done, we can easily define our dataloaders:

 

이제 이 작업이 완료되었으므로 데이터로더를 쉽게 정의할 수 있습니다.

 

from torch.utils.data import DataLoader

# 훈련 데이터 로더 생성
train_dataloader = DataLoader(
    tokenized_datasets["train"],  # 훈련 데이터셋
    shuffle=True,                 # 에폭마다 데이터를 섞을지 여부
    batch_size=8,                 # 배치 크기
    collate_fn=data_collator      # 데이터 콜레이터 함수 (패딩 추가)
)

# 검증 데이터 로더 생성
eval_dataloader = DataLoader(
    tokenized_datasets["validation"],  # 검증 데이터셋
    batch_size=8,                       # 배치 크기
    collate_fn=data_collator            # 데이터 콜레이터 함수 (패딩 추가)
)

 

이 코드는 PyTorch의 DataLoader를 사용하여 훈련 및 검증 데이터셋에 대한 데이터 로더를 만드는 부분입니다. 코드를 단계별로 설명하겠습니다.

 

해석:

  1. DataLoader: PyTorch의 데이터 로더 클래스로, 데이터셋에서 샘플을 미니배치로 효율적으로 로드하는 데 사용됩니다.
  2. tokenized_datasets["train"] 및 tokenized_datasets["validation"]: 각각 훈련 및 검증 데이터셋을 나타냅니다.
  3. shuffle=True: 훈련 데이터셋을 에폭(epoch)마다 섞을지 여부를 나타내는 매개변수입니다. 훈련 데이터셋을 섞어 모델이 다양한 샘플을 학습하도록 도웁니다.
  4. batch_size=8: 미니배치의 크기를 나타내는 매개변수로, 각 미니배치에 포함될 샘플의 수를 결정합니다.
  5. collate_fn=data_collator: 데이터 콜레이터 함수를 지정합니다. 이 함수는 배치의 샘플을 처리하여 패딩을 추가하고 동일한 길이로 만들어주는 역할을 합니다. 여기서는 앞서 생성한 DataCollatorWithPadding 객체를 사용합니다.

이렇게 생성된 train_dataloader와 eval_dataloader는 각각 훈련 및 검증 단계에서 사용됩니다. 모델 훈련 시에는 train_dataloader를 이용하여 미니배치 단위로 데이터를 모델에 공급하고, 검증 시에는 eval_dataloader를 사용하여 검증 데이터셋에 대한 예측을 수행합니다.

 

 

To quickly check there is no mistake in the data processing, we can inspect a batch like this:

 

데이터 처리에 실수가 없는지 빠르게 확인하기 위해 다음과 같은 배치를 검사할 수 있습니다.

 

for batch in train_dataloader:
    break
{k: v.shape for k, v in batch.items()}
{'attention_mask': torch.Size([8, 65]),
 'input_ids': torch.Size([8, 65]),
 'labels': torch.Size([8]),
 'token_type_ids': torch.Size([8, 65])}

 

이 코드는 train_dataloader에서 첫 번째 미니배치를 가져와서 그 구조와 크기를 출력하는 부분입니다. 코드를 단계별로 설명하겠습니다.

 

해석:

  1. for batch in train_dataloader:: train_dataloader에서 미니배치를 순회합니다.
  2. break: 첫 번째 미니배치를 가져오고 반복문을 종료합니다. 이 부분에서는 첫 번째 미니배치만 확인합니다.
  3. {k: v.shape for k, v in batch.items()}: 미니배치의 각 텐서의 크기(shape)를 딕셔너리 형태로 출력합니다. 이 딕셔너리는 각 텐서의 키와 크기를 보여줍니다.
    • k는 텐서의 키를 나타내며, 여기서는 "input_ids," "attention_mask," "labels" 등이 될 수 있습니다.
    • v.shape는 텐서의 크기를 나타내며, 예를 들어 (배치 크기, 최대 시퀀스 길이)와 같은 형태일 것입니다.

이 코드를 실행하면 첫 번째 미니배치의 구조와 크기를 확인할 수 있습니다. 이는 데이터 처리 및 토큰화가 올바르게 이루어졌는지 확인하는 데 도움이 됩니다.

 

 

 

 

Note that the actual shapes will probably be slightly different for you since we set shuffle=True for the training dataloader and we are padding to the maximum length inside the batch.

 

훈련 데이터로더에 shuffle=True를 설정하고 배치 내부의 최대 길이까지 패딩하기 때문에 실제 모양은 약간 다를 수 있습니다.

 

Now that we’re completely finished with data preprocessing (a satisfying yet elusive goal for any ML practitioner), let’s turn to the model. We instantiate it exactly as we did in the previous section:

 

이제 데이터 전처리(ML 실무자에게는 달성하기 어려운 목표이지만 그래도 만족스러)가 완전히 완료되었으므로 모델을 살펴보겠습니다. 이전 섹션에서 했던 것과 똑같이 인스턴스화합니다.

 

from transformers import AutoModelForSequenceClassification

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

 

이 코드는 Hugging Face Transformers 라이브러리를 사용하여 시퀀스 분류 모델을 로드하는 부분입니다. 코드를 단계별로 설명하겠습니다.

 

해석:

  1. from transformers import AutoModelForSequenceClassification: 시퀀스 분류 모델을 불러오기 위해 Hugging Face Transformers 라이브러리에서 AutoModelForSequenceClassification 클래스를 가져옵니다.
  2. AutoModelForSequenceClassification.from_pretrained(checkpoint, num_labels=2): 미리 훈련된 모델을 로드합니다. checkpoint는 로드하려는 모델의 이름 또는 경로를 나타냅니다. num_labels=2는 출력 레이블의 수를 나타내며, 이 경우 이진 분류를 위해 2로 설정되었습니다.

로드된 모델은 텍스트 시퀀스를 입력으로 받아 각 클래스에 대한 로짓을 출력하는 시퀀스 분류 모델입니다. 이 모델은 이미 사전 훈련된 가중치를 가지고 있으며, 특정 작업에 맞게 조정할 수 있습니다. 이러한 모델을 훈련하거나 텍스트 분류 작업에 활용할 수 있습니다.

 

To make sure that everything will go smoothly during training, we pass our batch to this model:

 

훈련 중에 모든 것이 원활하게 진행되도록 배치를 다음 모델에 전달합니다.

 

outputs = model(**batch)
print(outputs.loss, outputs.logits.shape)

 

tensor(0.5441, grad_fn=<NllLossBackward>) torch.Size([8, 2])

 

이 코드는 시퀀스 분류 모델에 입력 데이터를 주입하고, 모델의 출력인 손실 값(loss)과 로짓(logits)의 형태(shape)를 출력하는 부분입니다. 코드를 단계별로 설명하겠습니다.

 

해석:

  1. model(**batch): batch에 있는 입력 데이터를 모델에 전달합니다. batch에는 토큰화된 입력 데이터가 있으며, 모델은 이를 처리하여 예측을 수행합니다.
  2. outputs: 모델의 출력 결과를 저장한 객체입니다. 이 객체에는 여러 속성이 포함되어 있습니다.
    • outputs.loss: 모델의 출력 손실 값입니다. 이 값은 훈련 중에 사용되며, 손실을 최소화하기 위해 모델의 가중치가 업데이트됩니다.
    • outputs.logits: 모델의 출력으로, 각 클래스에 대한 로짓 값입니다. 로짓은 softmax 함수를 거친 후 확률로 변환되어 예측 클래스가 결정됩니다. logits.shape는 로짓 텐서의 크기를 나타냅니다.
  3. print(outputs.loss, outputs.logits.shape): 모델의 출력인 손실 값과 로짓 텐서의 크기를 출력합니다.

이 코드는 모델이 입력 데이터를 처리하고 그 결과를 확인하는 데 사용됩니다. 특히, 훈련할 때는 손실 값이 중요하며, 추론 및 평가 단계에서는 로짓을 통해 예측 결과를 확인할 수 있습니다.

 

 

 

All 🤗 Transformers models will return the loss when labels are provided, and we also get the logits (two for each input in our batch, so a tensor of size 8 x 2).

 

모든 🤗 Transformers 모델은 레이블이 제공되면 손실을 반환하며 로지트도 얻습니다(배치의 각 입력에 대해 2개이므로 크기가 8 x 2인 텐서).

 

We’re almost ready to write our training loop! We’re just missing two things: an optimizer and a learning rate scheduler. Since we are trying to replicate what the Trainer was doing by hand, we will use the same defaults. The optimizer used by the Trainer is AdamW, which is the same as Adam, but with a twist for weight decay regularization (see “Decoupled Weight Decay Regularization” by Ilya Loshchilov and Frank Hutter):

 

훈련 루프를 작성할 준비가 거의 다 되었습니다! 우리는 최적화 프로그램과 학습률 스케줄러라는 두 가지를 놓치고 있습니다. Trainer가 직접 수행한 작업을 복제하려고 하므로 동일한 기본값을 사용하겠습니다. Trainer에서 사용하는 최적화 프로그램은 AdamW입니다. 이는 Adam과 동일하지만 체중 감소 정규화에 대한 변형이 있습니다(Ilya Loshchilov 및 Frank Hutter의 "De커플링된 체중 감소 정규화" 참조).

 

from transformers import AdamW

# 모델의 파라미터에 AdamW 옵티마이저를 설정
optimizer = AdamW(model.parameters(), lr=5e-5)
 

이 코드는 Hugging Face Transformers 라이브러리에서 제공하는 AdamW 옵티마이저를 설정하는 부분입니다. 코드를 단계별로 설명하겠습니다.

 

해석:

  1. from transformers import AdamW: Hugging Face Transformers 라이브러리에서 AdamW 옵티마이저를 가져옵니다.
  2. optimizer = AdamW(model.parameters(), lr=5e-5): 모델의 파라미터를 가져와서 이를 AdamW 옵티마이저에 전달합니다. lr=5e-5는 학습률(learning rate)을 나타내며, 이 값은 학습 과정에서 가중치를 업데이트하는 정도를 조절합니다.

AdamW는 Adam 옵티마이저에 가중치 감쇠(weight decay)를 추가한 버전입니다. 가중치 감쇠는 모델의 가중치가 너무 커지지 않도록 제한하고, 오버피팅을 방지하는 데 도움을 줍니다.

이렇게 설정된 옵티마이저는 모델의 가중치를 업데이트할 때 사용되며, 이후에 이 옵티마이저를 통해 모델을 최적화하는 학습 과정을 진행할 수 있습니다.

 

Finally, the learning rate scheduler used by default is just a linear decay from the maximum value (5e-5) to 0. To properly define it, we need to know the number of training steps we will take, which is the number of epochs we want to run multiplied by the number of training batches (which is the length of our training dataloader). The Trainer uses three epochs by default, so we will follow that:

 

마지막으로, 기본적으로 사용되는 학습률 스케줄러는 최대값(5e-5)에서 0까지의 선형 감쇠일 뿐입니다. 이를 올바르게 정의하려면 수행할 학습 단계 수, 즉 에포크 수를 알아야 합니다. 훈련 배치 수(훈련 데이터로더의 길이)를 곱하여 실행하려고 합니다. Trainer는 기본적으로 세 가지 에포크를 사용하므로 다음을 따릅니다.

 

from transformers import get_scheduler

# 학습 에폭 수와 전체 학습 단계 수 설정
num_epochs = 3
num_training_steps = num_epochs * len(train_dataloader)

# 선형 학습률 스케줄러 설정
lr_scheduler = get_scheduler(
    "linear",
    optimizer=optimizer,
    num_warmup_steps=0,
    num_training_steps=num_training_steps,
)

# 전체 학습 단계 수 출력
print(num_training_steps)
1377

 

 

이 코드는 Hugging Face Transformers 라이브러리에서 제공하는 학습률 스케줄러를 설정하는 부분입니다. 코드를 단계별로 설명하겠습니다.

 

해석:

  1. from transformers import get_scheduler: Hugging Face Transformers 라이브러리에서 학습률 스케줄러를 가져옵니다.
  2. num_epochs = 3 및 num_training_steps = num_epochs * len(train_dataloader): 전체 학습 에폭 수와 전체 학습 단계 수를 설정합니다. 이 값들은 학습률 스케줄러 설정에 사용됩니다.
  3. lr_scheduler = get_scheduler("linear", optimizer=optimizer, num_warmup_steps=0, num_training_steps=num_training_steps): 선형 학습률 스케줄러를 설정합니다. "linear"는 선형 스케줄러를 의미하며, 학습률이 선형으로 감소하도록 만듭니다. num_warmup_steps=0은 워머핑 단계 수를 0으로 설정하며, num_training_steps는 총 학습 단계 수입니다.
  4. print(num_training_steps): 전체 학습 단계 수를 출력합니다.

이렇게 설정된 선형 학습률 스케줄러는 학습률을 일정한 비율로 감소시키면서 학습을 진행합니다. 설정된 값들은 Trainer 클래스에서 사용되는 기본값을 따르도록 설정되어 있습니다.

 

 

The training loop

 

One last thing: we will want to use the GPU if we have access to one (on a CPU, training might take several hours instead of a couple of minutes). To do this, we define a device we will put our model and our batches on:

 

마지막으로, GPU에 액세스할 수 있는 경우 GPU를 사용하고 싶을 것입니다(CPU에서는 훈련에 몇 분이 아닌 몇 시간이 걸릴 수 있습니다). 이를 위해 모델과 배치를 배치할 장치를 정의합니다.

 

import torch

# CUDA가 사용 가능한 경우 GPU를, 그렇지 않은 경우 CPU를 선택
device = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu")

# 모델을 선택한 디바이스로 이동
model.to(device)

# 선택한 디바이스 출력
device
device(type='cuda')

 

이 코드는 PyTorch를 사용하여 모델을 GPU 또는 CPU로 이동하는 부분입니다. 코드를 단계별로 설명하겠습니다.

 

해석:

  1. import torch: PyTorch 라이브러리를 가져옵니다.
  2. device = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu"): GPU(CUDA)가 사용 가능한 경우 GPU를 선택하고, 그렇지 않은 경우 CPU를 선택합니다. 이를 위해 torch.cuda.is_available() 함수를 사용하여 GPU 사용 가능 여부를 확인합니다.
  3. model.to(device): 모델을 선택한 디바이스로 이동시킵니다. 이로써 모델의 연산이 선택한 디바이스에서 수행되게 됩니다.
  4. device: 선택한 디바이스를 출력합니다. 이는 모델이 현재 어떤 디바이스에서 실행되고 있는지 확인할 수 있습니다.

이 코드는 모델을 GPU로 이동시키는데 사용되며, GPU가 없거나 사용이 불가능한 경우 CPU에서 모델을 실행하게 됩니다. GPU를 사용하면 모델의 연산이 병렬로 처리되어 훨씬 빠른 학습이 가능합니다.

 

 

CoLab에서는 GPU 사용은 안되고 CPU 를 사용해야 합니다.

 

We are now ready to train! To get some sense of when training will be finished, we add a progress bar over our number of training steps, using the tqdm library:

 

이제 훈련할 준비가 되었습니다! 훈련이 언제 완료되는지 알아보기 위해 tqdm 라이브러리를 사용하여 훈련 단계 수에 진행률 표시줄을 추가합니다.

 

from tqdm.auto import tqdm

# 훈련 단계 수만큼의 프로그레스 바 생성
progress_bar = tqdm(range(num_training_steps))

# 모델을 훈련 모드로 설정
model.train()

# 에폭 수만큼 반복
for epoch in range(num_epochs):
    # 훈련 데이터로더에서 미니배치를 가져와 반복
    for batch in train_dataloader:
        # 미니배치의 각 요소를 선택한 디바이스로 이동
        batch = {k: v.to(device) for k, v in batch.items()}
        
        # 모델에 미니배치를 전달하여 출력을 얻음
        outputs = model(**batch)
        
        # 손실 값을 얻음
        loss = outputs.loss
        
        # 역전파 수행
        loss.backward()
        
        # 옵티마이저로 모델 파라미터 업데이트
        optimizer.step()
        
        # 학습률 스케줄러를 업데이트
        lr_scheduler.step()
        
        # 기울기를 초기화하여 다음 미니배치에 대한 역전파를 위해 준비
        optimizer.zero_grad()
        
        # 프로그레스 바 업데이트
        progress_bar.update(1)

 

이 코드는 모델을 훈련하기 위한 학습 루프를 나타냅니다. 코드를 단계별로 설명하겠습니다.

 

해석:

  1. from tqdm.auto import tqdm: 훈련 과정에서 진행 상황을 시각적으로 확인하기 위해 tqdm 라이브러리에서 프로그레스 바를 사용합니다.
  2. progress_bar = tqdm(range(num_training_steps)): 전체 훈련 단계 수에 대한 프로그레스 바를 생성합니다.
  3. model.train(): 모델을 훈련 모드로 설정합니다. 이는 드롭아웃과 배치 정규화와 같은 학습 관련 기능을 활성화합니다.
  4. for epoch in range(num_epochs):: 지정된 에폭 수만큼 반복합니다.
  5. for batch in train_dataloader:: 훈련 데이터로더에서 미니배치를 가져와서 반복합니다.
  6. batch = {k: v.to(device) for k, v in batch.items()}: 미니배치의 각 요소를 선택한 디바이스로 이동시킵니다.
  7. outputs = model(**batch): 모델에 미니배치를 전달하여 모델의 출력을 얻습니다.
  8. loss = outputs.loss: 모델의 출력에서 손실 값을 얻습니다.
  9. loss.backward(): 역전파를 통해 기울기를 계산합니다.
  10. optimizer.step(): 옵티마이저를 사용하여 모델 파라미터를 업데이트합니다.
  11. lr_scheduler.step(): 학습률 스케줄러를 업데이트합니다.
  12. optimizer.zero_grad(): 모델 파라미터의 기울기를 초기화하여 다음 미니배치에 대한 역전파를 위해 준비합니다.
  13. progress_bar.update(1): 프로그레스 바를 업데이트하여 진행 상황을 시각적으로 확인합니다.

이렇게 훈련 루프를 통해 모델은 주어진 에폭 수에 대해 훈련되고, 손실이 감소하도록 파라미터가 업데이트됩니다.

 

You can see that the core of the training loop looks a lot like the one in the introduction. We didn’t ask for any reporting, so this training loop will not tell us anything about how the model fares. We need to add an evaluation loop for that.

 

훈련 루프의 핵심이 소개 부분과 매우 유사하다는 것을 알 수 있습니다. 우리는 보고를 요청하지 않았으므로 이 훈련 루프는 모델이 어떻게 진행되는지에 대해 아무 것도 알려주지 않습니다. 이를 위해 평가 루프를 추가해야 합니다.

 

The evaluation loop

 

As we did earlier, we will use a metric provided by the 🤗 Evaluate library. We’ve already seen the metric.compute() method, but metrics can actually accumulate batches for us as we go over the prediction loop with the method add_batch(). Once we have accumulated all the batches, we can get the final result with metric.compute(). Here’s how to implement all of this in an evaluation loop:

 

이전과 마찬가지로 🤗 Evaluate library 에서 제공하는 측정항목을 사용하겠습니다. 우리는 이미 metric.compute() 메소드를 보았지만 add_batch() 메소드를 사용하여 예측 루프를 진행하면서 메트릭은 실제로 배치를 누적할 수 있습니다. 모든 배치를 누적한 후에는 metric.compute()를 사용하여 최종 결과를 얻을 수 있습니다. 평가 루프에서 이 모든 것을 구현하는 방법은 다음과 같습니다.

 

import evaluate

# GLUE 메트릭을 로드
metric = evaluate.load("glue", "mrpc")

# 모델을 평가 모드로 설정
model.eval()

# 검증 데이터로더에서 미니배치를 가져와 반복
for batch in eval_dataloader:
    # 미니배치의 각 요소를 선택한 디바이스로 이동
    batch = {k: v.to(device) for k, v in batch.items()}

    # 기울기를 계산하지 않도록 설정하여 평가 수행
    with torch.no_grad():
        outputs = model(**batch)

    # 모델의 출력에서 로짓(확률 분포)을 얻음
    logits = outputs.logits

    # 로짓에서 예측 클래스를 결정
    predictions = torch.argmax(logits, dim=-1)

    # 메트릭에 현재 미니배치의 예측값과 레이블을 추가
    metric.add_batch(predictions=predictions, references=batch["labels"])

# 메트릭을 통해 최종 평가 수행
metric.compute()
{'accuracy': 0.8431372549019608, 'f1': 0.8907849829351535}

이 코드는 모델을 사용하여 검증 데이터셋에 대한 평가를 수행하는 부분입니다. 코드를 단계별로 설명하겠습니다.

 

해석:

  1. import evaluate: 평가 관련 함수들이 정의된 evaluate 모듈을 가져옵니다.
  2. metric = evaluate.load("glue", "mrpc"): GLUE 벤치마크의 MRPC(Microsoft Research Paraphrase Corpus)에 대한 메트릭을 로드합니다.
  3. model.eval(): 모델을 평가 모드로 설정합니다. 이는 드롭아웃과 배치 정규화와 같은 학습 관련 기능을 비활성화합니다.
  4. for batch in eval_dataloader:: 검증 데이터로더에서 미니배치를 가져와 반복합니다.
  5. batch = {k: v.to(device) for k, v in batch.items()}: 미니배치의 각 요소를 선택한 디바이스로 이동시킵니다.
  6. with torch.no_grad():: 기울기를 계산하지 않도록 설정하여 평가 수행을 위해 모델을 실행합니다.
  7. outputs = model(**batch): 모델에 미니배치를 전달하여 모델의 출력을 얻습니다.
  8. logits = outputs.logits: 모델의 출력에서 로짓(확률 분포)을 얻습니다.
  9. predictions = torch.argmax(logits, dim=-1): 로짓에서 예측 클래스를 결정합니다.
  10. metric.add_batch(predictions=predictions, references=batch["labels"]): 메트릭에 현재 미니배치의 예측값과 레이블을 추가합니다.
  11. metric.compute(): 메트릭을 통해 최종 평가를 수행합니다.

이를 통해 모델이 검증 데이터에 대해 얼마나 좋은 성능을 보이는지를 측정하고, GLUE 벤치마크에서 정의된 평가 메트릭을 계산합니다.

 

Again, your results will be slightly different because of the randomness in the model head initialization and the data shuffling, but they should be in the same ballpark.

 

다시 말하지만, 모델 헤드 초기화 및 데이터 셔플링의 무작위성으로 인해 결과가 약간 다르지만 동일한 기준점에 있어야 합니다.

 

✏️ Try it out! Modify the previous training loop to fine-tune your model on the SST-2 dataset.

 

✏️ 한번 사용해 보세요! 이전 훈련 루프를 수정하여 SST-2 데이터세트에서 모델을 미세 조정하세요.

 

 

Supercharge your training loop with 🤗 Accelerate

https://youtu.be/s7dy8QRgjJ0?si=tR63TKSpr0Wj3Ebn

 

 

 

TPU(Tensor Processing Unit)는 구글에서 개발한 특수한 하드웨어로, 딥러닝 작업을 가속화하기 위해 설계되었습니다. TPU는 주로 텐서플로우(TensorFlow) 딥러닝 프레임워크와 함께 사용되며, 딥러닝 모델의 학습과 추론 속도를 높이는 데 중점을 둡니다.

 

TPU의 주요 특징은 다음과 같습니다:

  1. 고성능 병렬 처리: TPU는 텐서 연산에 특화된 구조로 구성되어 있어, 행렬 곱셈 및 기타 텐서 연산을 효율적으로 수행할 수 있습니다. 이는 딥러닝 모델의 대규모 연산에 적합합니다.
  2. 낮은 전력 소모: TPU는 높은 성능에도 불구하고 상대적으로 낮은 전력을 소비합니다. 이는 에너지 효율성 면에서 우수한 성능을 제공합니다.
  3. TensorFlow와의 통합: TPU는 주로 텐서플로우와 함께 사용되며, 텐서플로우에서 제공하는 TPU 지원 기능을 활용하여 모델을 효율적으로 실행할 수 있습니다.
  4. 대규모 딥러닝 모델 지원: TPU는 대규모 딥러닝 모델의 학습에 적합하며, 대규모 데이터셋에서의 훈련 작업에 특히 유용합니다.

TPU는 클라우드 기반의 딥러닝 작업에 많이 사용되며, 구글 클라우드(Google Cloud)와 같은 클라우드 서비스 제공업체에서 TPU를 사용할 수 있는 환경을 제공하고 있습니다. TPU는 GPU와 비교하여 특정 딥러닝 워크로드에서 높은 성능을 발휘할 수 있으며, 딥러닝 연구 및 응용 분야에서 중요한 역할을 하고 있습니다.

 
 

The training loop we defined earlier works fine on a single CPU or GPU. But using the 🤗 Accelerate library, with just a few adjustments we can enable distributed training on multiple GPUs or TPUs. Starting from the creation of the training and validation dataloaders, here is what our manual training loop looks like:

이전에 정의한 훈련 루프는 단일 CPU 또는 GPU에서 잘 작동합니다. 하지만 🤗 Accelerate 라이브러리를 사용하면 몇 가지 조정만으로 여러 GPU 또는 TPU에서 분산 교육을 활성화할 수 있습니다. 교육 및 검증 데이터로더 생성부터 시작하여 수동 교육 루프는 다음과 같습니다.
 
 
from transformers import AdamW, AutoModelForSequenceClassification, get_scheduler

# 사전 훈련된 모델과 함께 시퀀스 분류 모델을 불러옴
model = AutoModelForSequenceClassification.from_pretrained(checkpoint, num_labels=2)

# AdamW 옵티마이저를 정의하고 모델의 파라미터를 전달
optimizer = AdamW(model.parameters(), lr=3e-5)

# 사용 가능한 GPU가 있다면 GPU로 모델을 이동
device = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu")
model.to(device)

# 훈련 설정: 에폭 수 및 훈련 스텝 수 설정
num_epochs = 3
num_training_steps = num_epochs * len(train_dataloader)

# 러닝 레이트 스케줄러 설정
lr_scheduler = get_scheduler(
    "linear",
    optimizer=optimizer,
    num_warmup_steps=0,
    num_training_steps=num_training_steps,
)

# tqdm을 사용하여 훈련 진행 상황을 시각적으로 표시
progress_bar = tqdm(range(num_training_steps))

# 모델을 훈련 모드로 설정
model.train()

# 에폭 수 만큼 반복
for epoch in range(num_epochs):
    # 훈련 데이터로더에서 미니배치를 가져와 반복
    for batch in train_dataloader:
        # 미니배치의 각 요소를 선택한 디바이스로 이동
        batch = {k: v.to(device) for k, v in batch.items()}

        # 모델에 미니배치를 전달하여 출력을 얻음
        outputs = model(**batch)

        # 손실을 얻고 역전파
        loss = outputs.loss
        loss.backward()

        # 옵티마이저를 사용하여 모델 파라미터 업데이트
        optimizer.step()

        # 러닝 레이트 스케줄러를 사용하여 러닝 레이트 조절
        lr_scheduler.step()

        # 기울기 초기화
        optimizer.zero_grad()

        # tqdm 업데이트
        progress_bar.update(1)

 

이 코드는 딥러닝 모델의 훈련을 위한 기본적인 스크립트를 나타냅니다. 코드를 단계별로 설명하겠습니다.

 

해석:

  1. 모델, 옵티마이저, 디바이스 설정: 사전 훈련된 모델을 불러오고, AdamW 옵티마이저를 정의하며, 사용 가능한 GPU가 있다면 GPU로 모델을 이동시킵니다.
  2. 훈련 설정: 에폭 수 및 훈련 스텝 수 설정합니다.
  3. 러닝 레이트 스케줄러 설정: 러닝 레이트 스케줄러를 설정하여 훈련 동안 러닝 레이트를 동적으로 조절합니다.
  4. tqdm을 사용한 진행 표시: tqdm은 훈련 진행 상황을 시각적으로 표시하는 도구입니다.
  5. 모델 훈련: 훈련 데이터로더에서 미니배치를 가져와 모델에 전달하고, 손실을 계산하여 역전파를 수행하며, 옵티마이저를 사용하여 모델 파라미터를 업데이트합니다. 러닝 레이트 스케줄러를 사용하여 러닝 레이트를 조절하고, tqdm을 업데이트하여 훈련 진행 상황을 표시합니다.

이러한 훈련 스크립트는 특정 모델과 데이터에 맞게 조정될 수 있으며, 주로 Hugging Face의 Transformers 라이브러리를 사용하여 딥러닝 모델을 훈련하는 일반적인 흐름을 나타냅니다.

 

And here are the changes:  변경 사항은 다음과 같습니다.

 

from accelerate import Accelerator
from transformers import AdamW, AutoModelForSequenceClassification, get_scheduler

# Accelerator 객체 생성
accelerator = Accelerator()

# AutoModelForSequenceClassification 모델 및 AdamW 옵티마이저 초기화
model = AutoModelForSequenceClassification.from_pretrained(checkpoint, num_labels=2)
optimizer = AdamW(model.parameters(), lr=3e-5)

# 훈련 및 검증 데이터로더, 모델, 옵티마이저를 Accelerator로 준비
train_dataloader, eval_dataloader, model, optimizer = accelerator.prepare(
    train_dataloader, eval_dataloader, model, optimizer
)

# 나머지 코드는 동일하게 유지됨
num_epochs = 3
num_training_steps = num_epochs * len(train_dataloader)
lr_scheduler = get_scheduler(
    "linear",
    optimizer=optimizer,
    num_warmup_steps=0,
    num_training_steps=num_training_steps
)

progress_bar = tqdm(range(num_training_steps))

model.train()
for epoch in range(num_epochs):
    for batch in train_dataloader:
        # batch = {k: v.to(device) for k, v in batch.items()}  # 이 부분 삭제
        outputs = model(**batch)
        loss = outputs.loss
        # loss.backward()  # 이 부분 변경
        accelerator.backward(loss)

        optimizer.step()
        lr_scheduler.step()
        optimizer.zero_grad()
        progress_bar.update(1)

 

이 코드는 accelerate 라이브러리를 사용하여 GPU 가속을 적용한 딥러닝 모델의 훈련 스크립트를 나타냅니다. 코드의 변경점에 대해 설명하겠습니다.

 

변경된 부분:

  1. Accelerator 사용: Accelerator 객체를 생성하고, prepare 메서드를 사용하여 훈련 데이터로더, 검증 데이터로더, 모델, 옵티마이저를 가속화합니다.
  2. Device 설정 제거: GPU 디바이스 설정 부분이 삭제되었습니다. Accelerator가 내부적으로 디바이스 관리를 수행합니다.
  3. Gradient 계산 변경: loss.backward() 대신 accelerator.backward(loss)를 사용하여 gradient 계산을 가속화합니다. Accelerator는 내부적으로 gradient 계산 및 관리를 처리합니다.

이러한 변경으로 코드는 GPU 가속을 사용하면서도 간소화되었고, 가속화 라이브러리를 통해 더욱 효율적으로 딥러닝 모델을 훈련할 수 있습니다.

 

The first line to add is the import line. The second line instantiates an Accelerator object that will look at the environment and initialize the proper distributed setup. 🤗 Accelerate handles the device placement for you, so you can remove the lines that put the model on the device (or, if you prefer, change them to use accelerator.device instead of device).

 

추가할 첫 번째 줄은 import 줄입니다. 두 번째 줄은 환경을 살펴보고 적절한 분산 설정을 초기화하는 Accelerator 개체를 인스턴스화합니다. 🤗 Accelerate가 장치 배치를 자동으로 처리하므로 장치에 모델을 배치하는 줄을 제거할 수 있습니다(또는 원하는 경우 장치 대신 accelerator.device를 사용하도록 변경).

 

Then the main bulk of the work is done in the line that sends the dataloaders, the model, and the optimizer to accelerator.prepare(). This will wrap those objects in the proper container to make sure your distributed training works as intended. The remaining changes to make are removing the line that puts the batch on the device (again, if you want to keep this you can just change it to use accelerator.device) and replacing loss.backward() with accelerator.backward(loss).

 

그런 다음 데이터로더, 모델 및 최적화 프로그램을 accelerator.prepare()로 보내는 라인에서 주요 작업이 수행됩니다. 이렇게 하면 분산 교육이 의도한 대로 작동하는지 확인하기 위해 해당 개체를 적절한 컨테이너에 래핑합니다. 나머지 변경 사항은 장치에 배치를 배치하는 줄을 제거하고(다시 말하지만 이를 유지하려면 accelerator.device를 사용하도록 변경하면 됩니다) loss.backward()를 accelerator.backward(loss)로 바꾸는 것입니다. .

 

⚠️ In order to benefit from the speed-up offered by Cloud TPUs, we recommend padding your samples to a fixed length with the `padding="max_length"` and `max_length` arguments of the tokenizer.
 
⚠️ Cloud TPU가 제공하는 속도 향상의 이점을 활용하려면 토크나이저의 `padding="max_length"` 및 `max_length` 인수를 사용하여 샘플을 고정 길이로 패딩하는 것이 좋습니다.
 

If you’d like to copy and paste it to play around, here’s what the complete training loop looks like with 🤗 Accelerate:

 

복사하여 붙여넣고 놀고 싶다면 🤗 Accelerate를 사용한 전체 훈련 루프는 다음과 같습니다.

 

from accelerate import Accelerator
from transformers import AdamW, AutoModelForSequenceClassification, get_scheduler

# Accelerator 객체 생성
accelerator = Accelerator()

# AutoModelForSequenceClassification 모델 및 AdamW 옵티마이저 초기화
model = AutoModelForSequenceClassification.from_pretrained(checkpoint, num_labels=2)
optimizer = AdamW(model.parameters(), lr=3e-5)

# 훈련 및 검증 데이터로더, 모델, 옵티마이저를 Accelerator로 준비
train_dl, eval_dl, model, optimizer = accelerator.prepare(
    train_dataloader, eval_dataloader, model, optimizer
)

# 훈련 설정: 에폭 수 및 훈련 스텝 수 설정
num_epochs = 3
num_training_steps = num_epochs * len(train_dl)

# 러닝 레이트 스케줄러 설정
lr_scheduler = get_scheduler(
    "linear",
    optimizer=optimizer,
    num_warmup_steps=0,
    num_training_steps=num_training_steps,
)

# tqdm을 사용하여 훈련 진행 상황을 시각적으로 표시
progress_bar = tqdm(range(num_training_steps))

# 모델을 훈련 모드로 설정
model.train()

# 에폭 수 만큼 반복
for epoch in range(num_epochs):
    # 훈련 데이터로더에서 미니배치를 가져와 반복
    for batch in train_dl:
        # 모델에 미니배치를 전달하여 출력을 얻음
        outputs = model(**batch)
        # 손실을 얻고 역전파
        loss = outputs.loss
        accelerator.backward(loss)

        # 옵티마이저를 사용하여 모델 파라미터 업데이트
        optimizer.step()
        # 러닝 레이트 스케줄러를 사용하여 러닝 레이트 조절
        lr_scheduler.step()
        # 기울기 초기화
        optimizer.zero_grad()
        # tqdm 업데이트
        progress_bar.update(1)

 

이 코드는 accelerate 라이브러리를 사용하여 GPU 가속을 적용한 딥러닝 모델의 훈련 스크립트를 나타냅니다. 

 

변경된 부분:

  1. Accelerator 사용: Accelerator 객체를 생성하고, prepare 메서드를 사용하여 훈련 데이터로더, 검증 데이터로더, 모델, 옵티마이저를 가속화합니다.
  2. 변수 명칭 변경: train_dl 및 eval_dl로 변수명을 변경하여 가속화된 데이터로더를 사용합니다.

나머지 코드는 이전과 동일하게 유지되며, 가속화 라이브러리를 사용하여 GPU 가속을 적용한 효율적인 딥러닝 모델 훈련을 수행합니다.

 

Putting this in a train.py script will make that script runnable on any kind of distributed setup. To try it out in your distributed setup, run the command:

 

이것을 train.py 스크립트에 넣으면 모든 종류의 분산 설정에서 해당 스크립트를 실행할 수 있습니다. 분산 설정에서 사용해 보려면 다음 명령을 실행하세요.

 

accelerate config

 

accelerate config 명령어는 accelerate 라이브러리의 환경 설정을 확인하는 명령어입니다. 이 명령어를 사용하면 현재 가속화 환경에 대한 설정 정보를 확인할 수 있습니다. 아래는 해당 명령어에 대한 설명입니다.

 

위 명령어를 실행하면, 현재 사용 중인 환경에 대한 다양한 설정이 출력됩니다. 주로 다음과 같은 정보를 확인할 수 있습니다.

  1. accelerator 설정: 현재 사용 중인 가속화 기술, 예를 들어, cuda 또는 tpu 등이 표시됩니다.
  2. num_processes 및 num_gpus 설정: 병렬 처리에 사용되는 프로세스 수와 GPU 수가 표시됩니다.
  3. fp16 설정: 16-bit 부동 소수점 사용 여부에 대한 설정이 표시됩니다.
  4. fp16_backend 설정: 16-bit 부동 소수점 연산을 처리하는 백엔드(예: apex 또는 amp)가 표시됩니다.
  5. ddp 설정: 분산 데이터 병렬 설정이 표시됩니다.

이 명령어를 사용하면 가속화 환경에 대한 자세한 설정을 확인할 수 있어, 딥러닝 모델을 효율적으로 훈련하기 위해 가속화 라이브러리를 조정하는 데 도움이 됩니다.

 

 

which will prompt you to answer a few questions and dump your answers in a configuration file used by this command:

 

그러면 몇 가지 질문에 대답하고 이 명령에서 사용하는 구성 파일에 답변을 덤프하라는 메시지가 표시됩니다.

 

accelerate launch train.py

 

accelerate launch train.py 명령어는 accelerate 라이브러리를 사용하여 딥러닝 모델을 훈련하는 스크립트인 train.py를 실행하는 명령어입니다. 이 명령어를 사용하면 가속화 환경에서 훈련을 수행할 수 있습니다. 아래는 해당 명령어에 대한 설명입니다.

 

해당 명령어를 실행하면, train.py 스크립트가 가속화 라이브러리의 환경 설정에 맞게 실행됩니다. 이때, 여러 GPU 또는 TPU 등을 활용하여 훈련을 가속화할 수 있습니다.

 

이 명령어를 사용하는 주요 이점은:

  1. 분산 훈련 지원: accelerate는 분산 훈련을 지원하며, 여러 GPU 또는 TPU에서 모델을 효율적으로 훈련할 수 있도록 도와줍니다.
  2. Mixed Precision 훈련: 16-bit 부동 소수점 연산을 사용하여 모델의 훈련 속도를 향상시킵니다.
  3. 간편한 사용: accelerate를 사용하면 분산 훈련 및 가속화 설정에 대한 복잡한 부분을 자동으로 처리하여 간편하게 활용할 수 있습니다.

따라서, accelerate launch 명령어를 사용하면 train.py를 가속화된 환경에서 간편하게 실행할 수 있습니다.

 

 

which will launch the distributed training. 분산 교육이 시작됩니다.

 

If you want to try this in a Notebook (for instance, to test it with TPUs on Colab), just paste the code in a training_function() and run a last cell with:

 

노트북에서 이 작업을 시도하려면(예: Colab의 TPU로 테스트) training_function()에 코드를 붙여넣고 다음을 사용하여 마지막 셀을 실행하세요.

 

from accelerate import notebook_launcher

notebook_launcher(training_function)

 

from accelerate import notebook_launcher와 notebook_launcher(training_function) 코드는 Jupyter Notebook 환경에서 accelerate 라이브러리를 사용하여 모델 훈련 함수(training_function)를 가속화하여 실행하는 코드입니다. 이 코드를 사용하면 Jupyter Notebook에서 간편하게 모델 훈련을 가속화할 수 있습니다.

해당 코드를 단계별로 설명하겠습니다:

 

notebook_launcher 임포트:

from accelerate import notebook_launcher

 

 

accelerate 라이브러리에서 notebook_launcher 모듈을 임포트합니다. 이 모듈은 Jupyter Notebook에서 가속화된 훈련을 지원합니다.

 

notebook_launcher 사용:

notebook_launcher(training_function)

 

  1. notebook_launcher 함수에 모델을 훈련시키는 함수(training_function)를 전달하여 사용합니다. 이 함수는 가속화된 환경에서 모델 훈련을 시작합니다. notebook_launcher는 분산 훈련 및 Mixed Precision 훈련을 처리하는 등 가속화에 필요한 설정을 자동으로 수행합니다.

이 코드를 사용하면 Jupyter Notebook에서 간편하게 training_function을 실행할 수 있으며, accelerate 라이브러리의 기능을 활용하여 가속화된 딥러닝 모델 훈련을 수행할 수 있습니다.

 

You can find more examples in the 🤗 Accelerate repo.

 

🤗 Accelerate 저장소에서 더 많은 예시를 찾아보실 수 있습니다.

 

반응형


반응형

https://huggingface.co/learn/nlp-course/chapter3/3?fw=pt

 

Fine-tuning a model with the Trainer API - Hugging Face NLP Course

🤗 Transformers provides a Trainer class to help you fine-tune any of the pretrained models it provides on your dataset. Once you’ve done all the data preprocessing work in the last section, you have just a few steps left to define the Trainer. The har

huggingface.co

 

Fine-tuning a model with the Trainer API

 

https://youtu.be/nvBXf7s7vTI?si=7V5gLAt293qhuK67

 

🤗 Transformers provides a Trainer class to help you fine-tune any of the pretrained models it provides on your dataset. Once you’ve done all the data preprocessing work in the last section, you have just a few steps left to define the Trainer. The hardest part is likely to be preparing the environment to run Trainer.train(), as it will run very slowly on a CPU. If you don’t have a GPU set up, you can get access to free GPUs or TPUs on Google Colab.

 

🤗 Transformers는 데이터세트에서 제공하는 사전 훈련된 모델을 미세 조정하는 데 도움이 되는 Trainer 클래스를 제공합니다. 마지막 섹션에서 모든 데이터 전처리 작업을 완료하고 나면 Trainer를 정의하기 위한 몇 단계만 남았습니다. 가장 어려운 부분은 Trainer.train()을 실행하기 위한 환경을 준비하는 것입니다. 왜냐하면 Trainer.train()은 CPU에서 매우 느리게 실행되기 때문입니다. GPU가 설정되어 있지 않은 경우 Google Colab에서 무료 GPU 또는 TPU에 액세스할 수 있습니다.

 

The code examples below assume you have already executed the examples in the previous section. Here is a short summary recapping what you need:

 

아래 코드 예제에서는 이전 섹션의 예제를 이미 실행했다고 가정합니다. 다음은 필요한 사항을 간략하게 요약한 것입니다.

 

from datasets import load_dataset
from transformers import AutoTokenizer, DataCollatorWithPadding

# MRPC 데이터셋 로드
raw_datasets = load_dataset("glue", "mrpc")

# BERT 모델의 체크포인트를 "bert-base-uncased"로 지정하여 토크나이저 초기화
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)

 

이 코드는 Hugging Face Transformers 라이브러리를 사용하여 MRPC(Microsoft Research Paraphrase Corpus) 데이터셋을 로드하고, BERT 모델의 토크나이저를 초기화하며, 토큰화 함수와 데이터 콜레이터를 정의하는 예제입니다. 코드를 단계별로 설명하겠습니다.

 

해석:

  1. load_dataset("glue", "mrpc"): Hugging Face의 datasets 라이브러리를 사용하여 MRPC 데이터셋을 로드합니다.
  2. AutoTokenizer.from_pretrained(checkpoint): BERT 모델의 체크포인트를 지정하여 해당 모델에 대한 토크나이저를 초기화합니다.
  3. def tokenize_function(example): MRPC 데이터셋의 각 예시에 대한 사용자 정의 토크나이즈 함수를 정의합니다. 이 함수는 "sentence1"과 "sentence2" 필드의 문장을 토큰화합니다.
  4. raw_datasets.map(tokenize_function, batched=True): map 함수를 사용하여 데이터셋의 각 예시에 대해 토크나이즈 함수를 적용하고, 배치(batch) 단위로 토큰화된 데이터셋을 생성합니다.
  5. DataCollatorWithPadding(tokenizer=tokenizer): 데이터 콜레이터를 초기화합니다. 이 데이터 콜레이터는 패딩을 적용하여 배치의 모든 입력 시퀀스를 동일한 길이로 만들어주는 역할을 합니다.

이렇게 초기화된 토크나이저, 토큰화 함수, 데이터 콜레이터는 이후 모델 훈련 또는 추론을 위해 사용될 수 있습니다.

 

 

Training

The first step before we can define our Trainer is to define a TrainingArguments class that will contain all the hyperparameters the Trainer will use for training and evaluation. The only argument you have to provide is a directory where the trained model will be saved, as well as the checkpoints along the way. For all the rest, you can leave the defaults, which should work pretty well for a basic fine-tuning.

 

Trainer를 정의하기 전 첫 번째 단계는 Trainer가 훈련 및 평가에 사용할 모든 하이퍼파라미터를 포함는 TrainingArguments 클래스를 정의하는 것입니다. 제공해야 하는 유일한 인수는 학습된 모델이 저장될 디렉터리와 그 과정에서 체크포인트입니다. 나머지 모든 사항에 대해서는 기본값을 그대로 두면 기본 미세 조정에 매우 적합합니다.

 

from transformers import TrainingArguments

training_args = TrainingArguments("test-trainer")

 

이 코드는 Hugging Face Transformers 라이브러리를 사용하여 모델 훈련에 필요한 훈련 인자(Training Arguments)를 설정하는 예제입니다. 코드를 단계별로 설명하겠습니다.

 

해석:

  1. TrainingArguments: Hugging Face Transformers 라이브러리에서 제공하는 모델 훈련을 위한 인자를 설정하는 클래스입니다.
  2. TrainingArguments("test-trainer"): 훈련 인자 객체를 초기화합니다. 여기서 "test-trainer"는 훈련의 이름(디렉토리 이름)을 나타냅니다.

이렇게 초기화된 training_args 객체에는 모델 훈련에 필요한 다양한 설정이 포함되어 있습니다. 훈련 스크립트에서 이 인자들을 참조하여 모델 훈련을 조절할 수 있습니다. 이 예제에서는 가장 기본적인 훈련 인자만 설정되었습니다. 나중에 필요에 따라 추가적인 설정을 적용할 수 있습니다.

 

CoLab에서는 아래와 같은 에러가 남

 

 

pip install transformers[torch] 를 한 후 CoLab을 Restart 한 후 다시 실행하면 됨
 

 

 

💡 If you want to automatically upload your model to the Hub during training, pass along push_to_hub=True in the TrainingArguments. We will learn more about this in Chapter 4

 

💡 훈련 중에 모델을 허브에 자동으로 업로드하려면 TrainingArguments에 push_to_hub=True를 전달하세요. 이에 대한 자세한 내용은 4장에서 알아보겠습니다.

 

The second step is to define our model. As in the previous chapter, we will use the AutoModelForSequenceClassification class, with two labels:

 

두 번째 단계는 모델을 정의하는 것입니다. 이전 장에서와 마찬가지로 두 개의 레이블이 있는 AutoModelForSequenceClassification 클래스를 사용합니다.

 

from transformers import AutoModelForSequenceClassification

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

 

이 코드는 Hugging Face Transformers 라이브러리를 사용하여 사전 훈련된 모델을 불러오거나 새로운 모델을 초기화하는 예제입니다. 코드를 단계별로 설명하겠습니다.

 

해석:

  1. AutoModelForSequenceClassification: Hugging Face Transformers 라이브러리에서 제공하는 시퀀스 분류(sequence classification) 모델을 초기화하는 클래스입니다.
  2. from_pretrained(checkpoint, num_labels=2): from_pretrained 메서드를 사용하여 사전 훈련된 모델을 불러오거나 새로운 모델을 초기화합니다. checkpoint는 모델의 체크포인트를 지정하고, num_labels=2는 모델의 출력 클래스의 개수를 나타냅니다. 이 경우에는 이진 분류를 수행하는 모델로서 출력 클래스가 2개인 경우입니다.

이 코드를 실행하면 model 변수에는 초기화된 모델이 저장되어 있습니다. 이 모델은 이진 분류를 수행할 수 있으며, 사전 훈련된 모델을 사용하여 특정 작업에 미세 조정(fine-tuning)을 할 수 있습니다.

 

 

You will notice that unlike in Chapter 2, you get a warning after instantiating this pretrained model. This is because BERT has not been pretrained on classifying pairs of sentences, so the head of the pretrained model has been discarded and a new head suitable for sequence classification has been added instead. The warnings indicate that some weights were not used (the ones corresponding to the dropped pretraining head) and that some others were randomly initialized (the ones for the new head). It concludes by encouraging you to train the model, which is exactly what we are going to do now.

 

2장과 달리 사전 훈련된 모델을 인스턴스화한 후 경고가 표시된다는 점을 알 수 있습니다. 이는 BERT가 문장 쌍을 분류하는 데 사전 학습되지 않았기 때문에 사전 학습된 모델의 헤드를 삭제하고 대신 시퀀스 분류에 적합한 새로운 헤드를 추가했기 때문입니다. 경고는 일부 가중치(삭제된 사전 훈련 헤드에 해당하는 가중치)가 사용되지 않았으며 일부 가중치(새 헤드에 대한 가중치)가 무작위로 초기화되었음을 나타냅니다. 우리가 지금 하려고 하는 것이 바로 모델 훈련을 권장하는 것으로 마무리됩니다.

 

Once we have our model, we can define a Trainer by passing it all the objects constructed up to now — the model, the training_args, the training and validation datasets, our data_collator, and our tokenizer:

 

모델이 있으면 지금까지 구성한 모든 개체(모델, training_args, 훈련 및 검증 데이터 세트, data_collator 및 토크나이저)를 전달하여 Trainer를 정의할 수 있습니다.

 

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

 

이 코드는 Hugging Face Transformers 라이브러리를 사용하여 모델을 훈련하기 위한 Trainer를 초기화하는 예제입니다. 코드를 단계별로 설명하겠습니다.

 

해석:

  1. Trainer: Hugging Face Transformers 라이브러리에서 제공하는 훈련을 관리하는 클래스입니다.
  2. model: 훈련에 사용될 모델 객체입니다.
  3. training_args: 앞서 설정한 모델 훈련 인자(Training Arguments) 객체입니다.
  4. train_dataset=tokenized_datasets["train"]: 훈련에 사용될 데이터셋을 지정합니다. 여기서는 토큰화된 훈련 데이터셋을 사용합니다.
  5. eval_dataset=tokenized_datasets["validation"]: 모델의 성능을 평가할 때 사용될 검증 데이터셋을 지정합니다.
  6. data_collator=data_collator: 데이터 콜레이터 객체를 지정합니다. 이 객체는 배치를 처리하여 패딩을 추가하고 동일한 길이로 만들어주는 역할을 합니다.
  7. tokenizer=tokenizer: 토크나이저 객체를 지정합니다. 이 토크나이저는 모델 입력을 토큰화하는 데 사용됩니다.

이렇게 초기화된 Trainer 객체를 사용하면 지정된 모델과 데이터셋으로 모델을 훈련하고 평가할 수 있습니다. Trainer 객체를 사용하여 모델 훈련에 관련된 다양한 작업을 수행할 수 있습니다.

 

Note that when you pass the tokenizer as we did here, the default data_collator used by the Trainer will be a DataCollatorWithPadding as defined previously, so you can skip the line data_collator=data_collator in this call. It was still important to show you this part of the processing in section 2!

 

여기에서 했던 것처럼 토크나이저를 전달하면 Trainer에서 사용하는 기본 data_collator는 이전에 정의한 대로 DataCollatorWithPadding이 되므로 이 호출에서 data_collator=data_collator 줄을 건너뛸 수 있습니다. 섹션 2에서 처리 중 이 부분을 보여주는 것이 여전히 중요했습니다!

 

To fine-tune the model on our dataset, we just have to call the train() method of our Trainer:

 

데이터 세트의 모델을 미세 조정하려면 Trainer의 train() 메서드를 호출하기만 하면 됩니다.

 

trainer.train()

 

이 코드는 Hugging Face Transformers 라이브러리의 Trainer 객체를 사용하여 모델을 훈련하는 메서드를 호출하는 예제입니다.

 

해석:

  • trainer: 앞서 초기화한 Trainer 객체입니다.
  • train(): Trainer 객체의 train 메서드를 호출합니다. 이 메서드는 모델을 실제로 훈련시키는 역할을 합니다. 메서드가 실행되면 지정된 횟수만큼 모델이 훈련되며, 각 에폭(epoch)마다 훈련 손실(training loss) 및 검증 손실(validation loss) 등의 정보가 출력됩니다.

이 코드를 실행하면 모델이 지정된 횟수만큼 데이터셋에 대해 훈련되며, 훈련 손실 및 검증 손실이 출력됩니다. Trainer 객체는 앞서 설정한 훈련 인자(Training Arguments)에 따라 훈련이 진행되며, 필요한 경우 추가적인 설정을 적용할 수 있습니다.

 

CoLab에서 train() 을 하면 두시간이 걸린다.

 

 

This will start the fine-tuning (which should take a couple of minutes on a GPU) and report the training loss every 500 steps. It won’t, however, tell you how well (or badly) your model is performing. This is because:

 

그러면 미세 조정(GPU에서는 몇 분 정도 소요)이 시작되고 500단계마다 훈련 손실이 보고됩니다. 그러나 모델의 성능이 얼마나 좋은지(또는 나쁜지) 알려주지는 않습니다. 그 이유는 아래와 같습니다.

 

  1. We didn’t tell the Trainer to evaluate during training by setting evaluation_strategy to either "steps" (evaluate every eval_steps) or "epoch" (evaluate at the end of each epoch).

    training_strategy를 "steps"(모든 eval_steps 평가) 또는 "epoch"(각 epoch 끝에서 평가)로 설정하여 훈련 중에 평가하도록 트레이너에게 지시하지 않았습니다.

  2. We didn’t provide the Trainer with a compute_metrics() function to calculate a metric during said evaluation (otherwise the evaluation would just have printed the loss, which is not a very intuitive number).

    우리는 평가 중에 메트릭을 계산하기 위해 Compute_metrics() 함수를 Trainer에 제공하지 않았습니다(그렇지 않으면 평가에서 매우 직관적인 숫자가 아닌 손실만 인쇄했을 것입니다).


Evaluation

 

Let’s see how we can build a useful compute_metrics() function and use it the next time we train. The function must take an EvalPrediction object (which is a named tuple with a predictions field and a label_ids field) and will return a dictionary mapping strings to floats (the strings being the names of the metrics returned, and the floats their values). To get some predictions from our model, we can use the Trainer.predict() command:

 

유용한 Compute_metrics() 함수를 어떻게 구축하고 다음 훈련에 사용할 수 있는지 살펴보겠습니다. 함수는 EvalPrediction 객체(예측 필드와 label_ids 필드가 있는 명명된 튜플)를 가져와야 하며 문자열을 부동 소수점(문자열은 반환된 측정항목의 이름이고 부동 소수점 값)에 매핑하는 사전을 반환합니다. 모델에서 몇 가지 예측을 얻으려면 Trainer.predict() 명령을 사용할 수 있습니다.

 

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

 

이 코드는 Hugging Face Transformers 라이브러리의 Trainer 객체를 사용하여 검증 데이터셋에 대한 예측을 수행하고, 그 결과를 출력하는 예제입니다.

 

해석:

  • trainer: 앞서 초기화한 Trainer 객체입니다.
  • predict(tokenized_datasets["validation"]): Trainer 객체의 predict 메서드를 호출하여 검증 데이터셋에 대한 예측을 수행합니다. tokenized_datasets["validation"]은 검증 데이터셋의 토큰화된 버전을 나타냅니다.
  • predictions.predictions.shape: 예측된 결과의 모양(shape)을 나타냅니다. 예측된 결과는 모델의 출력으로, 각 클래스에 대한 확률 값이 포함된 텐서입니다.
  • predictions.label_ids.shape: 실제 레이블(ground truth)의 모양(shape)을 나타냅니다. 이는 검증 데이터셋의 실제 클래스 레이블을 나타내는 텐서입니다.

결과로 출력되는 predictions.predictions.shape와 predictions.label_ids.shape은 각각 예측된 결과의 모양과 실제 레이블의 모양을 나타내므로, 모델의 성능 평가 및 분석에 활용할 수 있습니다. 이를 통해 모델이 얼마나 잘 예측했는지를 확인할 수 있습니다.

 

 

 

The output of the predict() method is another named tuple with three fields: predictions, label_ids, and metrics. The metrics field will just contain the loss on the dataset passed, as well as some time metrics (how long it took to predict, in total and on average). Once we complete our compute_metrics() function and pass it to the Trainer, that field will also contain the metrics returned by compute_metrics().

 

predict () 메서드의 출력은 predict , label_ids 및 메트릭이라는 세 가지 필드가 있는 또 다른 명명된 튜플입니다. 측정항목 필드에는 전달된 데이터 세트의 손실과 일부 시간 측정항목(전체 및 평균으로 예측하는 데 걸린 시간)만 포함됩니다. Compute_metrics() 함수를 완성하고 이를 Trainer에 전달하면 해당 필드에는 Compute_metrics()에서 반환된 측정항목도 포함됩니다.

 

As you can see, predictions is a two-dimensional array with shape 408 x 2 (408 being the number of elements in the dataset we used). Those are the logits for each element of the dataset we passed to predict() (as you saw in the previous chapter, all Transformer models return logits). To transform them into predictions that we can compare to our labels, we need to take the index with the maximum value on the second axis:

 

보시다시피 예측은 408 x 2 모양의 2차원 배열입니다(408은 우리가 사용한 데이터세트의 요소 수입니다). 이는 우리가 predict  ()에 전달한 데이터 세트의 각 요소에 대한 로짓입니다(이전 장에서 보았듯이 모든 Transformer 모델은 로짓을 반환합니다). 이를 레이블과 비교할 수 있는 predict  으로 변환하려면 두 번째 축에서 최대값을 갖는 인덱스를 가져와야 합니다.

 

import numpy as np

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

 

이 코드는 NumPy 라이브러리를 사용하여 모델의 예측 결과에서 각 샘플에 대한 최대값을 찾아 클래스를 선택하는 예제입니다.

 

해석:

  • predictions.predictions: 모델의 예측 결과로, 각 클래스에 대한 확률 값이 담긴 텐서입니다.
  • np.argmax(predictions.predictions, axis=-1): NumPy의 argmax 함수를 사용하여 각 샘플에 대해 가장 높은 확률 값을 가진 클래스의 인덱스를 찾습니다. axis=-1는 가장 안쪽(마지막) 차원을 기준으로 최댓값을 찾도록 지정합니다.

결과로 얻어지는 preds는 각 샘플에 대해 모델이 예측한 클래스의 인덱스를 담은 배열이 됩니다. 이를 통해 각 샘플에 대한 최종 예측 클래스를 확인할 수 있습니다. 예를 들어, 이 배열의 첫 번째 원소는 첫 번째 샘플의 예측 클래스를 나타냅니다.

 

 

We can now compare those preds to the labels. To build our compute_metric() function, we will rely on the metrics from the 🤗 Evaluate library. We can load the metrics associated with the MRPC dataset as easily as we loaded the dataset, this time with the evaluate.load() function. The object returned has a compute() method we can use to do the metric calculation:

 

이제 해당 pred를 레이블과 비교할 수 있습니다. Compute_metric() 함수를 빌드하기 위해 🤗 Evaluate 라이브러리의 메트릭을 사용합니다. 이번에는 estimate.load() 함수를 사용하여 데이터세트를 로드한 것처럼 쉽게 MRPC 데이터세트와 관련된 측정항목을 로드할 수 있습니다. 반환된 객체에는 측정항목 계산을 수행하는 데 사용할 수 있는 Compute() 메서드가 있습니다.

 

import evaluate

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

 

{'accuracy': 0.8578431372549019, 'f1': 0.8996539792387542}

 

이 코드는 Hugging Face의 evaluate 모듈을 사용하여 모델의 성능 지표를 계산하는 예제입니다. 코드를 단계별로 설명하겠습니다.

 

해석:

  1. import evaluate: Hugging Face에서 제공하는 evaluate 모듈을 가져옵니다.
  2. evaluate.load("glue", "mrpc"): "glue" 데이터셋의 "mrpc" 태스크에 해당하는 성능 지표 메트릭을 로드합니다. 이 메트릭은 해당 태스크에 대한 평가 지표를 계산하는 데 사용됩니다.
  3. metric.compute(predictions=preds, references=predictions.label_ids): compute 메서드를 사용하여 모델의 예측값 (preds)과 실제 레이블 (predictions.label_ids)을 입력으로 주어 성능 지표를 계산합니다. 이 메서드는 정확도(accuracy) 및 기타 태스크별 지표를 반환할 수 있습니다.

결과로 얻어지는 값은 해당 데이터셋 및 태스크에 대한 모델의 성능을 나타내며, 필요에 따라 이를 기반으로 모델을 평가하고 비교할 수 있습니다.

 
 
 

The exact results you get may vary, as the random initialization of the model head might change the metrics it achieved. Here, we can see our model has an accuracy of 85.78% on the validation set and an F1 score of 89.97. Those are the two metrics used to evaluate results on the MRPC dataset for the GLUE benchmark. The table in the BERT paper reported an F1 score of 88.9 for the base model. That was the uncased model while we are currently using the cased model, which explains the better result.

 

모델 헤드의 무작위 초기화로 인해 얻은 측정항목이 변경될 수 있으므로 얻을 수 있는 정확한 결과는 다를 수 있습니다. 여기서 우리 모델의 검증 세트 정확도는 85.78%이고 F1 점수는 89.97임을 알 수 있습니다. 이는 GLUE 벤치마크에 대한 MRPC 데이터 세트의 결과를 평가하는 데 사용되는 두 가지 측정항목입니다. BERT 논문의 표는 기본 모델의 F1 점수가 88.9라고 보고했습니다. 우리가 현재 케이스를 씌운 모델을 사용하고 있는 동안 그것은 케이스가 없는 모델이었습니다. 이것이 더 나은 결과를 설명합니다.

 

Wrapping everything together, we get our compute_metrics() function:

 
모든 것을 하나로 묶으면 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)
 
이 코드는 모델의 평가를 위해 사용되는 사용자 정의 메트릭을 계산하는 함수를 정의한 예제입니다. 코드를 단계별로 설명하겠습니다.
 
 

해석:

  1. compute_metrics 함수 정의: 사용자가 정의한 평가 메트릭을 계산하는 함수입니다.
  2. metric = evaluate.load("glue", "mrpc"): "glue" 데이터셋의 "mrpc" 태스크에 해당하는 성능 지표 메트릭을 로드합니다.
  3. logits, labels = eval_preds: eval_preds는 평가 중에 생성된 모델의 예측값(logits)과 실제 레이블(labels)을 포함하는 튜플입니다.
  4. predictions = np.argmax(logits, axis=-1): 모델의 예측값인 logits에서 각 샘플에 대한 최대값을 가진 클래스의 인덱스를 찾아 predictions 배열에 저장합니다.
  5. return metric.compute(predictions=predictions, references=labels): 로드한 메트릭을 사용하여 예측값과 실제 레이블을 입력으로 주어 성능 지표를 계산하고 반환합니다.

이렇게 정의된 compute_metrics 함수는 모델을 평가할 때 사용되며, 평가 결과에 대한 성능 지표를 반환합니다. 사용자는 필요에 따라 이 함수를 수정하여 다양한 성능 지표를 계산할 수 있습니다.

 

And to see it used in action to report metrics at the end of each epoch, here is how we define a new Trainer with this compute_metrics() function:

 

그리고 각 에포크가 끝날 때 지표를 보고하기 위해 실제로 사용되는 것을 확인하기 위해 이 Compute_metrics() 함수를 사용하여 새 Trainer를 정의하는 방법은 다음과 같습니다.

 

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

 

이 코드는 Hugging Face Transformers 라이브러리를 사용하여 모델 훈련을 설정하는 부분입니다. 코드를 단계별로 설명하겠습니다.

 

해석:

  1. TrainingArguments("test-trainer", evaluation_strategy="epoch"): 훈련 인자(Training Arguments) 객체를 초기화합니다. 여기서는 훈련의 이름(디렉토리 이름)을 "test-trainer"로 지정하고, evaluation_strategy="epoch"를 통해 검증을 에폭(epoch) 단위로 수행하도록 설정합니다.
  2. AutoModelForSequenceClassification.from_pretrained(checkpoint, num_labels=2): 사전 훈련된 모델을 불러오거나 새로운 모델을 초기화합니다. checkpoint는 모델의 체크포인트를 지정하고, num_labels=2는 모델의 출력 클래스의 개수를 나타냅니다. 이 경우에는 이진 분류를 수행하는 모델로서 출력 클래스가 2개인 경우입니다.
  3. 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: 사용자 정의 메트릭을 계산하는 함수를 지정합니다.

이렇게 초기화된 Trainer 객체를 사용하면 모델을 지정된 횟수만큼 데이터셋에 대해 훈련하고, 검증을 에폭 단위로 수행할 수 있습니다. 필요에 따라 추가적인 설정을 적용할 수 있습니다.

 

Note that we create a new TrainingArguments with its evaluation_strategy set to "epoch" and a new model — otherwise, we would just be continuing the training of the model we have already trained. To launch a new training run, we execute:

 

Evaluation_strategy가 "epoch"로 설정된 새로운 TrainingArguments와 새 모델을 생성합니다. 그렇지 않으면 이미 훈련한 모델의 훈련을 계속할 것입니다. 새로운 훈련 실행을 시작하기 위해 다음을 실행합니다.

 

trainer.train()

 

 

This time, it will report the validation loss and metrics at the end of each epoch on top of the training loss. Again, the exact accuracy/F1 score you reach might be a bit different from what we found, because of the random head initialization of the model, but it should be in the same ballpark.

 

이번에는 훈련 손실 외에 각 에포크가 끝날 때마다 검증 손실과 측정항목을 보고합니다. 다시 말하지만, 도달한 정확한 정확도/F1 점수는 모델의 무작위 헤드 초기화로 인해 우리가 찾은 것과 약간 다를 수 있지만 동일한 기준점에 있어야 합니다.

 

The Trainer will work out of the box on multiple GPUs or TPUs and provides lots of options, like mixed-precision training (use fp16 = True in your training arguments). We will go over everything it supports in Chapter 10.

 

Trainer는 여러 GPU 또는 TPU에서 즉시 작동하며 혼합 정밀도 교육과 같은 다양한 옵션을 제공합니다(교육 인수에서 fp16 = True 사용). 10장에서 지원되는 모든 내용을 살펴보겠습니다.

 

This concludes the introduction to fine-tuning using the Trainer API. An example of doing this for most common NLP tasks will be given in Chapter 7, but for now let’s look at how to do the same thing in pure PyTorch.

 

이것으로 Trainer API를 사용한 미세 조정에 대한 소개를 마칩니다. 가장 일반적인 NLP 작업에 대해 이 작업을 수행하는 예는 7장에서 제공되지만 지금은 순수한 PyTorch에서 동일한 작업을 수행하는 방법을 살펴보겠습니다.

 

✏️ Try it out! Fine-tune a model on the GLUE SST-2 dataset, using the data processing you did in section 2.

 

✏️ 한번 사용해 보세요! 섹션 2에서 수행한 데이터 처리를 사용하여 GLUE SST-2 데이터 세트에서 모델을 미세 조정합니다.

 

Summary

 

지난 단원에서는 데이터를 로드하고 미세조정 하기 위해 텍스트 데이터를 토큰화하고 정수화 하고 길이 등을 맞춰 training을 준비 했다면 이번 단원에서는 그 준비된 데이터로 실제 training을 진행하는 과정을 설명 함.

 

Training을 하기 위해서는 Huggingface의 Trainer class를 사용한다.

처음으로 TrainingArguments를 사용해 Arguments를 세팅하고 Trainer를 사용해 지금까지 준비한 모든 것을 Model에 전달하기 위한 정의를 마친다.

그 다음 train() 메소드를 실행하면 실제로 training이 이루어 진다.

training이 끝나면 validation 데이터로 predict을 한다. predict()

그리고 이 predict 한 내용을 evaluate 한다.

 

이것이 전체 training 과정 임.

 

참고로 training() 은 시간이 오래 걸리는데 이 때 더 자세한 정보가 나오도록 하기 위해 compute_metrics() 함수를 만들어 Trainer() 에 추가 했음. (compute() 메소드를 사용해서 추가 정보가 나오도록 했음)

 

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

 

 

 

 

반응형