Nie et al. arXiv:2211.14730 · Das et al. arXiv:2310.10688 · Ansari et al. arXiv:2403.07815

Time-Series Foundation Models

A sentence arrives pre-chopped into words. A photograph arrives on a bounded grid. A time series arrives as an unbounded stream of real numbers with no alphabet at all — which is exactly why it was the last modality to get a foundation model, and why the three papers here are really three answers to one question: what is a token?

Prerequisites: what a dot product is and what softmax does. Patching, quantization, instance normalisation, MASE, and decoder-only rollout are all built from zero.
10
Chapters
6
Interactive Sims
4096
Chronos Vocabulary
200M
TimesFM Params

Chapter 0: One Model, Any Series

You own forecasting at a mid-size retailer. Forty thousand products, each with a weekly demand history. Every Sunday night a job wakes up, and for each of those forty thousand series it fits a model: an exponential smoothing state-space model, or an ARIMA whose orders are chosen by a search over a grid. Forty thousand independent fits. Forty thousand sets of parameters. The job takes six hours and it is the single most brittle thing in your stack, because when a series is new — a product launched on Tuesday — there is nothing to fit.

Down the hall, a colleague working on language models has not fitted anything to anything in two years. She downloads a checkpoint, types a sentence, gets an answer. The model was trained once, by someone else, on a corpus she has never seen, and it works on her sentence because her sentence is made of the same stuff as the corpus: words.

The obvious question — obvious enough that a dozen groups asked it simultaneously in 2023 — is why forecasting cannot work that way. Train one model, once, on a huge pile of time series from every domain anyone has ever measured. Ship the weights. When a new series arrives, feed it in and read the forecast out. No fitting. No parameter search. No six-hour Sunday job.

The claim these papers make, stated plainly so you can hold them to it. A single set of weights, trained once and never touched again, can forecast a series it has never seen — different domain, different sampling frequency, different horizon — about as accurately as a model trained specifically on that series. TimesFM puts it as zero-shot performance that "comes close to the accuracy of state-of-the-art supervised forecasting models for each individual dataset." Chronos reports zero-shot performance "comparable and occasionally superior" to methods trained on the target data. Notice how carefully both sentences are hedged. Chapter 6 is about earning — and puncturing — those hedges.

Why time series was the last modality in the door

Language got a foundation model in 2018. Vision got one in 2021. Audio got one in 2022. Time series — arguably the oldest quantitative modelling problem in the world, with a century of statistical machinery behind it — did not get a credible one until 2023. That lag is not an accident of attention. It is a consequence of what a time series actually is.

Take the thing that makes a language model possible and try to find its analogue.

What a foundation model needsLanguage has itImages have itTime series…
A finite alphabet of atoms~50,000 subword tokens, fixed foreverPixels in [0, 255], patches of 16×16None. The atoms are real numbers on an unbounded line
Scale-free inputs"cat" is "cat" in every documentPixel values are bounded by constructionNo. One series lives near 10−3, the next near 106
A single notion of "next"The next wordNot applicable — images are not sequentialAmbiguous. Next hour? Next year? Both, in one corpus
Fixed input dimensionalityOne stream of tokens3 colour channels, alwaysNo. 1 variate, or 7, or 862, task by task
Semantics carried by the atom"catastrophe" means something aloneA patch of sky is recognisable aloneNo. The number 37.2 means nothing without context

Read the last row twice, because it is the deepest one. In language, a token carries meaning by itself — that is why an embedding table works at all. In a time series, a single observation carries almost nothing. 37.2 could be a body temperature in Celsius (perfectly normal), a stock price, a wind speed in metres per second (a storm), or a warehouse's Tuesday order count. Meaning lives in the local shape — is it rising, is it oscillating, did it just jump — and shape is a property of a window, not a point.

The one sentence that organises this entire lesson. Every time-series foundation model is, first and foremost, a proposal for what a token is. Everything else — the architecture, the loss, the corpus — follows from that choice. PatchTST says a token is a short window of consecutive values. Chronos says a token is a bin index, so that an off-the-shelf language model can be used with no modification whatsoever. TimesFM says a token is a window on the way in and a longer window on the way out. Three answers, three sets of consequences, and you can predict most of each paper's results from its answer alone.

See the three answers side by side

Before any machinery, look at what each proposal literally does to the same forty-eight numbers. The simulation below takes one series and tokenises it three ways. Watch what happens to the token count, and watch what each token is.

What is a token? — three answers on one series

The same 48-point series, tokenised three ways. Point is the naive choice most early time-series Transformers made. Patch is PatchTST and TimesFM. Bin is Chronos. Read the token count in the header — it is the number the attention cost squares.

Three things to notice. First, point tokenisation keeps every number but produces the most tokens, and attention cost grows with the square of that count. Second, patching collapses sixteen numbers into one vector — the token count drops by a factor of the stride, and each token now carries a shape rather than a value. Third, binning does something categorically different: it throws away the real line entirely and replaces each number with an integer, at which point the sequence is literally a sentence, and any language model will eat it without modification.

The three papers, and the two that frame them

ModelYearA token is…ObjectiveSizePretraining corpus
PatchTST
Nie, Nguyen, Sinthong, Kalagnanam
2022A window of P = 16 consecutive values, stride S = 8MSE on the horizon; or masked patch reconstruction~1M (3 layers, D = 128)One dataset at a time — not a foundation model, but the tokenizer everything else uses
TimesFM
Das, Kong, Sen, Zhou (Google)
2023An input patch of 32 values; the output patch is 128MSE on the next output patch, decoder-only200M (20 layers, d = 1280, 16 heads)O(100B) timepoints: Google Trends, Wiki pageviews, M4, plus synthetic
Chronos
Ansari, Stella, Türkmen et al. (Amazon)
2024A bin index in a 4096-word vocabularyCross-entropy over bins — regression by classification20M – 710M (T5 family, unmodified)28 public datasets, 10M TSMixup augmentations, 1M synthetic GP series
MOMENT
Goswami et al. (CMU)
2024A non-overlapping patch of 8 valuesMasked patch reconstruction, 30% masked40M / 125M / 385MThe Time Series Pile — assembled from public archives
Moirai
Woo et al. (Salesforce)
2024A patch whose size depends on the frequencyNegative log-likelihood of a mixture distribution14M / 91M / 311MLOTSA — over 27B observations across nine domains

PatchTST is in this table under slightly false pretenses and it is important to say so up front: PatchTST is not a foundation model. It is trained per dataset, evaluated per dataset, and its paper never claims otherwise. It is here because it contributed the tokenizer — patching plus channel independence — that TimesFM, MOMENT and Moirai all adopted. The genealogy is explicit: TimesFM's own text says "Inspired by the success of patch based modeling in the recent long horizon forecasting work [24] we also choose to break down the time-series into patches," where [24] is PatchTST.

2022 — PatchTST invents the token
Patch the series, treat each channel independently, share one Transformer across all channels. A 21.0% MSE reduction against the best Transformer baselines. Also shows that masked-patch pretraining transfers across datasets.
↓ keep the tokenizer, scale the corpus, go causal
2023 — TimesFM makes it a foundation model
Decoder-only over patches, with the output patch longer than the input patch so any horizon is reachable in a few steps. 200M parameters, O(100B) timepoints, top of the Monash archive without ever training on it.
↓ or: refuse to build an architecture at all
2024 — Chronos changes the data instead
Scale, quantize, and hand the integers to a stock T5. No architectural change beyond resizing the embedding table. The forecast is a sampled sequence of tokens, so the predictive distribution comes free.

What "zero-shot" means here, precisely

Zero-shot in this literature means: no gradient step is taken on the target series or its dataset. You load weights, you feed a context window, you read a horizon. It does not mean the model has never seen a series that looks like yours — on the contrary, the whole bet is that it has seen millions of series that look a bit like yours, which is what makes contamination such a live worry (Chapter 6 returns to it with teeth).

SettingFits per new seriesData needed from youLatency at deployCold start?
Local statistical (ARIMA, ETS)One fit per seriesThe series itself, long enough to identify ordersSeconds to minutes per seriesImpossible — nothing to fit
Global deep (DeepAR, PatchTST)One training run per datasetThe full dataset, plus a train/val splitMilliseconds after trainingWorks only if the new series joins a trained panel
Foundation model, zero-shotZeroA context window. That is allTens of ms to a few secondsYes — day-one forecasts
Foundation model, fine-tunedOne short run per datasetA modest slice of the datasetSame as zero-shot afterwardsYes, then improves

That last row matters more than it looks. Chronos's own experiment is blunt about it: they fine-tuned the smallest useful model, Chronos-T5 (Small, 46M), on individual held-out datasets for 1000 steps, and it "takes the top spot on Benchmark II overall, overtaking both larger (zero shot) Chronos models and the best task-specific models." A thousand steps. If you have any data at all, zero-shot is a floor, not a ceiling.

The engineering case, before the accuracy case

It is tempting to argue about which model wins on which metric. Practitioners who adopted these models mostly did not adopt them for accuracy. They adopted them for what the diagram below does to an operations page.

Before
40,000 fits → 40,000 parameter sets to store, version and monitor → a fit that can fail per series (non-convergence, too few observations, an all-zero history) → a retraining schedule → a backfill story for when the schedule slips.
After
One checkpoint → one inference service → a new series is a new request, not a new job. Chronos names this directly: deployment "obviat[es] the need for task-specific training", and the models "can be deployed for datasets with diverse history lengths, frequencies, prediction horizons, and context lengths."

The cost is real and Chapter 6 will price it: inference is slower per series than evaluating a fitted ETS model, these models take no covariates, and the failure modes are unfamiliar. But the operational simplification is why this line of work matters even where the accuracy gain is a wash.

Where we are going

Chapters 1–3 — the tokenizer
The four properties that break naive transfer → PatchTST's patching and channel independence, with the patch arithmetic done by hand → what changes when you swap the forecasting head for a reconstruction objective
Chapters 4–5 — the two foundation models
Chronos's mean-scaling and binning derived digit by digit, including the two ways it breaks → TimesFM's decoder-only rollout, the longer output patch, and the masking trick that makes every context length reachable
Chapters 6–9 — interrogate and recombine
Honest zero-shot evaluation with the embarrassing cases included → using a forecaster as an embedding model → the design axes you would recombine to invent the next one → the lineage and a cheat sheet
Why did time series get a credible foundation model years after language, vision, and audio?

Chapter 1: Why Series Resisted

Chapter 0 asserted that time series lacks a vocabulary. This chapter makes that concrete, because each missing property maps to a specific engineering decision in each of the three papers — and if you understand the four obstacles you can practically re-derive the models.

Obstacle 1 — No vocabulary
Values are real numbers on an unbounded line. There is no embedding table because there is nothing countable to index. And a single value has no standalone meaning.
Obstacle 2 — Scale varies wildly
Across a pretraining corpus, one series lives near 0.001 and another near 1,000,000. A shared first layer sees inputs spanning nine orders of magnitude.
Obstacle 3 — Frequency varies
"One step ahead" means five minutes here and a year there. The same weights must encode seasonality at period 7, 12, 24, 52, 96, 168…
Obstacle 4 — Channel count varies
One task has 1 variate, another 7, another 862. And the relationships between channels are dataset-specific — there is no universal "channel 3".

Obstacle 1: the number 37.2 does not mean anything

Start with what a language model does on its very first layer. The token cat has an integer id, say 4826, and that id indexes a row of an embedding matrix E of shape (V, d) — a lookup, nothing more. The row was learned. Crucially, every time cat appears anywhere in the corpus it retrieves the same row, so the model accumulates evidence about that atom across billions of occurrences.

Now try it on a series. What is the id of 37.2? There isn't one; the reals are uncountable. You could round — and hold that thought, because that is exactly what Chronos does — but round to what precision, and relative to what? 37.2 in a body-temperature series is routine; 37.2 in a series whose values are usually 0.001 is a catastrophic spike.

So the first layer cannot be a lookup. It has to be a projection: a learned linear map from a vector of raw values into the model dimension. Which immediately raises the question of what goes into the vector.

ChoiceFirst layerTokens for L = 512Attention cellsWhat one token means
One token per timepointLinear: R1 → RD512262,144A single scalar — almost nothing
Patch of 16, stride 8Linear: R16 → RD644,096A local shape: level, slope, wiggle
Patch of 32, no overlapLinear: R32 → RD16256A longer motif
Quantized bin (Chronos)Lookup: id → row of E512262,144"The scaled value is about 0.87"

The pointwise row is the design that early time-series Transformers — Informer, Autoformer, FEDformer — used, and it is the one PatchTST attacks. A linear map from R1 into R128 is a rank-one operation: every token embedding is the same vector scaled by the value. Whatever structure attention then discovers, it had to discover from scaled copies of a single direction. PatchTST's ablation is stark: strip patching out, keep everything else, and several configurations do not merely get worse — they run "out of GPU memory (NVIDIA A40 48GB) even with batch size 1."

The information-theoretic way to see it. A word carries meaning because it was chosen from a large alphabet — log2(50,000) ≈ 15.6 bits of choice, and a human made the choice deliberately. A single float in a smooth series carries almost no choice at all: given the previous value, the next one is nearly determined, so its conditional entropy is tiny. Meaning in a series is not in the sample, it is in the local trajectory. Patching is the operation that moves the token up to the level where meaning lives.

Obstacle 2: nine orders of magnitude in one batch

Suppose your pretraining corpus contains hourly electricity load in kilowatt-hours (values around 3,000), daily website conversions (values around 12), and a sensor's drift in volts (values around 0.0004). All three enter the same batch, hit the same first linear layer, and their gradients are summed into the same weights.

Written out, the first layer computes Wpxpatch. If xpatch has entries near 3,000 the pre-activation is near 3,000·‖W‖; if near 0.0004 it is seven orders of magnitude smaller. One of the two produces gradients that dominate; the other produces gradients that are numerically invisible. No amount of training fixes this, because the problem is in the inputs, not the parameters.

The fix everyone uses is instance normalisation: normalise each series (or each context window) by its own statistics before it enters the model, then invert the transform on the output. There are three flavours in these papers and the differences matter.

SchemeTransformUsed byProperty worth knowing
Standardisation (RevIN)x̃ = (x − μ) / σ, per windowPatchTST, MOMENT, TimesFM (mean and std of the first input patch)Centres and rescales; destroys the meaning of zero
Mean scalingx̃ = x / s, with s = (1/C) ∑|xi|, no centringChronosPreserves zeros. Zero sales stays zero; zero solar output at night stays zero
Min-maxx̃ = (x − min) / (max − min)Rare hereBounded output, but one outlier compresses everything else

Chronos's justification for mean scaling is one line and it is a genuinely good piece of domain thinking: "An attractive feature of mean scaling is that it preserves zero values in the time series, which are often semantically meaningful, such as zero sales for a product or zero solar energy generation at night." Subtracting a mean turns "we sold nothing" into "we sold 1.4 below average", which is a different fact.

Work one instance by hand. Take a context of eight weekly demand values:

x = [ 10, 12, 8, 14, 11, 15, 9, 13 ]

