Tsinghua University logo

Kronos

Kronosv2025Current
byTsinghua UniversityTsinghua University(enterprise)
Released August 2, 2025
Context--
Training Cutoff2025 financial K-line corpus
CategoryTime Series Foundation Model

About Kronos

Kronos is a foundation model for financial K-line market sequences. It tokenizes continuous market records and uses autoregressive pre-training for forecasting, volatility, and synthetic time-series tasks.

Capabilities

time series forecastingfinancial modelingsynthetic datavolatility prediction

Input Modalities

tabular-time-seriesk-line

Output Modalities

forecastsynthetic-time-series

Technical Details

API Identifier
shiyu-coder/kronos
Category
Time Series Foundation Model

Tags

financial-aitime-seriesfoundation-modelforecastingopen-source

Run this model yourself

Local and cloud setup for Kronos, with exact configurations, sources and clear evidence limits.

Find a model for your hardware
Local hardwareDocumented setupSources checked Oct 16, 2026

Forecast eight synthetic OHLCVA bars with Kronos-mini on a research CPU desktop

Run the native Kronos-mini predictor with its mandatory learned Tokenizer-2k in CPU float32. A private research endpoint accepts one original synthetic fixture: 64 historical OHLCVA bars and eight future bars in an explicitly reduced 128-position window. Each position contains two hierarchical code IDs; eight output positions generate 16 scalar IDs per path and decode to eight six-value rows. These are financial sequence units, not text tokens. Fit, speed and forecast quality are unmeasured.

Hardware
Intel Core i5-12400 desktop, 4 inference threads, 32 GiB RAM
Runtime
Pinned Kronos native CPU paired-code forecasting research harness Pinned upstream; torch 2.6.0+cpu; Python 3.12; numpy 1.26.4; pandas 2.2.2; einops 0.8.1; hub 0.33.1; safetensors 0.6.2; tqdm 4.67.1 · CPU
Model format
safetensors · CPU float32 execution for both predictor and learned tokenizer; on-disk tensor dtype not independently inspected · Unquantized native checkpoint; explicit CPU float32 execution choice
Workload
128 token context · 1 concurrent

Based on source documentation; this setup has not been executed by OpenTools. Memory: unknown. No compatible measurement available.

Read the complete setup guide

Before you start

  • Use an owned Intel Core i5-12400 desktop with Ubuntu 24.04 x86_64, 32 GiB RAM and 40 GiB free disk. Allocate four CPU threads. These are author planning allocations, not measured requirements.
  • Review the pinned upstream MIT notice and both official checkpoint cards; retain notices with copies. No access token is needed for the selected publicly readable snapshots. This guide grants no rights to outside financial datasets.
  • Research-only synthetic OHLCVA fixture; no live market data, uploads, filesystem paths, symbols or trading recommendations. Inspect the generated fixture before interpreting numerical forecasts.
  • Use Python 3.12 and the pinned CPU package choices below. No author installation or model execution occurred; transitive/system packages resolve on installation and must be recorded. Stop on dependency, key, dtype or shape errors.

Exact model and requirements

Artifact:
NeoQuasar (official upstream Kronos model-zoo publisher) / Kronos-mini predictor; mandatory matching Kronos-Tokenizer-2k auxiliary weights · checkpoint NeoQuasar/Kronos-mini
Publisher revision:
f4e68697d9d5aed55cef5c96aabc3376bcad9f81
Artifact digest:
sha256:a7d5f37e2e9fbd9891f7d7d4f72574512dd1f704fee14223e0a8cd0fbf54197c
Download size:
0.02 GiB
Memory requirement (unknown):
Unknown — No measured peak for both networks, CPU tensors, native decoding, dependencies and serialization.
System RAM / disk:
Unknown / Unknown
Placement:
single device. One CPU host; no model sharding. Both networks and all input/output processing remain on CPU; no GPU or disk offload.
KV cache:
Pinned native inference recomputes the paired-code sequence window each step; no autoregressive K/V cache is configured.
Workload:
128 token context; 64 input tokens; 8 output tokens; concurrency 1; batch 1; cache unknown; repetitions Unknown.
Tokenizer:
Native learned Kronos-Tokenizer-2k; two 10-bit scalar code streams per bar position · 26966d0035065a0cae0ebad7af8ece35bc1fb51c
Sampling / reasoning:
Fixed seed 20251016 reset per request; temperature 1.0, top_k 0, top_p 0.9, sample_count 1. Native inference samples coarse then fine IDs for every future bar. Eight forecast positions mean 16 scalar IDs per path, not eight scalar IDs or text tokens. Seed does not guarantee cross-version or cross-hardware identity. No chat, prompt template, language reasoning or tool calling. Context 128, input 64 and output eight denote paired-code autoregressive bar positions. Both streams are embedded into one position. Mini published context is 2048; this author workload is a reduced window, not a new global model maximum. Total 72 positions never reach the rolling-window boundary. half=True in native encoding splits hierarchical codes; execution remains float32.
Runtime prerequisites:
Ubuntu 24.04 x86_64; See prerequisites above.

Official artifact · License

Upstream source MIT license and both official artifact cards declare MIT. Retain the copyright and permission notice in copies or substantial portions; supplied without warranty. This original synthetic fixture has no external market-data dependency. MIT does not grant rights to third-party financial datasets or provide trading, accuracy or legal assurances.

  • Main predictor LFS artifact is 16,440,776 bytes; mandatory learned tokenizer adds 15,842,376 bytes. Their 32,283,152-byte total is serialized weight metadata, not peak process memory. No weight body downloaded or independently hashed by author.
  • Four CPU threads, 32 GiB RAM and 40 GiB disk are author allocations. Required CPU memory, fit and performance remain unknown.

One-time setup and hardware

hardware
Unknown — Existing desktop purchase price and incremental hardware cost depend on the reader; unknown.
Existing desktop purchase price and incremental hardware cost depend on the reader; unknown. Tax: unknown.
setup
Unknown — Initial provisioning/build time and labor cost are unknown.
Initial provisioning/build time and labor cost are unknown. Tax: unknown.

Recurring costs

electricity
Unknown — Actual wall power, electricity rate and powered hours are unknown; no TDP-to-wall-power conversion.
Actual wall power, electricity rate and powered hours are unknown; no TDP-to-wall-power conversion. Tax: unknown.
storage
Unknown — Incremental cost of local disk capacity is unknown. The 40 GiB free-disk walkthrough allocation is an author choice, not a measured requirement.
Incremental cost of local disk capacity is unknown. The 40 GiB free-disk walkthrough allocation is an author choice, not a measured requirement. Tax: unknown.
egress
Unknown — Data transfer price, allowances and traffic volume are unknown.
Data transfer price, allowances and traffic volume are unknown. Tax: unknown.
administration
Unknown — Maintenance labor rate and hours are unknown.
Maintenance labor rate and hours are unknown. Tax: unknown.

