Safe By Design AI

PatchTSMixerForPrediction

PatchTSMixerForPrediction at 2 layers and hidden size 48. One published checkpoint has this shape.

Implementing it

One forward, written out, per checkpoint whose arithmetic actually differs. A shape groups checkpoints by class, depth, width and layer stack — none of which decides an activation, a rope base or a routing rule — so where the members of this shape disagree there is a block each, and each names the checkpoint it was generated from.

No forward was recorded for this shape, so there is no pass above to compare it against — this block is what the published configuration says the arithmetic is, not a transcript of a run. Where the configuration does not say, the line says that instead of guessing.

The names are the ones the published checkpoint uses where a name is published, and canonical otherwise. A checkpoint loader may store them differently — fusing a gate/up pair into one matrix, or splitting one published projection in two — and those are that loader's names, not the model's. Everything spelled here is what the download contains.

Generated from granite-timeseries-patchtsmixer.

# The backbone and a head — the smallest forecaster here, and the model
# TinyTimeMixer derives from. No attention anywhere.

x = last 512 samples, front-padded if short
obs = observed_mask(x)                    # the pad is not an observation
z = StdScaler(x, over observed values only)
p = patch(z, length=16)                # 32 patches
h = p @ W_emb.T                           # -> 48

for i in 0 .. 1:
    # A mixer layer is two mixes, each:
    #   LayerNorm -> MLP(x3, exact GELU) -> softmax gate -> +residual
    # The gate is `y * softmax(Wy + b)` and it is the library default
    # `gate_mode`. Dropping it leaves a model that forecasts.
    h = mix(h, across=patches)        # MLP over the patch axis
    h = mix(h, across=features)       # MLP over the feature axis

y = flatten(h)                             # [32 x 48]
forecast = (y @ W_head.T) * scale + loc   # [96 samples]

The scaler reads observed values only. A short series is front-padded with zeros and the pad is not an observation — folding it into the mean drags the whole forecast toward zero.

Each mix ends in a softmax gate, y * softmax(Wy + b), which is the library's default gate_mode. It carries weights, so a port that omits it fails to load rather than running — unless the loader silently defaults, which is why the author's implementation does not.

What TinyTimeMixer adds and this does not have: adaptive patching, an adapter projection, and a decoder stack. This is the backbone and a head.

The reversible normalization is load-bearing: the statistics come from the input window and are re-applied to the output, so a series is forecast in its own units without the model ever seeing them.

Geometry

layers2
hidden size48
context window512 samples
forecast horizon96 samples
patch length16 samples
patch stride16 samples
patches32
feed-forward expansion3
input channels7
largest checkpoint196.1K

How this was checked

implemented, evidence grade class, per the assessment: the architecture class is implemented; nothing specific to this checkpoint was measured. The implementation meant here and below is an unpublished independent inference implementation by the author.

What stands behind the block above, beyond the published configuration it is read from:

Where an independent implementation and the published configuration disagree, the configuration is what this page reports and the disagreement is what it says.

Checkpoints with this architecture

modelparameterscontext
granite-timeseries-patchtsmixer196.1K