Latent Gated Fusion (LGF) — Bridging Knowledge Graphs and LLM Latent Spaces for Cross-Domain Recommendation
A dual-stream recommender that fuses a Knowledge-Graph stream (LightGCN over the user–item bipartite graph, items warm-started by TransR pre-training over a metadata-derived KG) and a frozen-LLM semantic stream (e5-large, 2-layer MLP projector) via a per-item learnable gate. Trained end-to-end with BPR loss, evaluated on Amazon-Reviews-2023 Books (5-core) with Recall@10 and NDCG@10.
The project's central claim: a learned per-item α ∈ (0, 1) outperforms KG-only, LLM-only, and uniform-mix baselines, especially on cold-start items.
| Doc | What's in it |
|---|---|
docs/CF_project.pdf |
Original project specification (architecture, datasets, pipeline, eval) |
docs/architecture.jpeg |
DualKGAT architecture diagram |
docs/setup.md |
Complete developer guide — every script, module, config, flag |
Start with docs/setup.md if you want to run, modify, or navigate the code.
# 0. (Optional) wandb login for live dashboards. Skip with --no-wandb or
# WANDB_MODE=disabled if you don't want cloud logging.
.venv/bin/wandb login
# 1. Bootstrap (creates .venv with Python 3.11, installs requirements)
bash scripts/00_lab_setup.sh
# 2. Data (one-time, ~15 min)
bash scripts/01_download.sh
.venv/bin/python -m codes.data.build_index
.venv/bin/python -m codes.data.download
bash scripts/02_build_kg.sh
# 3. Offline LLM embeddings (one-time, ~30 min on A100)
.venv/bin/python -m codes.embeddings.compute_llm_emb \
--model intfloat/e5-large-v2 --prefix "passage: " --batch-size 256
# 4. KG-only TransR warm-start for entity embeddings (~5 min on GPU).
# Precursor: its output (checkpoints/transr_entities.pt) is the initial
# entity_emb table for the main BPR training below.
.venv/bin/python -m codes.training.transr_pretrain --config configs/full_lgf.yaml
# 5a. Train ONE config (~30-60 min on A100)
bash scripts/04_train.sh configs/full_lgf.yaml
# 5b. OR train + eval ALL FOUR ablation configs end-to-end (~3-4 hours on A100)
bash scripts/06_ablation_all.sh
# 6. Cold-start analysis — the headline plot
.venv/bin/python -m codes.eval.coldstart \
--ckpt checkpoints/full_lgf_best.pt \
--baseline-ckpt checkpoints/kg_only_best.ptFinal artefacts land in results/: ablation_table.csv, coldstart_alpha.png,
coldstart_gain.png, plus per-run *_metrics.json. Per-run training history
is also written to logs/<run_name>_history.json (always) and streamed to
Weights & Biases (when logged in). See docs/setup.md §9.6
for the full logging behaviour.
Collaborative-Filtering-Project/
├── codes/ # all Python source (data, models, training, eval, utils)
├── configs/ # YAML per ablation (full_lgf, kg_only, llm_only, mean_fusion)
├── scripts/ # bash entry points, numbered in run order (00-06)
├── docs/ # spec PDF, architecture image, setup.md guide
├── checkpoints/ # *.pt (gitignored)
├── logs/ # per-run history.json (gitignored)
├── results/ # ablation_table.csv, plots, summaries
├── notebooks/ # exploration (placeholder)
├── datasets/ # symlink to data root (large files live off-repo)
├── requirements.txt
└── README.md
See docs/setup.md §3 for the per-file breakdown.
Every requirement from the project spec is implemented; one deliberate deviation is documented below.
| Spec section | Requirement | Implementation | Status |
|---|---|---|---|
| §1 Abstract | Dual-stream gated architecture, frozen LLM as latent reasoner | codes/models/lgf.py |
✅ |
| §2 Stream A | LightGCN (or GAT) over interaction matrix + KG triplets | codes/models/kgat.py (LightGCN); TransR pre-init from KG triplets in codes/training/transr_pretrain.py |
✅ |
| §2 Stream B | Frozen LLM (e5-large 1024-dim or Llama-3 4096-dim) → 2-layer MLP with ReLU | codes/embeddings/compute_llm_emb.py (e5-large supported) + codes/models/llm_proj.py (Linear→ReLU→Linear) |
✅ |
| §2 Fusion gate | α = σ(W_gate · [h_kg ∥ h_sem] + b), h_item = α ⊙ h_kg + (1 − α) ⊙ h_sem |
codes/models/gate.py:34,41 (exact mathematical match) |
✅ |
| §2 Prediction head | score(u, i) = h_user · h_item |
codes/training/train.py:118 and codes/models/lgf.py:56 |
✅ |
| §3 Dataset | Amazon-Books (one of three doc options; user-selected) | Amazon-Reviews-2023 Books, 5-core: 776K users, 495K items, 9.5M interactions, 2.44M KG triplets | ✅ |
| §4 Phase 1 | Pre-compute LLM embeddings offline, save .pt, never in training loop |
codes/embeddings/compute_llm_emb.py writes .pt; LLM stored as register_buffer (no grad) |
✅ |
| §4 Phase 2 | Use PyTorch Geometric for unified heterogeneous graph | codes/data/splits.py:build_norm_adj uses torch.sparse_coo_tensor directly + raw triplet array |
|
| §4 Phase 3 | LightGCN + MLP + Gating layer trained with BPR loss | codes/models/lgf.py wires all three; codes/training/bpr.py is -F.logsigmoid(s_pos - s_neg).mean() |
✅ |
| §4 Phase 4 | Recall@10, NDCG@10, ablations: no-KG, no-LLM, average-pooling | codes/eval/metrics.py (full-rank); 4 configs in configs/ |
✅ |
| §5 References | LightGCN, AlphaRec, FiLM, KGRec | Hyperparams + design choices traced in docs/setup.md §13 |
✅ |
§4 Phase 2 says "Use PyTorch Geometric (PyG) to load your user-item interactions
and KG triplets into a unified, heterogeneous graph." The current implementation
builds the symmetric-normalized bipartite adjacency directly with
torch.sparse_coo_tensor (codes/data/splits.py:build_norm_adj) and stores
the KG triplets as a numpy array consumed only by TransR pre-training. The math
is equivalent — LightGCN propagation only needs the U–I sparse adjacency and
TransR only needs the triplet list — but the HeteroData abstraction is
absent. If strict PyG compliance is required, wrapping the existing tensors in
a HeteroData object is a ~1-hour change.
- No
bought_withKG edges — thebought_togetherfield is uniformly empty in the AR-2023 Books category. The relation was removed fromcodes/data/build_kg.py:RELATIONSrather than emit zero triplets. - No user reviews in LLM text — only
title + description[:500]. AlphaRec showed title alone suffices, and reviews carry time-leakage risk. sold_byis author for Books, not publisher/brand — closest available signal in AR-2023 metadata.
The full pipeline has been smoke-tested end-to-end on Mac MPS:
| Stage | Result |
|---|---|
| Data download (3 CSVs + filtered metadata) | ✅ 776K users, 495K items, 9.5M interactions |
| KG construction | ✅ 2,444,279 triplets, 3 relations, 733K entities |
| LLM embedding (smoke: 500 items) | ✅ correct shape (495063, 384) |
| TransR pre-training (5 epochs, 2.44M triplets) | ✅ loss 0.51 → 0.05, 179 MB checkpoint |
| Full ablation (4 configs × 15 batches each) | ✅ all 4 train + eval + aggregate, ablation_table.csv produced |
| Cold-start analysis | ✅ 2 PNGs + summary JSON produced |
Numbers from the smoke run are not meaningful (under-trained, mostly-zero embeddings); full production run happens on the lab GPU.
Project for academic coursework. Underlying datasets:
- Amazon-Reviews-2023 — McAuley Lab, UCSD (arXiv:2403.03952)
Reference papers (used as design inspiration, not redistributed):
- LightGCN — He et al., SIGIR 2020 (arXiv:2002.02126)
- AlphaRec — Sheng et al., 2024 (arXiv:2407.05441)
- FiLM — Perez et al., ICML 2018 (arXiv:1709.07871)
- KGRec — Yang et al., KDD 2023 (arXiv:2307.02759)