> ## 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.

# 데이터셋 업로드

> 이미 보유한 JSONL 파일을 Management API로 업로드하여 데이터셋을 생성합니다.

트레이닝 예시가 이미 프로젝트 외부에 있다면 [inference proxy](/ko/model-distillation/proxy/overview)로 트래픽을 기록하는 대신 JSONL 파일로 업로드하세요. Model Distillation은 파일을 검증하고 트레이닝 및 검증 분할을 부여한 뒤 데이터셋을 생성합니다. 이 데이터셋은 다른 데이터셋과 마찬가지로 재레이블링, 파인튜닝, 평가에 사용할 수 있습니다.

업로드는 Management API를 통해서만 할 수 있습니다. UI에는 생성된 데이터셋과 데이터셋 설정의 **Uploaded source** 패널이 표시되지만, 파일 선택기는 제공되지 않습니다.

이 페이지에서는 업로드 진행 과정, 파일 준비 방법, 파일을 여러 부분으로 나누어 업로드하는 방법, 검증 결과를 확인하는 방법을 설명합니다.

<h2 id="prerequisites">
  사전 요구 사항
</h2>

시작하기 전에 다음 항목이 준비되어 있는지 확인하세요.

* Model Distillation에 액세스할 수 있는 팀의 W\&B API 키. 예시에서는 `WANDB_API_KEY` 환경 변수에서 이 키를 읽어 `Authorization` 헤더로 전달하고, `Wandb-Entity` 헤더에 entity 이름을 지정합니다.
* 해당 팀의 프로젝트. 프로젝트 별칭은 모든 요청 경로에 포함됩니다. 프로젝트를 만들려면 [퀵스타트](/ko/model-distillation/quickstart)를 참조하세요.
* [파일 업로드](#upload-the-file)에서 사용할 탭에 맞는 도구. 다음 구성 중 하나만 있으면 됩니다.
  * `curl`, `jq`, `split`
  * `requests` 패키지가 설치된 Python 3.9 이상
  * Node.js 18 이상(추가 패키지 불필요)

<h2 id="how-an-upload-works">
  업로드 작동 방식
</h2>

업로드는 프로젝트 범위의 *임포트 세션*입니다. 세션 하나에는 JSONL 파일이 정확히 하나만 포함되며, 이 파일을 여러 파트로 나누어 오브젝트 스토리지에 직접 전송합니다. 세션은 다음 상태를 거칩니다.

| 상태 | 의미 |
| - | - |
| `uploading` | 세션이 파트 업로드를 받을 수 있습니다. |
| `queued`, `validating`, `auditing`, `committing` | 업로드가 완료되었습니다. Model Distillation이 행을 파싱하고 분할과 중복을 확인한 다음 데이터셋을 작성합니다. |
| `ready` | 데이터셋이 생성되었습니다. 데이터셋 ID는 `dataset_id`에서 확인할 수 있습니다. |
| `failed` | 검증 또는 데이터셋 생성에 실패했습니다. `error`에서 실패 원인을 확인할 수 있으며, `validation.errors`에는 행 수준의 문제가 나열됩니다. |
| `cancelled` | 세션이 `ready`에 도달하기 전에 삭제되었습니다. |
| `expired` | 세션이 완료되지 않은 채 7일 동안 `uploading` 상태로 남아 있었습니다. |

생성 후 7일이 지나도 `uploading` 상태인 세션은 만료됩니다. 만료된 세션에 대한 파트 요청과 완료 요청은 `410 Gone`을 반환하며, 매시간 실행되는 작업이 세션을 `expired`로 전환하고 파트를 폐기합니다. 업로드된 오브젝트와 완료되지 않은 멀티파트 업로드는 세션 완료 여부와 관계없이 작성 후 8일이 지나면 삭제됩니다.

entity는 `Wandb-Entity` 헤더에 지정된 팀 또는 개인 계정입니다. 각 entity는 세션을 동시에 두 개까지 진행할 수 있으며, 진행 중인 세션들의 선언된 파일 크기 합계는 최대 2 GiB입니다. 세션은 생성 시점부터 `ready`, `failed`, `cancelled`, `expired` 중 하나에 도달할 때까지 두 한도 모두에 포함됩니다. 두 한도 중 하나라도 초과하는 요청은 `429 Too Many Requests`를 반환합니다. 용량을 확보하려면 더 이상 필요 없는 세션을 취소하거나 실행 중인 세션이 끝날 때까지 기다리세요.

<h2 id="prepare-the-file">
  파일 준비
</h2>

임포트 세션을 생성하기 전에 파일이 행 형식에 맞는지, 그리고 이 섹션에 설명된 제한을 넘지 않는지 확인하세요. 검증은 업로드를 완료한 후에만 실행되며, 실패한 세션은 다시 열 수 없습니다. 형식 문제를 해결하려면 새 세션을 생성하고 파일을 다시 업로드하세요.

파일은 UTF-8 JSONL 형식이어야 합니다. 즉, 한 줄에 JSON 객체가 하나씩 있어야 하며, 한 객체 안에 중복된 키가 없어야 합니다.

<h3 id="row-format">
  행 형식
</h3>

각 행은 OpenAI Chat Completions 요청이며, 마지막 메시지는 학습 목표로 삼을 assistant 응답입니다. Model Distillation은 앞선 메시지와 `tools`, `tool_choice`, `response_format`(있는 경우)을 입력으로 저장하고, 마지막 assistant 메시지를 출력으로 저장합니다.

```json theme={"system"}
{"messages":[{"role":"system","content":"Classify the ticket."},{"role":"user","content":"My invoice is wrong."},{"role":"assistant","content":"billing"}],"row_id":"ticket-1042"}
```

각 행에는 최소 2개에서 최대 1,000개의 메시지가 포함되어야 합니다. `tools`에는 함수 도구를 최대 128개까지, JSON을 최대 1MiB까지 지정할 수 있습니다. 마지막 메시지가 assistant 메시지가 아닌 행은 `missing_assistant_target` 오류로 실패합니다.

<h3 id="optional-fields">
  선택 필드
</h3>

각 행에는 다음 선택 필드를 포함할 수 있습니다.

| 필드 | 용도 |
| - | - |
| `row_id` | 최대 512자의 고정 식별자입니다. 파일 내에서 고유해야 합니다. 지정하지 않으면 줄 번호로 행을 식별합니다. |
| `group_id` | 관련된 행들이 같은 분할에 속하도록 묶으며, 최대 512자입니다. 기본값은 행 ID입니다. |
| `split` | `train` 또는 `val`입니다. `split_policy.mode`가 `preserve`이면 모든 행에 필수이고, 모드가 `automatic`이면 무시됩니다. |
| `metadata` | 최대 64KiB, 중첩 깊이 최대 10단계의 임의 JSON입니다. |
| `provenance` | 행의 출처를 기록하는 임의 JSON이며, `metadata`와 동일한 제한이 적용됩니다. |

행에는 이 외의 최상위 필드를 포함할 수 없습니다.

<h3 id="limits">
  제한
</h3>

파일과 임포트 세션은 다음 제한을 넘지 않아야 합니다.

| 제한 | 값 |
| - | - |
| 파일 크기 | 1 GiB |
| 파일당 행 수 | 100,000 |
| 행 크기 | 10 MiB |
| JSON 중첩 | 64단계 |
| 파트 크기 | 32 MiB(서버에서 고정) |
| entity당 진행 중인 세션 수 | 2 |
| entity당 진행 중인 세션의 총 `size_bytes` | 2 GiB |

<h2 id="upload-the-file">
  파일 업로드
</h2>

업로드는 세션 생성, 파일 분할 업로드, 업로드 완료, 데이터셋이 준비될 때까지 폴링의 단계로 진행됩니다. 다음 탭에서는 전체 플로우를 하나의 스크립트로 `curl`, Python, JavaScript 버전별로 보여 줍니다. 번호가 매겨진 주석으로 각 단계를 표시했으며, 각 단계에 대한 설명은 [스크립트 작동 방식](#how-the-script-works)을 참조하세요.

스크립트에서는 프로젝트 별칭으로 `ticket-classifier`를, 파일 이름으로 `tickets.jsonl`을 사용합니다. 스크립트를 실행하기 전에 entity, 별칭, 파일 이름을 자신의 값으로 바꾸고, 환경 변수 `WANDB_API_KEY`를 설정하세요. 서로 다른 업로드마다 새로운 `idempotency_key`를 사용하세요.

<Tabs>
  <Tab title="curl">
    ```bash theme={"system"}
    #!/usr/bin/env bash
    # curl, jq, split이 필요합니다.
    set -euo pipefail

    API="https://distillation.training.wandb.ai/v1/tasks/ticket-classifier"
    ENTITY="your-team"
    FILE="tickets.jsonl"
    auth=(--header "Authorization: Bearer $WANDB_API_KEY" --header "Wandb-Entity: $ENTITY")

    # 1. 임포트 세션을 생성합니다.
    size=$(wc -c < "$FILE" | tr -d ' ')
    curl --silent --fail --request POST --url "$API/dataset-imports" "${auth[@]}" \
      --header "Content-Type: application/json" \
      --data "$(jq -n --arg name "$FILE" --argjson size "$size" '{
        idempotency_key: "support-tickets-v1",
        name: "Support tickets (uploaded)",
        file: { name: $name, size_bytes: $size },
        split_policy: { mode: "automatic", val_fraction: 0.1 },
        duplicate_policy: { split_overlap: "drop_train" }
      }')" --output session.json
    import_id=$(jq -r '.id' session.json)
    part_size=$(jq -r '.file.part_size_bytes' session.json)
    part_count=$(jq -r '.file.part_count' session.json)

    # 2. 각 파트의 서명된 업로드 URL을 요청합니다.
    curl --silent --fail --request POST --url "$API/dataset-imports/$import_id/parts" "${auth[@]}" \
      --header "Content-Type: application/json" \
      --data "$(jq -n --argjson count "$part_count" '{ part_numbers: [range(1; $count + 1)] }')" \
      --output urls.json

    # 3. 파트를 업로드합니다. 파트 번호는 1부터 시작합니다. 서명된 URL에는 자체 인증 정보가 포함되어 있습니다.
    split -b "$part_size" -d -a 4 "$FILE" part-
    n=1
    for chunk in part-*; do
      url=$(jq -r --argjson n "$n" '.parts[] | select(.part_number == $n) | .url' urls.json)
      curl --silent --fail --request PUT --upload-file "$chunk" "$url"
      n=$((n + 1))
    done
    rm part-*

    # 4. 선택 사항: 세션을 조회하여 업로드된 파트를 확인합니다.
    curl --silent --fail --url "$API/dataset-imports/$import_id" "${auth[@]}" | jq '.file | {uploaded_bytes, parts}'

    # 5. 업로드를 완료합니다. 그러면 검증 및 데이터셋 생성 작업이 큐에 추가됩니다.
    curl --silent --fail --request POST --url "$API/dataset-imports/$import_id/complete" "${auth[@]}" --output /dev/null

    # 6. 세션이 ready 또는 failed 상태가 될 때까지 폴링합니다.
    while true; do
      curl --silent --fail --url "$API/dataset-imports/$import_id" "${auth[@]}" --output status.json
      case "$(jq -r '.state' status.json)" in
        ready|failed) break ;;
      esac
      sleep 10
    done
    jq '{state, dataset_id, error}' status.json
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={"system"}
    # Python 3.9 이상과 requests 패키지가 필요합니다.
    import os
    import time

    import requests

    API = "https://distillation.training.wandb.ai/v1/tasks/ticket-classifier"
    HEADERS = {
        "Authorization": f"Bearer {os.environ['WANDB_API_KEY']}",
        "Wandb-Entity": "your-team",
    }
    FILE = "tickets.jsonl"

    # 1. 임포트 세션을 생성합니다.
    response = requests.post(
        f"{API}/dataset-imports",
        headers=HEADERS,
        json={
            "idempotency_key": "support-tickets-v1",
            "name": "Support tickets (uploaded)",
            "file": {"name": FILE, "size_bytes": os.path.getsize(FILE)},
            "split_policy": {"mode": "automatic", "val_fraction": 0.1},
            "duplicate_policy": {"split_overlap": "drop_train"},
        },
    )
    response.raise_for_status()
    session = response.json()
    import_id = session["id"]
    part_size = session["file"]["part_size_bytes"]
    part_count = session["file"]["part_count"]

    # 2. 각 파트의 서명된 업로드 URL을 요청합니다.
    response = requests.post(
        f"{API}/dataset-imports/{import_id}/parts",
        headers=HEADERS,
        json={"part_numbers": list(range(1, part_count + 1))},
    )
    response.raise_for_status()
    url_by_part = {part["part_number"]: part["url"] for part in response.json()["parts"]}

    # 3. 파트를 업로드합니다. 파트 번호는 1부터 시작합니다. 서명된 URL에는 자체 인증 정보가 포함되어 있습니다.
    with open(FILE, "rb") as handle:
        for part_number in range(1, part_count + 1):
            chunk = handle.read(part_size)
            requests.put(url_by_part[part_number], data=chunk).raise_for_status()

    # 4. 선택 사항: 세션을 조회하여 어떤 파트가 업로드되었는지 확인합니다.
    progress = requests.get(f"{API}/dataset-imports/{import_id}", headers=HEADERS).json()
    uploaded = {part["part_number"] for part in progress["file"]["parts"]}
    missing = [n for n in range(1, part_count + 1) if n not in uploaded]

    # 5. 업로드를 완료합니다. 그러면 검증 및 데이터셋 생성 작업이 큐에 추가됩니다.
    requests.post(f"{API}/dataset-imports/{import_id}/complete", headers=HEADERS).raise_for_status()

    # 6. 세션이 ready 또는 failed 상태가 될 때까지 폴링합니다.
    while True:
        status = requests.get(f"{API}/dataset-imports/{import_id}", headers=HEADERS).json()
        if status["state"] in ("ready", "failed"):
            break
        time.sleep(10)

    print(status["state"], status["dataset_id"], status["error"])
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={"system"}
    // Node.js 18 이상이 필요합니다. 별도로 설치할 패키지는 없습니다.
    import { open, stat } from "node:fs/promises";

    const API = "https://distillation.training.wandb.ai/v1/tasks/ticket-classifier";
    const HEADERS = {
      Authorization: `Bearer ${process.env.WANDB_API_KEY}`,
      "Wandb-Entity": "your-team",
    };
    const FILE = "tickets.jsonl";

    async function call(path, init = {}) {
      const response = await fetch(`${API}${path}`, { ...init, headers: { ...HEADERS, ...init.headers } });
      if (!response.ok) throw new Error(`${init.method ?? "GET"} ${path} failed: ${await response.text()}`);
      return response.status === 204 ? null : response.json();
    }

    // 1. 임포트 세션을 생성합니다.
    const { size } = await stat(FILE);
    const session = await call("/dataset-imports", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        idempotency_key: "support-tickets-v1",
        name: "Support tickets (uploaded)",
        file: { name: FILE, size_bytes: size },
        split_policy: { mode: "automatic", val_fraction: 0.1 },
        duplicate_policy: { split_overlap: "drop_train" },
      }),
    });
    const importId = session.id;
    const partSize = session.file.part_size_bytes;
    const partCount = session.file.part_count;

    // 2. 모든 파트의 서명된 업로드 URL을 요청합니다.
    const urls = await call(`/dataset-imports/${importId}/parts`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ part_numbers: Array.from({ length: partCount }, (_, i) => i + 1) }),
    });
    const urlByPart = new Map(urls.parts.map((part) => [part.part_number, part.url]));

    // 3. 파트를 업로드합니다. 파트 번호는 1부터 시작합니다. 서명된 URL에는 자체 인증 정보가 포함되어 있습니다.
    const handle = await open(FILE, "r");
    try {
      for (let partNumber = 1; partNumber <= partCount; partNumber++) {
        const offset = (partNumber - 1) * partSize;
        const chunk = Buffer.alloc(Math.min(partSize, size - offset));
        await handle.read(chunk, 0, chunk.length, offset);
        const put = await fetch(urlByPart.get(partNumber), { method: "PUT", body: chunk });
        if (!put.ok) throw new Error(`Part ${partNumber} failed with ${put.status}`);
      }
    } finally {
      await handle.close();
    }

    // 4. 선택 사항: 세션을 조회하여 수신된 파트를 확인합니다.
    const progress = await call(`/dataset-imports/${importId}`);
    const uploaded = new Set(progress.file.parts.map((part) => part.part_number));
    const missing = Array.from({ length: partCount }, (_, i) => i + 1).filter((n) => !uploaded.has(n));

    // 5. 업로드를 완료합니다. 그러면 검증 및 데이터셋 생성 작업이 큐에 추가됩니다.
    await call(`/dataset-imports/${importId}/complete`, { method: "POST" });

    // 6. 세션이 ready 또는 failed 상태가 될 때까지 폴링합니다.
    let status;
    while (true) {
      status = await call(`/dataset-imports/${importId}`);
      if (status.state === "ready" || status.state === "failed") break;
      await new Promise((resolve) => setTimeout(resolve, 10_000));
    }
    console.log(status.state, status.dataset_id, status.error);
    ```
  </Tab>
</Tabs>

<h3 id="how-the-script-works">
  스크립트 작동 방식
</h3>

각 스크립트에서 번호가 매겨진 주석은 다음 단계에 해당합니다.

<Steps>
  <Step title="임포트 세션 생성">
    스크립트는 파일 이름과 정확한 바이트 크기, 분할 정책, 그리고 선택 사항인 중복 정책을 전송합니다. 각 정책의 동작은 [분할 및 중복](#splits-and-duplicates)을 참조하세요. 요청에는 고유한 `idempotency_key`도 필요합니다. 따라서 요청을 재시도하면 세션이 새로 생성되지 않고 기존 세션이 반환됩니다.

    응답은 세션 정보가 포함된 `201 Created`입니다. 스크립트는 응답에서 `id`, `file.part_size_bytes`, `file.part_count`를 저장해 둡니다. 다음은 해당 필드를 보여 주는 응답의 일부입니다.

    ```json theme={"system"}
    {
      "id": "3f9c2d1e-7b4a-4c58-9e21-0d6f8a1b2c3d",
      "state": "uploading",
      "dataset_id": null,
      "total_bytes": 73400320,
      "expires_at": "2026-09-24T18:02:11.000Z",
      "file": {
        "name": "tickets.jsonl",
        "size_bytes": 73400320,
        "part_size_bytes": 33554432,
        "part_count": 3,
        "state": "pending",
        "uploaded_bytes": 0,
        "parts": []
      }
    }
    ```
  </Step>

  <Step title="업로드 URL 요청">
    스크립트는 1부터 `file.part_count`까지 모든 파트 번호에 대해 서명된 URL을 요청합니다. 응답에는 각 `part_number`와 해당 `url`, 그리고 `expires_in_seconds`가 포함됩니다. 각 URL은 15분 동안 유효합니다. URL을 사용하기 전에 만료되었다면 다시 요청하세요.
  </Step>

  <Step title="파트 업로드">
    스크립트는 파일을 `file.part_size_bytes` 크기의 청크 단위로 읽고, 각 청크를 해당 파트 번호의 URL로 `PUT` 요청을 보내 전송합니다. 파트 번호는 1부터 시작하므로 첫 번째 청크가 파트 1입니다. 마지막 파트를 제외한 모든 파트는 크기가 정확히 `file.part_size_bytes`여야 하며, 마지막 파트에는 남은 데이터가 담깁니다. 파트는 순서에 상관없이 병렬로 전송할 수 있습니다.

    서명된 URL에는 자체 인증 정보가 포함되어 있으므로, 스크립트는 이 요청에 `Authorization` 또는 `Wandb-Entity` 헤더를 추가하지 않습니다.
  </Step>

  <Step title="선택: 업로드된 파트 확인">
    전송이 중단된 후 재개하려면 세션을 조회하세요. `file.parts`에는 업로드된 각 파트와 그 크기가 나열되고, `file.uploaded_bytes`에는 그 합계가 표시됩니다. 누락된 파트가 있으면 새 URL을 요청해 다시 전송하세요. Python 및 JavaScript 스크립트는 누락된 파트 번호를 계산하고, `curl` 스크립트는 업로드된 파트 목록을 출력합니다. 중단 없이 한 번에 실행하면 누락된 파트가 생기지 않으므로, 누락된 파트를 재전송하는 스크립트는 없습니다.
  </Step>

  <Step title="업로드 완료">
    모든 파트가 업로드되면 스크립트가 업로드를 완료합니다. Model Distillation은 파트가 선언된 크기와 일치하는지 확인하고, 다이제스트를 계산한 다음, 검증 및 데이터셋 생성 작업을 큐에 추가합니다.

    응답은 `202 Accepted`입니다. 누락된 파트가 있으면 유형이 `upload_incomplete`인 `409 Conflict`가 반환됩니다. 파트 크기가 잘못되었으면 유형은 `upload_manifest_mismatch`입니다. 두 경우 모두 세션이 `uploading` 상태로 유지되므로, 파트를 수정한 뒤 업로드 완료를 다시 요청할 수 있습니다. 이미 완료된 업로드에 완료를 다시 요청하면 오류 없이 현재 세션이 반환됩니다.
  </Step>

  <Step title="데이터셋이 준비될 때까지 폴링">
    스크립트는 `state`가 `ready` 또는 `failed`가 될 때까지 10초마다 세션을 조회합니다. 검증이 진행되는 동안 `validation.validated_rows`에는 파싱된 행 수가 집계되고, `counters`에는 `staged_rows`, `rejected_rows`, `rows_by_split`이 표시됩니다.

    `state`가 `ready`이면 `dataset_id`로 새 데이터셋을 식별할 수 있습니다. 이 ID를 재레이블링, 파인튜닝, 평가에 사용하거나 UI에서 데이터셋을 열어 보세요. `state`가 `failed`이면 [검증 결과 조회](#read-validation-results)를 참조하세요.
  </Step>
</Steps>

<h2 id="splits-and-duplicates">
  분할과 중복
</h2>

`split_policy`는 행을 트레이닝 분할과 검증 분할로 나누는 방식을 결정합니다.

* \*\*`preserve`\*\*는 각 행의 `split` 값을 그대로 유지합니다. `split`이 없는 행은 `missing_split` 오류와 함께 검증에 실패합니다.
* \*\*`automatic`\*\*은 행에 지정된 `split` 값을 모두 무시합니다. 각 행의 `group_id`를 해시하며, `group_id`가 없으면 행 ID를 대신 해시합니다. 그런 다음 `val_fraction`에 지정된 비율만큼의 행을 검증 분할에 할당합니다. 기본 비율은 0.2입니다. `group_id`가 같은 행은 항상 같은 분할에 할당됩니다.

`duplicate_policy.split_overlap`은 분할 할당 후 동일한 입력이 두 분할에 모두 존재할 때의 처리 방식을 결정합니다.

* **`reject`**(기본값)는 겹치는 행마다 검증 오류를 기록하며, 임포트가 실패합니다.
* \*\*`drop_train`\*\*은 트레이닝 분할의 사본을 삭제하고 검증 분할의 사본을 유지합니다.

파일 내에서 `row_id`가 두 번 이상 나타나면 어떤 정책을 사용하든 `duplicate_row_id` 오류와 함께 검증에 실패합니다.

<h2 id="read-validation-results">
  검증 결과 확인
</h2>

`failed` 세션은 `error`에 간단한 요약을 제공하고, 자세한 내용은 `validation`에 담습니다.

* `error_count`는 발견된 문제의 총 개수입니다.
* `errors`는 최대 100개의 문제를 줄 순서대로 나열하며, 각 문제에는 `physical_line`, `code`, `message`가 포함됩니다.
* `errors_truncated`는 목록에 표시된 것보다 문제가 더 많으면 `true`입니다.

주요 코드로는 `invalid_json`, `invalid_utf8`, `duplicate_json_key`, `row_too_large`, `missing_assistant_target`, `tools_too_large`, `missing_split`, `duplicate_row_id`가 있습니다. 파일을 수정한 다음 새 세션을 생성하세요. 실패한 세션은 다시 열 수 없습니다.

<h2 id="cancel-an-upload">
  업로드 취소
</h2>

세션을 폐기하려면 세션을 삭제하세요. 취소는 `ready`를 제외한 모든 상태에서 가능하므로, 아직 검증 중이거나 실패한 세션도 중단할 수 있습니다. 응답으로 `204 No Content`가 반환되고, 상태가 `cancelled`로 바뀌며, 업로드된 파트는 폐기되고 일부만 생성된 데이터셋도 모두 제거됩니다. 이미 취소된 세션에 같은 요청을 다시 보내도 `204 No Content`가 반환됩니다.

```bash theme={"system"}
curl --request DELETE \
  --url "https://distillation.training.wandb.ai/v1/tasks/ticket-classifier/dataset-imports/$IMPORT_ID" \
  --header "Authorization: Bearer $WANDB_API_KEY" \
  --header "Wandb-Entity: your-team"
```

이미 `ready` 상태에 도달한 세션에서는 유형이 `dataset_import_ready`인 `409 Conflict`가 반환됩니다. 이 세션에서 생성된 데이터셋을 제거하려면 대신 해당 데이터셋을 삭제하세요. 자세한 내용은 [데이터셋 삭제](/ko/model-distillation/studio/datasets#delete-a-dataset)를 참조하세요.

<h2 id="errors">
  오류
</h2>

임포트 세션 요청은 다음 오류를 반환할 수 있습니다.

| 상태 | 유형 | 원인 |
| - | - | - |
| `403 Forbidden` | `dataset_uploads_disabled` | 해당 entity에 업로드가 활성화되어 있지 않습니다. |
| `409 Conflict` | `idempotency_conflict` | `idempotency_key`가 이미 다른 요청 본문에 사용되었습니다. |
| `409 Conflict` | `dataset_import_not_uploading` | 세션이 `uploading` 상태를 벗어나 더 이상 새 파트를 받지 않습니다. |
| `409 Conflict` | `upload_incomplete` | 모든 파트가 도착하기 전에 업로드를 완료하려고 했습니다. |
| `409 Conflict` | `upload_manifest_mismatch` | 업로드된 파트 또는 병합된 파일이 선언된 크기와 일치하지 않습니다. |
| `409 Conflict` | `dataset_import_ready` | 이미 데이터셋을 생성한 세션을 취소하려고 했습니다. |
| `409 Conflict` | `dataset_import_state_changed` | 요청을 처리하는 도중 세션 상태가 변경되었습니다. 세션을 다시 조회한 후 재시도하세요. |
| `410 Gone` | `dataset_import_expired` | 세션이 생성된 지 7일이 지났습니다. 새 세션을 생성하세요. |
| `422 Unprocessable Entity` | `validation_error` | 파트 번호가 `file.part_count`보다 큽니다. |
| `429 Too Many Requests` | `dataset_import_concurrency_limit` | 해당 entity에 이미 진행 중인 세션이 2개 있습니다. |
| `429 Too Many Requests` | `dataset_import_byte_quota` | 새 파일을 추가하면 해당 entity의 진행 중인 세션 전체에서 선언된 크기 합계가 2 GiB를 초과합니다. |
| `502 Bad Gateway` | `object_storage_error` | 업로드 저장소가 요청을 거부했습니다. 나중에 다시 시도하세요. |
| `503 Service Unavailable` | `uploads_unavailable`, `temporal_unavailable` | 업로드 저장소 또는 검증 큐에 연결할 수 없습니다. 나중에 다시 시도하세요. |

요청 및 응답 스키마는 Management API 레퍼런스의 다음 페이지를 참조하세요.

* [데이터셋 임포트 세션 생성](/ko/model-distillation/reference/management/datasets/create-a-dataset-import-session)
* [파일 파트용 업로드 URL 생성](/ko/model-distillation/reference/management/datasets/create-upload-urls-for-file-parts)
* [데이터셋 임포트 세션 조회](/ko/model-distillation/reference/management/datasets/get-a-dataset-import-session)
* [데이터셋 임포트 완료 및 검증](/ko/model-distillation/reference/management/datasets/complete-and-validate-a-dataset-import)
* [데이터셋 임포트 취소](/ko/model-distillation/reference/management/datasets/cancel-a-dataset-import)

<h2 id="next-steps">
  다음 단계
</h2>

<CardGroup cols={2}>
  <Card title="재레이블링" icon="pen-to-square" href="/ko/model-distillation/studio/relabeling">
    원본 행은 그대로 둔 채, 더 강력한 모델로 업로드한 데이터셋의 assistant 응답을 다시 작성하세요.
  </Card>

  <Card title="파인튜닝" icon="graduation-cap" href="/ko/model-distillation/studio/fine-tuning">
    원본 출력이나 재레이블링된 출력 세트를 사용해 업로드한 데이터셋으로 지원되는 기본 모델을 학습시키세요.
  </Card>
</CardGroup>


## Related topics

- [Datasets](/ko/model-distillation/studio/datasets.md)
