Skip to main content

Sum Product Flow: An Easy and Extensible Library for Sum-Product Networks

Project description

SPFlow: An Easy and Extensible Library for Probabilistic Circuits

Python version License Code style: black & isort codecov Semantic Versioning

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

Installation

Install from PyPI:

pip install spflow

For contributor/development setup (from source), see CONTRIBUTING.md.

Quick Start

Let's start with a tiny DSL-based example that builds a simple circuit, evaluates log-likelihood, and visualizes the structure.

import shutil

import torch
from spflow.dsl import dsl
from spflow.modules.leaves import Normal
from spflow.utils.visualization import visualize

with dsl():
    terms = 0.4 * Normal(0) * Normal(1) + 0.6 * Normal(0) * Normal(1)

pc = terms.build()
ll = pc.log_likelihood(torch.randn(8, 2))
print(ll.shape)

# Optional visualization (requires Graphviz `dot`)
if shutil.which("dot") is not None:
    visualize(pc, output_path="/tmp/dsl-structure", format="svg")

A more complex circuit with explicit products/sums, likelihood evaluation, and sampling could look like the following.

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)
# Build each feature separately so categorical dimensions get valid integer values.
num_rows = 32
data_x = torch.randn(num_rows)
data_z1 = torch.randint(low=0, high=3, size=(num_rows,), dtype=torch.int64).to(torch.float32)
data_z2 = torch.randn(num_rows)
data = torch.stack([data_x, data_z1, data_z2], dim=1)
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.

Documentation

  • User Guide: Comprehensive notebook with examples covering model construction, training, inference, and advanced use cases
  • Contributing Guide: Contributor workflow, coding standards, PR process, and commit conventions
  • Versioning Guide: Semantic versioning and deprecation policy
  • Release Guide: Maintainer runbook for creating and publishing releases

Development Status

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.

Contributing

We welcome contributions! Please see CONTRIBUTING.md for contribution guidelines.

Citation

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},
}

Authors & Contributors

Lead Authors

Contributors

See the full list of contributors on GitHub.

License

This project is licensed under the Apache License, Version 2.0 - see the LICENSE file for details.

Acknowledgments

  • 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).

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

spflow-1.0.0.tar.gz (506.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

spflow-1.0.0-py3-none-any.whl (670.0 kB view details)

Uploaded Python 3

File details

Details for the file spflow-1.0.0.tar.gz.

File metadata

  • Download URL: spflow-1.0.0.tar.gz
  • Upload date:
  • Size: 506.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for spflow-1.0.0.tar.gz
Algorithm Hash digest
SHA256 fef42f38bc079d258d60384d4115312c4ff8ee72f373aa854ba0db8def804075
MD5 775fad8ad9082452476eecd010c81143
BLAKE2b-256 da432cf62c7df58fcdcf54ab05dd65e9024602f18ae47f319f19c9be253ad258

See more details on using hashes here.

File details

Details for the file spflow-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: spflow-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 670.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for spflow-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2d4a3a664e70c683658fdd39ef8c0803d7b4652ee299587660da566e95f4626e
MD5 288f6688d8817c7419c81c0b5a003270
BLAKE2b-256 48dc5cf8fdc0baf269810956acdcec0586f913285404308f362b15d272f821ae

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page