코드를 짜다가 모델 이름만 다르고 하이퍼파라미터 등의 속성은 전부 같은 여러 트레이너를 만들어야 하는 상황이 왔는데, 이를 클래스로 관리하면 좋을 것 같아서 클래스를 제작했다.
from utils import (
ModelArguments,
Metrics,
)
from transformers import (
AutoConfig,
AutoTokenizer,
AutoModelForTokenClassification,
Trainer,
TrainingArguments,
DataCollatorForTokenClassification
)
class ModelTrainer:
def __init__(self,
model_name_or_path,
initial_train_dataset,
eval_dataset,
label_list,
metrics,
args):
self.model_args = ModelArguments(model_name_or_path=model_name_or_path, batch_size=32)
self.config = AutoConfig.from_pretrained(model_name_or_path, num_labels=len(label_list))
self.tokenizer = AutoTokenizer.from_pretrained(model_name_or_path, use_fast=True)
self.model = AutoModelForTokenClassification.from_pretrained(model_name_or_path, config=self.config)
self.training_args = TrainingArguments(
output_dir=self.model_args.output_dir,
num_train_epochs=self.model_args.num_train_epochs,
per_device_train_batch_size=self.model_args.batch_size,
per_device_eval_batch_size=self.model_args.batch_size,
warmup_steps=self.model_args.warmup_steps,
weight_decay=self.model_args.weight_decay,
log_level="info",
logging_dir=self.model_args.logging_dir,
logging_steps=self.model_args.logging_steps,
save_steps=self.model_args.save_steps,
fp16=self.model_args.fp16,
metric_for_best_model="f1",
)
self.data_collator = DataCollatorForTokenClassification(self.tokenizer,
pad_to_multiple_of=8 if self.training_args.fp16 else None)
self.trainer = Trainer(
model=self.model,
args=self.training_args,
train_dataset=initial_train_dataset if args.do_train else None,
eval_dataset=eval_dataset if args.do_eval else None,
tokenizer=self.tokenizer,
data_collator=self.data_collator,
compute_metrics=metrics.compute_metrics,
)
근데 model_name_or_path 말고는 다 같으니까, 메서드를 하나 만들어서 거기에 model name: str을 넣어주면 되는 거 아닐까? 하고 생각했다.
GPT4는 이렇게 얘기해주었다.
물론 set_model_trainer와 같은 메서드를 사용하여 모델 트레이너를 추가하는 방식으로 구현할 수도 있지만, 이렇게 구현하는 경우 몇 가지 문제가 있습니다.
따라서 __init__ 메서드에서 모델을 설정하게끔 구현하는 것이 객체 생성 시 정확히 어떤 작업이 이루어지는지 명확하게 알 수 있고, 객체의 상태를 더 잘 관리할 수 있습니다. 또한 코드가 더 간결하고 명료해집니다. 이러한 이유로 __init__ 메서드에서 모델을 설정하는 것이 더 좋은 방식입니다.
"그냥 이렇게하면 되겠다!"같은 느낌은 있는데, 왜? 라고 물어보면 대답이 망설여진다.
내 생각에 이건, 제대로 잘 모르는데 경험은 있으니까 결론부터 나오는 거다.
아무튼 나에게는 좋은 스승인 GPT 가 있고, 그 대답을 기반으로 다시 나만의 방식으로 정립해보자 한다.