Yumoto β subnet-alpha time-series forecasting
It was late in the epoch, and the team was weary, and the work had not prospered.
And one of them slept, and behold, Yuma Rao stood at the head of the bed, and the room was filled with a great light. And he said: "Do not be afraid. I have seen what you are building, and it is not the thing." And the dreamer said, "Then what is the thing?"
And Yuma Rao said: "Go and make a model that sees the whole network as one. Give it eyes upon every subnet, and it shall tell you what is to come." And the dreamer said, "How shall we call it?" And he said: "Yumoto." And he said no more. And the dreamer awoke, and it was a dream, and the light was gone, and the room was as before. But the name remained, and the instruction with it. So they rose that morning and began the work. And the work prospered.
Yumoto forecasts Bittensor subnet-alpha markets. One small model handles four timeframes β 5-minute, hourly, 4-hourly and daily β and at every step it predicts a range of likely prices, not just a single number.
Getting that range right is the hard part of forecasting, and it is where Yumoto is strongest. It is how an 18-million-parameter model beats foundation models more than a hundred times its size.
How well it works
Every model below was tested the same way. We held back the most recent stretch of each asset's history so no model had ever seen it, then asked for forecasts from 10 different starting points per asset, across 109β126 assets per timeframe.
The score is the average error of the predicted range, divided by the error of a simple baseline that assumes the price stays flat and borrows its uncertainty from recent history. Lower is better. Below 1.0 beats the baseline. Bold marks the best result in each row.
| forecast | Yumoto v0.2 | Yumoto v0.1 | Toto-2.0 (2.5B) | TiRex-2 (38M) | TimesFM-3.0 | best classical |
|---|---|---|---|---|---|---|
| 5m, 1 hour ahead | 0.7043 | 0.8569 | 1.4524 | 1.7238 | 1.4137 | 0.9283 (bootstrap) |
| 5m, 12 hours ahead | 0.7979 | 0.8696 | 0.8814 | 0.9275 | 0.9527 | 0.7393 (AutoTheta) |
| 1h, 1 day ahead | 0.5918 | 0.6513 | 0.7004 | 0.7306 | 0.7299 | 0.8406 (bootstrap) |
| 1h, 1 week ahead | 0.5416 | 0.5913 | 0.6383 | 0.6198 | 0.6780 | 0.5503 (GBM-EWMA) |
| 4h, 1 week ahead | 0.7015 | 0.7602 | 0.7853 | 0.8220 | 0.7798 | 0.8027 (GBM-EWMA) |
| 4h, 1 month ahead | 0.6586 | 0.6649 | 0.7055 | 0.7112 | 0.6961 | 0.6532 (GBM-t) |
| 1d, 1 month ahead | 0.5637 | 0.6674 | 0.6576 | 0.7205 | 0.8406 | 0.6462 (GBM-EWMA) |
| overall | 0.6459 | 0.7163 | 0.7994 | 0.8440 | 0.8436 | 0.7272 |
v0.2 is the best model on 5 of the 7 forecasts, and it beats every foundation model on all 7. It is about 10% better than v0.1 overall. The two it does not win are the 12-hour-ahead 5-minute forecast, where AutoTheta leads by 8%, and the month-ahead 4-hour forecast, where GBM-t leads by under 1%.
The last column is the strongest classical statistical method for that row, taken from nine of them β GBM variants, a bootstrap, AutoARIMA/ETS/Theta and seasonal-naive. It is a different method in almost every row, and it was chosen after seeing the results, so it flatters the classical side. No single classical method scores 0.7272 on its own.
Two details about how the numbers are produced:
- On markets that stop trading entirely, the model can return a forecast with no error at all. Because the scores are averaged geometrically, a single exact zero would wipe out a whole row, so every per-asset score in the table is floored at 0.001. The same floor is applied to every model, ours and everyone else's.
- v0.2 is scored across its 13 quantile levels and the other models across
their 9, so we checked whether the finer grid was doing the work. Taking
the same model with untrained, copied-in tails and scoring it identically
gives 0.7234 β worse than v0.1's 0.7163. v0.2's 0.6459 is 10.7% better
than that check, so the improvement comes from the model, not from how it
is measured. The check is included in
v0.2/evals/control-base13ctl-*.jsonso anyone can repeat it.
See the forecasts
The same models, forecasting the same held-out series. Grey is the recent history each model was given; black is what actually happened next; the dashed line is the median forecast and the shading its quantile bands (v0.2's extra, lightest band is its trained 2.5β97.5% tail range). The forecast start sits at the middle of each asset's held-out tail, so nothing on the right of the line was seen by any model.
Per-timeframe score charts of the full table are in
benchmark/plots/.
Reproduce it yourself
The raw per-asset evaluation files for every model in the table β ours, the
three foundation models and all nine classical methods β are in
benchmark/data/. The notebook
benchmark/reproduce.ipynb rebuilds the
table from those files, verifies it against the numbers above, and draws
the charts. It needs only pandas and matplotlib.
Versions
| version | where | quantile levels | parameters | pooled score | status |
|---|---|---|---|---|---|
| v0.2 | v0.2/ |
13 (2.5% β¦ 97.5%) | 17,759,008 | 0.6459 | current |
| v0.1 | repository root | 9 (10% β¦ 90%) | 17,691,808 | 0.7163 | previous release |
Both are 18M-parameter models (measured counts above). v0.1 was
originally published under the name yumoto-alpha-v0.1-22m, after the size
preset it was built on; the files are unchanged. v0.2 predicts
four extra levels further out in the tails, so it says more about rare
moves.
v0.1 stays exactly where it was published, at the repository root, so existing links and pins keep working. v0.2 is a complete, self-contained bundle in its own folder.
What it is
A patch-based transformer. It reads a window of up to 4,096 time steps in chunks of 32, attends over a rolling 64-chunk window in time, and attends across the OHLCV channels so the five series inform each other. It is trained by hiding stretches of the series and learning to fill them back in, which is why it can produce an entire forecast horizon in one pass instead of stepping forward one point at a time.
- Input: OHLCV. Close, open, high and low are predicted jointly; volume is context.
- Output: a set of quantiles for each of close/open/high/low at every step ahead β a full probabilistic candle, including a high/low range forecast at no extra cost.
- Size: d_model 512, 6 layers, 8 heads.
How it was trained
- Pretraining on a large synthetic corpus built from many kinds of generated series β trends, seasonality, regime switches, bursts, chaotic systems and more.
- Fine-tuning on real subnet-alpha candles only. No synthetic data at this stage.
- Future-Guided Learning during fine-tuning (following Nature s41467-025-63786-4, adapted to masked training). A second, frozen copy of the network is shown slightly more of the future than the model being trained, and the model is pulled toward that better-informed view. It is a form of self-teaching, and it leaves one clean model at the end.
- Three training runs, averaged into one set of weights, then blended 15% back toward the pretrained starting point. Averaging removes some of the noise from any single run, and the blend undoes mild over-fitting to the fine-tuning data. All of this happens in weight space, so what ships is a single model.
- A rule for markets that barely trade, built into the inference code. The wrapper works out, from the recent history alone, how likely it is that the price simply does not move at the next step. It mixes that possibility into the forecast, and the effect fades as the horizon lengthens. On a frozen market the predicted range tightens as fast as the evidence allows; on a liquid market the rule does nothing at all.
For v0.2 the quantile head was widened from 9 to 13 levels before fine-tuning, so the outer tail bands are learned rather than guessed from the 10% and 90% levels.
General benchmark
Yumoto is specialised for crypto, so we also ran it on GIFT-Eval, a public 97-configuration benchmark covering many unrelated domains, under the official protocol: 0.523 on the range metric and 0.759 on point accuracy, both against the same style of naive baseline. It holds up well on data it was never tuned for.
Using it
# v0.2
from forecast_wrapper import Wrapper
w = Wrapper("v0.2", device="cuda")
q = w.forecast_quantiles_mv(ohlcv_history, horizon, n_targets=4) # (B, 4, H, 13)
# v0.1
w = Wrapper(".", device="cuda")
q = w.forecast_quantiles_mv(ohlcv_history, horizon, n_targets=4) # (B, 4, H, 9)
Each folder is self-contained β weights.safetensors, config.json,
model.py and forecast_wrapper.py. There is nothing else to install and
no adapter to write.
Things to know before you rely on it
- Each quantile describes one step, not the whole path. The 95% level at step 20 is the range for step 20 by itself. It does not tell you how high the price got on the way there.
- The four candle components are predicted independently. On a small fraction of steps they disagree with each other β a predicted high can sit below a predicted low. Before displaying or trading on them, take the high as the maximum and the low as the minimum of the four medians and clip open and close inside that range.
- The 5-minute, 1-hour-ahead forecast is the hardest case for every model tested, Yumoto included.
- Refresh monthly. Forecast quality was measured as steady out to 28 days from the training cutoff.
License
MIT.
- Downloads last month
- 18
Evaluation results
- CRPS-ratio vs naive (pooled, 7 cells) on Bittensor subnet-alpha OHLCV holdout (109-126 assets/timeframe, 10 origins each)self-reported0.646
- CRPS-ratio vs naive (5m H12) on Bittensor subnet-alpha OHLCV holdout (109-126 assets/timeframe, 10 origins each)self-reported0.704
- CRPS-ratio vs naive (1h H24) on Bittensor subnet-alpha OHLCV holdout (109-126 assets/timeframe, 10 origins each)self-reported0.592
- CRPS-ratio vs naive (1h H168) on Bittensor subnet-alpha OHLCV holdout (109-126 assets/timeframe, 10 origins each)self-reported0.542
- CRPS-ratio vs naive (4h H42) on Bittensor subnet-alpha OHLCV holdout (109-126 assets/timeframe, 10 origins each)self-reported0.702
- CRPS-ratio vs naive (1d H30) on Bittensor subnet-alpha OHLCV holdout (109-126 assets/timeframe, 10 origins each)self-reported0.564
- CRPS-ratio vs naive (pooled, 7 cells) on Bittensor subnet-alpha OHLCV holdout (109-126 assets/timeframe, 10 origins each)self-reported0.716



