File size: 6,391 Bytes
a2a4a3b 0af98fe a2a4a3b 9cc39bf a2a4a3b 0af98fe a2a4a3b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | ---
license: apache-2.0
language:
- en
tags:
- time-series
- multimodal
- forecasting
- foundation-model
- chronicle
library_name: pytorch
pipeline_tag: time-series-forecasting
---
<p align="center">
<a href="https://www.inertialai.com">
<img src="https://www.inertialai.com/biglogo-v2.webp" alt="InertialAI" height="56">
</a>
</p>
# Chronicle
**A multimodal foundation model for joint language and time series understanding.**
Chronicle is a compact **324M-parameter decoder-only transformer trained from scratch on
natural language and time series** within a single unified architecture. Text tokens and
time-series patches share the same transformer blocks, attention mechanism, and residual
stream β cross-modal capability emerges from shared parameters rather than from bolting a
time-series encoder onto a pretrained LLM.
- π **Paper:** [Chronicle: A Multimodal Foundation Model for Joint Language and Time
Series Understanding](https://arxiv.org/abs/2605.20268) (Quinlan, Levasseur, Li, Zhu)
- π» **Code & finetuning examples:** [github.com/InertialAI/Chronicle](https://github.com/InertialAI/Chronicle)
- βοΈ **Hosted API with self-serve finetuning *(coming soon)*:** [inertialai.com](https://www.inertialai.com/platform)
## Checkpoints in this repo
| Path | Stage | Description |
| --- | --- | --- |
| `stage-1/` | **Stage 1** | Unimodal-batch pretraining (~92% text / 8% time series) β cross-modal ability from shared parameters alone. `model.safetensors` + `config.json` |
| `stage-2/` | **Stage 2** | Stage 1 + a short alignment stage that interleaves the two modalities (best multimodal results); context extended to 4096. `model.safetensors` + `config.json` |
| `tokenizer/` | β | 131k-vocabulary BPE tokenizer (trained from scratch) |
| `model.py` Β· `tokenizer.py` | β | Minimal inference implementation (`Chronicle`, `ChronicleConfig`, `ChronicleTokenizer`) |
| `config.json` | β | Repo-level model metadata (mirrors the stage-2 architecture); the per-stage `config.json` files remain authoritative for loading |
## Architecture
| | |
| --- | --- |
| Parameters | 324M, 16-layer decoder-only transformer |
| Width / heads | d=1024, 8 attention heads (4 KV, GQA) |
| Context | 2048 tokens (stage 1) / 4096 (stage 2) β text tokens + 32-step series patches, one shared stream |
| Series head | 21-quantile next-patch forecasting with instance normalization |
| Objective | causal next-token / next-patch prediction |
## Usage
Weights ship as **safetensors**; `model.py` and `tokenizer.py` are a minimal,
dependency-light inference implementation (`torch`, `tiktoken`). Verified example (text generation,
CPU):
```python
import json
import sys
import torch
from huggingface_hub import snapshot_download
from safetensors.torch import load_file
repo = snapshot_download("InertialAI/Chronicle")
sys.path.insert(0, repo)
from model import Chronicle, ChronicleConfig
from tokenizer import ChronicleTokenizer
config = ChronicleConfig(**json.load(open(f"{repo}/stage-2/config.json")))
model = Chronicle(config)
state = load_file(f"{repo}/stage-2/model.safetensors")
state = {k: v.float() if v.dtype is torch.bfloat16 else v for k, v in state.items()}
model.load_state_dict(state, strict=True)
model = model.float().eval()
model.cos, model.sin = model.cos.float(), model.sin.float() # fp32 rotary on CPU
tokenizer = ChronicleTokenizer.from_directory(f"{repo}/tokenizer")
ids = [tokenizer.get_bos_token_id()] + tokenizer.encode("Time series forecasting is")
with torch.no_grad():
for _ in range(16):
out = model(torch.tensor([ids]))
logits = out[0] if isinstance(out, tuple) else out
ids.append(int(logits[0, -1].argmax()))
print(tokenizer.decode(ids[1:]))
# -> "Time series forecasting is a technique used to forecast future values
# of a time series based on historical data."
```
For the time-series pathway (quantile forecasting via `ts_patches`) and
`forecast()` / `embed()` conveniences, use the **transformers-native port (in
progress)** or the [hosted API](https://docs.inertialai.com) (coming soon), which
will serve these models. The finetuning recipes in the
[GitHub repo](https://github.com/InertialAI/Chronicle) show the downstream-task
protocols used in the paper.
## Results
One backbone, evaluated against dedicated unimodal foundation models in *both*
domains β the core claim is breadth: strong language understanding, state-of-the-art
frozen time-series embeddings, and best-in-class multimodal forecasting, all from the
same weights. Numbers below are from the paper.
**Language understanding** (19-task NLU average) β parity with text-only models of the
same scale, trained on ~40Γ fewer text tokens:
| | GPT-2 (124M) | Gemma-3 (270M) | **Chronicle-1 (324M)** | **Chronicle-2 (324M)** | LFM-2 (350M) |
| --- | --- | --- | --- | --- | --- |
| NLU avg | 0.324 | 0.406 | **0.411** | **0.406** | 0.449 |
**Time series classification** (24 UCR/UEA datasets, linear probe on frozen
embeddings) β a new bar among TS foundation models:
| Dataset | Chronos-2 | TimesFM | Moirai-2 | **Chronicle-1** |
| --- | --- | --- | --- | --- |
| GunPoint | 0.528 | 0.712 | 0.931 | **0.919** |
| FaceFour | 0.236 | 0.609 | 0.582 | **0.864** |
| Trace | 0.288 | 0.630 | 0.802 | **0.936** |
| ECG200 | 0.672 | 0.840 | 0.820 | **0.846** |
**Multimodal forecasting** (Time-MMD, 9 domains, MAE β) β beats every supervised
fusion baseline and every frozen FM-fusion pairing (baseline columns show the best
baseline per metric):
| | Best MM-TSFlib | Best FM Fusion | **Chronicle-2 (LP)** |
| --- | --- | --- | --- |
| Avg NMAE | 0.621 | 0.588 | **0.514** |
| Avg rank | 6.78 | 6.11 | **2.56** |
**Multimodal classification** (TimeCAP: weather, finance, healthcare) β Chronicle-2
LoRA reaches **0.613 F1 / 0.757 AUC**, ahead of every MM-TSFlib and FM-fusion baseline.
See the [paper](https://arxiv.org/abs/2605.20268) for full tables, protocols, and
baselines, and the [GitHub repo](https://github.com/InertialAI/Chronicle) for
reproduction scripts on public data.
## Citation
```bibtex
@article{quinlan2026chronicle,
title={Chronicle: A Multimodal Foundation Model for Joint Language and Time Series Understanding},
author={Quinlan, Paul and Levasseur, Jeremy and Li, Qingguo and Zhu, Xiaodan},
journal={arXiv preprint arXiv:2605.20268},
year={2026}
}
```
## License
Apache 2.0.
|