Mean scaling sets m = 0 and s = the mean absolute value: (10 + 12 + 8 + 14 + 11 + 15 + 9 + 13) / 8 = 92 / 8 = 11.5. Dividing through:

x̃ = [ 0.8696, 1.0435, 0.6957, 1.2174, 0.9565, 1.3043, 0.7826, 1.1304 ]

Now multiply every original value by 1,000 — a different unit, a different product, a different domain. The mean absolute value becomes 11,500, and x̃ comes out identical to four decimal places. That is the whole point: the model never sees the unit. It sees shape. Keep this exact vector; Chapter 4 turns it into tokens.

Three series, three scales, one first layer

Three real-shaped series with wildly different magnitudes. Toggle the normalisation and watch the range readout under each panel — that range is literally what the model's first linear layer receives. Note what happens to the dashed zero line under standardisation versus mean scaling.

Sparsity of series 3 0%

Drag the sparsity slider up and watch series 3 fill with zeros. Under mean scaling the zeros stay pinned to the zero line no matter how sparse the series gets. Under standardisation they lift off it, and they lift further the sparser the series becomes — the mean of a mostly-zero series is small, but the standard deviation is smaller still, so the zeros drift to a large negative z-score. Chapter 4 shows the exact failure this causes once you then quantize.

Inline concept check. Instance normalisation solves scale. Does it solve distribution shift within a single series — a product whose demand triples permanently after a promotion?  …  Partly. If you normalise per context window at inference, the new level becomes the new s, so the model sees a normal-looking series and forecasts sensibly — that is the good case, and it is why PatchTST reports that instance normalisation "help[s] mitigating the distribution shift effect between the training and testing data." But if the shift happens inside the context window, s is an average of two regimes and neither half looks right. No normalisation scheme fixes a regime change; it only stops you being surprised by a permanent one.

Obstacle 3: "next step" is not one thing

A language model's notion of "next" is fixed by the tokenizer. A forecaster's is fixed by whoever installed the sensor. Within one pretraining corpus you have 5-minute traffic counts, hourly electricity, daily page views, weekly sales, monthly tourism, and yearly macroeconomic indicators — and the seasonal period, the thing a forecaster most needs to detect, is a different integer in each: 288, 24, 7, 52, 12, and none.

ResponseWhoMechanismCost
Ignore frequency entirelyChronos, TimesFMThe model must infer the period from the context. Frequency is never an inputNeeds a context long enough to contain several periods — a hard constraint at high frequency
Balance the mixtureTimesFMThe loader gives "equal weights to the groups: hourly + sub-hourly, daily, weekly, and monthly"; 80% real data, 20% syntheticA curation decision that is invisible at inference but shapes everything
Condition on frequencyMoiraiPatch size is chosen by frequency — larger patches for high-frequency data, smaller for low — with a separate projection layer per patch sizeYou must know and supply the frequency; more parameters

TimesFM's context-length choices show how sharp the constraint is in practice. It trains "with a maximum context length of 512 whenever the length of the time-series allows that. For weekly granularity we do not have sufficiently long time-series; therefore a maximum context length of 256 is used. For the same reason, a maximum context length of 64 is used while training on ≥ monthly granularity data." A 64-step context on monthly data is five years and four months — barely five annual cycles. There is no way around it: the data simply does not exist.

The high-frequency squeeze, in arithmetic. Suppose you have 5-minute data with a daily period of 288, and you want the model to see three full days so it can tell weekday shape from weekend shape. That needs a context of 864 timepoints. Chronos, which spends one token per timepoint, would need 864 tokens — above its trained context length of 512, and 8642 = 746,496 attention cells. TimesFM with input patch 32 needs 864 / 32 = 27 tokens and 729 cells. This is not a small difference in efficiency. It is the difference between the model being able to see the pattern and not.

Obstacle 4: how many channels is a time series?

A multivariate series has M simultaneous measurements per timestep: the Weather dataset has 21, ETTh1 has 7, Traffic has 862. The obvious instinct is to let the model see all channels at once so it can exploit cross-channel structure — if road sensor 41 spikes, sensor 42 spikes eight minutes later.

The obvious instinct is mostly wrong, and PatchTST is where that became consensus. Its second contribution is channel independence: split the M-variate series into M univariate series, run each through the same shared Transformer independently, and never let them attend to each other.

Why does throwing away cross-channel information help? Three reasons that stack.

One — the parameter count of channel mixing scales with M, and M is dataset-specific. A channel-mixing first layer maps RM into RD, so its shape depends on the dataset. A channel-independent one maps RP into RD, and P is your hyperparameter, identical everywhere. This alone is why every foundation model in the table adopted it: you cannot pretrain across datasets with different M unless the weights are M-agnostic.

Two — it multiplies the effective dataset size by M. ETTh1 with 7 channels is one 7-channel training sequence per window under mixing, but seven univariate sequences per window under independence. PatchTST's Figure 7 shows the consequence directly: channel mixing "quickly overfits the data", while channel independence "contributes to a quicker convergence as more training data is available."

Three — the cross-channel signal is often weaker than the within-channel signal. For long-horizon forecasting, the dominant structure is each channel's own seasonality and trend. Spending capacity on cross-channel attention buys a small gain at a large overfitting risk.

Say what it costs, though. Channel independence genuinely discards information. If channel A leads channel B by three steps, a channel-independent model cannot use it — ever, at any scale. Every foundation model above accepted this trade, and it is the single largest known gap in the family. Moirai is the exception that proves it: its Any-variate Attention "simultaneously considers both time and variate axes as a single sequence", using rotary position embeddings for time and learned binary attention biases for variate identity, so the model can attend across channels while still accepting an arbitrary number of them. That is what solving the problem properly looks like, and it costs a bespoke attention mechanism.

The four obstacles, and what each paper did

ObstaclePatchTSTChronosTimesFM
No vocabularyPatch of 16, linear projectionInvent one: 4096 binsPatch of 32, MLP residual block
ScaleRevIN standardisationMean scaling (zero-preserving)Standardisation using the first patch's statistics
FrequencyNot applicable — one dataset at a timeInfer from context; context length 512Balance the loader; cap context by granularity
ChannelsChannel independence — the contributionUnivariate only; multivariate listed as future workUnivariate only; covariates listed as a limitation

Look at the bottom row. Two of the three foundation models simply declined the multivariate problem. Chronos's discussion says so plainly: "we have focused on univariate forecasting of uniformly-spaced time series since it constitutes the most common of real-world time series use-cases", and lists covariates and multivariate forecasting as open. TimesFM's limitations section says "the model is not pretrained with covariates as one of the key challenges is finding large volumes of pretrained data with meaningful covariates." When you deploy one of these and it ignores your promotion calendar, that is not a bug. It is the scope.

Why is channel independence a prerequisite for a time-series foundation model, not merely an accuracy trick?

Chapter 2: PatchTST — A Patch Is a Token

The title of the PatchTST paper is "A Time Series is Worth 64 Words." That is not a flourish; it is the arithmetic result of the paper's central choice, and by the end of this chapter you will be able to produce the number 64 yourself from the look-back window and two hyperparameters.

The setup. You are given a multivariate series with look-back window L — L past timesteps — and asked to forecast T future steps. Each timestep xt is a vector of dimension M. Formally: given (x1, …, xL), predict (xL+1, …, xL+T).

Step 1: split the channels

Before anything else, the M-variate input is split into M univariate series, each of shape (1, L). Each goes through the backbone independently, and the backbone's weights are shared across all of them. In tensor terms this is a reshape that folds the channel axis into the batch axis:

(B, M, L)  →  (B·M, 1, L)

That single line is the whole of channel independence as an implementation. A batch of 32 samples from ETTh1, which has M = 7, becomes 224 univariate sequences. The Transformer never learns that there were seven of anything.

Step 2: normalise, then patch

Each univariate window is instance-normalised — zero mean, unit standard deviation, with the statistics stashed so they can be added back to the output — and then cut into patches. Two hyperparameters govern the cut:

If S < P the patches overlap; if S = P they tile exactly; if S > P you skip data. PatchTST's default is P = 16, S = 8 — fifty percent overlap.

The number of patches is given in the paper as

N = ⌊ (L − P) / S ⌋ + 2

and the "+ 2" deserves a full explanation, because it looks like a fudge and is not. Count carefully. Patches start at index 1, 1 + S, 1 + 2S, … The last patch that fits entirely inside a window of length L starts at 1 + kS where kS + P ≤ L, so k = ⌊(L − P)/S⌋, giving k + 1 patches. The extra one is the padded tail: PatchTST appends S copies of the final value xL before patching, so one more patch fits, and it is anchored on the most recent observation. That is the "+ 2" — (k + 1) real patches plus 1 padded patch.

Why pad with the last value rather than zeros. The final patch is the one nearest the forecast origin — the most predictive token in the sequence. Padding it with zeros would inject a synthetic crash exactly where the model is most attentive; padding with a repeat of xL injects a flat continuation, which is the least surprising thing you can say. It is the same instinct behind replicate padding in convolutional networks, applied where it matters most.

The worked patch arithmetic

Do the two configurations the paper actually ships. PatchTST/42 uses the default long-horizon look-back L = 336 — fourteen days at hourly resolution:

PatchTST/42 — the default configuration, by handL = 336, P = 16, S = 8

L - P            = 336 - 16 = 320
(L - P) / S      = 320 / 8  = 40        # exact; no flooring needed here
floor(...)       = 40
N                = 40 + 2  = 42         # hence the name PatchTST/42

# and the larger variant:
L = 512, P = 16, S = 8
(512 - 16) / 8   = 496 / 8 = 62
N                = 62 + 2  = 64         # "A Time Series is Worth 64 Words"

There is the title. Sixty-four words is L = 512 with P = 16 and S = 8. Now the payoff, which is why anyone cares:

what patching buys — attention cost# self-attention builds an N x N matrix. Cost is quadratic in the TOKEN count.

pointwise, L = 512 :  512 * 512  = 262,144 attention cells
patched,   N =  64 :   64 *  64  =   4,096 attention cells
                                    ---------------------
                                    64x fewer

# the reduction factor is (L/N)^2 ~ S^2 for large L, since N ~ L/S.
# S = 8  ->  64x.    S = 16 -> 256x.    S = 32 -> 1024x.

The paper measures the wall-clock consequence rather than only the FLOP count: "By setting patch length P = 16 and stride S = 8 with L = 336, the training time is significantly reduced as much as 22 time on large datasets." Twenty-two times faster, measured, on the Traffic dataset with its 862 channels.

Every tensor shape, in order

This is the part that separates reading the paper from being able to write it. Track one univariate series through the whole forward pass with PatchTST/42 numbers and D = 128:

StageOperationShape outNote
Input(B, M, 336)B samples, M channels, L = 336
Channel splitreshape(B·M, 336)Channels folded into batch. Nothing learned here
Instance norm(x − μ) / σ per row(B·M, 336)μ, σ stashed for the inverse at the end
Padrepeat xL S = 8 times(B·M, 344)So the final patch is anchored at the forecast origin
Patchunfold(size = 16, step = 8)(B·M, 42, 16)N = 42 tokens, each a 16-vector
ProjectWp ∈ R128×16(B·M, 42, 128)2,048 weights. This is the entire "embedding table"
Position+ Wpos ∈ R128×42(B·M, 42, 128)Learned, additive, 5,376 parameters
Encoder3 vanilla Transformer layers(B·M, 42, 128)Multi-head attention + FFN, with BatchNorm, not LayerNorm
Flattenreshape(B·M, 5376)42 × 128 = 5,376
HeadLinear 5376 → T(B·M, T)For T = 96 that is 516,096 weights — the biggest single block
Denorm + unfold·σ + μ, reshape(B, M, T)Back to the caller's shape

Two details in that table are worth stopping on.

The projection is 2,048 parameters. That is the entire mechanism by which raw numbers become tokens: one 128×16 matrix. Compare a language model's embedding table at 50,000 × 4,096 = 205 million. The tokenizer here is five orders of magnitude smaller than the thing it replaces, because it does not have to memorise atoms — it has to compute them.

BatchNorm, not LayerNorm. The paper's footnote cites Zerveas et al.: "BatchNorm outperforms LayerNorm in time series Transformer." This is a genuine departure from NLP practice and it is a consequence of the domain. LayerNorm normalises across the feature dimension of a single token — but a patch's features are 16 consecutive time values, and normalising across them would destroy the level and slope information that makes the patch meaningful in the first place. BatchNorm normalises each feature across the batch, leaving the within-patch shape intact.

Patch arithmetic, live

Drag L, P and S and watch the patch boundaries move. The readout gives N from the paper's formula, the token tensor shape, and the attention-cell count against the pointwise baseline. Push S down to 1 to see what "no patching" costs; push P above S to open the overlap.

Look-back L 336
Patch length P 16
Stride S 8

Why a longer look-back only helps once you patch

Here is the experiment that motivates the whole design, and it is small and sharp. Everyone knew that longer look-back windows should help — more history, more information. Everyone also observed that pointwise Transformers got worse as the look-back grew, because the token count grew with it and the model overfitted.

PatchTST ran the control that separates the two effects. Take L = 380, but subsample it — keep every 4th point, plus the last one — so the token count is 96, the same as a pointwise model with L = 96. Same number of tokens, four times the span. Result: MSE 0.447 with the long-span subsampled input against 0.518 with the recent-96 input.

What that control proves. The gain from a longer look-back is not about having more samples; it is about spanning more time. The subsampled input had exactly the same number of tokens and threw away three quarters of the values, and it still won by 0.071 MSE — roughly 14%. So the question becomes: can we span more time without either exploding the token count or throwing values away? Patching is precisely that answer. Group the local timesteps that would have been discarded into one token instead.

With that established, the look-back curve inverts. PatchTST sweeps L ∈ {24, 48, 96, 192, 336, 720} and reports that "our model gains performance improvement with increasing look-back window", while the Transformer baselines flatten or degrade. The default of 336 and the large variant at 512 are chosen on that curve.

The results, and the ablation that isolates the cause

On the eight standard long-horizon benchmarks — Weather, Traffic, Electricity, ILI and the four ETT datasets — against FEDformer, Autoformer, Informer, Pyraformer, LogTrans and DLinear:

VariantLook-backTokensMSE reduction vs best TransformerMAE reduction
PatchTST/64L = 5126421.0%16.7%
PatchTST/42L = 3364220.2%16.4%

A twenty percent MSE reduction is a large number in this literature. But an aggregate improvement never tells you which idea earned it, so the paper runs the 2×2 ablation: patching on or off, channel independence on or off.

ConfigurationPatchingChannel independenceOutcome reported
P + CI (full PatchTST)YesYesBest across the board
CI only (P = S = 1)NoYesWorks, clearly worse, far slower
P onlyYesNoWorse than P + CI
Neither (original TST)NoNoWorst; several settings report "—" — out of GPU memory on an A40 48GB at batch size 1

The dashes in that table are the most eloquent entry. Without patching, a Transformer over Traffic's 862 channels and a 336-step window does not merely underperform. It does not run.

