본문 바로가기

딥러닝/트랜스포머

[huggingface][transformers] model.generate 모델 예측값 고정(temperature란?)

  • LLaMA로 inference만 하던 중, set_seed(42)로 seed 값을 고정해도 결과값이 다르게 나온다는 사실을 알았다.
  • 모델 결과를 고정하려면 생성할 때 decoding에서 temperature 값을 0에 가깝게 설정해야 한다.

1. model.generate 일관적인 결과 얻기

  • 아래 코드는 모델을 단순 inference 하기 위해서 라이브러리를 부르는 코드이다.
  • 테스트용으로 작성을 하여 가독성이 안 좋을 수 있다.
import sys
import torch
import transformers
from transformers import (
    AutoModelForCausalLM,
    AutoTokenizer,
    BitsAndBytesConfig,
    TrainingArguments,
    pipeline,
    logging,
    set_seed,
)
from peft import LoraConfig, PeftModel
from trl import SFTTrainer
from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import PeftModel, PeftConfig

import sys, json

from tqdm import tqdm

set_seed(42)
  • 허깅페이스의 트랜스포머 라이브러리에는 set_seed라는 함수가 있고, 이를 이용해서 seed를 고정할 수 있다.
  • seed를 고정하면 라이브러리에서 사용할 수도 있는 난수값을 고정한다는 의미이다.
  • 그러나 seed를 고정한다고 해서 무조건 코드를 실행할 때마다 동일한 입력에 대하여 동일한 출력이 생성됨을 보장할 수 없다.
  • 따라서 아래와 같이 generate에서 temperature 옵션을 0에 가까운 수로 주어야 한다.
  • 0으로 설정할 경우 에러가 발생한다.
    • ValueError: temperature (=0.0) has to be a strictly positive float, otherwise your next token scores will be invalid. If you're looking for greedy decoding strategies, set do_sample=False.(왜 temperature는 positive float 값을 가져야 하는 지는 아래에..)
outputs = self.model.generate(**inputs, 
                max_length=2048, 
                num_return_sequences=1, 
                early_stopping=True,
                do_sample=True,
                temperature=0.2
#                 num_beams=2
#                 no_repeat_ngram_size=3
                )

 

2. temperature란?

  • temperature는 NN에서 출력값의 분포를 수정하기 위해서 사용
  • 즉, model에서 output을 생성할 때 logits 값에 softmax를 취하기 전, temperature을 다음과 같이 적용하여 분포를 수정
    • $$q_i = \frac{exp(z_i/T)}{\sum_j{exp(z_j/T)}}$$
    • 따라서 temperature를 0으로 설정할 경우 계산 과정에서 0으로 나누려고 하기 때문에 오류가 발생
  • temperature가 1이면 softmax를 취한 값과 동일하고, 0에 가까울 수록 가장 높은 확률로 나온 토큰을 결정적으로 선택
  • 따라서 `do_sample`을 사용하지 않는다면 일반적으로 default가 greedy이므로 랜덤한 결과가 나오지 않지만, `do_sample`을 사용하는 경우에는 temperature를 0에 가까운 수로 설정을 해두어야 일관된 결과를 얻을 수 있음
  • 보통 temperature를 사용하는 이유는 모델이 다양한 결과물을 생성했으면 하기 때문