DealTracker - Introduction
About DealTracker
DealTracker is a tool that took me several years to develop. It's my most accomplished personal project, so if you were to only know one, this should be it. It's a system that automatically finds the best deals published on second-hand listing sites, available to everyone.
You can check out my website at the following address: https://www.dealtracker.org.
Technologies Implemented
DealTracker relies on a multi-part architecture:
Fine-tuning vision models to identify specific objects among millions of diverse images
Solving this non-trivial problem took me two years, and 200,000 manual annotations.
The model is a 146-class image classifier based on a stacked ensemble of 4 architectures from timm, whose logits are fused by two meta-model layers. The architecture is trained with an iterative active learning pipeline. Each model, base predictors or meta-model, is optimized with Optuna.
To ensure the relevance and diversity of annotated examples, I select the unannotated images where the model is most uncertain, then apply a diversity selection algorithm (farthest-first traversal on embeddings).
To handle class imbalance, I used:
- Focal Loss
- A custom evaluation metric specific to the problem
- Aggressive data augmentation (AugMix, rotation, perspective, color jitter...).
Everything was developed with PyTorch, at a low level. The GPU worker runs in a separate process (aioprocessing.AioQueue) with hot model swapping, explicit memory management, and backpressure handling in the pipeline via semaphore.
Production Inference
The inference pipeline processes listings continuously through a multi-step asynchronous architecture:
- Image retrieval
- GPU inference (PyTorch + TensorRT)
- Multi-image aggregation
- Linguistic rule filtering
- Calculation of a listing's attractiveness relative to the median price of an object
The pipeline throughput is 450 listings per minute on an RTX 3060 Ti.
Data Service, Front-end
To serve data at high performance, I set up a FastAPI.
On the Front-end side, I wanted the best possible performance, so I went with NextJS (app router), with an output consisting solely of static files. I put a lot of work into the interface and SEO optimization.
This part required me to work on various topics:
- Geographical filtering with Geopandas
- API design to limit database calls
- Optimizing information serving speed at the cache level
- Defining data flows between front-end and backend
- Studying the best available front-end libraries