mirror of
https://github.com/ruvnet/RuVector.git
synced 2026-07-10 01:38:44 +00:00
chore(release): publish timesfm + ruvector-timesfm 2.2.4 (#613)
timesfm gained quantization/f16/select_device/serde after 2.2.3 was published; bump to 2.2.4 and publish so ruvector-timesfm (new crate, uses those APIs) can depend on it. Adds ruvector-timesfm README. Only ruvector-timesfm depends on timesfm, so the off-workspace-version pin is self-contained. Co-authored-by: ruvnet <ruvnet@gmail.com>
This commit is contained in:
parent
1329db1f24
commit
48dbbb663c
3 changed files with 87 additions and 3 deletions
|
|
@ -1,6 +1,7 @@
|
|||
[package]
|
||||
name = "ruvector-timesfm"
|
||||
version.workspace = true
|
||||
# Tracks timesfm 2.2.4 (the version carrying the APIs this crate uses).
|
||||
version = "2.2.4"
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
license.workspace = true
|
||||
|
|
@ -9,6 +10,7 @@ repository.workspace = true
|
|||
description = "RuVector integration for the TimesFM time-series foundation model: a high-level quantile Forecaster, forecast-band anomaly detection, and TimesFM-driven early-stopping for optimization sweeps (ADR-191)"
|
||||
keywords = ["timesfm", "forecasting", "time-series", "anomaly", "ruvector"]
|
||||
categories = ["science", "algorithms"]
|
||||
readme = "README.md"
|
||||
publish = true
|
||||
|
||||
[lib]
|
||||
|
|
@ -39,7 +41,7 @@ cuda = ["candle", "timesfm/cuda", "candle-core/cuda", "candle-nn/cuda"]
|
|||
metal = ["candle", "timesfm/metal", "candle-core/metal", "candle-nn/metal"]
|
||||
|
||||
[dependencies]
|
||||
timesfm = { path = "../timesfm", version = "2.2.3" }
|
||||
timesfm = { path = "../timesfm", version = "2.2.4" }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde_json = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
|
|
|
|||
79
crates/ruvector-timesfm/README.md
Normal file
79
crates/ruvector-timesfm/README.md
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
# ruvector-timesfm
|
||||
|
||||
RuVector-facing integration for the [`timesfm`](https://crates.io/crates/timesfm)
|
||||
TimesFM 1.0 200M time-series foundation model. The base crate is a faithful,
|
||||
parity-validated candle port of the model; this crate wraps it in the things
|
||||
RuVector and ruflo actually call.
|
||||
|
||||
[](https://crates.io/crates/ruvector-timesfm)
|
||||
[](LICENSE)
|
||||
|
||||
---
|
||||
|
||||
## What you get
|
||||
|
||||
| Module | Purpose |
|
||||
|---|---|
|
||||
| [`Forecaster`] | Load weights once, `forecast(series, horizon)` → point + calibrated **p10..p90 quantile bands**; `forecast_batch` for throughput. |
|
||||
| [`anomaly`] | Forecast-band anomaly detection — flag observed points that fall outside their p10/p90 band (host/vector-db telemetry: disk-fill, GPU memory, query load). |
|
||||
| [`sweep::EarlyStopper`] | TimesFM-driven early stopping for optimization sweeps (ADR-191) — kill doomed ruflo/Darwin runs early, with a `min_history` warm-up + confidence gate. |
|
||||
| [`rebuild`] | Forecast an index's recall-drift curve and advise *when* to rebuild an HNSW index — just before the conservative (p10) forecast crosses a recall floor. |
|
||||
| `ruvector-timesfm-forecast` | A JSON-in/JSON-out CLI = the `time_series_forecast` MCP tool entry point. |
|
||||
|
||||
## Feature gating
|
||||
|
||||
The numeric path is behind the **`candle`** feature (and `cuda`/`metal`, which
|
||||
imply it), mirroring `timesfm`. Without it, only the plain data types compile, so
|
||||
a stock `cargo build` stays light.
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
ruvector-timesfm = { version = "2.2", features = ["candle"] }
|
||||
```
|
||||
|
||||
## Quick start
|
||||
|
||||
```rust,ignore
|
||||
use ruvector_timesfm::Forecaster;
|
||||
|
||||
// Pick CPU / cuda / metal via the TIMESFM_DEVICE env var.
|
||||
let f = Forecaster::load("/path/timesfm.safetensors", timesfm::select_device()?)?;
|
||||
|
||||
let forecast = f.forecast(&history, 64)?; // 64-step forecast
|
||||
let (lo, mid, hi) = (forecast.p10(), forecast.p50(), forecast.p90());
|
||||
|
||||
// Forecast-band anomaly detection on an observed window:
|
||||
let report = f.detect_anomalies(&history, &observed, 0)?;
|
||||
println!("{} anomalies", report.n_anomalies);
|
||||
```
|
||||
|
||||
## Precision knobs
|
||||
|
||||
| API | Use | Tradeoff (measured, real weights) |
|
||||
|---|---|---|
|
||||
| `Forecaster::load` (f32) | default | reference accuracy; CPU ~45 ms, cuda ~4 ms / forecast |
|
||||
| `Forecaster::load_f16` | GPU latency | ~1.6× faster batched on GPU; rel error ~2e-2 (CPU f16 is slower) |
|
||||
| `Forecaster::load_quantized(Quant::Q8_0)` | edge memory | ~4× smaller (~212 MB), rel error ~3e-3; CPU slower (dequant) |
|
||||
| `Quant::Q4_0` | tightest memory | ~7× smaller (~112 MB), rel error ~3e-2 |
|
||||
|
||||
## MCP tool
|
||||
|
||||
`ruvector-timesfm-forecast` reads a JSON request on stdin and writes a forecast
|
||||
on stdout — the shell-out entry point for the RuVector `time_series_forecast`
|
||||
MCP tool:
|
||||
|
||||
```bash
|
||||
echo '{"weights":"/path/timesfm.safetensors","series":[...],"horizon":32}' \
|
||||
| ruvector-timesfm-forecast
|
||||
# → {"horizon":32,"device":"cpu","point":[...],"p10":[...],"p50":[...],"p90":[...]}
|
||||
```
|
||||
|
||||
## Weights
|
||||
|
||||
Weights are not bundled — download `google/timesfm-1.0-200m` from HuggingFace and
|
||||
convert with `timesfm`'s `scripts/convert_weights.py` (PyTorch state_dict →
|
||||
candle safetensors). See the [`timesfm`](https://crates.io/crates/timesfm) crate.
|
||||
|
||||
## License
|
||||
|
||||
Apache-2.0.
|
||||
|
|
@ -1,6 +1,9 @@
|
|||
[package]
|
||||
name = "timesfm"
|
||||
version.workspace = true
|
||||
# Pinned ahead of the shared workspace version: this crate gained the
|
||||
# quantization / f16 / select_device APIs after timesfm 2.2.3 was published.
|
||||
# Only ruvector-timesfm depends on it (and tracks the same 2.2.4).
|
||||
version = "2.2.4"
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
license.workspace = true
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue