> ## Documentation Index
> Fetch the complete documentation index at: https://docs.wandb.ai/llms.txt
> Use this file to discover all available pages before exploring further.

> Python 코드 스크립트 또는 Jupyter Notebook에 W&B를 추가합니다.

# 코드에 W&B (wandb) 추가하기

이 가이드는 하이퍼파라미터 검색 최적화를 위해 Python 트레이닝 스크립트 또는 노트북에 W\&B를 통합하는 방법에 대한 권장 사항을 안내합니다.

<div id="original-training-script">
  ## 원본 트레이닝 스크립트
</div>

아래와 같이 모델을 트레이닝하는 Python 스크립트가 있다고 가정해 보겠습니다. 목표는 검증 정확도(`val_acc`)를 최대화하는 하이퍼파라미터를 찾는 것입니다.

Python 스크립트에서는 `train_one_epoch`와 `evaluate_one_epoch`라는 두 개의 함수를 정의합니다. `train_one_epoch` 함수는 한 에포크 동안의 트레이닝을 시뮬레이션하고, 트레이닝 정확도와 손실을 반환합니다. `evaluate_one_epoch` 함수는 검증 데이터 세트에서 모델을 평가하는 과정을 시뮬레이션하고, 검증 정확도와 손실을 반환합니다.

학습률(`lr`), batch size(`batch_size`), 에포크 수(`epochs`)와 같은 하이퍼파라미터 값을 포함하는 설정 딕셔너리(`config`)를 정의합니다. 설정 딕셔너리의 값은 트레이닝 과정을 제어합니다.

다음으로 일반적인 트레이닝 루프를 모방하는 `main` 함수를 정의합니다. 각 에포크마다 트레이닝 및 검증 데이터 세트에서 정확도와 손실을 계산합니다.

<Note>
  이 코드는 모의 트레이닝 스크립트입니다. 실제로 모델을 트레이닝하지는 않으며, 무작위 정확도와 손실 값을 생성해 트레이닝 과정을 시뮬레이션합니다. 이 코드의 목적은 트레이닝 스크립트에 W\&B를 통합하는 방법을 보여주는 것입니다.
</Note>

```python theme={null}
import random
import numpy as np

def train_one_epoch(epoch, lr, batch_size):
    acc = 0.25 + ((epoch / 30) + (random.random() / 10))
    loss = 0.2 + (1 - ((epoch - 1) / 10 + random.random() / 5))
    return acc, loss

def evaluate_one_epoch(epoch):
    acc = 0.1 + ((epoch / 20) + (random.random() / 10))
    loss = 0.25 + (1 - ((epoch - 1) / 10 + random.random() / 6))
    return acc, loss

# 하이퍼파라미터 값이 포함된 설정 변수
config = {"lr": 0.0001, "batch_size": 16, "epochs": 5}

def main():
    lr = config["lr"]
    batch_size = config["batch_size"]
    epochs = config["epochs"]

    for epoch in np.arange(1, epochs):
        train_acc, train_loss = train_one_epoch(epoch, lr, batch_size)
        val_acc, val_loss = evaluate_one_epoch(epoch)

        print("epoch: ", epoch)
        print("training accuracy:", train_acc, "training loss:", train_loss)
        print("validation accuracy:", val_acc, "validation loss:", val_loss)

if __name__ == "__main__":
    main()
```

다음 섹션에서는 트레이닝 중 하이퍼파라미터와 메트릭을 추적하기 위해 Python 스크립트에 W\&B를 추가합니다. 검증 정확도(`val_acc`)를 최대화하는 최적의 하이퍼파라미터를 찾는 데 W\&B를 사용합니다.

<div id="add-wb-to-your-training-script">
  ## 트레이닝 스크립트에 W\&B 추가
</div>

트레이닝 스크립트를 업데이트해 W\&B를 포함하세요. W\&B를 Python 스크립트 또는 노트북에 어떻게 통합할지는 Sweeps를 관리하는 방식에 따라 달라집니다.

