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.
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: , ahol a modell által adott pontszám, 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:
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 , 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ó.
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 | és 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 regisztrációs AUC | rollback_to |
A fenti folyamat invariánsai:
staging és
pending, soha nem production.approved.rollback_to értéke null, amíg nincs
visszaállítási esemény.metrics mezőt: az AUC a
rögzített teszten mért érték, nem a regisztráció során újraszámolt
adat.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.
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.
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.
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.
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?
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.
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 NoneHaszná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
.
Megjegyzés: a tényleges rollback nem automatikus; a review-nak kell
jóváhagynia.
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.
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
,
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.
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.
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.