31.4 Modelljelölt, jóváhagyás és registry

31.4.1 Cél és konkrét helyzet

A Northstar prediktív projektben már van egy működő modell, a northstar-late-v2, amely rendeléskor becsüli annak valószínűségét, hogy a kézbesítés 7 napnál tovább tart. A Modellartefaktum és betöltési határ egységben ezt a pipeline-t séma- és verzióinformációval együtt mentettük, és betöltési ellenőrzést végeztünk. Most új jelölt érkezett: a northstar-late-v3 logisztikus regresszió. A rögzített, purged teszthalmazon a v3 AUC-értéke 0,66, a v2-é 0,63. A feladat nem új statisztikai elemzés, hanem az üzembe helyezési döntés: regisztrálni a jelöltet, felülvizsgálni, majd csak teljesült feltételek esetén championná tenni, világos visszaállítási úttal.

Megfigyelési egység: egy rendelés. Bemenet a rendeléskori feature-vektor, kimenet a pred_prob (késői kézbesítés becsült valószínűsége 0 és 1 között) és a pred_class (0/1). Az előzetes eredménybecslés: ha a v3 AUC 0,66, és a belépési küszöb 0,65, akkor a challenger jogosult a review-ra, de ez még nem jelenti automatikusan a champion cserét. A fejezet célja, hogy ezt a döntést nyomon követhető, visszavonható adminisztratív folyamattá tegye.

31.4.2 Fogalmi magyarázat: registry, candidate, champion, review, rollback, lineage

A modellnyilvántartás (model registry) olyan nyilvántartó réteg, amely a modellek életciklus-állapotát tárolja. A leggyakoribb állapotok: staging (kipróbálás alatt), production (éles kiszolgálás), archived (archivált). A registry adminisztratív állapotot rögzít; nem számol újra metrikát, nem bizonyít tudományos minőséget. Egy bejegyzés megléte önmagában csak annyit mond, hogy valaki regisztrálta a modellt.

A modelljelölt (candidate) egy konkrét, verzióval ellátott modellartefaktum, amelyhez tartozik:

A champion/challenger minta két szerepet különít el. A champion (elsődleges modell) az, amely jelenleg kiszolgálja a predikciókat. A challenger (kihívó) az új jelölt, amely a champion helyére pályázik. A váltás nem attól függ, hogy a challengernek valamivel jobb egyetlen metrikája; a belépési feltételnek explicitnek kell lennie, például:

Az AUC itt a modell pontszámának rangsorolási képességét méri: AUC=P(ŝi>ŝj∣yi=1,yj=0)\mathrm{AUC} = P(\hat{s}_i > \hat{s}_j \mid y_i=1, y_j=0), ahol ŝ\hat{s} a modell által adott pontszám, yy pedig a bináris cél. Ez egyetlen szám, nem helyettesíti a kalibráció, a szegmensenkénti teljesítmény vagy az üzleti költség vizsgálatát.

A review (felülvizsgálat, jóváhagyás) az a lépés, amelyben emberi döntéshozó vagy automatizált ellenőrzőlista alapján a challenger státuszt kap. A review lehetséges állapotai: pending, approved, rejected. A review-nak ellenőriznie kell:

  1. a teljesítményfeltételt,
  2. a sémát és a predikciós szerződést,
  3. a lineage teljességét,
  4. a reprodukálhatósági nyilatkozatot.

A rollback (visszaállítás) azt az eljárást jelenti, amellyel egy production modellt egy korábbi, jóváhagyott változatra cserélünk vissza. A visszaállítás is állapotváltozás, ezért ahhoz is feltétel és review kell. Tipikus visszaállítási feltétel: a production challenger 7 napos monitorablakban mért AUC-ja legalább 0,02-del alacsonyabb a regisztrációs AUC-nál, vagy séma-/batchhiba lép fel.

A lineage (származási lánc) a modellhez vezető összes bemenet verziózott láncolata: adatverzió, splitmanifest, kód commit, környezet, tanítási paraméterek, kiértékelési eredmény. A SQL-transzformáció és dbt helye egységben az SQL-transzformációk lineage-ét, az Adatverzió és splitmanifest egységben a splitmanifestet, az Adatkezelés és reprodukálhatóság külső modellnél egységben a külső modell verziózását tárgyaltuk. A registry akkor hasznos, ha a lineage alapján bármelyik modellváltozatot újra tudjuk építeni, vagy meg tudjuk indokolni, miért nem.

