[misc]: model_id is the only load key — HF repo strings are card ingredients, never resolvable

This commit is contained in:
SolitaryThinker
2026-07-22 16:06:59 -07:00
parent ac11912063
commit dcec5644c2
3 changed files with 26 additions and 67 deletions
+14 -39
View File
@@ -1,16 +1,13 @@
"""The catalog — one place that maps names to (card, pipeline builder).
Identity policy (three levels):
Identity policy (two levels, nothing else resolves):
* ``model_id`` is the PRIMARY identity — it names a *servable* (weights plus
loop semantics, precision regime, conventions, defaults). One HF repo can
back many cards (base / distilled / precision variants) and one card can
draw from many repos (the aligned Wan card loads the official-layout DiT
and the diffusers-layout encoder/VAE), so repo strings cannot be identities.
* HF repo strings are *ingredients* (``card.weights``, ``ComponentSpec.source``)
accepted here as a convenience alias — but only while unambiguous. As soon
as two cards reference the same repo, resolving by that repo fails with the
candidate list; it never picks silently.
* ``model_id`` is THE identity — it names a *servable* (weights plus loop
semantics, precision regime, conventions, defaults). HF repo strings are
ingredients on the card (``card.weights``, ``ComponentSpec.source``), never
load keys: one repo can back many cards (base / distilled / precision
variants) and one card can draw from many repos (the aligned Wan card loads
the official-layout DiT and the diffusers-layout encoder/VAE).
* ``card.digest()`` is the machine identity: evidence records, T1 baselines,
and environment manifests key on it, never on names.
@@ -33,32 +30,10 @@ PIPELINES: dict[str, Callable[[], Any]] = {
}
def _build_aliases(cards: dict[str, Any]) -> dict[str, list[str]]:
"""HF repo string -> model_ids referencing it (as card weights or as a
per-component source). Values with several ids are ambiguous aliases."""
out: dict[str, list[str]] = {}
for card in cards.values():
refs = {card.weights} | {s.source for s in card.components.values() if s.source}
for ref in sorted(refs):
ids = out.setdefault(ref, [])
if card.model_id not in ids:
ids.append(card.model_id)
return out
_ALIASES = _build_aliases(CARDS)
def resolve(name: str) -> tuple[ModelCard, Callable[[], Any]]:
"""model_id (primary), or an unambiguous HF repo alias -> (card, pipeline
builder)."""
if name in CARDS:
return CARDS[name], PIPELINES[name]
hits = _ALIASES.get(name, [])
if len(hits) == 1:
return CARDS[hits[0]], PIPELINES[hits[0]]
if hits:
raise KeyError(f"{name!r} is a weights repo referenced by several cards "
f"{hits} — load by model_id")
raise KeyError(f"unknown model {name!r}; known ids: {sorted(CARDS)}; "
f"known repo aliases: {sorted(_ALIASES)}")
def resolve(model_id: str) -> tuple[ModelCard, Callable[[], Any]]:
"""model_id -> (card, pipeline builder). Only model ids resolve — pass an
HF repo string and you get the catalog, not a guess."""
if model_id not in CARDS:
raise KeyError(f"unknown model {model_id!r}; known ids: {sorted(CARDS)} "
f"(HF repo strings are card ingredients, not load keys)")
return CARDS[model_id], PIPELINES[model_id]
+4 -3
View File
@@ -117,8 +117,9 @@ class Model:
f"digest={self.card.digest()})")
def load(model: str, *, root: str | None = None, device: str | None = None) -> Model:
"""Resolve a model id or HF repo id, load it resident, return the handle."""
def load(model_id: str, *, root: str | None = None, device: str | None = None) -> Model:
"""Resolve a model id from the catalog, load it resident, return the
handle. HF repo strings are card ingredients, not load keys."""
from fastvideo2.registry import resolve
card, build_pipeline = resolve(model)
card, build_pipeline = resolve(model_id)
return Model(card, build_pipeline(), _load_instance(card, root=root, device=device))
+8 -25
View File
@@ -1,9 +1,7 @@
"""T0: the identity policy — model_id primary, HF repos as unambiguous aliases."""
from types import SimpleNamespace
"""T0: the identity policy — model_id is the only load key."""
import pytest
from fastvideo2.registry import CARDS, _build_aliases, resolve
from fastvideo2.registry import CARDS, PIPELINES, resolve
from fastvideo2.wan21 import WAN21_T2V_1_3B
@@ -12,31 +10,16 @@ def test_resolve_by_model_id():
assert card is WAN21_T2V_1_3B and callable(build)
def test_resolve_by_weights_repo_alias():
card, _ = resolve("Wan-AI/Wan2.1-T2V-1.3B-Diffusers")
assert card.model_id == "wan2.1-t2v-1.3b"
def test_hf_repo_strings_do_not_resolve():
for repo in ("Wan-AI/Wan2.1-T2V-1.3B-Diffusers", "Wan-AI/Wan2.1-T2V-1.3B"):
with pytest.raises(KeyError, match="not load keys"):
resolve(repo)
def test_resolve_by_component_source_alias():
# the official-layout DiT repo is an ingredient of the same card
card, _ = resolve("Wan-AI/Wan2.1-T2V-1.3B")
assert card.model_id == "wan2.1-t2v-1.3b"
def test_unknown_name_lists_ids_and_aliases():
def test_unknown_id_lists_catalog():
with pytest.raises(KeyError, match="known ids"):
resolve("no/such-model")
def test_ambiguous_repo_alias_fails_closed():
def fake(mid):
spec = SimpleNamespace(source="")
return SimpleNamespace(model_id=mid, weights="acme/shared-repo",
components={"c": spec})
aliases = _build_aliases({"a": fake("card-a"), "b": fake("card-b")})
assert aliases["acme/shared-repo"] == ["card-a", "card-b"] # resolve() would error
resolve("no-such-model")
def test_every_card_id_has_a_pipeline():
from fastvideo2.registry import PIPELINES
assert set(CARDS) == set(PIPELINES)