Install the runtime

  1. 1. Create the pinned native CPU research environment

    Use a dedicated directory, the official hashed CPU wheel and the exact upstream commit. The selected direct dependency versions are source-qualified author choices; no CUDA driver or Transformers runtime is needed. Record resolved transitive and system versions.

    Command
    sudo apt-get update
    sudo apt-get install -y python3.12 python3.12-venv git curl ca-certificates openssl
    mkdir -p "$HOME/kronos-mini-forecast/checkpoints/model" "$HOME/kronos-mini-forecast/checkpoints/tokenizer"
    cd "$HOME/kronos-mini-forecast"
    python3.12 -m venv .venv
    .venv/bin/python -m pip install 'https://download.pytorch.org/whl/cpu/torch-2.6.0%2Bcpu-cp312-cp312-linux_x86_64.whl#sha256=59e78aa0c690f70734e42670036d6b541930b8eabbaa18d94e090abf14cc4d91'
    .venv/bin/python -m pip install 'numpy==1.26.4' 'pandas==2.2.2' 'einops==0.8.1' 'huggingface_hub==0.33.1' 'safetensors==0.6.2' 'tqdm==4.67.1'
    .venv/bin/python -m pip check
    .venv/bin/python -m pip freeze > resolved-environment.txt
    git clone https://github.com/shiyu-coder/Kronos.git runtime
    git -C runtime checkout --detach 67b630e67f6a18c9e9be918d9b4337c960db1e9a
    test "$(git -C runtime rev-parse HEAD)" = '67b630e67f6a18c9e9be918d9b4337c960db1e9a'

    Expected result: pip check succeeds, environment is recorded, and the runtime checkout matches the pinned commit. This has not been installed by the author.

Download the model

  1. 1. Retrieve both exact native checkpoints and notice

    Read the MIT notice first. Download the mini predictor and its mandatory matching Tokenizer-2k, not the base tokenizer. Verify all five file hashes. Weight hashes and sizes are official LFS metadata; author did not retrieve weights.

    Command
    cd "$HOME/kronos-mini-forecast"
    curl --fail --location --output checkpoints/model/model.safetensors 'https://huggingface.co/NeoQuasar/Kronos-mini/resolve/f4e68697d9d5aed55cef5c96aabc3376bcad9f81/model.safetensors'
    curl --fail --location --output checkpoints/model/config.json 'https://huggingface.co/NeoQuasar/Kronos-mini/resolve/f4e68697d9d5aed55cef5c96aabc3376bcad9f81/config.json'
    curl --fail --location --output checkpoints/tokenizer/model.safetensors 'https://huggingface.co/NeoQuasar/Kronos-Tokenizer-2k/resolve/26966d0035065a0cae0ebad7af8ece35bc1fb51c/model.safetensors'
    curl --fail --location --output checkpoints/tokenizer/config.json 'https://huggingface.co/NeoQuasar/Kronos-Tokenizer-2k/resolve/26966d0035065a0cae0ebad7af8ece35bc1fb51c/config.json'
    curl --fail --location --output KRONOS-LICENSE 'https://raw.githubusercontent.com/shiyu-coder/Kronos/67b630e67f6a18c9e9be918d9b4337c960db1e9a/LICENSE'
    sha256sum --check <<'SHA256'
    a7d5f37e2e9fbd9891f7d7d4f72574512dd1f704fee14223e0a8cd0fbf54197c  checkpoints/model/model.safetensors
    70daca2cb11e3a979dd6b8ac12ee08e2aace877acf28f5b8dfb4fe5609736201  checkpoints/model/config.json
    b97ec46b3b72160509e289183eaf7bdf5f0dac5bb9b49522f6d46638a99a8717  checkpoints/tokenizer/model.safetensors
    0b30a443affb03e05a876a083857de9164f899feb7b4d261da02c485c9a3e3b6  checkpoints/tokenizer/config.json
    acb2d194d378204e5f2be4dcd24d39ecac437903620c790c3315a96dab388fdc  KRONOS-LICENSE
    SHA256

    Expected result: Both checkpoint directories contain verified configs and native safetensors; exact MIT notice retained.

