Saving and loading models

XGBoost · Essentials · 7 min

Production models must be reloadable reliably, ideally independent of Python pickles.

XGBoost has its own model format, separate from Python pickling:

  • model.save_model("model.json") writes the trees and parameters as JSON, readable by any XGBoost binding (Python, R, JVM, C) and compatible across XGBoost versions,
  • model.save_model("model.ubj") writes the same content as binary UBJSON: smaller and faster to load,
  • XGBClassifier().load_model("model.json") or xgb.Booster(model_file="model.json") loads it back.

The scikit-learn wrapper stores extra attributes it needs (such as the classes and the best iteration from early stopping) inside the file, so loading into a fresh XGBClassifier restores a usable estimator.

When should you pickle instead? If the model is inside a scikit-learn Pipeline with preprocessing steps, you typically save the whole pipeline with joblib. That works, but it ties the file to your library versions, so record them; and only load pickles you trust. A common compromise is to save the XGBoost model in JSON and the rest of the pipeline separately.

The older binary .deprecated format is gone; always use .json or .ubj extensions. To inspect what a model learned, booster.get_dump() or booster.trees_to_dataframe() list every tree's splits.

Example

import numpy as np
from sklearn.datasets import load_iris
from xgboost import XGBClassifier

X, y = load_iris(return_X_y=True)
model = XGBClassifier(n_estimators=50, max_depth=3).fit(X, y)
model.save_model("iris_xgb.json")            # portable, version-independent

loaded = XGBClassifier()
loaded.load_model("iris_xgb.json")
print(np.array_equal(model.predict(X), loaded.predict(X)))   # True
print(loaded.classes_)                       # [0 1 2]

trees = loaded.get_booster().trees_to_dataframe()
print(trees["Tree"].nunique())               # 150 (50 rounds x 3 classes)

Remember

  • save_model to .json or .ubj is portable across versions and languages
  • Load into a fresh estimator with load_model
  • Pickle/joblib only for whole pipelines, with pinned versions

Watch out for

  • Pickling a bare XGBoost model and failing to load it after upgrading.

Check yourself

  1. Why prefer model.save_model("m.json") over pickle for an XGBoost model?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: xgboost.readthedocs.io/en/stable/tutorials/saving_model.html

Builds on

Unlocks

Nothing builds on this yet.