Paper: List-aware Reranking-Truncation Joint Model for Search and Retrieval-augmented Generation
Authors: Shicheng Xu, Liang Pang, Jun Xu, Huawei Shen, Xueqi Cheng
Venue: WWW '24: Proceedings of the ACM Web Conference 2024
GenRT/
βββ README.md # This file
βββ requirements.txt # Python dependencies
βββ .gitignore # Git ignore rules
β
βββ app.py # Flask web application (Phase 4)
βββ train_web10k.py # Training script (Phase 2)
βββ test_inference.py # Inference testing (Phase 3)
βββ test_gpu_fit.py # GPU memory verification
β
βββ app/ # Web application assets
β βββ templates/
β β βββ index.html # Search interface
β β βββ result.html # Results display
β βββ static/
β βββ style.css # Styling
β
βββ model/ # GenRT model implementation
β βββ modeling_t5_add_pos_eof.py # Main model (training)
β βββ modeling_t5_add_pos_eof_predict.py # Model (inference)
β βββ embedding_layer.py # Feature embedding layers
β
βββ services/ # Inference service layer
β βββ __init__.py
β βββ inference_service.py # GenRTInference class
β
βββ setup/ # Data preparation scripts
β βββ create_data_web10k.py # Process LETOR β pickle
β βββ merge_tables.py # Merge feature tables
β βββ download_t5_clean.py # Download T5-small
β βββ fix_t5_model.py # Fix model format issues
β βββ verify_data.py # Verify processed data
β
βββ data/ # Raw dataset (LETOR format)
β βββ MSLR-WEB10K/
β βββ Fold1/
β βββ train.txt # Training data
β βββ train.predict # LambdaMART scores
β βββ test.txt # Test data
β βββ test.predict # LambdaMART scores
β βββ vali.txt # Validation data
β βββ my_model.txt # Trained LambdaMART model
β
βββ dataset/ # Processed data (pickle files)
β βββ MSLR-WEB10K/
β βββ FOLD1/
β βββ processed_data/
β βββ train_top40.pkl
β βββ train_top40_table.pkl
β βββ test_top40.pkl
β βββ test_top40_table.pkl
β βββ feature_top40_table.pkl
β
βββ checkpoints/ # Trained model weights
β βββ checkpoint_best.pth # Best validation checkpoint
β βββ checkpoint_latest.pth # Latest checkpoint
β
βββ T5-small/ # T5-small base model
β βββ config.json
β βββ pytorch_model.bin
β βββ spiece.model
β
βββ mytransformers_emb_sim/ # Modified HuggingFace Transformers
βββ src/transformers/
βββ models/t5/ # Custom T5 with GenRT modifications
| Requirement | Version | Notes |
|---|---|---|
| Python | 3.8+ | Tested on 3.10, 3.11 |
| PyTorch | 1.10+ | CUDA support recommended |
| GPU | 8GB+ VRAM | RTX 4060 or better |
| Java | JRE 8+ | For RankLib |
# 1. Navigate to project directory
cd GenRT
# 2. Create virtual environment (recommended)
python -m venv venv
source venv/bin/activate # Linux/Mac
# or: venv\Scripts\activate # Windows
# 3. Install dependencies
pip install -r requirements.txt
# 4. Verify GPU
python test_gpu_fit.py- Visit Microsoft Learning to Rank Datasets
- Download MSLR-WEB10K.zip (~1GB)
- Extract to
data/MSLR-WEB10K/
Expected structure:
data/MSLR-WEB10K/
βββ Fold1/
β βββ train.txt # ~235MB, 723K lines
β βββ test.txt # ~78MB, 241K lines
β βββ vali.txt # ~78MB, 241K lines
βββ Fold2/
β βββ ...
βββ Fold5/
Download RankLib-2.18.jar and place in data/MSLR-WEB10K/Fold1/.
cd data/MSLR-WEB10K/Fold1
# Train LambdaMART model (takes ~10-30 minutes)
java -Xmx8g -jar RankLib.jar \
-train train.txt \
-ranker 6 \
-metric2t NDCG@10 \
-tree 1000 \
-leaf 20 \
-save my_model.txt
# Generate prediction scores for each split
java -jar RankLib.jar -load my_model.txt -rank train.txt -score train.predict
java -jar RankLib.jar -load my_model.txt -rank test.txt -score test.predict
java -jar RankLib.jar -load my_model.txt -rank vali.txt -score vali.predictcd setup
python download_t5_clean.pyIf you encounter safetensors issues:
python fix_t5_model.pycd setup
# Convert LETOR format to pickle (creates train/test/vali pkl files)
python create_data_web10k.py
# Merge all feature tables into one
python merge_tables.py
# Verify everything is ready
python verify_data.pyπ‘ Pre-trained Checkpoints Available!
You can skip training by downloading our pre-trained checkpoints:
π₯ Download Checkpoints from Google Drive
Extract and place the files in thecheckpoints/directory.
# From project root
python train_web10k.py# Custom hyperparameters
python train_web10k.py --batch_size 32 --epochs 15 --lr 5e-5
# Resume from checkpoint
python train_web10k.py --resume latest --epochs 20
# Reduced memory usage
python train_web10k.py --batch_size 8 --grad_accum 2| Argument | Default | Description |
|---|---|---|
--batch_size |
16 | Training batch size |
--eval_batch_size |
32 | Evaluation batch size |
--epochs |
10 | Number of training epochs |
--lr |
1e-4 | Learning rate |
--weight_decay |
0.0005 | Weight decay |
--lr_decay |
0.95 | LR decay per epoch |
--resume |
None | 'latest', 'best', or checkpoint path |
--no_amp |
False | Disable mixed precision |
--grad_accum |
1 | Gradient accumulation steps |
--early_stop |
5 | Early stopping patience |
π GenRT Trainer Initialization
========================================
β
GPU: NVIDIA GeForce RTX 4060
Memory: 8.0 GB
π Loading data...
β
Train: 10,000 queries
β
Test: 3,000 queries
π€ Initializing model...
β
Model parameters: 12.5M
π Training Progress:
Epoch 1/10: 100%|ββββββββββ| 625/625 [05:32<00:00]
Train Loss: 2.3456
Test NDCG@10: 0.4521
β
Best model saved!
python test_inference.pyExpected output:
π§ͺ Testing GenRT Inference Service
========================================
π§ Initializing inference service...
β
Loaded 3000 queries
π Available sample QIDs: [1, 2, 3, ...]
π Testing prediction for QID: 1
β
Prediction successful!
π Results:
NDCG@10 Baseline: 0.4231
NDCG@10 GenRT: 0.4687
Improvement: +0.0456
python app.pyOpen browser: http://localhost:5000
- Enter Query ID to see reranking results
- Side-by-side comparison: Baseline vs GenRT
- Visual indicators for promoted/demoted documents
- NDCG metrics display
- Truncation point visualization
from services.inference_service import GenRTInference
# Initialize service (loads model once)
inference = GenRTInference(
checkpoint_path="./checkpoints/checkpoint_best.pth",
device="cuda" # or "cpu"
)
# Get available query IDs
all_qids = inference.get_available_qids()
sample_qids = inference.get_sample_qids(n=10)
# Predict for a single query
result = inference.predict(qid=12345)
# Result structure
{
'qid': 12345,
'baseline_ranking': [
{'doc_id': 0, 'lambdamart_score': 1.234, 'relevance_label': 2},
...
],
'genrt_ranking': [
{'doc_id': 5, 'lambdamart_score': 0.987, 'relevance_label': 3, 'original_rank': 6},
...
],
'truncation_point': 15,
'metrics': {
'ndcg@5_baseline': 0.412,
'ndcg@5_genrt': 0.456,
'ndcg@10_baseline': 0.423,
'ndcg@10_genrt': 0.468,
'improvement': 0.045
},
'num_docs_baseline': 40,
'num_docs_genrt': 15
}
# Batch prediction
results = inference.predict_batch(qids=[1, 2, 3, 4, 5])| Endpoint | Method | Description |
|---|---|---|
/ |
GET | Home page with search interface |
/search |
POST | Submit query and get results |
/api/predict/<qid> |
GET | Get prediction JSON for QID |
/api/qids |
GET | Get list of available QIDs |
# Get prediction for QID
curl http://localhost:5000/api/predict/12345
# Get available QIDs (optional: ?n=100)
curl http://localhost:5000/api/qids?n=50Input: [Query Features] + [Doc1 Features] + [Doc2 Features] + ... + [DocN Features]
β
βββββββββββββββββββββββββββββββββ
β Global Dependency Encoder β
β (Multi-Head Self-Attention) β
βββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββββββββββββ
β Sequential Dependency Decoder β
β (Step-by-step Generation) β
βββββββββββββββββββββββββββββββββ
β
Output: Reranked List + Truncation Point
- Input Embedding: 136 LETOR features + 1 LambdaMART score = 137-dim vector
- Transfer Layer: MLP with Swish activation β hidden size
- Context Modeling: Multi-Head Self-Attention captures list-level dependencies
- Residual Connection: Preserves original features while adding context
- Step-by-step Generation: Outputs one document per step
- Truncation Decision: Binary classification at each step
- Cross-Attention: Attends to encoder output for document selection
- Position Encoding: Relative position encoding for order awareness
-
Reranking Loss (
$\mathcal{L}_R$ ):- Step-adaptive attention loss (weights top positions more)
- Step-by-step lambda loss (pairwise ranking)
-
Truncation Loss (
$\mathcal{L}_T$ ):- Binary classification with TDCG-based soft labels
- Reward Augmented Maximum Likelihood (RAML)
If you use this code, please cite the original paper:
@inproceedings{xu2024genrt,
title={List-aware Reranking-Truncation Joint Model for Search and Retrieval-augmented Generation},
author={Xu, Shicheng and Pang, Liang and Xu, Jun and Shen, Huawei and Cheng, Xueqi},
booktitle={Proceedings of the ACM Web Conference 2024},
pages={1028--1037},
year={2024},
organization={ACM}
}| Issue | Solution |
|---|---|
| CUDA out of memory | Reduce --batch_size to 8 or 4; Use --grad_accum 2 |
| T5 model loading error | Run python setup/fix_t5_model.py; Ensure pytorch_model.bin exists |
| Missing .predict files | Follow Step 1.2 to generate with RankLib |
| Feature table not found | Run python setup/merge_tables.py |
| Web app fails to start | Check checkpoint and processed data exist |
| Java not found | Install JRE 8+; Add to PATH |
| Import errors | Ensure virtual environment is activated |
# Check GPU
python -c "import torch; print(torch.cuda.is_available())"
# Check data files
python setup/verify_data.py
# Check model loads
python test_gpu_fit.pyThis project is for educational and research purposes only.
- Original GenRT paper authors
- Microsoft Research for MSLR datasets
- HuggingFace for Transformers library
- RankLib for LambdaMART implementation