Sitemap
Phillip Wenig

Phillip Wenig

Machine Learning and Software Engineering

System One Time Series Models

8 min read5 days ago

--

Ask your time series questions, get calibrated answers.

TL;DR

  • The problem: A single test run can produce 200 sensor channels across five million time steps, which is far too much for anyone to check by hand.
  • What Justin is: A model that reads multivariate time series, takes a question in natural language and assigns probabilities to the possible answers.
  • How it works: Timestral encodes the time series and MiniLM encodes the question. A fusion layer combines the two.
  • In practice: It finds the root cause of an incident and the metric that deviated most, and shows where in the data it happened.
  • The vision: Justin’s answers become automated decisions. It signs off a test run, stops a test, rolls back a release or calls the right specialist.
  • Current state: Both encoders are small and real-world data is scarce. We build synthetic data and trace the information flow through the network to fix tasks that train poorly.
  • Next: More real data and a bigger model.
  • Try it: An open-source version is on Hugging Face and runs from Python or Rust.
  • Work with us: We are looking for industry partners who have time-series data and want to put Justin into their workflow.
Press enter or click to view image in full size
Photo by Dynamic Wang on Unsplash

An engineer stands in the test hall after a new turbo motor has just finished its run on the bed. The test cost several thousand dollars in special fixtures, instrumented parts, and a carefully controlled setup. Now the data is in: 200 sensor channels across five million time steps. The engineer is supposed to look at the readings and confirm that everything is fine. They cannot. The volume is too large, the patterns too subtle, and the cost of missing something too high to rely on manual inspection.

A specialist classifier could catch one known failure mode, but every new failure mode would need its own model, its own training data, and its own validation cycle. What would be useful is something with native general time series understanding, able to answer whatever typed questions the engineer defines on the fly, without building a new specialist for each one.

System One

System One models exist because many real software tasks need fast, structured decisions rather than open-ended text. Large language models are slower and more expensive, generate free-form output that code must parse and validate, and do not natively return well-calibrated probabilities over a fixed answer set. A purpose-built classifier or specialized model is also limited: it hard-codes one task and answer space, so every new question requires new training or engineering.

A general System One model addresses this by taking unstructured input plus a set of typed questions defined at inference time and returning calibrated probabilities over only the answers you declared, all in a single fast pass. This keeps the answer space open while guaranteeing valid, probabilistic, low-latency output that software can branch on directly.

The same motivation applies to time series. Sensors, financial feeds, industrial telemetry, and operational metrics continuously produce sequences that drive downstream decisions such as alerts, routing, risk limits, control actions, or escalations. In these settings an answer cannot be free-form text; it must be a type-safe, immediately usable response that code can act on without further parsing or interpretation.

Get Phillip Wenig’s stories in your inbox

Join Medium for free to get updates from this writer.

A time-series System One model gets rid of text generation entirely and is more general than any fixed classifier, so it is a natural fit for these use cases: it accepts a sequence plus typed questions defined on the fly and returns structured probabilities in one pass, remaining reusable across many decision points without the latency, cost, or rigidity of the alternatives.

Justin

Like Jev, Justin time.

What is it?

Justin is the first System One model for time series that I know of. Its inputs are a (multivariate) time series and a question about the timeseries of three possible types: Option, Noul, Location.

Option expects a question with at least two possible answers. Justin will give probabilities to each option for being the correct answer to the question. E.g. Q: “Why did the CPU load increase?”, O: [“increase in requests”, “exhausted database worker pool”, “third party service not reacting”]

Noul expects a yes/no question and assigns a probability that the question is true. E.g. Q: “Is there an anomaly in the memory channel?”

Location expects a question about the channel and time span of a certain event and returns the most likely locations in a time series. E.g. Q: “Where is the level shift happening?”

How does it work?

Justin takes two inputs: a multichannel time series and a question about it. Each goes to its own encoder. The series goes to Timestral, a compact 5M-parameter time-series encoder from Mistral AI that cuts every channel into short patches and turns each patch into a vector. The question goes to MiniLM, a small sentence encoder that turns the text into word-level vectors. The two encoders don’t run independently: before Timestral reads the series, the question adjusts each of its layers (a technique called FiLM). That way the model already knows what it is looking for while it encodes the data.

Justin’s architecture

