Skip to main content
Managed SFT and DPO no longer accept new jobs. Your trained models stay deployable. To keep training, follow Migrate from Managed Training.
To view, stop, or delete your jobs, see Existing jobs.

Dataset format

A dataset is JSONL: one JSON object per line, from 3 to 3 million lines. Each object has a messages array and may have a tools array of OpenAI function definitions. There is no weight on the example itself. This is the OpenAI chat format, so an existing OpenAI SFT dataset works without conversion. Each message is an object:
  • role: system, user, assistant, or tool
  • content: a string, or a list of parts. A text part is {"type": "text", "text": "..."}. A thinking part is {"type": "thinking", "thinking": "..."}. One text part is the same as a string. Several parts stay separate through the chat template. Image parts are under Vision training.
  • tool_calls: optional on an assistant message, and enough on its own when content is omitted. Use {"type": "function", "function": {"name": "...", "arguments": ...}}, where arguments is a JSON object or a JSON string. {"name": "...", "args": {...}} is also accepted.
  • weight: optional number on a message. 0 excludes that message from the loss. Any other number trains it. trainable is a boolean for the same switch and wins when both are set.
A tool message returns a tool result and should set tool_call_id. Assistant thinking can also be a string field, thinking, reasoning, or reasoning_content. When more than one is set, thinking is used, then a non-empty reasoning, then a non-empty reasoning_content. Whether earlier thinking remains in later turns depends on the base model.

Thinking history in training

Compare every supported model, understand per-user-turn unrolling, configure the job field, and preview what the trainer will see.

Deploying a trained model

After training completes, evaluate the model before you hold dedicated capacity for production serving. To deploy for inference:
This creates a dedicated deployment with performance matching the base model. To pick a specific shape instead of default, see Deployment shapes.
For more details on deploying trained models, including multi-LoRA deployments, see the Deploying Trained Models guide.

Additional managed training job settings

These are the optional settings that managed SFT and preference (DPO/ORPO) jobs accepted. Use them to read an existing job’s configuration, for example with firectl sftj get <JOB_ID>. To carry a setting over to the Training API, see “Which managed job settings carry over?” in the migration guide FAQ.
By default, the training job will run evaluation by running the trained model against an evaluation set that’s created by automatically carving out a portion of your training set. You have the option to explicitly specify a separate evaluation dataset to use instead of carving out training data.evaluation_dataset: The ID of a separate dataset to use for evaluation. Must be pre-uploaded via firectlfirectl sftj flag: --evaluation-dataset.
Depending on the size of the model, the default context size will be different. For most models, the default context size is >= 32768. Usually you do not need to set the max context length unless out of memory error is encountered with higher lora rank and large max context length.firectl sftj flag: --max-context-length.
Managed SFT and preference tuning use sample-count batching. batch_size_samples is the number of SFT samples or preference pairs included in each optimizer step. It is independent of max_context_length, which limits the token length of each sample. The UI defaults are 32 samples for SFT and 4 preference pairs for DPO/ORPO.firectl sftj flag: --batch-size-samples.
Epochs are the number of passes over the training data. Our default value is 1. If the model does not follow the training data as much as expected, increase the number of epochs by 1 or 2. Epochs must be a whole number.Note: we set a max value of 3 million dataset examples × epochsfirectl sftj flag: --epochs.
Learning rate controls how fast the model updates from data. We generally do not recommend changing learning rate. The default value is automatically based on your selected model.firectl sftj flag: --learning-rate.
Learning rate warmup steps controls the number of training steps during which the learning rate will be linearly ramped up to the set learning rate.firectl sftj flags: --learning-rate, --learning-rate-warmup-steps.
Configure how the learning rate changes over training. Supported schedulers are constant, linear, and cosine. When unset, the trainer uses its legacy constant schedule. The same flags apply to SFT and preference tuning jobs (DPO/ORPO).For linear and cosine, you can optionally set:
  • --learning-rate-min-lr-ratio: minimum learning rate as a fraction of --learning-rate (0 to 1)
  • --learning-rate-decay-ratio: fraction of total training steps over which to decay; 0 decays over the full run
firectl sftj flags: --learning-rate, --learning-rate-warmup-steps, --learning-rate-scheduler, --learning-rate-min-lr-ratio, --learning-rate-decay-ratio.In the REST API, the job’s lrScheduler field holds one of constant, linear, or cosine, with minLrRatio and decayRatio for the last two.
LoRA rank refers to the number of parameters that will be tuned in your LoRA add-on. Higher LoRA rank increases the amount of information that can be captured while tuning. The maximum rank depends on the base model’s training shape, up to 128; higher values are rejected. firectl defaults to 8.In the REST API the field is loraRank, and in the Python SDK lora_rank. A rank of 0 means the job trained all parameters instead of a LoRA adapter.firectl sftj flag: --lora-rank.
The training service integrates with Weights & Biases to provide observability into the tuning process. To use this feature, you must have a Weights & Biases account and have provisioned an API key.firectl sftj flags: --wandb-entity, --wandb-api-key, --wandb-project.
By default, the training job will generate a random unique ID for the model. This ID is used to refer to the model at inference time. You can optionally specify a custom ID, within ID constraints.firectl sftj flag: --output-model.
By default, the training job will generate a random unique ID for the training job. You can optionally choose a custom ID.firectl sftj flag: --job-id.
Reservation placement is off unless you request it. If you request it and your account has an active reservation for the job’s accelerator type, the job runs only on that reservation, not on shared trainer capacity. If the account has no matching reservation, the setting is ignored and the job uses shared capacity.
  • firectl: --use-reservation.
  • REST: useReservation in the job body.
  • Python SDK: the field is use_reservation.

Deprecated parameters

These parameters are deprecated. Do not include them in new managed training requests. The wire fields remain present so existing resources can still be read, but Training V2 rejects or ignores non-default values as described below.

Appendix

Vision training

Vision SFT uses the same messages JSONL. Put image parts on user messages. Some vision renderers also allow them on tool messages. system and assistant messages cannot contain images. Encode each image as a data:image/<type>;base64,... URI before upload, and keep the MIME type accurate (image/jpeg, image/png). These parts are the same image:
  • {"type": "image_url", "image_url": {"url": "data:image/jpeg;base64,..."}}
  • {"type": "image_url", "image_url": "data:image/jpeg;base64,..."}
  • {"type": "image", "image": "data:image/jpeg;base64,..."}
Confirm the base model in Models. Training API VLM loops use these same parts: Training Shapes.

Debug SFT tokenization

If the model learns the wrong text or ignores assistant turns, the training renderer may not match inference tokenization.
  1. In the dashboard, open your SFT job → Render Samples to inspect token boundaries and loss masks.
  2. Compare rendered tokens against inference for the same prompt.
  3. For custom renderers or agent-driven debugging, use the training skill — renderer verification.
In the REST response, the render preview identifies each datum produced from a source row with examples[].renderings[].renderedDatums[].datumIndex. Downloaded Render Samples use the legacy split_index field. The fields play corresponding roles in different schemas; split_index has not been renamed in the downloadable artifact.
Common fix: ensure assistant messages you intend to train have non-zero loss weight; system/user turns should be masked out.

Common findings