Pyro: deep probabilistic programming on PyTorch, and where it gets awkward
Deep universal probabilistic programming with Python and PyTorch
At a glance
- What is it?
- Pyro is a universal probabilistic programming library built on PyTorch, aimed at people who want Bayesian inference inside a normal deep learning stack. It installs with a single pip command, but the real cost is in choosing an inference strategy.
- Who is it for?
- Pyro suits people already fluent in PyTorch who need custom inference, discrete latent variables, or models that do not fit a fixed inference engine. It is the wrong tool if you want a sampler that just runs, or if you cannot commit to writing and debugging guides.
- 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 23 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 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Pyro actually solves for a PyTorch user
A PyTorch model gives you a differentiable function and an optimizer. It does not give you a way to express uncertainty about the parameters themselves, and it does not give you a principled way to fit a model whose latent variables are discrete. Pyro fills that gap by adding a small set of primitives to ordinary Python and PyTorch code. The README describes the library as "a flexible, scalable deep probabilistic programming library built on PyTorch", and lists four design principles: universal, scalable, minimal, flexible.
The audience is narrow and specific. If you already write PyTorch modules, you keep them. Pyro does not ask you to learn a new tensor library or a new autodiff system. What it asks you to learn is a second vocabulary: how to mark random choices, and how to describe the distribution that approximates the posterior. That second part is where most of the work lives, and the README is explicit that Pyro "aims for automation when you want it, control when you need it".
The project was originally developed at Uber AI, is now maintained by community contributors including a team at the Broad Institute, and became a Linux Foundation project in 2019. The last push to the repository was on 2026-09-07, so the codebase is still moving; the most recent tagged release listed is 1.9.1 from 2024-06-02, which means the release cadence and the commit cadence are not the same thing.
Random choices, guides, and the two programs you write
Pyro's mechanism is easiest to see in the smallest example the repository ships. The file examples/minipyro.py exists precisely to show the core in a compact form: a model function that samples latent values, a guide function that samples from an approximating distribution, and an optimizer that pushes the guide toward the model's posterior.
Every latent variable in a Pyro model is created through the primitives package, which wraps PyTorch distributions. When you call a sample statement, Pyro records the value and the log probability into an effect handler stack. That stack is what makes the same model function usable for prior sampling, for running a guide, and for computing an evidence lower bound, without rewriting the model.
The guide is the part newcomers underestimate. Pyro does not derive the variational family for you in the general case. You write a second function whose sample statements mirror the model's latent sites, and the quality of your posterior approximation is bounded by how well that guide matches the true posterior. For continuous latents with a mean-field guide this is usually fine. For strongly correlated posteriors, a diagonal guide will understate uncertainty, and no amount of optimizer steps fixes that. This is the design trade-off at the center of the library: flexibility in exchange for the user carrying the modeling burden.
For models where you do not want to hand-write a guide, Pyro also exposes MCMC through the same model function. The examples directory includes examples/sir_hmc.py and examples/neutra.py, which show Hamiltonian Monte Carlo and a learned reparameterization respectively. The same random-choice machinery drives both inference families.
Installing Pyro and running a first inference step
The README gives the stable install as a single pip command. It pulls in torch>=2.0, numpy, opt_einsum, pyro-api and tqdm as declared dependencies in pyproject.toml.
pip install pyro-pplIf you plan to run the models under examples/ or the notebooks under tutorial/, the README asks you to install the extra dependency group instead, and warns that the models must come from the same release version of the Pyro source as the library you installed.
pip install pyro-ppl[extras]There is also a dev install path straight from the repository, which the README recommends when you need recent features. Note that the README's source-build snippet checks out master, while the repository's default branch is dev.
git clone https://github.com/pyro-ppl/pyro
cd pyro
pip install .Once installed, the smallest real use is a model with one latent, a guide, and a short optimization loop. The repository's examples/minipyro.py is the canonical walkthrough of exactly this, and the tutorial notebooks under tutorial/ cover the same ground with more narrative. A first run should print an increasing evidence lower bound across iterations; if the number is flat, the usual cause is a guide that cannot represent the posterior rather than a bug in the optimizer.
Where Pyro is the wrong tool
Pyro does not do inference for you. That sentence is the whole limitation. If your model has a latent structure you cannot write a reasonable guide for, and you also cannot afford the runtime of MCMC over your dataset, Pyro leaves you without a third option. The README's claim of scalability is about overhead relative to hand-written code, not about removing the need to choose an inference algorithm.
The second limitation is version coupling. The README states that models should come from the same release version as the installed library, and the repository's Makefile pins the development install to an editable strict mode with several dependency groups. If you copy a model from a tutorial written against an older release and run it against a newer one, the failure mode is not always an exception. Sometimes a site name changes and your guide silently stops matching the model, which shows up as a posterior that never moves.
The third is scope. Pyro is a Python library, and pyproject.toml lists Linux and macOS classifiers only. If your deployment target is a JVM service or a pure C++ inference binary, Pyro is not the component you want, regardless of how well the model fits. The repository does ship a docker/ directory with its own README for containerized runs, which is the documented path for isolating the environment.
Pyro compared with NumPyro
NumPyro is the natural comparison and the one people search for. It shares the same modeling vocabulary, the same sample-statement style, and largely the same tutorial material, but it is built on JAX rather than PyTorch. That single substitution changes everything downstream.
With JAX, models compile through jit and vectorize through vmap, so a sampler written once can be batched across chains without rewriting the model. With Pyro, you are inside PyTorch's eager execution model, which means you get direct access to the PyTorch ecosystem: torchvision, existing nn.Module code, Lightning via the examples/svi_lightning.py example, and Horovod via examples/svi_horovod.py. Neither is strictly better. If your existing code is PyTorch and your team knows it, Pyro avoids a second framework. If you are starting from scratch and want compiled samplers, NumPyro is the shorter path. The repository itself acknowledges the overlap by keeping the two projects' example sets closely aligned.
A second alternative worth naming is writing the inference yourself with PyTorch distributions. That works for a model with two or three latents and a closed-form guide. It stops working the moment you need discrete latents or a nontrivial posterior geometry, which is exactly the territory Pyro's effect-handler design was built to cover.
Licence, maintenance, and what an upgrade costs
Pyro is Apache-2.0, declared in pyproject.toml with license-files pointing at LICENSE.md, and the repository also carries a LICENSES/ directory. The README's source files carry SPDX headers, and the Makefile has a license target that runs scripts/update_headers.py to keep them in place. Apache-2.0 is permissive and includes an explicit patent grant, which matters if you are embedding the library in a commercial product. This is a description of the licence text, not legal advice; your own counsel decides what it means for your distribution.
The maintenance picture is mixed and worth stating plainly. The last push was on 2026-09-07, so commits are recent. The newest release listed is 1.9.1 from 2024-06-02, so tagged releases are much less frequent than commits. If you depend on released artifacts, expect to sit on a version for a while. The repository has a RELEASE-MANAGEMENT.md file describing the release process and a scripts/update_version.py invoked by the Makefile's version target.
Upgrade cost is dominated by the guide, not by the API. The Makefile's test target runs a full lint, docs build, doctest pass and unit suite, which tells you the project holds itself to a real bar, but it also tells you that a version bump is not a drop-in event for downstream code. Budget time to re-run your own inference and check that the posterior has not shifted.
Editorial conclusion
Pyro suits people already fluent in PyTorch who need custom inference, discrete latent variables, or models that do not fit a fixed inference engine. It is the wrong tool if you want a sampler that just runs, or if you cannot commit to writing and debugging guides. Before adopting it, install the pinned release rather than the dev branch, and check that the examples you intend to follow come from the same release, since the README warns that models must match the Pyro version you installed.
Frequently asked questions
What is Pyro used for?
Pyro is used for probabilistic modeling and inference in Python: you write a model with random choices, write a guide or run MCMC, and fit it on top of PyTorch. The README describes it as a deep probabilistic programming library built on PyTorch.
What does the prefix pyro mean?
The repository does not explain the name. It only states that the project was originally developed at Uber AI and became a Linux Foundation project in 2019.
What are Pyro objects?
The repository does not use the phrase Pyro objects. What it does describe is random choices recorded through Pyro's primitives, which wrap PyTorch distributions and are used inside model and guide functions.
Does Pyro mean fire?
The repository does not discuss the etymology of the name, so this cannot be answered from the available documentation.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/pyro-ppl-pyro)