Discrete tokenization framework for time-series understanding in LLMs. Converts raw signals to FSQ codes via a learned Transformer tokenizer, embeds them as native LLM tokens, and trains with DoRA adapters. Supports classification, anomaly detection, reasoning across sensor, medical, and industrial domains.
14
stars
17
commits
Python
primary language
Jul 28, 2026
updated
TEMPO is a backbone-agnostic framework that turns any decoder-only LLM into a time-series reasoner. Signals are encoded into discrete tokens by a small FSQ-Transformer quantizer, aligned with the LLM's embedding space in a Phase 0 pass, and trained to answer questions and classify patterns in a Phase 1 pass.
[!WARNING] This repository is not yet functional. Model checkpoints and trained weights are not publicly released — you cannot run inference or reproduce results without them. Full release coming soon.
Three components, trained in sequence:
Tokenizer (1.6M params, frozen after pre-training). Maps normalized real-valued samples to discrete codes via FSQ-Transformer with levels = [5,5,5,5] (625 codes, 4:1 compression).
Phase 0: Alignment. LLM frozen; a small projection is trained so that tokenizer code embeddings align with the LLM's input space.
Phase 1: Instruction tuning. LoRA/DoRA adapters trained on downstream tasks (MCQ, captioning, CoT, classification) with signal tokens inlined into the chat template.
git clone https://github.com/Forgis-Labs/TEMPO.git
cd TEMPO
uv pip install -e .
Python >= 3.10. Dependencies listed in pyproject.toml.
import tempo
model = tempo.TEMPO.from_pretrained(
"checkpoints/phase1_best.pt",
fsq_ckpt="checkpoints/fsq_transformer_rope_625_best.pt",
llm_id="Qwen/Qwen3-4B",
use_dora=True,
)
answer = model.analyze(signal, question="Describe the trend in this signal.")
from tempo import TEMPO, TEMPOConfig
from tempo.train import run_pipeline, PipelineConfig
model = TEMPO(TEMPOConfig(llm_id="Qwen/Qwen3-4B", lora_r=32, use_dora=True))
run_pipeline(model, PipelineConfig(batch_size=4, grad_accum=4))
from tempo.eval import evaluate
result = evaluate(model, test_dataset, output_dir="results/phase1",
dataset_name="har", task="classification")
print(result.accuracy, result.f1_macro)
@misc{2026tempo,
title = {TEMPO: Time Series Understanding via Discrete Tokenization},
year = {2026},
url = {https://github.com/Forgis-Labs/TEMPO},
}
CC BY-NC-SA 4.0 — free for research and non-commercial use.
Python
77.3%
HTML
22.7%
Discrete tokenization framework for time-series understanding in LLMs. Converts raw signals to FSQ codes via a learned Transformer tokenizer, embeds them as native LLM tokens, and trains with DoRA adapters. Supports classification, anomaly detection, reasoning across sensor, medical, and industrial domains.
14
stars
17
commits
Python
primary language
Jul 28, 2026
updated
TEMPO is a backbone-agnostic framework that turns any decoder-only LLM into a time-series reasoner. Signals are encoded into discrete tokens by a small FSQ-Transformer quantizer, aligned with the LLM's embedding space in a Phase 0 pass, and trained to answer questions and classify patterns in a Phase 1 pass.
[!WARNING] This repository is not yet functional. Model checkpoints and trained weights are not publicly released — you cannot run inference or reproduce results without them. Full release coming soon.
Three components, trained in sequence:
Tokenizer (1.6M params, frozen after pre-training). Maps normalized real-valued samples to discrete codes via FSQ-Transformer with levels = [5,5,5,5] (625 codes, 4:1 compression).
Phase 0: Alignment. LLM frozen; a small projection is trained so that tokenizer code embeddings align with the LLM's input space.
Phase 1: Instruction tuning. LoRA/DoRA adapters trained on downstream tasks (MCQ, captioning, CoT, classification) with signal tokens inlined into the chat template.
git clone https://github.com/Forgis-Labs/TEMPO.git
cd TEMPO
uv pip install -e .
Python >= 3.10. Dependencies listed in pyproject.toml.
import tempo
model = tempo.TEMPO.from_pretrained(
"checkpoints/phase1_best.pt",
fsq_ckpt="checkpoints/fsq_transformer_rope_625_best.pt",
llm_id="Qwen/Qwen3-4B",
use_dora=True,
)
answer = model.analyze(signal, question="Describe the trend in this signal.")
from tempo import TEMPO, TEMPOConfig
from tempo.train import run_pipeline, PipelineConfig
model = TEMPO(TEMPOConfig(llm_id="Qwen/Qwen3-4B", lora_r=32, use_dora=True))
run_pipeline(model, PipelineConfig(batch_size=4, grad_accum=4))
from tempo.eval import evaluate
result = evaluate(model, test_dataset, output_dir="results/phase1",
dataset_name="har", task="classification")
print(result.accuracy, result.f1_macro)
@misc{2026tempo,
title = {TEMPO: Time Series Understanding via Discrete Tokenization},
year = {2026},
url = {https://github.com/Forgis-Labs/TEMPO},
}
CC BY-NC-SA 4.0 — free for research and non-commercial use.
Python
77.3%
HTML
22.7%