Files
iomgaa 58d75cc56a 层1/T1: SFTConfig dataclass 与构造校验(docs/02 §4)
- ars_opd/configs.py: 冻结 dataclass,机器路径无默认强制显式传入;
  双预算/enable_thinking/lr 差异均按 §7 规范标注
- __post_init__ 构造即校验,防"completion 预算为零→loss 恒 0"静默空训练
- tests/test_configs.py: 6 个校验测试

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 04:40:45 -04:00

50 lines
1.3 KiB
Python

"""SFTConfig 的构造校验测试(层 1 / T1)。
只测"配置错误必须在构造时炸"这一条约定;参数语义本身没有逻辑可测。
"""
import dataclasses
import pytest
from ars_opd.configs import SFTConfig
def make(**overrides):
"""最小合法配置;单测只关心被覆盖的那个字段。"""
base = dict(dataset_path="dummy.parquet", output_dir="/tmp/dummy")
base.update(overrides)
return SFTConfig(**base)
def test_合法配置可构造():
cfg = make()
assert cfg.max_length > cfg.max_prompt_length
def test_prompt预算吞掉总预算时报错():
# 这是最危险的静默失败:completion 预算为 0 → labels 全 -100 → loss 恒 0
with pytest.raises(ValueError, match="max_prompt_length"):
make(max_prompt_length=4096, max_length=4096)
def test_非法学习率报错():
with pytest.raises(ValueError, match="learning_rate"):
make(learning_rate=0.0)
def test_非法子集大小报错():
with pytest.raises(ValueError, match="subset_size"):
make(subset_size=0)
def test_非法max_steps报错():
with pytest.raises(ValueError, match="max_steps"):
make(max_steps=0)
def test_配置冻结不可变():
cfg = make()
with pytest.raises(dataclasses.FrozenInstanceError):
cfg.learning_rate = 1e-3