Configure

  1. 1. Write the bounded private research wrapper

    This reader-authored wrapper is not publisher serving code. Native checkpoint loading is strict; both networks are explicitly CPU float32 in evaluation mode. Only a fixed synthetic fixture is accepted. Body framing and JSON errors are rejected before inference. This serial research server has a socket read timeout, no TLS, no inference deadline and no public-service hardening.

    Command
    cd "$HOME/kronos-mini-forecast"
    cat > reader-forecast-server.py <<'PYWRAPPER'
    """Reader-authored fixed synthetic Kronos research endpoint; not publisher serving code."""
    import datetime as dt
    import hmac
    import json
    import math
    import os
    from http.server import BaseHTTPRequestHandler, HTTPServer
    from pathlib import Path
    
    ROOT = Path(__file__).resolve().parent
    COLUMNS = ['open', 'high', 'low', 'close', 'volume', 'amount']
    SEED = 20251016
    
    def fixture():
        start = dt.datetime(2025, 1, 2, 9, 30)
        times = [(start + dt.timedelta(minutes=5*i)).isoformat() for i in range(72)]
        rows = [[100+i, 102+i, 99+i, 101+i, 1000+10*i, (1000+10*i)*(201+2*i)/2] for i in range(64)]
        return dict(columns=COLUMNS, history=rows, history_timestamps=times[:64], future_timestamps=times[64:])
    
    def result(values):
        if not isinstance(values, list) or len(values) != 8:
            raise ValueError('forecast shape')
        for row in values:
            if not isinstance(row, list) or len(row) != 6:
                raise ValueError('forecast shape')
            if any(isinstance(v, bool) or not isinstance(v, (float, int)) or not math.isfinite(v) for v in row):
                raise ValueError('nonfinite forecast')
        return dict(fixture='synthetic-ohlcva-v1', columns=COLUMNS,
                    timestamps=fixture()['future_timestamps'], forecast=values,
                    history_positions=64, forecast_positions=8, context_positions=128,
                    scalar_codes_per_position=2, generated_scalar_ids_per_path=16,
                    sample_count=1, seed=SEED, generated_text_tokens=None)
    
    def object_pairs(pairs):
        out = {}
        for k, v in pairs:
            if k in out:
                raise ValueError('duplicate key')
            out[k] = v
        return out
    
    def create_server(predict, key, port=8993):
        if len(key) < 32 or not key.isascii() or not key.isalnum():
            raise ValueError('key must be at least 32 ASCII alphanumeric characters')
        class Handler(BaseHTTPRequestHandler):
            protocol_version = 'HTTP/1.0'
            def setup(self):
                super().setup()
                self.connection.settimeout(5)
            def log_message(self, *_):
                pass
            def reply(self, code, obj):
                data = json.dumps(obj, allow_nan=False, separators=(',', ':')).encode()
                self.send_response(code)
                self.send_header('Content-Type', 'application/json')
                self.send_header('Content-Length', str(len(data)))
                self.send_header('Connection', 'close')
                self.end_headers()
                try:
                    self.wfile.write(data)
                except OSError:
                    pass
            def authorized(self):
                vals = self.headers.get_all('Authorization') or []
                if len(vals) != 1 or not hmac.compare_digest(vals[0].encode(), ('Bearer '+key).encode()):
                    self.reply(401, {'error': 'unauthorized'})
                    return False
                return True
            def do_GET(self):
                if not self.authorized(): return
                if self.path != '/health':
                    self.reply(404, {'error': 'not found'}); return
                self.reply(200, dict(status='ready', model='Kronos-mini', tokenizer='Kronos-Tokenizer-2k', device='cpu', dtype='float32', context_positions=128, history_positions=64, forecast_positions=8))
            def do_POST(self):
                if not self.authorized(): return
                if self.path != '/v1/forecast':
                    self.reply(404, {'error': 'not found'}); return
                if self.headers.get_all('Transfer-Encoding'):
                    self.reply(400, {'error': 'transfer encoding unsupported'}); return
                lens = self.headers.get_all('Content-Length') or []
                if len(lens) != 1 or not lens[0] or not lens[0].isascii() or not lens[0].isdigit():
                    self.reply(411, {'error': 'one ASCII content length required'}); return
                if len(lens[0]) > 4 or int(lens[0]) > 256:
                    self.reply(413, {'error': 'body too large'}); return
                if (self.headers.get_all('Content-Type') or []) != ['application/json']:
                    self.reply(415, {'error': 'application/json required'}); return
                try:
                    raw = self.rfile.read(int(lens[0]))
                    if len(raw) != int(lens[0]): raise ValueError('short body')
                    obj = json.loads(raw, object_pairs_hook=object_pairs, parse_constant=lambda _: (_ for _ in ()).throw(ValueError('nonfinite')))
                    if obj != {'fixture': 'synthetic-ohlcva-v1'}: raise ValueError('fixed fixture only')
                except (ValueError, UnicodeError, OSError):
                    self.reply(400, {'error': 'invalid fixed-fixture request'}); return
                try:
                    payload = result(predict(fixture()))
                except Exception:
                    self.reply(500, {'error': 'forecast failed'}); return
                self.reply(200, payload)
        return HTTPServer(('127.0.0.1', port), Handler)
    
    def main():
        import sys
        sys.path.insert(0, str(ROOT/'runtime'))
        import torch
        import pandas as pd
        from model import Kronos, KronosTokenizer, KronosPredictor
        torch.set_num_threads(4)
        cfg = json.loads((ROOT/'checkpoints/model/config.json').read_text())
        tcfg = json.loads((ROOT/'checkpoints/tokenizer/config.json').read_text())
        assert (cfg['d_model'], cfg['n_layers'], cfg['n_heads'], cfg['s1_bits'], cfg['s2_bits']) == (256, 4, 4, 10, 10)
        assert (tcfg['d_in'], tcfg['group_size'], tcfg['s1_bits'], tcfg['s2_bits']) == (6, 5, 10, 10)
        model = Kronos.from_pretrained(str(ROOT/'checkpoints/model'), map_location='cpu', strict=True, local_files_only=True).float().cpu().eval()
        tokenizer = KronosTokenizer.from_pretrained(str(ROOT/'checkpoints/tokenizer'), map_location='cpu', strict=True, local_files_only=True).float().cpu().eval()
        assert not model.training and not tokenizer.training
        assert all(p.device.type == 'cpu' and p.dtype == torch.float32 for m in (model, tokenizer) for p in m.parameters())
        predictor = KronosPredictor(model, tokenizer, device='cpu', max_context=128, clip=5)
        expected = fixture()
        (ROOT/'synthetic-fixture.json').write_text(json.dumps(expected, indent=2)+'\n')
        def predict(f):
            assert f == expected and len(f['history']) == 64 and len(f['future_timestamps']) == 8
            assert 64+8 <= 128 and all(math.isfinite(v) for r in f['history'] for v in r)
            torch.manual_seed(SEED)
            df = pd.DataFrame(f['history'], columns=COLUMNS)
            x = pd.Series(pd.to_datetime(f['history_timestamps']))
            y = pd.Series(pd.to_datetime(f['future_timestamps']))
            out = predictor.predict(df, x, y, pred_len=8, T=1.0, top_k=0, top_p=0.9, sample_count=1, verbose=False)
            assert list(out.columns) == COLUMNS and out.shape == (8, 6)
            assert list(out.index) == list(y)
            return out.to_numpy().tolist()
        key = (ROOT/'server.key').read_text().strip()
        create_server(predict, key).serve_forever()
    
    if __name__ == '__main__':
        main()
    PYWRAPPER
    sha256sum --check <<'SHA256'
    2251375140e107d89d5e60485f548b8574f144cf4c323d3134c532c0677e3865  reader-forecast-server.py
    SHA256

    Expected result: Wrapper hash matches. Startup will fail rather than silently accept incompatible state dictionaries or training-mode execution.

Start the model

  1. 1. Load both networks and serve on loopback

    Run in the foreground; keep the terminal open. Preserve the private key across restarts and never paste it into logs. Health becomes available only after successful strict model/tokenizer loading. Use another terminal for checks.

    Command
    cd "$HOME/kronos-mini-forecast"
    umask 077
    if [ ! -e server.key ]; then openssl rand -hex 32 > server.key; fi
    test -s server.key
    chmod 600 server.key
    OMP_NUM_THREADS=4 MKL_NUM_THREADS=4 HF_HUB_OFFLINE=1 .venv/bin/python reader-forecast-server.py

    Expected result: Native predictor and tokenizer load locally, fixture is written, and the private serial service binds only to loopback port 8993. Startup time and fit are unknown.

Connect to your endpoint

http://127.0.0.1:8993/v1/forecast

Same trusted desktop loopback only.

Access: loopback. Private Bearer key required for health and forecast requests. Send a JSON object with fixture set to synthetic-ohlcva-v1. The custom response contains columns, timestamps, finite forecast rows, position and scalar-ID counts, sample count and seed. Generated text tokens are not applicable. This is a typed forecasting endpoint.

Verify the setup

  1. 1. Check authenticated readiness

    In a second server terminal use the dedicated virtual environment explicitly. Do not print the key.

    Command
    cd "$HOME/kronos-mini-forecast"
    KRONOS_KEY=$(cat server.key)
    curl --fail --silent --show-error -H "Authorization: Bearer $KRONOS_KEY" http://127.0.0.1:8993/health > health.json
    .venv/bin/python - <<'PYHEALTH'
    import json
    x=json.load(open('health.json'))
    assert x['status']=='ready' and x['device']=='cpu' and x['dtype']=='float32'
    assert (x['context_positions'],x['history_positions'],x['forecast_positions'])==(128,64,8)
    print('ready fixed synthetic forecast endpoint')
    PYHEALTH

    Expected result: Ready response reports CPU float32, 128 configured paired-code positions, 64 history and eight forecast positions.

  2. 2. Forecast the original fixed synthetic sequence

    Submit exactly one fixture selector. The fixture contains 64 original five-minute OHLCVA rows from a synthetic timezone-naive calendar; it is not an exchange calendar. The request does not accept parameters or arbitrary data. Verify fixture bytes, shape, future timestamps, finite numbers and explicit native units. No exact forecast values or quality threshold are asserted.

    Command
    cd "$HOME/kronos-mini-forecast"
    KRONOS_KEY=$(cat server.key)
    curl --fail --silent --show-error --max-time 600 -H "Authorization: Bearer $KRONOS_KEY" -H 'Content-Type: application/json' --data '{"fixture":"synthetic-ohlcva-v1"}' http://127.0.0.1:8993/v1/forecast > forecast.json
    .venv/bin/python - <<'PYCHECK'
    import json,math,datetime,hashlib
    assert hashlib.sha256(open('synthetic-fixture.json','rb').read()).hexdigest()=='f532d0bd540cabb9fabd8107af42986a83f62d5246a025f6bd657c6217f74506'
    x=json.load(open('forecast.json'))
    assert x['columns']==['open','high','low','close','volume','amount']
    assert (x['history_positions'],x['forecast_positions'],x['context_positions'])==(64,8,128)
    assert x['scalar_codes_per_position']==2 and x['generated_scalar_ids_per_path']==16
    assert x['generated_text_tokens'] is None and x['sample_count']==1 and x['seed']==20251016
    start=datetime.datetime(2025,1,2,9,30)
    assert x['timestamps']==[(start+datetime.timedelta(minutes=5*i)).isoformat() for i in range(64,72)]
    assert len(x['forecast'])==8
    assert all(len(r)==6 and all(type(v) in (int,float) and math.isfinite(v) for v in r) for r in x['forecast'])
    print('eight finite six-value forecast rows, exact future timestamps and explicit paired-code units')
    PYCHECK

    Expected result: Eight finite rows with six named values and exact future timestamps pass the checks. A client timeout is not cancellation; stop the foreground process if needed. This expected behavior was not model-executed by the author.

  3. 3. Verify the private access boundary

    Health requires the same Bearer key as forecasting. An unauthenticated request must fail.

    Command
    cd "$HOME/kronos-mini-forecast"
    test "$(curl --silent --output unauthorized.json --write-out '%{http_code}' http://127.0.0.1:8993/health)" = 401
    .venv/bin/python - <<'PYAUTH'
    import json
    assert json.load(open('unauthorized.json'))=={'error':'unauthorized'}
    print('unauthenticated health request rejected')
    PYAUTH

    Expected result: HTTP 401 and structured unauthorized JSON; no model work is triggered.

Performance evidence

No compatible measurement available. Documented support and estimated memory do not establish response speed.

Limits and troubleshooting

  • The custom wrapper is an educational private serial endpoint, not an official or production server. It accepts only the original fixed synthetic fixture; no arbitrary dataset, file path, network URL, market symbol or variable horizon is supported.
  • The unit in context, input and output fields is one autoregressive bar position containing two scalar 10-bit IDs. Each stream has 1024 possible IDs. Eight output positions correspond to 16 scalar generated IDs per sampled path and decode to eight rows of six values, not text.
  • The configured 128-position window is deliberately below mini published 2048-position context. Sixty-four history plus eight future positions fit without rollover. Native predictor encodes history before window cropping; this wrapper bounds input before calling it and does not silently truncate. Small/base checkpoints and the unreleased large variant remain separate unresolved jobs.
  • Both networks explicitly use eval mode and CPU float32. Source Hub safetensors loading does not itself call eval, and native predictor only moves devices. Strict checkpoint loading and saved-config assertions are required. No model execution, peak-memory or latency measurement was performed.
  • Native preprocessing computes mean and standard deviation over provided history, normalizes using std plus a small stabilizer, clips normalized values to minus five through five, and inverse-scales predictions. All six columns are supplied to avoid missing-volume/amount defaults. Minute, hour, weekday, day and month are encoded; year, seconds, timezone and exchange calendars are not.
  • Native decoded output is unconstrained: prices or volumes may be negative, and OHLC relationships need not hold. Finite shape checks are interface checks, not forecast accuracy, market validity, safety, investment advice or profit guarantees. No real financial data or trading is used.
  • Fixed seed aids investigation but is not a guarantee of identical numerical results across runtime versions or hardware. Client timeout does not cancel in-progress CPU work; the server has no generation deadline. Keep it on trusted loopback.
Checkpoint or config mismatch
If strict loading or saved-config assertions fail, stop and verify the exact mini predictor and matching Tokenizer-2k snapshots and source checkout. Do not weaken strict loading or substitute the base tokenizer.
Invalid forecast result
If results contain nonfinite values or the expected eight-by-six shape/index fails, the wrapper returns a generic failure; retain the pinned environment and investigate offline. Do not treat shape success as a quality result.
Insufficient resources
If startup exhausts memory or is too slow, stop the process. Allocated RAM and threads are not measured fit or speed evidence; no reduced-precision or remote fallback is configured.
HTTP 401
If HTTP 401 occurs, read the existing private server.key only in the client shell and send a single Bearer header. Never print, commit or upload the key.
Request timeout
If a request hangs, the 600-second client limit only stops waiting. Use Ctrl+C in the foreground server terminal to stop native work before retrying.

Stop the model

  1. 1. Stop the private forecasting process

    Press Ctrl+C in the foreground server terminal. In each client shell unset the key; confirm loopback no longer serves.

    Command
    unset KRONOS_KEY
    if curl --silent --max-time 2 http://127.0.0.1:8993/health >/dev/null; then echo "Port still responds; inspect the foreground process"; exit 1; fi

    Expected result: Foreground process stopped and loopback port no longer responds.

Uninstall

  1. 1. Remove dedicated research files

    Preserve desired outputs and license notices first. Confirm the dedicated path before removal. Shared Ubuntu packages remain.

    Command
    rm -r -- "$HOME/kronos-mini-forecast"

    Expected result: Dedicated weights, source checkout, virtual environment, wrapper, fixture, results and private key removed.

Sources and verification

Sources checked Oct 16, 2026. Verification source

Compare this configuration
Cloud serverDocumented setupSources checked Oct 16, 2026

Forecast eight synthetic OHLCVA bars with Kronos-mini on an AWS r7i CPU VM

Run the native Kronos-mini predictor with its mandatory learned Tokenizer-2k in CPU float32. A private research endpoint accepts one original synthetic fixture: 64 historical OHLCVA bars and eight future bars in an explicitly reduced 128-position window. Each position contains two hierarchical code IDs; eight output positions generate 16 scalar IDs per path and decode to eight six-value rows. These are financial sequence units, not text tokens. Fit, speed and forecast quality are unmeasured.

