← Writing

Engineering · September 2, 2026 · 4 min

A foundation model in your browser

What if you could run our 102-million-parameter forecasting foundation model, t0-alpha, in your browser?

At The Forecasting Company, we enjoy exploring how the same model can work across very different use cases and deployment settings. Need low-latency access in production? There is our descriptive API, which forecasts and reshapes your data for you. Want to explore backtests across a hierarchy of your data in a visual interface? Say hello to Retrocast™. Prefer working through an agent? There is an MCP for that. And if you would rather self-host and experiment with the model, we have an open-weights version on Hugging Face.

But what if you want a useful model inside the browser itself, for local and edge applications? We wanted to see what it would take to move t0-alpha all the way into a browser tab.

The result is a quantized 8-bit version of the model, built with ONNX and run by ONNX Runtime Web through WebAssembly. (We like WebAssembly, and I personally enjoy buying domain names, so you can also find this WASM-ready model at wasmgonnahappen.com.) Forecasting can now happen in a pure front-end application: static assets and a model running in the tab, with no inference backend in the interaction path.

To show what that makes possible, we built Finish This Chart, a small forecasting game that asks: can you outforecast a machine? In Freestyle mode, you can draw an entirely new time series and let t0-alpha continue it. Your drawing becomes the model’s context and its forecast appears immediately beside it.

Finish This Chart: human intuition versus machine prediction

Finish This Chart runs t0-alpha locally in the browser. In Freestyle mode, the line you draw becomes the model’s context.

We could have built the same interaction against our API. Running it locally was a deliberate technical constraint: we do not operate GPU inference for each play, and the data used for a forecast stays in the tab. It also gave us a fun reason to find out how portable an ONNX build of the model could be.

A portable graph

The ONNX build is designed to be small enough for a browser without hard-coding the game itself into the model. It accepts multiple targets, arbitrary context lengths, different forecast horizons, and known-future covariates:

target_context              float32 [target_rows, context]
target_group_ids            int32   [target_rows]
future_covariate_context    float32 [covariate_rows, context]
future_covariate_future     float32 [covariate_rows, compute_horizon]
future_covariate_group_ids  int32   [covariate_rows]
quantiles                   float32 [target_rows, compute_horizon, 5]

The width of future_covariate_future selects how much of the forecast the graph computes. t0-alpha forecasts in 32-step patches, so callers round the desired horizon up to a multiple of 32 and slice the returned forecast back to the requested length. Padding for arbitrary context lengths happens inside the graph, while group IDs retain joint attention across related rows. The full calling contract is documented on Hugging Face.

We tested context lengths from 1 to 4096, horizons from 32 to 1024, and up to 64 target rows and 64 covariate rows. At the game’s workload, warm one-thread WASM inference takes roughly 38 ms on our test machine. The graph does not include autoregressive rollout beyond 1024 steps, but its dynamic interface makes it useful for browser applications beyond the game.

Getting t0-alpha through ONNX

During prediction, t0-alpha does more than call a transformer: it creates time-series structures, represents missing values, computes causal scaling statistics, builds attention masks, rescales the output and selects forecast patches. Some of our model code contains Python control flow that is reasonable in PyTorch but difficult for an ONNX exporter to capture as a tensor graph.

Most of the necessary changes were small but specific. We rewrote the causal scaling calculation as branch-free cumulative tensor operations, expressed attention-mask construction with boolean operators supported by ONNX Runtime’s CPU and WASM backends, and removed tensor-valued Python branches. An independent Apache-2.0 ONNX export by Siddharth7113 was a useful reference for these changes.

These rewrites are guarded by numerical checks. Across contexts from 1 to 4096 steps and compute horizons from 32 to 1024, the FP32 ONNX graph matched the PyTorch model.predict() output within 2e-4 maximum absolute error.

Quantization and validation

For edge deployments, and especially for models downloaded into a browser, size matters. So we experimented with quantizing t0-alpha. The portable FP32 graph is 411.0 MB; dynamic, per-channel signed INT8 weight quantization reduces it to 107.3 MB. That is still a meaningful first download, so Finish This Chart loads the model only when the first forecast is submitted and stores it with the browser Cache API.

Across our validation matrix, mean absolute INT8 drift was typically 0.5–1.3% of the PyTorch forecast spread, reaching roughly 2–3% for the longest contexts. We also tested INT4. A weight-only block-16 graph reached 84.0 MB with good numerical parity, but was roughly six times slower in our one-thread ONNX Runtime Web harness. The smaller file was not worth the slower interaction, so the public build uses INT8.

Running in the tab

With the graph settled, the browser integration is fairly small. The page pins a specific model revision, validates its manifest, loads ONNX Runtime Web and creates a single-threaded WASM session. The history is passed in as a float32 tensor; the returned quantiles are drawn directly into the chart.

So that’s it. We think it’s pretty cool that a forecasting foundation model can live inside a pure front-end app! We’d love to see what other people do with the quantized model, especially for local and edge use cases—please share what you build with us.

Have a go at Finish(ing) This Chart, or download the portable ONNX model on Hugging Face. Finally, the ONNX build is a size-optimized derivative; if you need the full thing, check out t0-alpha.