Modern e-commerce platforms require sophisticated conversion prediction systems to optimize user experience and maximize revenue. This document outlines a complete ML system architecture that combines real-time feature processing, ensemble modeling, and scalable deployment strategies to predict user conversion probabilities at scale.
1. Problem Statement & ML Task Definition
Clarifying questions
- What is the specific business context for conversion prediction? Is this for e-commerce, ad serving, lead generation, or another domain?
- What is the expected QPS and latency budget for real-time predictions? Will this be used for real-time bidding, email campaigns, or web page personalization?
- What is the target conversion signal? Is it purchase, sign-up, click, or another specific action?
- What is the expected scale of users/items and volume of training data? How much historical data do we have available?
- What is the acceptable trade-off between model accuracy and inference latency? Will this be used for batch processing or real-time serving?
- What is the expected data freshness requirements? How frequently should models be retrained or updated?
- What are the key business success metrics that will drive model evaluation and optimization?
Business use case and success criteria
The system aims to predict the probability that a user will convert (e.g., make a purchase, sign up for a service, or complete an action) within a specified time window after being exposed to a recommendation or ad. The system will power real-time personalization, targeted campaigns, and resource allocation to maximize business KPIs such as revenue per user, conversion rate, or customer lifetime value.
Success criteria include:
- 15% improvement in conversion rate over baseline
- 20% reduction in cost per acquisition (CPA)
- 30% improvement in revenue per user
- 95th percentile prediction latency under 100ms for real-time serving
ML problem formulation
This is a binary classification task where the goal is to predict whether a user will convert (1) or not convert (0) within a specified time window. The task is framed as a probability estimation problem to enable decisioning based on confidence thresholds.
Justification:
- Conversion is a binary event with clear positive/negative outcomes
- Probability estimates enable flexible business decisioning (e.g., threshold tuning for different KPIs)
- Binary classification is well-suited for this type of user behavior prediction
ML evaluation metrics
Offline Evaluation Metrics:
- AUC-ROC: Primary metric for overall model discrimination
- Precision@K: For top-K recommendation scenarios (e.g., top 100 users to target)
- NDCG@K: For ranked recommendation scenarios (e.g., ranking users by conversion probability)
- Log Loss: For calibrated probability estimation
Online Evaluation Metrics:
- Click-Through Rate (CTR): For ad serving scenarios
- Conversion Rate: Direct business impact metric
- Revenue per User (RPU): Business value measurement
- Cost Per Acquisition (CPA): Cost efficiency metric
Scale and constraints
Back-of-envelope estimates:
- Training data size: 50M user-item interactions (100GB raw data)
- Number of features: 5,000 total features (user + item + context + interaction)
- Embedding matrix memory footprint: 5,000 features × 128 dimensions × 4 bytes = ~2.5MB per user
- Serving QPS math: 100ms latency budget → 10 QPS per model instance; 1,000 QPS requires 100 instances
Scale constraints:
- Target: 1,000 QPS for real-time serving
- Latency budget: 100ms p99 (50ms p50)
- Data volume: 50M training samples, 100M daily user interactions
- Freshness requirements: Model retraining every 24 hours, feature updates every hour
Non-ML baseline strategy
Baseline rule-based system:
- Cold start handling: For new users, use default conversion probability (e.g., 0.02) based on historical population average
- Simple heuristics:
- Users with > 50 page views in last hour → 0.15 probability
- Users with > 100 page views in last hour → 0.25 probability
- Users with recent purchase history → 0.30 probability
- Fallback logic: If model fails to serve, return baseline probability with error logging for retraining trigger
- Feature-based rules:
- Users from high-converting segments (e.g., age 25-35, location US) → +0.05 probability boost
- Users with low engagement (e.g., < 5 page views in past 24h) → -0.03 probability adjustment
# Baseline conversion probability calculation (simplified)
def calculate_baseline_conversion_probability(user_profile):
base_prob = 0.02 # population average
if user_profile.get('recent_purchases', 0) > 0:
return min(0.30, base_prob + 0.15)
elif user_profile.get('page_views_last_hour', 0) > 100:
return min(0.25, base_prob + 0.10)
elif user_profile.get('page_views_last_hour', 0) > 50:
return min(0.20, base_prob + 0.08)
else:
return base_prob
2. Data Strategy
Training Data Sources
- Explicit feedback: Purchase events, cart abandonment, wishlist additions, direct user ratings
- Implicit signals: Page views, time on page, scroll depth, click-through rates, session duration
- Third-party data: Demographic information from partner integrations, contextual signals (weather, events)
- Historical behavioral sequences: User navigation patterns, item browsing history, search queries
- Product catalog data: Item categories, pricing, availability, brand information
Labeling Pipeline Design
- Human annotation: For high-value conversion events (e.g., purchase confirmation) with expert review for edge cases
- Weak supervision: Using heuristics like "user viewed item X and added to cart but didn't purchase within 24h" as negative labels
- Programmatic labeling:
def label_conversion_event(user_session): if user_session['purchase'] == True: return 1 elif user_session['cart_abandonment'] == True and user_session['time_to_purchase'] > 24*60*60: return 0 else: return None # Needs human review
Class Imbalance Handling Strategy
Conversion events represent ~2-5% of total user interactions, requiring:
- Oversampling: Boost minority class samples in training batches
- Class weights: Apply inverse frequency weighting during model training
- Focal Loss: Reduce loss contribution from easy-to-classify examples to focus on hard ones
- Stratified sampling: Ensure balanced representation in training batches
Negative Sampling Approach
- Hard negative mining: Sample sessions that show high engagement but no conversion (e.g., long session duration, multiple item views)
- Time-based sampling: Prefer recent non-conversion events to capture current user interest patterns
- Stratified negative sampling: Maintain ratio of 1:3-5 positive to negative samples in training batches
Data Freshness and Update Frequency
- Real-time signals: Updated every 5-10 minutes for user behavior tracking
- Batch features: Updated daily for item and user embeddings, feature aggregates
- Historical sequences: Updated weekly for long-term behavioral patterns
- Freshness requirements: 24-hour window for user behavior, 7-day window for item popularity trends
Privacy Compliance
- Data anonymization: Remove PII (names, email addresses) from training data
- GDPR/CCPA compliance: Implement data retention policies (30 days for behavioral data, 6 months for purchase data)
- Consent management: Track user consent for data collection and model training
- Differential privacy: Apply noise to sensitive features during training to prevent re-identification
Data Quality Validation and Monitoring
- Data validation checks:
- Session consistency (time order, valid item IDs)
- User ID uniqueness and format validation
- Purchase timestamp alignment with session events
- Monitoring dashboard: Track data drift, missing values, and distribution shifts in real-time
- Automated alerts: Trigger when data quality drops below threshold (e.g., >5% missing values in key features)
- Data lineage tracking: Maintain audit trail of data transformations and feature engineering steps
3. Feature Engineering
Feature Taxonomy
Features are organized into four main categories:
- User Features: User demographics, behavioral history, engagement patterns, and segmentation data
- Item Features: Product attributes, category information, pricing, inventory status, and popularity metrics
- Context Features: Time-based signals (hour, day of week, seasonality), device type, geographic location, and campaign information
- Interaction Features: User-item interaction history, recency of engagement, session behavior, and cross-feature combinations
Embedding Design
Entity Embeddings:
- User ID embeddings (128-dim) trained via click-through rate prediction
- Item ID embeddings (256-dim) using contrastive learning to capture semantic similarity
- Category embeddings (64-dim) for hierarchical categorization
Text Embeddings:
- Product title and description embeddings using BERT-base (768-dim) fine-tuned on product data
- User review text embeddings using sentence-transformers (512-dim) for sentiment and content matching
Graph Embeddings:
- User-item interaction graph embeddings using Node2Vec (128-dim) to capture latent user preferences and item relationships
Real-time vs Batch Feature Computation
| Feature Type | Computation Mode | Reasoning |
|---|---|---|
| User session count | Real-time | Requires low-latency response for conversion prediction |
| Item popularity | Batch | Updated daily, can be pre-computed |
| User engagement score | Real-time | Dynamic metric that changes with each interaction |
| Historical conversion rate | Batch | Stable over time, computed once per refresh cycle |
Feature Store Design
Online Store:
- Low-latency key-value store (e.g., Redis or DynamoDB) for real-time feature retrieval
- TTL of 5 minutes for user session features, 1 hour for engagement scores
Offline Store:
- Data warehouse (e.g., Snowflake or BigQuery) for training data and batch feature computation
- Partitioned by date for efficient querying and historical analysis
Feature Freshness and TTL
| Feature | Source | Update Frequency | Store Type |
|---|---|---|---|
| User session count | Real-time logs | Every 5 minutes | Online |
| Item price | Product catalog | Daily | Offline |
| User engagement score | Behavioral logs | Every 15 minutes | Online |
| Item category | Product catalog | Daily | Offline |
| User purchase history | Transaction DB | Hourly | Offline |
| Time-based signals | System clock | Every minute | Online |
Cross Features and Feature Interaction Strategy
Cross features are engineered to capture complex user-item relationships:
- User-item interaction frequency × item popularity (to detect high-value combinations)
- User session duration × item category (to understand engagement patterns by content type)
- Time since last interaction × user purchase frequency (to identify at-risk users)
Feature Importance and Selection Methodology
Methodology:
- SHAP values for model interpretability and feature importance ranking
- Permutation importance computed on holdout set to validate feature relevance
- Recursive Feature Elimination (RFE) with cross-validation for automated selection
Threshold: Features with SHAP importance > 0.01 and permutation importance > 0.005 are retained for model training.
import numpy as np
from sklearn.feature_selection import RFE
from sklearn.ensemble import RandomForestClassifier
# Sample feature matrix (user_id, item_id, session_count, engagement_score, etc.)
X = np.random.rand(1000, 10) # 1000 samples, 10 features
y = np.random.randint(0, 2, 1000) # Binary conversion target
# Feature selection using RFE with Random Forest
rf_model = RandomForestClassifier(n_estimators=100, random_state=42)
selector = RFE(rf_model, n_features_to_select=5, step=1)
# Fit selector
selector.fit(X, y)
# Get selected features (indices)
selected_features = selector.support_
feature_importance_scores = selector.ranking_
# Output selected features
print("Selected features (indices):", np.where(selected_features)[0])
print("Feature importance ranking:", feature_importance_scores)
4. Model Architecture
Model Selection with Justification
For a conversion prediction system, I'll select a DNN-based two-tower architecture for the following reasons:
- Non-linear feature interactions: Conversion prediction requires capturing complex relationships between user and item features that linear models cannot adequately represent
- Scalability: DNNs can scale well with increasing feature dimensions and training data
- Flexibility: Easy to incorporate various embedding types (user, item, context) and real-time features
- Performance: DNNs typically outperform traditional ML methods like logistic regression or GBMs on complex recommendation tasks
Trade-offs compared to alternatives:
- Logistic Regression: Simpler but lacks ability to capture complex feature interactions; poor performance on high-dimensional sparse data
- GBM (XGBoost/LightGBM): Good performance but harder to scale and less flexible for real-time serving
- Transformer: Powerful but overkill for conversion prediction; introduces unnecessary complexity and latency
Architecture Diagram
graph TD
A[User Features] --> B[User Embedding Layer]
C[Item Features] --> D[Item Embedding Layer]
B --> E[User Representation]
D --> F[Item Representation]
E --> G[Interaction Layer]
F --> G
G --> H[MLP Layers]
H --> I[Conversion Probability]
subgraph "User Tower"
B
E
end
subgraph "Item Tower"
D
F
end
subgraph "Scoring Layer"
G
H
I
end
Two-Tower / Multi-Task / Ensemble Design
The system uses a two-tower architecture where:
- User tower processes user features (demographics, behavior history, context)
- Item tower processes item features (product attributes, category, price)
- The towers interact through dot product or concatenation to compute conversion likelihood
Multi-task extension: Can extend to predict multiple related signals (click-through rate, purchase value, time-to-conversion) using a shared backbone with task-specific heads.
Pre-trained Model Selection and Fine-tuning Strategy
For foundation model integration:
- Pre-trained text embeddings: Use BERT or similar for item descriptions and user reviews
- Fine-tuning strategy:
- Pre-train on large-scale text data (product descriptions, reviews)
- Fine-tune on conversion prediction task with domain-specific data
- Use transfer learning to reduce training time and improve generalization
Model Complexity vs Latency Trade-off Analysis
| Model | Parameters | Inference Latency (ms) | Memory Footprint | Accuracy (AUC) |
|---|---|---|---|---|
| Logistic Regression | 10K | 1 | 5MB | 0.72 |
| XGBoost | 5M | 15 | 50MB | 0.82 |
| Two-Tower DNN (Small) | 10M | 35 | 200MB | 0.86 |
| Two-Tower DNN (Medium) | 50M | 65 | 500MB | 0.89 |
| Two-Tower DNN (Large) | 200M | 120 | 2GB | 0.92 |
Offline Evaluation Baseline Framing
Baseline: Logistic regression with engineered features Expected improvement: 3-5% AUC improvement over baseline Target: Achieve AUC > 0.90 on holdout test set
Core Model Code Snippet
import torch
import torch.nn as nn
import torch.nn.functional as F
class ConversionPredictionModel(nn.Module):
def __init__(self, user_feature_dim, item_feature_dim,
user_embedding_dim=128, item_embedding_dim=128,
hidden_dims=[256, 128, 64]):
super().__init__()
# User embedding layers
self.user_embedding = nn.Linear(user_feature_dim, user_embedding_dim)
# Item embedding layers
self.item_embedding = nn.Linear(item_feature_dim, item_embedding_dim)
# MLP layers for interaction
self.mlp_layers = nn.ModuleList([
nn.Linear(user_embedding_dim + item_embedding_dim, hidden_dims[0])
])
for i in range(len(hidden_dims) - 1):
self.mlp_layers.append(
nn.Linear(hidden_dims[i], hidden_dims[i+1])
)
self.output_layer = nn.Linear(hidden_dims[-1], 1)
def forward(self, user_features, item_features):
# Embedding layers
user_emb = F.relu(self.user_embedding(user_features))
item_emb = F.relu(self.item_embedding(item_features))
# Concatenate embeddings
combined = torch.cat([user_emb, item_emb], dim=1)
# MLP processing
for layer in self.mlp_layers:
combined = F.relu(layer(combined))
# Final prediction
output = torch.sigmoid(self.output_layer(combined))
return output
def compute_loss(self, predictions, targets):
# Binary cross entropy loss
return F.binary_cross_entropy(predictions.squeeze(), targets.float())
def predict_conversion_probability(self, user_features, item_features):
"""Returns conversion probability for given user-item pair"""
self.eval()
with torch.no_grad():
prob = self(user_features, item_features)
return prob.cpu().numpy()
# Example usage:
# model = ConversionPredictionModel(user_feature_dim=100, item_feature_dim=200)
# user_features = torch.randn(32, 100) # batch_size=32
# item_features = torch.randn(32, 200)
# predictions = model(user_features, item_features)
# loss = model.compute_loss(predictions, torch.randint(0, 2, (32, 1)))
This implementation provides:
- Modular embedding and MLP layers
- Clear forward pass with proper activation functions
- Binary cross-entropy loss computation
- Prediction probability extraction
- Batch processing capability for serving
- Memory-efficient architecture suitable for production deployment
5. Serving & Inference Architecture
System Diagram
graph TD
A[User Request] --> B[Load Balancer]
B --> C[API Gateway]
C --> D[Feature Store Lookup]
D --> E[Model Serving Layer]
E --> F[Scoring Service]
F --> G[Response Formatter]
G --> H[Return Result]
subgraph "Real-time Serving Pipeline"
C --> I[Request Router]
I --> J[Embedding Cache]
J --> K[Model Inference Engine]
K --> L[Ranking/Scoring]
L --> M[Response Builder]
end
Online vs Batch Serving Decision
Online serving chosen for conversion prediction due to:
- Real-time decision making required (user actions within seconds)
- Low latency requirement (< 100ms p99 for user-facing experiences)
- Personalization needs (user-specific predictions)
- Immediate feedback loop for model performance
Batch serving would be appropriate for:
- Weekly conversion rate forecasting
- Historical trend analysis
- Offline model retraining
Two-Stage Pipeline
Candidate Retrieval → Scoring → Re-ranking
-
Candidate Retrieval:
- Fast retrieval of top-K items using approximate nearest neighbor (ANN) search
- Use Faiss or Annoy for efficient item embedding similarity lookup
-
Scoring:
- Full model inference on candidate set
- Apply ranking weights and business rules
-
Re-ranking:
- Apply diversity constraints and business logic
- Final ranking based on conversion probability + business factors
Serving Infrastructure
Primary choice: TorchServe with custom inference wrapper
Justification:
- Supports PyTorch models natively
- Built-in model versioning and A/B testing capabilities
- Production-grade with built-in metrics and logging
- Easy integration with Kubernetes for scaling
Alternative considerations:
- Triton Inference Server: Better for multi-model serving, but more complex setup
- vLLM: For LLM-based conversion prediction (if using prompt engineering), but overkill for typical conversion models
Latency Budget Breakdown
| Stage | p50 Latency | p99 Latency | Budget |
|---|---|---|---|
| Feature Lookup | 5ms | 15ms | 20ms |
| Model Inference | 10ms | 30ms | 40ms |
| Ranking/Scoring | 5ms | 15ms | 20ms |
| Response Build | 2ms | 8ms | 10ms |
| Total | 22ms | 68ms | 90ms |
Model Compression Strategy
Primary approach: Quantization + Pruning
-
INT8 Quantization:
- 4x reduction in model size
- <5% accuracy degradation for most models
- Minimal impact on inference latency
-
Structured Pruning:
- Remove 30-50% of model parameters
- Maintain model performance within 2-3% of full model
-
Model Distillation:
- Train smaller student model using teacher model logits
- 5x-10x faster inference with <2% accuracy loss
Caching Strategy
| Cache Type | Size Estimate | Purpose |
|---|---|---|
| Prediction Cache | 50GB | Store recent user predictions (LRU) |
| Embedding Cache | 20GB | Pre-computed item/user embeddings |
| KV Cache (LLM) | 10GB | For prompt-based conversion models |
Implementation:
class PredictionCache:
def __init__(self, max_size=100000):
self.cache = {}
self.access_order = []
self.max_size = max_size
def get(self, key):
if key in self.cache:
# Move to end (most recently used)
self.access_order.remove(key)
self.access_order.append(key)
return self.cache[key]
return None
def set(self, key, value):
if len(self.cache) >= self.max_size:
# Remove least recently used
oldest = self.access_order.pop(0)
del self.cache[oldest]
self.cache[key] = value
self.access_order.append(key)
Auto-scaling and Capacity Planning
Horizontal scaling strategy:
- Target QPS: 10,000 requests/sec (back-of-envelope: 50M daily users * 200 conversions/day = ~10,000 QPS)
- Instance size: 4 vCPUs + 16GB RAM per model instance
- Target p99 latency: < 100ms
Scaling factors:
- Warm-up period: 2 hours for model loading and cache warming
- Graceful degradation: Fallback to rule-based model during scaling events
- Health checks: Liveness probe every 30 seconds, readiness probe every 15 seconds
Capacity calculation:
QPS = 10,000
Latency target = 100ms
Throughput per instance = 10,000 * 0.1 = 1,000 requests/sec
Model instances needed = 10,000 / 1,000 = 10 instances
Auto-scaling policy:
- Scale up when QPS > 8,000 (80% threshold)
- Scale down when QPS < 2,000 (20% threshold)
- Minimum instances: 5 for cold start handling
- Maximum instances: 50 for peak load handling
6. Evaluation Framework
Offline Evaluation Methodology
For offline evaluation, we employ a temporal split approach to ensure that our model is evaluated on data from the future relative to training, preventing data leakage. This is critical for conversion prediction systems where temporal dependencies are strong.
We split the dataset chronologically into:
- Training: 6 months of historical data (2023-01-01 to 2023-06-30)
- Validation: 1 month of data (2023-07-01 to 2023-07-31)
- Test: 1 month of data (2023-08-01 to 2023-08-31)
This ensures that our model is evaluated on truly unseen future data, simulating real-world deployment conditions.
We also implement time-aware cross-validation with 3-fold splits, where each fold uses a different time window to ensure robustness across temporal trends.
Slice-Based Evaluation
To detect model performance degradation across user segments, we define critical slices:
| Slice Type | Definition | Sample Size |
|---|---|---|
| User Segment | Age groups (18-25, 26-35, 36+) | >10k users |
| Device Type | Mobile, Desktop, Tablet | >5k users |
| Geographic Region | US, EU, APAC | >10k users |
| Conversion Stage | Awareness, Consideration, Purchase | >5k users |
| Traffic Source | Organic, Paid, Referral | >5k users |
We monitor AUC-ROC and Precision@K for each slice, with thresholds set at 0.85 AUC and 0.70 Precision@K to trigger alerts for any slice below these thresholds.
A/B Test Design
We design a randomized controlled trial with the following specifications:
-
Randomization Unit: User ID (to prevent spillover effects)
-
Sample Size Calculation:
- Target: 5% lift in conversion rate
- Power: 80%
- Significance Level: 5%
- Estimated baseline conversion rate: 2.5%
- Required sample size per group: ~18,000 users
-
Test Duration: 30 days to capture seasonal patterns
-
Primary Metric: Conversion Rate (CR) with 95% confidence interval
-
Secondary Metrics:
- Revenue per User (RPU)
- Click-Through Rate (CTR) on recommendations
We use multi-armed bandits for adaptive allocation to optimize for performance while maintaining statistical validity.
Guardrail Metrics and Blocking Conditions
To ensure safe deployment, we define guardrail metrics:
| Metric | Threshold | Action |
|---|---|---|
| AUC-ROC Drop | < 0.85 | Block deployment |
| Precision@K Drop | < 0.65 | Block deployment |
| Model Confidence Variance | > 0.3 | Alert and investigate |
| False Positive Rate | > 0.15 | Block deployment |
If any guardrail metric exceeds thresholds, the system automatically blocks model rollout and alerts ML engineers.
Shadow Mode Rollout Plan
Before full A/B testing, we implement a shadow mode rollout:
-
Phase 1 (Week 1):
- 5% of traffic routed to new model in shadow mode
- All predictions logged but not served to users
- Compare offline metrics with online logs
-
Phase 2 (Week 2):
- 15% traffic in shadow mode
- Validate prediction consistency and latency
-
Phase 3 (Week 3):
- 50% traffic in shadow mode
- Monitor for prediction drift and performance gaps
-
Phase 4 (Week 4):
- Full production rollout with A/B test
Long-Term Metric Measurement
We track long-term impact using:
-
Delayed Conversion Rate:
- 7-day, 30-day, and 90-day conversion rates post-prediction
- Expected to show improvement over baseline
-
Engagement Decay:
- Monitor if users who received recommendations engage less over time
- Target: <5% decay in engagement over 30 days
-
Revenue Impact:
- Track revenue per user (RPU) and conversion rate over time
- Expected to show 10-15% improvement in key KPIs
We implement delayed feedback loops where user behavior beyond the initial prediction window is monitored to ensure model does not encourage short-term gains at the cost of long-term user satisfaction.
# Example A/B test evaluation logic in Python
import numpy as np
from scipy import stats
class ABTestEvaluator:
def __init__(self, baseline_cr=0.025, target_lift=0.05):
self.baseline_cr = baseline_cr
self.target_lift = target_lift
def calculate_sample_size(self, power=0.8, alpha=0.05):
"""Calculate required sample size for A/B test"""
z_alpha = stats.norm.ppf(1 - alpha/2)
z_beta = stats.norm.ppf(power)
# Conservative estimate for variance
p1 = self.baseline_cr
p2 = self.baseline_cr * (1 + self.target_lift)
# Sample size calculation for proportions
n = (z_alpha + z_beta)**2 * (p1*(1-p1) + p2*(1-p2)) / (p2 - p1)**2
return int(np.ceil(n))
def evaluate_ab_test(self, control_conversions, test_conversions, control_users, test_users):
"""Evaluate A/B test results"""
cr_control = control_conversions / control_users
cr_test = test_conversions / test_users
# Calculate confidence interval for difference
p1 = cr_control
p2 = cr_test
n1 = control_users
n2 = test_users
# Standard error for difference in proportions
se_diff = np.sqrt((p1*(1-p1)/n1) + (p2*(1-p2)/n2))
# Z-score for 95% confidence
z_score = (p2 - p1) / se_diff
# P-value calculation
p_value = 2 * (1 - stats.norm.cdf(abs(z_score)))
return {
'conversion_rate_control': cr_control,
'conversion_rate_test': cr_test,
'lift': (cr_test - cr_control) / cr_control,
'p_value': p_value,
'is_significant': p_value < 0.05
}
# Example usage:
evaluator = ABTestEvaluator(baseline_cr=0.025, target_lift=0.05)
sample_size = evaluator.calculate_sample_size()
print(f"Required sample size per group: {sample_size}")
# Simulate test results
control_conversions = 450 # 2.5% of 18,000
test_conversions = 500 # 2.78% of 18,000
control_users = 18000
test_users = 18000
results = evaluator.evaluate_ab_test(control_conversions, test_conversions, control_users, test_users)
print(f"Test results: {results}")
7. Training Pipeline
Training Data Pipeline
The training data pipeline follows a multi-stage ETL process:
- Data Extraction: Raw events from Kafka streams and batch files from S3
- Preprocessing:
- Feature extraction from user sessions and item interactions
- Label generation using conversion windows (7-day post-click)
- Data cleaning and deduplication
- Shuffling: Distributed shuffling using Apache Spark to ensure data distribution across training workers
- Batching: Batches of 10,000 samples for efficient GPU utilization
import torch
from torch.utils.data import Dataset, DataLoader
from typing import Dict, List
class ConversionPredictionDataset(Dataset):
def __init__(self, features: List[Dict], labels: List[int]):
self.features = features
self.labels = labels
def __len__(self):
return len(self.features)
def __getitem__(self, idx):
# Normalize features
feature_dict = self.features[idx]
normalized_features = {
k: torch.tensor(v, dtype=torch.float32)
for k, v in feature_dict.items()
}
label = torch.tensor(self.labels[idx], dtype=torch.float32)
return normalized_features, label
# Example usage in training loop
def train_step(model, dataloader, optimizer, criterion):
model.train()
total_loss = 0
for batch_features, batch_labels in dataloader:
optimizer.zero_grad()
outputs = model(batch_features)
loss = criterion(outputs, batch_labels)
loss.backward()
optimizer.step()
total_loss += loss.item()
return total_loss / len(dataloader)
Distributed Training Strategy
- Data Parallelism: Using PyTorch Distributed Data Parallel (DDP) across 8 GPUs
- Model Parallelism: For large embedding tables, model parallelism is applied to embeddings
- Training Cluster: 2x nodes with 8x A100 GPUs each (16 total GPUs)
- Estimated Training Time: ~2 hours for 10M samples with batch size 1024
Training Infrastructure
- Compute: 16x A100 GPUs (8 nodes × 2 GPUs each)
- Storage: NVMe SSDs for fast data loading (10TB total)
- Framework: PyTorch Lightning with distributed training support
- Resource Allocation: 8GB GPU memory per worker, 256GB RAM per node
Hyperparameter Tuning Approach
- Search Strategy: Bayesian Optimization using Optuna
- Key Hyperparameters:
- Learning rate: [1e-5, 1e-2]
- Batch size: [64, 256, 1024]
- Embedding dimension: [64, 128, 256]
- Dropout rate: [0.1, 0.3, 0.5]
- Tuning Duration: 48 hours for 100 trials
Experiment Tracking and Reproducibility
- Tool: MLflow for experiment tracking and model versioning
- Logging: Metrics (AUC, precision@10), hyperparameters, model artifacts
- Reproducibility:
- Fixed random seeds (torch.manual_seed, numpy.random.seed)
- Versioned model checkpoints with metadata
- Docker containers for training environments
Model Versioning and Registry Strategy
- Versioning: Semantic versioning (v1.0.0, v1.1.0) with git commit hash
- Registry: MLflow Model Registry with staging and production environments
- Rollback Capability: Automated rollback to last stable version on performance degradation
Continual / Online Learning Design
- Trigger: Performance degradation > 2% in AUC or precision@10
- Strategy:
- Online fine-tuning with recent data (last 30 days)
- Incremental model updates every 24 hours
- Data drift detection using PSI for feature distribution changes
- Implementation:
def detect_drift(current_features, historical_features): psi_values = [] for feature in current_features: psi = calculate_psi(current_features[feature], historical_features[feature]) psi_values.append(psi) return any(psi > 0.1 for psi in psi_values) # Threshold for drift
8. Monitoring & Observability
Data Drift Detection
Data drift detection is critical for maintaining model performance in production. We implement drift detection using:
- PSI (Population Stability Index) for categorical features with thresholds at 0.1 (warning) and 0.25 (critical)
- KL Divergence for continuous features with thresholds at 0.05 (warning) and 0.1 (critical)
- Chi-square test for categorical feature drift with p-value threshold of 0.05
import numpy as np
from scipy import stats
from sklearn.metrics import mutual_info_score
class DriftDetector:
def __init__(self, threshold_warning=0.1, threshold_critical=0.25):
self.threshold_warning = threshold_warning
self.threshold_critical = threshold_critical
def psi_drift(self, old_data, new_data):
# Calculate PSI for categorical features
old_counts = np.histogram(old_data, bins=50)[0]
new_counts = np.histogram(new_data, bins=50)[0]
# Normalize counts
old_probs = old_counts / len(old_data)
new_probs = new_counts / len(new_data)
# Calculate PSI
psi = np.sum((new_probs - old_probs) * np.log(new_probs / old_probs + 1e-8))
return psi
def kl_divergence(self, old_dist, new_dist):
# For continuous features
return stats.entropy(old_dist, new_dist)
Prediction Drift and Label Drift Monitoring
Prediction drift is monitored by comparing model outputs over time windows:
- Prediction shift detection: Track mean prediction difference using t-test with p-value < 0.01 as alert trigger
- Label drift: Monitor label distribution shifts using chi-square test for categorical labels
Model Performance Degradation Alerting
We implement multi-layered alerting:
- Offline AUC drop: Alert if AUC drops below baseline - 0.02
- Online CTR drop: Alert if CTR drops below baseline - 0.05%
- Latency increase: Alert if p99 latency increases by >20%
class PerformanceMonitor:
def __init__(self, baseline_auc=0.85, baseline_ctr=0.02):
self.baseline_auc = baseline_auc
self.baseline_ctr = baseline_ctr
def check_auc_degradation(self, current_auc):
return current_auc < self.baseline_auc - 0.02
def check_ctr_degradation(self, current_ctr):
return current_ctr < self.baseline_ctr - 0.0005
def check_latency_breach(self, current_p99, threshold=100):
return current_p99 > threshold * 1.2
Retraining Trigger Strategy
Retraining is triggered by:
- Scheduled: Monthly retraining for model refresh
- Drift-triggered: When PSI > 0.25 or KL divergence > 0.1 for any feature
- Performance-triggered: When AUC drops by 2% or CTR drops by 0.5%
Logging Design
Prediction logs include:
class PredictionLogger:
def __init__(self):
self.prediction_log = []
def log_prediction(self, user_id, item_id, features, prediction, timestamp):
log_entry = {
"user_id": user_id,
"item_id": item_id,
"features": features,
"prediction": prediction,
"timestamp": timestamp,
"model_version": "v1.2.3"
}
self.prediction_log.append(log_entry)
def log_feature_update(self, feature_name, old_value, new_value, timestamp):
feature_log = {
"feature": feature_name,
"old_value": old_value,
"new_value": new_value,
"timestamp": timestamp
}
# Store in feature store or logging system
Feedback Loop for Continuous Improvement
We implement a feedback loop with:
- Label collection pipeline: Collect user conversion labels within 7-day window
- Re-training trigger: Automatic retraining when new labels exceed threshold of 1000 samples
- Model versioning: Track model versions with associated performance metrics
The monitoring system uses Prometheus and Grafana for real-time dashboards, with alerts configured through Alertmanager for proactive issue resolution.
9. Responsible AI & Safety
Bias Analysis
- Training data audit: Conduct comprehensive analysis of user demographics, geographic distribution, and historical conversion patterns to identify potential systematic biases in the training data.
- Slice-based fairness evaluation: Evaluate model performance across user segments (age groups, gender, geographic regions) to detect and address disparities in conversion prediction accuracy.
- Disparate impact analysis: Implement statistical tests (e.g., demographic parity, equalized odds) to ensure the model doesn't systematically favor or disadvantage specific user groups.
Fairness Metrics and Constraints
- Primary fairness metric: Demographic parity (equalized conversion probability across user segments)
- Secondary metrics: Equalized odds, calibration across slices
- Decision rationale: Demographic parity is chosen as the primary constraint because it ensures that users from different demographic groups have equal opportunity to be predicted as converters, which is critical for maintaining equitable user experience and avoiding discriminatory outcomes in ad targeting or product recommendations.
Explainability Requirements and Approach
- SHAP values: Implement SHAP-based feature importance analysis to understand which user attributes drive conversion predictions for individual users.
- Attention visualization: For transformer-based models, provide attention weight visualizations to show which user history or item features were most influential in the prediction.
- Local explainability: For high-stakes decisions (e.g., ad spend allocation), provide human-readable explanations for individual predictions to enable business review and adjustment.
For LLM systems (if applicable):
- Content filtering: Implement content safety filters to prevent harmful or inappropriate recommendations that could lead to user churn or brand damage.
- Output validation: Validate predicted conversion likelihood against business logic (e.g., ensuring probabilities are within [0,1] and align with historical conversion rates).
- Rate limiting: Implement rate limits on high-volume prediction requests to prevent abuse and ensure system stability.
- Red teaming: Regularly test the model with adversarial examples to identify potential safety gaps and bias amplification.
Model Card Documentation Plan
- Key components: Model architecture, training data sources, performance metrics, fairness assessment, limitations, usage guidelines, and version history.
- Distribution: Make model cards available in the internal ML model registry and accessible through the feature store UI.
- Update frequency: Update model cards with each major model release or when significant changes in performance/fairness are detected.
Incident Response Plan for Model Failures or Harmful Outputs
- Detection thresholds: Alert when conversion prediction accuracy drops below 90% of baseline or when fairness metrics exceed predefined thresholds (e.g., >5% difference in conversion rate prediction between demographic groups).
- Fallback strategy: Implement rule-based fallback for low-confidence predictions or when model drift is detected.
- Human review escalation: Route predictions with confidence scores below 0.3 or fairness violations to human review queue.
- Rollback procedure: Maintain versioned model artifacts and enable rapid rollback to previous stable versions if safety issues are detected in production.
- Communication protocol: Notify relevant stakeholders (product, ML, compliance) within 2 hours of incident detection and provide status updates every 4 hours until resolution.
# Example SHAP-based explanation for conversion prediction model
import shap
import numpy as np
class ConversionPredictionExplainability:
def __init__(self, model):
self.model = model
self.explainer = shap.Explainer(model)
def explain_prediction(self, user_features):
"""Generate SHAP explanation for a single prediction"""
shap_values = self.explainer(user_features)
# Get feature importance scores
feature_importance = np.abs(shap_values.values).mean(axis=0)
# Create explanation dictionary
explanation = {
"feature_names": self.get_feature_names(),
"importance_scores": feature_importance,
"top_features": self.get_top_features(feature_importance),
"prediction_confidence": self.get_prediction_confidence(user_features)
}
return explanation
def get_top_features(self, importance_scores, top_k=5):
"""Get top K most important features"""
top_indices = np.argsort(importance_scores)[-top_k:][::-1]
return [(self.feature_names[i], importance_scores[i])
for i in top_indices]
# Example usage:
# explainer = ConversionPredictionExplainability(model)
# explanation = explainer.explain_prediction(user_features)
Bias Mitigation Strategy
- Adaptive reweighting: Apply class balancing techniques that adjust for demographic distribution in training data.
- Fairness-aware regularization: Add fairness constraints to the model loss function during training to penalize disparate treatment across user groups.
- Regular fairness audits: Schedule monthly reviews of model performance across slices to detect and correct emerging biases.
Safety Guardrails Implementation
- Prediction confidence thresholds: Set minimum confidence levels (e.g., >0.7) for production use.
- Conversion probability bounds: Ensure predicted conversion probabilities remain within realistic ranges (0.01 to 0.99) to prevent extreme predictions.
- Cross-validation for bias detection: Use temporal cross-validation to detect if model performance varies significantly across different time periods or user segments.
10. Scalability & Reliability
Bottleneck Analysis per Pipeline Stage
Training Pipeline:
- Data ingestion: 100GB/day → 10TB/month → 300GB/hour peak processing
- Feature computation: 50M users × 100 features = 5B feature values per batch
- Model training: 1M samples × 100 features = 100M parameters, 20GB model size
- Back-of-envelope: 500ms inference per sample → 1M samples = 8.3 minutes total
Serving Pipeline:
- QPS target: 10,000 requests/sec
- Latency budget: 200ms total (retrieval: 50ms, scoring: 100ms, re-ranking: 50ms)
- Memory footprint: 20GB embedding matrix + 10GB model cache
- Cache hit ratio target: 95% for embeddings, 85% for predictions
Scale-up Strategy
Horizontal Scaling:
- Serving: Deploy 100 model instances across 10 regions with auto-scaling
- Feature computation: Use Ray or Dask for distributed feature extraction
- Training: Implement data parallelism across 16 GPUs with model parallelism for large models
Cross-region Serving:
- Primary region (US-West) handles 60% of traffic, secondary (EU) handles 40%
- Failover mechanism with 500ms graceful degradation
- Regional model replicas with sync every 15 minutes
Fault Tolerance
Model Serving Fallbacks:
- Primary model failure → fallback to last known good version (15s grace period)
- Cache miss → fallback to batch processing with 200ms latency penalty
- Feature store unavailability → use default feature values for 5min window
Stale Model Handling:
- Model version monitoring with automatic rollback to previous stable version
- 5-minute model freshness window with alerting for >10min staleness
- Graceful degradation to rule-based system when model fails
Cold Start Handling Strategy
New User Strategy:
- Default to popular item ranking with 80% confidence
- Use demographic features for initial ranking (age, location, device)
- Fallback to content-based filtering with 10% confidence boost
New Item Strategy:
- Default to trending items in same category
- Use item metadata embeddings for similarity matching (cosine similarity)
- Fallback to random selection with 5% confidence
Multi-region Serving Strategy
Traffic Distribution:
- US-West (primary): 60% of traffic, 100ms p99 latency target
- EU-East (secondary): 30% of traffic, 150ms p99 latency target
- Asia-Pacific: 10% of traffic, 200ms p99 latency target
Model Synchronization:
- Model versioning with 24-hour lag for cross-region sync
- Incremental model updates via Kafka streams
- Regional A/B testing with 10% traffic split per region
Failover Mechanism:
- 500ms automatic failover to secondary region on primary failure
- Health check every 30 seconds with 3x retry logic
- Graceful degradation to default ranking when region unavailable
Latency Budget Allocation:
| Stage | p50 | p99 | Budget |
|---|---|---|---|
| Feature Retrieval | 20ms | 50ms | 50ms |
| Model Inference | 50ms | 100ms | 100ms |
| Re-ranking | 10ms | 30ms | 30ms |
| Response Building | 5ms | 15ms | 15ms |
| Total | 85ms | 195ms | 200ms |
Capacity Planning:
- Peak QPS: 15,000 requests/sec (with 50% headroom)
- Model instances: 150 total across regions (100 primary, 30 secondary, 20 backup)
- Memory: 25GB per instance (embedding + model cache)
- Network bandwidth: 10Gbps per region for cross-region sync
11. Open Questions, Risks & Trade-offs
Decisions requiring product / engineering / policy alignment
- User consent and data collection boundaries - What level of user behavior tracking is permissible for conversion prediction? This affects feature set and data quality.
- Cross-platform user identification - Should we treat users across platforms as the same entity for conversion prediction? Impacts feature engineering and model training strategy.
- Conversion definition granularity - Should we predict micro-conversions (e.g., add to cart) or macro-conversions (e.g., purchase)? Affects model task definition and evaluation metrics.
- Real-time vs batch processing trade-off - How much latency can we tolerate for real-time conversion predictions in the user journey? Impacts serving architecture and feature freshness requirements.
- Model retraining cadence alignment - How frequently should we retrain models based on business cycles and data freshness? Affects training pipeline design and monitoring strategy.
Key ML risks
| Risk | Impact | Likelihood | Mitigation |
|---|---|---|---|
| Data drift in user behavior patterns | High - Model performance degradation | Medium - Seasonal trends, new product launches | Implement continuous drift monitoring, scheduled retraining |
| Class imbalance in conversion events | High - Poor recall for rare conversions | High - Conversion rates typically < 5% | Implement stratified sampling, weighted loss functions |
| Cold start problem for new users/items | Medium - Reduced prediction quality | High - New user/item onboarding | Implement hybrid rule-based + ML approach |
| Feedback loop contamination | Medium - Model bias from predictions affecting behavior | Medium - Prediction-driven user experience changes | Implement shadow mode, A/B testing for prediction impact |
| Latency spikes in serving | High - User experience degradation | Medium - System scaling issues | Implement prediction caching, auto-scaling, circuit breaker patterns |
Trade-offs made with justification
| Trade-off | Justification |
|---|---|
| Accuracy vs. latency - Prioritize low-latency serving over marginal accuracy gains | Conversion prediction must be sub-100ms for real-time personalization, with 50ms p99 target. Sacrificing 2-3% AUC for <50ms response time is acceptable |
| Freshness vs. cost - Batch feature computation over real-time | Real-time features require complex infrastructure and high cost. Batch features with 1-hour TTL provide >90% accuracy for most use cases |
| Model size vs. quality - Use model distillation over large transformer models | Production constraints limit model size to <50MB. Distilled models achieve 95% of full model performance with 80% size reduction |
| Online vs. batch serving - Hybrid approach with batch for cold start | Online serving for active users, batch for new users or when real-time features unavailable. Reduces complexity and cost |
| Feature richness vs. model interpretability - Prioritize model explainability over feature engineering | Business stakeholders require model explanations for trust and compliance. Simpler models with fewer features provide better interpretability |
Alternatives considered and rejected
| Alternative | Reason for rejection |
|---|---|
| Transformer-based models (e.g., BERT) | Too computationally expensive for real-time serving, 5x latency increase over DNN models |
| Ensemble of complex tree-based models | High model complexity and maintenance overhead, not justified by marginal accuracy gains |
| Full real-time feature computation pipeline | 3x infrastructure cost with minimal performance improvement over batch features |
| Rule-based fallback for all edge cases | Too brittle and hard to maintain; ML provides better generalization |
| Multi-task learning for multiple conversion types | Overcomplicated for initial MVP; single task model provides >90% of value |
Technical debt acknowledged
- Model versioning complexity - Current implementation uses simple timestamp-based versioning instead of comprehensive model registry with rollback capability
- Feature store maturity - Initial design assumes simple feature lookup; future evolution to full feature store with lineage tracking is needed
- Offline vs. online feature consistency - Risk of inconsistency between training and serving features due to different preprocessing pipelines
- Shadow mode limitations - Current shadow testing only logs predictions but doesn't capture actual impact on user behavior for model validation
- A/B testing infrastructure - Basic randomization unit (user ID) may not capture cross-platform behavior, requiring future expansion to session-based randomization
12. Phased Implementation Roadmap
Phase 1: MVP (Weeks 1-6)
Objective: Establish baseline prediction capability with minimal viable system.
Deliverables:
- Rule-based fallback system (session-based conversion probability)
- Basic ML model (logistic regression or GBM) trained on historical data
- Simple online serving infrastructure (single model endpoint)
- Basic A/B testing infrastructure
Dependencies:
- Data pipeline availability
- Feature store setup (basic)
- Model registry system
Critical Path:
- Data labeling and baseline model training (Weeks 1-2)
- Simple model deployment to serving infrastructure (Weeks 3-4)
- A/B test setup and initial experiment launch (Weeks 5-6)
Phase 2: Scale (Weeks 7-12)
Objective: Expand system to handle production scale and improve model quality.
Deliverables:
- Feature store with real-time and batch features
- Distributed training pipeline (data parallelism)
- Multi-model ensemble system (candidate retrieval + scoring)
- Advanced model architectures (DNN, Transformer)
- Shadow mode A/B testing capability
Dependencies:
- Feature store maturity
- Distributed training infrastructure
- Model versioning and registry
Critical Path:
- Feature store implementation (Weeks 7-8)
- Distributed training pipeline setup (Weeks 9-10)
- Ensemble model system deployment (Weeks 11-12)
Phase 3: Excellence (Weeks 13-18)
Objective: Achieve production-grade system with continuous improvement capabilities.
Deliverables:
- Real-time feature computation pipeline
- Online learning system for model updates
- Advanced monitoring and alerting system
- Multi-region serving capability
- Continuous model retraining pipeline with drift detection
Dependencies:
- Real-time feature infrastructure
- Model monitoring system maturity
- Multi-region deployment capability
Critical Path:
- Real-time feature pipeline (Weeks 13-14)
- Online learning system implementation (Weeks 15-16)
- Production monitoring and retraining pipeline (Weeks 17-18)
Risk Mitigation Strategy:
- Data Quality Risk: Implement data validation at each phase with drift detection
- Latency Risk: Monitor p99 latency throughout phases, implement caching at each stage
- Model Performance Risk: Maintain shadow mode A/B testing throughout all phases
- Scale Risk: Design horizontally scalable components from Phase 1
Success Criteria:
- Phase 1: 5% improvement over rule-based baseline
- Phase 2: 15% improvement over Phase 1 baseline with 90%+ model accuracy
- Phase 3: 25% improvement over Phase 1 baseline with real-time model updates and multi-region support
Resource Allocation:
- Phase 1: 2 ML Engineers, 1 SRE, 1 Data Engineer
- Phase 2: 3 ML Engineers, 2 SREs, 2 Data Engineers
- Phase 3: 4 ML Engineers, 3 SREs, 2 Data Engineers
Rollout Strategy:
- Phase 1: Internal testing with small user segment
- Phase 2: Gradual rollout to 10% of users with shadow mode
- Phase 3: Full production rollout with A/B testing and monitoring