A fusion layer then lets the question’s words attend to the encoded patches and pull out the evidence that matters, condensed into a single answer vector. The question’s type decides what comes out. A choice question gets the best option and a probability for each one. A noul (yes/no) question gets the probability of yes. Location questions skip the fusion step. They read both encoders directly, because they need to point at a specific place in the series rather than summarize it. They return the channel and the time span where the thing asked about happens, or say that it isn’t there.

What can it do?

To see what this looks like in practice, take an incident from the Sock Shop microservice demo that Justin never saw during training: 40 metrics (CPU, memory, workload and latency for every service), recorded once a second for almost three minutes, with a network delay injected into the user service partway through.

Justin answering questions

We give Justin the whole window and ask it two questions about the same data, changing only the text. Asked which service is the root cause, it picks user with 99.7%. Asked which of four candidate metrics deviated most once the fault hit, it chooses orders_latency-90 with 98.9%. The orders service calls user, so its latency climbs with it. Nothing is retrained or configured per question: the questions and their options are plain text, and every answer comes with a probability, so you can tell a confident answer from a guess.

Justin finding locations

Some questions aren’t about what happened but where. For those, Justin has a separate location head. It splits every metric into short patches, 32 seconds each here, and points at the one the question asks about, or says the thing isn’t there. On the same Sock Shop window, asked to locate the onset of the spike in orders_latency-90, it points at seconds 100 — 132 of that metric with 98.5%, the patch where the latency jumps. Asked the same about front-end_latency-90, it again picks the right metric and patch, but with only 63%: the remaining 36% goes to the same moment in orders_latency-90, whose spike starts slightly earlier and looks much alike. The probabilities show this hesitation directly, so the answer doesn’t look more certain than it is. In both cases it puts less than 0.1% on the spike not being there.

Automated Possibilities

Back in the test hall, the engineer no longer has to read the data alone. While the turbo motor is still running on the bed, Justin watches all 200 channels and answers the questions a seasoned test engineer would ask: Is the engine behaving the way this test plan expects? Which component is behind any change: the compressor, the bearings, the cooling loop, or the instrumentation itself? Where in the run did it start, and on which sensor? Those answers turn into decisions while the test is underway. A clean run is signed off when the motor stops, and the next engine moves onto the bed the same afternoon. A bearing temperature that begins to drift is caught minutes into the run, and the test stops before an expensive prototype is damaged. When a thermocouple comes loose, the run continues, the faulty channel is set aside, and the technician gets a note naming the sensor to replace, instead of the whole test being repeated. When a real issue appears, the right specialist receives the moment it started, the channels involved and the component they point to. The engineer still makes the calls that matter, but now starts from answers rather than five million time steps.

Current state

The current Justin is deliberately small. Both encoders are small on purpose. Timestral has about five million parameters, and MiniLM-L6 has six layers. That makes Justin fast and cheap enough to run on a laptop or next to a test bench, but it limits how much the model can understand and how fine a pattern it can resolve. The larger limit is data. Real-world recordings that have known faults, incidents and outcomes are rare, and most of them never leave the companies that collect them. So we build synthetic data to fill the gaps: series with faults we inject and control, paired with questions whose answers we know. Not every task trains equally well. Where one falls behind, we follow the information through the network, layer by layer and from head to head, to see where it gets lost. Then we fix the architecture or the training signal at that point instead of just adding more data. The next step is clear: more real data and a bigger model. Larger encoders and a wider fusion layer will let Justin read longer runs, more channels and subtler patterns, and real recordings from industry will ground it in the problems engineers actually face.

Try it yourself

There is an open-source version of Justin. The weights are on Hugging Face at ppweni/justin-timestral-minilm, and you can run them from Python or Rust. In Python, Justin.from_pretrained loads the model in one line. In Rust, the native implementation runs without a Python runtime, so Justin can sit directly in a monitoring pipeline, a deployment system or a test-bench controller and act on its own answers. Load your own metrics, ask a question in plain English and let Justin decide what happens next: sign off a run, stop a test, roll back a release or call the right specialist. What Justin learns depends on the data it sees, and that is where we need you. If you run test benches, operate production systems or collect sensor data from machines, and you have recordings with known faults, incidents or test outcomes, we would like to work with you. Together we can train Justin on your domain, test it on your hardest cases and connect it to the systems where its decisions take effect. Get in touch and let’s make sure no engineer is left alone with five million time steps again.

--

--

Written by Phillip Wenig

Machine Learning and Software Engineering