cascade logo

# cascade: SOTA time-series foundation models on Bittensor cascade builds time-series foundation models on Bittensor by competing on **data**. The model is fixed and byte-identical for everyone; miners write the synthetic data generators that train it. Better data trains a better forecaster, and that is measured every round on private real-world windows. - Miners: [docs/MINER.md](docs/MINER.md) (five-command version: [docs/MINER_FUNDED_QUICKSTART.md](docs/MINER_FUNDED_QUICKSTART.md)) - Validators: [docs/VALIDATOR.md](docs/VALIDATOR.md) - Design: [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md), decisions in `decisions/` ## Why compete on data Recent time-series models win benchmarks through better synthetic priors, not better architectures. Chronos-2 (Amazon) trains heavily on synthetic series and its purely-synthetic ablation stays within a point of the full model on GIFT-Eval ([arXiv 2510.15821](https://arxiv.org/abs/2510.15821)). FlowState (IBM, 9.1M) out-forecasts rivals 20× its size after pretraining on CauKer synthetic data ([arXiv 2508.05287](https://arxiv.org/abs/2508.05287)). ForecastPFN and TempoPFN were trained on synthetic distributions only. DynaMix beats Chronos zero-shot on real traffic and weather data with ~10k parameters trained on 34 synthetic chaotic systems ([arXiv 2505.13192](https://arxiv.org/abs/2505.13192)). Toto 2.0 itself was pretrained on 57.5% synthetic data. The synthetic distribution does the heavy lifting. cascade makes that distribution the competition. ## How it works ### The fixed model A Toto2-4M backbone ([Datadog/Toto-2.0-4m](https://huggingface.co/Datadog/Toto-2.0-4m)) trained inside the subnet, never a fine-tune of released weights. Rounds train from a shared init: random at generation 0, and since promotions started firing, the promoted checkpoint of the previous generation (see [the cascade](#the-cascade-promoted-generations)). Every learned parameter was produced by the competition, so the corpus is the only source of signal. Toto 2.0 is the first time-series family with a clean scaling law across sizes (4M → 2.5B) under u-μP, so hyperparameters tuned at 4M transfer up the ladder. The 4M rung trains from scratch in hours and sits on a curve known to behave; the 22M rung is a built, dormant seam in `chain.toml`. ### A round Rounds run every 12 h (`[round] epoch_blocks = 3600`, boundaries ≈ 08:30 and 20:30 UTC). 1. **Field.** Commitments revealed before the boundary, funded by their miner (the miner's own Lium key pays for the training pod), seat in reveal order up to the round's cap. Everyone seated duels the king; there is no heat screen. An unfunded boundary runs nothing. 2. **Training.** King and every challenger train the full budget (~5 h, enforced as a fixed token count) on the same GPU type, from the same init, with the same seeds. The only difference between runs is the generator. 3. **Manifest.** The operator signs a manifest of checkpoints and digests to Hippius S3 (mirrored to R2 and a HuggingFace dataset as fallbacks). 4. **Verdict.** Validators verify the manifest's signature and contract digests, score king and challengers on the same private windows (geomean of CRPS and MASE on a 64 / 256 / 720-step horizon ladder), and decide the throne with a paired bootstrap. 5. **Bench.** Each checkpoint is benched on GIFT-Eval / BOOM / TIME. These numbers are public telemetry and feed promotion, never the verdict. **Rolling intake (next).** The boundary round gives way to rolling intake (DEC-CA-0043): a funded leg trains the moment it is funded, every 3 h boundary *settles* whatever finished against a king trained once per 12 h era, and the GPU type is chosen per leg under price caps. The switch is decided on chain rather than typed in (DEC-CA-0045): validators on the release post a readiness note, and the first boundary where 51 % of validator stake has signed locks in the switch for the boundary after it. `docs/MINER.md` §6 has the miner view, `docs/VALIDATOR.md` the validator side, `docs/MINER_FUNDED_ROUNDS.md` the operator sequence. ```mermaid flowchart LR miner["miner: generator
cascade submit / deploy + fund"] -->|on-chain pointer + Lium key| trainer trainer["trainer (owner)
king + challengers, same init, same GPU type"] -->|signed manifest + checkpoints| validator validator["validators
private windows → paired bootstrap → weights"] ``` ### The throne A challenger takes the throne when the paired-bootstrap lower confidence bound of its advantage clears the round's margin: 1% against a fresh king, decaying to a 0.5% floor over 8 held rounds. With several challengers a cohort-wide max-T correction keeps the king's false-dethrone risk fixed. From block 9046800 the margin is priced against the per-round improvement over the shared init, so a mature lineage stays dethronable. Weights follow geometric decay across the lineage: the king plus up to 4 prior kings share ∝ `0.5**i` (≈ 52 / 26 / 13 / 6 / 3 %). Unregistered share burns. ### Private code, public kings Miners can submit code privately (`cascade submit`): it lives in the operator's vault and trains on the miner's own pod. Only a king is published, the moment it is crowned (`champion_publish = "crown"`), to `champions/` on the manifest bucket; `cascade fetch king` resolves it. Losers stay private. ### Multivariate data Generators may yield `(C, L)` series with up to 32 coupled channels. A channel costs what it trains, step count is independent of width, and from block 9068400 multivariate eval windows are scored jointly. ## The cascade: promoted generations When a king holds 5 consecutive rounds (`cascade_reign_rounds`), up to 3 (`cascade_top_k`) of the reign's best duel checkpoints, king's or challengers', are promoted as the next warm-start generation. Members are picked by the geometric mean of six signed benchmark numbers (GIFT-Eval / BOOM / TIME × CRPS / MASE), within 5% of the reign's best, for error diversity. Later rounds rotate through them. A promotion never ratchets downhill, the king persists (only the reign clock resets), and each promotion is a signed public record under `promotions/`. Generations have been promoted on mainnet; warm-started rounds are the live case. ## Roadmap - **Phase 1, now: compete on data.** Model fixed, data is the variable. - **Phase 2: prove it scales.** Show the data advantage survives model size using the u-μP ladder (the `throne_sizes` seam pools verdicts across sizes). - **Phase 3: open model training.** Widen the contract once data quality is a solved, measurable axis. - **North star: multimodal forecasting** across time series, language and vision. ## Repository ``` cascade/ interface/ the DataGenerator contract, output checks, static guard eval/ CRPS (MWSQL), MASE, paired bootstrap, KOTH decision, checkpoint guard trainer/ owner GPU service: corpus, contract, training, manifest, funded legs validator/ manifest gate, evaluator, KOTH state, weights, cascade promotion miner/ miner CLI funding/ intake service, funded queue, payer-key vault provision/ GPU pod rental (Lium), bootstrap, ledger audit/ cascade-audit: re-derive published rounds pool/ private eval-window pool shared/ config, Hippius Hub/S3, chain client, manifest schema website/ the public dashboard (index.html) docs/ MINER.md, MINER_FUNDED_QUICKSTART.md miners INTERFACE.md the submission contract VALIDATOR.md, ARCHITECTURE.md, AUDIT.md, EVAL_POOL.md, DEPLOY_PODS.md MINER_FUNDED_ROUNDS.md operator runbook for funded rounds scripts/example_generator/ a forkable reference generator ``` ## Commands Miner (`cascade`, no GPU): - `verify `: every check the trainer runs, including determinism. - `score --pool-dir `: train at a cheap budget and score locally; `--warm-start live` uses the current round's init. - `submit `: private submission, on-chain commit and funding in one request. - `deploy `: push to a public Hippius Hub repo and commit on-chain; then `fund --ref ` pays for the leg. - `queue`, `round`, `heat`, `duel`, `reveal-status`: the live queue and roster, the round countdown and dethrone bar, who seated, the settled verdict (`duel --hotkey `: which domains you beat the king in and by how much), and whether your reveal landed. - `fetch king | | | `: download a public generator. Operator and validator: - `cascade-trainer`: the training service (`--offline` for a config smoke, `--remote-hosts` for SSH GPU pods). - `cascade-train-worker`: the per-pod worker. - `cascade-intake`: the funding and private-submission intake. - `cascade-validator`: the validator loop. - `cascade-audit latest | round `: re-derive a published round from its public artifacts, nonzero exit on any mismatch. ## Storage and public records Generators and checkpoints live on the Hippius Hub registry (OCI, pinned by `repo@digest`). Manifests, receipts, logs and benchmark reports live on Hippius S3, dual-written to Cloudflare R2, with a HuggingFace dataset as the read fallback for manifests and checkpoints. Credentials are environment only (`HIPPIUS_*`, `HF_TOKEN`), never in files. ``` manifests/round-.json the trainer's signed manifest receipts//round-.json a validator's signed receipt (scores, verdict, weights) receipts/index.json rolling summary the dashboard reads funded/round-.json seat order, GPU capacities, outcomes benchmarks/round-.json signed public benchmark numbers champions/ published kings promotions/ signed warm-start promotions ``` `cascade-audit latest` re-derives a receipt without trusting the operator. The dashboard (`cascade/website/index.html`) reads only these public records. Every throne-holding generator is also archived to a private bucket by `scripts/scrape_kings.py`. ## Quick start (development) ```bash pip install -e '.[dev]' python -m pytest tests/unit -q # CPU only, no torch/chain needed ``` Extras: `.[train]` (torch, the trainer and evaluator), `.[hippius]` (registry and S3), `.[chain]` (bittensor). `chain.toml` ships mainnet values (netuid 91, worker image digest, pool bucket); operator-specific values are set on the deployment box. ## License MIT