TimeBraid logo

TimeBraid-2.5B

TimeBraid: Unifying Time Series and Language for Understanding and Forecasting

Project · GitHub · Examples · Alignment Dataset · SFT Dataset

TimeBraid combines numerical time series and natural language in one model. It can explain an observed series in words and predict future values using both its history and relevant text.

Highlights

  • Understand time series. Describe trends, answer questions about temporal patterns, and compare multiple series in natural language.
  • Forecast with context. Combine observed values with text about events or conditions to produce numerical forecasts.
  • Use one interface. Supply numeric arrays and messages through the Hugging Face processor; choose text output or a forecast for one selected series.

Model overview

Property TimeBraid-2.5B
Total parameters 2.5 billion
Language backbone Qwen3-1.7B
Time-series backbone TimesFM 2.5 200M
Architecture Mixture-of-Transformers with global residual attention
Weight precision BF16
Outputs Natural-language responses or numerical forecasts

The checkpoint includes both backbones, fusion layers, tokenizer, and processor. A separate TimesFM checkpoint is not needed for inference.

Exact parameter counts

The complete model contains 2,497,200,576 unique parameters: 1,720,574,976 language, 231,289,280 time-series, and 545,336,320 fusion parameters. This includes frozen parameters and counts shared embedding/output weights once.

Quickstart

Use Linux, Python 3.11, CUDA 12.8, and a FlashAttention-2-compatible NVIDIA GPU. The examples below load the model once and reuse it for each task.

Install the tested dependencies

Install the CUDA development toolkit, including nvcc, before these commands. Install Torch before building FlashAttention.

python -m pip install --upgrade pip setuptools wheel packaging psutil ninja
python -m pip install numpy==2.1.3
python -m pip install torch==2.10.0 --index-url https://download.pytorch.org/whl/cu128
MAX_JOBS=4 python -m pip install flash-attn==2.8.3 --no-build-isolation
python -m pip install accelerate==1.11.0 huggingface-hub==0.36.2 \
  safetensors==0.5.3 tokenizers==0.22.2 transformers==4.57.6

If a matching FlashAttention wheel is unavailable, installation builds it from source. For an H100-only build, prefix its installation command with FLASH_ATTN_CUDA_ARCHS=90.

Load the model

The repository includes custom TimeBraid inference code, loaded with trust_remote_code=True.

import torch
from transformers import AutoModelForCausalLM, AutoProcessor

repo_id = "XinyueWangg/TimeBraid-2.5B"
processor = AutoProcessor.from_pretrained(
    repo_id, trust_remote_code=True, fix_mistral_regex=False,
)
model = AutoModelForCausalLM.from_pretrained(
    repo_id,
    trust_remote_code=True,
    dtype=torch.bfloat16,
    attn_implementation="flash_attention_2",
    device_map={"": "cuda:0"},
).eval()

def generate(inputs):
    device_inputs = {
        key: value.to(model.device) if isinstance(value, torch.Tensor) else value
        for key, value in inputs.items()
    }
    with torch.inference_mode():
        output = model.generate(
            **device_inputs, max_new_tokens=512, do_sample=False,
        )
    return processor.post_process_generation(output, model_inputs=inputs)

How time-series inputs appear to the model

Pass the original numeric values through timeseries. For each input series, TimeBraidProcessor computes its length, mean, and population standard deviation, normalizes the numeric values, and adds a stats block to the model's prompt. For example, input [1.0, 2.0, 3.0] is represented as:

Series 1: <stats>len=3, mean=2, std=0.816497</stats> <ts></ts>

The <ts></ts> pair marks where the numeric series enters the model; the values are carried separately in the processor's tensor inputs. With multiple series, the processor adds one stats block and time-series marker per series. The code examples below supply numeric arrays directly, so you do not need to write these tags in messages yourself.

1. Understand observed time series

Provide a question and the observed values. Without horizon, the model returns text. This illustrative example pairs CPU utilization with request latency for the same service.

inputs = processor(
    messages=[{
        "role": "user",
        "content": "Series 1 is CPU utilization (%) and Series 2 is p99 request latency (ms) for the same service. In two sentences, describe how latency changes as CPU usage rises and whether the operator should investigate before the next traffic peak.",
    }],
    timeseries=[
        [46.0, 48.0, 51.0, 55.0, 58.0, 62.0, 66.0, 70.0, 74.0, 78.0, 82.0, 86.0],
        [118.0, 120.0, 119.0, 121.0, 123.0, 122.0, 126.0, 131.0, 142.0, 168.0, 220.0, 340.0],
    ],
    return_tensors="pt",
)
result = generate(inputs)
print(result["content"])

