Skip to main content
Unsloth’s popular Qwen3 (4B) Colab notebook fine-tunes a 4-bit Qwen3-4B-Instruct with LoRA adapters on a chat dataset. This demo runs the same recipe as a managed SFT job on Veri: you submit one job, and Veri provisions the GPU, installs the stack, runs the training loop, and uploads the checkpoint. No notebook, no CUDA setup, no runtime babysitting.
This spends real GPU credit. Check your balance with veri billing balance first.

Prerequisites

  • Install the SDK: pip install veri-sdk
  • Authenticate: veri login (or set VERI_API_KEY)

The script

Save and run as sft_unsloth.py:
sft_unsloth.py
Sixty steps is a fast smoke test, same as the notebook. For a real run, remove max_steps and set num_epochs to 1.

Watch it train in W&B

If your W&B account is connected (veri wandb set, one time), this job streams the notebook’s loss curve to your W&B project live, and the finished job carries the run link:
The dashboard’s job page shows the same link as a “View in W&B” button. Not connected? Metrics still stream to Veri’s native charts on the job page.

What the hyperparameters do

Each key in hyperparameters is one setting from the notebook. Veri’s worker runs the same TRL SFTTrainer underneath, with Unsloth patching it when use_unsloth is on. For every SFT option and its default, see SFT hyperparameters.

How many steps is one epoch?

One epoch is one full pass over the dataset, so it depends on dataset size and effective batch, not on max_steps directly:
For this demo, FineTome-100k has about 100,000 examples and an effective batch of 2 × 4 × 1 = 8, so one epoch is about 100,000 / 8 = 12,500 steps. The max_steps: 60 smoke test is roughly 0.5% of that, which is why switching to num_epochs: 1 is a much longer (and more expensive) run.

Sequence length, by example

max_seq_length caps the tokenized conversation after the chat template renders it to text, not characters or the number of turns. As a rough guide, one token is about three-quarters of an English word.
  • A short exchange (“What color is the sky?” / “It is blue.”) renders to roughly 30 tokens, trains in full, and is padded up to the longest example in its batch.
  • A long multi-turn conversation that tokenizes to 3,000 tokens is truncated to the first 2,048; the tail (often the final assistant answer) is dropped. Raise max_seq_length when your data runs long, at the cost of more GPU memory.
Veri handles the notebook’s data prep for you, so standardize_data_formats, get_chat_template, and formatting_prompts_func have no equivalent here (see the note below). Batch size, warmup, and optimizer settings use Veri’s defaults. The notebook’s train_on_responses_only step is not exposed on the managed path, so loss is computed on the full conversation; use the custom-script variant if you need response-only loss.
FineTome-100k is stored in ShareGPT format ({"from": "human", "value": ...}). Veri detects and converts it (and other common formats like Alpaca) automatically; see supported formats.

Run the same recipe as a custom script

If you want the parts the managed method does not expose (like train_on_responses_only, or any other change to the loop), run the notebook code itself as a custom script. Veri still provisions the GPU, streams logs, and uploads the checkpoint; the difference is that you own the training loop and its dependencies.
Preview: this variant is ported verbatim from the notebook but is pending an end-to-end verification run on a live GPU.
A two-file project directory:
train.py is the notebook, adapted to the Veri contract: read nothing but env, write the checkpoint to VERI_OUTPUT_DIR.
train.py
requirements.txt layers Unsloth (which pulls in TRL and bitsandbytes) on top of the veri/base image:
requirements.txt
Submit it with the same GPU shape as the managed job:
Both paths end the same way: a job you can watch live and a checkpoint in your account, so the download step below is unchanged. Trade-offs: the custom script gives you the full notebook (including response-only loss) and any edit you want, but you own dataset prep, hyperparameter defaults, and dependency versions, and cold start is a little slower while unsloth installs.

Get the checkpoint

job.download pulls the trained checkpoint once the job completes. You can also grab it from the CLI:

Next steps

SFT (text)

Every SFT hyperparameter, dataset formats, and the LoRA/QLoRA rules.

Deploy your checkpoint

Serve the trained model with an OpenAI-compatible API.