Uni2TS: A Training and Inference Stack for Universal Time Series Transformers
Unified Training of Universal Time Series Forecasting Transformers
At a glance
- What is it?
- Uni2TS packages Salesforce's Moirai family into one PyTorch library for pre-training, fine-tuning, inference and evaluation. It is a research framework first, and its GluonTS dependency shapes almost everything about how you use it.
- Who is it for?
- Adopt Uni2TS if you already work inside GluonTS and want to run Moirai, Moirai-MoE or Moirai 2.0 without writing your own inference wrapper, or if you are reproducing the LOTSA pre-training pipeline. Do not adopt it as a general forecasting library if your data lives in sktime, Darts or a plain NumPy array pipeline, because the dataset abstraction is the entry point, not an optional adapter.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 105 days ago.
- What is it written in?
- Mainly Jupyter Notebook, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
What Uni2TS Is Actually For
Most time series forecasting code is written for one dataset at a time. You pick a model, you tune it on your series, and the artifact does not travel. Uni2TS takes the opposite position: it is the training and serving infrastructure for models that are meant to forecast series they were never trained on. The README describes it as a quote, unified framework for large-scale pre-training, fine-tuning, inference, and evaluation of Universal Time Series Transformers, unquote. That sentence is the scope statement, and it is broader than a model release.
The audience is narrow and specific. This is for researchers and applied teams who want to either (a) run a pre-trained Moirai checkpoint zero-shot, or (b) reproduce or extend the pre-training recipe on their own corpus. It is not a general-purpose forecasting library for analysts who want to fit ARIMA to a CSV. The repository ships Jupyter notebooks as the primary language, which tells you how the authors expect people to enter the code: interactively, inspecting intermediate objects, not through a stable public API surface with versioning guarantees.
The Moirai Family and the Version Split
The library is the home of three model lines, and the README treats them as separate entry points rather than one model with flags. Moirai 1.x weights are published as small, base and large under the Salesforce/moirai-1.1-R-* naming. Moirai-MoE adds a mixture-of-experts variant with its own module class and its own checkpoint names (moirai-moe-1.0-R-small and moirai-moe-1.0-R-base). Moirai 2.0 arrived as release 2.0.0 in November 2025, with a small checkpoint published as moirai-2.0-R-small.
That split matters operationally. The README example branches on a MODEL variable with three values: moirai, moirai-moe and moirai2. Each branch constructs a different forecast class and a different module class, and each branch uses different argument values. The Moirai 2.0 branch, for instance, passes prediction_length=100 and context_length=1680 and sets both dynamic feature dimensions to 0, while the Moirai 1.x branch passes patch_size as a configurable value and reads the feature dimensions off the dataset. If you copy the example without reading the branch you are in, you will get argument mismatches. Treat the three model lines as three integrations that happen to share a repository.
How Inference Flows Through GluonTS
The mechanism visible in the README is a chain, not a single call. Data starts as a wide pandas DataFrame, one column per series. PandasDataset from gluonts.dataset.pandas converts it into a GluonTS dataset. split, imported from gluonts.dataset.split, carves off the last N time steps as a test set by passing a negative offset. Then test_template.generate_instances produces rolling windows, parameterised by prediction_length, a window count, and a distance between windows. The README notes that distance equal to prediction_length gives non-overlapping windows.
Only after that does the model appear. You construct a forecast object by pairing a module loaded from a Hugging Face checkpoint with a set of shape parameters: prediction_length, context_length, patch_size, num_samples, target_dim, and the two dynamic feature dimensions. The predictor then consumes the windowed dataset. The practical consequence is that Uni2TS does not own your data pipeline. GluonTS does. Any transformation you need has to be expressible as a GluonTS dataset or applied before the PandasDataset call.
The num_samples parameter is worth pausing on, because it reveals the output type. Moirai produces sample paths, not point forecasts. The README example sets num_samples=100 and imports plot_single from uni2ts.eval_util.plot, which suggests the intended inspection workflow is visual and distributional. If your downstream system expects a single number per horizon step, you are responsible for the reduction, and the library does not document which reduction is appropriate.
Installation and the Two Paths In
There are two documented installation routes. The source route clones the repository, creates a virtualenv, activates it, and runs pip install -e '.[notebook]'. The editable install with the notebook extra is the one that matches the repository's own examples. The README also states that installation via PyPI is supported with a plain pip install uni2ts. That second path is shorter but gives you the library without the notebook tooling, and the README does not describe what the PyPI package omits relative to the source install.
The source route ends with touch .env. The README does not explain what belongs in that file. It is created and left empty in the instructions. If you need environment configuration, you will have to find the keys by reading the code, because the installation section does not enumerate them. This is a small gap, but it is the kind of gap that costs an afternoon when a training run fails on a missing credential.
Model weights are not bundled. Every branch of the getting-started example calls from_pretrained against a Salesforce repository on the Hugging Face Hub, so the first run requires network access to huggingface.co and enough disk for the checkpoint you select. The README imports hf_hub_download explicitly, which confirms the Hub is a hard dependency of the documented workflow rather than an optional convenience.
Fine-Tuning and Evaluation Are Separate Projects
The repository is organised around a project directory, and the README points at it repeatedly rather than describing the contents inline. Fine-tuning examples live under project/moirai-1/finetune_lsf, added in August 2025 alongside what the release notes call an enhanced fine-tuning module. Evaluation code for external models (TimesFM, Chronos, VisionTS) lives under project/benchmarks, published in September 2024. Moirai-MoE inference code and notebooks live under project/moirai-moe-1 and example respectively.
The consequence is that the top-level README is an index, not a manual. A reader who wants to fine-tune has to leave the README and read the project directory. Nothing in the supplied material describes the fine-tuning configuration format, the expected dataset layout for LSF, or how a fine-tuned checkpoint is reloaded for inference. That is not a criticism of the design, since separating research projects from the core library keeps the core smaller, but it does mean the documentation depth is uneven. The zero-shot inference path is documented end to end. The training and fine-tuning paths are documented by reference.
Where Uni2TS Is the Wrong Tool
The most concrete limitation is architectural: the inference path is built on GluonTS, and the README says so directly, noting that Uni2TS relies on GluonTS for inference because it provides convenience functions for splitting and rolling evaluation. If your existing stack is sktime, Darts, or hand-rolled NumPy arrays, adopting Uni2TS means adopting a second forecasting framework alongside the one you already have. For a single-series forecasting task, that is a bad trade. A classical model fitted directly to your series will be faster to build, easier to debug, and will not require downloading a checkpoint.
A second limitation is the shape of the model interface. Context length, prediction length and patch size are constructor arguments, not learned properties. The README example hardcodes context_length=200 for Moirai 1.x and context_length=1680 for Moirai 2.0. Choosing a context length shorter or longer than what the checkpoint was trained with is a decision the library does not protect you from. There is no documented validation that warns you when you have configured a mismatch.
A third issue is the state of the documentation itself. The supplied README ends mid-statement, with the line predictor followed by nothing. The getting-started section shows how to build the model and the dataset but does not show the call that produces forecasts. That is almost certainly a truncation in the material rather than a defect in the repository, but it illustrates a real risk: this is a research repository where the examples are the documentation, and examples drift. Pin to a release tag rather than tracking main if you need reproducibility.
How It Compares to Chronos and TimesFM
The repository itself provides the comparison. Uni2TS ships evaluation code for Chronos and TimesFM under project/benchmarks, run against the Monash, LSF and PF benchmark suites. That is an unusual move: the maintainers published the harness for competing models alongside their own.
The difference in approach is in the packaging, not the architecture. Chronos and TimesFM are released primarily as model weights with a minimal inference path, and the surrounding tooling is left to the user. Uni2TS is released as a training framework that happens to ship weights. It contains the pre-training pipeline, the LOTSA dataset reference, the fine-tuning module, and the evaluation harness in one repository. If you want to run a pre-trained model once, the other two are lighter. If you want to pre-train on your own corpus or reproduce an ablation, Uni2TS is the one that gives you the training loop. The trade is that you inherit more surface area, more dependencies, and a project layout that expects you to navigate subdirectories.
Licence, Maintenance and Upgrade Cost
Uni2TS is licensed Apache-2.0, and the README's badge links to the Apache 2.0 text. Apache-2.0 permits commercial use and modification and includes an explicit patent grant, which matters if you plan to embed the library in a product. It also requires that you preserve the licence and notice files and state significant changes. This is a description of the licence terms, not legal advice; if you are redistributing modified weights or code, have counsel read the actual file, including the model card terms on the Hugging Face Hub, which are separate from the repository licence.
The release cadence visible in the material is uneven. Version 1.1.0 landed in June 2024, 1.2.0 in November 2024, and 2.0.0 in November 2025. That is roughly one meaningful release per year, with the 2.0.0 jump introducing a new model generation rather than an incremental change. The practical upgrade cost is that moving from Moirai 1.x to 2.0 is not a version bump; the README shows a different module class, different constructor arguments, and a different checkpoint namespace. Budget for a rewrite of your inference wrapper, not a dependency update. Within a major version, the risk is lower, but pinning is still the safer default given that the primary language of the repository is Jupyter Notebook and the examples are the specification.
Editorial conclusion
Adopt Uni2TS if you already work inside GluonTS and want to run Moirai, Moirai-MoE or Moirai 2.0 without writing your own inference wrapper, or if you are reproducing the LOTSA pre-training pipeline. Do not adopt it as a general forecasting library if your data lives in sktime, Darts or a plain NumPy array pipeline, because the dataset abstraction is the entry point, not an optional adapter. Before committing, verify three things against your own environment: that pip install -e '.[notebook]' resolves on your Python and PyTorch versions, that the Hugging Face weights for the model size you want download at your network policy allows, and that the fixed context and prediction lengths you need are expressible as the constructor arguments shown in the README example.
Community notes