How post-training runs DPO
DPO uses a trainer-only resource (num_generator_replicas=0). Before any updates, the cookbook scores all training and validation pairs with forward to snapshot the reference policy. Each training step then runs:
forward: The trainer returns per-target-token log-probabilities without accumulating gradients.- Local loss: Your process computes the loss in PyTorch from live and reference log-probabilities, then calls
.backward()to get per-token log-probability gradients. custom_forward_backward: Your process sends those gradients to the trainer, which repeats the forward pass and backpropagates through the model to accumulate parameter gradients.optim_step: The optimizer applies the accumulated gradients.
Run the DPO recipe
The cookbook’s DPO loop trains on HelpSteer3 preference pairs:uv run python recipes/dpo/helpsteer3.py. train provisions a trainer-only resource and one session, then stops both when it returns. To use an existing resource, attach through the SDK, because DPOConfig has no model_resources_id field.
Settings worth knowing:
beta: The temperature on the implicit reward. Higher values keep the policy closer to the reference.enable_thinking: Set it toFalsefor Qwen preference data without reasoning, such as HelpSteer3. The catalog’s Qwen models default to thinking on, making these pairs unrenderable, sotrainraisesValueErrorbefore provisioning. GLM-5.3 accepts these pairs with thinking on and rejectsFalse, so leave the setting unset for it.label_smoothing: Conservative-DPO smoothing. Off by default.learning_rate: The default is5e-6with cosine decay, lower than for supervised fine-tuning (SFT).precompute_ref_batch_size: Samples per forward pass for reference precomputation and validation. Lower it if long pairs cause out-of-memory errors.val_interval: The number of steps between validation runs on held-out pairs.
DPOConfig field.
Prepare preference pairs
You choose your dataset schema and prepare tokenized samples in your code. The cookbook’sbuild_preference_pair takes two full conversations with identical history, ending in a chosen and a rejected assistant response. It applies the model’s chat template and returns two SFT-style Sample objects, masking only the final responses:
None, which means truncation to max_length left at least one side with no trained token. Unrenderable chat templates raise ValueError. For Qwen data without reasoning, pass enable_thinking=False to get_codec.
The cookbook interleaves samples as [chosen_0, rejected_0, chosen_1, rejected_1, ...]: chosen responses at even indexes, rejected responses at odd indexes.
Use your own preference dataset
Select data for the cookbook’s Hugging Facedatasets loader with dataset_name, dataset_config, and dataset_split. Pass train a to_pair function that returns (chosen_messages, rejected_messages) per row, or None to skip it. The default, helpsteer3_pair in post_training_cookbook.dpo.train, chooses by HelpSteer3’s overall_preference and skips ties. This example maps prompt, chosen, and rejected text columns:
"validation" split, set val_split to a held-out split it has, or disable validation with val_interval=0. Reusing the training split inflates val/preference_accuracy.
Write your own DPO loop
Customize data loading, preprocessing, tokenization, or the objective in your own loop. This example renders in-memory preference pairs with the cookbook’s chat-template codec:make_dpo_loss binds the loss to a batch’s reference sums and response masks. It sums masked token log-probabilities, computes the chosen-minus-rejected margin relative to the reference, and averages -log σ(β · margin) across pairs. Pass label_smoothing for conservative DPO.
compute_custom_forward_backward runs the two trainer passes and local PyTorch autograd. Log its result.loss yourself, because the service doesn’t report a loss for a custom loss function.
compute_logprobs scores its whole batch in one forward pass, so the loop chunks the reference snapshot by REF_CHUNK_SIZE. Lower it if long pairs run out of memory. The recipe uses precompute_ref_batch_size and adds a cosine learning-rate schedule, validation, and periodic checkpoints.
Validate with preference accuracy
DPO validates with implicit-reward preference accuracy, rather than token-level accuracy. Everyval_interval steps, the recipe measures the fraction of held-out pairs whose reward shift favors the chosen response. Watch val/preference_accuracy and val/mean_margin rise. At step zero, accuracy is 0, because the policy equals the reference and ties count as wrong. See DPO metrics.
Next steps
Supervised fine-tuning
Warm up a model on demonstrations before preference training.
Monitoring
Read the DPO validation metrics.
Write a custom loss function
Adapt the DPO pattern to your own objective.
Deploy a checkpoint
Deploy the trained model.