Running Kronos, the Open-Source Financial Forecasting Model, on Apple Silicon
Kronos is the first open-source foundation model purpose-built for financial candlestick (K-line) forecasting. It was trained on data from over 45 global exchanges and recently accepted at AAAI 2026. If you have a Mac with an M-series chip, you can run it entirely on-device with full GPU acceleration via Apple's Metal Performance Shaders (MPS) -- no cloud, no API keys, no data leaving your machine.
This guide walks through the complete setup on an M4 Max MacBook Pro (64GB RAM), but the steps apply to any Apple Silicon Mac. Everything here has been tested and verified end-to-end.
How Kronos Works (The Short Version)
Kronos uses a two-stage architecture:
- Specialized tokenizer -- Binary Spherical Quantization (BSQ) converts continuous candlestick data (open, high, low, close, volume) into discrete tokens. This is not a text tokenizer; it is purpose-built for financial time series.
- Decoder-only Transformer -- A GPT-style model trained autoregressively on those tokens, predicting the next candle given a context window of historical candles.
The result is a model that natively understands the structure of OHLCV data rather than treating it as generic numbers.
Available Models
All open-source weights are hosted on HuggingFace under the NeoQuasar organization.
| Model | Context Length | Parameters | Open-Source |
|---|---|---|---|
| Kronos-mini | 2048 | 4.1M | Yes |
| Kronos-small | 512 | 24.7M | Yes |
| Kronos-base | 512 | 102.3M | Yes |
| Kronos-large | 512 | 499.2M | No |
For most experimentation, Kronos-base (102M parameters) is a good starting point. It is small enough to run fast on a laptop and large enough to produce useful forecasts.
Setup
1. Clone the Repository
git clone https://github.com/shiyu-coder/Kronos.git
cd Kronos
2. Set Up Python (Watch the Version)
Gotcha: Python 3.14 does not work. As of this writing, there are no PyTorch wheels for Python 3.14. Use Python 3.13, which works perfectly.
If you use Homebrew:
brew install python@3.13
Create and activate a virtual environment:
/opt/homebrew/bin/python3.13 -m venv .venv
source .venv/bin/activate
Verify you are on the right version:
python --version
# Python 3.13.x
3. Install Dependencies
pip install -r requirements.txt
This pulls in PyTorch 2.11.0 (with MPS support built in), along with:
einopshuggingface_hubmatplotlibpandassafetensors
The full dependency list requires torch>=2.0.0, and any recent pip on macOS will automatically select the MPS-enabled build. No special install flags or channel selection needed.
4. Apple Silicon GPU -- It Just Works
Kronos includes built-in MPS auto-detection. In model/kronos.py, the KronosPredictor class checks for MPS availability at initialization:
elif hasattr(torch.backends, 'mps') and torch.backends.mps.is_available():
device = "mps"
You do not need to modify any code, set environment variables, or pass device flags. If you are on Apple Silicon, inference runs on the GPU automatically.
5. Download Models for Offline Use
The first time you instantiate a model, it downloads weights from HuggingFace. If you want to cache them locally (recommended for reproducibility and offline work):
from model import Kronos, KronosTokenizer
# Download and save tokenizer
tokenizer = KronosTokenizer.from_pretrained("NeoQuasar/Kronos-Tokenizer-base")
tokenizer.save_pretrained("./models/Tokenizer-base")
# Download and save model
model = Kronos.from_pretrained("NeoQuasar/Kronos-base")
model.save_pretrained("./models/102M")
From then on, load from the local path:
tokenizer = KronosTokenizer.from_pretrained("./models/Tokenizer-base")
model = Kronos.from_pretrained("./models/102M")
This avoids any network dependency at inference time. The Kronos-base model weights are around 400MB on disk.
Running Your First Forecast
Here is a complete, working script. The repo includes test data you can use out of the box.
import pandas as pd
import sys
sys.path.insert(0, ".")
from model import Kronos, KronosTokenizer, KronosPredictor
# Load model and tokenizer (local paths after download)
tokenizer = KronosTokenizer.from_pretrained("./models/Tokenizer-base")
model = Kronos.from_pretrained("./models/102M")
predictor = KronosPredictor(model, tokenizer, max_context=512)
# Load sample data
df = pd.read_csv("./tests/data/regression_input.csv")
df['timestamps'] = pd.to_datetime(df['timestamps'])
lookback = 400 # number of historical candles to use as context
pred_len = 120 # number of future candles to predict
# Prepare input and output timestamps
x_df = df.loc[:lookback-1, ['open', 'high', 'low', 'close', 'volume', 'amount']]
x_timestamp = df.loc[:lookback-1, 'timestamps']
y_timestamp = df.loc[lookback:lookback+pred_len-1, 'timestamps']
# Run inference
pred_df = predictor.predict(
df=x_df,
x_timestamp=x_timestamp,
y_timestamp=y_timestamp,
pred_len=pred_len,
T=1.0,
top_p=0.9,
sample_count=1,
verbose=True
)
print(pred_df.head())
Input Format
The model expects a pandas DataFrame with these columns:
- Required:
open,high,low,close - Optional:
volume,amount
Timestamps should be pandas datetime objects. The x_timestamp and y_timestamp series define the historical and forecast time ranges, respectively.
Key Parameters
pred_len-- How many future candles to generate.T(temperature) -- Controls randomness. 1.0 is the default; lower values produce more deterministic forecasts.top_p-- Nucleus sampling threshold. 0.9 is a reasonable default.sample_count-- Number of independent forecast samples to generate. Useful for building prediction intervals.max_context-- Maximum number of historical candles the model considers (limited by the model variant's context length).
Performance on Apple Silicon
On an M4 Max (64GB unified memory), Kronos-base runs at roughly 18 iterations per second during autoregressive generation. Each iteration produces one predicted candle.
| Prediction Length | Approximate Time |
|---|---|
| 12 candles | < 1 second |
| 60 candles | ~3 seconds |
| 120 candles | ~7 seconds |
This is fast enough for interactive use, backtesting loops, and batch processing of multiple assets. The unified memory architecture means there is no CPU-GPU data transfer bottleneck -- the model weights and intermediate tensors live in the same memory pool.
What Can You Do With It
Kronos outputs predicted OHLCV candles, not just a single price point. That opens up several practical use cases:
Short-term price forecasting. Generate the next N candles for any asset and timeframe the model was trained on. Because the output includes open, high, low, and close, you get a richer picture than a single-point forecast.
Scenario analysis. Set sample_count greater than 1 to generate multiple independent forecast paths. This gives you a distribution of outcomes -- useful for estimating prediction intervals or understanding tail risk.
Feature generation for downstream models. Use Kronos forecasts as input features for a trading strategy, risk model, or portfolio optimizer. The predicted candle structure encodes information about expected volatility (high-low spread) and direction (open-close relationship).
Backtesting signal generation. Run Kronos over historical windows and compare predicted candles against actuals. This lets you evaluate whether the model's directional accuracy or volatility estimates are useful for your specific market and timeframe.
Cross-asset pattern recognition. Because Kronos was trained on 45+ exchanges spanning equities, crypto, forex, and commodities, it has learned generalizable candlestick patterns. You can apply it to assets it has never explicitly seen.
Gotchas and Tips
Python version matters. Python 3.14 will fail at the PyTorch install step. Stick with 3.13.
First-run downloads. If you do not pre-download the models (step 5), the first call to from_pretrained with a HuggingFace model ID will download weights over the network. This can be slow and will fail without internet access. Download once, save locally, and point to the local path.
The model runs 100% locally. Once the weights are downloaded, no data is sent anywhere. All inference happens on-device via MPS. This matters if you are working with proprietary trading data.
Memory usage. Kronos-base at 102M parameters is modest. Even on an M1 with 8GB, you should have no issues. If you want to experiment with Kronos-mini (4.1M params, 2048 context length), that one is even lighter and supports longer context windows.
Repo structure. The model code lives in the model/ directory. KronosPredictor in model/kronos.py is the main inference interface. The tokenizer is a separate component (KronosTokenizer) that handles the BSQ encoding/decoding.
Wrapping Up
Kronos is a lightweight, specialized model that does one thing well: forecast financial candlesticks. The fact that it runs natively on Apple Silicon with zero configuration is a nice bonus. Clone, install, run -- you can have your first forecast in under five minutes.
For the paper, the full architecture details, and training methodology, see the arXiv preprint. For the code and model weights, everything is on GitHub and HuggingFace.
Niël Malan
The Practical Futurist