laudmt/uni2ts

Moirai pretrained from scratch on GiftEvalPretrain — GIFT-Eval benchmark

0

stars

123

commits

Python

primary language

May 18, 2026

updated

README

Train a Time Series Foundation Model

Summary

Trained Moirai-Small (14M parameters) from scratch on a curated subset of GiftEvalPretrain, evaluated zero-shot on the GIFT-Eval benchmark.
Final result for best model : rank #72 (vs Moirai-Small original at #68), trained from scratch in 4h11 on 8× A100 (40Gb of VRAM) for 100K steps (1000 epochs of num_batches_per_epoch = 100).

Also trained a morai-base (91M parameters) for 8h20 with 100K steps (1000 epochs of num_batches_per_epoch = 100), reached rank #75.

Full details can be found in the report.

Dataset

Reduced GiftEvalPretrain from 149 datasets to 67 with 3 things in mind, removing :

  • very big datasets (buildings_900k, era5_, cmip6_)
  • most of the multivariate
  • some other big datasets because of filesystem needs

I meant to only train on univariate data (to reduce complexity) but ended up doing multivariate training anyway. 7 datasets in the training subset contained multiple channels despite initial filtering.

Full selection rationale in the report.

Model

Initially launched a training of morai-base model (94M) only to realise its bad results were due to the low amount of training steps (1000 epochs * 100 batch_size = 100K steps (10% of total training stated in the paper)).

Then trained a morai-small on 100K steps and reached #72 global benchmark (original morai-small is #68).

Results

ModelStepsRankMASE (avg)
Moirai-Base (first run)100k (10% of full)#75~2.26
Moirai-Small (final)100k (100% of full)#722.065
Moirai-Small (original paper)100k on LOTSA#681.958

See full analysis in the report.

Reproducibility

Install uv, env and dependencies

curl -LsSf https://astral.sh/uv/install.sh | sh
uv sync
cp .env.template .env # and add var
set -a && source ./uni2ts/.env && set +a

Train the model (auto detect multi GPU and launches DDP training) :

uv run python -m cli.train \                                                                                           
    -cp conf/pretrain \                                                                                                  
    run_name=my_moirai_small \                                                                                            
    model=moirai_small_gift_eval \                                                                                        
    data=gift_eval_pretrain

Evaluate the model :

# Download eval data (one-time)
huggingface-cli download Salesforce/GiftEval --repo-type=dataset --local-dir /home/sagemaker-user/gift_eval_data

# Run evaluation
./project/moirai-1/eval/gift_eval_small.sh \
  outputs/pretrain/moirai_base_gift_eval/gift_eval_pretrain/my_moirai_small/checkpoints/last.ckpt

Changes to original uni2ts

Dependencies

Added uv as python dependency manager

Bug Fixes

FileFix
src/uni2ts/data/builder/gift_eval/pretrain.pyHF rate-limiter: dataloader was hitting the Hub API on every batch. Fixed by detecting the local HF Arrow cache (~/.cache/huggingface/datasets/) and loading directly with Dataset.from_file(), bypassing all API calls.
src/uni2ts/data/dataset.pyEmpty covariate crash: 54/61 GiftEvalPretrain datasets store absent covariates as np.array([]) instead of omitting the field, causing SampleDimension to crash on check_ndim. Fixed by skipping any numpy array with size == 0 in _flatten_data.
src/uni2ts/transform/resample.pySampleDimension integer underflow: 7 datasets have covariates with more dimensions than max_dim. When computing the per-field dimension budget, integer division (max_dim * len(arr)) // total_field_dim produces 0, causing uniform_sampler(0)ValueError: low >= high. Fixed by clamping to max(1, ...). Also added an early-return guard for empty arrays.

New Code

FileDescription
src/uni2ts/data/builder/gift_eval/pretrain.pyGiftEvalPretrainDatasetBuilder loads 73 subsets from HF Hub
src/uni2ts/eval_util/data.pyget_gift_eval_dataset() load GiftEval dataset, handle rolling windows, multivariate splitting, M4 support
cli/eval.pywrite_gift_eval_csv() appends metrics to CSV per eval run
cli/conf/pretrain/data/gift_eval_pretrain.yamlPretrain data config
cli/conf/eval/data/gift_eval.yamlEval data config
cli/conf/eval/default_gift_eval.yamlFull eval config
cli/conf/pretrain/model/moirai_small_gift_eval.yamlSmall model config
cli/conf/pretrain/model/moirai_base_gift_eval.yamlBase model config
project/moirai-1/eval/gift_eval_small.shEval script looping all GIFT-Eval datasets for the small model
project/moirai-1/eval/gift_eval_base.shEval script looping all GIFT-Eval datasets for the base model

Time Spent

PhaseTime
Research + design~3h
Data pipeline + bug fixes~2h
Training (Base + Small)~12h
Evaluation + analysis~3h
Write-up~3h
Total~11h (with 22h of compute)

Contributors

gorold

63 commits

liu-jc

20 commits

chenghaoliu89

15 commits

laudmt

9 commits

laudmt/uni2ts

