개발 철학¶
PyTorch의 자유로운 모듈 작성 방식은 실험 구성 간 인터페이스 불일치와 모듈 간 의존성을 높일 수 있습니다. CVLab-Kit은 PyTorch를 기반으로도 실험 환경의 반복 실험과 빠른 프로토타이핑을 위해 다음과 같은 개발 철학을 바탕으로 설계되었습니다:
1. Automatic Grid Search¶
- 설정(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클래스가 있어야 합니다.
- 클래스명은 파스칼 케이스(PascalCase)여야 합니다 (예:
4. Dependency Resolution¶
원활한 실험 프로토타이핑을 위해, 다양한 의존성을 체계적으로 해결해야 합니다. CVLab-Kit은 의존성을 세 가지 유형으로 정의하고, 각각에 대한 명확한 해결책을 구현하여 프레임워크의 유연성과 확장성을 보장합니다.
1. 상속 의존성 (Inheritance Dependency)¶
- 문제점: PyTorch는
nn.Module이나optim.Optimizer와 같은 특정 클래스를 상속받아야 정상적으로 동작하는 경우가 많습니다. 사용자가 직접 만든 컴포넌트가 이러한 기본 규칙을 지키지 않으면, 프레임워크가 동적으로 로드하더라도 호환성 오류가 발생할 수 있습니다. - 해결 방식:
cvlab-kit은 각 컴포넌트 타입별로 추상 클래스(Abstract Base Class)를 제공하여 PyTorch의 기본 클래스 상속을 강제합니다. 예를 들어,cvlabkit.component.base.Model은torch.nn.Module을 상속받도록 설계되었습니다. 이를 통해 사용자가 어떤 모델을 만들더라도 최소한의 호환성을 확보하여, 자동 탐색 및 호출 시에도 일관된 작동을 보장합니다.
2. 컴포넌트 간 의존성 (Inter-component Dependency)¶
- 문제점: 한 컴포넌트가 다른 컴포넌트의 인스턴스 자체를 필요로 하는 경우입니다. 가장 대표적인 예로,
Optimizer는Model이 완전히 생성된 후에야 얻을 수 있는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객체를 주입하여, 모든 '부품'이 동일한 '설계도'를 공유하도록 만듭니다.
이처럼 각 의존성에 대한 역할과 해결책을 명확히 분리하는 설계 덕분에, 개발자는 각 컴포넌트의 독립성을 유지하면서도 다양한 실험 조합을 빠르고 유연하게 구성할 수 있습니다.