Prerequisites
Before you begin, make sure you have the following:- A W&B API key for a team that has access to Model Distillation. The examples read it from the
WANDB_API_KEYenvironment variable, pass it in theAuthorizationheader, and name the entity in theWandb-Entityheader. - A project in that team. The project alias appears in every request path. To create one, see the Quick Start.
- The tools for the tab you plan to use in Upload the file. You need only one of the following sets:
curltogether withjqandsplit.- Python 3.9 or later with the
requestspackage. - Node.js 18 or later, with no extra packages.
How an upload works
An upload is an import session scoped to a project. One session holds exactly one JSONL file, which you send directly to object storage in parts. The session moves through the following states:
A session that is still
uploading 7 days after creation expires. Part and completion requests to it return 410 Gone, and an hourly job moves it to expired and discards its parts. Uploaded objects and incomplete multipart uploads are deleted 8 days after they were written, whether or not the session completed.
An entity is the team or personal account named in the Wandb-Entity header. Each entity can have two sessions in progress at a time, with up to 2 GiB of declared file size between them. A session counts toward both limits from creation until it reaches ready, failed, cancelled, or expired. A request that would exceed either limit returns 429 Too Many Requests. To free capacity, cancel a session you no longer need, or wait for a running session to finish.
Prepare the file
Before you create an import session, make sure the file matches the row format and stays within the limits described in this section. Validation runs only after you complete the upload, and a failed session can’t be reopened. To fix a formatting problem, create a new session and upload the file again. The file must be UTF-8 JSONL: one JSON object per line, with no duplicate keys within an object.Row format
Each row is an OpenAI Chat Completions request whose last message is the assistant response to train toward. Model Distillation stores the preceding messages, plus anytools, tool_choice, and response_format, as the input, and the final assistant message as the output.
tools accepts up to 128 function tools and 1 MiB of JSON. A row whose last message isn’t from the assistant fails with missing_assistant_target.
Optional fields
Rows can carry the following optional fields:
Rows must not contain other top-level fields.
Limits
Files and import sessions must stay within the following limits:Upload the file
An upload proceeds in stages: create the session, upload the file in parts, complete the upload, and poll until the dataset is ready. The following tabs show the whole flow as one script incurl, Python, and JavaScript. Numbered comments mark the stages, and How the script works explains each one.
The scripts use a project alias of ticket-classifier and a file named tickets.jsonl. Before you run a script, replace the entity, alias, and filename with your own, and set WANDB_API_KEY in your environment. Use a new idempotency_key for each distinct upload.
- curl
- Python
- JavaScript
How the script works
The numbered comments in each script correspond to the following stages.1
Create the import session
The script sends the filename and exact byte size, the split policy, and an optional duplicate policy. To learn what each policy does, see Splits and duplicates. The request also requires a unique
idempotency_key, so a retried request returns the existing session instead of creating a second one.The response is 201 Created with the session. The script keeps id, file.part_size_bytes, and file.part_count from it. The following excerpt shows those fields:2
Request upload URLs
The script requests a signed URL for every part number from 1 through
file.part_count. The response lists each part_number with its url, plus expires_in_seconds. Each URL is valid for 15 minutes. If the URLs expire before you use them, request them again.3
Upload the parts
The script reads the file in
file.part_size_bytes chunks and sends a PUT request with each chunk to the URL that matches its part number. Part numbers start at 1, so the first chunk is part 1. Every part except the last must be exactly file.part_size_bytes long, and the last part holds the remainder. You can send the parts in any order and in parallel.The signed URLs carry their own authorization, so the script doesn’t add the Authorization or Wandb-Entity headers to these requests.4
Optional: Check which parts arrived
To resume after an interrupted transfer, read the session.
file.parts lists each uploaded part with its size, and file.uploaded_bytes totals them. Request new URLs for any missing parts and send them again. The Python and JavaScript scripts compute the missing part numbers, and the curl script prints the list of uploaded parts. None of the scripts resends missing parts, because a single uninterrupted run doesn’t produce any.5
Complete the upload
When every part is present, the script completes the upload. Model Distillation verifies that the parts match the declared size, computes a digest, and queues validation and dataset creation.The response is
202 Accepted. If a part is missing, the response is 409 Conflict with type upload_incomplete. If a part has the wrong size, the type is upload_manifest_mismatch. In both cases, the session stays in uploading, so you can fix the parts and complete the upload again. If you complete an upload that’s already complete, the request returns the current session without error.6
Poll until the dataset is ready
The script reads the session every 10 seconds until
state is ready or failed. While validation runs, validation.validated_rows counts parsed rows, and counters reports staged_rows, rejected_rows, and rows_by_split.When state is ready, dataset_id identifies the new dataset. Use it with relabeling, fine-tuning, and evaluations, or open it in the UI. If state is failed, see Read validation results.Splits and duplicates
split_policy determines how rows are divided between training and validation:
preservekeeps thesplitvalue on each row. A row withoutsplitfails validation withmissing_split.automaticignores anysplitvalue on the rows. It hashes each row’sgroup_id, or its row identity whengroup_idis absent, and assigns the fraction inval_fractionto the validation split. The default fraction is 0.2. Rows that share agroup_idare always assigned to the same split.
duplicate_policy.split_overlap determines what happens when an identical input appears in both splits after assignment:
reject, the default, records a validation error for each overlapping row, and the import fails.drop_traindrops the training copies and keeps the validation copies.
row_id that appears more than once in the file fails validation with duplicate_row_id under either policy.
Read validation results
Afailed session reports error as a short summary, and validation carries the details:
error_countis the total number of problems found.errorslists up to 100 problems, ordered by line, each withphysical_line,code, andmessage.errors_truncatedistruewhen more problems exist than the list shows.
invalid_json, invalid_utf8, duplicate_json_key, row_too_large, missing_assistant_target, tools_too_large, missing_split, and duplicate_row_id. Fix the file and create a new session. A failed session can’t be reopened.
Cancel an upload
To discard a session, delete it. Cancellation works in every state exceptready, so you can also abandon a session that is still validating or that failed. The response is 204 No Content, the state becomes cancelled, uploaded parts are discarded, and any partially created dataset is removed. Repeating the request on a cancelled session returns 204 No Content again.
ready returns 409 Conflict with type dataset_import_ready. To remove the dataset it created, delete the dataset instead. See Delete a dataset.
Errors
Import session requests can return the following errors.
For request and response schemas, see the following pages in the Management API reference:
- Create a dataset import session
- Create upload URLs for file parts
- Get a dataset import session
- Complete and validate a dataset import
- Cancel a dataset import
Next steps
Relabeling
Ask a stronger model to rewrite the assistant responses in the uploaded dataset without changing the original rows.
Fine-tuning
Train a supported base model on the uploaded dataset, using the original outputs or a relabeled output set.