Moirai pretrained from scratch on GiftEvalPretrain — GIFT-Eval benchmark

0

stars

123

commits

Python

primary language

May 18, 2026

updated

README

Train a Time Series Foundation Model

Summary

Trained Moirai-Small (14M parameters) from scratch on a curated subset of GiftEvalPretrain, evaluated zero-shot on the GIFT-Eval benchmark.
Final result for best model : rank #72 (vs Moirai-Small original at #68), trained from scratch in 4h11 on 8× A100 (40Gb of VRAM) for 100K steps (1000 epochs of num_batches_per_epoch = 100).

Also trained a morai-base (91M parameters) for 8h20 with 100K steps (1000 epochs of num_batches_per_epoch = 100), reached rank #75.

Full details can be found in the report.

Dataset

Reduced GiftEvalPretrain from 149 datasets to 67 with 3 things in mind, removing :

  • very big datasets (buildings_900k, era5_, cmip6_)
  • most of the multivariate
  • some other big datasets because of filesystem needs

I meant to only train on univariate data (to reduce complexity) but ended up doing multivariate training anyway. 7 datasets in the training subset contained multiple channels despite initial filtering.

Full selection rationale in the report.

Model

Initially launched a training of morai-base model (94M) only to realise its bad results were due to the low amount of training steps (1000 epochs * 100 batch_size = 100K steps (10% of total training stated in the paper)).

Then trained a morai-small on 100K steps and reached #72 global benchmark (original morai-small is #68).

Results

ModelStepsRankMASE (avg)
Moirai-Base (first run)100k (10% of full)#75~2.26
Moirai-Small (final)100k (100% of full)#722.065
Moirai-Small (original paper)100k on LOTSA#681.958

See full analysis in the report.

Reproducibility

Install uv, env and dependencies

curl -LsSf https://astral.sh/uv/install.sh | sh
uv sync
cp .env.template .env # and add var
set -a && source ./uni2ts/.env && set +a

Train the model (auto detect multi GPU and launches DDP training) :

uv run python -m cli.train \                                                                                           
    -cp conf/pretrain \                                                                                                  
    run_name=my_moirai_small \                                                                                            
    model=moirai_small_gift_eval \                                                                                        
    data=gift_eval_pretrain

Evaluate the model :

# Download eval data (one-time)
huggingface-cli download Salesforce/GiftEval --repo-type=dataset --local-dir /home/sagemaker-user/gift_eval_data

# Run evaluation
./project/moirai-1/eval/gift_eval_small.sh \
  outputs/pretrain/moirai_base_gift_eval/gift_eval_pretrain/my_moirai_small/checkpoints/last.ckpt

Changes to original uni2ts

Dependencies

Added uv as python dependency manager

Bug Fixes

FileFix
src/uni2ts/data/builder/gift_eval/pretrain.pyHF rate-limiter: dataloader was hitting the Hub API on every batch. Fixed by detecting the local HF Arrow cache (~/.cache/huggingface/datasets/) and loading directly with Dataset.from_file(), bypassing all API calls.
src/uni2ts/data/dataset.pyEmpty covariate crash: 54/61 GiftEvalPretrain datasets store absent covariates as np.array([]) instead of omitting the field, causing SampleDimension to crash on check_ndim. Fixed by skipping any numpy array with size == 0 in _flatten_data.
src/uni2ts/transform/resample.pySampleDimension integer underflow: 7 datasets have covariates with more dimensions than max_dim. When computing the per-field dimension budget, integer division (max_dim * len(arr)) // total_field_dim produces 0, causing uniform_sampler(0)ValueError: low >= high. Fixed by clamping to max(1, ...). Also added an early-return guard for empty arrays.

New Code

FileDescription
src/uni2ts/data/builder/gift_eval/pretrain.pyGiftEvalPretrainDatasetBuilder loads 73 subsets from HF Hub
src/uni2ts/eval_util/data.pyget_gift_eval_dataset() load GiftEval dataset, handle rolling windows, multivariate splitting, M4 support
cli/eval.pywrite_gift_eval_csv() appends metrics to CSV per eval run
cli/conf/pretrain/data/gift_eval_pretrain.yamlPretrain data config
cli/conf/eval/data/gift_eval.yamlEval data config
cli/conf/eval/default_gift_eval.yamlFull eval config
cli/conf/pretrain/model/moirai_small_gift_eval.yamlSmall model config
cli/conf/pretrain/model/moirai_base_gift_eval.yamlBase model config
project/moirai-1/eval/gift_eval_small.shEval script looping all GIFT-Eval datasets for the small model
project/moirai-1/eval/gift_eval_base.shEval script looping all GIFT-Eval datasets for the base model

Time Spent

PhaseTime
Research + design~3h
Data pipeline + bug fixes~2h
Training (Base + Small)~12h
Evaluation + analysis~3h
Write-up~3h
Total~11h (with 22h of compute)

Contributors

gorold

63 commits

liu-jc

20 commits

chenghaoliu89

15 commits

laudmt

9 commits

Languages

Python

88.7%

HTML

10.6%