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.