OC_P8 / scripts /export_to_onnx.py
KLEB38's picture
Upload folder using huggingface_hub
f63ae60 verified
Raw
History Blame Contribute Delete
2.34 kB
"""Convert the LightGBM credit-scoring model to ONNX format.
Reads `models/model.joblib`, unwraps the MLflow PyFunc layer if present,
converts the underlying LightGBM model to ONNX via `onnxmltools`, and writes
`models/model.onnx`.
Run:
uv run python scripts/export_to_onnx.py
"""
from __future__ import annotations
import argparse
import json
from pathlib import Path
import joblib
from onnxmltools import convert_lightgbm
from onnxmltools.convert.common.data_types import FloatTensorType
ROOT = Path(__file__).resolve().parents[1]
DEFAULT_MODEL_PATH = ROOT / "models" / "model.joblib"
DEFAULT_FEATURE_NAMES_PATH = ROOT / "models" / "feature_names.json"
DEFAULT_OUT_PATH = ROOT / "models" / "model.onnx"
def export(
model_path: Path,
feature_names_path: Path,
out_path: Path,
target_opset: int = 13,
) -> Path:
"""Convert LightGBM joblib → ONNX file. Returns the output path."""
model = joblib.load(model_path)
raw_model = model.get_raw_model() if hasattr(model, "get_raw_model") else model
feature_names = json.loads(feature_names_path.read_text())
n_features = len(feature_names)
# ONNX requires a fixed-shape input declaration. None = dynamic batch dim.
initial_types = [("input", FloatTensorType([None, n_features]))]
onnx_model = convert_lightgbm(
raw_model,
initial_types=initial_types,
target_opset=target_opset,
zipmap=False, # Output raw probability array instead of list-of-dicts.
)
out_path.parent.mkdir(parents=True, exist_ok=True)
out_path.write_bytes(onnx_model.SerializeToString())
return out_path
def main() -> None:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--model", type=Path, default=DEFAULT_MODEL_PATH)
parser.add_argument(
"--feature-names", type=Path, default=DEFAULT_FEATURE_NAMES_PATH
)
parser.add_argument("--out", type=Path, default=DEFAULT_OUT_PATH)
parser.add_argument("--opset", type=int, default=13)
args = parser.parse_args()
out = export(
model_path=args.model,
feature_names_path=args.feature_names,
out_path=args.out,
target_opset=args.opset,
)
size_mb = out.stat().st_size / (1024 * 1024)
print(f"Wrote {out} ({size_mb:.2f} MB)")
if __name__ == "__main__":
main()