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

# table 로깅하기

> Python SDK를 사용하여 immutable, mutable, incremental 등 다양한 로깅 모드로 W&B Tables를 생성하고 로깅합니다.

W\&B Tables로 표 형식 데이터를 시각화하고 로깅하세요. W\&B Table은 각 열에 한 가지 유형의 데이터만 담기는 2차원 데이터 그리드입니다. 각 행은 W\&B [run](/ko/products/wandb/runs)에 로깅된 하나 이상의 데이터 포인트를 나타냅니다. W\&B Tables는 기본 유형과 숫자 유형뿐 아니라 중첩된 목록, 딕셔너리, 리치 미디어 유형도 지원합니다.

W\&B Table은 W\&B의 특수한 [데이터 유형](/ko/products/wandb/ref/python/data-types)으로, [아티팩트](/ko/products/wandb/artifacts) 객체로 로깅됩니다.

[table 객체는 W\&B Python SDK로 생성하고 로깅](#create-and-log-a-new-table)합니다. table 객체를 생성할 때는 table의 열과 데이터, 그리고 [모드](#table-logging-modes)를 지정합니다. 모드에 따라 ML 실험 중에 table이 로깅되고 업데이트되는 방식이 달라집니다.

<Note>
  `INCREMENTAL` 모드는 W\&B Server v0.70.0 이상에서 지원됩니다.
</Note>

<h2 id="create-and-log-a-table">
  table 생성 및 로깅하기
</h2>

1. `wandb.init()`으로 새 run을 초기화하세요.
2. [`wandb.Table`](/ko/products/wandb/ref/python/data-types/table) 클래스로 table 객체를 생성하세요. table의 열과 데이터는 각각 `columns` 및 `data` 매개변수에 지정하세요. 선택 매개변수인 `log_mode`는 `IMMUTABLE`(기본값), `MUTABLE`, `INCREMENTAL` 세 가지 모드 중 하나로 설정하는 것이 좋습니다. 자세한 내용은 다음 섹션의 [table 로깅 모드](#logging-modes)를 참조하세요.
3. `run.log()`로 table을 W\&B에 로깅하세요.

다음 예시는 `a`와 `b` 두 개의 열과 `["a1", "b1"]`, `["a2", "b2"]` 두 개의 데이터 행으로 구성된 table을 생성하고 로깅하는 방법을 보여줍니다.

```python theme={"system"}
import wandb

# 새 run 시작
with wandb.init(project="table-demo") as run:

    # 열 2개와 데이터 행 2개로 구성된 table 객체 생성
    my_table = wandb.Table(
        columns=["a", "b"],
        data=[["a1", "b1"], ["a2", "b2"]],
        log_mode="IMMUTABLE"
        )

    # W&B에 table 로깅
    run.log({"Table Name": my_table})
```

<h2 id="logging-modes">
  로깅 모드
</h2>

[`wandb.Table`](/ko/products/wandb/ref/python/data-types/table)의 `log_mode` 매개변수는 ML 실험 중에 table을 로깅하고 업데이트하는 방식을 결정합니다. `log_mode` 매개변수에는 `IMMUTABLE`, `MUTABLE`, `INCREMENTAL` 세 가지 인수 중 하나를 지정할 수 있습니다. 모드에 따라 table을 로깅하는 방식, table을 수정할 수 있는 방식, W\&B App에서 table이 렌더링되는 방식이 달라집니다.

다음 표에서는 세 가지 로깅 모드와 모드 간의 주요 차이, 그리고 각 모드의 일반적인 사용 사례를 설명합니다.

| 모드 | 정의 | 사용 사례 | 이점 |
| - | - | - | - |
| `IMMUTABLE` | table을 W\&B에 로깅한 후에는 수정할 수 없습니다. | - run 종료 시 생성된 표 형식 데이터를 저장하여 추가로 분석 | - run 종료 시 로깅하면 오버헤드가 최소화됨<br />- UI에 모든 행이 렌더링됨 |
| `MUTABLE` | table을 W\&B에 로깅한 후 기존 table을 새 table로 덮어쓸 수 있습니다. | - 기존 table에 열 또는 행 추가<br />- 새로운 정보로 결과 보강 | - Table 변경 사항 캡처<br />- UI에 모든 행이 렌더링됨 |
| `INCREMENTAL` | 머신러닝 실험 전반에 걸쳐 새 행을 배치 단위로 table에 추가합니다. | - 배치 단위로 table에 행 추가<br /> - 장시간 실행되는 트레이닝 작업<br />- 대규모 데이터셋을 배치 단위로 처리<br />- 진행 중인 결과 모니터링 | - 트레이닝 중 UI에서 업데이트 확인<br />- 증분별로 단계적으로 탐색 가능 |

다음 섹션에서는 각 모드의 예시 코드 스니펫과 함께 모드별로 어떤 상황에서 사용하면 좋은지에 대한 고려 사항을 설명합니다.

<h3 id="mutable-mode">
  MUTABLE 모드
</h3>

`MUTABLE` 모드는 기존 table을 새 table로 교체하는 방식으로 업데이트합니다. 반복적이지 않은 프로세스에서 기존 table에 새 열과 행을 추가하려는 경우에 유용합니다. UI에서는 처음 로깅한 후에 추가된 열과 행까지 포함하여 모든 행과 열이 table에 렌더링됩니다.

<Note>
  `MUTABLE` 모드에서는 table을 로깅할 때마다 table 객체가 교체됩니다. table을 새 table로 덮어쓰는 작업은 계산 비용이 크므로, table이 크면 속도가 느려질 수 있습니다.
</Note>

다음 예시는 `MUTABLE` 모드로 table을 생성하고 로깅한 다음 새 열을 추가하는 방법을 보여줍니다. table 객체는 초기 데이터, 신뢰도 점수, 최종 예측을 각각 한 번씩 포함하여 총 세 번 로깅됩니다.

<Note>
  다음 예시에서는 데이터를 로드하는 플레이스홀더 함수 `load_eval_data()`와 예측을 수행하는 플레이스홀더 함수 `model.predict()`를 사용합니다. 이 함수들을 직접 작성한 데이터 로드 함수와 예측 함수로 바꾸세요.
</Note>

```python theme={"system"}
import wandb
import numpy as np

with wandb.init(project="mutable-table-demo") as run:

    # MUTABLE 로깅 모드로 table 객체 생성
    table = wandb.Table(columns=["input", "label", "prediction"],
                        log_mode="MUTABLE")

    # 데이터 로드 및 예측 수행
    inputs, labels = load_eval_data() # 플레이스홀더 함수
    raw_preds = model.predict(inputs) # 플레이스홀더 함수

    for inp, label, pred in zip(inputs, labels, raw_preds):
        table.add_data(inp, label, pred)

    # 1단계: 초기 데이터 로깅 
    run.log({"eval_table": table})  # 초기 table 로깅

    # 2단계: 신뢰도 점수 추가 (예: softmax 최댓값)
    confidences = np.max(raw_preds, axis=1)
    table.add_column("confidence", confidences)
    run.log({"eval_table": table})  # 신뢰도 정보 추가

    # 3단계: 후처리한 예측 추가
    # (예: 임계값을 적용하거나 평활화한 출력)
    post_preds = (confidences > 0.7).astype(int)
    table.add_column("final_prediction", post_preds)
    run.log({"eval_table": table})  # 열을 하나 더 추가하여 최종 업데이트
```

트레이닝 루프에서처럼 열은 추가하지 않고 새로운 행 배치만 점진적으로 추가하려면 [`INCREMENTAL` 모드](#INCREMENTAL-mode)를 사용하는 것이 좋습니다.

<h3 id="incremental-mode">
  INCREMENTAL 모드
</h3>

증분 모드에서는 머신러닝 실험 중에 행을 배치 단위로 table에 로깅합니다. 이 방식은 장시간 실행되는 작업을 모니터링할 때나, run 중에 업데이트할 때마다 로깅하기에는 비효율적인 대용량 table을 다룰 때 적합합니다. UI에서는 새 행이 로깅될 때마다 table이 업데이트되므로, run 전체가 종료될 때까지 기다리지 않고도 최신 데이터를 확인할 수 있습니다. 또한 증분을 하나씩 넘겨 가며 시점별 table을 확인할 수도 있습니다.

<Note>
  W\&B App의 run 워크스페이스에서는 증분을 최대 100개까지 표시할 수 있습니다. 100개를 초과하는 증분을 로깅하면 run 워크스페이스에는 가장 최근 100개만 표시됩니다.
</Note>

다음 예시에서는 `INCREMENTAL` 모드로 table을 생성하고 로깅한 다음, 새 행을 추가합니다. table은 트레이닝 step(`step`)마다 한 번씩 로깅됩니다.

<Note>
  다음 예시에서는 데이터를 로드하는 플레이스홀더 함수 `get_training_batch()`, 모델을 트레이닝하는 플레이스홀더 함수 `train_model_on_batch()`, 예측을 수행하는 플레이스홀더 함수 `predict_on_batch()`를 사용합니다. 이 함수들은 직접 작성한 데이터 로드, 트레이닝, 예측 함수로 바꿔서 사용하세요.
</Note>

```python theme={"system"}
import wandb

with wandb.init(project="incremental-table-demo") as run:

    # INCREMENTAL 로깅 모드로 table 생성
    table = wandb.Table(columns=["step", "input", "label", "prediction"],
                        log_mode="INCREMENTAL")

    # 트레이닝 루프
    for step in range(get_num_batches()): # 플레이스홀더 함수
        # 배치 데이터 로드
        inputs, labels = get_training_batch(step) # 플레이스홀더 함수

        # 트레이닝 및 예측 수행
        train_model_on_batch(inputs, labels) # 플레이스홀더 함수
        predictions = predict_on_batch(inputs) # 플레이스홀더 함수

        # table에 배치 데이터 추가
        for input_item, label, prediction in zip(inputs, labels, predictions):
            table.add_data(step, input_item, label, prediction)

        # table을 증분 방식으로 로깅
        run.log({"training_table": table}, step=step)
```

증분 로깅은 일반적으로 매번 새 table을 로깅하는 방식(`log_mode=MUTABLE`)보다 계산 효율이 높습니다. 하지만 증분을 많이 로깅하면 W\&B App에서 table의 모든 행을 렌더링하지 못할 수 있습니다. run이 진행되는 동안 table 데이터를 업데이트하고 확인하면서 모든 데이터를 분석에도 활용하려면 table 두 개를 사용하는 방법을 고려하세요. 하나는 `INCREMENTAL` 로그 모드로, 다른 하나는 `IMMUTABLE` 로그 모드로 로깅합니다.

다음 예시는 `INCREMENTAL`과 `IMMUTABLE` 로깅 모드를 함께 사용해 이를 구현하는 방법을 보여줍니다.

```python theme={"system"}
import wandb

with wandb.init(project="combined-logging-example") as run:

    # 트레이닝 중 효율적으로 업데이트할 수 있도록 증분 table 생성
    incr_table = wandb.Table(columns=["step", "input", "prediction", "label"],
                            log_mode="INCREMENTAL")

    # 트레이닝 루프
    for step in range(get_num_batches()):
        # 배치 처리
        inputs, labels = get_training_batch(step)
        predictions = model.predict(inputs)

        # 증분 table에 데이터 추가
        for inp, pred, label in zip(inputs, predictions, labels):
            incr_table.add_data(step, inp, pred, label)

        # 증분 업데이트 로깅 (최종 table과 구분할 수 있도록 -incr 접미사를 붙임)
        run.log({"table-incr": incr_table}, step=step)

    # 트레이닝이 끝나면 전체 데이터를 담은 불변 table 생성
    # 전체 데이터셋을 보존하도록 기본값인 IMMUTABLE 모드 사용
    final_table = wandb.Table(columns=incr_table.columns, data=incr_table.data, log_mode="IMMUTABLE")
    run.log({"table": final_table})
```

이 예제에서는 트레이닝 중에 `incr_table`을 증분 방식(`log_mode="INCREMENTAL"`)으로 로깅합니다. 이렇게 하면 새 데이터가 처리될 때마다 table의 업데이트를 로깅하고 확인할 수 있습니다. 트레이닝이 끝나면 증분 table의 모든 데이터를 담은 불변 table(`final_table`)이 생성됩니다. 이 불변 table을 로깅하면 추가 분석에 필요한 전체 데이터셋을 보존할 수 있으며, W\&B App에서 모든 행을 확인할 수 있습니다.

<h2 id="examples">
  예시
</h2>

<h3 id="enriching-evaluation-results-with-mutable">
  MUTABLE로 평가 결과 보강하기
</h3>

```python theme={"system"}
import wandb
import numpy as np

with wandb.init(project="mutable-logging") as run:

    # 1단계: 초기 예측 로깅
    table = wandb.Table(columns=["input", "label", "prediction"], log_mode="MUTABLE")
    inputs, labels = load_eval_data()
    raw_preds = model.predict(inputs)

    for inp, label, pred in zip(inputs, labels, raw_preds):
        table.add_data(inp, label, pred)

    run.log({"eval_table": table})  # 원시 예측 로깅

    # 2단계: 신뢰도 점수 추가(예: softmax 최댓값)
    confidences = np.max(raw_preds, axis=1)
    table.add_column("confidence", confidences)
    run.log({"eval_table": table})  # 신뢰도 정보 추가

    # 3단계: 후처리한 예측 추가
    # (예: 임계값을 적용했거나 평활화한 출력)
    post_preds = (confidences > 0.7).astype(int)
    table.add_column("final_prediction", post_preds)
    run.log({"eval_table": table})
```

<h3 id="resuming-runs-with-incremental-tables">
  INCREMENTAL table을 사용하는 run 재개하기
</h3>

run을 재개할 때 증분 table에 이어서 계속 로깅할 수 있습니다.

```python theme={"system"}
# run을 시작하거나 재개합니다
resumed_run = wandb.init(project="resume-incremental", id="your-run-id", resume="must")

# 증분 table을 생성합니다. 이전에 로깅한 table의 데이터를 다시 채울 필요는 없습니다
# 증분은 기존 Table 아티팩트에 계속 추가됩니다.
table = wandb.Table(columns=["step", "metric"], log_mode="INCREMENTAL")

# 로깅을 이어서 진행합니다
for step in range(resume_step, final_step):
    metric = compute_metric(step)
    table.add_data(step, metric)
    resumed_run.log({"metrics": table}, step=step)

resumed_run.finish()
```

<Note>
  `wandb.Run.define_metric("<table_key>", summary="none")` 또는 `wandb.Run.define_metric("*", summary="none")`로 증분 table에 사용하는 키의 요약을 비활성화하면 증분이 새 table에 로깅됩니다.
</Note>

<h3 id="training-with-incremental-batch-training">
  INCREMENTAL 배치 트레이닝으로 트레이닝하기
</h3>

```python theme={"system"}

with wandb.init(project="batch-training-incremental") as run:

    # 증분 table 생성
    table = wandb.Table(columns=["step", "input", "label", "prediction"], log_mode="INCREMENTAL")

    # 트레이닝 루프 시뮬레이션
    for step in range(get_num_batches()):
        # 배치 데이터 로드
        inputs, labels = get_training_batch(step)

        # 현재 배치로 모델 트레이닝
        train_model_on_batch(inputs, labels)

        # 모델 추론 실행
        predictions = predict_on_batch(inputs)

        # table에 데이터 추가
        for input_item, label, prediction in zip(inputs, labels, predictions):
            table.add_data(step, input_item, label, prediction)

        # table의 현재 상태를 증분 방식으로 로깅
        run.log({"training_table": table}, step=step)
```
