DPTrainer
DPTrainer bridges Opacus and Hugging Face's Trainer ecosystem — including the alignment trainers in TRL (DPOTrainer, SFTTrainer, etc.) — so you can add DP-SGD to any Trainer-based workflow without rewriting training loops or modifying trainer source code.
The Problem
Opacus provides the building blocks for DP-SGD (per-sample gradients, DPOptimizer, privacy accountants, Poisson-sampled data loaders), but it is designed around a manual PyTorch training loop. Hugging Face Trainer is the dominant high-level training API for Transformers — and TRL extends it with alignment-specific trainers — but neither has any awareness of differential privacy.
Plugging Opacus into a Trainer-based pipeline requires coordinated changes across model wrapping, optimizer creation, data loading, loss computation, checkpointing, and callback management. These concerns interact in non-obvious ways, and getting any one of them wrong silently breaks the privacy guarantee.
What DPTrainer Handles
| Concern | Hugging Face Trainer / TRL | Opacus | DPTrainer |
|---|---|---|---|
| Optimizer creation | Internal; builds Adam/AdamW from TrainingArguments |
Wraps any optimizer in DPOptimizer |
Intercepts create_optimizer to wrap the HF-created optimizer with DPOptimizer |
| Gradient computation | Standard backprop (batch gradients) | Requires per-sample gradients via GradSampleModule |
Wraps the model in GradSampleModule before passing it to Trainer |
| Data loading | Standard DataLoader with fixed batches |
DPDataLoader for Poisson-sampled batches |
Overrides get_train_dataloader to return DPDataLoader when Poisson sampling is enabled |
| Privacy accounting | Not supported | Manual — user calls the accountant each step | Automatically tracks (ε, δ) via a DPCallback hooked into the optimizer step |
| Noise calibration | Not supported | User computes and passes noise_multiplier |
Automatically calibrates noise_multiplier from a target ε budget |
| Ghost clipping | Not supported | Provides DPLossFastGradientClipping primitive |
Wraps the loss function with ghost clipping and warns if subclass overrides could bypass it |
| Checkpointing | Saves model/optimizer/scheduler state | No checkpoint integration | Saves and restores accountant state with HF checkpoints for correct budget tracking across restarts |
| Early stopping | Generic EarlyStoppingCallback |
Not provided | Privacy-budget-aware early stopping that halts training when ε is exhausted |
Installation
uv pip install --index-url https://europe-west4-python.pkg.dev/jetbrains-ml4se-fed/jbr-fed-python/simple DPTrainer
Or with pip:
pip install --index-url https://europe-west4-python.pkg.dev/jetbrains-ml4se-fed/jbr-fed-python/simple DPTrainer
Quick Start — DPTrainer as a Drop-In Replacement
DPTrainer extends transformers.Trainer, so all standard training arguments, callbacks, checkpointing, and evaluation workflows work unchanged. Pass a PrivacyArguments instance to control the privacy budget:
from transformers import AutoModelForCausalLM, AutoTokenizer, TrainingArguments, DataCollatorForLanguageModeling
from dptrainer import DPTrainer, PrivacyArguments
model = AutoModelForCausalLM.from_pretrained("gpt2")
tokenizer = AutoTokenizer.from_pretrained("gpt2")
tokenizer.pad_token = tokenizer.eos_token
privacy_args = PrivacyArguments(
target_epsilon=8.0,
per_sample_max_grad_norm=1.0,
)
training_args = TrainingArguments(
output_dir="./output",
num_train_epochs=3,
per_device_train_batch_size=32,
)
trainer = DPTrainer(
model=model,
args=training_args,
train_dataset=train_dataset,
privacy_args=privacy_args,
data_collator=DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm=False),
)
trainer.train()
Privatizing Any Trainer (TRL, Seq2Seq, etc.)
DPTrainer works as a direct replacement for Trainer, but many workflows use specialized subclasses — TRL's DPOTrainer, SFTTrainer, Hugging Face's Seq2SeqTrainer, and others — that add task-specific logic on top of Trainer. Rewriting them to inherit from DPTrainer would be invasive and fragile.
The privatize_trainer utility solves this by patching any Trainer-based class at runtime, swapping Trainer for DPTrainer in its inheritance chain. The patched class keeps all of its original behavior (custom loss, generation logic, reward computation) while gaining differential privacy:
from trl import DPOTrainer
from transformers import TrainingArguments
from dptrainer import PrivacyArguments
from dptrainer import privatize_trainer
privacy_args = PrivacyArguments(
target_epsilon=8.0,
per_sample_max_grad_norm=1.0,
)
# One-line patch — DPOTrainer now trains with DP-SGD
privatize_trainer(DPOTrainer)
# Use DPOTrainer exactly as before — no other code changes needed
trainer = DPOTrainer(
model=model,
args=training_args,
train_dataset=train_dataset,
processing_class=tokenizer,
privacy_args=privacy_args,
)
trainer.train()
Note:
privatize_trainerpatches the trainer class, not a specific instance. It injectsDPTrainerinto the class hierarchy so that all future instances of that class train with DP-SGD. Use it once at import time or before constructing trainer instances.
Limitation:
privatize_trainerworks only on subclasses oftransformers.Trainer(e.g.,Seq2SeqTrainer,DPOTrainer,SFTTrainer). It cannot be called onTraineritself — doing so raises aValueError. If you want DP training with the baseTrainer, useDPTrainerdirectly as shown in the Quick Start section above.
When ghost clipping is enabled, privatize_trainer automatically inspects the patched class's MRO and warns if any intermediate class overrides compute_loss or training_step in a way that could bypass DPTrainer's loss wrapping.
PrivacyArguments Reference
| Parameter | Default | Description |
|---|---|---|
target_epsilon |
None |
Target ε at end of training. Mutually exclusive with noise_multiplier. |
target_delta |
None |
Target δ. Defaults to 1/N (dataset size). |
noise_multiplier |
None |
Explicit noise multiplier. Mutually exclusive with target_epsilon. |
per_sample_max_grad_norm |
0.5 |
Max L2 norm for per-sample gradient clipping. |
clipping |
"flat" |
Clipping strategy: "flat", "adaptive" (AdaClip), or "per_layer". |
poisson_sampling |
True |
Use Poisson sub-sampling for privacy amplification. |
grad_sample_mode |
"hooks" |
Opacus grad sample mode ("hooks" or "ew"). Use "ew" for ghost clipping. |
accountant |
"rdp" |
Privacy accountant type (passed to Opacus). |
epsilon_log_mode |
"eval" |
When to log the expended privacy budget: "none", "train", "eval", or "both". |
Docs
For detailed documentation, please visit the docs.
License
Licensed under the MIT License. See LICENSE.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dptrainer-0.1.2.tar.gz.
File metadata
- Download URL: dptrainer-0.1.2.tar.gz
- Upload date:
- Size: 90.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3651ba42ff8ee3dc9b29bd85d1d4f9078fdee7d12016900ac49a0829e9aae405
|
|
| MD5 |
0b9bdabee0ad99ab951b19790e67cad5
|
|
| BLAKE2b-256 |
4d6fd7dd61ace4014bcd4819163a7ed1bc5647dfbd6bd913411e13a41e721e0f
|
Provenance
The following attestation bundles were made for dptrainer-0.1.2.tar.gz:
Publisher:
release-package.yaml on JetBrains-Research/DPTrainer
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dptrainer-0.1.2.tar.gz -
Subject digest:
3651ba42ff8ee3dc9b29bd85d1d4f9078fdee7d12016900ac49a0829e9aae405 - Sigstore transparency entry: 2420146781
- Sigstore integration time:
-
Permalink:
JetBrains-Research/DPTrainer@e7c95a6064cf06c7afbc52099bf0bdb437d1b17e -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/JetBrains-Research
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-package.yaml@e7c95a6064cf06c7afbc52099bf0bdb437d1b17e -
Trigger Event:
push
-
Statement type:
File details
Details for the file dptrainer-0.1.2-py3-none-any.whl.
File metadata
- Download URL: dptrainer-0.1.2-py3-none-any.whl
- Upload date:
- Size: 15.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
08be90bed8a2ae77f4c7cd29d7d2bd3fa29b17b53daf81446536f2029a53ffbb
|
|
| MD5 |
2fe18a64c458262911c6e621b9ffea16
|
|
| BLAKE2b-256 |
c3bdfd58acdcbb290ce7d66122f5517a32fc38e7064b0c4aa7c5d8ffdc91c9ef
|
Provenance
The following attestation bundles were made for dptrainer-0.1.2-py3-none-any.whl:
Publisher:
release-package.yaml on JetBrains-Research/DPTrainer
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dptrainer-0.1.2-py3-none-any.whl -
Subject digest:
08be90bed8a2ae77f4c7cd29d7d2bd3fa29b17b53daf81446536f2029a53ffbb - Sigstore transparency entry: 2420146876
- Sigstore integration time:
-
Permalink:
JetBrains-Research/DPTrainer@e7c95a6064cf06c7afbc52099bf0bdb437d1b17e -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/JetBrains-Research
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-package.yaml@e7c95a6064cf06c7afbc52099bf0bdb437d1b17e -
Trigger Event:
push
-
Statement type: