Library / SDK
meta-pytorch/opacus avatar
meta-pytorch/opacus

Opacus: Adding Differential Privacy to an Existing PyTorch Training Loop

Training PyTorch models with differential privacy

1,959 stars396 forksPythonApache-2.0

At a glance

What is it?
Opacus wraps a PyTorch model, optimizer and DataLoader behind a PrivacyEngine and trains with DP-SGD. It is a small API surface over a large change in what a training step means, and the memory and accuracy costs are where adoption decisions get made.
Who is it for?
Adopt Opacus when you already have a working PyTorch training script and need DP-SGD without rewriting it: the PrivacyEngine wrapper and the make_private call are the whole migration. Do not adopt it if you need formal DP guarantees for arbitrary models or non-DP-SGD mechanisms, or if your architecture trips the module validator and you cannot restructure it.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 64 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The problem Opacus solves is the gap between a normal training loop and DP-SGD

DP-SGD is not a loss function you can swap in. It changes the gradient computation itself: gradients are computed per sample rather than per batch, each per-sample gradient is clipped to a maximum norm, and calibrated noise is added before the optimizer step. Implementing that by hand means rewriting the backward pass, tracking a privacy budget across steps, and getting the accounting right. Opacus exists to absorb that work. The README states the library supports training with minimal code changes on the client, has little impact on training performance, and lets the client track the privacy budget expended at any moment. The audience is stated explicitly: ML practitioners who want a gentle introduction to training with differential privacy, and DP researchers who want to experiment without rebuilding the mechanics. If you are in neither group, the library is probably not aimed at you.

PrivacyEngine.make_private is the entire integration point

The README gives the canonical example. You define your model, optimizer and DataLoader as usual, then construct a PrivacyEngine and call make_private with the module, optimizer, data_loader, noise_multiplier and max_grad_norm. The method returns private counterparts of all three, and the README's comment after the call is "Now it's business as usual". That is the data flow: your objects go in, wrapped versions come out, and the training loop keeps calling optimizer.step() and iterating the loader. Underneath, the wrapped module computes per-sample gradients, the wrapped optimizer applies clipping and noise, and the wrapped loader handles the sampling that the privacy accounting assumes. The two parameters in the call are the ones that determine the privacy-utility trade-off: max_grad_norm is the clipping threshold, noise_multiplier scales the Gaussian noise added to the summed gradients. Both are your responsibility to choose. The README does not tell you how to choose them, and that is the honest shape of the library: it gives you the mechanism and an accountant, not a recommended operating point.

Per-sample gradients are the cost, and clipping is the mitigation

The obvious expense of DP-SGD is that you cannot use the standard batched backward pass. Per-sample gradients need more memory than a single averaged gradient, and for large models that is the constraint that decides whether DP training is feasible on your hardware. The README's latest updates note that Fast Gradient Clipping and Ghost Clipping were introduced in August 2024, described as significantly reducing the memory requirements of DP-SGD, with a PyTorch blog post linked for detail. That is a real change to the feasibility envelope, but the README does not quantify it, and the blog post is where the numbers live. Treat the memory reduction as directionally true from the release notes and measure it on your own model. The other design lever is the gradient sampler. The README lists a dedicated tutorial, guide_to_grad_sampler.ipynb, which implies the per-sample gradient computation is pluggable rather than fixed. If you are memory-bound, that is the first place to look after reading the clipping blog post.

The module validator is a gate you should hit before training, not after

Opacus works by wrapping modules, and not every PyTorch module can be wrapped. The README includes a tutorial called guide_to_module_validator.ipynb, which points at a validator and a fixer. The existence of a fixer tells you the intended workflow: run the validator, find the modules Opacus cannot handle, and either replace them with supported equivalents or accept that the model needs restructuring. This is the most likely place a migration stalls. Custom layers, unusual normalization, or anything that does not expose the hooks the per-sample gradient machinery needs will surface here. The README also lists a non-wrapping mode tutorial, non_wrapping_mode.ipynb, which is the alternative path when wrapping is undesirable. Between the validator, the fixer and non-wrapping mode, there are three distinct ways to handle a model that does not fit cleanly, and which one applies depends on your architecture. Read the validator tutorial before you estimate effort.

