| 1 |
"""Every curated entry is well-formed and passes the audit-02 F04/F21 rules.""" |
| 2 |
|
| 3 |
from __future__ import annotations |
| 4 |
|
| 5 |
import re |
| 6 |
|
| 7 |
import pytest |
| 8 |
|
| 9 |
from dlm.base_models import BASE_MODELS, known_keys |
| 10 |
from dlm.base_models.registry import _ENTRIES |
| 11 |
|
| 12 |
_SHA_RE = re.compile(r"^[0-9a-f]{40}$") |
| 13 |
|
| 14 |
|
| 15 |
class TestLaunchTen: |
| 16 |
def test_minimum_launch_entries(self) -> None: |
| 17 |
# The original launch ten + PaliGemma (Sprint 35 v1). Additional |
| 18 |
# VL bases land in Sprint 35.3; this floor only enforces "don't |
| 19 |
# regress below what we've shipped". |
| 20 |
assert len(BASE_MODELS) >= 11 |
| 21 |
assert len(_ENTRIES) >= 11 |
| 22 |
|
| 23 |
def test_entries_keyed_by_key(self) -> None: |
| 24 |
for entry in _ENTRIES: |
| 25 |
assert BASE_MODELS[entry.key] is entry |
| 26 |
|
| 27 |
def test_known_keys_stable_ordering(self) -> None: |
| 28 |
keys = known_keys() |
| 29 |
assert isinstance(keys, tuple) |
| 30 |
assert list(keys) == list(BASE_MODELS.keys()) |
| 31 |
|
| 32 |
|
| 33 |
class TestRevisionPinning: |
| 34 |
"""Audit-02 F11: every registry entry has a real 40-char commit SHA.""" |
| 35 |
|
| 36 |
@pytest.mark.parametrize("entry", _ENTRIES, ids=lambda e: e.key) |
| 37 |
def test_revision_is_40char_hex(self, entry: object) -> None: |
| 38 |
assert _SHA_RE.fullmatch(entry.revision), ( # type: ignore[attr-defined] |
| 39 |
f"{entry.key} has non-conforming revision {entry.revision!r}" # type: ignore[attr-defined] |
| 40 |
) |
| 41 |
|
| 42 |
|
| 43 |
class TestLicenseFields: |
| 44 |
"""Audit-02 F04 + F21: license + gating fields populated correctly.""" |
| 45 |
|
| 46 |
@pytest.mark.parametrize("entry", _ENTRIES, ids=lambda e: e.key) |
| 47 |
def test_license_spdx_present(self, entry: object) -> None: |
| 48 |
assert entry.license_spdx # type: ignore[attr-defined] |
| 49 |
|
| 50 |
@pytest.mark.parametrize("entry", _ENTRIES, ids=lambda e: e.key) |
| 51 |
def test_gated_entries_have_license_url(self, entry: object) -> None: |
| 52 |
if entry.requires_acceptance: # type: ignore[attr-defined] |
| 53 |
assert entry.license_url, ( # type: ignore[attr-defined] |
| 54 |
f"{entry.key} is gated but has no license_url" # type: ignore[attr-defined] |
| 55 |
) |
| 56 |
|
| 57 |
def test_llama_entries_are_gated_and_nonredistributable(self) -> None: |
| 58 |
"""Explicit check: shipped Llama entries keep the Meta gating pattern.""" |
| 59 |
for key in ("llama-3.2-1b", "llama-3.2-3b", "llama-3.3-8b-instruct"): |
| 60 |
entry = BASE_MODELS[key] |
| 61 |
assert entry.requires_acceptance is True |
| 62 |
assert entry.redistributable is False |
| 63 |
|
| 64 |
def test_gemma2_entries_are_gated_and_nonredistributable(self) -> None: |
| 65 |
for key in ("gemma-2-2b-it", "gemma-2-9b-it"): |
| 66 |
entry = BASE_MODELS[key] |
| 67 |
assert entry.requires_acceptance is True |
| 68 |
assert entry.redistributable is False |
| 69 |
|
| 70 |
def test_apache_entries_are_open_and_redistributable(self) -> None: |
| 71 |
for key in ( |
| 72 |
"qwen2.5-0.5b", |
| 73 |
"qwen2.5-1.5b", |
| 74 |
"qwen2.5-coder-1.5b", |
| 75 |
"qwen3-1.7b", |
| 76 |
"qwen3-1.7b-thinking", |
| 77 |
"qwen3-4b", |
| 78 |
"qwen3-8b", |
| 79 |
"mixtral-8x7b-instruct", |
| 80 |
"smollm3-3b", |
| 81 |
"olmo-2-7b-instruct", |
| 82 |
"qwen2-audio-7b-instruct", |
| 83 |
"smollm2-135m", |
| 84 |
"smollm2-360m", |
| 85 |
"smollm2-1.7b", |
| 86 |
): |
| 87 |
entry = BASE_MODELS[key] |
| 88 |
assert entry.license_spdx == "Apache-2.0" |
| 89 |
assert entry.requires_acceptance is False |
| 90 |
assert entry.redistributable is True |
| 91 |
|
| 92 |
def test_phi_is_mit(self) -> None: |
| 93 |
for key in ("phi-3.5-mini", "phi-4-mini-reasoning"): |
| 94 |
assert BASE_MODELS[key].license_spdx == "MIT" |
| 95 |
|
| 96 |
|
| 97 |
class TestArchitectureShapes: |
| 98 |
"""Templates, gguf_arch, and target_modules match the architecture family.""" |
| 99 |
|
| 100 |
def test_qwen25_entries_use_qwen2_gguf_arch(self) -> None: |
| 101 |
for key, entry in BASE_MODELS.items(): |
| 102 |
# Audio-language Qwen2 variants carry a distinct gguf_arch |
| 103 |
# (no llama.cpp converter support) and a multi-modal template. |
| 104 |
if not key.startswith("qwen2.5") or entry.modality != "text": |
| 105 |
continue |
| 106 |
assert entry.gguf_arch == "qwen2" |
| 107 |
assert entry.architecture == "Qwen2ForCausalLM" |
| 108 |
assert entry.template == "chatml" |
| 109 |
|
| 110 |
def test_llama_entries_use_llama_gguf_arch(self) -> None: |
| 111 |
for key in ("llama-3.2-1b", "llama-3.2-3b", "llama-3.3-8b-instruct"): |
| 112 |
entry = BASE_MODELS[key] |
| 113 |
assert entry.gguf_arch == "llama" |
| 114 |
assert entry.architecture == "LlamaForCausalLM" |
| 115 |
assert entry.template == "llama3" |
| 116 |
|
| 117 |
def test_phi_uses_fused_qkv_target_modules(self) -> None: |
| 118 |
for key, template in (("phi-3.5-mini", "phi3"), ("phi-4-mini-reasoning", "phi4mini")): |
| 119 |
entry = BASE_MODELS[key] |
| 120 |
assert "qkv_proj" in entry.target_modules |
| 121 |
assert entry.gguf_arch == "phi3" |
| 122 |
assert entry.template == template |
| 123 |
|
| 124 |
def test_olmo2_uses_olmo2_converter_path(self) -> None: |
| 125 |
entry = BASE_MODELS["olmo-2-7b-instruct"] |
| 126 |
assert entry.gguf_arch == "olmo2" |
| 127 |
assert entry.architecture == "Olmo2ForCausalLM" |
| 128 |
assert entry.template == "olmo2" |
| 129 |
|
| 130 |
def test_gemma2_uses_gemma2_converter_path(self) -> None: |
| 131 |
for key in ("gemma-2-2b-it", "gemma-2-9b-it"): |
| 132 |
entry = BASE_MODELS[key] |
| 133 |
assert entry.gguf_arch == "gemma2" |
| 134 |
assert entry.architecture == "Gemma2ForCausalLM" |
| 135 |
assert entry.template == "gemma2" |
| 136 |
|
| 137 |
def test_size_gb_fp16_monotonic_within_family(self) -> None: |
| 138 |
qwen_sizes = [ |
| 139 |
BASE_MODELS[k].size_gb_fp16 for k in ("qwen2.5-0.5b", "qwen2.5-1.5b", "qwen2.5-3b") |
| 140 |
] |
| 141 |
assert qwen_sizes == sorted(qwen_sizes) |
| 142 |
qwen3_sizes = [ |
| 143 |
BASE_MODELS[k].size_gb_fp16 |
| 144 |
for k in ("qwen3-1.7b", "qwen3-1.7b-thinking", "qwen3-4b", "qwen3-8b") |
| 145 |
] |
| 146 |
assert qwen3_sizes == sorted(qwen3_sizes) |
| 147 |
smol_sizes = [ |
| 148 |
BASE_MODELS[k].size_gb_fp16 for k in ("smollm2-135m", "smollm2-360m", "smollm2-1.7b") |
| 149 |
] |
| 150 |
assert smol_sizes == sorted(smol_sizes) |
| 151 |
gemma_sizes = [BASE_MODELS[k].size_gb_fp16 for k in ("gemma-2-2b-it", "gemma-2-9b-it")] |
| 152 |
assert gemma_sizes == sorted(gemma_sizes) |