> ## Documentation Index
> Fetch the complete documentation index at: https://wb-21fd5541-sdk-testing-latest.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> W&B를 사용해 여러 GPU로 분산 트레이닝 실험을 로깅합니다.

# 분산 트레이닝 실험 로깅

분산 트레이닝 실험에서는 여러 머신이나 클라이언트를 병렬로 사용해 모델을 트레이닝합니다. W\&B를 사용하면 분산 트레이닝 실험을 추적할 수 있습니다. 사용 사례에 따라 다음 접근 방식 중 하나로 분산 트레이닝 실험을 추적하세요.

* **단일 프로세스 추적**: W\&B로 rank 0 프로세스(“leader” 또는 “coordinator”라고도 함)를 추적합니다. 이는 [PyTorch Distributed Data Parallel](https://pytorch.org/docs/stable/generated/torch.nn.parallel.DistributedDataParallel.html#torch.nn.parallel.DistributedDataParallel) (DDP) 클래스로 분산 트레이닝 실험을 로깅할 때 흔히 사용하는 방법입니다.
* **여러 프로세스 추적**: 여러 프로세스의 경우 다음 중 하나를 선택할 수 있습니다.
  * 프로세스마다 하나의 run을 사용해 각 프로세스를 개별적으로 추적합니다. 필요하면 W\&B App UI에서 이들을 함께 그룹화할 수 있습니다.
  * 모든 프로세스를 하나의 run으로 추적합니다.

<Tip>
  **동시 연결**

  각 동시 연결은 컴퓨팅, 메모리, 네트워크 리소스를 사용합니다. 메트릭을 정기적으로 로깅하지 않는 유휴 클라이언트 연결도 시스템 메트릭 업데이트를 계속 전송하므로, 차트를 로드할 때 성능이 저하될 수 있습니다.

  W\&B는 워크로드에 맞게 동시 클라이언트 연결의 최대 수를 제한하고, 시간에 따라 리소스 사용량을 모니터링할 것을 권장합니다. W\&B는 **Dedicated Cloud**에서 동시 클라이언트 연결 수 300개를 하드 제한으로 테스트했습니다.

  **Multi-tenant Cloud** 조직에서는 분산 트레이닝용 클라이언트 연결에 일반 트레이닝 run과 동일한 [요청 속도 제한](/ko/models/track/limits#rate-limits)이 적용됩니다. [Teams and Enterprise plans](https://wandb.ai/site/pricing)의 Users는 Free 플랜 사용자보다 더 높은 요청 속도 제한을 받습니다.
</Tip>

<div id="track-a-single-process">
  ## 단일 프로세스 추적
</div>

이 섹션에서는 rank 0 프로세스에서 사용할 수 있는 값과 메트릭을 추적하는 방법을 설명합니다. 이 방법은 단일 프로세스에서만 확인할 수 있는 메트릭만 추적할 때 사용하세요. 일반적인 메트릭으로는 GPU/CPU 사용량, 공유 검증 세트에서의 동작, 그라디언트와 파라미터, 대표 데이터 예제에 대한 loss 값 등이 있습니다.

rank 0 프로세스 내에서 [`wandb.init()`](/ko/models/ref/python/functions/init)으로 W\&B run을 초기화하고, 실험 데이터를 해당 run에 [`wandb.Run.log()`](/ko/models/ref/python/experiments/run/#method-runlog)로 로깅합니다.

다음 [샘플 Python 스크립트 (`log-ddp.py`)](https://github.com/wandb/examples/blob/master/examples/pytorch/pytorch-ddp/log-ddp.py)는 PyTorch DDP를 사용해 단일 머신의 두 GPU에서 메트릭을 추적하는 한 가지 방법을 보여줍니다. [PyTorch DDP](https://pytorch.org/tutorials/intermediate/ddp_tutorial.html)(`torch.nn`의 `DistributedDataParallel`)는 분산 트레이닝에 널리 사용되는 라이브러리입니다. 기본 원칙은 모든 분산 트레이닝 설정에 적용되지만, 구현 방식은 다를 수 있습니다.

Python 스크립트는 다음을 수행합니다:

1. `torch.distributed.launch`로 여러 프로세스를 시작합니다.
2. `--local_rank` 명령줄 인수로 rank를 확인합니다.
3. rank가 0으로 설정된 경우, [`train()`](https://github.com/wandb/examples/blob/master/examples/pytorch/pytorch-ddp/log-ddp.py#L24) 함수에서 조건부로 `wandb`를 로깅하도록 설정합니다.

```python theme={null}
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)
```

단일 프로세스에서 추적한 메트릭을 보여주는 [예시 대시보드](https://wandb.ai/ayush-thakur/DDP/runs/1s56u3hc/system)를 살펴보세요.

대시보드에는 온도와 사용량 등 두 GPU의 시스템 메트릭이 표시됩니다.

<Frame>
  <img src="https://mintcdn.com/wb-21fd5541-sdk-testing-latest/H06KgVKW2CsyczDM/images/track/distributed_training_method1.png?fit=max&auto=format&n=H06KgVKW2CsyczDM&q=85&s=60df69791f11756d5d235ba1107e24a5" alt="GPU 메트릭 대시보드" width="1822" height="733" data-path="images/track/distributed_training_method1.png" />
</Frame>

하지만 에포크와 배치 크기에 따른 손실값은 단일 GPU에서만 로깅되었습니다.

<Frame>
  <img src="https://mintcdn.com/wb-21fd5541-sdk-testing-latest/_BDoNoao0FSZz-dv/images/experiments/loss_function_single_gpu.png?fit=max&auto=format&n=_BDoNoao0FSZz-dv&q=85&s=40a308c85c630fb805edd0114f1faef0" alt="손실 함수 플롯" width="1207" height="391" data-path="images/experiments/loss_function_single_gpu.png" />
</Frame>

<div id="track-multiple-processes">
  ## 여러 프로세스 추적하기
</div>

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

* 각 프로세스마다 run을 생성해 [각 프로세스를 개별적으로 추적](/ko/models/track/log/distributed-training/#track-each-process-separately)합니다.
* [모든 프로세스를 단일 run으로 추적](/ko/models/track/log/distributed-training/#track-all-processes-to-a-single-run)합니다.

<div id="track-each-process-separately">
  ### 각 프로세스를 개별적으로 추적하기
</div>

이 섹션에서는 각 프로세스마다 run을 생성해 각 프로세스를 개별적으로 추적하는 방법을 설명합니다. 각 run 내에서 해당 run에 메트릭, Artifacts 등을 로깅합니다. 모든 프로세스가 정상적으로 종료되도록 트레이닝이 끝나면 `wandb.Run.finish()`를 호출해 run이 완료되었음을 표시하세요.

여러 실험에 걸쳐 run을 추적하다 보면 관리가 어려울 수 있습니다. 이를 완화하려면 W\&B를 초기화할 때(`wandb.init(group='group-name')`) `group` 파라미터에 값을 지정해 어떤 run이 특정 실험에 속하는지 추적하세요. 실험에서 트레이닝 및 평가 W\&B Runs를 추적하는 방법에 대한 자세한 내용은 [Group Runs](/ko/models/runs/grouping/)를 참조하세요.

<Note>
  **개별 프로세스의 메트릭을 추적하려는 경우 이 방식을 사용하세요**. 일반적인 예로는 각 노드의 데이터와 예측(데이터 분포 디버깅용), 그리고 메인 노드 외부의 개별 배치 메트릭이 있습니다. 이 방식은 모든 노드의 시스템 메트릭을 가져오거나 메인 노드에서 사용할 수 있는 요약 통계를 얻기 위해 꼭 필요한 것은 아닙니다.
</Note>

다음 Python 코드 스니펫은 W\&B를 초기화할 때 `group` 파라미터를 설정하는 방법을 보여줍니다:

```python theme={null}
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 완료로 표시
```

여러 프로세스에서 추적한 메트릭의 [예시 대시보드](https://wandb.ai/ayush-thakur/DDP?workspace=user-noahluna)를 보려면 W\&B App UI를 살펴보세요. 왼쪽 사이드바에서 두 개의 W\&B Runs가 함께 그룹화되어 있는 것을 확인할 수 있습니다. 그룹을 클릭하면 해당 실험의 전용 그룹 페이지를 볼 수 있습니다. 이 전용 그룹 페이지에는 각 프로세스의 메트릭이 개별적으로 표시됩니다.

<Frame>
  <img src="https://mintcdn.com/wb-21fd5541-sdk-testing-latest/_BDoNoao0FSZz-dv/images/experiments/dashboard_grouped_runs.png?fit=max&auto=format&n=_BDoNoao0FSZz-dv&q=85&s=b55e3f86eb95fec14a74e3c39da1dfd1" alt="그룹화된 분산 run" width="3730" height="1722" data-path="images/experiments/dashboard_grouped_runs.png" />
</Frame>

위 이미지는 W\&B App UI 대시보드를 보여줍니다. 사이드바에는 두 개의 실험이 있습니다. 하나는 'null'로 표시되고, 다른 하나는(노란색 상자로 강조된) 'DPP'입니다. 그룹을 확장하면(Group 드롭다운을 선택) 해당 실험에 연결된 W\&B Runs를 볼 수 있습니다.

<div id="organize-distributed-runs">
  ### 분산 run 정리
</div>

노드를 역할에 따라 분류하려면 W\&B를 초기화할 때 `job_type` 파라미터를 설정하세요(`wandb.init(job_type='type-name')`). 예를 들어, 메인 조정 노드 하나와 리포팅 워커 노드 여러 개가 있을 수 있습니다. 메인 조정 노드에는 `job_type`을 `main`으로, 리포팅 워커 노드에는 `worker`로 설정할 수 있습니다:

```python theme={null}
   # 메인 조정 노드
   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`을 설정한 후에는 워크스페이스에서 [저장된 뷰](/ko/models/track/workspaces/#create-a-new-saved-workspace-view)를 만들어 run을 정리할 수 있습니다. 오른쪽 상단의 **action (<Icon icon="ellipsis" iconType="solid" />)** 메뉴를 클릭한 다음 **Save as new view**를 클릭합니다.

예를 들어, 다음과 같은 저장된 뷰를 만들 수 있습니다:

* **기본 뷰**: 워커 노드를 필터링해 노이즈 줄이기
  * **Filter**를 클릭한 다음 **Job Type**을 `worker`로 설정합니다.

  * 리포팅 노드만 표시합니다

  * **디버그 뷰**: 문제 해결을 위해 워커 노드에 집중
    * **Filter**를 클릭한 다음 **Job Type**을 `==` `worker`로 설정하고 **State**를 `IN` `crashed`로 설정합니다.
    * 비정상 종료되었거나 오류 상태인 워커 노드만 표시합니다

  * **모든 노드 뷰**: 전체 노드를 함께 보기
    * 필터 없음
    * 전체적인 모니터링에 유용합니다

저장된 뷰를 열려면 프로젝트 사이드바에서 **Workspaces**를 클릭한 다음 메뉴를 클릭합니다. Workspaces는 목록 상단에 표시되고 저장된 뷰는 하단에 표시됩니다.

<div id="track-all-processes-to-a-single-run">
  ### 모든 프로세스를 단일 run에 추적하기
</div>

<Warning>
  `x_` 접두사가 붙은 파라미터(`x_label` 등)는 공개 프리뷰 상태입니다. 피드백을 제공하려면 [W\&B 저장소에 GitHub issue](https://github.com/wandb/wandb)를 생성하세요.
</Warning>

<Note>
  **Requirements**

  여러 프로세스를 단일 run에 추적하려면 다음이 필요합니다.

  * W\&B Python SDK `v0.19.9` 이상

  * W\&B Server v0.68 이상
</Note>

이 방식에서는 기본 노드 하나와 하나 이상의 워커 노드를 사용합니다. 기본 노드에서 W\&B run을 초기화합니다. 각 워커 노드에서는 기본 노드가 사용한 run ID를 사용해 run을 초기화합니다. 트레이닝 중에는 각 워커 노드가 기본 노드와 동일한 run ID에 로깅합니다. W\&B는 모든 노드의 메트릭을 집계해 W\&B App UI에 표시합니다.

기본 노드에서는 [`wandb.init()`](/ko/models/ref/python/functions/init)으로 W\&B run을 초기화합니다. `settings` 파라미터에 `wandb.Settings` 객체를 전달하고(`wandb.init(settings=wandb.Settings()`) 다음을 설정합니다.

1. 공유 모드를 활성화하려면 `mode` 파라미터를 `"shared"`로 설정합니다.
2. [`x_label`](https://github.com/wandb/wandb/blob/main/wandb/sdk/wandb_settings.py#L638)에 고유한 레이블을 지정합니다. `x_label`에 지정한 값은 W\&B App UI의 로깅과 시스템 메트릭에서 데이터가 어느 노드에서 왔는지 파악하는 데 사용됩니다. 지정하지 않으면 W\&B가 호스트 이름과 임의의 해시를 사용해 레이블을 생성합니다.
3. 이 노드가 기본 노드임을 나타내려면 [`x_primary`](https://github.com/wandb/wandb/blob/main/wandb/sdk/wandb_settings.py#L660) 파라미터를 `True`로 설정합니다.
4. 선택적으로 GPU 인덱스 목록(\[0,1,2])을 `x_stats_gpu_device_ids`에 전달해 W\&B가 메트릭을 추적할 GPU를 지정할 수 있습니다. 목록을 제공하지 않으면 W\&B는 머신의 모든 GPU에 대한 메트릭을 추적합니다.

기본 노드의 run ID를 기록해 두세요. 각 워커 노드에는 기본 노드의 run ID가 필요합니다.

<Note>
  `x_primary=True`는 기본 노드와 워커 노드를 구분합니다. 기본 노드만 설정 파일, 텔레메트리 등 노드 간에 공유되는 파일을 업로드합니다. 워커 노드는 이러한 파일을 업로드하지 않습니다.
</Note>

각 워커 노드에서는 [`wandb.init()`](/ko/models/ref/python/functions/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_state`](https://github.com/wandb/wandb/blob/main/wandb/sdk/wandb_settings.py#L772)를 `False`로 설정합니다. 이렇게 하면 기본 노드가 아닌 노드가 [run 상태](/ko/models/runs/run-states#run-states)를 너무 일찍 `finished`로 업데이트하는 것을 방지하여, run 상태가 일관되게 유지되고 기본 노드에서 관리되도록 할 수 있습니다.

<Note>
  * 모든 노드에서 동일한 entity와 프로젝트를 사용하세요. 이렇게 하면 올바른 run ID를 찾는 데 도움이 됩니다.
  * 각 워커 노드에서 기본 노드의 run ID를 설정하는 환경 변수를 정의하는 것도 좋습니다.
</Note>

다음 샘플 코드는 여러 프로세스를 단일 run에 추적하기 위한 상위 수준 요구 사항을 보여줍니다.

```python theme={null}
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,
)
```

실제 환경의 예에서는 각 워커 노드가 서로 다른 머신에 있을 수 있습니다.

<Note>
  GKE의 멀티노드 및 멀티 GPU Kubernetes 클러스터에서 모델을 트레이닝하는 방법에 대한 엔드 투 엔드 예시는 [Distributed Training with Shared Mode](https://wandb.ai/dimaduev/simple-cnn-ddp/reports/Distributed-Training-with-Shared-Mode--VmlldzoxMTI0NTE1NA) report를 참조하세요.
</Note>

run이 로깅하는 프로젝트에서 멀티노드 프로세스의 콘솔 로그를 보려면 다음과 같이 하세요:

1. run이 포함된 프로젝트로 이동합니다.
2. 프로젝트 사이드바에서 **Runs** 탭을 클릭합니다.
3. 보려는 run을 클릭합니다.
4. 프로젝트 사이드바에서 **Logs** 탭을 클릭합니다.

콘솔 로그 페이지 상단의 UI 검색 표시줄에서 `x_label`에 지정한 레이블을 기준으로 콘솔 로그를 필터링할 수 있습니다. 예를 들어, 다음 이미지는 `rank0`, `rank1`, `rank2`, `rank3`, `rank4`, `rank5`, `rank6` 값을 `x_label`에 제공한 경우 콘솔 로그를 필터링할 때 사용할 수 있는 옵션을 보여줍니다.

<Frame>
  <img src="https://mintcdn.com/wb-21fd5541-sdk-testing-latest/BwrnEjaj-2zjRpjo/images/track/multi_node_console_logs.png?fit=max&auto=format&n=BwrnEjaj-2zjRpjo&q=85&s=12974c0c3a94fb9658b4f577fa3dd3ef" alt="멀티노드 콘솔 로그" width="3446" height="1976" data-path="images/track/multi_node_console_logs.png" />
</Frame>

자세한 내용은 [Console logs](/ko/models/app/console-logs/)를 참조하세요.

W\&B는 모든 노드의 시스템 메트릭을 집계해 W\&B App UI에 표시합니다. 예를 들어, 다음 이미지는 여러 노드의 시스템 메트릭이 포함된 샘플 대시보드를 보여줍니다. 각 노드에는 `x_label` 매개변수로 지정한 고유한 레이블(`rank_0`, `rank_1`, `rank_2`)이 있습니다.

<Frame>
  <img src="https://mintcdn.com/wb-21fd5541-sdk-testing-latest/BwrnEjaj-2zjRpjo/images/track/multi_node_system_metrics.png?fit=max&auto=format&n=BwrnEjaj-2zjRpjo&q=85&s=fb16c5d22253ec665c5a65ae0bba077b" alt="멀티노드 시스템 메트릭" width="2450" height="1972" data-path="images/track/multi_node_system_metrics.png" />
</Frame>

선형 플롯 패널을 사용자 지정하는 방법은 [Line plots](/ko/models/app/features/panels/line-plot/)를 참조하세요.

<div id="example-use-cases">
  ## 사용 사례 예시
</div>

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

<div id="spawn-process">
  ### 프로세스 생성
</div>

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

```python theme={null}
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()
```

<div id="share-a-run">
  ### run 공유하기
</div>

프로세스 간에 run을 공유하려면 run 객체를 인수로 전달합니다:

```python theme={null}
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는 로깅 순서를 보장할 수 없습니다. 동기화는 스크립트 작성자가 직접 수행해야 합니다.

<div id="troubleshooting">
  ## 문제 해결
</div>

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에서 흔히 발생합니다.

<div id="enable-wb-service">
  ### W\&B Service 활성화
</div>

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

<div id="wb-sdk-0130-and-above">
  #### W\&B SDK 0.13.0 이상
</div>

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

<div id="wb-sdk-0125-and-above">
  #### W\&B SDK 0.12.5 이상
</div>

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

```python theme={null}
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"`로 설정하세요.
