Wrapping Up My GSoC 2026 Journey with sbi
This is my final work product for Google Summer of Code 2026 , where I spent the summer redesigning how sbi builds neural networks. What the project is about? sbi does Bayesian inference for simulators you cannot write a likelihood for. You have a simulator and a prior, you run simulations, and a neural network learns the posterior over the simulator's parameters from those runs. It implements a…
For Google Summer of Code 2026, the final project focused on redesigning how sbi, a library for Bayesian inference in simulators, builds neural networks. sbi uses neural networks to learn the posterior over simulator parameters from simulation runs. The project aimed to improve the API by replacing the old string and factory-function interface with typed configuration objects, one per model, across every estimator family in the library.
Three main problems were addressed: the old API had three ways to specify a network, they were inconsistent, and lacked type information. The design goal was to create a layered API with typed, inspectable configurations, where mistakes fail at configuration time rather than training time, and existing code would continue working through a deprecation path.
The solution involved creating typed config objects for every estimator family. These config objects are frozen dataclasses, allowing for clean printing, logging, and editor autocompletion. Strings still work, but emit a FutureWarning suggesting the new configuration class. Custom modules are still supported.
The most significant improvement is in error handling. There are now three distinct failures, all occurring before training. For instance, NSFConfig with misspelled attributes raises a TypeError, a misspelled value raises a ValueError, and a configuration with an unsupported setting also raises a TypeError. This ensures that configuration errors are caught early, making the development process more efficient.
The project involved several key contributions. First, the groundwork was laid in PR #1872, establishing the shared base class, supporting types, and renaming a protocol to accommodate the new objects. Next, PR #1877 introduced the first real builder, and #1882 integrated it into the NPE trainers with the deprecation path for strings.
One important realization during the process was the removal of a premature abstraction. An initial design included a BuildContext object carrying shape, device, and z-scoring statistics. However, it was later discovered that this parameter was not used, simplifying the system and saving maintenance effort. This early recognition of a non-essential feature proved beneficial.
Another significant change involved the builder function, renamed from build() to build(batch_input, batch_condition). This change allows for flexibility, with input being whatever the model is modeling and condition being whatever it is conditioning on. The trainer then determines which is which, enhancing the functionality and reducing potential bugs.
Additionally, PR #1912 added support for mixed density estimators for MNLE and MNPE, accommodating scenarios where part of the data is discrete. PR #1920 incorporated the NRE classifiers and included fixes to the shared base class, ensuring that these changes benefited the entire library.
Several improvements were made to the configuration objects. Invalid literal values now raise immediately during construction, and misspelled field names raise errors too. A misspelled value on a correctly named field was also made visible, preventing silent failures until training. Configurations are now immutable, and a custom __repr__ method provides a clear, concise representation of the settings.
The public API has been standardized, with one builder now exported to ensure consistency across all families. The naming of z_score_x and z_score_y, which were ambiguous and created confusion across different families, was clarified by renaming them to z_score_input and z_score_condition, reflecting their actual roles.
Finally, PR #1921 addressed FMPE and NPSE, and #1920 integrated the NRE classifiers, along with fixes to the shared base class, creating a cohesive and extensible framework. This series of improvements not only enhanced the usability and reliability of sbi but also set a solid foundation for future developments.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.