LC_8 / app /model_loader.py
github-actions[bot]
Deploy API from GitHub Actions
4e13ce7
Raw History Blame Contribute Delete
3.46 kB
import os
from pathlib import Path
from typing import Any
import mlflow
import mlflow.lightgbm
import onnxruntime as ort
_model: Any | None = None
def get_model_runtime() -> str:
return os.environ.get("MODEL_RUNTIME", "onnx").lower()
def _default_local_model_path() -> Path:
artifact_root = Path.cwd() / "mlflow" / "artifacts" / "models"
candidates = sorted(artifact_root.glob("*/artifacts/MLmodel"))
if not candidates:
raise FileNotFoundError(f"No local MLflow model found under {artifact_root}")
return candidates[0].parent
def _default_onnx_model_path() -> Path:
return Path.cwd() / "models" / "onnx" / "home_credit_lightgbm.onnx"
def load_onnx_model() -> ort.InferenceSession:
onnx_model_path = Path(
os.environ.get("ONNX_MODEL_PATH", str(_default_onnx_model_path()))
)
if not onnx_model_path.exists():
raise FileNotFoundError(f"ONNX model not found: {onnx_model_path}")
model = ort.InferenceSession(
str(onnx_model_path),
providers=["CPUExecutionProvider"],
)
print(f"Model loaded from ONNX Runtime: {onnx_model_path}")
return model
def load_lightgbm_model() -> Any:
mlflow_tracking_uri = os.environ.get(
"MLFLOW_TRACKING_URI",
f"sqlite:///{Path.cwd() / 'mlflow' / 'mlflow.db'}",
)
model_name = os.environ.get("MODEL_NAME", "home_credit_scoring")
model_version = os.environ.get("MODEL_VERSION", "1")
local_model_uri = os.environ.get("LOCAL_MODEL_URI")
mlflow.set_tracking_uri(mlflow_tracking_uri)
registry_model_uri = f"models:/{model_name}/{model_version}"
if local_model_uri:
try:
model = mlflow.lightgbm.load_model(local_model_uri)
print(f"Model loaded from local MLflow artifact: {local_model_uri}")
return model
except Exception as local_error:
raise RuntimeError(
f"Failed to load model from LOCAL_MODEL_URI '{local_model_uri}'. "
f"Error: {local_error}"
) from local_error
try:
model = mlflow.lightgbm.load_model(registry_model_uri)
print(f"Model loaded from MLflow Registry: {registry_model_uri}")
return model
except Exception as registry_error:
fallback_path = _default_local_model_path()
try:
model = mlflow.lightgbm.load_model(str(fallback_path))
print(f"Model loaded from local MLflow artifact: {fallback_path}")
return model
except Exception as local_error:
raise RuntimeError(
f"Failed to load model from registry '{registry_model_uri}' "
f"or local artifact '{fallback_path}'. "
f"Registry error: {registry_error}. Local error: {local_error}"
) from local_error
def load_model() -> Any:
"""Load the configured model runtime once."""
global _model
if _model is not None:
return _model
runtime = get_model_runtime()
if runtime == "onnx":
_model = load_onnx_model()
return _model
if runtime == "lightgbm":
_model = load_lightgbm_model()
return _model
raise ValueError(
f"Unsupported MODEL_RUNTIME '{runtime}'. "
"Expected 'onnx' or 'lightgbm'."
)
def get_model() -> Any:
"""Get the loaded model."""
if _model is None:
raise RuntimeError("Model not loaded. Call load_model() first.")
return _model