콘텐츠로 이동

개발 철학

PyTorch의 자유로운 모듈 작성 방식은 실험 구성 간 인터페이스 불일치와 모듈 간 의존성을 높일 수 있습니다. CVLab-Kit은 PyTorch를 기반으로도 실험 환경의 반복 실험과 빠른 프로토타이핑을 위해 다음과 같은 개발 철학을 바탕으로 설계되었습니다:

  • 설정(YAML) 파일 안에 리스트 타입으로 설정된 값들이 자동으로 조합되어 반복 실험을 수행합니다.

2. Why in Key, How in Value

설정(YAML)을 작성할 때, Agent의 변수인 Key에는 행위의 목적(Why)을, 실제 컴포넌트 구현체인 Value에는 그 목적을 달성할 방법(How)을 명시합니다. 이는 프레임워크의 모든 컴포넌트 설계와 사용법을 관통하는 가장 중요한 원칙입니다.

이 원칙은 특정 기술(How)이 컴포넌트의 이름이나 구조에 종속되는 것을 방지하고, 재사용성을 극대화합니다.

3. Component Interface

  • cvlabkit/component/base 디렉토리에 컴포넌트의 추상 클래스를 정의함으로써, 모든 하위 클래스가 동일한 인터페이스를 가지도록 합니다. 이는 코드 일관성을 유지하고 확장성을 높입니다.
  • 명명 규칙: 각 컴포넌트의 인터페이스가 되는 추상 클래스는 다음과 같은 명명 규칙을 따라야 합니다:
    • 클래스명은 파스칼 케이스(PascalCase)여야 합니다 (예: DataLoader, Optimizer).
    • 파일명은 스네이크 케이스(snake_case)여야 합니다 (예: data_loader.py, optimizer.py).
    • 클래스명과 파일명의 영문 구성은 동일해야 하며, 케이스만 달라야 합니다. 예를 들어, data_loader.py 파일에는 DataLoader 클래스가 있어야 합니다.

4. Dependency Resolution

원활한 실험 프로토타이핑을 위해, 다양한 의존성을 체계적으로 해결해야 합니다. CVLab-Kit은 의존성을 세 가지 유형으로 정의하고, 각각에 대한 명확한 해결책을 구현하여 프레임워크의 유연성과 확장성을 보장합니다.

1. 상속 의존성 (Inheritance Dependency)

  • 문제점: PyTorch는 nn.Module이나 optim.Optimizer와 같은 특정 클래스를 상속받아야 정상적으로 동작하는 경우가 많습니다. 사용자가 직접 만든 컴포넌트가 이러한 기본 규칙을 지키지 않으면, 프레임워크가 동적으로 로드하더라도 호환성 오류가 발생할 수 있습니다.
  • 해결 방식: cvlab-kit은 각 컴포넌트 타입별로 추상 클래스(Abstract Base Class)를 제공하여 PyTorch의 기본 클래스 상속을 강제합니다. 예를 들어, cvlabkit.component.base.Modeltorch.nn.Module을 상속받도록 설계되었습니다. 이를 통해 사용자가 어떤 모델을 만들더라도 최소한의 호환성을 확보하여, 자동 탐색 및 호출 시에도 일관된 작동을 보장합니다.

2. 컴포넌트 간 의존성 (Inter-component Dependency)

  • 문제점: 한 컴포넌트가 다른 컴포넌트의 인스턴스 자체를 필요로 하는 경우입니다. 가장 대표적인 예로, OptimizerModel이 완전히 생성된 후에야 얻을 수 있는 model.parameters()를 필요로 합니다.
  • 해결 방식: Agent가 지휘하는 Creator의 단계적 생성(Step-by-step Creation) 방식을 사용합니다. Agent는 먼저 model = create.model()을 통해 모델을 생성하고, 그 결과물인 model.parameters()를 다음 컴포넌트 생성 시 명시적 의존성 주입(Explicit Dependency Injection)으로 전달합니다. (optimizer = create.optimizer(model.parameters())) 이처럼 생성 순서와 컴포넌트 간의 의존성은 Agent가 책임지고 관리합니다.

3. 객체 속성 의존성 (Object Property Dependency)

  • 문제점: 여러 컴포넌트가 num_classes, learning_rate동일한 설정 값을 공유해야 하거나, 각자의 동작에 필요한 개별 설정 값을 참조해야 합니다.
  • 해결 방식: Creator는 모든 컴포넌트를 생성할 때, 설정 파일 전체를 담고 있는 Config 객체를 생성자의 인자로 주입합니다. 이는 일종의 스탬프 결합(Stamp Coupling) 방식으로, 각 컴포넌트는 cfg.num_classes처럼 필요한 모든 설정 값에 일관되게 접근할 수 있습니다. 이를 통해 공통 파라미터와 개별 파라미터 모두를 안정적으로 전달합니다.

결론적으로, cvlab-kit은 프로토타이핑의 범용성을 극대화하기 위해 세 가지 유형의 의존성을 각각 다른 방식으로 명확하게 해결합니다.

  • 상속 의존성은 각 컴포넌트의 추상 클래스가 PyTorch의 필수 클래스 상속을 강제함으로써 해결합니다.
  • 컴포넌트 간 의존성Agent가 지휘자가 되어, Creator를 통해 컴포넌트를 순서대로 생성하고 그 결과물을 다음 컴포넌트에 명시적으로 전달하여 조립하는 방식으로 해결합니다.
  • 객체 속성 의존성Creator가 모든 컴포넌트 생성 시 Config 객체를 주입하여, 모든 '부품'이 동일한 '설계도'를 공유하도록 만듭니다.

이처럼 각 의존성에 대한 역할과 해결책을 명확히 분리하는 설계 덕분에, 개발자는 각 컴포넌트의 독립성을 유지하면서도 다양한 실험 조합을 빠르고 유연하게 구성할 수 있습니다.