Transformers Trainer 뜯어보기
🤗

Transformers Trainer 뜯어보기

Tags
NLP
MLDL Framework
Published
Published May 22, 2021

Huggingface Transformers의 Trainer

Huggingface Transformers에서는 보다 쉬운 모델 학습을 위해 Trainer 라는 라이브러리를 제공한다.
사용하는 것은 많이 하지만, 실제로 모델을 어떻게 받고 데이터를 어떻게 넘겨줘서 → 어떻게
설명대상 코드

Trainer는 어떻게 쓰나?

Transformers Example에 있는 run_clm.py 등에서는 Trainer를 사용해서 학습한다.
# Initialize our Trainer trainer = Trainer( model=model, args=training_args, train_dataset=train_dataset if training_args.do_train else None, eval_dataset=eval_dataset if training_args.do_eval else None, tokenizer=tokenizer, # Data collator will default to DataCollatorWithPadding, so we change it. data_collator=default_data_collator, )
위 코드는 Trainer 클래스에 Model, Training 인자, dataset, tokenizer, data collator를 넣어준다.
  • model: ~~ForCasualLM, ~~ForMaskedLM 같은 CLM/MLM 모델을 넣어준다.
  • args: ModelArguments 라는 DataClass를 기반으로 만들어서 모델 instance를 생성할 때, 아래와 같이 인자를 받아서 model_args 로 전달해준다.
    • class Model Arguments 코드
      @dataclass class ModelArguments: """ Arguments pertaining to which model/config/tokenizer we are going to fine-tune, or train from scratch. """ model_name_or_path: Optional[str] = field( default=None, metadata={ "help": "The model checkpoint for weights initialization." "Don't set if you want to train a model from scratch." }, ) model_type: Optional[str] = field( default=None, metadata={"help": "If training from scratch, pass a model type from the list: " + ", ".join(MODEL_TYPES)}, ) config_name: Optional[str] = field( default=None, metadata={"help": "Pretrained config name or path if not the same as model_name"} ) tokenizer_name: Optional[str] = field( default=None, metadata={"help": "Pretrained tokenizer name or path if not the same as model_name"} ) cache_dir: Optional[str] = field( default=None, metadata={"help": "Where do you want to store the pretrained models downloaded from huggingface.co"}, ) use_fast_tokenizer: bool = field( default=True, metadata={"help": "Whether to use one of the fast tokenizer (backed by the tokenizers library) or not."}, ) model_revision: str = field( default="main", metadata={"help": "The specific model version to use (can be a branch name, tag name or commit id)."}, ) use_auth_token: bool = field( default=False, metadata={ "help": "Will use the token generated when running `transformers-cli login` (necessary to use this script " "with private models)." }, )
  • train_dataset: lm_datasets["train"] 라는 형태로 들어가는데, 일종의 dict ~ pandas df 사이의 어딘가에 있는 느낌이다.
  • tokenizer:
    • 이 옵션을 처음에 봤을때는 Model 학습 단계에서 Trainer level에서 데이터셋을 매 batch마다 tokenize해서 넣어주는줄 알았는데, 실제로는 단순히 Tokenizer의 meta정보를 받기 위해서 들어가는 형태다.
      tokenized_datasets 에서 tokenize를 진행하고, 이때 tokenized는 사실은 Encoded 되었다, 라고 말하는 것이 더 적합하다. BERT Tokenizer 등에서 {'input_ids': [2, 19017, 8482, 3], 'token_type_ids': [0, 0, 0, 0], 'attention_mask': [1, 1, 1, 1]} 와 같은 형태의 결과물을 저장한다.
      또한, lm_datasets 의 경우, 위 dict 처럼 잘려진 상태를 정해진 길이만큼 붙이는 (GPT-2의 경우 1000단위로 붙이고, RoBERTa의 경우 512 단위로 붙이는 등) 과정을 통해 padding을 최대한 줄이는 방향으로 학습한다. (*물론, 이건 모델마다 다르다.)
      이 과정으로 인해, TEXT 데이터의 경우 txt → encoded json → concated json 형태로 진행하는데, 이 과정에 시간이 굉장히 오래 걸리게 된다.
      따라서, 가능하다면 concated json까지 PyArrow로 변환한 뒤 학습을 시작하자.

그러면, Trainer는 어떻게 동작하나?