Skip to main content
Saving and loading trained Deep Learning models has multiple valuable uses. These models are often costly to train; storing a pre-trained model can help reduce costs as it can be loaded and reused to forecast multiple times. Moreover, it enables Transfer learning capabilities, consisting of pre-training a flexible model on a large dataset and using it later on other data with little to no training. It is one of the most outstanding πŸš€ achievements in Machine Learning 🧠 and has many practical applications. In this notebook we show an example on how to save and load NeuralForecast models. The two methods to consider are:
1. NeuralForecast.save: Saves models into disk, allows save dataset and config.
2. NeuralForecast.load: Loads models from a given path.
Important This Guide assumes basic knowledge on the NeuralForecast library. For a minimal example visit the Getting Started guide.
You can run these experiments using GPU with Google Colab. Open In Colab

1. Installing NeuralForecast

2. Loading AirPassengers Data

For this example we will use the classical AirPassenger Data set. Import the pre-processed AirPassenger from utils.

3. Model Training

Next, we instantiate and train three models: NBEATS, NHITS, and AutoMLP. The models with their hyperparameters are defined in the models list.
Produce the forecasts with the predict method.
We plot the forecasts for each model.

4. Save models

To save all the trained models use the save method. This method will save both the hyperparameters and the learnable weights (parameters). The save method has the following inputs:
  • path: directory where models will be saved.
  • model_index: optional list to specify which models to save. For example, to only save the NHITS model use model_index=[2].
  • overwrite: boolean to overwrite existing files in path. When True, the method will only overwrite models with conflicting names.
  • save_dataset: boolean to save Dataset object with the dataset.
For each model a single file is created:
  • [model_name]_[suffix].safetensors: the learnable weights, with the hyperparameters stored in the file’s metadata header.
Two files describe the rest of the state:
  • configuration.json: the NeuralForecast configuration, including which class each checkpoint holds.
  • dataset.json and dataset.safetensors: the stored dataset, when save_dataset=True.
Where model_name corresponds to the name of the model in lowercase (eg. nhits). We use a numerical suffix to distinguish multiple models of each class. In this example the names will be automlp_0, nbeats_0, and nhits_0.
Important The Auto models will be stored as their base model. For example, the AutoMLP trained above is stored as an MLP model, with the best hyparparameters found during tuning.

A note on the artifact format

Directories saved by version 3.3.0 and later hold safetensors weights and JSON metadata, and they are loaded without executing any code they contain. Earlier versions used pickle, which executes arbitrary code contained in the artifact when it is loaded. Reading one of those directories therefore requires you to say so:
Only do that for artifacts you trust. To convert an old directory once, instead of passing the flag every time:
This writes ./old_checkpoints_v2/, leaves the original untouched, and checks that the result loads with no pickle consent at all. It also takes a single checkpoint: python -m neuralforecast.migrate ./NHITS_0.ckpt. Two cases to be aware of:
  • A directory saved with save_dataset=True by an older version must be migrated. Its dataset.pkl stores tensors inside a plain pickle, and there is no way to read that safely. If you would rather not migrate, re-save with save_dataset=False and pass df to predict().
  • TimeLLM can no longer be saved or loaded. It resolves its llm argument through from_pretrained while being constructed, so an artifact could direct that fetch. Train and predict with it in the same process.

Loading from remote storage

load refuses non-local paths unless you opt in:
Anyone who can write that location chooses what gets loaded on the machine doing the loading, so this is worth being deliberate about.

Custom losses, optimizers and schedulers

Class names inside an artifact are resolved through a closed registry, so anything the library does not ship has to be registered before it can be saved:
Two things to know:
  • Registration has to run in the process that loads, too, not only the one that saves. The artifact stores the registered name; the class itself comes from your code.
  • Any nn.Module can be registered as a loss. One that does not inherit a neuralforecast loss base has no recorded constructor arguments, so they are recovered from the object and checked by rebuilding it when you save. If the rebuild would differ, saving fails rather than writing an artifact that loads as a different loss.
Registration is what makes a class saveable. load additionally accepts the same four arguments, to replace what an artifact stored β€” useful when the stored class is no longer importable, or when you want to swap it:
That works for both formats, but it cannot rescue a model that failed to save: those errors appear before any file is written. load also accepts map_location, and rejects anything else rather than ignoring it.

What is not carried in an artifact

Some settings describe the run rather than the model, and are dropped on save or on load with a warning naming them. Set them on the loaded object if you want them back.
  • Callbacks are dropped on save, as in earlier versions. Early stopping is rebuilt from early_stop_patience_steps, so that keeps working. Re-attach others with model.trainer_kwargs['callbacks'] = [...].
  • A logger instance is dropped; logger=False is kept, since it is configuration rather than an object.
  • Trainer and DataLoader settings that belong to the machine β€” default_root_dir, strategy, num_nodes, profiler, num_workers, prefetch_factor, multiprocessing_context β€” are not restored from an artifact, because a file should not choose where checkpoints are written or how many processes are spawned on the host loading it.
  • Anything that needs pickle to serialize, such as a worker_init_fn in dataloader_kwargs or an lr_lambda in lr_scheduler_kwargs, is dropped on save with a warning. A model argument that cannot be encoded is an error instead, so a model never silently reloads without its loss.

5. Load models

Load the saved models with the load method, specifying the path, and use the new nf2 object to produce forecasts.
Finally, plot the forecasts to confirm they are identical to the original forecasts.

References

https://pytorch-lightning.readthedocs.io/en/stable/common/checkpointing_basic.html Oreshkin, B. N., Carpov, D., Chapados, N., & Bengio, Y. (2019). N-BEATS: Neural basis expansion analysis for interpretable time series forecasting. ICLR 2020 Cristian Challu, Kin G. Olivares, Boris N. Oreshkin, Federico Garza, Max Mergenthaler-Canseco, Artur Dubrawski (2021). N-HiTS: Neural Hierarchical Interpolation for Time Series Forecasting. Accepted at AAAI 2023.