hiyouga/LlamaFactory · error · ValueError
DPO training dataset is empty: {dataset_path}
Error message
DPO training dataset is empty: {dataset_path} What it means
ValueError from _validate_dpo_dataset_format (dpo_trainer.py:73) when the non-streaming train DataEngine has zero samples. It is an early, explicit check so the user sees a clear message at trainer construction instead of a confusing empty-dataloader failure mid-run. Streaming datasets are exempted because their length cannot be known up front.
Source
Thrown at src/llamafactory/v1/trainers/dpo_trainer.py:73
ref_rejected_logps: Log-probabilities from the reference model for rejected responses.
beta: Temperature / scaling factor for the DPO loss.
label_smoothing: Label smoothing factor in [0, 1].
Returns:
Per-sample element-wise loss tensor.
"""
chosen_logratios = policy_chosen_logps - ref_chosen_logps
rejected_logratios = policy_rejected_logps - ref_rejected_logps
logits = chosen_logratios - rejected_logratios
return -F.logsigmoid(beta * logits) * (1 - label_smoothing) - F.logsigmoid(-beta * logits) * label_smoothing
def _validate_dpo_dataset_format(train_dataset: DataEngine, dataset_path: str) -> None:
if train_dataset.streaming:
return
if len(train_dataset) == 0:
raise ValueError(f"DPO training dataset is empty: {dataset_path}")
sample = train_dataset[0]
if "chosen_messages" in sample and "rejected_messages" in sample:
return
dataset_name = sample.get("_dataset_name", "unknown")
sample_keys = sorted(sample.keys())
raise ValueError(
"DPO training requires pair-format samples containing chosen/rejected responses. "
f"First sample from dataset '{dataset_name}' has keys: {sample_keys}. "
"Please use pair data (e.g. a dataset with chosen_messages/rejected_messages)."
)
class DPOTrainer(BaseTrainer):
def __init__(
self,
args: TrainingArguments,View on GitHub (pinned to f28afaf635)
Solutions
- Load the dataset manually (DataEngine or datasets.load_dataset) and print len() to confirm it is non-empty before constructing the trainer.
- Check dataset_info.json entries, filtering options, and max_samples so samples are not all discarded.
- If the dataset is genuinely streaming, ensure train_dataset.streaming is True so the check is bypassed.
- Inspect the first raw row to verify the expected columns exist under the names the converter maps.
Defensive patterns
Strategy: validation
Validate before calling
assert train_dataset.streaming or len(train_dataset) > 0, f"dataset {dataset_path} is empty after preprocessing" Prevention
- Log len(train_dataset) after preprocessing in every training script.
- Dry-run the data pipeline on a small slice before a full launch.
When it happens
Trigger: Calling DPOTrainer with a DataEngine whose filtered/processed dataset has 0 rows: empty dataset file, all samples filtered out by a max-samples or filter setting, or a dataset_info entry pointing at a file with no records.
Common situations: max_samples smaller than the skip offset; a converter/template dropping every sample; wrong dataset name in dataset_info.json resolving to an empty file; train/prompt column names not matching so 0 rows survive preprocessing.
Related errors
- DPO training requires pair-format samples containing chosen/
- RM training dataset is empty: {dataset_path}
- RM training requires pair-format samples containing chosen/r
- Unknown mixing strategy: {data_args.mix_strategy}.
- Cannot specify `val_size` if `eval_dataset` is not None.
AI-assisted analysis of hiyouga/LlamaFactory@f28afaf635 (2026-08-14).
Data as JSON: /api/errors/786b3d2233621db9.
Report an issue: GitHub.