#3177·darts

Safe-by-default model loading

Author: dennisbaderCreated Aug 13, 2026Updated Aug 19, 2026
Labelscore improvement

Safe-by-default model loading

Problem

Loading a saved model through the public load() API can run arbitrary code if the checkpoint comes from an untrusted source (shared file, download, etc.). That is the usual pickle/torch unpickling risk, and it affects the normal "save and load a trained model" workflow.

Two places in the codebase:

  1. TorchForecastingModel (darts/models/forecasting/torch_forecasting_model.py, around lines 2388, 2488, 2629): calls torch.load(..., weights_only=False), which turns off PyTorch 2.6+'s safer default.
  2. ForecastingModel.load() (darts/models/forecasting/forecasting_model.py, around line 2737): uses raw pickle.load for non-torch models.

Both are reachable through the documented API with no extra flags.

What we need from a fix

  • Safe for the common case without asking users to configure trust lists.
  • Still works with the third-party backends we support (they store things differently, and not all handle save/load themselves).
  • Keeps current behavior where possible: creation params (including stateful ones), model attributes, etc. If something has to change, we should call it out explicitly.

Proposed plan

Phase 1: TorchForecastingModel

  • Use torch.load(..., weights_only=True).
  • Register the classes we actually serialize via torch.serialization.add_safe_globals([...]) (darts types, PyTorch Lightning, whatever the checkpoint needs).
  • Store model weights, ... as safetensors?
  • Drop the global torch.load monkeypatch if we still have it.

This should be a standalone PR and fixes the torch path without changing normal usage.

Phase 2: ForecastingModel

  • Replace raw pickle.load with a safer unpickler (for example find_class allowlist, ...).
  • Start with what we know we store: darts.*, numpy/pandas, sklearn/statsmodels basics, stdlib types we rely on.
  • Reject obvious bad imports (os, subprocess, eval, etc.).

For saves that contain something outside the allowlist (custom estimator, third-party stateful object in creation params), fail with a clear message and let the user opt in, e.g. ForecastingModel.load(path, trusted=True). Optional: trusted_classes=[...] for power users.

Suggested order

  1. PR for torch loading.
  2. PR for general ForecastingModel loading (iterate on the allowlist with real saved models).
  3. Docs on new save / load behavior, explain when trusted, trusted_classes are needed and how to fix failing loading.