본문 바로가기
  • 머킹이의 머신로그
AI/코드 실습하기

Transformer 모델 학습 중 발생하는 --load_best_model_at_end 에러: 원인과 해결 방법

by 머킹 2024. 8. 20.
728x90

1. Transformer 모델 학습 중 발생하는 --load_best_model_at_end 에러: 원인과 해결 방법

2. "element 0 of tensors does not require grad and does not have a grad_fn" 에러 해결 방법 

 

Transformer 모델을 학습할 때, 모델의 성능을 모니터링하고, 최적의 모델을 저장하는 것은 매우 중요한 과정입니다.

이를 위해 Hugging Face의 transformers 라이브러리는 --load_best_model_at_end 옵션을 제공합니다.

 

그러나 이 옵션을 사용할 때, ValueError: --load_best_model_at_end requires the saving steps to be a round multiple of the evaluation steps라는 에러가 발생할 수 있습니다.

이번 글에서는 이 에러가 발생하는 원인과 이를 해결하는 방법에 대해 자세히 알아보겠습니다.


에러 메시지 분석

먼저, 에러 메시지를 살펴보겠습니다:

ValueError: --load_best_model_at_end requires the saving steps to be a round multiple of the evaluation steps, but found 200, which is not a round multiple of 500.

이 메시지는 --load_best_model_at_end 옵션을 사용할 때, save_steps와 eval_steps 간의 관계에 문제가 있다는 것을 의미합니다.


에러의 원인

--load_best_model_at_end 옵션은 학습 과정에서 성능이 가장 좋았던 모델을 마지막에 불러오기 위해 사용됩니다.

이 옵션을 사용하면, 모델은 학습이 끝난 후 가장 낮은 평가 손실을 기록한 체크포인트를 자동으로 로드합니다.

그러나 이 옵션이 제대로 작동하려면, 모델을 평가(evaluation)하는 시점과 저장(saving)하는 시점이 일치해야 합니다.

 

즉, 모델이 평가된 후 그 평가 결과를 기준으로 최적의 모델을 저장해야 하기 때문에,

eval_steps와 save_steps가 일치하거나 save_steps가 eval_steps의 배수가 되어야 합니다.

 

만약 eval_steps가 500이고 save_steps가 200이라면, 500번 학습 후 평가가 이루어질 때,

그 시점에 모델이 저장되지 않습니다. 이로 인해 최적의 모델을 선택하는 과정이 불가능해지거나 불완전해질 수 있습니다.


해결 방법

이 문제를 해결하기 위해서는 save_steps를 eval_steps의 배수로 설정하거나, 둘을 동일하게 설정해야 합니다.

이렇게 하면 평가 후 저장이 항상 이루어지므로, --load_best_model_at_end 옵션이 올바르게 작동하게 됩니다.

 

예를 들어, eval_steps가 500이라면, save_steps를 500 또는 1000, 1500 등으로 설정할 수 있습니다.

이렇게 설정하면 평가된 모델이 그 시점에 저장되어, 최적의 모델을 마지막에 불러올 수 있습니다.

 

이러한 설정의 예시:

training_args = TrainingArguments(
    output_dir='./results',
    num_train_epochs=3,
    per_device_train_batch_size=8,
    per_device_eval_batch_size=8,
    eval_strategy="steps",
    logging_dir='./logs',
    save_total_limit=3,
    save_steps=500,         # save_steps를 eval_steps와 동일하게 설정
    eval_steps=500,         # 평가 주기
    logging_steps=100,
    gradient_accumulation_steps=2,
    max_grad_norm=1.0,
    learning_rate=2e-5,
    load_best_model_at_end=True,  # 최적 모델 불러오기 옵션
)

결론

--load_best_model_at_end 옵션은 모델의 성능을 최적화하고,

가장 성능이 좋은 모델을 마지막에 사용할 수 있게 해줍니다.

 

그러나 이 기능이 제대로 작동하려면 save_steps와 eval_steps의 관계를 주의 깊게 설정해야 합니다.


두번째 에러 

element 0 of tensors does not require grad and does not have a grad_fn 

 

이 에러 메시지는 학습 중 역전파(backpropagation)를 수행하려고 할 때 발생합니다.

에러의 원인은 loss 값이 제대로 역전파되기 위한 grad_fn(gradient function)을 가지고 있지 않기 때문입니다.

이는 보통 모델의 파라미터가 학습 중 "requires_grad"가 설정되지 않았거나,

loss가 텐서가 아니라 단순한 값이 되었을 때 발생합니다.

 

원인 분석

이 에러는 보통 다음과 같은 경우에 발생합니다:

  1. 모델 파라미터의 requires_grad 속성 문제: 모델의 모든 파라미터가 학습 중 업데이트될 수 있도록 requires_grad=True로 설정되어야 합니다. 만약 어떤 이유로 이 속성이 False로 설정되면, 해당 파라미터는 학습 중 업데이트되지 않으며, 역전파 시 grad_fn이 없어집니다.
  2. loss 텐서가 아닌 값: loss 함수가 반환하는 값이 텐서가 아니거나, 텐서에 대한 추가 연산 후 grad_fn이 사라졌을 경우입니다.

 

해결 방법

다음은 이 문제를 해결하기 위한 몇 가지 방법입니다:

1. 모델 파라미터의 requires_grad 속성 확인

모델의 모든 파라미터가 requires_grad=True로 설정되어 있는지 확인합니다.

코드에서 이미 모든 파라미터에 대해 requires_grad=True로 설정하는 부분이 있지만, 이를 다시 한 번 확실히 확인합니다.

for param in model.parameters():
    param.requires_grad = True

2. loss 함수의 반환 값 확인

Trainer가 사용되는 경우, compute_loss 메서드가 텐서를 반환하는지 확인해야 합니다.

만약 커스텀 compute_loss 함수가 있다면, 반드시 텐서를 반환해야 하며, 반환된 텐서가 grad_fn을 가지고 있는지 확인합니다.

3. Trainer가 올바른 입력을 받고 있는지 확인

Trainer 클래스가 학습 시 올바른 입력을 받고 있는지 확인합니다.

특히 model_inputs가 올바르게 생성되고 labels가 설정되어 있는지 확인해야 합니다.