메인 콘텐츠로 건너뛰기
분산 트레이닝 실험에서는 여러 머신이나 클라이언트를 병렬로 사용해 모델을 트레이닝합니다. W&B를 사용하면 분산 트레이닝 실험을 추적할 수 있습니다. 사용 사례에 따라 다음 접근 방식 중 하나로 분산 트레이닝 실험을 추적하세요.
  • 단일 프로세스 추적: W&B로 rank 0 프로세스(“leader” 또는 “coordinator”라고도 함)를 추적합니다. 이는 PyTorch Distributed Data Parallel (DDP) 클래스로 분산 트레이닝 실험을 로깅할 때 흔히 사용하는 방법입니다.
  • 여러 프로세스 추적: 여러 프로세스의 경우 다음 중 하나를 선택할 수 있습니다.
    • 프로세스마다 하나의 run을 사용해 각 프로세스를 개별적으로 추적합니다. 필요하면 W&B App UI에서 이들을 함께 그룹화할 수 있습니다.
    • 모든 프로세스를 하나의 run으로 추적합니다.
동시 연결각 동시 연결은 컴퓨팅, 메모리, 네트워크 리소스를 사용합니다. 메트릭을 정기적으로 로깅하지 않는 유휴 클라이언트 연결도 시스템 메트릭 업데이트를 계속 전송하므로, 차트를 로드할 때 성능이 저하될 수 있습니다.W&B는 워크로드에 맞게 동시 클라이언트 연결의 최대 수를 제한하고, 시간에 따라 리소스 사용량을 모니터링할 것을 권장합니다. W&B는 Dedicated Cloud에서 동시 클라이언트 연결 수 300개를 하드 제한으로 테스트했습니다.Multi-tenant Cloud 조직에서는 분산 트레이닝용 클라이언트 연결에 일반 트레이닝 run과 동일한 요청 속도 제한이 적용됩니다. Teams and Enterprise plans의 Users는 Free 플랜 사용자보다 더 높은 요청 속도 제한을 받습니다.

단일 프로세스 추적

이 섹션에서는 rank 0 프로세스에서 사용할 수 있는 값과 메트릭을 추적하는 방법을 설명합니다. 이 방법은 단일 프로세스에서만 확인할 수 있는 메트릭만 추적할 때 사용하세요. 일반적인 메트릭으로는 GPU/CPU 사용량, 공유 검증 세트에서의 동작, 그라디언트와 파라미터, 대표 데이터 예제에 대한 loss 값 등이 있습니다. rank 0 프로세스 내에서 wandb.init()으로 W&B run을 초기화하고, 실험 데이터를 해당 run에 wandb.Run.log()로 로깅합니다. 다음 샘플 Python 스크립트 (log-ddp.py)는 PyTorch DDP를 사용해 단일 머신의 두 GPU에서 메트릭을 추적하는 한 가지 방법을 보여줍니다. PyTorch DDP(torch.nnDistributedDataParallel)는 분산 트레이닝에 널리 사용되는 라이브러리입니다. 기본 원칙은 모든 분산 트레이닝 설정에 적용되지만, 구현 방식은 다를 수 있습니다. Python 스크립트는 다음을 수행합니다:
  1. torch.distributed.launch로 여러 프로세스를 시작합니다.
  2. --local_rank 명령줄 인수로 rank를 확인합니다.
  3. rank가 0으로 설정된 경우, train() 함수에서 조건부로 wandb를 로깅하도록 설정합니다.
if __name__ == "__main__":
    # 인수 조회
    args = parse_args()

    if args.local_rank == 0:  # 메인 프로세스에서만 실행
        # wandb run 초기화
        run = wandb.init(
            entity=args.entity,
            project=args.project,
        )
        # DDP로 모델 트레이닝
        train(args, run)
    else:
        train(args)
단일 프로세스에서 추적한 메트릭을 보여주는 예시 대시보드를 살펴보세요. 대시보드에는 온도와 사용량 등 두 GPU의 시스템 메트릭이 표시됩니다.
GPU 메트릭 대시보드
하지만 에포크와 배치 크기에 따른 손실값은 단일 GPU에서만 로깅되었습니다.
손실 함수 플롯

여러 프로세스 추적하기

다음 방법 중 하나로 W&B에서 여러 프로세스를 추적할 수 있습니다:

각 프로세스를 개별적으로 추적하기