W\&B Python SDK를 사용해 Sweeps를 시작, 중지, 관리하려면 **Python script or notebook** 탭의 지침을 따르세요. 대신 W\&B CLI를 사용하려면 **CLI** 탭의 지침을 따르세요.

<Tabs>
  <Tab title="CLI">
    sweep 설정이 포함된 YAML 설정 파일을 만드세요. 이
    설정 파일에는 sweep에서 탐색할 하이퍼파라미터가 들어 있습니다. 다음
    예시에서는 배치 크기(`batch_size`), 에포크(`epochs`), 그리고
    학습률(`lr`) 하이퍼파라미터가 각 sweep 실행 중에 변경됩니다.

    ```yaml theme={null}
    # config.yaml
    program: train.py
    method: random
    name: sweep
    metric:
      goal: maximize
      name: val_acc
    parameters:
      batch_size:
        values: [16, 32, 64]
      lr:
        min: 0.0001
        max: 0.1
      epochs:
        values: [5, 10, 15]
    ```

    W\&B Sweep 설정을 만드는 방법에 대한 자세한 내용은 [Sweep 설정 정의](/ko/models/sweeps/define-sweep-configuration/)를 참조하세요.

    YAML 파일의 `program` 키에 Python 스크립트 이름을
    지정해야 합니다.

    다음으로, 코드 예제에 다음 내용을 추가합니다:

    1. W\&B Python SDK(`wandb`)와 PyYAML(`yaml`)을 임포트합니다. PyYAML은 YAML 설정 파일을 읽는 데 사용됩니다.
    2. 설정 파일을 읽어옵니다.
    3. [`wandb.init()`](/ko/models/ref/python/functions/init)을 사용해 데이터를 동기화하고 로그하기 위한 백그라운드 프로세스를 [W\&B Run](/ko/models/ref/python/experiments/run)으로 시작합니다. 설정 객체를 `config` 파라미터에 전달합니다.
    4. 하드코딩된 값을 사용하는 대신 `wandb.Run.config`에서 하이퍼파라미터 값을 정의합니다.
    5. [`wandb.Run.log()`](/ko/models/ref/python/experiments/run.md/#method-runlog)를 사용해 최적화할 메트릭을 로그합니다. 설정에 정의된 메트릭을 반드시 로그해야 합니다. 설정 딕셔너리(이 예제에서는 `sweep_configuration`)에서 `val_acc` 값을 최대화하도록 sweep을 정의합니다.

    ```python theme={null}
    import wandb
    import yaml
    import random
    import numpy as np


    def train_one_epoch(epoch, lr, batch_size):
        acc = 0.25 + ((epoch / 30) + (random.random() / 10))
        loss = 0.2 + (1 - ((epoch - 1) / 10 + random.random() / 5))
        return acc, loss


    def evaluate_one_epoch(epoch):
        acc = 0.1 + ((epoch / 20) + (random.random() / 10))
        loss = 0.25 + (1 - ((epoch - 1) / 10 + random.random() / 6))
        return acc, loss


    def main():
        # 기본 하이퍼파라미터 설정
        with open("./config.yaml") as file:
            config = yaml.load(file, Loader=yaml.FullLoader)

        with wandb.init(config=config) as run:
            for epoch in np.arange(1, run.config['epochs']):
                train_acc, train_loss = train_one_epoch(epoch, run.config['lr'], run.config['batch_size'])
                val_acc, val_loss = evaluate_one_epoch(epoch)
                run.log(
                    {
                        "epoch": epoch,
                        "train_acc": train_acc,
                        "train_loss": train_loss,
                        "val_acc": val_acc,
                        "val_loss": val_loss,
                    }
                )

    # main 함수를 호출합니다.
    main()
    ```

    CLI에서 sweep
    agent가 시도할 최대 run 수를 설정합니다.
    이는 선택 사항입니다. 이 예제에서는 최대
    수를 5로 설정합니다.

    ```bash theme={null}
    NUM=5
    ```

    다음으로, [`wandb sweep`](/ko/models/ref/cli/wandb-sweep) 명령을 사용해 sweep를 초기화합니다. YAML 파일 이름을 지정합니다. 선택적으로 프로젝트 플래그(`--project`)에 사용할 프로젝트 이름을 지정합니다:

    ```bash theme={null}
    wandb sweep --project sweep-demo-cli config.yaml
    ```

    sweep ID가 반환됩니다. sweep를 초기화하는 방법에 대한 자세한 내용은
    [Initialize sweeps](./initialize-sweeps)를 참조하세요.

    sweep 작업을 시작하려면 sweep ID를 복사한 다음 아래 코드 스니펫의 `sweepID`를 바꿔
    [`wandb agent`](/ko/models/ref/cli/wandb-agent)
    명령어를 사용하세요:

    ```bash theme={null}
    wandb agent --count $NUM your-entity/sweep-demo-cli/sweepID
    ```

    자세한 내용은 [sweep 작업 시작하기](./start-sweep-agents)를 참조하세요.
  </Tab>

  <Tab title="Python 스크립트나 노트북">
    다음 단계에 따라 Python 스크립트에 W\&B를 추가하세요:

    1. 키-값 쌍으로 [sweep configuration](/ko/models/sweeps/define-sweep-configuration/)을 정의하는 딕셔너리 객체를 만드세요. sweep configuration은 최적화하려는 metric과 함께 W\&B가 대신 탐색할 하이퍼파라미터를 정의합니다. 앞의 예제에 이어서, 배치 크기(`batch_size`), 에포크(`epochs`), 학습률(`lr`)은 각 sweep에서 변경할 하이퍼파라미터입니다. 검증 score의 accuracy를 최대화하려면 `"goal": "maximize"`로 설정하고, 최적화할 변수의 이름(이 경우 `val_acc`)을 지정합니다(`"name": "val_acc"`).
    2. sweep 설정 딕셔너리를 [`wandb.sweep()`](/ko/models/ref/python/functions/sweep)에 전달합니다. 그러면 sweep이 초기화되고 sweep ID(`sweep_id`)를 반환합니다. 자세한 내용은 [sweep 초기화](./initialize-sweeps)를 참조하세요.
    3. 스크립트 상단에서 W\&B Python SDK(`wandb`)를 임포트하세요.
    4. `main` 함수 내에서 [`wandb.init()`](/ko/models/ref/python/functions/init)을 사용해 데이터를 동기화하고 기록하는 백그라운드 프로세스를 생성하여 [W\&B Run](/ko/models/ref/python/experiments/run)으로 실행하세요. 프로젝트 이름을 `wandb.init()`에 매개변수로 전달하세요. 프로젝트 이름을 전달하지 않으면 W\&B는 기본 프로젝트 이름을 사용합니다.
    5. `wandb.Run.config` 객체에서 하이퍼파라미터 값을 가져옵니다. 그러면 하드코딩된 값 대신 sweep 설정 딕셔너리에 정의된 하이퍼파라미터 값을 사용할 수 있습니다.
    6. [`wandb.Run.log()`](/ko/models/ref/python/experiments/run.md/#method-runlog)을 사용해 최적화할 metric을 W\&B에 기록하세요. 설정에 정의된 metric을 반드시 기록해야 합니다. 예를 들어 최적화할 metric을 `val_acc`로 정의했다면 `val_acc`를 기록해야 합니다. metric을 기록하지 않으면 W\&B는 무엇을 최적화해야 하는지 알 수 없습니다. 설정 딕셔너리(이 예제에서는 `sweep_configuration`)에서 `val_acc` 값을 최대화하도록 sweep을 정의합니다.
    7. [`wandb.agent()`](/ko/models/ref/python/functions/agent)로 sweep을 시작합니다. sweep ID와 sweep이 실행할 함수 이름(`function=main`)을 지정하고, 시도할 최대 run 수를 4로 설정합니다(`count=4`).

    이 모든 내용을 종합하면, 스크립트는 다음과 같은 형태가 됩니다:

    ```python theme={null}
    import wandb # W&B Python SDK 임포트
    import numpy as np
    import random
    import argparse

    def train_one_epoch(epoch, lr, batch_size):
        acc = 0.25 + ((epoch / 30) + (random.random() / 10))
        loss = 0.2 + (1 - ((epoch - 1) / 10 + random.random() / 5))
        return acc, loss

    def evaluate_one_epoch(epoch):
        acc = 0.1 + ((epoch / 20) + (random.random() / 10))
        loss = 0.25 + (1 - ((epoch - 1) / 10 + random.random() / 6))
        return acc, loss

    def main(args=None):
        # sweep agent에 의해 호출될 때 args는 None이므로,
        # sweep 설정의 프로젝트를 사용합니다
        project = args.project if args else None
        
        with wandb.init(project=project) as run:
            # `wandb.Run.config` 객체에서 하이퍼파라미터 값을 가져옵니다
            lr = run.config["lr"]
            batch_size = run.config["batch_size"]
            epochs = run.config["epochs"]

            # 트레이닝 루프를 실행하고 성능 값을 W&B에 기록합니다
            for epoch in np.arange(1, epochs):
                train_acc, train_loss = train_one_epoch(epoch, lr, batch_size)
                val_acc, val_loss = evaluate_one_epoch(epoch)
                run.log(
                    {
                        "epoch": epoch,
                        "train_acc": train_acc,
                        "train_loss": train_loss,
                        "val_acc": val_acc, # 최적화할 메트릭
                        "val_loss": val_loss,
                    }
                )

    if __name__ == "__main__":
        parser = argparse.ArgumentParser()
        parser.add_argument("--project", type=str, default="sweep-example", help="W&B 프로젝트 이름")
        args = parser.parse_args()

        # sweep 설정 딕셔너리 정의
        sweep_configuration = {
            "method": "random",
            "name": "sweep",
            # 최적화할 메트릭
            # 예를 들어, 검증 정확도를 최대화하려면
            # "goal": "maximize"로 설정하고 최적화할 변수의
            # 이름을 지정합니다. 이 경우 "val_acc"
            "metric": {
                "goal": "maximize",
                "name": "val_acc"
                },
            "parameters": {
                "batch_size": {"values": [16, 32, 64]},
                "epochs": {"values": [5, 10, 15]},
                "lr": {"max": 0.1, "min": 0.0001},
            },
        }

        # 설정 딕셔너리를 전달하여 sweep 초기화
        sweep_id = wandb.sweep(sweep=sweep_configuration, project=args.project)

        # sweep 작업 시작
        wandb.agent(sweep_id, function=main, count=4)
    ```
  </Tab>
</Tabs>

<Note>
  **sweep에서 W\&B에 메트릭 로깅하기**

  sweep 설정과 `wandb.Run.log()`에서 모두 정의한, 그리고 최적화 대상으로 지정한 메트릭을 반드시 로깅해야 합니다. 예를 들어 sweep 설정에서 최적화할 메트릭을 `val_acc`로 정의했다면, `val_acc`도 W\&B에 로깅해야 합니다. 메트릭을 로깅하지 않으면 W\&B는 무엇을 최적화해야 하는지 알 수 없습니다.

  ```python theme={null}
  with wandb.init() as run:
      val_loss, val_acc = train()
      run.log(
          {
              "val_loss": val_loss,
              "val_acc": val_acc
              }
          )
  ```

  다음은 메트릭을 W\&B에 로깅하는 올바르지 않은 예입니다. sweep 설정에서 최적화 대상인 메트릭은 `val_acc`이지만, 코드에서는 `validation` 키 아래의 중첩된 딕셔너리 안에 `val_acc`를 로깅하고 있습니다. 메트릭은 중첩된 딕셔너리 안이 아니라 직접 로깅해야 합니다.

  ```python theme={null}
  with wandb.init() as run:
      val_loss, val_acc = train()
      run.log(
          {
              "validation": {
                  "val_loss": val_loss, 
                  "val_acc": val_acc
                  }
              }
          )
  ```
</Note>
