A hybrid recommendation engine, built on Facebook's DLRM (Deep Learning Recommendation Model) architecture. The system combines on-chain user behaviour (staking history, connections) with product interaction data to predict ratings and surface personalised recommendations.
The model is an adaptation of Facebook's DLRM that handles both sparse and dense input features:
| Feature type | Examples | Processed by |
|---|---|---|
| Sparse (categorical) | user, product, brand, category | Embedding layers |
| Dense (continuous) | connections, amount staked, locked days, is-weekend | Bottom MLP |
The bottom MLP projects dense features into the same embedding space as the sparse features. A feature interaction layer then computes pairwise dot products across all feature embeddings. The resulting interaction vector is passed through the top MLP, which outputs a rating class (1–5) using cross-entropy loss with focal weighting to handle class imbalance.
Content-Based — recommends products similar to what a user has rated highly, based on product features (category, brand, description).
Collaborative Filtering — finds users with similar taste and recommends what they liked. Works well with sufficient rating history but suffers from the cold-start problem for new users.
Hybrid (DLRM) — combines both with on-chain user context (staking amount, network connections, lock duration) to provide recommendations even for cold-start users.
DLRM/
├── data/ # Datasets
│ ├── connections.csv # On-chain user connection/staking data
│ ├── users.csv # User aggregate stats
│ ├── dlrm_recommendation_test.csv # Combined rating + blockchain dataset
│ ├── dlrm_recommendation_preproc_test.csv/pkl # Pre-processed test split
│ └── amazon_grocery_and_gourmet_food_products.csv # Product catalogue
├── models/
│ ├── dlrm_recommender_export.pth # Trained DLRM model weights
│ └── dlrm_baseline_recommender_export.pkl # Baseline collaborative filter
├── dlrm/
│ ├── dlrm.py # DLRM model (MLP, feature_interaction, DLRM class)
│ ├── gpu_training.py # Hyperparameter grid-search script (GPU)
│ └── webapp.py # Streamlit demo application
├── nbs/ # Jupyter notebooks (nbdev source of truth)
│ ├── index.ipynb # Project overview
│ ├── dlrm_pytorch.ipynb # Main training notebook
│ ├── Hyperparameters_tuning_gpu.ipynb # GPU hyperparameter sweep
│ └── Web Application.ipynb # Webapp notebook
└── _docs/ # Auto-generated documentation (Quarto/nbdev)
- Python ≥ 3.7
- PyTorch (CPU or CUDA)
- fastai v2
pip install fastai streamlit pandas pillow category_encoders tqdmTo install this project as a local package:
pip install -e .Or install directly from GitHub:
pip install git+https://github.com/santamm/dlrm_recommendations.gitTraining is driven by the Jupyter notebooks under nbs/. The notebooks are the canonical source and the Python modules under dlrm/ are auto-generated from them via nbdev.
Open and run nbs/dlrm_pytorch.ipynb end-to-end. It:
- Loads and merges
dlrm_recommendation_test.csvwith the on-chain user data - Pre-processes categorical and continuous features with fastai
TabularPandas - Defines the
DLRMmodel with configurable MLP architectures and embedding dimension - Trains with
FocalLossFlat(handles rating imbalance) and saves the model
The trained model is saved to models/dlrm_recommender_export.pth.
For GPU-accelerated training with a parameter grid, run:
python dlrm/gpu_training.pyThis script loads the pre-processed data from data/dlrm_recommendation_preproc.pkl and sweeps over embedding dimensions, MLP architectures, learning rates, and dropout values. Results are logged to CSV.
Alternatively, run the equivalent notebook:
nbs/Hyperparameters_tuning_gpu.ipynb
| Parameter | Default | Description |
|---|---|---|
embedding_dim |
32 | Dimension of all sparse feature embeddings |
bot_mlp_arch |
(dense_size, 32) |
Bottom MLP layers (dense → embedding space) |
top_mlp_arch |
(128, 64, num_classes) |
Top MLP layers (interactions → rating logits) |
dropout |
0.2 | Dropout probability in both MLPs |
gamma |
3.0 | Focal loss gamma (higher = more focus on hard examples) |
Inference uses the fastai Learner API with a test dataloader. Example from a notebook or script:
from fastai.tabular.all import *
from dlrm.dlrm import DLRM
# Load pre-processed data and rebuild dataloaders
to = torch.load("data/dlrm_recommendation_preproc.pkl")
dls = to.dataloaders(bs=128)
# Re-instantiate model with the same architecture used during training
embedding_dim = 32
emb_dims = [to.items[col].nunique() + 1 for col in dls.cat_names]
model = DLRM(emb_dims, embedding_dim, len(dls.cont_names),
(len(dls.cont_names), embedding_dim), (128, 64, len(dls.vocab)),
num_classes=len(dls.vocab))
learn = Learner(dls, model, loss_func=FocalLossFlat(gamma=3.0))
learn = learn.load("dlrm_recommender_export") # loads from models/
# Run predictions on a test batch
_, test_dl = dls
preds, _ = learn.get_preds(dl=test_dl)The Streamlit webapp showcases three recommendation scenarios:
| Demo | Scenario |
|---|---|
| User near a shop | Given a user and a brand, recommend the highest-rated products from that brand |
| Best for the weekend | Recommend products the user hasn't rated yet, ranked by predicted rating |
| Cold Start | Recommend popular, highly-rated products for a brand-new user with no history |
From the repository root:
streamlit run dlrm/webapp.pyThe webapp loads the product catalogue, pre-processed dataloaders, and trained model on startup. Make sure the following files are present before launching:
data/amazon_grocery_and_gourmet_food_products.csv
data/dlrm_recommendation_preproc.pkl # generated by the training notebook
models/dlrm_recommender_export.pth
dl_hybridRecc.webp
Open http://localhost:8501 in your browser, select a demo from the sidebar, choose a user (and brand, if applicable), then click Run demo.
- DLRM: An Advanced Open Source Deep Learning Recommendation Model — Facebook AI
- DLRM paper (arXiv)
- Deep Learning Recommendation Models — A Deep Dive — informal blog introduction
- Neural Collaborative Filtering (2017)
- fastai tabular docs
Apache 2.0 — see LICENSE.