이 섹션에서는 각 프로세스마다 run을 생성해 각 프로세스를 개별적으로 추적하는 방법을 설명합니다. 각 run 내에서 해당 run에 메트릭, Artifacts 등을 로깅합니다. 모든 프로세스가 정상적으로 종료되도록 트레이닝이 끝나면 wandb.Run.finish()를 호출해 run이 완료되었음을 표시하세요. 여러 실험에 걸쳐 run을 추적하다 보면 관리가 어려울 수 있습니다. 이를 완화하려면 W&B를 초기화할 때(wandb.init(group='group-name')) group 파라미터에 값을 지정해 어떤 run이 특정 실험에 속하는지 추적하세요. 실험에서 트레이닝 및 평가 W&B Runs를 추적하는 방법에 대한 자세한 내용은 Group Runs를 참조하세요.
개별 프로세스의 메트릭을 추적하려는 경우 이 방식을 사용하세요. 일반적인 예로는 각 노드의 데이터와 예측(데이터 분포 디버깅용), 그리고 메인 노드 외부의 개별 배치 메트릭이 있습니다. 이 방식은 모든 노드의 시스템 메트릭을 가져오거나 메인 노드에서 사용할 수 있는 요약 통계를 얻기 위해 꼭 필요한 것은 아닙니다.
다음 Python 코드 스니펫은 W&B를 초기화할 때 group 파라미터를 설정하는 방법을 보여줍니다:
if __name__ == "__main__":
    # 인수 조회
    args = parse_args()
    # run 초기화
    run = wandb.init(
        entity=args.entity,
        project=args.project,
        group="DDP",  # 실험의 모든 run을 하나의 그룹으로
    )
    # DDP로 모델 트레이닝
    train(args, run)

    run.finish()  # run 완료로 표시
여러 프로세스에서 추적한 메트릭의 예시 대시보드를 보려면 W&B App UI를 살펴보세요. 왼쪽 사이드바에서 두 개의 W&B Runs가 함께 그룹화되어 있는 것을 확인할 수 있습니다. 그룹을 클릭하면 해당 실험의 전용 그룹 페이지를 볼 수 있습니다. 이 전용 그룹 페이지에는 각 프로세스의 메트릭이 개별적으로 표시됩니다.
그룹화된 분산 run
위 이미지는 W&B App UI 대시보드를 보여줍니다. 사이드바에는 두 개의 실험이 있습니다. 하나는 ‘null’로 표시되고, 다른 하나는(노란색 상자로 강조된) ‘DPP’입니다. 그룹을 확장하면(Group 드롭다운을 선택) 해당 실험에 연결된 W&B Runs를 볼 수 있습니다.

분산 run 정리

노드를 역할에 따라 분류하려면 W&B를 초기화할 때 job_type 파라미터를 설정하세요(wandb.init(job_type='type-name')). 예를 들어, 메인 조정 노드 하나와 리포팅 워커 노드 여러 개가 있을 수 있습니다. 메인 조정 노드에는 job_typemain으로, 리포팅 워커 노드에는 worker로 설정할 수 있습니다:
   # 메인 조정 노드
   with wandb.init(project="<project>", job_type="main", group="experiment_1") as run:
        # 트레이닝 코드

   # 리포팅 워커 노드
   with wandb.init(project="<project>", job_type="worker", group="experiment_1") as run:
        # 트레이닝 코드
노드에 job_type을 설정한 후에는 워크스페이스에서 저장된 뷰를 만들어 run을 정리할 수 있습니다. 오른쪽 상단의 action () 메뉴를 클릭한 다음 Save as new view를 클릭합니다. 예를 들어, 다음과 같은 저장된 뷰를 만들 수 있습니다:
  • 기본 뷰: 워커 노드를 필터링해 노이즈 줄이기
    • Filter를 클릭한 다음 Job Typeworker로 설정합니다.
    • 리포팅 노드만 표시합니다
    • 디버그 뷰: 문제 해결을 위해 워커 노드에 집중
      • Filter를 클릭한 다음 Job Type== worker로 설정하고 StateIN crashed로 설정합니다.
      • 비정상 종료되었거나 오류 상태인 워커 노드만 표시합니다
    • 모든 노드 뷰: 전체 노드를 함께 보기
      • 필터 없음
      • 전체적인 모니터링에 유용합니다
저장된 뷰를 열려면 프로젝트 사이드바에서 Workspaces를 클릭한 다음 메뉴를 클릭합니다. Workspaces는 목록 상단에 표시되고 저장된 뷰는 하단에 표시됩니다.

모든 프로세스를 단일 run에 추적하기

x_ 접두사가 붙은 파라미터(x_label 등)는 공개 프리뷰 상태입니다. 피드백을 제공하려면 W&B 저장소에 GitHub issue를 생성하세요.
Requirements여러 프로세스를 단일 run에 추적하려면 다음이 필요합니다.
  • W&B Python SDK v0.19.9 이상
  • W&B Server v0.68 이상