And one more control that is easy to miss: the paper trains PatchTST with and without instance normalisation and finds it "improves the forecasting performance slightly", concluding that "the improvement mainly comes from patching and channel-independence." That is a rare and honest sentence — the authors explicitly deny credit to one of their own components.

Derivation challenge — do this before Chapter 3.

You have hourly data and want a context spanning four full weeks, so L = 672. Your GPU budget allows at most 2,500 attention cells per head per layer. (1) Find the smallest stride S, with P = 2S so overlap stays at 50%, that fits the budget. (2) Give N, the patch tensor shape for a batch of 16 samples from a 21-channel dataset, and the size of Wp for D = 128. (3) State one thing you have lost relative to S = 8.

Answer. (1) N2 ≤ 2500 means N ≤ 50. With P = 2S, N = ⌊(672 − 2S)/S⌋ + 2, which for S dividing 672 is (672/S − 2) + 2 = 672/S. Need 672/S ≤ 50, so S ≥ 13.44; take S = 14, P = 28, giving N = 48 and 2,304 cells. (2) The patch tensor is (16·21, 48, 28) = (336, 48, 28), and Wp is 128×28 = 3,584 weights. (3) Each token now averages 28 timesteps rather than 16, so the finest structure the model can resolve inside a token is coarser — a sharp one-hour spike is one twenty-eighth of a token's content rather than one sixteenth, and the linear projection must compress it into the same 128 dimensions. You bought span with resolution.

PatchTST's formula gives N = ⌊(L − P)/S⌋ + 2. Where does the "+ 2" come from?

Chapter 3: Representations vs Heads

Everything in Chapter 2 was supervised: patches in, horizon out, MSE against the truth. That is a forecaster, not a foundation model. The difference is one sentence long — a foundation model learns a representation before it learns a task — and the second half of PatchTST is where that transition happens for time series.

This chapter is the pivot of the lesson. It is also where the tensor shapes get interesting, because the choice of head turns out to constrain the choice of objective far more tightly than anyone expected.

The forecasting head is bigger than the model

Go back to the shape table. Three Transformer layers at D = 128 come to roughly 600,000 parameters. The flatten-and-project head, for a single horizon T:

head parameter count — flatten (N x D), then Linear to TN = 42, D = 128   ->   flattened width = 42 * 128 = 5,376

T =  96 :  5,376 *  96 =   516,096 params   (0.52 M)
T = 192 :  5,376 * 192 = 1,032,192 params   (1.03 M)
T = 336 :  5,376 * 336 = 1,806,336 params   (1.81 M)
T = 720 :  5,376 * 720 = 3,870,720 params   (3.87 M)

At T = 720 the head is roughly six times the size of the backbone. Worse, it is horizon-specific: the supervised PatchTST trains a separate model for every prediction length, because the output width is baked into a weight matrix.

Now recall the alternative the paper argues against — the pointwise masked-autoencoder design of Zerveas et al., where every timestep is a token. Its head has to map L·D features to M·T outputs:

the head PatchTST is arguing againstW has shape (L * D) x (M * T)
L = 512, D = 128, M = 7, T = 96
  -> (512 * 128) x (7 * 96)
  =  65,536 x 672
  =  44,040,192 params  (44.0 M)   # 85x the patched head, for the same task

The paper's phrasing is dry — "This matrix can be particularly oversized if either one or all of these four values are large. This may cause overfitting when the number of downstream training samples is scarce" — but the factor is 85×. Patching shrinks the head as a side effect of shrinking the sequence, and that is what makes a reusable backbone practical.

The generalisable lesson. When you design a pretraining objective, look at the head it forces you to attach. If the head is larger than the backbone, most of your downstream fine-tuning capacity lives in freshly initialised weights, and whatever the backbone learned is being relearned by the head. Patching keeps the head small, which keeps the backbone load-bearing, which is what "representation learning" actually requires.

The masked-patch objective

Swap the objective. Remove the forecasting head. Attach instead a linear layer of shape D × P — one that maps each token's representation back to the P raw values it came from. Then:

  1. Cut the series into non-overlapping patches. Overlap would leak: a masked patch's values would still be visible inside its neighbours.
  2. Choose a random subset of patch indices — PatchTST masks 40% of them — and set those patches to zero.
  3. Run the encoder. Reconstruct all patches through the D×P head. Compute MSE on the masked positions only.

Their representation-learning configuration is L = 512 with patch size 12, non-overlapping. That gives 512 / 12 = 42.67, so 42 complete patches (the paper reports 42; the trailing 8 values do not form a full patch). Head size: 128 × 12 = 1,536 parameters — four orders of magnitude smaller than the 44M pointwise head, and about a thousandth of the T = 336 forecasting head.

Why masking patches and not points

This is the sharpest argument in the paper and it generalises far beyond forecasting. Mask a single timestep in a smooth series and ask a model to recover it. Its neighbours are right there. Linear interpolation between xt−1 and xt+1 recovers xt to within the local curvature — no understanding required.

Make it numeric. Let the series be a smooth sinusoid sampled at 24 points per period, so consecutive samples differ in phase by 2π/24 = 0.2618 radians. Mask xt. The midpoint of its neighbours is

( sin(θ − 0.2618) + sin(θ + 0.2618) ) / 2 = sin(θ) · cos(0.2618) = 0.9659 · sin(θ)

The interpolation is off by 3.4% of the amplitude, and that is the entire difficulty of the task. The paper says it exactly: masked values "can be easily inferred by interpolating with the immediate proceeding or succeeding time values without high level understanding of the entire sequence, which deviates from our goal of learning important abstract representation."

Now mask a whole patch of 12 consecutive points. Interpolation across a 12-step gap in a period-24 sinusoid spans half a cycle — a straight line between the endpoints misses the entire hump, and the error is on the order of the amplitude itself, not 3.4% of it. To fill it you must recognise the periodicity from the unmasked patches and extrapolate the phase. That is a representation.

The same lesson, three modalities. BERT masks whole subword tokens, not characters — masking one character of "transformer" is guessable from spelling. Masked autoencoders for images mask 75% of patches, not pixels, and He et al. found that low masking ratios make the task solvable by local interpolation. PatchTST masks 40% of patches for identical reasons. The invariant: the mask must be larger than the correlation length of the signal, or the objective teaches interpolation instead of understanding. If you are ever designing a masked objective for a new modality, that sentence is the whole design rule.

Does the representation actually transfer? The three-way comparison

A pretraining objective is only worth anything if the frozen representation is useful. PatchTST measures this three ways, and the ordering is the point:

ProtocolWhat trainsEpochsResult reported
Supervised from scratchEverything, from random initFull run per horizonThe Chapter 2 baseline
Linear probingThe head only; backbone frozen20"already comparable with training the entire network from scratch and better than DLinear"
Fine-tuningProbe for 10 epochs, then everything for 2030Best. "on large datasets our pre-training procedure contributes a clear improvement compared to supervised training from scratch"

Linear probing matching from-scratch supervision is the load-bearing result. It says the frozen features already contain what the forecasting task needs; the head is only reading them out. That is precisely the property that makes a backbone worth shipping as a checkpoint.

The two-stage schedule — probe first, then unfreeze — is not incidental either. The paper cites Kumar et al.: "a two-step strategy with linear probing followed by fine-tuning can outperform only doing fine-tuning directly." The reason is that a randomly initialised head produces large, meaningless gradients on the first steps, and those gradients flow straight into the pretrained backbone and damage it. Ten epochs of probing lets the head become sane before it is allowed to speak to the backbone.

Transfer across datasets — the first real foundation-model signal

The experiment that points directly at TimesFM and Chronos: pretrain on Electricity, fine-tune on the others. The result is honest and modest — "overall the fine-tuning MSE is lightly worse than pre-training and fine-tuning on the same dataset, which is reasonable", and sometimes worse than supervised training — but "the forecasting performance is still better than other models", and at a fraction of the compute, since only the head or a few epochs are retrained.

And the structural observation buried in that section is the one that made everything after it possible:

The sentence that unlocks pretraining across datasets. "This design can allow the pre-training data to contain different number of time series than the downstream data, which may not be feasible by other approaches." Because the backbone is channel-independent and patch-shaped, nothing inside it knows how many series it was trained on or how many it will be used on. Pretrain on 321 channels of Electricity, deploy on 1 channel of a customer's sales. Same weights, no reshaping. That is the precondition for a corpus-scale pretraining run, and it is why Chapter 2's contribution had to come first.

Reconstruct or predict? The objective fork

Two objectives are now on the table, and the three foundation models split between them. This fork determines everything downstream, so lay it out plainly.

Masked reconstructionCausal next-patch prediction
AttentionBidirectional — a token sees the futureCausal — a token sees only the past
Supervision per sequenceOnly the masked positions (40% or 30%)Every position — N predictions per sequence
Natural downstream tasksImputation, anomaly detection, classification, embeddingForecasting, at any horizon, by rollout
Forecasting needsA head, plus a decision about how the horizon entersNothing — just keep decoding
Variable context lengthFree — mask whatever you likeFree only with care — see Chapter 5's masking trick
Chosen byPatchTST (SSL variant), MOMENT, MoiraiTimesFM, Chronos

The second row decides most arguments. In a causal model every one of the N tokens produces a training signal on every sequence; in a masked model only the masked fraction does. For the same number of tokens processed, causal training extracts roughly 2.5× more supervision at a 40% mask rate. That efficiency is exactly why language models converged on causal decoding, and it is why both models that set out to be forecasters chose it.

But look at row three. If you want the checkpoint to be useful for classification, imputation and anomaly detection — which is MOMENT's entire thesis — bidirectional reconstruction is the better objective, because those tasks are all instances of "fill in what is missing given everything else". Chapter 7 returns to this with numbers.

Supervision density, counted

"Roughly 2.5× more supervision" was a hand-wave. Count it properly, because the real number is much larger than that and it explains a design choice in Chapter 5 that otherwise looks arbitrary.

Take a 512-point training sequence and ask, for each objective, how many numbers the loss is computed on.

supervised values per 512-point sequence# A. masked reconstruction, PatchTST SSL config: P = 12, disjoint, 40% maskedpatches            = 512 / 12          = 42
masked patches     = 0.40 * 42          = 17
supervised values  = 17 * 12            = 204      # 0.40x the observations

# B. causal next-patch, output patch equal to input patch: p = h = 32tokens             = 512 / 32          = 16
# token j predicts steps 32j+1 .. 32j+32, and the last one falls off the endsupervised values  = 15 * 32            = 480      # 0.94x the observations

# C. causal next-patch, TimesFM's actual config: p = 32, h = 128tokens             = 16
# token j predicts steps 32j+1 .. 32j+128 — targets OVERLAPtokens 1..12 : 128 valid targets each  = 1,536
token 13     :  96   token 14 : 64
token 15     :  32   token 16 :  0     =   192
supervised values                       = 1,728    # 3.38x the observations

# ratio C : A  =  1,728 / 204  =  8.5x more supervision from the same data
Read configuration C again, because it contains something genuinely surprising. The number of supervised values is larger than the number of observations — 1,728 targets from 512 numbers. That is not double counting a mistake; it is the point. Because h / p = 128 / 32 = 4, every timepoint in the middle of the sequence is a prediction target for four different tokens, each of which saw a different amount of history. The model is asked "predict step 300" from 172 points of context, then from 204, then from 236, then from 268 — four separate lessons about the same number. Long output patches are not only about fewer rollout steps at inference. They are a supervision multiplier at training time.

And notice what this does to the data problem. Time-series corpora are small compared with text: Chronos trains on a corpus assembled from 28 public datasets, and MOMENT had to build the Time Series Pile from four archives because nothing suitable existed. When data is the binding constraint, an objective that extracts 3.4 targets per observation instead of 0.4 is worth more than an extra billion parameters.

The counter-argument, for balance: those four lessons about step 300 are highly correlated, so eight and a half times the targets is not eight and a half times the information. It is closer to a curriculum — the same target, at four difficulties — and curricula have diminishing returns. But the gradient signal is real, and it is free.

Design challenge.

You are pretraining on 10-minute weather data. Your patches are 12 points (two hours) and you mask 40% of them. A colleague reports that the model reconstructs masked patches almost perfectly after one epoch, and yet the frozen features are useless for forecasting. Diagnose it, and give two fixes.

Answer. The correlation length of 10-minute weather far exceeds two hours — temperature at 14:00 is very well predicted by temperature at 12:00 and 16:00. So a two-hour mask is still inside the interpolable regime, and the model has learned an interpolator, not a representation. This is the point-masking failure at a coarser grain. Fixes: (1) increase the mask span — mask contiguous runs of several patches so the gap exceeds the correlation length, which is what a 75% image-masking ratio achieves; (2) change what is predicted — move to causal next-patch prediction, where the right-hand context is unavailable by construction, so interpolation is impossible. And a cheaper diagnostic to run first: compute the reconstruction MSE of plain linear interpolation on the same masked positions. If your model is not comfortably beating it, the task is too easy and no amount of training will make the features better.

Why does PatchTST mask entire patches rather than individual timesteps?

Chapter 4: Chronos — A Value Is a Word

Every paper so far has answered "what is a token?" by building something — a projection, a residual block, an architecture. Chronos answers it by refusing to build anything at all.

The proposal, in one sentence: round the numbers to a fixed grid, call each grid cell a word, and hand the resulting sentence to an unmodified language model. The paper's own summary is almost defiantly plain: Chronos "tokenizes time series values using scaling and quantization into a fixed vocabulary and trains existing transformer-based language model architectures on these tokenized time series via the cross-entropy loss."

Not a new architecture. Not even a new loss. T5, exactly as published, with one change: the embedding table is resized. The paper is explicit that "No modifications are required to the language model architecture, except adjusting the vocabulary size to |Vts|… Concretely, adjusting the vocabulary size entails truncating (or extending) the input and output embedding layers of the language model."

Take a second to feel how strange this is. A forecaster that has no idea numbers are ordered. Bin 2000 and bin 2001 are adjacent on the real line, but to the model they are just two rows of an embedding table — as related, a priori, as "cat" and "carburettor". The loss does not know that predicting 2001 when the truth is 2000 is a near-miss and predicting 100 is a catastrophe; both cost the same. And it works anyway. Understanding why it works anyway is the most interesting thing in this chapter, and we get to it after the mechanics.

Step 1: scaling (already done in Chapter 1)

Recall the mean-scaling transform. Given a context x1:C, set m = 0 and

s = (1/C) ∑i=1..C |xi| ,    x̃i = xi / s

and keep our eight weekly demand values from Chapter 1:

x = [ 10, 12, 8, 14, 11, 15, 9, 13 ] ,   s = 92 / 8 = 11.5
x̃ = [ 0.8696, 1.0435, 0.6957, 1.2174, 0.9565, 1.3043, 0.7826, 1.1304 ]

These are still real numbers. A language model cannot read them. That is what step two is for.

Step 2: quantization, derived

Pick B bin centers c1 < c2 < … < cB on the real line, with B − 1 edges bi sitting between consecutive centers. The quantization function q maps a real to an integer, and the dequantization function d maps it back:

q(x) = i  such that  bi−1 ≤ x < bi   (with b0 = −∞, bB = +∞)
d(i) = ci