Hardware
AWS r7i.xlarge, 32 GiB RAM, Ubuntu x86_64
Runtime
Pinned Kronos native CPU paired-code forecasting research harness Pinned upstream; torch 2.6.0+cpu; Python 3.12; numpy 1.26.4; pandas 2.2.2; einops 0.8.1; hub 0.33.1; safetensors 0.6.2; tqdm 4.67.1 · CPU
Model format
safetensors · CPU float32 execution for both predictor and learned tokenizer; on-disk tensor dtype not independently inspected · Unquantized native checkpoint; explicit CPU float32 execution choice
Workload
128 token context · 1 concurrent

Based on source documentation; this setup has not been executed by OpenTools. Memory: unknown. No compatible measurement available.

Read the complete setup guide

Before you start

  • Use an owned AWS r7i.xlarge Ubuntu 24.04 x86_64 VM in us-east-1 with 32 GiB RAM, four vCPUs and a chosen 40 GiB gp3 volume. Use existing SSH access; allow SSH only from your client and keep port 8993 closed in the security group. Provisioning is reader action and incurs the quoted and other applicable costs.
  • Review the pinned upstream MIT notice and both official checkpoint cards; retain notices with copies. No access token is needed for the selected publicly readable snapshots. This guide grants no rights to outside financial datasets.
  • Research-only synthetic OHLCVA fixture; no live market data, uploads, filesystem paths, symbols or trading recommendations. Inspect the generated fixture before interpreting numerical forecasts.
  • Use Python 3.12 and the pinned CPU package choices below. No author installation or model execution occurred; transitive/system packages resolve on installation and must be recorded. Stop on dependency, key, dtype or shape errors.

Exact model and requirements

Artifact:
NeoQuasar (official upstream Kronos model-zoo publisher) / Kronos-mini predictor; mandatory matching Kronos-Tokenizer-2k auxiliary weights · checkpoint NeoQuasar/Kronos-mini
Publisher revision:
f4e68697d9d5aed55cef5c96aabc3376bcad9f81
Artifact digest:
sha256:a7d5f37e2e9fbd9891f7d7d4f72574512dd1f704fee14223e0a8cd0fbf54197c
Download size:
0.02 GiB
Memory requirement (unknown):
Unknown — No measured peak for both networks, CPU tensors, native decoding, dependencies and serialization.
System RAM / disk:
Unknown / Unknown
Placement:
single device. One CPU host; no model sharding. Both networks and all input/output processing remain on CPU; no GPU or disk offload.
KV cache:
Pinned native inference recomputes the paired-code sequence window each step; no autoregressive K/V cache is configured.
Workload:
128 token context; 64 input tokens; 8 output tokens; concurrency 1; batch 1; cache unknown; repetitions Unknown.
Tokenizer:
Native learned Kronos-Tokenizer-2k; two 10-bit scalar code streams per bar position · 26966d0035065a0cae0ebad7af8ece35bc1fb51c
Sampling / reasoning:
Fixed seed 20251016 reset per request; temperature 1.0, top_k 0, top_p 0.9, sample_count 1. Native inference samples coarse then fine IDs for every future bar. Eight forecast positions mean 16 scalar IDs per path, not eight scalar IDs or text tokens. Seed does not guarantee cross-version or cross-hardware identity. No chat, prompt template, language reasoning or tool calling. Context 128, input 64 and output eight denote paired-code autoregressive bar positions. Both streams are embedded into one position. Mini published context is 2048; this author workload is a reduced window, not a new global model maximum. Total 72 positions never reach the rolling-window boundary. half=True in native encoding splits hierarchical codes; execution remains float32.
Runtime prerequisites:
Ubuntu 24.04 x86_64; See prerequisites above.

Official artifact · License

Upstream source MIT license and both official artifact cards declare MIT. Retain the copyright and permission notice in copies or substantial portions; supplied without warranty. This original synthetic fixture has no external market-data dependency. MIT does not grant rights to third-party financial datasets or provide trading, accuracy or legal assurances.

  • Main predictor LFS artifact is 16,440,776 bytes; mandatory learned tokenizer adds 15,842,376 bytes. Their 32,283,152-byte total is serialized weight metadata, not peak process memory. No weight body downloaded or independently hashed by author.
  • Four CPU threads, 32 GiB RAM and 40 GiB disk are author allocations. Required CPU memory, fit and performance remain unknown.

One-time setup and hardware

hardware
Not applicable — AWS hardware acquisition is included in compute rental; no purchased GPU required. Any separate hardware cost is not applicable.
AWS hardware acquisition is included in compute rental; no purchased GPU required. Any separate hardware cost is not applicable. Tax: unknown.
setup
Unknown — Initial provisioning/build time and labor cost are unknown.
Initial provisioning/build time and labor cost are unknown. Tax: unknown.

Recurring costs

compute
$0.26 / hour
AWS public us-east-1 Linux On-Demand rate USD 0.2646 per billed instance-hour, no paid preinstalled software. Eight hours USD 2.1168; 24 hours USD 6.3504 compute. Idle running hours bill. Storage, egress, tax and administration separate; no Spot/reservation/discount assumed. Capacity/quota unverified. Region: us-east-1. SKU: r7i.xlarge Linux On-Demand. Tax: excluded. Price dated Oct 15, 2026. Price source
storage
$0.08 / GB month
US East (N. Virginia) gp3 USD 0.08 per GB-month; AWS defines GB as 1024^3 bytes. Selected 40 GiB root volume is USD 3.20 per full month, prorated by provisioned duration. Baseline 3000 IOPS / 125 MB/s; no extras assumed. Retained snapshots/resources separate; storage persists after instance stop. Tax excluded. Region: us-east-1. SKU: EBS gp3 baseline 3000 IOPS / 125 MB/s. Tax: excluded. Price dated Oct 16, 2026. Price source
egress
Unknown — Data transfer price, allowances and traffic volume are unknown.
Data transfer price, allowances and traffic volume are unknown. Tax: unknown.
administration
Unknown — Maintenance labor rate and hours are unknown.
Maintenance labor rate and hours are unknown. Tax: unknown.

