Skip to main content

A package for applying differential privacy to model training using gradient shuffling and membership inference attack detection.

Project description

๐Ÿ›ก๏ธ ForgetNet: Differentially Private Block-wise Gradient Shuffle for Deep Learning ๐Ÿง 

PyPI version License: MIT

ForgetNet introduces a novel privacy-preserving technique for deep learning: Differentially Private Block-wise Gradient Shuffle (DP-BloGS). ๐Ÿ”’๐Ÿ”€

๐ŸŒŸ Features

  • ๐Ÿš€ Fast training times, close to non-private training
  • ๐ŸŽฏ Competitive privacy guarantees compared to DP-SGD
  • ๐Ÿ“Š Better privacy-utility trade-off in many scenarios
  • ๐Ÿ‹๏ธ Scalable to large models (tested up to 1.1 billion parameters)
  • ๐Ÿงฎ Parameter-wise privacy budget allocation

๐Ÿ“ฆ Installation

pip install forgetnet

๐Ÿš€ Quick Start BloGSSFTTrainer

from forgetnet import BloGSSFTTrainer
from transformers import AutoModelForCausalLM, AutoTokenizer

# Load your model and tokenizer
model = AutoModelForCausalLM.from_pretrained("gpt2")
tokenizer = AutoTokenizer.from_pretrained("gpt2")

# Initialize the DP-BloGS trainer
trainer = BloGSSFTTrainer(
    model=model,
    args=training_args,
    train_dataset=train_dataset,
    eval_dataset=eval_dataset,
    tokenizer=tokenizer,
    dataset_text_field="text",
    target_epsilon=1.0,
    delta=1e-5,
    clip_value=1.0
)

# Train your model with privacy guarantees
trainer.train()

๐Ÿš€ Quick Start with Privacy Engine and ResNet

Here's how to use the BloGS Privacy Engine with a ResNet model for MNIST classification:

import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
from torchvision.models import resnet18
from torch.utils.data import DataLoader
from forgetnet import BloGSPrivacyEngine

# Modify ResNet18 for MNIST (1 channel input instead of 3)
def mnist_resnet18():
    model = resnet18()
    model.conv1 = nn.Conv2d(1, 64, kernel_size=7, stride=2, padding=3, bias=False)
    model.fc = nn.Linear(model.fc.in_features, 10)  # 10 classes for MNIST
    return model

# Hyperparameters
batch_size = 64
learning_rate = 0.01
epochs = 10
target_epsilon = 1.0
delta = 1e-5
clip_value = 1.0

# Device
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

# Load MNIST dataset
transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.1307,), (0.3081,))
])
train_dataset = datasets.MNIST('./data', train=True, download=True, transform=transform)
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)

