SPFlow is a flexible, modular library for building and reasoning with Sum-Product Networks (SPNs) and Probabilistic Circuits (PCs). These are deep generative and discriminative models that enable tractable (polynomial-time) probabilistic inference while maintaining expressive power. SPFlow is built on PyTorch, providing GPU acceleration and seamless integration with modern deep learning workflows.
Key Features:
- Exact probabilistic inference: marginals, conditionals, most probable explanations
- Modular model construction: manual design or automatic structure learning
- Learning algorithms: gradient descent, expectation-maximization, structure learning
- Full support for missing data and various distribution types
- GPU acceleration via PyTorch
Install from PyPI:
pip install spflowFor contributor/development setup (from source), see CONTRIBUTING.md.
This example builds a more complex circuit, runs likelihood evaluation and sampling, and (optionally) visualizes it.
import shutil
import torch
from spflow.meta import Scope
from spflow.modules.leaves import Categorical, Normal
from spflow.modules.products import Product
from spflow.modules.sums import Sum
from spflow.utils.visualization import visualize
torch.manual_seed(0)
# Feature indices (X, Z1, Z2)
x_idx, z1_idx, z2_idx = 0, 1, 2
# ---- Leaf modules ----
# Left branch will model Z1 together with a mixture over (X, Z2)
leaf_z1_left = Categorical(scope=Scope([z1_idx]), out_channels=2, K=3)
leaf_x_1 = Normal(scope=Scope([x_idx]), out_channels=2)
leaf_z2_1 = Normal(scope=Scope([z2_idx]), out_channels=2)
leaf_x_2 = Normal(scope=Scope([x_idx]), out_channels=2)
# Right branch will model Z2 together with a mixture over (Z1, X)
leaf_z2_right = Normal(scope=Scope([z2_idx]), out_channels=2)
leaf_z1_1 = Categorical(scope=Scope([z1_idx]), out_channels=2, K=3)
leaf_x_3 = Normal(scope=Scope([x_idx]), out_channels=2)
leaf_z1_2 = Categorical(scope=Scope([z1_idx]), out_channels=2, K=3)
# ---- Left branch: Z1 × Sum(X × Z2) ----
# Products combine disjoint scopes (decomposability)
prod_x_z2 = Product(inputs=[leaf_x_1, leaf_z2_1])
prod_z2_x = Product(inputs=[leaf_z2_1, leaf_x_2])
# Sum mixes alternatives with identical scope
sum_x_z2 = Sum(inputs=[prod_x_z2, prod_z2_x], out_channels=2)
prod_z1_sum_xz2 = Product(inputs=[leaf_z1_left, sum_x_z2])
# ---- Right branch: Z2 × Sum(Z1 × X) ----
prod_z1_x_1 = Product(inputs=[leaf_z1_1, leaf_x_3])
prod_z1_x_2 = Product(inputs=[leaf_z1_2, leaf_x_3])
sum_z1_x = Sum(inputs=[prod_z1_x_1, prod_z1_x_2], out_channels=2)
prod_z2_sum_z1x = Product(inputs=[leaf_z2_right, sum_z1_x])
# ---- Root: mixture over the two branches ----
root = Sum(inputs=[prod_z1_sum_xz2, prod_z2_sum_z1x], out_channels=1)
# Likelihood evaluation expects data shaped (N, D)
data = torch.randn(32, 3)
ll = root.log_likelihood(data)
# Unconditional sampling
samples = root.sample(num_samples=5)
print(f"root.out_shape={root.out_shape}")
print(f"data.shape={data.shape}")
print(f"ll.shape={ll.shape}")
print(f"samples.shape={samples.shape}")
# Optional visualization (requires Graphviz `dot`)
if shutil.which("dot") is not None:
visualize(root, output_path="/tmp/spflow-structure", show_scope=True, show_shape=True, format="svg")More examples can be found in the User Guide(https://spflow.github.io/guides/user_guide.html)
- User Guide: Comprehensive notebook with examples covering model construction, training, inference, and advanced use cases
- Contributing Guide: Guidelines for contributing to SPFlow
- Versioning Guide: Semantic versioning and commit conventions
- Release Guide: Release process documentation
SPFlow 1.0.0 represents a complete rewrite of SPFlow with PyTorch as the primary backend. This version features:
- Modern PyTorch architecture for GPU acceleration
- Significantly improved performance
- Enhanced modular design
See the CHANGELOG for detailed version history and recent changes.
We welcome contributions! Please see CONTRIBUTING.md for contribution guidelines.
If you find SPFlow useful please cite us in your work:
@misc{Molina2019SPFlow,
Author = {Alejandro Molina and Antonio Vergari and Karl Stelzner and Robert Peharz and Pranav Subramani and Nicola Di Mauro and Pascal Poupart and Kristian Kersting},
Title = {SPFlow: An Easy and Extensible Library for Deep Probabilistic Learning using Sum-Product Networks},
Year = {2019},
Eprint = {arXiv:1901.03704},
}
- Steven Braun - TU Darmstadt
- Arseny Skryagin - TU Darmstadt
- Alejandro Molina - TU Darmstadt
- Antonio Vergari - University of Edinburgh
- Karl Stelzner - TU Darmstadt
- Robert Peharz - TU Graz
- Nicola Di Mauro - University of Bari Aldo Moro
- Kristian Kersting - TU Darmstadt
- Philipp Deibert - TU Darmstadt
- Kevin Huy Nguyen - TU Darmstadt
- Bennet Wittelsbach - TU Darmstadt
- Felix Divo - TU Darmstadt
- Moritz Kulessa - TU Darmstadt
- Claas Voelcker - TU Darmstadt
- Simon Roesler - Karlsruhe Institute of Technology
- Alexander L. Hayes - Indiana University, Bloomington
- Alexander Zeikowsky - TU Darmstadt
See the full list of contributors on GitHub.
This project is licensed under the Apache License, Version 2.0 - see the LICENSE file for details.
-
Parts of SPFlow as well as its motivating research have been supported by the Germany Science Foundation (DFG) - AIPHES, GRK 1994, and CAML, KE 1686/3-1 as part of SPP 1999- and the Federal Ministry of Education and Research (BMBF) - InDaS, 01IS17063B.
-
This project received funding from the European Union's Horizon 2020 research and innovation programme under the Marie Sklodowska-Curie Grant Agreement No. 797223 (HYBSPN).