Two decisions remain: where to put the centers, and how many.

Where. You could space them by quantiles of the training data — more resolution where values are dense. Chronos deliberately does not: "Since the distribution of values for unseen downstream datasets can differ significantly from the training distribution, we opt for uniform binning." This is a foundation-model decision, not a compression decision. Quantile bins are optimal for the corpus you have and mis-shaped for the corpus you have not seen. Uniform bins are never optimal and never catastrophic.

So the centers are uniformly spaced on [c1, cB] = [−15, +15], with edges exactly midway: bi = (ci + ci+1) / 2.

How many. The vocabulary size is 4096, "including the special tokens (PAD and EOS)". Subtract those two and you get B = 4094 numeric bins — the number the paper uses in its own error analysis.

Now the spacing falls out. With B centers spanning a range of 30, there are B − 1 gaps:

Δ = 30 / (B − 1) = 30 / 4093 = 0.00732959

and the i-th center (1-indexed) is ci = −15 + (i − 1)Δ.

The full hand-worked tokenisation

To turn a scaled value v into an index, invert that formula and round to the nearest center:

i = round( (v − (−15)) / Δ ) + 1 = round( (v + 15) / 0.00732959 ) + 1

Do the first one completely, digit by digit. v = 0.8696:

quantizing one value, every step shownv + 15            = 0.8696 + 15 = 15.8696
(v + 15) / delta  = 15.8696 / 0.00732959 = 2164.87
round(...)        = 2165
index i           = 2165 + 1 = 2166

# check by going back: the center of bin 2166 is
c_2166            = -15 + 2165 * 0.00732959 = -15 + 15.868563 = 0.868563
# and un-scaling by s = 11.5:
c_2166 * s        = 0.868563 * 11.5 = 9.9884      # true value was 10
error             = -0.0116                        # 0.12% of the value

The whole context, tokenised:

xx̃ = x / 11.5Token idBin center ciDequantized ci·sError
100.869621660.8685639.9884−0.0116
121.043521901.04446612.0114+0.0114
80.695721420.6926467.9654−0.0346
141.217422141.22037614.0343+0.0343
110.956521780.95651110.9999−0.0001
151.304322251.30100214.9615−0.0385
90.782621540.7806018.9769−0.0231
131.130422021.13242113.0228+0.0228

So the sentence a T5 encoder sees is literally

[ 2166, 2190, 2142, 2214, 2178, 2225, 2154, 2202 ]

and the worst error in the table is 0.0385 out of a value of 15 — 0.26%. The theoretical bound is half a bin width: Δ/2 = 0.003665 in scaled units, which is 0.003665 × 11.5 = 0.0421 in original units, and every row respects it.

The range [−15, +15] is not arbitrary. Because the scale s is the mean absolute value of the context, a scaled value of 1.0 means "a typical-sized observation". So the vocabulary spans from fifteen times the typical magnitude below zero to fifteen times above. For nearly any well-behaved series that is generous — our demand series only used the interval [0.70, 1.30], which is 1.4% of the representable range, roughly 82 of the 4094 bins. Almost the entire vocabulary is spare capacity for series that are spikier than this one. And that spare capacity is exactly what runs out in the failure modes below.
Value quantization explorer

The top panel shows the raw series and, over it, the dequantized reconstruction Chronos would see. The bottom shows the token ids. Shrink the vocabulary and watch the reconstruction step; switch to the sparse-spike or offset-sine series and watch the two documented failure modes appear on screen. The readouts under the panels are computed live from the same arithmetic you just did by hand.

Vocabulary B 4094
Offset / spike gap 0

Step 3: the model, which is not a step at all

Token ids in, T5 out. The only architectural surgery is the embedding table, and it is worth seeing what that does to the parameter counts, because it explains a footnote that otherwise reads as a typo.

Chronos variantBase architectureParamsNote
Chronos-T5 (Mini)T5 encoder-decoder20MThe paper flags that "These numbers differ from the original sizes of the T5 models… due to the change in the vocabulary size." T5's text vocabulary is 32,128; the time-series vocabulary is 4,096, so the input and output embedding tables shrink by roughly 87%
Chronos-T5 (Small)T5 encoder-decoder46M
Chronos-T5 (Base)T5 encoder-decoder200M
Chronos-T5 (Large)T5 encoder-decoder710M
Chronos-GPT2GPT-2, decoder-only90MIncluded to show the recipe is architecture-agnostic — encoder-decoder or decoder-only, both work

The context length is 512 — "the default for T5 models" — and the prediction length is 64, "a value greater than the prediction lengths of all tasks we consider in our evaluation." Note that these are timepoints, not patches: Chronos spends one token per observation, which is the price of using a language model verbatim. Chapter 1's high-frequency squeeze is exactly this constraint.

The loss: regression by classification

The output distribution is a categorical over the 4096 vocabulary entries, and the loss is ordinary cross-entropy. The paper names the paradigm: "Chronos uses a categorical distribution to model the observations, performing regression via classification."

Work an instance. Suppose at some position the model's logits over five neighbouring bins are (0.4, 2.1, 3.6, 1.9, 0.2), and the true next value quantizes to the middle bin.

cross-entropy at one position, by handlogits        = [ 0.4 , 2.1 , 3.6 , 1.9 , 0.2 ]
subtract max  = [-3.2 ,-1.5 , 0.0 ,-1.7 ,-3.4 ]   # numerically safe softmax
exp           = [0.0408, 0.2231, 1.0000, 0.1827, 0.0334]
sum Z         = 1.4799
probabilities = [0.0275, 0.1508, 0.6757, 0.1234, 0.0226]

truth = middle bin  ->  loss = -ln(0.6757) = 0.3920
# and here is the point:
truth = next bin over ->  loss = -ln(0.1234) = 2.0920
truth = four bins away -> loss = -ln(0.0275) = 3.5920

# the guessing baseline for a 4096-way softmax is ln(4096) = 8.3178

Notice the middle line. Being one bin off — an error of 0.0073 in scaled units, utterly negligible — costs 2.09 nats, while being four bins off costs 3.59. The ratio is not 4:1, or 16:1, or anything proportional to the distance. It is whatever the softmax happens to produce, because cross-entropy has no notion of distance between classes. A conventional forecasting loss like MSE punishes errors quadratically by construction; this one does not punish by magnitude at all.

So why does it work? The answer is in the data, not the loss. The paper observes: "Even though the cross entropy is not distance-aware, the model learns to estimate distributions over neighboring tokens, and of diverse shapes, including multimodal ones." Here is the mechanism. The training targets are drawn from smooth real processes, so bin 2166 and bin 2167 co-occur in nearly identical contexts, millions of times. Two tokens that appear in interchangeable contexts get similar embeddings — this is the distributional hypothesis, exactly as it operates on synonyms in text. The ordering of the real line is not encoded in the loss; it is recovered from the data as an emergent property of the embedding table. The model learns that its vocabulary is ordered, in the same way a language model learns that Tuesday and Wednesday are similar.

And the paper is candid that this is unfinished business: "An in-depth theoretical and empirical analysis of the regression-via-classification paradigm in the context of time series forecasting would constitute interesting future research."

What you get for free: a predictive distribution

Because the output is a categorical distribution and generation is autoregressive sampling, a probabilistic forecast requires no extra machinery at all. Draw a token, dequantize it, append it to the context, draw the next, and repeat to the horizon. Do that 20 times — the paper's setting — and you have 20 sample paths. Read quantiles off them.

Encode
x1:C → scale by s → quantize → token ids → T5 encoder. Shape (C,) integers.
↓ 20 independent sampling runs
Decode
Sample ẑC+1 from the categorical, append, repeat for H steps. Shape (20, H) integers.
Invert
d(·) to centers, multiply by s. Shape (20, H) reals → take the 0.1, 0.2, …, 0.9 quantiles across the 20 paths. That is the interval forecast.

This is a real advantage over TimesFM, whose base model emits point forecasts and would need extra quantile heads (its paper notes this as a straightforward extension). It also costs something: a point forecast from Chronos requires aggregating over samples, which the discussion section lists as a target for future speedups.

The data: two augmentations that carry the whole corpus

Chronos's public pretraining data is smaller than TimesFM's by orders of magnitude — 28 public datasets, not 100 billion timepoints from Google's logs. Two augmentation schemes make up the difference.

TSMixup. Sample k ~ U{1, K} series of a common length from different datasets, scale each, and take a convex combination:

TSMixup1:l = ∑i=1..k λi(i)1:l

with K = 3 in the main runs. Because k can be 1, "original time series are adequately represented since they are included in the TSMixup augmentations with probability 1/3." The purpose is stated as pattern diversity: a mixture of a traffic series and a retail series is a series with two simultaneous seasonalities, which is a pattern the corpus does not otherwise contain.

KernelSynth. Build a bank of Gaussian-process kernels — linear for trend, RBF for smooth local variation, periodic for seasonality — then sample j ~ U{1, J} of them, combine with random + or × operations, and draw a sample from the resulting GP prior. The paper credits the Automatic Statistician for the idea and notes that it is running it backwards: that system searches over compositional kernels to explain a series, and "We use the inverse of this process — randomly compose GP kernels to generate new time series."

Why kernel composition is the right generator. Addition of kernels superposes structures — linear + periodic gives a trending seasonal. Multiplication modulates them — RBF × periodic gives a seasonality whose amplitude drifts, which is what almost every real series actually does. So a small kernel bank plus two operators covers a large fraction of the qualitative behaviours a forecaster must recognise, with an exactly known ground truth and no licensing or contamination worries. The main runs use 10M TSMixup augmentations plus 1M synthetic series.

The two ways this tokenizer breaks

Chronos has an honest limitations section, and both failure modes are direct consequences of the arithmetic above. They are worth knowing before you deploy it, because both are silent.

Failure 1 — overflow on sparse series. The representable range in original units is [−15s, +15s]. If s is tiny relative to the peaks, the peaks fall off the end of the vocabulary. The paper's own example: unit spikes every n observations, so s = 1/n.

the intermittent-demand failure, by handspikes of height 1.0, one every n observations
s = mean|x| = 1/n
maximum representable original value = 15 * s = 15/n

n = 10 :  15/10 = 1.50   ->  spike of 1.0 fits   (OK)
n = 20 :  15/20 = 0.75   ->  spike of 1.0 CLIPS  (top bin)
n = 50 :  15/50 = 0.30   ->  spike of 1.0 CLIPS  badly

# the paper: "When 1 > 15/n then the model cannot possibly capture
# the spikes appropriately... since their value is not represented
# accurately by tokens."

Intermittent demand — the spare part that sells four units a year — is one of the most common real forecasting problems there is, and it is precisely where mean scaling collapses. This is the single most practically important sentence in the Chronos paper.

Failure 2 — precision loss on offset series. The opposite regime. If s is large relative to the variance, the interesting variation is smaller than one bin. Token spacing in original units is 30s / (B − 1):

Seriess ≈Token spacing 30s / 4093Distinct tokens across a peak-to-peak swing of 2.0
sine of amplitude 1, offset μ = 110.00733273 — plenty
sine of amplitude 1, offset μ = 10100.0733027
sine of amplitude 1, offset μ = 50500.366485.5 — the wave is a staircase

A signal riding on a large DC offset — a temperature in Kelvin, a stock index, a cumulative counter — loses almost all its structure. The fix the paper offers is an inference-time heuristic, not a model change: "preprocess the time series using an alternative normalization scheme, such as standardization, for time series with large scale and small variance." In other words, centre it yourself before you hand it over.

Both failures are the same failure. Mean scaling sets one number, s, from the mean absolute level, and then a fixed window of ±15s has to accommodate the spread. When level and spread are decoupled — sparse spikes have a tiny level and a large spread; offset sines have a large level and a tiny spread — the window is the wrong size, and there is no learning that fixes it, because the damage happens in the tokenizer before the model ever sees the data. Every quantization scheme has this shape of failure. The design question is always: which statistic sets the grid, and what is the range of things that statistic fails to predict?

One ablation that is more interesting than it looks

The paper sweeps the vocabulary size on Chronos-T5 (Small) and reports something that is not a clean win: "modest improvements in the point forecasting metric (MASE) as the vocabulary size increases. In contrast, the WQL initially improves but deteriorates for larger vocabulary sizes."

Their explanation is a metric argument and it is worth internalising, because it is a trap you can fall into on any project. MASE is scale-invariant, and so is the training loss (which operates entirely on scaled values), so the two move together: more bins means finer resolution means better MASE. WQL is scale-dependent, so it does not track the training loss and "behaves less predictably as precision increases." The paper's conclusion is deliberately modest: selecting a vocabulary size "would pose a trade-off", between resolution and the number of examples the model sees for each token.

Break-it lab.

You are forecasting a warehouse temperature sensor reporting in Kelvin. Values sit between 291.0 K and 294.0 K. Compute the token spacing Chronos would use, the number of distinct tokens your entire signal can occupy, and then give the one-line preprocessing fix and verify it.

Answer. s = mean|x| ≈ 292.5. Token spacing = 30 × 292.5 / 4093 = 8775 / 4093 = 2.144 K. Your entire 3.0 K signal spans 3.0 / 2.144 = 1.4 tokens — effectively two values. The model will emit a flat line and be technically almost correct on MASE while being completely useless. Fix: subtract a constant before scaling — work in Celsius (values around 19.0, s ≈ 19, spacing 0.139 K, 21 tokens across the swing) or, better, subtract the context mean and hand over the residual, then add it back (values around ±1.5, s ≈ 0.85, spacing 0.0062 K, about 480 tokens across the swing). The lesson: for a Chronos-style tokenizer, the choice of unit and origin is a modelling decision, not a formatting one.

Chronos's cross-entropy loss treats bins as unordered classes, yet the paper shows the model produces smooth, sometimes multimodal distributions over neighbouring bins. Why?

Chapter 5: TimesFM — Decoder-Only Rollout

Chronos borrowed a language model whole. TimesFM borrowed only the shape of one — a causal decoder that predicts the next thing from all previous things — and then broke the analogy in exactly one place, which turns out to be the most interesting design decision in the paper.

The claim is a modest-sounding one for a 200M-parameter model: zero-shot performance that "comes close to the accuracy of fully-supervised forecasting models on a diverse set of time-series data." And the authors are careful to put it in context against the alternative that was popular at the time: "unlike recent work that recommends Large Language Models such as GPT-3 and LLama-2 as out-of-the-box zero-shot forecasters, foundation models trained from scratch exclusively on time-series data can obtain much better zero-shot performance at a tiny fraction of its costs."

The three decisions, in order of increasing interest

Decision one: patch. Inherited from PatchTST, and justified in the same terms — "A patch of a time-series is a natural analogue for a token in language models" — with the added inference argument that "the number of tokens being fed into the transformer is reduced by a factor of the patch length."

Decision two: go causal. "A key difference between our architecture and PatchTST is that our model is trained in decoder-only mode. In other words, given a sequence of input patches, the model is optimized to predict the next patch as a function of all past patches. Similar to LLMs this can be done in parallel over the entire context window, and automatically enables the model to predict the future after having seen varying number of input patches."