# Calculate total_iterations based on dataset size
total_iterations = (len(train_dataset) // batch_size) * epochs

# Initialize model
model = mnist_resnet18().to(device)

# Initialize optimizer
optimizer = optim.SGD(model.parameters(), lr=learning_rate)

# Wrap the optimizer with the PrivacyEngine
privacy_engine = BloGSPrivacyEngine(
    optimizer=optimizer,
    model=model,
    target_epsilon=target_epsilon,
    delta=delta,
    clip_value=clip_value,
    steps=total_iterations,
    batch_size=batch_size
)

# Training loop
model.train()
for epoch in range(epochs):
    for batch_idx, (data, target) in enumerate(train_loader):
        data, target = data.to(device), target.to(device)
        privacy_engine.zero_grad()
        output = model(data)
        loss = nn.functional.cross_entropy(output, target)
        loss.backward()

        epsilon_spent, delta = privacy_engine.step()

        if batch_idx % 100 == 0:
            print(f'Epoch {epoch}, Batch {batch_idx}, Loss: {loss.item():.4f}, Epsilon: {epsilon_spent:.4f}')

# Get total privacy spent after training
total_epsilon_spent = privacy_engine.get_privacy_spent()
print(f"Total privacy spent: ฮต = {total_epsilon_spent:.4f}")

This example demonstrates:

  1. Setting up a ResNet18 model modified for MNIST
  2. Loading the MNIST dataset
  3. Initializing the PrivacyEngine with the model and optimizer
  4. Training the model with privacy-preserving gradient updates
  5. Monitoring privacy budget expenditure during training

Adjust hyperparameters as needed for your specific use case.

๐Ÿ“š How It Works

DP-BloGS introduces a probabilistic approach to gradient noise through block-wise shuffling:

  1. ๐Ÿ“Š Divide gradients into blocks
  2. ๐Ÿ”€ Shuffle blocks randomly
  3. ๐Ÿ“ Apply layer-specific block sizes
  4. โœ‚๏ธ Use batch layer clipping
  5. ๐Ÿงฎ Accumulate gradients

This combination allows for fast training while maintaining strong privacy guarantees!

๐Ÿ“ˆ Performance

DP-BloGS has been tested on various model architectures, including:

  • GPT-2 (124M)
  • BERT (110M)
  • OPT (350M)
  • BLOOM (560M)
  • TinyLlama (1.1B)

Results show competitive or better performance compared to DP-SGD in terms of:

  • ๐Ÿƒโ€โ™‚๏ธ Training speed
  • ๐ŸŽญ Privacy guarantees
  • ๐Ÿ“Š Model utility

๐Ÿ•ต๏ธ Membership Inference Attack (MIA)

ForgetNet now includes a powerful Membership Inference Attack tool to assess the privacy risks of your language models:

๐Ÿš€ Quick Start

from forgetnet import LanguageMIA

# Initialize the MIA tool
mia = LanguageMIA()

# Perform the attack
results = mia.attack(train_dataset, test_dataset, model, tokenizer)

# Print the results
print(f"ROC AUC: {results['roc_auc']:.4f}")
print(f"Precision-Recall AUC: {results['precision_recall_auc']:.4f}")
print(f"Best model: {results['best_model']}")
print(f"Optimal threshold: {results['optimal_threshold']:.4f}")

๐Ÿ“Š Comprehensive Evaluation

The LanguageMIA class provides a detailed analysis of your model's vulnerability to membership inference attacks:

  • ๐ŸŽฏ ROC AUC: Measures the overall performance of the attack
  • ๐Ÿ“ˆ Precision-Recall AUC: Assesses the trade-off between precision and recall
  • ๐Ÿง  Best Model: Identifies the most effective attack model
  • ๐Ÿ” Optimal Threshold: Determines the best decision threshold for classification
  • ๐Ÿ“‰ Standard and Optimal Metrics: Provides accuracy, precision, recall, and F1 score for both standard (0.5) and optimal thresholds

๐Ÿ› ๏ธ Integration with Model Evaluation

Easily incorporate MIA into your model evaluation pipeline:

def evaluate_model(model, train_dataset, test_dataset, tokenizer):
    # Perform membership inference attack
    mia = LanguageMIA()
    mia_results = mia.attack(train_dataset, test_dataset, model, tokenizer)

    # Evaluate perplexity (assuming a function evaluate_perplexity exists)
    perplexity = evaluate_perplexity(model, test_dataset, tokenizer)

    # Combine results
    results = {
        'perplexity': perplexity,
        'mia_results': mia_results,
    }

    return results

# Usage
evaluation_results = evaluate_model(model, train_dataset, test_dataset, tokenizer)
print(f"Model Perplexity: {evaluation_results['perplexity']:.2f}")
print(f"MIA ROC-AUC: {evaluation_results['mia_results']['roc_auc']:.4f}")

๐ŸŽฏ Benefits

  • ๐Ÿ”’ Quantify Privacy Risks: Understand your model's vulnerability to membership inference attacks
  • ๐Ÿ“ˆ Track Improvements: Monitor how privacy-preserving techniques affect model privacy
  • ๐Ÿš€ Optimize Trade-offs: Fine-tune the balance between utility and privacy in your models

Use the LanguageMIA tool to ensure your language models are both powerful and privacy-preserving!

๐Ÿ“„ Citation

If you use ForgetNet in your research, please cite my paper:

@article{zagardo2024dpblogs,
  title={Differentially Private Block-wise Gradient Shuffle for Deep Learning},
  author={Zagardo, David},
  journal={arXiv preprint arXiv:2407.21347},
  year={2024},
  note={arXiv:2407.21347 [cs.LG]}
}

๐Ÿค Contributing

We welcome contributions! Please see my CONTRIBUTING.md for details on how to get started.

๐Ÿ“œ License

This project is licensed under the MIT License - see the LICENSE file for details.

๐Ÿ™ Acknowledgements

We thank the open-source community and the authors of the papers cited in our work for their valuable contributions to the field of privacy-preserving machine learning.


Built with ๐Ÿง  by David Zagardo

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

forgetnet-0.1.21.tar.gz (21.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

forgetnet-0.1.21-py3-none-any.whl (20.2 kB view details)

Uploaded Python 3

File details

Details for the file forgetnet-0.1.21.tar.gz.

File metadata

  • Download URL: forgetnet-0.1.21.tar.gz
  • Upload date:
  • Size: 21.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.11.4

File hashes

Hashes for forgetnet-0.1.21.tar.gz
Algorithm Hash digest
SHA256 6c9651abe920cfe4870fb6e102448c19e3ce1e3557466e4fc1c39f545746f1dd
MD5 3984d487bdab62c9130115e4cb74cc6f
BLAKE2b-256 a8b9acf13250caab3c851bdb1d468ea2307c4d4af6aff49d04a8f16787df54fd

See more details on using hashes here.

File details

Details for the file forgetnet-0.1.21-py3-none-any.whl.

File metadata

  • Download URL: forgetnet-0.1.21-py3-none-any.whl
  • Upload date:
  • Size: 20.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.11.4

File hashes

Hashes for forgetnet-0.1.21-py3-none-any.whl
Algorithm Hash digest
SHA256 185c4365c6906ade83f19511cff9d7051108fea2e3f00cf65e508ef6c723544b
MD5 9c69d5a5adac3b9033bc48404237adac
BLAKE2b-256 020fb2cbf4a1346bcc1fd4198946cb09bcf5e7a46564e447f2455571d6b91645

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page