Kis kézi kontroll: ha a v3 AUC-ja 0,66, a champion v2 AUC-ja 0,63, a belépési küszöb max(0,65,0,63+0,01)=0,65\max(0{,}65, 0{,}63+0{,}01)=0{,}65, akkor a v3 teljesíti a teljesítményfeltételt. Ha viszont a séma eggyel több oszlopot tartalmaz, a jelölt már a review előtt elutasítható.

31.4.3 Teljes minimális munkapélda: hash-alapú regisztrációs kártya

Az MLflow és a DVC hasznos, de a laborban hash-alapú, helyi manifestet használunk, mert nincs szükség külső szolgáltatásra. A következő kód szemléltető: a hash-értékek helyettesítők, a kimenet elméletileg várt, nem mért. Platform: helyi CPU, munkakönyvtár lab/, Python 3.12.

A register.py beolvassa a mentett pipeline metaadatait, kiszámolja az SHA-256-ot, validálja a review-feltételeket, és előállítja a modellátadási lapot. A pipeline betöltését a Modellartefaktum és betöltési határ egység load check lépése már elvégezte; itt csak a metaadatokkal dolgozunk.

"""Szemléltető hash-alapú modellregisztráció. Nem futtatott példa."""
import hashlib
import json
from datetime import datetime, timezone
from pathlib import Path

ARTIFACT = Path("artifacts/northstar_late_pipeline_v3.pkl")
SPLIT = Path("artifacts/split.json")
METRICS = Path("artifacts/metrics_v3.json")

REQUIRED_INPUT = [
    "distance_km", "priority_flag", "basket_minor", "quantity_sum",
    "account_age_days", "segment", "region", "acquisition_channel",
]


def sha256_file(path: Path) -> str:
    return hashlib.sha256(path.read_bytes()).hexdigest()


def build_card() -> dict:
    metrics = json.loads(METRICS.read_text())
    split_meta = json.loads(SPLIT.read_text())
    return {
        "model_id": "northstar-late-v3",
        "created_at": datetime.now(timezone.utc).isoformat(),
        "artifact_sha256": sha256_file(ARTIFACT),
        "input_schema": REQUIRED_INPUT,
        "output_schema": {"pred_prob": "float64", "pred_class": "int64"},
        "metrics": metrics,
        "lineage": {
            "data_ref": "northstar/2026-10-20/split.json",
            "code_ref": "main@a1b2c3d4",
            "split_sha256": split_meta.get("hash"),
            "training_script": "train_logreg.py",
            "env": "python=3.12.4,scikit-learn=1.5.2",
        },
        "stage": "staging",
        "review": "pending",
    }


def validate_card(card: dict, champion_auc: float) -> tuple[bool, list[str]]:
    errors = []
    if len(card["artifact_sha256"]) != 64:
        errors.append("artifact hash nem 64 hexa karakter")
    if card["input_schema"] != REQUIRED_INPUT:
        errors.append("bemeneti séma eltér a szerződéstől")
    if not all(card["lineage"].values()):
        errors.append("lineage hiányos")
    if card["metrics"]["auc_test"] < max(0.65, champion_auc + 0.01):
        errors.append("teljesítményfeltétel nem teljesül")
    if card["stage"] != "staging" or card["review"] != "pending":
        errors.append("helytelen kezdeti állapot")
    return (len(errors) == 0), errors


if __name__ == "__main__":
    # A champion v2 ismert, rögzített teszt AUC-ja.
    card = build_card()
    ok, errors = validate_card(card, champion_auc=0.63)
    Path("artifacts/model_card_v3.json").write_text(json.dumps(card, indent=2))
    print("Validation:", "PASS" if ok else "FAIL")
    for e in errors:
        print(" -", e)

Elméletileg várt kimenet, ha a metaadatok rendben vannak:

Validation: PASS

A generált regisztrációs kártya (rövidítve, a hash-ek szemléltető értékek):

{
  "model_id": "northstar-late-v3",
  "created_at": "2026-10-20T10:00:00+00:00",
  "artifact_sha256": "a4f9c2e7... (64 hexa karakter)",
  "input_schema": [
    "distance_km", "priority_flag", "basket_minor", "quantity_sum",
    "account_age_days", "segment", "region", "acquisition_channel"
  ],
  "output_schema": {"pred_prob": "float64", "pred_class": "int64"},
  "metrics": {"auc_test": 0.66, "n_test": 300, "threshold": 0.45},
  "lineage": {
    "data_ref": "northstar/2026-10-20/split.json",
    "code_ref": "main@a1b2c3d4",
    "split_sha256": "b7e1... (64 hexa karakter)",
    "training_script": "train_logreg.py",
    "env": "python=3.12.4,scikit-learn=1.5.2"
  },
  "stage": "staging",
  "review": "pending"
}

