Preference tuning is how a model learns which of two acceptable answers is better — tone, length, how much to hedge, when to refuse. It needs pairs, and pairs are expensive, so it is worth knowing the real published scales before you budget an annotation project.
The data contract
Direct Preference Optimisation trains on triples: a prompt, a chosen completion and a rejected one. TRL defines the field names, and because the popular wrappers all call into TRL, this is the shape your data ends up in regardless of which trainer you use.
TRL's own guidance is to include an explicit prompt field rather than folding the prompt into both completions. The implicit form works, but it forces the trainer to infer the shared prefix, and any mismatch between the two completions' prefixes becomes part of what the model learns to prefer — which is not what you wanted it to learn.
# explicit prompt - recommended
{"prompt": "Explain gradient descent to a beginner.",
"chosen": "Gradient descent is a way of ...",
"rejected": "Gradient descent is an optimization algorithm that ..."}
# implicit prompt - works, but the prefix must match exactly
{"chosen": "Explain ...\nGradient descent is a way of ...",
"rejected": "Explain ...\nGradient descent is an optimization ..."}
# conversational variant - prompt and completions are message lists
{"prompt": [{"role": "user", "content": "Explain gradient descent."}],
"chosen": [{"role": "assistant", "content": "Gradient descent is ..."}],
"rejected": [{"role": "assistant", "content": "It's an algorithm ..."}]}
The published scales
This is the stage where guidance is thinnest. Neither TRL nor the major wrappers publish a recommended row count for preference tuning — if someone gives you a specific number, it is their experience rather than a documented figure. What we do have is the sizes of the reference datasets, which is the honest way to orient.
UltraFeedback collects about 64,000 prompts with four responses each, giving roughly 256,000 rated samples, drawn from a pool of 17 models and annotated by GPT-4 on four aspects: instruction-following, truthfulness, honesty and helpfulness. Its binarised form is the usual DPO-ready version.
Tülu 3 reports 354,192 instances for preference tuning in total, with an 8B mix of 271,409 and a 70B mix of 334,302. Its per-source breakdown is instructive: a large share is reused SFT prompts answered off-policy, plus instruction-following augmentation and real user prompts from WildChat.
For the historical reference point, InstructGPT used 13k SFT prompts, 33k reward-model prompts and 31k PPO prompts, annotated by about 40 contractors. That is the scale at which the original RLHF result was obtained — tens of thousands, not millions.
| Dataset | Published size | Licence |
|---|---|---|
| UltraFeedback | ~64k prompts × 4 responses = 256k samples | MIT |
| UltraFeedback-binarized | 61,135 train / 2,000 test preference pairs | MIT |
| Tülu 3 preference mixes | 354,192 instances; 8B mix 271,409; 70B mix 334,302 | ODC-BY-1.0 |
| InstructGPT RM data | 33k RM prompts, 31k PPO prompts | not released |
The hyperparameters are not SFT's
Preference tuning makes small corrections to a model that is already aligned, and its settings reflect that. The gap surprises people who reuse an SFT config.
Learning rate is the big one. Unsloth's DPO example uses 5e-6 against 2e-4 for SFT — a fortyfold difference. Tülu 3 goes lower still: 5e-7 for its 8B DPO run and 2e-7 for 70B, with an effective batch size of 128, a maximum length of 2,048 and one epoch.
beta controls how far the tuned model may drift from the reference model. Lower values permit larger changes; 0.1 is a common starting point. And you do not necessarily need a separate reference model: when training a PEFT adapter you can pass ref_model=None, because disabling the adapter recovers the base model, which saves loading a second copy of the model.
Where the rejected answers come from
Getting a chosen answer is easy; a good rejected answer is the hard part, and the quality of your rejected set determines what the model actually learns.
The common approaches, roughly in order of cost: sample several completions from the model you are tuning and have a stronger model or a human rank them, which is what on-policy means and is generally the most effective; sample from a weaker model or an earlier checkpoint; use an existing multi-model pool like UltraFeedback's 17 models.
The failure to avoid: rejected answers that are bad in a uniform, obvious way. If every rejected completion is shorter, or always starts with the same phrase, or comes from a model with a distinctive tic, the model learns to avoid that artefact rather than to prefer quality. Tülu 3's mix of on-policy and off-policy sources is partly a defence against exactly this.
Consider whether you need pairs at all
Pairs are the expensive shape. For every prompt someone must read two answers and decide, and on answers of similar quality that judgement is slow and inconsistent between annotators.
KTO needs only a single answer plus a binary judgement — thumbs up or down. That is a much cheaper annotation task, and more importantly it is the shape feedback naturally arrives in from real users, who will readily click a thumbs-down but will not sit through a comparison.
If you have production traffic with any feedback mechanism, you may already have KTO data and no pairs at all. Manufacturing pairs from it is usually worse than using the method designed for the shape you have.
Questions people ask
How many pairs do I need?
Not published by any major framework. The reference datasets sit in the tens to hundreds of thousands, and InstructGPT's original result used 33k reward-model prompts. For a narrow behavioural correction, far fewer may suffice — run the doubling experiment against a held-out evaluation set rather than targeting a number.
Can I turn my SFT data into preference data?
Partly. Your existing good answer becomes chosen, but you still need a plausible rejected, and generating those from a weaker model risks teaching the model to avoid that model's artefacts rather than to prefer quality. Sampling from the model you are tuning and ranking the samples is better.
DPO or PPO?
DPO is simpler and is what most open recipes now use: no separate reward model, no sampling loop, just the triples. PPO with a learned reward model is the original InstructGPT approach and still has advantages when you want to optimise against a reward you can model but not enumerate. For most teams DPO is the default and ORPO or KTO are the variations worth knowing.
Will DPO hurt capabilities I already have?
It can, which is why the learning rates are so low and the runs so short. Evaluate the capabilities you are not trying to change as well as the behaviour you are. A preference run that improves tone while quietly degrading maths is a common and easily missed outcome.