Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Direct Preference Optimization: Data Preparation

In the previous chapter, we used SFT to teach the model to converse by following instructions. But SFT has a limitation: it can only tell the model how to answer, not what a better answer is.

For example, two answers may both be correct, but one is concise and the other wordy, or one is polite and the other blunt. SFT cannot tell them apart.

In practice, researchers found that telling the model which answer is more reasonable during fine-tuning teaches it to answer questions in a more accurate, honest, and safe way. This fine-tuning technique is called preference optimization (PO). It is usually stacked on top of SFT to further improve the model’s output.

Preference optimization currently comes in three main kinds:

  • Reinforcement learning from human feedback (RLHF): train a reward model and use a reinforcement learning algorithm to optimize the model;

  • Direct preference optimization (DPO): train the model directly on data that carries preferences;

  • Test-time preference optimization (TPO): adjust the model’s output at inference time with specific strategies and algorithms (such as guided decoding and rejection sampling).

Direct preference optimization

Direct preference optimization (DPO) teaches the model to compare: show the model two answers to the same prompt and tell it which one is better.

Data format

The data format of DPO is a triple:

  • Prompt: the user’s question or command;

  • Chosen: the more reasonable answer;

  • Rejected: the worse answer.

For example:

Prompt: ROMEO:
        Hello, Juliet!
Chosen: JULIET:
        Hello, Romeo! Nice to meet you!
Rejected: JULIET:
          Hi!

Data source

As with the SFT data, we again extract conversation samples from the test set of the tiny Shakespeare (tinyshakespeare) dataset, as the prompts and the chosen answers. The rejected answers use the same prompts and are continuations written by the model.

💡 Tip: To make teaching easier, the samples in this chapter, like those in Chapter 15, come from the Shakespeare script: the chosen answer is the real speech, and the rejected answer is a continuation by the pre-trained model, so no manual preference annotation is needed. In real projects, preference data is usually produced by humans or stronger models comparing and labeling multiple answers to the same prompt.

Data extraction

Extracting the chosen answers

The same extraction function extract_turns as in the previous chapter extracts all the speeches from the test set of the Shakespeare script (the last 10% of the speech blocks, which lies inside the test set used in pre-training).

Generating the rejected answers

The function generate_rejected uses the pre-trained model to generate the rejected answers:

  • Temperature sampling: set the sampling temperature to 0.8 to control the randomness; the larger the value, the more random;

  • Top-k sampling: set top-k to 20, sampling only from the 20 most probable tokens to avoid generating gibberish;

  • Length: the generated length equals that of the chosen answer.

Hyperparameters

Model parameters

All the hyperparameters used here stay the same as in pre-training.

Building the samples

Loading the model

The rejected answers are generated by the pre-trained model, so we load the pre-trained model here and switch it to evaluation mode.

Extracting the samples

Build (prompt, chosen answer, rejected answer) triples from the test set of the dataset:

  • Pairing: as in SFT, extract adjacent pairs of speeches, as the prompt and the chosen answer;

  • Generating the rejected answers: use the pre-trained model to generate one output for each prompt as the rejected answer;

  • Filtering: remove the samples whose rejected answer is identical to the chosen answer.

generated 64/512 DPO samples
generated 128/512 DPO samples
generated 192/512 DPO samples
generated 256/512 DPO samples
generated 320/512 DPO samples
generated 384/512 DPO samples
generated 448/512 DPO samples
generated 512/512 DPO samples

Saving the samples

Save them to a file with pickle.dump() as well.

saved 512 DPO samples to ../../../../data/dpo-samples.pkl

Verifying the samples

Look at the first sample to confirm that the format is correct.

SEBASTIAN:
Foul weather?


ANTONIO:
Very foul.


ISABELLA:
I hope, sir

In this chapter, we again relied on the test set of the tiny Shakespeare dataset and built 512 DPO training samples: each sample consists of a prompt, a chosen answer (the real speech), and a rejected answer (the model output).

In the next chapter, we will use these samples to train the SFT model with direct preference optimization, so that it learns to pick the better one among several answers.

Exercises

Try raising the temperature used to generate the rejected answers from 0.8 to 1.5, and observe how the rejected answers change. How would this affect the quality of the preference data?