A registry állapota ezután:

{
  "champion": "northstar-late-v2",
  "challenger": "northstar-late-v3",
  "review": "pending",
  "rollback_to": null
}

A modellátadási lap (részlet) a feltételekkel:

Feltétel Elvárt érték Ellenőrzés
Teszt AUC ≥0,65\geq 0{,}65 és ≥\geq champion AUC + 0,01 metrics.json
Bemeneti séma pontosan a rendeléskori 8 oszlop input_schema
Lineage minden mező kitöltve lineage
Visszaállítás ha monitor AUC ≤\leq regisztrációs AUC −0,02-0{,}02 rollback_to

31.4.4 Eredmény értelmezése

A fenti folyamat invariánsai:

Kézi kontroll: a v3 AUC 0,66, a belépési küszöb 0,65, a különbség 0,01. Ha a séma eggyel több oszlopot tartalmazna, a validate_card azonnal FAIL-t adna, függetlenül az AUC-tól. Ez mutatja, hogy a regisztráció nem helyettesíti a tudományos értékelést, hanem azt a megfelelő lépésben ellenőrzi.

A registry állapot és a tudományos minőség elkülönülése itt konkrét: a model_card_v3.json létezése és a stage: "staging" bejegyzés csak azt igazolja, hogy a jelölt átment a formai és teljesítménybelépési szűrőn. Azt, hogy a modell valóban jól általánosít, a rögzített teszthalmaz, a kalibrációs görbe és a szegmensvizsgálat igazolja, amelynek eredményét a kártya metrics mezője hivatkozza.

A champion címke módosítható mutató. Auditálható kiadáshoz az immutábilis modellazonosítót és az engedélyezés idejét is őrizzük meg.

31.4.5 Feladatok

31.4.5.1 1. feladat: Értelmezés

A registry-ben a northstar-late-v4 bejegyzés állapota production, review-ja approved, AUC-ja 0,68. Egy kolléga azt állítja: „Mivel a registry szerint production és approved, ez a modell biztosan jó döntést ad.” Nevezz meg legalább két okot, amiért ez az állítás téves, és adj egy konkrét ellenőrzési lépést, amely a registry-n kívül szükséges.

31.4.5.2 2. feladat: Implementálás

Egészítsd ki a register.py kódját egy check_monitor_and_rollback() függvénnyel. A függvény a production challenger 7 napos monitorablakban mért AUC-ját kapja paraméterként, és ha az legalább 0,02-del alacsonyabb, mint a regisztrációs auc_test, akkor a registry állapotában a rollback_to mezőt a korábbi champion azonosítójára állítja, és a review-t pending-re teszi. Ha a monitor AUC elfogadható, a függvény None-t ad vissza. Írd le a függvényt, és mutasd meg, hogyan hívnád meg a northstar-late-v3 esetén, ha a monitor AUC 0,61.

31.4.5.3 3. feladat: Hibadiagnózis

Az alábbi manifest hibás:

{
  "model_id": "northstar-late-v5",
  "stage": "production",
  "review": "none",
  "metrics": {"auc_test": 0.99},
  "lineage": {},
  "artifact_sha256": "1234"
}

Sorold fel az összes hibát, valószínűsítsd, mi okozhatta, és írd le, milyen validációs lépéssel lehet megelőzni.

31.4.5.4 4. feladat: Megváltozott feltétel

A csapat újragenerálta a teszthalmazt, és a northstar-late-v3 AUC-ja az új kiértékelésben 0,61. A registry model_card_v3.json még a régi 0,66-ot tárolja. Mi a helyes eljárás? Milyen mezőket kell frissíteni, és milyen feltétellel engedhető a champion csere?

31.4.6 Megoldások és indoklás

31.4.6.1 1. megoldás

