refactor(tests): polish DPO example tests from PR #48

- Split the 22-assert config-values test into 3 focused tests
  (task+data, training hyperparams, LoRA config) so a deliberate
  example change surfaces in one targeted test, not a wall of asserts
- Add module docstring explaining why these tests lock the example state
- Add `from __future__ import annotations` (defensive; matches 14 other
  test modules in the project)
- Rename `f` -> `fh` in _load_jsonl to avoid shadowing short name
- Drop asserts on secondary fields (warmup_ratio, weight_decay, scheduler,
  logging_steps, etc.) -- they're tweakable knobs, not the example's
  teaching points; test brittleness > coverage here
This commit is contained in:
Alpamys 2026-04-23 12:22:52 +05:00
parent 0e69b210e3
commit a63e8875f0
1 changed files with 26 additions and 18 deletions

View File

@ -1,4 +1,12 @@
"""Tests for the DPO example config and sample data."""
"""Tests for the DPO example config and sample data.
These tests lock the example config + data to a working state so users who
follow README steps never hit a broken example. Values are asserted in
logical groups so a deliberate example change surfaces in one focused test
rather than a 22-line wall.
"""
from __future__ import annotations
import json
from pathlib import Path
@ -19,36 +27,36 @@ def test_dpo_example_config_loads():
assert isinstance(cfg, SoupConfig)
def test_dpo_example_config_values():
"""dpo_example.yaml should have the expected field values."""
def test_dpo_example_task_and_data():
"""Core task + data wiring: what matters for DPO to run at all."""
cfg = load_config(DPO_CONFIG_PATH)
assert cfg.base == "meta-llama/Llama-3.1-8B-Instruct"
assert cfg.task == "dpo"
assert cfg.data.train == "examples/data/dpo_sample.jsonl"
assert cfg.data.format == "dpo"
assert cfg.data.max_length == 2048
assert cfg.data.train == "examples/data/dpo_sample.jsonl"
assert cfg.base == "meta-llama/Llama-3.1-8B-Instruct"
def test_dpo_example_training_hyperparams():
"""Training hyperparameters match the example's advertised config."""
cfg = load_config(DPO_CONFIG_PATH)
assert cfg.training.epochs == 3
assert cfg.training.lr == 5e-6
assert cfg.training.dpo_beta == 0.1
assert cfg.training.quantization == "4bit"
assert cfg.training.batch_size == 4
assert cfg.training.gradient_accumulation_steps == 4
assert cfg.training.warmup_ratio == 0.1
assert cfg.training.weight_decay == 0.01
assert cfg.training.max_grad_norm == 1.0
assert cfg.training.optimizer == "adamw_torch"
assert cfg.training.scheduler == "cosine"
assert cfg.training.logging_steps == 10
assert cfg.training.save_steps == 100
def test_dpo_example_lora_config():
"""LoRA config matches the example's advertised rank/alpha."""
cfg = load_config(DPO_CONFIG_PATH)
assert cfg.training.lora.r == 16
assert cfg.training.lora.alpha == 32
assert cfg.training.lora.dropout == 0.05
assert cfg.training.lora.target_modules == "auto"
assert cfg.output == "./output_dpo_example/"
def test_dpo_sample_data_exists():
"""dpo_sample.jsonl should exist and be non-empty."""
"""dpo_sample.jsonl should exist and have the issue-#4 minimum of 5+ pairs."""
assert DPO_DATA_PATH.exists()
data = _load_jsonl(DPO_DATA_PATH)
assert len(data) >= 5, "Expected at least 5 preference pairs"
@ -92,5 +100,5 @@ def test_dpo_sample_data_converts():
def _load_jsonl(path: Path) -> list[dict]:
"""Load a JSONL file into a list of dicts."""
with open(path, encoding="utf-8") as f:
return [json.loads(line) for line in f if line.strip()]
with open(path, encoding="utf-8") as fh:
return [json.loads(line) for line in fh if line.strip()]