이 방식에서는 기본 노드 하나와 하나 이상의 워커 노드를 사용합니다. 기본 노드에서 W&B run을 초기화합니다. 각 워커 노드에서는 기본 노드가 사용한 run ID를 사용해 run을 초기화합니다. 트레이닝 중에는 각 워커 노드가 기본 노드와 동일한 run ID에 로깅합니다. W&B는 모든 노드의 메트릭을 집계해 W&B App UI에 표시합니다. 기본 노드에서는 wandb.init()으로 W&B run을 초기화합니다. settings 파라미터에 wandb.Settings 객체를 전달하고(wandb.init(settings=wandb.Settings()) 다음을 설정합니다.
  1. 공유 모드를 활성화하려면 mode 파라미터를 "shared"로 설정합니다.
  2. x_label에 고유한 레이블을 지정합니다. x_label에 지정한 값은 W&B App UI의 로깅과 시스템 메트릭에서 데이터가 어느 노드에서 왔는지 파악하는 데 사용됩니다. 지정하지 않으면 W&B가 호스트 이름과 임의의 해시를 사용해 레이블을 생성합니다.
  3. 이 노드가 기본 노드임을 나타내려면 x_primary 파라미터를 True로 설정합니다.
  4. 선택적으로 GPU 인덱스 목록([0,1,2])을 x_stats_gpu_device_ids에 전달해 W&B가 메트릭을 추적할 GPU를 지정할 수 있습니다. 목록을 제공하지 않으면 W&B는 머신의 모든 GPU에 대한 메트릭을 추적합니다.
기본 노드의 run ID를 기록해 두세요. 각 워커 노드에는 기본 노드의 run ID가 필요합니다.
x_primary=True는 기본 노드와 워커 노드를 구분합니다. 기본 노드만 설정 파일, 텔레메트리 등 노드 간에 공유되는 파일을 업로드합니다. 워커 노드는 이러한 파일을 업로드하지 않습니다.
각 워커 노드에서는 wandb.init()으로 W&B run을 초기화하고 다음을 제공합니다.
  1. settings 파라미터에 wandb.Settings 객체를 전달합니다(wandb.init(settings=wandb.Settings()). 포함할 항목은 다음과 같습니다.
    • 공유 모드를 활성화하려면 mode 파라미터를 "shared"로 설정합니다.
    • x_label에 고유한 레이블을 지정합니다. x_label에 지정한 값은 W&B App UI의 로깅과 시스템 메트릭에서 데이터가 어느 노드에서 왔는지 파악하는 데 사용됩니다. 지정하지 않으면 W&B가 호스트 이름과 임의의 해시를 사용해 레이블을 생성합니다.
    • 이 노드가 워커 노드임을 나타내려면 x_primary 파라미터를 False로 설정합니다.
  2. 기본 노드가 사용한 run ID를 id 파라미터에 전달합니다.
  3. 선택적으로 x_update_finish_stateFalse로 설정합니다. 이렇게 하면 기본 노드가 아닌 노드가 run 상태를 너무 일찍 finished로 업데이트하는 것을 방지하여, run 상태가 일관되게 유지되고 기본 노드에서 관리되도록 할 수 있습니다.
  • 모든 노드에서 동일한 entity와 프로젝트를 사용하세요. 이렇게 하면 올바른 run ID를 찾는 데 도움이 됩니다.
  • 각 워커 노드에서 기본 노드의 run ID를 설정하는 환경 변수를 정의하는 것도 좋습니다.
다음 샘플 코드는 여러 프로세스를 단일 run에 추적하기 위한 상위 수준 요구 사항을 보여줍니다.
import wandb

entity = "<team_entity>"
project = "<project_name>"

# 기본 노드에서 run 초기화
run = wandb.init(
    entity=entity,
    project=project,
	settings=wandb.Settings(
        x_label="rank_0",
        mode="shared",
        x_primary=True,
        x_stats_gpu_device_ids=[0, 1],  # (선택) GPU 0과 1의 메트릭만 추적
        )
)

# 기본 노드의 run ID를 기록해 두세요.
# 각 워커 노드에 이 run ID가 필요합니다.
run_id = run.id

# 기본 노드의 run ID를 사용하여 워커 노드에서 run 초기화
run = wandb.init(
    entity=entity, # 기본 노드와 동일한 entity 사용
    project=project, # 기본 노드와 동일한 프로젝트 사용
	settings=wandb.Settings(x_label="rank_1", mode="shared", x_primary=False),
	id=run_id,
)

# 기본 노드의 run ID를 사용하여 워커 노드에서 run 초기화
run = wandb.init(
    entity=entity, # 기본 노드와 동일한 entity 사용
    project=project, # 기본 노드와 동일한 프로젝트 사용
	settings=wandb.Settings(x_label="rank_2", mode="shared", x_primary=False),
	id=run_id,
)
실제 환경의 예에서는 각 워커 노드가 서로 다른 머신에 있을 수 있습니다.
GKE의 멀티노드 및 멀티 GPU Kubernetes 클러스터에서 모델을 트레이닝하는 방법에 대한 엔드 투 엔드 예시는 Distributed Training with Shared Mode report를 참조하세요.
run이 로깅하는 프로젝트에서 멀티노드 프로세스의 콘솔 로그를 보려면 다음과 같이 하세요:
  1. run이 포함된 프로젝트로 이동합니다.
  2. 프로젝트 사이드바에서 Runs 탭을 클릭합니다.
  3. 보려는 run을 클릭합니다.
  4. 프로젝트 사이드바에서 Logs 탭을 클릭합니다.
콘솔 로그 페이지 상단의 UI 검색 표시줄에서 x_label에 지정한 레이블을 기준으로 콘솔 로그를 필터링할 수 있습니다. 예를 들어, 다음 이미지는 rank0, rank1, rank2, rank3, rank4, rank5, rank6 값을 x_label에 제공한 경우 콘솔 로그를 필터링할 때 사용할 수 있는 옵션을 보여줍니다.
멀티노드 콘솔 로그
자세한 내용은 Console logs를 참조하세요. W&B는 모든 노드의 시스템 메트릭을 집계해 W&B App UI에 표시합니다. 예를 들어, 다음 이미지는 여러 노드의 시스템 메트릭이 포함된 샘플 대시보드를 보여줍니다. 각 노드에는 x_label 매개변수로 지정한 고유한 레이블(rank_0, rank_1, rank_2)이 있습니다.
멀티노드 시스템 메트릭
선형 플롯 패널을 사용자 지정하는 방법은 Line plots를 참조하세요.

사용 사례 예시

다음 코드 스니펫은 고급 분산 사용 사례의 일반적인 시나리오를 보여줍니다.

프로세스 생성

생성된 프로세스에서 run을 시작하는 경우 main 함수에서 wandb.setup()를 사용하세요:
import multiprocessing as mp

def do_work(n):
    with wandb.init(config=dict(n=n)) as run:
        run.log(dict(this=n * n))

def main():
    wandb.setup()
    pool = mp.Pool(processes=4)
    pool.map(do_work, range(4))


if __name__ == "__main__":
    main()

run 공유하기

프로세스 간에 run을 공유하려면 run 객체를 인수로 전달합니다:
def do_work(run):
    with wandb.init() as run:
        run.log(dict(this=1))

def main():
    run = wandb.init()
    p = mp.Process(target=do_work, kwargs=dict(run=run))
    p.start()
    p.join()
    run.finish()  # run을 완료로 표시


if __name__ == "__main__":
    main()
W&B는 로깅 순서를 보장할 수 없습니다. 동기화는 스크립트 작성자가 직접 수행해야 합니다.

문제 해결

W&B와 분산 트레이닝을 사용할 때 흔히 겪을 수 있는 문제는 두 가지입니다:
  1. 트레이닝 시작 시 멈춤 - wandb의 멀티프로세싱이 분산 트레이닝의 멀티프로세싱과 간섭하면 wandb 프로세스가 멈출 수 있습니다.
  2. 트레이닝 종료 시 멈춤 - wandb 프로세스가 언제 종료되어야 하는지 알지 못하면 트레이닝 작업이 멈출 수 있습니다. Python 스크립트 끝에서 wandb.Run.finish() API를 호출해 W&B에 run이 종료되었음을 알려주세요. wandb.Run.finish() API는 데이터 업로드를 완료하고 W&B를 종료합니다. W&B는 분산 작업의 안정성을 높이기 위해 wandb service 명령어를 사용할 것을 권장합니다. 앞서 설명한 두 가지 트레이닝 문제는 모두 wandb service를 사용할 수 없는 버전의 W&B SDK에서 흔히 발생합니다.

W&B Service 활성화

사용 중인 W&B SDK 버전에 따라 W&B Service가 기본적으로 이미 활성화되어 있을 수 있습니다.

W&B SDK 0.13.0 이상

W&B SDK 0.13.0 이상 버전에서는 W&B Service가 기본적으로 활성화됩니다.

W&B SDK 0.12.5 이상

W&B SDK 버전 0.12.5 이상에서 W&B Service를 활성화하려면 Python 스크립트를 수정하세요. wandb.require() 방법을 사용하고, 메인 함수 내에 문자열 "service"를 전달하세요:
if __name__ == "__main__":
    main()


def main():
    wandb.require("service")
    # 나머지-스크립트-내용-여기에-작성
최적의 사용 환경을 위해 최신 버전으로 업그레이드하는 것을 권장합니다. W&B SDK 0.12.4 이하 W&B SDK 버전 0.12.4 이하를 사용하는 경우, 대신 멀티스레딩을 사용하려면 WANDB_START_METHOD 환경 변수를 "thread"로 설정하세요.