Téves az állítás, mert: (a) a registry approved állapota csak a review-folyamat lezárását jelenti, nem a modell aktuális teljesítményét; (b) a teszt AUC egy adott, rögzített időablakra vonatkozik, és nem garantálja az éles forgalomban mért teljesítményt; (c) a döntési cél megváltozhat, például a küszöböt más költségfüggvényhez kalibrálták. Szükséges ellenőrzés: a legfrissebb monitor adatokon számolt AUC és kalibrációs görbe, valamint a bemeneti adatok eloszlásának összehasonlítása a tanító eloszlással.

31.4.6.2 2. megoldás

def check_monitor_and_rollback(registry: dict, card: dict,
                               monitor_auc: float) -> dict | None:
    if monitor_auc <= card["metrics"]["auc_test"] - 0.02:
        registry["rollback_to"] = registry["champion"]
        registry["review"] = "pending"
        return registry
    return None

Használat:

monitor_auc = 0.61
result = check_monitor_and_rollback(registry, card, monitor_auc)
if result is not None:
    print("Rollback javasolt ide:", result["rollback_to"])

Elméletileg várt kimenet: Rollback javasolt ide: northstar-late-v2, mert 0,61≤0,66−0,02=0,640{,}61 \le 0{,}66 - 0{,}02 = 0{,}64. Megjegyzés: a tényleges rollback nem automatikus; a review-nak kell jóváhagynia.

31.4.6.3 3. megoldás

Hibák: a stage nem lehet production, ha a review nem approved; a review értéke nem none (a megengedett: pending, approved, rejected); a lineage üres; az AUC 0,99 gyanúsan magas, valószínűleg adatszivárgásra vagy hibás kiértékelésre utal; a hash nem 64 hexa karakter. Valószínű ok: valaki kézzel szerkesztette a manifestet, vagy egy hibás pipeline kimenetét regisztrálta. Megelőzés: a validate_card-hoz hasonló sémaellenőrzés, a hash hosszának és a megengedett állapotoknak az ellenőrzése, valamint a metrika plauzibilitási határának beállítása.

31.4.6.4 4. megoldás

A helyes eljárás: a régi kártya metrics mezőjét nem szabad felülírni, mert az a korábbi értékelés lenyomata. Új kiértékelést kell végezni, új kártyát kell létrehozni, és a challenger belépési feltételt az új AUC-val újra kell vizsgálni. Ha az új AUC 0,61, a belépési küszöb max(0,65,0,63+0,01)=0,65\max(0{,}65, 0{,}63+0{,}01)=0{,}65, tehát a v3 nem teljesíti a feltételt: a review rejected, a champion marad a v2. Frissítendő mezők: metrics, lineage.split_sha256, created_at, review.

31.4.7 Gyakori tévedés és ellenpélda

A leggyakoribb tévedés: a registry-bejegyzés automatikusan jó modellt bizonyít. Ellenpélda: a northstar-late-v5 regisztrálva van, stage: "production", review: "approved", de a metrikája AUC 0,99 egy olyan teszthalmazon, amely a tanító időszakkal átfedésben van. A registry szempontjából minden formai feltétel teljesül, a modell mégsem általánosít. Egy másik ellenpélda: a v3 championná vált, de a döntési küszöböt a tesztkészleten optimalizálták, így a valós forgalomban a modell túl sok hamis pozitív riasztást ad. Az Adatverzió és splitmanifest egységben tárgyalt splitintegritás és a Modellartefaktum és betöltési határ egységben bemutatott sémaellenőrzés itt kapcsolódik vissza: a registry csak akkor hasznos, ha a bemenő bizonyítékok maguk is megbízhatóak.

Önellenőrzés: ha a model_card.json stage mezője production, de nincs approved review, akkor a folyamat sérült; ha a lineage hiányos, a modell nem reprodukálható; ha a rollback feltétel nincs előre rögzítve, egy éles hibánál kapkodás lesz a döntés.

31.4.8 Rövid összefoglaló

A modellnyilvántartás a modell adminisztratív életciklusát kezeli, nem a tudományos minőség bizonyítékát. A candidate egy verziózott artefaktum hash-sel, sémával, metrikával és lineage-dzsel. A champion/challenger váltás explicit feltételekhez kötött: a challengernek teljesítenie kell a teljesítmény- és sémaküszöböt, majd review-n kell átmennie. A rollback előre rögzített monitorfeltétel alapján egy korábbi jóváhagyott modellre mutat. A lineage biztosítja az újraépíthetőséget és a hibakeresést. A következő alkalmazásban ezt a regisztrációs lépést konténerben és CI-folyamatban futtatjuk, hogy az átadás más gépen is ismételhető legyen.