Installation and the version you are actually running

Installation is one of two package manager commands. The README gives pip install opacus and, as an alternative, conda install -c conda-forge opacus. For unreleased features it documents cloning the repository and running pip install -e . from inside the checkout, with the caveat that this brings quirks and potentially occasional bugs. The release cadence is worth noting for planning. The most recent release listed is v1.6.0 from May 2026, preceded by v1.5.4 in May 2025 and v1.5.3 in February 2025. That is roughly one minor release a year with patch releases in between, and the repository shows a push in July 2026, so the project is active. Pin the version explicitly in your environment file. A DP training run is sensitive to the accounting implementation, and the accountant is part of the library, so an unpinned upgrade can change your reported epsilon without changing your code. That is a reason to treat Opacus upgrades as something you re-validate rather than something you absorb silently.

What Opacus does not do for you

The library implements DP-SGD and its variants. It does not make a model differentially private in any sense beyond what the training procedure provides. If your threat model includes membership inference against a model trained without DP, Opacus is not a patch you apply afterward. It also does not choose your privacy budget. The noise_multiplier and max_grad_norm values in the example, 1.1 and 1.0, are illustrative for MNIST, and the README presents them without claiming they generalize. A second limitation is scope: DP-SGD assumes the privacy unit is the training example, and if your data has structure where one individual contributes many records, the guarantee is not what you want without group-level accounting. Nothing in the supplied material addresses that case. A third is that Opacus is a PyTorch library, full stop. If your training stack is not PyTorch, none of this transfers.

TensorFlow Privacy is the natural comparison, and the difference is in the wrapper

The most direct alternative is TensorFlow Privacy, which implements DP-SGD for TensorFlow. The difference in approach is not the algorithm, which is the same, but the integration model. TensorFlow Privacy ships a DP optimizer that you substitute for the standard optimizer and a privacy accountant you query separately. Opacus inverts that: the PrivacyEngine takes your existing model, optimizer and loader, and returns wrapped versions, so the training loop is untouched and the DP machinery is injected at the object level. If you are already on PyTorch, the Opacus route means your loop, your scheduler and your logging stay where they are. If you are on TensorFlow, the reverse holds. For researchers who want to swap in a different gradient sampler or accountant, Opacus exposes those as components with dedicated tutorials, which is closer to a research framework than a drop-in optimizer. That is a real distinction: one is an optimizer you adopt, the other is a wrapper you attach.

Licence, maintenance and what to verify before you commit

Opacus is released under Apache-2.0, as stated in the README and the LICENSE file. Apache-2.0 is permissive and includes an explicit patent grant, which matters for a library that may end up inside a product. It does not, however, grant you anything about the privacy claims of your trained model. The licence covers the code, not the guarantee. On maintenance, the release history shows a steady cadence and the repository is not archived. The cost of upgrading is the accountant: because epsilon depends on the library's implementation of the privacy accounting, a version bump can change reported numbers even when your hyperparameters do not. Before adopting, verify three things. Run the module validator against your actual model and confirm the fixer path is acceptable to you. Measure per-sample gradient memory at your real batch size, since the README's claims about Fast and Ghost Clipping are not quantified there. And compute the epsilon your chosen noise_multiplier and delta produce with the accountant in the version you pinned, rather than trusting the example values.

Editorial conclusion

Adopt Opacus when you already have a working PyTorch training script and need DP-SGD without rewriting it: the PrivacyEngine wrapper and the make_private call are the whole migration. Do not adopt it if you need formal DP guarantees for arbitrary models or non-DP-SGD mechanisms, or if your architecture trips the module validator and you cannot restructure it. Before committing, run the validator over your model, measure per-sample gradient memory against your real batch size, and check the epsilon your chosen noise_multiplier and delta actually produce with your accountant.

Official sources

  1. License: Apache-2.0
  2. meta-pytorch/opacus on GitHub
  3. Project website
  4. README
  5. Releases
Community notes

Community notes