Install the runtime

  1. 1. Create the pinned native CPU research environment

    Use a dedicated directory, the official hashed CPU wheel and the exact upstream commit. The selected direct dependency versions are source-qualified author choices; no CUDA driver or Transformers runtime is needed. Record resolved transitive and system versions.

    Command
    sudo apt-get update
    sudo apt-get install -y python3.12 python3.12-venv git curl ca-certificates openssl
    mkdir -p "$HOME/kronos-mini-forecast/checkpoints/model" "$HOME/kronos-mini-forecast/checkpoints/tokenizer"
    cd "$HOME/kronos-mini-forecast"
    python3.12 -m venv .venv
    .venv/bin/python -m pip install 'https://download.pytorch.org/whl/cpu/torch-2.6.0%2Bcpu-cp312-cp312-linux_x86_64.whl#sha256=59e78aa0c690f70734e42670036d6b541930b8eabbaa18d94e090abf14cc4d91'
    .venv/bin/python -m pip install 'numpy==1.26.4' 'pandas==2.2.2' 'einops==0.8.1' 'huggingface_hub==0.33.1' 'safetensors==0.6.2' 'tqdm==4.67.1'
    .venv/bin/python -m pip check
    .venv/bin/python -m pip freeze > resolved-environment.txt
    git clone https://github.com/shiyu-coder/Kronos.git runtime
    git -C runtime checkout --detach 67b630e67f6a18c9e9be918d9b4337c960db1e9a
    test "$(git -C runtime rev-parse HEAD)" = '67b630e67f6a18c9e9be918d9b4337c960db1e9a'

    Expected result: pip check succeeds, environment is recorded, and the runtime checkout matches the pinned commit. This has not been installed by the author.

Download the model

  1. 1. Retrieve both exact native checkpoints and notice

    Read the MIT notice first. Download the mini predictor and its mandatory matching Tokenizer-2k, not the base tokenizer. Verify all five file hashes. Weight hashes and sizes are official LFS metadata; author did not retrieve weights.

    Command
    cd "$HOME/kronos-mini-forecast"
    curl --fail --location --output checkpoints/model/model.safetensors 'https://huggingface.co/NeoQuasar/Kronos-mini/resolve/f4e68697d9d5aed55cef5c96aabc3376bcad9f81/model.safetensors'
    curl --fail --location --output checkpoints/model/config.json 'https://huggingface.co/NeoQuasar/Kronos-mini/resolve/f4e68697d9d5aed55cef5c96aabc3376bcad9f81/config.json'
    curl --fail --location --output checkpoints/tokenizer/model.safetensors 'https://huggingface.co/NeoQuasar/Kronos-Tokenizer-2k/resolve/26966d0035065a0cae0ebad7af8ece35bc1fb51c/model.safetensors'
    curl --fail --location --output checkpoints/tokenizer/config.json 'https://huggingface.co/NeoQuasar/Kronos-Tokenizer-2k/resolve/26966d0035065a0cae0ebad7af8ece35bc1fb51c/config.json'
    curl --fail --location --output KRONOS-LICENSE 'https://raw.githubusercontent.com/shiyu-coder/Kronos/67b630e67f6a18c9e9be918d9b4337c960db1e9a/LICENSE'
    sha256sum --check <<'SHA256'
    a7d5f37e2e9fbd9891f7d7d4f72574512dd1f704fee14223e0a8cd0fbf54197c  checkpoints/model/model.safetensors
    70daca2cb11e3a979dd6b8ac12ee08e2aace877acf28f5b8dfb4fe5609736201  checkpoints/model/config.json
    b97ec46b3b72160509e289183eaf7bdf5f0dac5bb9b49522f6d46638a99a8717  checkpoints/tokenizer/model.safetensors
    0b30a443affb03e05a876a083857de9164f899feb7b4d261da02c485c9a3e3b6  checkpoints/tokenizer/config.json
    acb2d194d378204e5f2be4dcd24d39ecac437903620c790c3315a96dab388fdc  KRONOS-LICENSE
    SHA256

    Expected result: Both checkpoint directories contain verified configs and native safetensors; exact MIT notice retained.

