--- license: apache-2.0 library_name: synthefy-migas pipeline_tag: time-series-forecasting tags: - pytorch - multimodal - financial - text-augmented --- # 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**: 1. **Univariate backbone**: A frozen Chronos-2 forecaster produces a base forecast from historical values 2. **Context summarization**: An LLM generates structured summaries with two sections — `FACTUAL SUMMARY:` (what happened) and `PREDICTIVE SIGNALS:` (forward-looking outlook, relative terms only) 3. **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 4. **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 5. **Convex combination**: A learned per-point blending of the univariate base forecast and the fused forecast 6. **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 ```python 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`. ```python 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 bash start_vllm.sh # or manually: # vllm serve openai/gpt-oss-120b --port 8004 ``` Configure via environment variables (defaults shown): ```bash 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: ```python # 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: ```python 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: ```python 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 - `torch` - `chronos-forecasting` (Amazon Chronos-2) - `sentence-transformers >= 5.1.1` - `huggingface-hub` - `anthropic` or `openai` (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](https://github.com/Synthefy/synthefy-migas) - **Dataset**: [Synthefy/multimodal_datasets](https://huggingface.co/datasets/Synthefy/multimodal_datasets)