Haribo ML, AI, MATH, Algorithm

일좀 같이 합시다!!

2025-12-07
Haribo

대규모 데이터셋, 분산 학습, 협업? 이거 그냥 코드만 짠다고 되는 게 아니다. “내 컴퓨터에서만 돌아가는데요?” 라는 소리 했다가는 머리통이 으깨질 수 있다.
수십 장의 GPU가 돌아가는 환경에서는 “재현성(Reproducibility)”“확장성(Scalability)” 이 생명이다.
이 두 가지를 보장하지 못하는 코드는 쓰레기다.

  • 에러뜨면 빠르게 수정하고 다시 돌리고
  • 다른사람이 수정한거 빨리 확인하거나 시켜서 다시 돌리고
  • 바꿀꺼 있으면 빨리 해서 돌리고

명심하자 H100 상무님은 놀게 냅두면 안된다.

  1. 환경 설정 및 의존성 관리 (기초 중의 기초)
  2. 프로젝트 구조와 패키징 (협업의 뼈대)
  3. 설정 관리 (Hydra & OmegaConf)
  4. 코드 품질과 테스트 (협업의 안전장치)
  5. Git 협업 프로토콜 (Social Coding)
  6. 분산 학습과 인프라 (The Heavy Lifting)

나도 쓰면서 공부하는거라 좆밥용 ~ 호날두용까지 두루두루 살펴보며 해볼 생각이다.


1. 환경 설정 및 의존성 관리

주제: “내 로컬이랑 서버랑 환경이 다른데요?” 소리 안 나오게 하기

  • UV (vs Poetry vs Pip): 왜 요즘 uv가 핫한가? 단순히 빠른 게 장점이 아님.
    • Resolution Logic: 의존성 충돌 해결 방식.
    • Lock file: uv.lock이 왜 절대적인 진실인지. (이게 없으면 협업 불가능)
  • Python Version Mgmt: uv python install 등으로 격리하는 법.
  • Docker와의 연계: 결국 배포는 도커로 나간다. 로컬 환경(uv)을 도커로 얇게 말아 올리는 효율적인 방법.

2. 프로젝트 구조와 패키징 (협업의 뼈대)

주제: 스크립트 짜깁기가 아니라 “패키지”를 만들어라

만든 코드를 다른 사람이 import my_model로 갖다 쓰게 하려면 이게 필수임. 스크립트 덩어리가 아니라 ‘라이브러리’를 만든다는 마인드로 접근하자.

  • Src Layout vs Flat Layout: 왜 src/ 디렉토리 밑에 코드를 두는가?
    • 이유: 테스트 코드 실행 시 현재 디렉토리의 파일이 임포트 되는 ‘Import Hell’ 방지. 명시적인 패키지 설치 유도.
  • Editable Install (-e .): 개발 중에 코드를 수정하면 재설치 없이 바로 반영되게 하는 원리.
  • __init__.py의 역할: 네임스페이스 관리. 외부에서 from my_repo import Trainer 처럼 깔끔하게 보이게 하는 파사드(Facade) 패턴.

3. 설정 관리 (Hydra & OmegaConf)

주제: 하드코딩 금지, 실험 설정의 계층적 관리

  • Why Hydra?
    • Composition: model/resnet.yaml, optimizer/adamw.yaml 조립해서 쓰는 법.
    • Override: CLI에서 python train.py optimizer.lr=1e-4 처럼 동적으로 덮어쓰는 강력함.
  • Multirun: 한 번 실행으로 학습률 0.1, 0.01, 0.001 싹 다 돌리는 스윕(Sweep) 기능.
  • OmegaConf: YAML 안에서 ${…} 변수 참조, 타입 검사(Type Checking) 기능. (숫자 넣어야 하는데 문자 넣으면 뱉어내야 함)
  • Instantiation: 설정 파일 자체를 객체로 바로 바꾸는 hydra.utils.instantiate 패턴. (이거 모르면 코드에 if-else 도배하게 됨)

4. 코드 품질과 테스트 (협업의 안전장치)

주제: “어? 제가 고치니까 님 코드가 안 돌아가는데요?” 방지

  • Pytest 기초 ~ 고급: assert 문 하나로 끝내는 간결함 ~ DDP, FSDP 환경까지 테스트
  • Fixture: 매 테스트마다 모델 초기화하고 데이터셋 로드할꺼임? conftest.py로 공통 자원 관리하는 법.
  • Mocking (중요): S3에서 데이터 다운로드하는 코드를 테스트할 때마다 진짜 다운로드할꺼임? 가짜 객체(Mock)로 흉내 내는 법.
  • Git Hooks (Pre-commit): 커밋 누르는 순간 black, isort, flake8이 자동으로 코드 스타일 교정하고, pytest 돌려서 통과 못 하면 커밋 거부하게 만드는 법. (팀원들의 혈압 보호)

5. Git 협업 프로토콜 (Social Coding)

주제: 말보다 명확한 커밋 메시지

  • Conventional Commits: feat:, fix:, chore:, refactor:, docs: 접두어의 의미와 규칙. (이걸로 릴리즈 노트 자동 생성 가능)
  • Semantic Versioning (SemVer): v1.0.0 vs v1.1.0 vs v1.0.1의 차이. (API가 깨지면 Major, 기능 추가면 Minor, 버그 픽스면 Patch)
  • PR (Pull Request) Etiquette:
    • PR 본문에 “무엇을”, “왜”, “어떻게” 고쳤는지 스크린샷과 함께 적기.
    • 리뷰어에게 떠먹여 주는 PR 작성법.

6. 분산 학습과 인프라 (The Heavy Lifting)

주제: GPU 수십 장을 하나의 오케스트라처럼

  • 기본 용어:
    • Rank: 전체 프로세스 중 내 번호 (0번이 보통 대장).
    • Local Rank: 한 노드(컴퓨터) 안에서의 내 GPU 번호.
    • World Size: 총 GPU 개수.
  • 통신 백엔드 (NCCL vs Gloo): NVIDIA GPU 쓸 거면 NCCL이 유일신이다. 근데 왜 터질까? (P2P 통신, 방화벽, IOMMU 이슈 등)
  • Data Loading 이슈:
    • NFS (Network File System): 여러 노드가 동시에 같은 파일 읽으려 할 때 생기는 병목. WebDataset이나 샤딩(Sharding)이 필요한 이유.
    • Segfault: 주로 공유 메모리(shm) 부족이나 C++ 레벨의 포인터 오류. Python 레벨에서만 놀던 내가 가장 당황할 에러.
  • 실행 방식: torchrun (Elastic) vs accelerate (HuggingFace). 왜 요즘은 python train.py 대신 torchrun을 쓰는가? (노드 죽었을 때 재시작 관리 등)

Similar Posts

Comments