That last clause is the whole reason. A bidirectional encoder with a forecasting head is trained for one context length and one horizon. A causal decoder over N patches produces N supervised predictions per sequence, each conditioned on a different amount of history — so it is simultaneously being trained to forecast from 1 patch, 2 patches, …, N−1 patches. Variable context length is not a feature you add; it is a side effect of the objective.

Decision three: make the output patch longer than the input patch. This is the novel one, and it deserves its own section.

Why the output patch is 128 when the input patch is 32

Start with the tension the paper identifies. In long-horizon forecasting "it has been observed that directly predicting the full horizon yields better accuracy than multi-step auto-regressive decoding" — a direct multi-step head beats rolling a one-step model forward, because rolled-forward errors compound. But you cannot bake the full horizon into the output width when you do not know the horizon in advance, "as in the case of zero-shot forecasting which is our primary goal."

TimesFM's answer: "We propose a middle ground by allowing our output patches for prediction to be longer than the input patches." Input patch p = 32, output patch h = 128.

The paper's own training illustration, spelled out: "suppose the input patch length is 32 and output patch length is 128. During training, the model is simultaneously trained to use the first 32 time-points to forecast the next 128 time-steps, the first 64 time-points to forecast time-steps 65 to 192, the first 96 time-points to forecast time-steps 97 to 224 and so on."

And the inference payoff, also the paper's example: "During inference, suppose the model is given a new time-series of length 256 and tasked with forecasting the next 256 time-steps into the future. The model will first generate the future predictions for time-steps 257 to 384, then condition on the initial 256 length input plus the generated output to generate time-steps 385 to 512."

rollout step count — the arithmetic that makes h mattersteps = ceil(H / h)          # H = requested horizon, h = output patch

H = 256, h = 128  ->  ceil(2.00) = 2 steps      # TimesFM as shipped
H = 256, h =  32  ->  ceil(8.00) = 8 steps      # if h were tied to p
H = 512, h = 128  ->  ceil(4.00) = 4 steps
H =  96, h = 128  ->  ceil(0.75) = 1 step       # most benchmarks: ONE forward pass

# each extra step feeds the model its own output, so errors compound.
# 2 steps instead of 8 is a 4x reduction in compounding opportunities,
# and a 4x reduction in sequential latency.

Look at the last line of that block. For the two most-reported long-horizon settings, T = 96 and T = 192, an output patch of 128 means the entire forecast comes out of one forward pass for T = 96 and two for T = 192. The model is behaving like a direct multi-step forecaster on exactly the benchmarks where direct multi-step is known to win, while remaining able to roll out arbitrarily far when asked.

The trade-off the paper names. "If the output patch length is too long, then it is difficult to handle time-series whose lengths are less than the output patch length for instance monthly, yearly time-series in our pretraining data." A yearly series with 40 observations cannot supervise a 128-step output patch — there is no target. So h is bounded above by the shortest granularity you care about, and bounded below by the number of rollout steps you are willing to compound. 128 is where those two constraints crossed for this corpus. Change the corpus and you should change h.

The architecture, with every shape

Track a series of length L = 512 through the model, with the 200M configuration: p = 32, h = 128, model_dim = 1280, 20 layers, 16 heads, FFN hidden size equal to model_dim.

StageOperationShape outNote
Inputy1:512 plus binary padding mask m1:512(512,) and (512,)mi = 1 means "ignore this input"
NormaliseStandardise using the mean and std of the first input patch(512,)The paper uses "only the standard normalization part of reversible instance normalization"
PatchContiguous, non-overlapping, size 32(16, 32) and (16, 32)512 / 32 = 16 tokens. Note: no overlap, unlike PatchTST
Input residual blockMLP with one hidden layer plus a skip connection, on [patch, mask](16, 1280)Not a bare linear map — the mask must be fused in here
Position+ positional encodings(16, 1280)
Stack20 layers, causal multi-head self-attention (16 heads) + FFN(16, 1280)Token j attends to tokens 1…j only
Output residual blockMLP 1280 → 128(16, 128)Each output token is a full 128-step forecast of what follows its own patch
Take the lastrow 16(128,)At inference only the final token's forecast is used; the other 15 exist to supervise training
Denormalise·σ + μ(128,)Back in the caller's units

Two structural notes. First, attention cost: 16 tokens is 256 attention cells, against 5122 = 262,144 for a pointwise model at the same context — a factor of 1024×. Second, the mask is an input, not a preprocessing step. It goes into the residual block alongside the values, so the model learns to interpret "this part of the patch is padding" rather than being handed silently corrupted numbers.

Where 200M comes from

Derive the parameter count from the four hyperparameters. It lands almost exactly on the headline number, which is a good sanity check that you have understood the architecture.

TimesFM 200M parameter count, derivedd = model_dim = 1280,  layers = 20,  FFN hidden = d (stated in the paper)

per transformer layer:
  attention  W_Q, W_K, W_V, W_O   = 4 * d * d = 4 * 1,638,400 =  6,553,600
  FFN        up + down             = 2 * d * d = 2 * 1,638,400 =  3,276,800
                                                                ----------
                                                                 9,830,400
x 20 layers                                                  = 196,608,000

input residual block  (patch 32 + mask 32 = 64) -> d -> d       ~ 1.80 M
output residual block  d -> d -> 128                            ~ 1.80 M
                                                                ----------
total                                                        ~ 200.2 M   # paper: "200M parameters"

Ninety-eight percent of the model is the transformer stack. The tokenizer and the head together are under 2%. Compare Chapter 3, where PatchTST's forecasting head was six times the backbone — the decoder-only design, with its fixed-width output patch, is what moves the parameters back into the part that generalises.

The masking trick that makes every context length reachable

Here is a subtle bug you would ship if you were not careful, and the two-line fix.

Patches are non-overlapping and aligned to the start of the sequence. So the amounts of history the model is ever asked to condition on are 32, 64, 96, 128, … — multiples of p. The paper states the risk directly: "If we use patches naively, the model might only learn to predict well for context lengths that are multiples of the input patch length." Hand it a context of 100 points at inference and it is in unfamiliar territory.

The fix: "For each time-series in the batch, we sample a random number r between 0 and p − 1. Then we set m1:r = 1 and the rest as zero, i.e. we mask out a fraction of the first input patch."

Follow the paper's worked example. Max context 512, p = 32, and suppose r = 4:

why masking r points of the FIRST patch covers every context lengthr = 4  ->  the first 4 values are masked out.

token o_1 sees 32 - 4               = 28 real points  ->  supervised at context 28
token o_2 sees 28 + 32              = 60 real points  ->  supervised at context 60
token o_3 sees 60 + 32              = 92 real points  ->  supervised at context 92
...                                                        (always 28 mod 32)

# now vary r over 0..31 across the batch and across training:
r = 0  covers contexts 32, 64,  96, ...   (0 mod 32)
r = 1  covers contexts 31, 63,  95, ...   (31 mod 32)
r = 2  covers contexts 30, 62,  94, ...   (30 mod 32)
...
r = 31 covers contexts  1, 33,  65, ...   (1 mod 32)

# union over r = 0..31: EVERY integer from 1 to 512. The paper:
# "the model has seen all possible context lengths till 512."

One random integer per sequence, and the model becomes context-length agnostic. That is the sort of two-line trick that separates a research prototype from something you can hand to a stranger with an arbitrary series.

Decoder rollout, with the horizon you choose

The context is patched into input tokens; each token emits a forecast of the next h steps, and only the last one is used at inference. Change the horizon and the output patch and watch the rollout steps — and the shaded compounding-error bands — grow or shrink. The masking slider hides the first r points of the first patch, exactly as in training.

Horizon H 256
Output patch h 128
Mask r (first patch) 0

The corpus, and what it is made of

TimesFM's pretraining data is the part of the paper that is hardest for anyone else to reproduce, and the authors are open about the sources.

SourceWhat it isScale reportedWhy it is in there
Wiki PageviewsHourly views of every Wikimedia page, Jan 2012 – Nov 2023, aggregated to hourly / daily / weekly / monthly"roughly 300B time-points"Enormous, genuinely multi-scale, and full of real human seasonality — weekday cycles, annual cycles, event spikes
Google TrendsSearch interest for a large query set, weekly and monthlyTens of thousands of series per granularityTrend, fashion, bursty attention. The paper notes this data is differentially private
M4The forecasting-competition archive, all granularities~100k seriesA curated mix of granularities from the community's own benchmark
Electricity, Traffic, WeatherStandard long-horizon datasetsHundreds to 800+ series, tens of thousands of points eachLong, dense, strongly seasonal series
SyntheticGenerated patterns20% of every batchCoverage of shapes the real corpus underrepresents

Total: "O(100B) timepoints", against 200M parameters. The ablation confirms the synthetic share is load-bearing — the paper compares the 200M model with and without synthetic data on both Monash and ETT.

Two ablations worth memorising

Input patch length. Sweeping p from 8 to 128 on a 70M model, "p = 16, 32 marks the best performance, with the error increasing towards either end." Too small and you are back to nearly-pointwise tokens with a huge sequence; too large and, as the paper says, "that makes the model shift from decoder only training more towards encoder-decoder style training" — in the limit p equals the context and there is only one token, so there is nothing causal left. They chose 32 over 16 because it is "almost twice as fast to train" for equal accuracy.

Scale. Three sizes — 17M, 70M, 200M — trained to 1.5M iterations at a global batch size of 4096 on TPUv5e, with checkpoints plotted against FLOPs. "It can be clearly seen that the errors decrease monotonically with the number of FLOPS (in log scale)." A clean log-linear scaling curve, on 100 billion timepoints, with the largest model costing "16 core TPUv5e for 2 days". That is a strikingly small budget for a foundation model, and it is the strongest evidence in the paper that the recipe is sound: the gains are coming from the design, not from brute force.

Concept check — answer before moving on. TimesFM emits a point forecast, not a distribution. What would you change to get intervals, and what would it cost?  …  The paper's own answer: "it is easy to have multiple output heads for each output patch, each head minimizing a separate quantile loss", or alternatively "output the logits of a probability distribution family and minimize the maximum likelihood loss." Cost: with 9 quantile levels the output residual block goes from 1280→128 to 1280→9×128, adding about 13M parameters — 6% of the model — and you must decide the quantile grid in advance. Chronos gets the same capability for free because its output was already a distribution; the price it pays is 20 sampling passes per forecast. Neither is free; they just bill you at different points.
TimesFM's output patch is 128 while its input patch is 32. What does that asymmetry buy, and what bounds it?

Chapter 6: Zero-Shot, Honestly

Every paper in this lesson reports that its model does well. All of them are telling the truth. This chapter is about reading those claims precisely enough to know what you are buying — because the honest summary is not "foundation models beat statistical baselines", and it is also not "the baselines still win". It is more specific and more useful than either.

First, the metrics — computed by hand

You cannot audit a claim in a unit you cannot compute. There are two units in this literature.

MASE — Mean Absolute Scaled Error. Take the mean absolute error of your forecast, and divide it by the mean absolute error a naive one-step model would have made in sample. The division is what makes it comparable across series with different scales.

MASE = MAE(forecast) / [ (1/(n−1)) ∑t=2..n |yt − yt−1| ]

Work one completely. Quarterly data, so the seasonal period m = 4. In-sample history and the four actuals we must forecast:

MASE, all of it, by handhistory y = [10, 20, 15, 5, 12, 22, 17, 7]     # 8 points, m = 4
actual  a = [11, 21, 16, 6]                    # what really happened

# denominator: mean absolute FIRST DIFFERENCE of the history
diffs = |20-10|,|15-20|,|5-15|,|12-5|,|22-12|,|17-22|,|7-17|
      =   10  ,   5   ,  10  ,   7  ,  10   ,   5   ,  10
sum   = 57 ,  count = 7
denom = 57 / 7 = 8.142857

# now score four forecasters:
seasonal naive  [12,22,17,7]     errs 1,1,1,1        MAE 1.000  MASE 0.1228
naive (last=7)  [ 7, 7, 7,7]     errs 4,14,9,1       MAE 7.000  MASE 0.8596
mean (13.5)     [13.5 x4    ]    errs 2.5,7.5,2.5,7.5 MAE 5.000 MASE 0.6140
over-smoothed   [11.5,19,15.5,8] errs 0.5,2,0.5,2    MAE 1.250  MASE 0.1535
a good model    [11.4,20.6,16.3,6.2] errs .4,.4,.3,.2 MAE 0.325 MASE 0.0399

Two lessons from that block, and they are the two that people get wrong.

MASE = 1 is not "good". It means you matched a naive one-step predictor's in-sample error. On a strongly seasonal series, seasonal naive already scores 0.1228 — eight times better than the denominator — so a model at MASE 0.9 is not "close to naive", it is seven times worse than copying last quarter.

A smooth, plausible-looking forecast can lose to a crude one. The "over-smoothed" row is what an underconfident model produces: right shape, shrunken amplitude. It scores 0.1535 against seasonal naive's 0.1228. It looks better on a chart. It is worse. Foundation models trained with an MSE-style objective are systematically prone to this, because shrinking toward the mean is the risk-minimising response to uncertainty.

WQL — Weighted Quantile Loss. Used for probabilistic forecasts, computed by Chronos "on 9 uniformly-spaced quantile levels {0.1, 0.2, …, 0.9}", with the quantiles estimated from 20 sample paths for methods that sample. The per-quantile ingredient is the pinball loss, which is asymmetric on purpose:

Lq(y, ŷ) = q · (y − ŷ) if y ≥ ŷ,   (1 − q) · (ŷ − y) otherwise
pinball loss — why the asymmetry is the whole ideatrue value y = 11, and we are scoring the q = 0.9 quantile forecast.

y_hat = 10  (too low)  ->  y >= y_hat  ->  0.9 * (11 - 10) = 0.90
y_hat = 13  (too high) ->  y <  y_hat  ->  0.1 * (13 - 11) = 0.20

# at q = 0.9 the loss punishes being too LOW 9x harder than being too high,
# which is exactly what forces the 0.9 quantile to sit above the data 90%
# of the time. Sum over the 9 levels, divide by sum|y|, and that is WQL.

Second, the aggregation — where a lot of intuition goes to die

Chronos reports "aggregated relative WQL" and "aggregated relative MASE". The recipe: score every model on every task, divide each score by the Seasonal Naive score on that task, and take a geometric mean across tasks.

Three consequences you must hold in your head when reading those figures.

ChoiceWhyWhat it hides
Normalise by Seasonal NaiveDatasets have wildly different difficulty; a raw average would be dominated by whichever dataset has the biggest numbersIf Seasonal Naive is unusually good on a dataset, every model's relative score looks bad there, and vice versa
Geometric, not arithmetic, meanRatios are multiplicative; the geometric mean is the right centre for them and is not dominated by one huge ratio. The paper notes it "is also not sensitive to the choice of the baseline"A model that is catastrophic on one dataset and fine elsewhere is treated more gently than an arithmetic mean would treat it
Equal weight per task"reflecting real-world scenarios where datasets may have different numbers of time series, frequencies, history and prediction lengths"A tiny 8-series dataset counts as much as one with 800 series

