# OpenTSLM: treating a time series as a modality an LLM can be prompted about

> OpenTSLM is a family of time series language models that integrate time series as a native modality into pretrained Llama and Gemma checkpoints, so a model can be prompted in natural language about ECG, EEG and accelerometer data. This looks at the library API, the model access requirements, and what the release state says about using it.

**OpenTSLM/OpenTSLM** — OpenTSLM: Time-Series Language Models for Reasoning over Multivariate Medical Text- and Time-Series Data

- Repository: https://github.com/OpenTSLM/OpenTSLM
- Website: https://www.opentslm.com
- Stars: 1,253 · Forks: 123
- Language: Python
- License: MIT
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/opentslm-opentslm

## The gap the project is filling is modality, not scale

OpenTSLM stands for Time-Series Language Models, and the project description states the problem plainly. Large Language Models have emerged as powerful tools for interpreting multimodal data, for example images, audio and text, often surpassing specialised models. In medicine, they hold particular promise for synthesising large volumes of clinical information into actionable insights and patient-facing digital health applications. Yet a major limitation remains, their inability to handle time series data.

So the intervention is to make time series a native modality of a pretrained language model, rather than bolting a signal encoder onto the side of one. The models are described as a family, and they enable natural-language prompting and reasoning over multiple time series of any length.

The provenance is visible in the files. The SPDX headers in the readme and the project metadata attribute the work to 2025 Stanford University, ETH Zurich, and the project authors, and the author list in the package metadata names researchers from both institutions. The paper is on arXiv with the DOI 10.48550/arXiv.2510.02410, and the project site is opentslm.com. The licence is MIT, and the package version is 0.1.0.

What this is not, judging by the readme, is a product. It is a research code release with a paper, a set of pretrained checkpoints on the Hugging Face Hub, and demo scripts.

## Five task families, and the reasoning outputs they produce

The examples section lists the tasks the models were tested across, and the list is what makes the project concrete.

Human Activity Recognition from 3-axis acceleration data, sleep staging from EEG readings, 12-lead ECG question answering, and time series captioning. The models reason over multiple time series of any length at once, generating findings, captions and rationales in natural language. The images in the readme show an ECG rationale, a HAR rationale and a caption for a multichannel record, and the paper has more.

The demo scripts map onto the task list one for one. There is `01_test_hf_tsqa.py` for Time Series Question Answering, `02_test_hf_m4.py` for M4, the time series captioning task, `03_test_hf_har_cot.py` for Human Activity Recognition with chain of thought, `04_test_hf_sleep_cot.py` for sleep stage classification with chain of thought, and `05_test_hf_ecg_qa_cot.py` for ECG question answering with chain of thought.

The chain-of-thought variants are the interesting ones for an evaluation. A conventional classifier returns a label, and you cannot ask it why. A model that emits a rationale gives a clinician or a researcher something to argue with, which is what makes these models usable in a research setting where the output has to be checked by a human rather than trusted as a score.

The repository also contains a `curriculum_learning.py` at the root, and the package description names curriculum learning for multimodal time series understanding, so the training procedure is part of the release, not just the inference code.

## load_pretrained, a dataset, and a collate function that does the patching

The library surface is small, and the minimal example in the readme is worth reading closely because two of the steps are not obvious.

```python
from opentslm import OpenTSLM
from opentslm.time_series_datasets.TSQADataset import TSQADataset
from opentslm.time_series_datasets.util import extend_time_series_to_match_patch_size_and_aggregate
from torch.utils.data import DataLoader
from opentslm.model_config import PATCH_SIZE

REPO_ID = "OpenTSLM/llama-3.2-1b-tsqa-sp"

# Use CPU or CUDA for inference. MPS does NOT work for pretrained HF checkpoints.
model = OpenTSLM.load_pretrained(REPO_ID, device="cuda" if torch.cuda.is_available() else "cpu")
test_dataset = TSQADataset("test", EOS_TOKEN=model.get_eos_token())

test_loader = DataLoader(
    test_dataset,
    shuffle=False,
    batch_size=1,
    collate_fn=lambda batch: extend_time_series_to_match_patch_size_and_aggregate(
         batch, patch_size=PATCH_SIZE
    ),
)
```

`OpenTSLM` is a factory class for loading pretrained models from the Hugging Face Hub, and its `load_pretrained` method automatically detects the model type and returns the appropriate model instance. The dataset takes the split name and the end-of-sequence token from the model, which is why the model has to be loaded first.

