OUBS is a unified framework for reproducible comparison of unlearning methods across multiple domains and deletion scenarios. The benchmark is designed with modularity and extensibility in mind, enabling both practical evaluation and research-oriented insights.
The Open Unlearning Benchmark Suite (OUBS) provides a standardized platform for evaluating machine unlearning methods across:
- 2 Baseline Methods: Retrain from Scratch + SISA
- 2 Datasets: CIFAR-10 (images) + Purchase100/Texas100 (tabular)
- 2 Deletion Scenarios: Random + Cluster-based
- 3 Evaluation Dimensions: Effectiveness, Utility, Efficiency
- Features
- Project Structure
- Installation
- Quick Start
- Usage Examples
- Evaluation Metrics
- Extending the Benchmark
- Results
- Citation
- Effectiveness: Membership inference attacks, model distance metrics
- Utility: Accuracy, F1-score, calibration, per-class fairness
- Efficiency: Training time, memory usage, computational cost
- Easy to add new datasets
- Simple to implement new unlearning methods
- Flexible deletion scenario generators
- Seed-based reproducibility
- Automated experiment tracking
- JSON-formatted results
- Command-line interface
- Comprehensive logging
oubs/
├── data/ # Dataset loaders
│ ├── cifar_loader.py # CIFAR-10 loader with index tracking
│ └── purchase_loader.py # Purchase100/Texas100 loader
│
├── models/ # Model architectures
│ ├── cifar_cnn.py # CNN for CIFAR-10
│ ├── purchase_mlp.py # MLP for tabular data
│ └── trainer.py # Unified training utilities
│
├── deletion_scenarios/ # Deletion strategy generators
│ ├── random.py # Random deletion
│ └── cluster.py # Cluster-based deletion
│
├── methods/ # Unlearning methods
│ ├── retrain/
│ │ └── retrain_baseline.py # Retrain from scratch
│ └── sisa/
│ └── sisa.py # SISA implementation
│
├── evaluation/ # Evaluation metrics
│ ├── effectiveness.py # MIA, model distance
│ ├── utility.py # Accuracy, fairness
│ └── efficiency.py # Time, resources
│
├── experiments/ # Experiment runners
│ ├── run_cifar.py # CIFAR-10 experiments
│ └── run_purchase.py # Purchase100 experiments
│
├── results/ # Experiment outputs
└── requirements.txt # Dependencies
- Python 3.10+ (tested with 3.13)
- GPU recommended (CUDA or Apple Silicon with MPS support)
# Clone the repository
git clone https://github.com/ndminhvn/oubs.git
cd oubs
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install dependencies
pip install --upgrade pip
pip install -r requirements.txt
# For CUDA support (NVIDIA GPUs), install PyTorch with CUDA (refer to https://pytorch.org/get-started/locally/)
# pip install torch torchvision --index-url https://download.pytorch.org/whl/cu130Note: The benchmark automatically detects and uses the best available device (CUDA, MPS, or CPU).
python experiments/run_cifar.py \
--method retrain \
--deletion random \
--num_delete 500 \
--epochs 50 \
--verbosepython experiments/run_cifar.py \
--method sisa \
--deletion cluster \
--delete_percent 5 \
--shards 10 \
--epochs 50python experiments/run_purchase.py \
--dataset purchase100 \
--method sisa \
--deletion random \
--delete_percent 1 \
--shards 10- Use
--delete_percent 1for 1% deletions or--delete_ratio 0.01if you prefer fractional inputs. - Percentage / ratio arguments override
--num_delete; the framework computes the exact sample count per dataset. - Config files now record the resolved deletion summary (percent + absolute count) to streamline experiment tracking.
python experiments/run_cifar.py \
--method retrain \
--deletion random \
--delete_percent 2 \
--epochs 50 \
--lr 0.001 \
--batch_size 128 \
--save_models \
--output_dir ./results/retrain_randompython experiments/run_cifar.py \
--method sisa \
--deletion cluster \
--delete_ratio 0.02 \
--cluster_method class-based \
--shards 10 \
--epochs 50 \
--save_modelspython experiments/run_purchase.py \
--dataset purchase100 \
--method sisa \
--deletion cluster \
--delete_percent 1 \
--shards 15 \
--epochs 40 \
--lr 0.0005 \
--hidden_dims 256 128 64 \
--exp_name purchase_sisa_clusterMeasures how well deleted data's influence is removed:
- Membership Inference Attack (MIA): Lower AUC = better unlearning
- Attack Accuracy / Threshold: Reported alongside AUC to show how confident an adversary could be
- Model Distance: KL/JS divergence to retrain baseline
- Confidence Gap & Variance: Difference in means plus per-group std devs to diagnose residual leakage
Evaluates performance on remaining data:
- Test Accuracy: Classification accuracy
- F1-Score: Macro and weighted F1
- Expected Calibration Error (ECE): Model calibration
- Fairness: Per-class accuracy variance
Quantifies computational cost:
- Training Time: Total time for unlearning
- Speedup: Relative to retrain baseline
- Memory Usage: Peak RAM/GPU memory
- Model Parameters: Number of retrained parameters
- Shard Coverage: Fraction of SISA shards touched during unlearning
- Create a loader in
data/:
class NewDatasetLoader:
def __init__(self, data_dir, seed=42):
# Load data
pass
def get_loaders(self, batch_size):
# Return train, val, test loaders
pass
def get_train_indices(self):
# Return all training indices
pass-
Create corresponding model in
models/ -
Create experiment runner in
experiments/
- Create method file in
methods/your_method/:
class YourMethod:
def __init__(self, model_fn, device):
self.model_fn = model_fn
self.device = device
def unlearn(self, delete_indices, retain_loader, ...):
# Implement unlearning logic
return unlearned_model, metrics- Import and integrate into experiment runners
Create scenario file in deletion_scenarios/:
def select_your_deletion(all_indices, num_delete, **kwargs):
# Generate deletion indices
delete_indices = ...
retain_indices = ...
return delete_indices, retain_indices, infoResults are saved as JSON files with the following structure:
{
"config": {
"method": "sisa",
"deletion": "cluster",
"num_delete": 500,
"delete_percent": 1.0,
"deletion_summary": "1% (500/50000 samples)",
"total_train_samples": 50000
},
"utility_metrics": {
"test_accuracy": 0.8542,
"f1_macro": 0.8498,
"ece": 0.0234
},
"effectiveness_metrics": {
"mia_auc": 0.5123,
"mia_attack_accuracy": 0.541,
"mia_attack_threshold": 0.7621,
"kl_divergence_to_retrain": 0.0045
},
"efficiency_metrics": {
"training_time": 234.56,
"unlearn_time": 45.67,
"speedup_vs_full": 5.14,
"shard_fraction": 0.2
}
}Once experiments finish, aggregate every results.json into publication-ready artifacts:
python scripts/py/generate_benchmark_report.py \
--results_dir ./results/benchmark_suite \
--output_dir ./results/benchmark_suite/overall/analysisThis produces:
summary_table.csv/benchmark_report.md: human-readable overview with deltas vs. retrainresults_table.tex: LaTeX-ready table for papers*_comparison.(png|pdf)plusradar_*.pdf: figures covering effectiveness, utility, efficiency, and trade-offs
| Dataset | Method | Deletion | Status |
|---|---|---|---|
| CIFAR-10 | Retrain | Random | ✅ |
| CIFAR-10 | Retrain | Cluster | ✅ |
| CIFAR-10 | SISA | Random | ✅ |
| CIFAR-10 | SISA | Cluster | ✅ |
| Purchase100 | Retrain | Random | ✅ |
| Purchase100 | Retrain | Cluster | ✅ |
| Purchase100 | SISA | Random | ✅ |
| Purchase100 | SISA | Cluster | ✅ |
We welcome contributions! Areas for improvement:
- Additional unlearning methods (e.g., gradient ascent, influence functions)
- More datasets (ImageNet, NLP datasets)
- Advanced deletion scenarios
- Additional evaluation metrics
- Performance optimizations
- SISA implementation based on Bourtoule et al. "Machine Unlearning" (2021)
- Purchase100/Texas100 datasets from Purchase100-Texas100-datasets
- Inspired by various machine unlearning research
- Minh Nguyen: GitHub
- Project Issues: GitHub Issues
Status: Active Development | Version: 1.0.0 | Last Updated: December 2025