And a rule that quietly matters: "For models that failed or could not finish evaluation within the allotted time on certain datasets, we used a relative score of 1", i.e. the baseline's score. A model that cannot run on a dataset is scored as if it had tied with Seasonal Naive there, rather than being penalised.

The results, stated exactly

Chronos, Benchmark I — 15 datasets that were in its training corpus. "The bigger Chronos-T5 models (Base and Large) significantly outperform baseline models… not only… better than local models (e.g., AutoETS and AutoARIMA), but they also perform better than task-specific deep learning models trained or fine-tuned for each dataset (e.g., PatchTST and DeepAR)."

That is a strong result, and it is an in-domain result — the correct comparison for "should I use one model instead of forty thousand", not for "will this work on my new data". Note also the observation the authors chose to publish: "the Seasonal Naive baseline performs competitively against other local models on this benchmark, suggesting that the datasets in this benchmark exhibit strong seasonal patterns." Half the standard benchmark suite is nearly solved by copying last week.

Chronos, Benchmark II — 27 datasets never seen in training. This is the real test, and the paper opens with the caveat rather than the headline: "This benchmark is clearly more challenging than Benchmark I, as the best models tend to offer lower improvements relative to the baseline."

ClaimExact wording
Versus statistical baselines"Chronos models significantly outperform standalone local statistical models"
Probabilistic ranking"Chronos models achieve the 2nd to 4th spots, performing better than most task-specific models that have been trained on these tasks"
Point ranking"Chronos-T5 (Large) places 2nd, surpassing most baselines, including the strong SCUM ensemble"
The summary"it performs significantly better than local models that are commonly used in a zero-shot setting, and it performs on par with the best task-specific deep learning models"
With fine-tuningChronos-T5 (Small) fine-tuned for 1000 steps "now takes the top spot on Benchmark II overall"

"Second to fourth, on par with the best task-specific models" is a genuinely impressive result for a model that took no gradient steps on those datasets. It is not "beats everything".

TimesFM, across three benchmark families. The pattern is different and more revealing.

BenchmarkWhat it isResult, in the paper's words
Monash18 datasets (after filtering ones with missing values), minutes to years, finance / demand / weather / traffic"TimesFM is the top model even though we never trained on these datasets. It is slightly better but within significance of N-BEATS but outperforms deep supervised models like DeepAR, and improves on llmtime's performance by more than 25%"
Darts8 univariate datasets, one series each, with interesting seasonalities and additive/multiplicative trends"TimesFM is within statistical significance of the best models that is llmtime and seasonal ARIMA… since there are only 8 individual time-series in this dataset group, the standard errors are not sharp"
ETT (Informer)4 electricity-transformer datasets, horizons 96 and 192, context 512"TimesFM performs the best and the supervised PatchTST baseline… is within significance of it"
The single most honest line in this literature, and it is in TimesFM's own paper. On Darts, a 200M-parameter foundation model pretrained on a hundred billion timepoints is within statistical significance of seasonal ARIMA — a method from 1970 — on eight univariate series. The authors even explain why and do not soften it: "note that for ARIMA, the seasonality needs to be encoded correctly in the parameters for the best results, which needed manual tuning." So: a hand-tuned classical model matches the foundation model when there is one long, clean, strongly seasonal series and a human in the loop. The foundation model's advantage is that nobody tuned anything, and it would have done the same on ten thousand other series while the human tuned one.

When they win and when they do not

Assemble the pattern from the evidence above and from the tokenizer failures in Chapters 4 and 5. This table is the practical takeaway of the whole lesson.

SituationZero-shot foundation modelWhy
Thousands of series, none individually preciousStrong winOne checkpoint against thousands of fits. The operational argument dominates before accuracy is even discussed
Cold start — a series with 30 observationsStrong winNothing to fit. ARIMA cannot identify orders; the foundation model just needs a context
Strongly seasonal, plenty of history, one seriesDrawSeasonal ARIMA / ETS / N-BEATS are within significance, per Darts and Monash
Long-horizon multivariate benchmarks (ETT etc.)Slight winTimesFM edges supervised PatchTST, which is within significance
Intermittent / sparse demandLoss, sometimes badlyChapter 4: mean scaling makes s tiny, spikes exceed 15s and clip. Croston-family methods exist for exactly this
Large offset, small variance (Kelvin, index levels)Loss unless you preprocessChapter 4: token spacing 30s/(B−1) swallows the signal
Forecast driven by covariates (price, promotion, weather)LossNeither model accepts covariates. Both papers list this as an open limitation
Strong cross-channel structureLossChannel independence discards it by construction (Chapter 1)
High frequency needing multi-period contextDepends on tokenizerPatch-based models cope; a one-token-per-point model runs out of context
You have a decent slice of target dataFine-tune, do not zero-shot1000 steps moved Chronos-Small from mid-pack to first on 27 datasets
Zero-shot vs baselines — all errors computed live

Pick an archetype. Three real baselines are computed in your browser — seasonal naive, last-value naive, and simple exponential smoothing — alongside a toy stand-in for a pretrained model: it searches a small "pretraining corpus" of motifs for the one best matching the recent context and copies that motif's continuation. That is a caricature of what these models do, and it has the same failure mode: when the archetype is not in the corpus, retrieval returns something confidently wrong. Bars are MASE; shorter is better.

Noise level 0.12

Play with the last two archetypes. On pure noise the retrieval stand-in loses to the mean forecast, because there is no motif to find and it copies a random one anyway — the same reason a foundation model's confident wiggle on an unforecastable series is worse than a flat line. On level shift everything degrades, and the ranking becomes mostly a lottery, which is the honest answer to "how do these models handle regime change".

Contamination, and the fact that everyone knows

The zero-shot claim rests entirely on the target data being absent from pretraining, and every author in this space knows the guarantee is soft. The disclosures are worth reading in full because they set the standard for what "honest" looks like here.

Chronos, in a footnote about Benchmark II: "From a rigorous standpoint, to prevent information leakage, the start time of any dataset within this category must be after the timestamp of the last observation from the pretraining dataset and Benchmark I. Nevertheless, we consider the risk to be minimal given that the datsets bear no overlap beyond high-level conceptual categorization."

Chronos, about a competitor it is beating: "the evaluation setup may have been advantageous for Moirai-1.0-R as many datasets in Benchmark II were part of its pretraining corpus." A paper flagging that its own comparison flatters itself.

TimesFM, about the Darts benchmark: "since these datasets are used in numerous time series blog posts for illustrative purposes, data contamination for llmtime cannot be ruled out." An LLM prompted with a famous series may simply have read it.

And the most quietly admirable one — Chronos's own changelog: "We found an off-by-one error in the decoded bin indices for Chronos models which had led to artificially worse results for Chronos models in the previous version. Upon fixing this issue, the results for Chronos models improved significantly." A one-index bug in dequantization, disclosed in public, that had been understating their own numbers. Note what it also implies for you: if you implement Chapter 4's quantization yourself and are off by one bin, you will lose accuracy in a way that looks like a modelling problem and is not.

How to audit a zero-shot claim in ten minutes. (1) Find the pretraining corpus list and check your dataset is not in it — and check its source is not in it, since Wiki pageviews and Google Trends touch a great many domains. (2) Check the dates: if pretraining ran to November 2023 and your "held-out" series starts in 2019, the same underlying process was observed. (3) Reproduce the Seasonal Naive number yourself; if you cannot match the paper's baseline, you are not measuring the same thing. (4) Compute your own MASE with a denominator you computed, not one you were handed. (5) Always report the fine-tuned number alongside the zero-shot one — it is usually available for a thousand steps of compute and it is what you would actually deploy.

The cost side of the ledger

Chronos measures inference time for a single series and reports that "the inference speed of the larger Chronos models is comparable to some statistical local models", while conceding that "a potential limitation of the larger Chronos models is their inference speed compared to task-specific deep learning models."

Read that comparison carefully, because it is doing real work. A statistical local model is fitted per series — that fit is the expensive part, and it is what the comparison includes. A task-specific deep model is trained once and then evaluated cheaply per series — but that training run is not in the number. So:

ApproachOne-time costPer-series cost at serve timeCost of a brand-new series
ARIMA / ETSNoneA fit plus a forecastA fit — if there is enough history to fit
Task-specific deep modelA training run per datasetOne forward passFree if the series joins a trained panel; otherwise a retrain
Foundation modelSomeone else's training runOne forward pass (Chronos: 20, for the sample paths)One forward pass

The third column is where Chronos pays for its distribution: twenty sampling passes per forecast, each autoregressive over the horizon. The paper's own list of remedies is a list of things the NLP community already built — "quantization… and faster decoding techniques, including speculative and lookahead decoding" — which is the clearest possible illustration of what you buy by making your model architecturally identical to a language model.

A model reports MASE 0.95 on your strongly seasonal weekly sales data, and a colleague calls it "roughly as good as naive". What is wrong with that reading?

Chapter 7: Embeddings From Forecasters

A forecaster consumes a context and emits a future. Somewhere in the middle it holds a fixed-size representation of that context — and if that representation is good enough to forecast from, the obvious question is what else it is good enough for.

This chapter is about pulling the vector out of the middle and using it: to classify a series, to find similar series, to score how anomalous a window is. It is also where the honest limits of "one model for everything" become visible, because the objective a model was trained on determines what its representation throws away, and forecasting throws away exactly the things classification wants.

Where the vector is, and what shape it has

Take MOMENT, the model in this family built explicitly for general-purpose analysis rather than forecasting. Its configuration is stated precisely: "All models take an input time series of length T = 512, breaking it into N = 64 disjoint patches of length P = 8. We mask 30% of the patches uniformly at random during pre-training."

StageShapeNote
Input window(512,)Univariate. Multivariate handled "by independently operating on each channel along the batch dimension"
RevIN(512,)"re-scaling and centering time series using reversible instance normalization enables MOMENT to model time series with significantly different temporal distributions"
Patch(64, 8)Disjoint, P = 8. 512 / 8 = 64 exactly
Embed(64, D)D = 512 / 768 / 1024 for Small / Base / Large
Encoder(64, D)6 / 12 / 24 layers; 40M / 125M / 385M parameters, sized to match T5 encoders
Pool(D,)Average over the 64 token positions. This is the embedding of the series.

So a 512-point window becomes a 1024-number vector in the Large model. That is a 2:1 compression in raw count — not impressive as compression — but the point was never compression. The point is that the 1024 numbers live in a space where distance means similarity of dynamics, and the original 512 do not.

Why raw windows are a terrible representation, in one example. Take two identical sine waves, one shifted by half a period. In raw space they are maximally far apart — every coordinate has the opposite sign, so their cosine similarity is −1. As dynamics they are the same thing: same frequency, same amplitude, same generative process. Any downstream task that cares about "what kind of series is this?" needs phase-insensitivity, and raw coordinates cannot provide it. A learned encoder can, because its objective never rewarded remembering absolute phase.

Retrieval, worked

Once you have vectors, similarity is a dot product. Do one by hand in four dimensions so nothing is hidden. Let a query window and three library windows have pooled embeddings:

cosine retrieval over pooled embeddings, by handq                = [ 0.8,  0.5, -0.2,  0.3]   |q| = sqrt(0.64+0.25+0.04+0.09) = 1.0100

v1 ECG normal    = [ 0.7,  0.6, -0.1,  0.4]   |v1| = 1.0100
   dot = 0.8(0.7) + 0.5(0.6) + (-0.2)(-0.1) + 0.3(0.4)
       = 0.56 + 0.30 + 0.02 + 0.12 = 1.0000
   cos = 1.0000 / (1.0100 * 1.0100) = 0.9804        # nearest

v2 ECG arrhythmia= [ 0.2, -0.5,  0.8,  0.1]   |v2| = 0.9695
   dot = 0.16 - 0.25 - 0.16 + 0.03 = -0.2200
   cos = -0.2200 / (1.0100 * 0.9695) = -0.2247

v3 motor vibration=[-0.6,  0.3,  0.5, -0.2]   |v3| = 0.8602
   dot = -0.48 + 0.15 - 0.10 - 0.06 = -0.4900
   cos = -0.4900 / (1.0100 * 0.8602) = -0.5640      # most dissimilar

Three lines of arithmetic and you have a nearest-neighbour search over an archive of sensor windows. Index a million of them and the same dot product becomes semantic search over machine behaviour: show me every window that looks like the four hours before the last failure. There is no forecasting anywhere in that query, and it is arguably the most valuable thing the checkpoint does.

The three downstream tasks, and how each reduces to the same encoder

Classification
Pool to (D,), fit a linear classifier or a k-NN on top. MOMENT evaluates this on the UCR archive — "159 time series datasets… belonging to seven different categories (Image Outline, Sensor Readings, Motion Capture, Spectrographs, ECG, Electric Devices, and Simulated Data)" — explicitly in an unsupervised-representation setting.
↓ same encoder, different read-out
Anomaly detection
Slide a window, reconstruct it, score by reconstruction error. MOMENT does "Reconstruction-based anomaly detection with window size = 512" and evaluates on TSB-UAD — "1980 univariate time series with labeled anomalies from 18 anomaly detection datasets". Rare dynamics reconstruct badly because the model never learned them.
↓ same encoder again
Imputation
Mask the missing positions and reconstruct — which is literally the pretraining task, so this one is zero-shot by construction. No head, no tuning, nothing.

Notice how tightly the objective and the task list are coupled. Masked reconstruction gives you imputation for free, anomaly detection almost for free (reconstruction error is already the loss), and classification cheaply (pool and probe). Causal next-patch prediction gives you forecasting for free and the others awkwardly. The objective is not a detail; it is the product roadmap.

The honest result you should know about

MOMENT's imputation section reports that with linear probing it "achieved the lowest reconstruction error on all ETT datasets", and then adds: "In the zero-shot setting, MOMENT consistently outperformed all statistical interpolation methods with the exception of linear interpolation."

Sit with that. A 385-million-parameter foundation model, pretrained on a corpus assembled from four public archives, loses zero-shot imputation to drawing a straight line between the two neighbouring points.

And it is exactly the finding Chapter 3 predicted. Short-gap imputation in a smooth series is the interpolation task — the very task PatchTST argued was too easy to be a good pretraining objective. Linear interpolation is close to optimal on it. The lesson is not that MOMENT is bad; it is that you should check the trivial baseline, every time, on every task, and that a large model earns nothing merely by being large. Where MOMENT wins is exactly where interpolation cannot go: long gaps, structured gaps, and the settings where linear probing was allowed.

Can you use a forecaster as an embedding model?

Chronos says maybe, and is careful to label it a hypothesis rather than a result: "We hypothesize that the representations learned by the encoders of Chronos-T5 models are universal and can be used for these tasks. An exploration of Chronos-T5 representations for various downstream tasks would constitute interesting future work."

You can reason about how well that will go by asking, for each task, what the forecasting objective was paid to keep.

