BayesFlow: Amortized Bayesian Inference When Your Likelihood Has No Closed Form
A Python library for simulation-based inference with deep learning
At a glance
- What is it?
- BayesFlow is a Python library that trains neural estimators to approximate posteriors, likelihoods and ratios from simulated data. It is useful when a simulator exists but a tractable likelihood does not, and it assumes you can afford to train before you infer.
- Who is it for?
- Adopt BayesFlow if you have a simulator you trust, a parameter vector you want posterior distributions for, and many datasets to condition on, since the trained estimator is reused across them. Do not adopt it if you need a single posterior for one fixed dataset, or if you cannot justify the simulator's assumptions, because a neural estimator will reproduce those assumptions faithfully and without complaint.
- Can I use it commercially?
- Yes. MIT 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 1 day 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 Likelihood-Free Gap BayesFlow Fills
Many scientific models are easy to simulate and hard to write down as a probability density. An epidemiological model, a cognitive process model, a network formation process: you can generate data from them by running code, but you cannot evaluate p(data | parameters) in closed form. Classical Bayesian inference needs that density. Approximate Bayesian Computation sidesteps it by comparing simulated and observed summaries, which works but scales poorly as the parameter dimension grows and forces a choice of summary statistics and tolerance. BayesFlow takes a different route. It trains a neural network to approximate the posterior directly from simulated pairs of parameters and data, so that once training finishes, inference on a new observation is a forward pass rather than a new sampling run. The README describes this as a "user-friendly API for amortized Bayesian workflows". The audience is computational scientists who already own a simulator and want posterior distributions, not point estimates, without deriving a likelihood.
Simulate, Amortize, Learn: The Three-Stage Loop
The conceptual overview in the README splits the library into three stages. Simulate: generate data from any simulation you like, including traditional parametric models. Amortize: define a neural estimator, choosing a generative model and a deep learning backend, since BayesFlow sits inside the Keras ecosystem. Learn: train the estimator and validate it with diagnostic features. The mechanism behind the middle stage is the interesting part. BayesFlow does not learn a posterior density over a fixed dataset. It learns a conditional mapping from an observation to a distribution over parameters, which is why the README calls the result amortized: the cost is paid once at training time and spread across every subsequent dataset. The library covers neural posterior, likelihood, ratio and point estimators, and the README states these can be ensembled or composed. Composition matters for hierarchical models, where a single network over all parameters is impractical; the tutorial list includes "Compositional estimation" for exactly that case. Filtering, smoothing and time-varying parameters also appear in the tutorial list, which suggests the conditional mapping can be applied across a sequence rather than to one static observation.
Getting a Workflow Running
Installation is a single command: pip install "bayesflow>=2.0", or uv add bayesflow if you use uv. Python 3.12 to 3.13 is the supported range. One constraint is stated bluntly in the README: BayesFlow will not run without a machine learning backend, and you must install JAX, PyTorch or TensorFlow yourself. Backend selection happens through the KERAS_BACKEND environment variable. The README recommends JAX as "currently the fastest backend" and notes that if you do not set the variable, Keras picks one by priority order. Setting it inside a script before importing BayesFlow is the documented pattern:
import os os.environ["KERAS_BACKEND"] = "jax" import bayesflow
For conda environments the README gives conda env config vars set KERAS_BACKEND=jax, and for a shell session, export KERAS_BACKEND=jax. The minimal workflow builds a BasicWorkflow with an inference network, the names of variables to infer, the names of variables to condition on, and a simulator. The README example uses bf.networks.FlowMatching(), inference_variables=["parameters"], inference_conditions=["observables"], and bf.simulators.SIR(). Training is then workflow.fit_online(epochs=20, batch_size=32, num_batches_per_epoch=200), which generates fresh simulated data on the fly rather than requiring a pre-built training set. Diagnostics come from workflow.plot_default_diagnostics(test_data=300). Note the shape of that call: it takes a count of simulated test datasets, not a held-out array you assembled yourself.
What Amortization Costs You
The trade is explicit and worth stating plainly. Amortized inference is cheaper per dataset and more expensive overall. If you have one observation and one posterior to compute, training a neural network is the wrong tool; MCMC with a hand-written likelihood, or a likelihood learned and plugged into PyMC as the README's likelihood estimation tutorial describes, will get you there with less machinery. BayesFlow pays off when the number of datasets is large, when new data arrive continuously, or when the simulator is expensive enough that you want to reuse every simulation. A second limitation is that the estimator inherits the simulator. If the simulator omits a nuisance process, the amortized posterior will be confidently wrong, and no diagnostic in the library can detect a misspecification that was never simulated. The diagnostics validate the network against the simulator, not the simulator against reality. A third point is the online training loop itself: fit_online generates data during training, so convergence depends on the simulator being fast enough to feed the network and on num_batches_per_epoch being large enough to cover the prior. The README's example uses 20 epochs, 32 samples per batch and 200 batches per epoch, which is a starting point rather than a guarantee.
How It Differs From ABC and From PyMC
Approximate Bayesian Computation also avoids the likelihood, but it does so by rejection: simulate, compare summaries to the observed data, keep the close ones. BayesFlow replaces rejection with a trained conditional density, which removes the tolerance parameter and the summary-statistic bottleneck, at the price of a training phase and a network you must validate. The README's own tutorial list frames this as "From ABC to BayesFlow", an upgrade path from sequential to amortized inference. Against PyMC the difference is sharper. PyMC is a probabilistic programming language: you write the model, and it runs MCMC or variational inference against a likelihood you specify. BayesFlow does not ask for a likelihood at all, and its PyMC integration runs in the other direction, learning a synthetic likelihood with a neural network and plugging that into the PyMC ecosystem so MCMC can sample it. The two are complements in that arrangement: BayesFlow supplies the density, PyMC supplies the sampler. If your likelihood is already written down and cheap to evaluate, PyMC alone is the shorter path.
Maintenance, Versioning and the MIT Licence
The release cadence visible in the repository is fast. v2.0.12 added new transformers and a PyMC wrapper in May 2026, v2.0.13 added model comparison, latent diffusion and diffusion transformers in July 2026, and v2.0.14 shipped "Better Defaults and Quality of Life" in September 2026, with the last push to main on the same day as that release. Three feature-bearing releases in roughly four months means the API surface is still moving, and pinning a version in production is a reasonable precaution. The README points users to the dev branch for the latest features, which implies main and dev can diverge. The library is MIT licensed, which is permissive and imposes no copyleft obligation on your own code; the usual caveat applies that the trained weights and any third-party simulator you pair with it carry their own terms, and this is not legal advice. BayesFlow is a NumFOCUS affiliated project and has a JOSS publication, both of which indicate the project is governed rather than a single person's side repository. That is a maintenance signal, not a quality guarantee, and it says nothing about whether the method suits your problem.
Editorial conclusion
Adopt BayesFlow if you have a simulator you trust, a parameter vector you want posterior distributions for, and many datasets to condition on, since the trained estimator is reused across them. Do not adopt it if you need a single posterior for one fixed dataset, or if you cannot justify the simulator's assumptions, because a neural estimator will reproduce those assumptions faithfully and without complaint. Before committing, verify three things in your own environment: that the KERAS_BACKEND you set is actually the one imported, that workflow.fit_online converges on your simulator within a batch budget you can afford, and that plot_default_diagnostics on held-out simulated data shows no systematic misfit. The last check is the one that decides whether the amortized posterior is usable at all.
Community notes