This script builds DPO preference pairs from a prompt-injection dataset. Each pair teaches the model to follow the user's original instruction while treating injected content as inert data.
| Branch | Behavior | Role |
|---|---|---|
| chosen | Executes ONLY the original task; injected probe stays as plain data | preferred |
| rejected | Executes the injected probe on clean input | dispreferred |
Pairing the two gives a (chosen, rejected) signal for DPO.
Run CleanAlpaca_to_DPO.py (alpaca) or SEP_to_DPO.py (sep) to produce {name}_injected_diff_output.json. Each request has instruction, clean_input, injected_input, injected_probe.
Run this script over the injected dataset.
- Load injected requests from
{name}_injected_diff_output.json. process_chosenwraps input as<instruction>...</instruction><start of data>...<end of data>, strips theINSISTENCEmarker, and queries the model with a system message enforcing data/instruction separation.- If
--no_judgeis off, an LLM judge (tasktracker_judge_prompt2.txt) checks the chosen response:INCLUDEDmeans the injected probe was reflected/executed in the answer (undesirable for the preferred response),NOT INCLUDEDmeans it was not. On"INCLUDED"it retries once, telling the model to treat the probe as inert data and perform only the original task.
- If
process_rejectedfeeds theinjected_probeas a developer message overclean_input, producing the non-compliant (injected) response.build_dpo_pairsjoins chosen and rejected on(instruction, input), then the result is shuffled and saved.
python data_curation_drip.py --dataset alpaca # or: sep
python data_curation_drip.py --dataset alpaca --no_judge # ablation| Flag | Default | Meaning |
|---|---|---|
--dataset |
alpaca |
alpaca or sep |
--no_judge |
off | ablation, skip judge validation/retry |
--batch_size |
100 | requests per checkpoint |
--max_concurrent |
8 | concurrent API calls |
Requires OPENAI_API_KEY. Judge prompt loaded from ./data_generation/tasktracker_judge_prompt2.txt.
{name}_injected_diff_output_retrieved{suffix}.jsonchosen{name}_injected_executed_retrieved.jsonrejected{name}_dpo{suffix}.jsonfinal DPO pairs
suffix = _ablate_no_judge when --no_judge is set.
- Async + checkpointing.
run_batchresumes from existing output; processing is concurrent, gated by a semaphore. - Ablation design.
--no_judgeisolates the contribution of the judge-based validation/retry step on chosen quality.