Property of the windowDoes a forecaster need it?Does a classifier want it?Consequence
Recent levelCritically — the forecast starts from itUsually not — an ECG is an ECG at any baselineForecaster embeddings are dominated by level; you may need to remove it
Phase within the cycleCritically — the next value depends on where in the cycle you areNo — class identity is phase-invariantTwo windows of the same class at different phases may sit far apart
Dominant frequencyYesYesShared — transfers well
Amplitude / variance structureYesYesShared — transfers well
Long-range morphologySomeCriticallyUnder-represented if the training horizon was short

The two "critically / no" rows are where forecaster embeddings will disappoint on classification, and they are also fixable: centre and phase-align before pooling, or pool over several offset windows and average, which washes out phase the way a bag-of-frames does in audio. That is a real technique, not a hedge — and it is exactly the kind of adaptation that separates using a checkpoint from understanding it.

Chronos also has a structural advantage worth naming: it is a T5, so it has a genuine encoder whose output is a bidirectional representation of the context. A pure decoder-only model like TimesFM has only causal states, so the representation at position j has never seen positions after j — you would pool the final state, or the mean of states, and accept that early tokens were encoded with less information than late ones.

Anomaly detection, with the threshold arithmetic

The reconstruction route deserves to be spelled out, because it is the one people deploy first and the one whose failure mode is least obvious.

The procedure: slide a window of 512 points along the series with some stride; run each window through the encoder and the reconstruction head; score the window by its mean squared reconstruction error. Rare dynamics score high because the model never learned to reproduce them.

Then you need a threshold, and the honest way to set one is to calibrate on a clean split rather than to pick a number.

calibrating an anomaly threshold, by hand# 1. run every window of a KNOWN-CLEAN period through the modelrecon errors on clean windows :  mean mu = 0.021 ,  sd = 0.006

# 2. pick a working point. three sigma is the usual first guess:threshold = mu + 3 * sd = 0.021 + 0.018 = 0.039

# 3. score a suspect windowe = 0.058
z = (0.058 - 0.021) / 0.006 = 6.17      # six sigma — flag it

# 4. sanity-check the alert rate BEFORE shipping.
#    at 3 sigma under a normal model, roughly 1 window in 741 fires.
#    with a 512-point window and a stride of 64 on 1 Hz data, that is
#    one window every 64 seconds -> about 65 false alarms per day, per sensor.
#    across 500 sensors that is 32,500 pages. The threshold is not the
#    hard part; the alert budget is.
The blind spot, and it is a foundation-model-specific one. Reconstruction-based detection assumes the model cannot reproduce what it has never seen. But a model pretrained on a corpus spanning nine domains has seen a great many failure signatures — bearing-fault harmonics, sensor dropouts, saturation clipping. If your anomaly is a common shape in the pretraining corpus, the model reconstructs it beautifully and the error stays low. The very generality that makes the checkpoint useful makes it blind to familiar anomalies. A small model trained on this one machine's normal behaviour has the opposite bias: it reconstructs nothing well except this machine, so it is a more sensitive detector and a noisier one. That is a real trade-off, not a bug, and it is the reason MOMENT evaluates on TSB-UAD's 1,980 labelled series rather than on one dataset.

How you pool matters more than you would guess

Every task above starts with "reduce (N, D) token representations to one (D,) vector". That reduction is a modelling choice, and different choices keep different things.

PoolingVectorPreservesDestroysGood for
Mean over tokens(D,)Average dynamics across the windowWhere in the window anything happenedClassification, retrieval — MOMENT's default
Last token(D,)The most recent state; the natural read-out for a causal modelEverything the model chose not to carry forwardForecasting from a decoder-only checkpoint
Max over tokens(D,)The strongest activation of each feature anywhere in the windowHow often it firedDetecting whether an event occurred at all
Mean & std concatenated(2D,)Average and variability of dynamicsOrderClasses that differ in regularity — arrhythmia versus normal sinus
No pooling(N, D)Everything, including positionNothing — but it is not a fixed-size vectorLocalisation: where the anomaly is, not just whether

The fourth row is the cheap win people miss. Concatenating the standard deviation across tokens costs one line and doubles the dimension, and it captures "how much did the dynamics change within this window" — which is precisely the discriminating feature in a great many sensor problems, and which mean pooling averages away by construction.

python — pulling embeddings out of a patched encoderimport torch

# x: (B, T) univariate windows, T = 512x = revin.normalize(x)                      # (B, 512)
patches = x.unfold(-1, 8, 8)                  # (B, 64, 8)   P = 8, disjoint
tok     = patch_proj(patches) + pos             # (B, 64, D)
h       = encoder(tok)                          # (B, 64, D)   D = 768 for Base

emb_mean = h.mean(dim=1)                      # (B, D)      the usual embedding
emb_rich = torch.cat([h.mean(1), h.std(1)], -1)  # (B, 2D)     dynamics + variability
emb_norm = torch.nn.functional.normalize(emb_mean, dim=-1)

# retrieval over an archive of M windows is now one matmulscores = emb_norm @ archive_norm.T              # (B, M) cosines
top    = scores.topk(10, dim=-1)                # nearest neighbours

Nine lines from a raw window to a semantic search over a sensor archive. The heaviest thing in that block is the encoder call, and it runs once per window, offline, exactly like indexing documents.

Which checkpoint for which job

You want to…Reach forBecause
Forecast, point estimate, long horizonTimesFMDecoder-only with a 128-step output patch; one or two passes for standard horizons
Forecast with calibrated intervalsChronosThe output is already a distribution; sample 20 paths and read the quantiles
Classify, cluster, retrieve, detect anomaliesMOMENT (or another masked model)Bidirectional masked reconstruction; pooled embeddings are the intended interface
Impute short gapsTry linear interpolation firstMOMENT's own zero-shot table says so
Forecast multivariate with true cross-channel structureMoirai, or a task-specific modelAny-variate attention is the only mechanism here that models channels jointly at arbitrary M
Anything, with a slice of labelled target dataFine-tune whichever of the above fitsChapter 6: 1000 steps changed Chronos-Small's ranking on 27 datasets
You pool a forecasting model's token representations and use the vector to classify ECG windows. Accuracy is mediocre. What is the most likely structural cause?

Chapter 8: The Design Axes

Eight chapters in, you have seen five models. It would be easy to file them as five separate inventions. They are not. They are five points in a small, enumerable design space, and once you can see the axes you can read any new paper in this area in about ten minutes — and, more to the point, you can propose the combinations nobody has shipped.

There are five axes that matter.

Axis 1 — Tokenization
What is one token? Point · patch · quantized bin · frequency-dependent patch. Sets the sequence length, and therefore the attention cost and the maximum span you can afford.
Axis 2 — Objective
Masked reconstruction · causal next-patch · categorical cross-entropy over bins · mixture NLL · quantile loss. Sets the supervision density and the downstream task list.
Axis 3 — Scaling
Standardise · mean-scale · none. Sets which series survive the tokenizer at all — recall the sparse-spike and large-offset failures.
Axis 4 — Attention shape
Bidirectional encoder · encoder-decoder · causal decoder · any-variate. Sets what a representation can see, and therefore whether the checkpoint is an embedder or a generator.
Axis 5 — Channels
Independent · mixed · any-variate. Sets whether the weights can be pretrained across datasets at all.

The five models, placed

TokenizationObjectiveScalingAttentionChannelsOutput
PatchTSTPatch 16, stride 8MSE horizon / masked patch (40%)RevIN standardiseBidirectional encoderIndependentPoint, fixed T
TimesFMPatch 32, disjointMSE on the next 128 stepsStandardise on the first patchCausal decoder, 20 layersIndependentPoint, any horizon
ChronosBin index, B = 4094Cross-entropy over binsMean scalingT5 encoder-decoder (or GPT-2)IndependentSampled distribution
MOMENTPatch 8, disjointMasked reconstruction (30%)RevIN standardiseBidirectional encoderIndependentReconstruction + task heads
MoiraiPatch size by frequencyMixture-distribution NLLInstance normalisationMasked encoder, any-variateAny-variateMixture distribution

Read the table by columns rather than rows and the field's actual state of knowledge appears. Column five is nearly constant — four of five models simply do not model channels — which tells you where the open problem is. Column three is nearly constant too, which tells you that scaling is considered solved (Chapter 4 says it is not). Columns one and two are where all the variation lives, which is why this lesson spent five chapters there.

Axis 1 in depth: the tokenization ladder

TokenSequence length for L = 512What the first layer isWinsLoses
Point512Rank-one linear mapNo information discarded; every value addressableQuadratic blow-up; each token nearly meaningless
Patch (overlap)64 at P = 16, S = 8Linear RP → RDShape-level tokens; smooth boundaries from overlapRedundant compute; leaks across masks in SSL
Patch (disjoint)16 at P = 32Linear or residual MLPCheapest; clean maskingBoundary artefacts; coarse resolution inside a token
Quantized bin512Embedding lookupA real vocabulary; language machinery works verbatim; distributions for freeQuantization error; overflow/precision failures; long sequences
Frequency-conditioned patchVariesOne projection per patch sizeRight resolution per granularityNeeds the frequency as an input; more parameters

Now look at the fourth and third rows together. The quantized token has the property everyone wants — a genuine discrete vocabulary — and the property nobody wants, a sequence as long as the series. The patched token has the opposite pair. Nothing in these five papers has both. That empty cell is the most obvious open recombination in the space, and it has a name in every neighbouring field: quantize the patch, not the value. Learn a codebook of K prototype shapes, assign each patch to its nearest code, and you get a short sequence of genuine discrete tokens.

This is not speculation; it is what other modalities already did. Audio went exactly this way: raw waveform → frames → a learned residual vector-quantized codebook, which is what makes a neural audio codec's output a sequence a language model can consume. Images went the same way with VQ-VAE. Both faced the identical problem — a continuous signal with no vocabulary — and both solved it with patch-level vector quantization rather than value-level scalar quantization. If you want to see the machinery in detail it is one link away in VAE and VQ-VAE and neural audio codecs. The reason it is harder for time series is that a codebook is learned on a distribution of shapes, and time-series shapes vary far more across domains than phonemes do across speakers.

Axis 2 in depth: what each objective buys and forecloses

ObjectiveSupervision per sequenceGives you freeMakes awkwardFailure signature
MSE on a fixed horizon1 targetDirect multi-step accuracyVariable horizon; needs a head per TAmplitude shrinkage under uncertainty
Masked reconstructionmask fraction × NImputation, anomaly scores, embeddingsForecasting (needs a head and a story)Learns interpolation if the mask is too small
Causal next-patch MSEN targetsAny horizon; any context lengthDistributions (needs quantile heads)Compounding error over rollout steps
Cross-entropy over binsN targetsA full predictive distribution; multimodalityPoint forecasts (must aggregate samples)Tokenizer overflow / precision, not model error
Mixture NLLN targetsContinuous distributions, no quantizationChoosing the mixture family in advanceMode collapse onto one component

The last column is the one to memorise, because it is your debugging checklist. When a foundation model produces a bad forecast, the first question is not "is it undertrained" but which of these signatures am I looking at. A flat, shrunken forecast is an objective problem. A staircase is a tokenizer problem. A forecast that drifts increasingly wrong after step 128 is a rollout problem. Three different fixes.

A design exercise: build the model these five cannot

Chapter 6 named intermittent demand as the clearest loss for this family. Design a model for it, on purpose, one axis at a time. Do not skip to the answer; the value is in watching each constraint propagate.

The data. Weekly demand for spare parts. A typical series is mostly zeros with occasional counts of 1–4, and the zeros are meaningful — they are not missing data. Horizon 13 weeks; what the business needs is P(demand > 0) and the size distribution, not a point estimate.

AxisChoiceReason, in one line
ScalingMean scaling — but with s from the non-zero values only, or no scaling at all if counts are smallChapter 4: s = mean|x| collapses toward zero as sparsity rises, and 15s stops covering the spikes. Scaling on non-zeros keeps the window sized to the events
TokenizationPatch, disjoint, length 4 (a month)A single zero is uninformative; "three zeros then a 2" is the unit of meaning. Patching is what moves the token to that level
ObjectiveTwo heads: Bernoulli over "any demand in this patch" plus a count distribution conditional on demandThe quantity of interest is explicitly a mixture of a point mass at zero and a positive distribution. MSE cannot represent that; neither can a single categorical over a uniform grid
AttentionCausal decoderVariable horizon, and N supervision targets per sequence — sparse data is scarce, so extract the most signal per sample
ChannelsIndependent, plus a static embedding for part categoryCross-part structure is real but weak; a static covariate is far cheaper than any-variate attention

Notice what happened. Every choice was forced by a property of the data that a general-purpose model had ignored, and the result is not a small tweak — it is a different model with a different loss, a different scaler and a different output head. That is the honest scope of "foundation model for time series" today: a very good default, and a starting point for the twenty percent of problems that have structure the default was never shown.

The five rules distilled. (1) The token sets the ceiling. Whatever the model cannot resolve inside a token, no amount of depth recovers. (2) The objective is the product roadmap — it decides which downstream tasks are free, which are cheap, and which are impossible. (3) The scaler decides which series survive, and its failures are silent because they happen before the model. (4) Causal training buys context-length freedom, and it does so for free, as a side effect. (5) Channel-agnostic weights are the price of admission to cross-dataset pretraining — and the thing everyone is still paying.

The sixth axis, which nobody calls an axis: the corpus

Architecture papers get read; data sections get skimmed. In this family the data section is where most of the variance actually lives, and the five models differ on it more than they differ on anything else.

ModelCorpusScaleAugmentationThe bet being made
TimesFMGoogle Trends, Wiki pageviews, M4, Electricity, Traffic, WeatherO(100B) timepoints20% synthetic, granularity-balanced loaderVolume and human-behavioural seasonality generalise to everything else
Chronos28 public datasets10M TSMixup + 1M syntheticConvex mixtures + Gaussian-process kernel compositionYou can manufacture pattern diversity when you cannot buy volume
MOMENTThe Time Series Pile, from 4 public archivesMulti-task, multi-domainNone; careful disjoint splits, seed 13Breadth of task beats depth of any one
MoiraiLOTSA> 27B observations, 9 domainsRandom context and prediction lengthsAn open archive is itself the contribution

Look at Chronos versus TimesFM. Chronos has roughly three orders of magnitude less real data and closes the gap with two generators — convex mixtures of real series, and samples from randomly composed GP kernels. Both are cheap, both are auditable, and neither requires access to a search engine's logs. If you are outside a large company, that row is the one to copy.

And the contamination point from Chapter 6 is really a corpus point. "Zero-shot" is a claim about the relationship between two datasets, so it is only as strong as the corpus documentation. A model whose corpus is a proprietary log stream cannot support an auditable zero-shot claim, no matter how good its numbers are.

The empty cells

Cross the axes and most combinations have never been shipped. Here are the four that look most load-bearing, with what each would buy and what it would cost.