Configure

  1. 1. Write the bounded private research wrapper

    This reader-authored wrapper is not publisher serving code. Native checkpoint loading is strict; both networks are explicitly CPU float32 in evaluation mode. Only a fixed synthetic fixture is accepted. Body framing and JSON errors are rejected before inference. This serial research server has a socket read timeout, no TLS, no inference deadline and no public-service hardening.

    Command
    cd "$HOME/kronos-mini-forecast"
    cat > reader-forecast-server.py <<'PYWRAPPER'
    """Reader-authored fixed synthetic Kronos research endpoint; not publisher serving code."""
    import datetime as dt
    import hmac
    import json
    import math
    import os
    from http.server import BaseHTTPRequestHandler, HTTPServer
    from pathlib import Path
    
    ROOT = Path(__file__).resolve().parent
    COLUMNS = ['open', 'high', 'low', 'close', 'volume', 'amount']
    SEED = 20251016
    
    def fixture():
        start = dt.datetime(2025, 1, 2, 9, 30)
        times = [(start + dt.timedelta(minutes=5*i)).isoformat() for i in range(72)]
        rows = [[100+i, 102+i, 99+i, 101+i, 1000+10*i, (1000+10*i)*(201+2*i)/2] for i in range(64)]
        return dict(columns=COLUMNS, history=rows, history_timestamps=times[:64], future_timestamps=times[64:])
    
    def result(values):
        if not isinstance(values, list) or len(values) != 8:
            raise ValueError('forecast shape')
        for row in values:
            if not isinstance(row, list) or len(row) != 6:
                raise ValueError('forecast shape')
            if any(isinstance(v, bool) or not isinstance(v, (float, int)) or not math.isfinite(v) for v in row):
                raise ValueError('nonfinite forecast')
        return dict(fixture='synthetic-ohlcva-v1', columns=COLUMNS,
                    timestamps=fixture()['future_timestamps'], forecast=values,
                    history_positions=64, forecast_positions=8, context_positions=128,
                    scalar_codes_per_position=2, generated_scalar_ids_per_path=16,
                    sample_count=1, seed=SEED, generated_text_tokens=None)
    
    def object_pairs(pairs):
        out = {}
        for k, v in pairs:
            if k in out:
                raise ValueError('duplicate key')
            out[k] = v
        return out
    
    def create_server(predict, key, port=8993):
        if len(key) < 32 or not key.isascii() or not key.isalnum():
            raise ValueError('key must be at least 32 ASCII alphanumeric characters')
        class Handler(BaseHTTPRequestHandler):
            protocol_version = 'HTTP/1.0'
            def setup(self):
                super().setup()
                self.connection.settimeout(5)
            def log_message(self, *_):
                pass
            def reply(self, code, obj):
                data = json.dumps(obj, allow_nan=False, separators=(',', ':')).encode()
                self.send_response(code)
                self.send_header('Content-Type', 'application/json')
                self.send_header('Content-Length', str(len(data)))
                self.send_header('Connection', 'close')
                self.end_headers()
                try:
                    self.wfile.write(data)
                except OSError:
                    pass
            def authorized(self):
                vals = self.headers.get_all('Authorization') or []
                if len(vals) != 1 or not hmac.compare_digest(vals[0].encode(), ('Bearer '+key).encode()):
                    self.reply(401, {'error': 'unauthorized'})
                    return False
                return True
            def do_GET(self):
                if not self.authorized(): return
                if self.path != '/health':
                    self.reply(404, {'error': 'not found'}); return
                self.reply(200, dict(status='ready', model='Kronos-mini', tokenizer='Kronos-Tokenizer-2k', device='cpu', dtype='float32', context_positions=128, history_positions=64, forecast_positions=8))
            def do_POST(self):
                if not self.authorized(): return
                if self.path != '/v1/forecast':
                    self.reply(404, {'error': 'not found'}); return
                if self.headers.get_all('Transfer-Encoding'):
                    self.reply(400, {'error': 'transfer encoding unsupported'}); return
                lens = self.headers.get_all('Content-Length') or []
                if len(lens) != 1 or not lens[0] or not lens[0].isascii() or not lens[0].isdigit():
                    self.reply(411, {'error': 'one ASCII content length required'}); return
                if len(lens[0]) > 4 or int(lens[0]) > 256:
                    self.reply(413, {'error': 'body too large'}); return
                if (self.headers.get_all('Content-Type') or []) != ['application/json']:
                    self.reply(415, {'error': 'application/json required'}); return
                try:
                    raw = self.rfile.read(int(lens[0]))
                    if len(raw) != int(lens[0]): raise ValueError('short body')
                    obj = json.loads(raw, object_pairs_hook=object_pairs, parse_constant=lambda _: (_ for _ in ()).throw(ValueError('nonfinite')))
                    if obj != {'fixture': 'synthetic-ohlcva-v1'}: raise ValueError('fixed fixture only')
                except (ValueError, UnicodeError, OSError):
                    self.reply(400, {'error': 'invalid fixed-fixture request'}); return
                try:
                    payload = result(predict(fixture()))
                except Exception:
                    self.reply(500, {'error': 'forecast failed'}); return
                self.reply(200, payload)
        return HTTPServer(('127.0.0.1', port), Handler)
    
    def main():
        import sys
        sys.path.insert(0, str(ROOT/'runtime'))
        import torch
        import pandas as pd
        from model import Kronos, KronosTokenizer, KronosPredictor
        torch.set_num_threads(4)
        cfg = json.loads((ROOT/'checkpoints/model/config.json').read_text())
        tcfg = json.loads((ROOT/'checkpoints/tokenizer/config.json').read_text())
        assert (cfg['d_model'], cfg['n_layers'], cfg['n_heads'], cfg['s1_bits'], cfg['s2_bits']) == (256, 4, 4, 10, 10)
        assert (tcfg['d_in'], tcfg['group_size'], tcfg['s1_bits'], tcfg['s2_bits']) == (6, 5, 10, 10)
        model = Kronos.from_pretrained(str(ROOT/'checkpoints/model'), map_location='cpu', strict=True, local_files_only=True).float().cpu().eval()
        tokenizer = KronosTokenizer.from_pretrained(str(ROOT/'checkpoints/tokenizer'), map_location='cpu', strict=True, local_files_only=True).float().cpu().eval()
        assert not model.training and not tokenizer.training
        assert all(p.device.type == 'cpu' and p.dtype == torch.float32 for m in (model, tokenizer) for p in m.parameters())
        predictor = KronosPredictor(model, tokenizer, device='cpu', max_context=128, clip=5)
        expected = fixture()
        (ROOT/'synthetic-fixture.json').write_text(json.dumps(expected, indent=2)+'\n')
        def predict(f):
            assert f == expected and len(f['history']) == 64 and len(f['future_timestamps']) == 8
            assert 64+8 <= 128 and all(math.isfinite(v) for r in f['history'] for v in r)
            torch.manual_seed(SEED)
            df = pd.DataFrame(f['history'], columns=COLUMNS)
            x = pd.Series(pd.to_datetime(f['history_timestamps']))
            y = pd.Series(pd.to_datetime(f['future_timestamps']))
            out = predictor.predict(df, x, y, pred_len=8, T=1.0, top_k=0, top_p=0.9, sample_count=1, verbose=False)
            assert list(out.columns) == COLUMNS and out.shape == (8, 6)
            assert list(out.index) == list(y)
            return out.to_numpy().tolist()
        key = (ROOT/'server.key').read_text().strip()
        create_server(predict, key).serve_forever()
    
    if __name__ == '__main__':
        main()
    PYWRAPPER
    sha256sum --check <<'SHA256'
    2251375140e107d89d5e60485f548b8574f144cf4c323d3134c532c0677e3865  reader-forecast-server.py
    SHA256

    Expected result: Wrapper hash matches. Startup will fail rather than silently accept incompatible state dictionaries or training-mode execution.

Start the model

  1. 1. Load both networks and serve on loopback

    Run in the foreground; keep the terminal open. Preserve the private key across restarts and never paste it into logs. Health becomes available only after successful strict model/tokenizer loading. Use another terminal for checks.

    Command
    cd "$HOME/kronos-mini-forecast"
    umask 077
    if [ ! -e server.key ]; then openssl rand -hex 32 > server.key; fi
    test -s server.key
    chmod 600 server.key
    OMP_NUM_THREADS=4 MKL_NUM_THREADS=4 HF_HUB_OFFLINE=1 .venv/bin/python reader-forecast-server.py

    Expected result: Native predictor and tokenizer load locally, fixture is written, and the private serial service binds only to loopback port 8993. Startup time and fit are unknown.

Connect to your endpoint

http://127.0.0.1:8993/v1/forecast

VM loopback only. Use existing SSH access with ssh -N -L 8993:127.0.0.1:8993 USER@VM_IP if needed; keep EC2 port 8993 closed. Shown checks run on the server. Copy the key only over your trusted SSH channel if using a local client.

Access: loopback. Private Bearer key required for health and forecast requests. Send a JSON object with fixture set to synthetic-ohlcva-v1. The custom response contains columns, timestamps, finite forecast rows, position and scalar-ID counts, sample count and seed. Generated text tokens are not applicable. This is a typed forecasting endpoint.