The interesting part is the collate function. `extend_time_series_to_match_patch_size_and_aggregate` is what turns a variable length recording into the fixed patch size the model expects, and it comes from `opentslm.time_series_datasets.util`, while `PATCH_SIZE` lives in `opentslm.model_config`. That is the seam where a time series becomes tokens for the language model, and it is the piece you would need to understand before trusting any output.

Then generation is ordinary: `model.generate(batch, max_new_tokens=200)`, looping over the loader and printing the question, the answer and the output for each sample.

## Model access is gated, and the default model is the small one

The setup section is where an evaluator loses an afternoon if they do not read it first.

OpenTSLM is designed to work with Llama and Gemma models, with Llama 3.2 1B as the default. These models are stored in Hugging Face repositories which may require access permissions. The steps are: request access on the Llama model repository such as meta-llama/Llama-3.2-1B, or on a Gemma repository such as google/gemma-3-270m, and request it from Meta. Then authenticate with Hugging Face by logging in to your account and configuring the CLI with `huggingface-cli login`. Then create an API token in the Hugging Face settings, generate a new token with `read` scope, and copy it for the CLI login.

The tested model list is short and explicit. For Llama there is meta-llama/Llama-3.2-1B, which is the default, and meta-llama/Llama-3.2-3B. For Gemma there is google/gemma-3-270m and google/gemma-3-1b-pt. The readme says other variants may work but have not been extensively tested.

Two practical notes follow from that. The first is that the base models are gated, so a CI runner or a colleague reproducing your work needs their own Hugging Face account with approved access, which is a real friction for reproducibility. The second is the one line in the example that people miss: MPS does not work for pretrained HF checkpoints, so on an Apple Silicon machine the code falls back to CPU, and the inference you get is not the inference you would get on a CUDA box.

## Installing, cloning, and the demo scripts

Installation of the library alone is one command:

```bash
pip install opentslm
```

To run the demos and the finetuning scripts, the documentation asks you to clone the repository and set up the dependencies, and it recommends uv:

```bash
git clone https://github.com/OpenTSLM/OpenTSLM.git


# uv environment management (recommended). Installs uv if it does not exist and creates the virtual environment
command uv > /dev/null || curl -LsSf https://astral.sh/uv/install.sh | sh
uv sync --all-groups
source .venv/bin/activate
```

The pip alternative is `pip install -r requirements.txt`, and that file ends with `-e.`, so it installs the project itself in editable mode. The requirements set recent minimum versions, numpy 2.3.5, pandas 2.3.3, torch 2.9.1, transformers 4.57.3, huggingface-hub 0.36.0, peft 0.18.0, wfdb 4.3.0 and open-flamingo, so the environment is a research environment rather than a light one.

The demo scripts are then run directly:

```bash
# Run any of the demo scripts
python demo/huggingface/01_test_hf_tsqa.py
python demo/huggingface/02_test_hf_m4.py
python demo/huggingface/03_test_hf_har_cot.py
```

Each script downloads the checkpoint from the Hugging Face Hub automatically, loads the corresponding test dataset, runs inference on the evaluation set, and prints model outputs with sample information, and you change the repo id in each file to pick a different checkpoint. The readme notes that the scripts use the OpenTSLM-SP models except for ECG-QA, because they require less VRAM and should run on most hardware.

The rest of the repository follows the same shape: `evaluation/` for evaluation code, `data/` for datasets, `scripts/`, `test/`, `assets/`, and a `uv.lock` for the environment.

## Where OpenTSLM is the wrong tool

Four limits are worth stating.

The first is the release state. The package version is 0.1.0, the repository has no GitHub releases, and the last push was on 2026-07-21. This is research code published alongside a paper, and adopting a 0.1.0 research release as a dependency for anything long-lived means you are pinning a commit and maintaining the patch yourself.

The second is the hardware and access chain. You need a CUDA machine for usable inference speed, a Hugging Face account with approved access to the gated base models, and a checkpoint per task. The MPS limitation means an Apple Silicon developer is testing on CPU unless they have a different machine, which is a poor way to iterate on a model.

The third is the dependency weight. The list includes torch, transformers, peft for parameter-efficient finetuning, open-flamingo, wfdb for reading PhysioNet waveforms, datasets, einops and scikit-learn. Fine for a research workstation, heavy for a service.