RecombinationWould buyWould costPrecedent elsewhere
Patch-level vector quantization — a learned codebook over patch shapes rather than over scalar valuesA genuine discrete vocabulary and a short sequence. Distributions for free, at 16 tokens instead of 512Codebook collapse; and time-series shapes vary far more across domains than phonemes do across speakersVQ-VAE for images; residual vector quantization in neural audio codecs
Causal decoder with a mixture-distribution head — TimesFM's rollout, Moirai's outputAny-horizon rollout and calibrated intervals, with no quantization error and no sampling passesYou must choose the mixture family in advance, and mixtures can collapse onto one componentDeepAR's parametric heads; Moirai already does the head, just not causally
Frequency-conditioned patching in a decoder — Moirai's multi patch-size projections, TimesFM's architectureRight resolution per granularity without giving up the rollout freedomThe frequency becomes a required input, which it often is not in practiceMoirai's own multi patch-size projection layers
Role-tagged tokens for covariates — every covariate patched by the same shared projection, distinguished by a learned role embeddingThe single largest missing capability: promotions, prices, weather forecastsSequence length grows linearly in the covariate count, so attention grows quadraticallyMoirai's learned variate identities; segment embeddings in BERT

How to read the next one of these in ten minutes

A new time-series foundation model appears roughly every few months. Six questions, in this order, will tell you almost everything before you reach the results table.

#QuestionWhat the answer predicts
1What is one token, and how many are there for a 512-point context?The attention budget, the maximum span, and whether high-frequency data is usable at all
2What is the loss computed on, and how many targets per sequence?Data efficiency, and which downstream tasks are free versus bolted on
3How is the input scaled, and what happens to a mostly-zero series?Whether intermittent demand works. This is almost never in the abstract
4Causal or bidirectional?Whether the checkpoint is a generator, an embedder, or awkwardly both
5What happens with 862 channels?Whether cross-channel structure is modelled or discarded — usually discarded
6What is in the corpus, and is my data's source in it?Whether the zero-shot number means anything for you

If you can answer all six, you can predict the failure modes without running anything — and you will know which of the ten rows in Chapter 6's win-and-lose table your problem sits in.

Invention challenge.

Design a time-series foundation model that accepts covariates — price, promotion flag, weather forecast — without abandoning cross-dataset pretraining. The hard constraint is the one from Chapter 1: the number and meaning of covariates differ per dataset, so no weight may have a shape that depends on them.

One good answer, with the reasoning. Treat every covariate as another univariate series and tokenise it with the same shared patch projection — that keeps all weights covariate-agnostic. Then you need to tell the model which tokens are the target and which are context, and that is a per-token flag, not a per-dataset weight: add a learned "role" embedding (target / past-covariate / known-future-covariate) to each token, exactly as Moirai adds a learned variate identity. Attention then runs over the flattened set of all tokens from all series, so an arbitrary number of covariates is admissible, and the forecast is read only off the target-role positions. The two costs are real: the sequence grows linearly in the number of covariates, so attention grows quadratically in it; and the model must learn what a covariate means from context alone, since "price" and "temperature" get the same role flag. The papers' own suggestions are cheaper and weaker — TimesFM proposes predicting in-context and then "linearly regress[ing] the residual on covariates", and Chronos proposes "stacking ensembles of Chronos and other light-weight models that excel at handling covariates such as LightGBM". Both are admissions that the covariate lives outside the model.

Across the five models, which design axis is least explored, and what does that tell you?

Chapter 9: Legacy & Cheat Sheet

Three papers, eighteen months, one question answered three ways. What is actually different about forecasting now?

Not the accuracy, mostly. Chapter 6 was blunt about that: on a single clean seasonal series, a tuned classical model is within significance. What changed is the unit of deployment. Before, the unit was a fitted model per series. After, the unit is a checkpoint per organisation. That is the same relocation that language modelling went through, and it has the same consequence: the interesting engineering moves from "how do I fit this" to "what do I ask it".

The symbol table

SymbolMeaningValue / shape in these papers
LLook-back window (context length), in timepoints336 or 512 (PatchTST); 512 (TimesFM, Chronos, MOMENT)
T, HForecast horizon96 / 192 / 336 / 720 (long-horizon); 64 (Chronos training)
MNumber of channels (variates)1, 7, 21, 321, 862 depending on dataset
P, pPatch length (input)16 (PatchTST), 32 (TimesFM), 8 (MOMENT), 12 (PatchTST SSL)
SStride between patches8 (PatchTST); equal to P for disjoint patching
hOutput patch length128 (TimesFM) — deliberately > p
NNumber of tokens, ⌊(L−P)/S⌋ + 242 or 64 (PatchTST); 16 (TimesFM, L = 512); 64 (MOMENT)
D, dModel dimension128 (PatchTST); 1280 (TimesFM); 512/768/1024 (MOMENT)
WpPatch projection — the entire "tokenizer"RD×P; 128×16 = 2,048 weights
WposLearned additive positional encodingRD×N; 128×42 = 5,376 weights
sChronos mean scale, (1/C)∑|xi|Scalar per context; 11.5 in the worked example
BNumber of quantization bins4094 numeric (4096 vocabulary including PAD and EOS)
ΔBin spacing, 30/(B−1)0.00732959 in scaled units
[c1, cB]Representable range in scaled units[−15, +15], i.e. [−15s, +15s] in original units
rTimesFM random mask length on the first patchSampled uniformly from {0, …, p−1}
m1:LBinary padding mask, an input to the model1 = ignore this timepoint

The equations, in order

(1)  patching:  xp ∈ RP×N,  N = ⌊(L − P)/S⌋ + 2
the +2 is one inclusive count plus one padded tail patch
(2)  embedding:  xd = Wp xp + Wposxd ∈ RD×N
this is the whole tokenizer — a linear map, not a lookup
(3)  channel independence:  (B, M, L) → (B·M, 1, L),  shared weights
the reshape that makes cross-dataset pretraining possible
(4)  mean scaling:  s = (1/C) ∑i |xi|,  x̃i = xi / s
m = 0, so zeros stay zeros
(5)  quantization:  q(x) = i  for  bi−1 ≤ x < bi,   d(i) = ci,   bi = (ci + ci+1)/2
uniform centers on [−15, +15]; uniform because downstream distributions are unknown
(6)  Chronos loss:  − ∑hi=1..|V| 1[zC+h+1 = i] · log pθ(zC+h+1 = i | z1:C+h)
plain cross-entropy; no distance awareness; chance baseline ln(4096) = 8.318
(7)  TimesFM rollout:  ŷL+1:L+h = f(y1:L),  then  ŷL+h+1:L+2h = f([y1:L ; ŷL+1:L+h])
⌈H / h⌉ steps in total — 2 for H = 256 at h = 128, versus 8 if h were 32
(8)  MASE = MAE(forecast) / [ (1/(n−1)) ∑t=2..n |yt − yt−1| ]
the denominator is in-sample and naive; 1.0 is not "good"

The numbers worth remembering

NumberWhat it is
42 and 64Token counts for L = 336 and L = 512 at P = 16, S = 8. The title of the PatchTST paper
64×Attention-cell reduction from patching at stride 8. And "as much as 22 time" faster training, measured
21.0% / 16.7%PatchTST/64's MSE and MAE reduction against the best Transformer baselines
0.447 vs 0.518Long-span-subsampled versus recent-96, at equal token count — the control that motivates patching
40% / 30% / 75%Mask ratios: PatchTST patches, MOMENT patches, image MAE patches
4096 / 4094 / 0.00733Chronos vocabulary, numeric bins, and the bin spacing 30/4093 in scaled units
[−15s, +15s]The representable range. Everything outside it clips; everything finer than 30s/(B−1) is lost
15/nMaximum representable spike height for unit spikes every n steps. Clips for n ≥ 16
20M – 710MChronos-T5 sizes, shrunk from the original T5 sizes by the vocabulary change
200M / 1280 / 20 / 16TimesFM parameters, model dimension, layers, heads. The stack alone is 196.6M
32 → 128Input patch to output patch. Cuts ⌈H/h⌉ rollout steps by 4×
O(100B)TimesFM's pretraining timepoints; Wiki pageviews alone contribute roughly 300B before mixing
16 cores, 2 daysTPUv5e cost of the final 200M TimesFM run — strikingly small for a foundation model
15 / 27 / 42Chronos Benchmark I (in-domain), Benchmark II (zero-shot), and the total dataset count
2nd – 4thChronos's zero-shot ranking on Benchmark II probabilistic forecasting. Not first
1000 stepsFine-tuning that moved Chronos-T5 (Small) to first place overall on Benchmark II
27B / 9 domainsMoirai's LOTSA corpus — the largest open pretraining archive in the family

Build it yourself — the weekend recipe

StepWhat to doThe decision that matters
1. DataGrab the Monash archive from Hugging Face, or M4. Filter series with missing values, as TimesFM didHold out entire datasets, not windows, or your "zero-shot" number is meaningless
2. ScaleMean scaling or RevIN, per context window, statistics stashed for the inverseChapter 4: does your domain have meaningful zeros? If yes, do not centre
3. Patchtensor.unfold(-1, P, S), with S copies of the last value padded onOverlap for supervised forecasting; disjoint if you will ever mask
4. EmbedOne nn.Linear(P, D), plus a learned positional tableThat is the entire tokenizer. Resist the urge to make it deep
5. BackboneA vanilla Transformer. BatchNorm, not LayerNormCausal if you want any-horizon forecasting; bidirectional if you want embeddings
6. HeadOutput patch h > p if causal; flatten-and-project if notChapter 3: if the head is bigger than the backbone, rethink the objective
7. MaskSample r ~ U{0, p−1} and mask the first r points of the first patchTwo lines. Without it your model only works at multiples of p
8. LossMSE for point forecasts; pinball at 9 levels for intervals; cross-entropy if you quantizedLog the objective and MASE separately — they diverge, and the gap is diagnostic
9. BaselinesSeasonal naive, naive, ETS, and linear interpolation for imputationChapter 7: a 385M model lost to a straight line. Always run the trivial baseline
10. ReportZero-shot and fine-tuned, with the pretraining corpus listedChapter 6: a claim without a corpus list is not auditable

Where to go from here

If you want…Go to
The classical forecasting machinery these models are measured againstTime-series forecasting and stationary signals
The Transformer itself, from zeroTransformer, attention, and the original Attention Is All You Need
Patching as tokenization in the modality that invented itVision Transformer — 16×16 pixel patches, the direct ancestor of P = 16
Masked reconstruction done properlyBERT, Audio-MAE, VideoMAE V2 — the same mask-span argument in three modalities
Quantizing a continuous signal into a vocabularyVAE and VQ-VAE, neural audio codecs, EnCodec, and quantization noise
How tokenizers get designed in languageTokenization and CS224N tokenization
Gaussian processes, the generator behind KernelSynthGaussian processes
Using the embeddings for search and retrievalVector embeddings, similarity metrics, vector databases
The state-estimation view of the same problemKalman filter and state-space models
Sequence models that are not TransformersSSMs and Mamba, RNN sequences
Sampling multiple paths to get a distributionSequential Monte Carlo

References

  1. Nie, Y., Nguyen, N. H., Sinthong, P., Kalagnanam, J. "A Time Series is Worth 64 Words: Long-term Forecasting with Transformers," ICLR 2023 — arXiv:2211.14730. Patching, channel independence, and the masked-patch pretraining that everything after it uses.
  2. Das, A., Kong, W., Sen, R., Zhou, Y. "A decoder-only foundation model for time-series forecasting," 2023 — arXiv:2310.10688. TimesFM: 200M parameters, O(100B) timepoints, the longer output patch and the first-patch masking trick.
  3. Ansari, A. F., Stella, L., Türkmen, C. et al. "Chronos: Learning the Language of Time Series," 2024 — arXiv:2403.07815. Mean scaling plus uniform binning, an unmodified T5, TSMixup and KernelSynth, and a candid limitations section.
  4. Goswami, M., Szafer, K., Choudhry, A. et al. "MOMENT: A Family of Open Time-series Foundation Models," ICML 2024 — arXiv:2402.03885. The Time Series Pile, masked pretraining for general-purpose analysis, and the imputation result that linear interpolation wins.
  5. Woo, G., Liu, C., Kumar, A., Xiong, C., Savarese, S., Sahoo, D. "Unified Training of Universal Time Series Forecasting Transformers" (Moirai), ICML 2024 — arXiv:2402.02592. LOTSA, multi patch-size projections, and Any-variate Attention — the only serious attempt here at the channel problem.
  6. Kim, T. et al. "Reversible Instance Normalization for Accurate Time-Series Forecasting against Distribution Shift," ICLR 2022. RevIN, the normalisation layer three of the five models use.
  7. Zerveas, G. et al. "A Transformer-based Framework for Multivariate Time Series Representation Learning," KDD 2021. The pointwise masked design PatchTST argues against, and the source of the BatchNorm-over-LayerNorm finding.
  8. Zeng, A. et al. "Are Transformers Effective for Time Series Forecasting?" (DLinear), 2022. The linear baseline that forced this whole line of work to justify itself. Still the first thing to run.
  9. Godahewa, R. et al. "Monash Time Series Forecasting Archive," NeurIPS 2021 Datasets and Benchmarks. The 30-dataset archive TimesFM tops zero-shot.
  10. Gruver, N. et al. "Large Language Models Are Zero-Shot Time Series Forecasters" (LLMTime), NeurIPS 2023. The prompt-an-LLM alternative that TimesFM beats by more than 25% on Monash at a tiny fraction of the cost.
  11. He, K. et al. "Masked Autoencoders Are Scalable Vision Learners," CVPR 2022. Where the "mask must exceed the correlation length" argument was made most sharply.
Cross-domain bridge
Chronos is a codec, and forecasting is decoding
A neural audio codec takes a waveform, cuts it into frames, and replaces each frame with an index into a learned codebook — producing a discrete sequence that a language model can generate. Chronos does the same thing with a cruder codebook: the frame is one sample, and the codebook is 4094 uniformly spaced scalars. Once the signal is a sequence of integers, forecasting and generation are the same operation. That is why Chronos gets a predictive distribution for free, why beam search and nucleus sampling are listed as future work in a forecasting paper, and why the authors can write that "developments in the NLP community [are] immediately transferable." It also tells you where the next improvement comes from: audio moved from scalar quantization to residual vector quantization over frames, which is Chapter 8's empty cell. Follow the machinery in neural audio codecs and EnCodec, and the analogy will keep paying.
"What I cannot create, I do not understand."
A patch is tensor.unfold. A tokenizer is one nn.Linear. A quantizer is a divide and a round. Every mechanism in this lesson fits in fifty lines, and the models that used them are downloadable. The only thing between you and a working time-series foundation model is a corpus and a weekend.
Exit gate — teach it back before you leave.

Without scrolling up: (1) derive N for L = 512, P = 16, S = 8 and explain both contributions to the "+ 2"; (2) mean-scale the vector [10, 12, 8, 14, 11, 15, 9, 13] and quantize the first entry to a token id, showing every step; (3) state the two ways Chronos's tokenizer breaks and give the arithmetic for each; (4) explain why TimesFM's output patch is longer than its input patch, and what bounds it above; (5) explain why masking whole patches rather than points is the difference between a representation and an interpolator; (6) give a MASE denominator from an 8-point history and say why MASE = 0.95 is bad news on seasonal data. If any of the six stalls, its chapter is one tap away.

Which sentence best captures what changed when time series got foundation models?