Verify the setup

  1. 1. Check authenticated readiness

    In a second server terminal use the dedicated virtual environment explicitly. Do not print the key.

    Command
    cd "$HOME/kronos-mini-forecast"
    KRONOS_KEY=$(cat server.key)
    curl --fail --silent --show-error -H "Authorization: Bearer $KRONOS_KEY" http://127.0.0.1:8993/health > health.json
    .venv/bin/python - <<'PYHEALTH'
    import json
    x=json.load(open('health.json'))
    assert x['status']=='ready' and x['device']=='cpu' and x['dtype']=='float32'
    assert (x['context_positions'],x['history_positions'],x['forecast_positions'])==(128,64,8)
    print('ready fixed synthetic forecast endpoint')
    PYHEALTH

    Expected result: Ready response reports CPU float32, 128 configured paired-code positions, 64 history and eight forecast positions.

  2. 2. Forecast the original fixed synthetic sequence

    Submit exactly one fixture selector. The fixture contains 64 original five-minute OHLCVA rows from a synthetic timezone-naive calendar; it is not an exchange calendar. The request does not accept parameters or arbitrary data. Verify fixture bytes, shape, future timestamps, finite numbers and explicit native units. No exact forecast values or quality threshold are asserted.

    Command
    cd "$HOME/kronos-mini-forecast"
    KRONOS_KEY=$(cat server.key)
    curl --fail --silent --show-error --max-time 600 -H "Authorization: Bearer $KRONOS_KEY" -H 'Content-Type: application/json' --data '{"fixture":"synthetic-ohlcva-v1"}' http://127.0.0.1:8993/v1/forecast > forecast.json
    .venv/bin/python - <<'PYCHECK'
    import json,math,datetime,hashlib
    assert hashlib.sha256(open('synthetic-fixture.json','rb').read()).hexdigest()=='f532d0bd540cabb9fabd8107af42986a83f62d5246a025f6bd657c6217f74506'
    x=json.load(open('forecast.json'))
    assert x['columns']==['open','high','low','close','volume','amount']
    assert (x['history_positions'],x['forecast_positions'],x['context_positions'])==(64,8,128)
    assert x['scalar_codes_per_position']==2 and x['generated_scalar_ids_per_path']==16
    assert x['generated_text_tokens'] is None and x['sample_count']==1 and x['seed']==20251016
    start=datetime.datetime(2025,1,2,9,30)
    assert x['timestamps']==[(start+datetime.timedelta(minutes=5*i)).isoformat() for i in range(64,72)]
    assert len(x['forecast'])==8
    assert all(len(r)==6 and all(type(v) in (int,float) and math.isfinite(v) for v in r) for r in x['forecast'])
    print('eight finite six-value forecast rows, exact future timestamps and explicit paired-code units')
    PYCHECK

    Expected result: Eight finite rows with six named values and exact future timestamps pass the checks. A client timeout is not cancellation; stop the foreground process if needed. This expected behavior was not model-executed by the author.

  3. 3. Verify the private access boundary

    Health requires the same Bearer key as forecasting. An unauthenticated request must fail.

    Command
    cd "$HOME/kronos-mini-forecast"
    test "$(curl --silent --output unauthorized.json --write-out '%{http_code}' http://127.0.0.1:8993/health)" = 401
    .venv/bin/python - <<'PYAUTH'
    import json
    assert json.load(open('unauthorized.json'))=={'error':'unauthorized'}
    print('unauthenticated health request rejected')
    PYAUTH

    Expected result: HTTP 401 and structured unauthorized JSON; no model work is triggered.

Performance evidence

No compatible measurement available. Documented support and estimated memory do not establish response speed.

Limits and troubleshooting

  • The custom wrapper is an educational private serial endpoint, not an official or production server. It accepts only the original fixed synthetic fixture; no arbitrary dataset, file path, network URL, market symbol or variable horizon is supported.
  • The unit in context, input and output fields is one autoregressive bar position containing two scalar 10-bit IDs. Each stream has 1024 possible IDs. Eight output positions correspond to 16 scalar generated IDs per sampled path and decode to eight rows of six values, not text.
  • The configured 128-position window is deliberately below mini published 2048-position context. Sixty-four history plus eight future positions fit without rollover. Native predictor encodes history before window cropping; this wrapper bounds input before calling it and does not silently truncate. Small/base checkpoints and the unreleased large variant remain separate unresolved jobs.
  • Both networks explicitly use eval mode and CPU float32. Source Hub safetensors loading does not itself call eval, and native predictor only moves devices. Strict checkpoint loading and saved-config assertions are required. No model execution, peak-memory or latency measurement was performed.
  • Native preprocessing computes mean and standard deviation over provided history, normalizes using std plus a small stabilizer, clips normalized values to minus five through five, and inverse-scales predictions. All six columns are supplied to avoid missing-volume/amount defaults. Minute, hour, weekday, day and month are encoded; year, seconds, timezone and exchange calendars are not.
  • Native decoded output is unconstrained: prices or volumes may be negative, and OHLC relationships need not hold. Finite shape checks are interface checks, not forecast accuracy, market validity, safety, investment advice or profit guarantees. No real financial data or trading is used.
  • Fixed seed aids investigation but is not a guarantee of identical numerical results across runtime versions or hardware. Client timeout does not cancel in-progress CPU work; the server has no generation deadline. Keep it on trusted loopback.
Checkpoint or config mismatch
If strict loading or saved-config assertions fail, stop and verify the exact mini predictor and matching Tokenizer-2k snapshots and source checkout. Do not weaken strict loading or substitute the base tokenizer.
Invalid forecast result
If results contain nonfinite values or the expected eight-by-six shape/index fails, the wrapper returns a generic failure; retain the pinned environment and investigate offline. Do not treat shape success as a quality result.
Insufficient resources
If startup exhausts memory or is too slow, stop the process. Allocated RAM and threads are not measured fit or speed evidence; no reduced-precision or remote fallback is configured.
HTTP 401
If HTTP 401 occurs, read the existing private server.key only in the client shell and send a single Bearer header. Never print, commit or upload the key.
Request timeout
If a request hangs, the 600-second client limit only stops waiting. Use Ctrl+C in the foreground server terminal to stop native work before retrying.

Stop the model

  1. 1. Stop the private forecasting process

    Press Ctrl+C in the foreground server terminal. In each client shell unset the key; confirm loopback no longer serves. A process stop does not stop cloud instance billing.

    Command
    unset KRONOS_KEY
    if curl --silent --max-time 2 http://127.0.0.1:8993/health >/dev/null; then echo "Port still responds; inspect the foreground process"; exit 1; fi

    Expected result: Foreground process stopped and loopback port no longer responds.

Uninstall

  1. 1. Remove dedicated research files

    Preserve desired outputs and license notices first. Confirm the dedicated path before removal. Shared Ubuntu packages remain.

    Command
    rm -r -- "$HOME/kronos-mini-forecast"

    Expected result: Dedicated weights, source checkout, virtual environment, wrapper, fixture, results and private key removed.

Shut down cloud resources

  1. 1. End cloud billing resources

    In EC2 us-east-1, stop for later reuse or terminate this exact VM. Review Delete on termination for its root volume. Delete unwanted detached EBS volumes, snapshots and reserved/Elastic/public IP resources. Stopped VM storage and retained resources may still bill. Check Bills/Cost Explorer later for final usage.

    Expected result: Exact instance is stopped/terminated as intended; no unwanted attached/retained billed resources remain. Instance compute stops only after its lifecycle transition, not when the Python service stops.

Sources and verification

Sources checked Oct 16, 2026. Verification source

Compare this configuration

Benchmarks

Performance scores for Kronos across standard benchmarks.

RankIC improvement over leading TSFMofficial-arxiv · Aug 2025
93
Volatility MAE reductionofficial-arxiv · Aug 2025
9
Synthetic K-line fidelity improvementofficial-arxiv · Aug 2025
22

Pricing and access

Open research model; API token pricing was not published in the GitHub or arXiv sources reviewed.

Tsinghua University logo

Research university with active AI and foundation-model work

1 ModelsFounded 1911Beijing, China
View full profile