The fourth is the domain and the claims. The models are for medical time series and the outputs are findings, captions and rationales that a human is expected to check. The readme frames the contribution as giving an LLM the time series modality, not as replacing a validated clinical model, and any evaluation should keep that distinction in view: a rationale is an explanation generated by the model, and it is not evidence that the model is right.

If your requirement is a trained classifier with a fixed label set and a probability you can calibrate, a specialised model with a validation study behind it is the better tool, and this project is not trying to be that.

## MIT with REUSE metadata, and a project with a paper behind it

The licensing and provenance paperwork is thorough, which is unusual and welcome for a research release.

Every file in the repository shown here carries an SPDX header with the copyright line for 2025 Stanford University, ETH Zurich and the project authors, and the SPDX-License-Identifier of MIT. There is a `LICENSE.md` at the root, a `LICENSES/` directory, a `REUSE.toml`, and the `reuse` tool in the dev dependency group, which is the tool that checks that every file carries its licence information. There is a `CONTRIBUTORS.md` with the full author list, a `CITATION.cff` for citation metadata, and `.linkspector.yml` for link checking in CI. The static analysis workflow badge in the readme is for a separate repository path, and the repository also has a `.python-version` file, so the interpreter is pinned.

The manifest requires Python 3.12 or later, and the package description names curriculum learning for multimodal time series understanding with large language models.

For the maintenance picture, the facts are simple: no GitHub releases, a 0.1.0 version, and a last push on 2026-07-21. For a research group that wants to reproduce or extend the paper's models, that is workable, since the checkpoints are on the Hub and the paper describes the method. For a production deployment, it is not, and the honest summary is that this is an open research artefact released under a permissive licence, not a maintained library.

## Conclusion

OpenTSLM fits a research team in medical signal analysis that wants to prompt a pretrained language model about ECG, EEG or activity recordings, and that wants the chain-of-thought variants rather than a classifier with a fixed label set. It does not fit a production service that needs a stable version, a supported release stream, or a model it can serve without gated Hugging Face access. It is also the wrong choice on Apple Silicon, since the documentation states that MPS does not work for the pretrained checkpoints. Before you plan around it, check that your hardware can run the checkpoint you need, note that the demo scripts use the smaller OpenTSLM-SP models because they need less VRAM, and read the paper, since the version in the repository is 0.1.0 with no GitHub releases.

## FAQ

### How do I install OpenTSLM?

Run `pip install opentslm` for the library. To run the demos and the finetuning scripts, clone the repository and set up the environment with `uv sync --all-groups` as recommended, or `pip install -r requirements.txt`, which includes the project in editable mode. Python 3.12 or later is required.

### Which base models does OpenTSLM work with?

Llama and Gemma models, with Llama 3.2 1B as the default. The tested models are meta-llama/Llama-3.2-1B, meta-llama/Llama-3.2-3B, google/gemma-3-270m and google/gemma-3-1b-pt. Other variants may work but have not been extensively tested, and the base repositories require requesting access from Meta.

### How do I load a pretrained OpenTSLM model?

Use the factory class: `model = OpenTSLM.load_pretrained(REPO_ID, device="cuda" if torch.cuda.is_available() else "cpu")`. The load_pretrained method automatically detects the model type and returns the appropriate model instance, and the demo scripts in demo/huggingface/ do the same thing for each task.

### Can OpenTSLM run on an Apple Silicon Mac?

The readme states in the quickstart that MPS does not work for pretrained HF checkpoints, so the example selects CUDA when available and CPU otherwise. An Apple Silicon machine therefore runs the models on CPU, which is considerably slower than a CUDA host.

### What licence is OpenTSLM released under?

MIT. The files carry SPDX headers attributing 2025 Stanford University, ETH Zurich and the project authors, and the repository includes a LICENSE.md, a LICENSES/ directory and a REUSE.toml, with the reuse tool in the dev dependencies to keep that metadata complete.

## Sources

- [Issues](https://github.com/OpenTSLM/OpenTSLM/issues)
- [License: MIT](https://github.com/OpenTSLM/OpenTSLM/blob/main/LICENSE)
- [OpenTSLM/OpenTSLM on GitHub](https://github.com/OpenTSLM/OpenTSLM)
- [Project website](https://www.opentslm.com)
- [README](https://github.com/OpenTSLM/OpenTSLM/blob/main/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/opentslm-opentslm