Example output:

The latency in Series 2 increases as the CPU utilization in Series 1 rises, indicating a potential correlation between higher CPU usage and increased latency. The operator should investigate before the next traffic peak to understand the underlying cause and mitigate any potential performance issues.

2. Forecast with textual context

This illustrative weekly-demand example includes information about an upcoming promotion. horizon=6 requests six future values.

inputs = processor(
    messages=[
        {"role": "system", "content": "You analyze weekly product demand."},
        {"role": "user", "content": "The values are weekly product demand in units. A promotion is scheduled to start at the first forecast step. Forecast the next 6 weekly values for inventory planning."},
    ],
    timeseries=[[200.0, 208.0, 215.0, 205.0, 198.0, 210.0, 218.0, 207.0, 201.0, 212.0, 220.0, 209.0]],
    horizon=6,
    return_tensors="pt",
)
result = generate(inputs)
print([round(value, 3) for value in result["timeseries"]["values"]])

Example output, rounded to three decimal places:

[204.359, 211.113, 217.502, 210.482, 204.328, 209.075]
Multiple input series, one forecast target

Both series are available as input; target_series_index=1 selects the second series as the forecast target. Indices start at zero.

inputs = processor(
    messages=[{
        "role": "user",
        "content": "Use both inputs and forecast the selected target series.",
    }],
    timeseries=[[100.0, 102.0, 104.0, 106.0], [10.0, 11.0, 13.0, 16.0]],
    target_series_index=1,
    horizon=4,
    return_tensors="pt",
)
result = generate(inputs)
print(result["timeseries"]["values"])

Evaluation

Selected results reported in the paper for the TimeBraid-2.5B setting, compared with the unified time-series/language baseline ChatTime-7B. Higher is better for ↑; lower is better for ↓. The paper provides the full comparisons and evaluation protocols.

Area Benchmark Metric TimeBraid-2.5B ChatTime-7B
Understanding TSAQA Overall score (%) ↑ 78.31 38.38
Understanding TimeSeriesExam Accuracy (%) ↑ 60.05 41.94
Understanding CaTS-Bench, human-rewritten split DeBERTa-F1 ↑ 0.708 0.371
Forecasting CGTSF Macro MSE ↓ 0.415 1.367
Forecasting CAF Normalized CRPS ↓ 0.235 0.345
Forecasting Ctrl-F Sibling retrieval Top-1 (%) ↑ 40.67 33.33

These are selected results from the paper's 2.5B experiments. The TimeSeriesExam and CaTS-Bench rows were produced by a separately trained checkpoint; the weights in this repository are not the source of those two rows. The release checkpoint has not been rerun across all six benchmarks, so this table is not a new evaluation of the downloadable weights.

Usage notes

Task Input Output
Text generation messages result["content"]
Time-series understanding messages and timeseries; omit horizon result["content"]
Forecasting messages, timeseries, and horizon result["timeseries"]["values"]
  • Pass numeric arrays through timeseries; the processor handles normalization and time-series formatting. Forecast values are returned on the input target's original scale.
  • Forecasting returns one target series. For multiple inputs, set target_series_index explicitly; a single input defaults to index 0.
  • Run one request at a time on one CUDA device with FlashAttention 2. Use greedy decoding (do_sample=False), a fresh prompt, and one returned sequence.
  • horizon controls the number of future numerical values; max_new_tokens controls the text-generation budget.

Training data

We plan to share two companion datasets in a common messages format:

The dataset repositories currently contain README pages only. We are reviewing licensing and redistribution terms before deciding what data can be shared. Stay tuned.

Citation

@misc{wang2026timebraidunifyingtimeseries,
      title={TimeBraid: Unifying Time Series and Language for Understanding and Forecasting},
      author={Xinyue Wang and Jiacheng Pang and Kun Zhou and Kexin Zhang and Defu Cao and Fan Feng and Faisal and Songyao Jin and Yan Liu and Biwei Huang},
      year={2026},
      eprint={2609.29792},
      archivePrefix={arXiv},
      primaryClass={cs.CL},
      url={https://arxiv.org/abs/2609.29792},
}

License

The model is released under the Apache 2.0 license. See third-party notices for its underlying components. We are reviewing licensing and redistribution terms for the training data.

Downloads last month
7
Safetensors
Model size
2B params
Tensor type
BF16
·
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Datasets used to train XinyueWangg/TimeBraid-2.5B

Paper for XinyueWangg/TimeBraid-2.5B