Skip to main content
Supervised fine-tuning (SFT) trains a model to imitate example responses. Each example pairs a prompt with the response you want, and training makes the model more likely to produce that response. Use it when you have demonstrations of the behavior you want, such as human-written answers or a fixed output format. SFT needs no reward function, so it’s the simplest method to start with. In this tutorial, you’ll train a low-rank adapter (LoRA) on the No Robots dataset with a ready-made recipe from the post-training cookbook, then download the trained weights.

Requirements

Before you begin, make sure you have:
  • Python 3.11 or later and uv.
  • A Together AI account with a credit balance of at least $100, the minimum for creating a model resource. See Pricing.
  • Your API key exported as TOGETHER_API_KEY. Get one from API keys in the Together AI console.
  • A Weights & Biases API key exported as WANDB_API_KEY. Most cookbook recipes log to Weights & Biases, including the one in this quickstart. To run without an account, export WANDB_MODE=offline instead.
  • Optionally, a Hugging Face token exported as HF_TOKEN for gated models or datasets.

Step 1: Clone the cookbook

Clone the cookbook and install its dependencies:

Step 2: Review the recipe

Open recipes/sft/no_robots.py. The recipe defines a config object and passes it to the cookbook’s SFT training loop:
recipes/sft/no_robots.py
Each No Robots example is a conversation with a user message and a human-written assistant response. The recipe trains the model to produce the assistant response from the conversation that precedes it. These settings shape the run: Under the hood, train provisions a trainer-only model resource and attaches a session. For each batch, it runs forward_backward with the cross-entropy loss, then optim_step. Supervised fine-tuning explains each piece.

Step 3: Run training

Run the recipe:
The recipe prints status lines while it waits for the model resource and the session to become ready, which usually takes a few minutes and longer when GPUs are scarce. If the resource is still queued after an hour, the SDK stops it and the recipe raises TimeoutError, as Create a resource explains. Then the recipe prints one line per step. The first step takes longer than the rest, and the inference checkpoint at the end can take several minutes to save. Expect output like this:
loss is the mean cross-entropy per trained token, so it stays comparable across steps even as the batch’s token count changes. It varies from batch to batch because each batch holds different examples, so watch its trend rather than single steps. lr decays linearly toward zero over the run. The recipe also logs each step to metrics.jsonl in the run directory and to Weights & Biases. At the last step, it saves a training checkpoint and an inference checkpoint, then stops the session and the model resource.

Step 4: Retrieve the trained model

The final inference checkpoint is registered in your project’s model registry. The inference checkpoint line prints its ID. The run directory records the checkpoint and the session that produced it:
checkpoints.jsonl holds one training entry and one inference entry, each with its step and ref. Each ref is the checkpoint’s ID. To download the weights, replace <session_id> with the ID from manifest.json and run the following. The script reads the session’s last inference checkpoint and passes its ID to download_checkpoint. The merged variant is the full model, about 56 GB for Qwen3.8 27B, so check your free disk space first:
CHECKPOINT_VARIANT_MERGED downloads the base model with the adapter merged in, ready for any inference framework. CHECKPOINT_VARIANT_ADAPTER downloads only the adapter weights, in a layout PEFT can’t load, as Download the weights explains. To serve the model on Together AI, see Deploy a checkpoint.
You trained a LoRA with post-training and downloaded its weights.

Confirm the resource stopped

The recipe stops the session and the model resource when it exits, so billing has already ended. If the run was interrupted, the resource may still be billing, or it may not be ready yet and start billing once it is. This script finds your resources that are waiting for capacity (PENDING), starting up (CREATING), or ready (READY), and stops each one:
created_by="me" limits the list to resources you created, so the script leaves other people’s resources in a shared project alone. force=True also stops any session that’s still attached. Without it, the API refuses to stop a resource while a session is active. If you have other runs in progress, the script stops their resources too. To stop only this run’s resource, pass the ID from the [model-resources:<id>] created line in the run’s output to client.post_training.model_resources.stop("your_resource_id", force=True). You can also stop resources from the Model resources tab under Post-training in the console. Manage model resources covers stopping, idle timers, and what a resource costs while it runs.

Continue with GRPO

A common pattern is to teach the model a format with SFT, then optimize for task accuracy with group relative policy optimization (GRPO). The GRPO run continues the same adapter from the training checkpoint this recipe saved. Chain SFT and GRPO shows how.

Next steps

RL quickstart

Train a model with GRPO and an exact-match reward on grade-school math.

Supervised fine-tuning

Loss masks, data preparation, and chaining SFT into GRPO.

Concepts

How work splits between your code and Together AI GPUs, and the model resources, sessions, and checkpoints behind the recipe.

Deploy a checkpoint

Deploy the trained model on dedicated model inference.