Python Class 객체 관리

Eunbin Park·2026년 9월 5일

코드를 짜다가 모델 이름만 다르고 하이퍼파라미터 등의 속성은 전부 같은 여러 트레이너를 만들어야 하는 상황이 왔는데, 이를 클래스로 관리하면 좋을 것 같아서 클래스를 제작했다.

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

GPT4는 이렇게 얘기해주었다.

물론 set_model_trainer와 같은 메서드를 사용하여 모델 트레이너를 추가하는 방식으로 구현할 수도 있지만, 이렇게 구현하는 경우 몇 가지 문제가 있습니다.

  • 객체의 상태 관리: 클래스 인스턴스의 상태를 추적하기 어렵습니다. set_model_trainer 메서드를 호출하면 이전에 설정된 모델이 변경되고, 이전 상태는 완전히 잊혀집니다. 이는 예기치 않은 동작이나 버그로 이어질 수 있습니다.
  • 명시성: 클래스를 사용할 때 객체를 생성하면서 모델을 설정하는 방식은 명시적입니다. __init__ 메서드에서 모델을 설정하게 되면, 객체가 생성될 때 정확히 어떤 작업이 이루어지는지 명확하게 이해할 수 있습니다. 반면에 set_model_trainer 메서드를 사용하면, 객체 생성 후에 언제든지 모델이 변경될 수 있어 코드를 이해하고 추적하기 어렵습니다.
  • 불필요한 복잡성: set_model_trainer 메서드를 사용하여 모델을 설정하는 것은 객체 생성 후에도 클래스의 상태를 변경할 수 있는 여지를 남겨둡니다. 이는 코드를 불필요하게 복잡하게 만들며, 클래스를 사용하는 개발자에게 추가적인 주의를 기울여야 하는 부담을 줍니다.

따라서 __init__ 메서드에서 모델을 설정하게끔 구현하는 것이 객체 생성 시 정확히 어떤 작업이 이루어지는지 명확하게 알 수 있고, 객체의 상태를 더 잘 관리할 수 있습니다. 또한 코드가 더 간결하고 명료해집니다. 이러한 이유로 __init__ 메서드에서 모델을 설정하는 것이 더 좋은 방식입니다.

이 대답은 뭘까

"그냥 이렇게하면 되겠다!"같은 느낌은 있는데, 왜? 라고 물어보면 대답이 망설여진다.
내 생각에 이건, 제대로 잘 모르는데 경험은 있으니까 결론부터 나오는 거다.
아무튼 나에게는 좋은 스승인 GPT 가 있고, 그 대답을 기반으로 다시 나만의 방식으로 정립해보자 한다.

객체 상태 관리

명시성

불필요한 복잡성

0개의 댓글