All projects

Infrastructure · 2025

Market Pulse

A high-throughput streaming pipeline that ingests live financial news, runs quantized FinBERT sentiment and entity extraction, and computes a real-time sentiment shock signal.

GoPythonKafkaONNXFinBERTPrometheusStreamlit

Problem

Financial-news streams are noisy, duplicated, and bursty. Running model inference directly on every item wastes compute and makes backpressure difficult to see.

Why I built it

I wanted to understand the boundary between high-throughput stream processing and CPU-bound model inference, then make that boundary observable under load.

Architecture

  • Go ingestion fans out concurrent fetches (GDELT, RSS, replay) into a channel and produces to the news.raw Kafka topic.
  • A Go processing consumer group deduplicates via content hash, normalizes, and filters before publishing to news.processed — so the model never runs on junk.
  • Python worker processes (not threads) join an inference consumer group, run INT8-quantized FinBERT, and feed a rolling z-score shock detector observable in Grafana.

Implementation

  • Go services ingest, normalize, deduplicate, and publish versioned events through Kafka.
  • A Python consumer group runs quantized ONNX FinBERT inference across worker processes.
  • Prometheus metrics, Grafana dashboards, and an offline replay mode make the full path inspectable without external API keys.

Experiments

  • Replay mode exercises the same pipeline as live ingestion so throughput and failure behavior can be reproduced.
  • A stress generator varies arrival rate and consumer count to expose queue growth and backpressure.

What I learned

  • A cheap filtering stage before inference reduces both cost and operational noise.
  • Kafka works well as a language boundary when schemas are treated as the shared API.

Next questions

  • How should inference workers be autoscaled from lag without oscillating?
  • How should model-version changes be replayed and compared against historical traffic?