Migas-1.5 β Text-Conditioned Time Series Forecasting
Migas-1.5 is a multimodal late-fusion model that combines a frozen univariate time series forecaster (Chronos-2) with LLM-generated text context to produce forecasts that respond to narrative signals β particularly for financial and economic time series.
Rewrite the narrative, watch the forecast shift.
Architecture
Migas-1.5 uses gated attention fusion:
- Univariate backbone: A frozen Chronos-2 forecaster produces a base forecast from historical values
- Context summarization: An LLM generates structured summaries with two sections β
FACTUAL SUMMARY:(what happened) andPREDICTIVE SIGNALS:(forward-looking outlook, relative terms only) - Text embedding: Summaries are encoded via a text embedder (FinBERT 768d, Qwen3-Embedding-4B 2560d, or Qwen3-Embedding-8B 4096d) and projected to a shared 512d space
- Gated attention fusion: The time series forecast embedding attends to factual and predictive text embeddings via 4-head cross-attention, modulated by a learned sigmoid gate
- Convex combination: A learned per-point blending of the univariate base forecast and the fused forecast
- Forecast head: The fused representation is decoded to the final prediction
Key components
| Component | Details |
|---|---|
| d_model | 512 |
| Fusion | 4-head cross-attention with sigmoid gating |
| Text projector | 2-layer MLP (Linear -> GELU -> LayerNorm -> Linear -> LayerNorm) |
| TS embedder | ResidualBlock (Linear -> SiLU + skip connection) |
| Convex combination | Learned per-point blending of univariate + fused forecasts |
| Modality dropout | Randomly zeros text embeddings during training (default 0.2) |
Model flow
History -> [Chronos-2 (frozen)] -> base forecast
|
[TS Embedder] -> h_ts (512d)
Text annotations -> [LLM Summarizer] -> FACTUAL SUMMARY + PREDICTIVE SIGNALS
|
[Text Embedder + Projector] -> h_fact, h_pred (512d)
[Gated Cross-Attention Fusion]
h_ts attends to [h_fact, h_pred]
|
[Convex Combination with base forecast]
|
[Forecast Head] -> final prediction
Usage
Basic inference with a pre-computed summary
import pandas as pd
from migaseval import MigasPipeline
# Load model from this repo
pipeline = MigasPipeline.from_pretrained(
"Synthefy/migas-1.5",
device="cuda", # or "cpu"
text_embedder="finbert", # must match training config
)
# Load your data (columns: t, y_t, text)
df = pd.read_csv("your_data.csv")
summary = """FACTUAL SUMMARY:
Oil prices declined steadily over the past month amid weakening demand signals...
PREDICTIVE SIGNALS:
OPEC production cuts expected to tighten supply, likely supporting prices in the near term..."""
forecast = pipeline.predict_from_dataframe(df, pred_len=16, summaries=summary)
Auto-generate summaries with an LLM
Requires ANTHROPIC_API_KEY (recommended) or OPENAI_API_KEY.
from migaseval.summary_utils import generate_summary
summaries = generate_summary(
series_name="Crude Oil WTI",
series=df,
pred_len=16,
llm_provider="anthropic",
n_summaries=9, # ensemble for stability
)
forecast = pipeline.predict_from_dataframe(df, pred_len=16, summaries=summaries)
Live summarization with a local vLLM server
If you have per-timestep text annotations in your data and want the model to summarize them on-the-fly (instead of passing pre-computed summaries), Migas-1.5 can call a local vLLM server to generate the FACTUAL SUMMARY + PREDICTIVE SIGNALS at inference time.
Start a vLLM server:
bash start_vllm.sh
# or manually:
# vllm serve openai/gpt-oss-120b --port 8004
Configure via environment variables (defaults shown):
export VLLM_BASE_URL="http://localhost:8004/v1"
export VLLM_MODEL="openai/gpt-oss-120b"
Then call predict without summaries β the model will use the text column to generate summaries automatically:
# df must have a 'text' column with per-timestep annotations
forecast = pipeline.predict_from_dataframe(df, pred_len=16) # no summaries arg
Ensemble mode
Pass multiple summaries to predict_from_dataframe to get a median-aggregated ensemble forecast β reduces variance from stochastic summary generation:
forecast = pipeline.predict_from_dataframe(df, pred_len=16, summaries=summaries) # list of str
Counterfactual analysis
Rewrite the PREDICTIVE SIGNALS: section to explore "what if" scenarios:
from migaseval.summary_utils import extract_factual
factual = extract_factual(summary) # keep the facts
bearish = f"{factual}\n\nPREDICTIVE SIGNALS:\nDemand destruction accelerating, prices likely to fall further..."
bullish = f"{factual}\n\nPREDICTIVE SIGNALS:\nSupply cuts expected to tighten market, prices likely to recover..."
forecast_bear = pipeline.predict_from_dataframe(df, pred_len=16, summaries=bearish)
forecast_bull = pipeline.predict_from_dataframe(df, pred_len=16, summaries=bullish)
Data format
| Column | Type | Description |
|---|---|---|
t |
str (YYYY-MM-DD) | Date |
y_t |
float | Observed value |
text |
str | Per-timestep text annotation (used for live LLM summarization; not needed if passing pre-computed summaries) |
split |
str (optional) | "context" or "ground_truth" |
Dependencies
torchchronos-forecasting(Amazon Chronos-2)sentence-transformers >= 5.1.1huggingface-hubanthropicoropenai(for summary generation)
Limitations
- Requires an LLM (Anthropic Claude or OpenAI) for automatic summary generation, or pre-computed summaries
- Chronos-2 must be downloadable at inference time (auto-fetched from HuggingFace Hub)
- Text embedder model must match the training configuration (default: FinBERT)
- Primarily evaluated on financial/economic time series
- Prediction horizon fixed at 16 steps (matching training)
Evaluation
Evaluated on held-out test splits (post 2022-12-31) across:
- FNSPID-100 (stock price indices)
- Trading Economics (macroeconomic indicators)
Metrics: MAE, MSE, RMSE, directional accuracy.
Links
- Code & notebooks: Synthefy/synthefy-migas
- Dataset: Synthefy/multimodal_datasets
Model tree for Synthefy/migas-1.5
Base model
amazon/chronos-2