diff --git a/configs/model/moe_small.toml b/configs/model/moe_small.toml index c00edf3..1f5a6fd 100644 --- a/configs/model/moe_small.toml +++ b/configs/model/moe_small.toml @@ -1,4 +1,8 @@ -# Small MoE: ~1B active params, ~4B total (8 experts, top-2, all layers) +# MoE reference architecture: ~2.9B active params, ~9.2B total +# (8 experts, top-2, every layer). Used by convert_checkpoint.py for +# DCP <-> HuggingFace conversion. + +[model] dim = 2048 n_layers = 24 n_heads = 16 diff --git a/tests/unit/test_config.py b/tests/unit/test_config.py index 35ad244..f7378a7 100644 --- a/tests/unit/test_config.py +++ b/tests/unit/test_config.py @@ -4,6 +4,7 @@ import random import sys +from pathlib import Path import numpy as np import pytest @@ -724,6 +725,23 @@ def test_enum_from_toml(self): assert config.scheduler.name == SchedulerType.cosine assert isinstance(config.scheduler.name, SchedulerType) + @pytest.mark.parametrize( + "config_path", + sorted(str(p) for p in Path("configs").rglob("*.toml")), + ids=lambda p: str(p).replace("configs/", "").replace("/", ":"), + ) + def test_shipped_config_loads(self, config_path): + """Every TOML under configs/ must load. + + `configs/model/moe_small.toml` shipped without its `[model]` section + header and was unloadable from the day it was added, because no test + exercised the shipped presets. This sweeps all of them so the next one + cannot ship broken. Load only -- `validate()` needs a world size and is + covered separately. + """ + config = load_config(config_path, cli_args=[]) + assert config.model.dim > 0, f"{config_path} loaded but has no model dim" + def test_missing_toml_raises(self): with pytest.raises(FileNotFoundError): load_config("nonexistent.toml", cli_args=[])