Skip to main content

fed-playground

A modular federated learning simulation framework for research and education.

CI License: MIT Python Code style: black Ruff Docs

Table of Contents


Overview

fed-playground is a pure-Python federated learning playground designed to make it easy to prototype, analyse, and teach the core ideas behind federated learning (FL) — without requiring a cluster or real network infrastructure.

The library implements a strategy-pattern architecture: every key concern (encryption, aggregation, model type, data loading) is expressed as an abstract base class that can be swapped out independently. This makes it straightforward to answer questions such as "what happens to model divergence as I increase the number of parties?" or "how does closed-form averaging compare to gradient descent in a federated setting?"

Out of the box the framework ships five swappable component types, each an ABC with multiple pure-NumPy implementations:

  • Models — linear regression (gradient-descent / closed-form / ridge), logistic regression, MLP regressor & classifier, plus SVM (Pegasos), Lasso, ElasticNet, Poisson GLM and Huber regression.
  • Aggregation strategies — FedAvg (mean), plus Byzantine-robust median, trimmed mean, Krum / Multi-Krum, Bulyan, geometric median (RFA), median-of-means and centered clipping.
  • Encryption schemes — passthrough baseline, Gaussian & Laplace local DP, additive secret sharing and pairwise-masking secure aggregation; FHE-ready via the optional [fhe] extra (Concrete ML).
  • Attacks — sign-flip, Gaussian, IPM and A-Little-Is-Enough Byzantine poisoning, for stress-testing robust aggregation.
  • Visualizers — training-history curves, model comparison, divergence analysis and DP privacy/utility frontiers.

Research-grounded components

Most of the classes above implement published algorithms; each cites its source in its docstring:

Type Class Reference
Aggregation KrumAggregation Blanchard et al., Byzantine-Tolerant Gradient Descent, NeurIPS 2017
Aggregation BulyanAggregation El Mhamdi et al., The Hidden Vulnerability of Distributed Learning in Byzantium, ICML 2018
Aggregation GeometricMedianAggregation (RFA) Pillutla et al., Robust Aggregation for Federated Learning, IEEE TSP 2022
Aggregation MedianOfMeansAggregation Nemirovski & Yudin 1983; Lugosi & Mendelson 2019
Aggregation CenteredClippingAggregation Karimireddy, He & Jaggi, Learning from History for Byzantine Robust Optimization, ICML 2021
Model SVMModel Shalev-Shwartz et al., Pegasos, Math. Programming 2011
Model LassoRegressionModel Tibshirani 1996; Friedman, Hastie & Tibshirani 2010
Model ElasticNetRegressionModel Zou & Hastie, Elastic Net, JRSS-B 2005
Model PoissonRegressionModel Nelder & Wedderburn, GLMs, JRSS-A 1972
Model HuberRegressionModel Huber, Robust Estimation of a Location Parameter, Ann. Math. Stat. 1964
Encryption LaplaceDPEncryption Dwork et al., Calibrating Noise to Sensitivity, TCC 2006
Encryption PairwiseMaskingEncryption Bonawitz et al., Practical Secure Aggregation, ACM CCS 2017
Visualizer PrivacyUtilityVisualizer Abadi et al., Deep Learning with Differential Privacy, ACM CCS 2016

Robust aggregators and additive-masking schemes carry an is_linear_only flag: masking schemes (secret sharing, pairwise masks) hide individual updates, so order/distance-based aggregators (Krum, median, Bulyan, …) correctly refuse them — only linear aggregation (MeanAggregation) is sound over masked shares.

Runnable demos for all of the above live in examples/ (e.g. example_byzantine_robust.py, example_svm_lasso.py, example_dp_and_secure_agg.py, example_elasticnet_poisson.py, example_bulyan_mom.py, example_privacy_utility_curve.py).

Benchmarking (fedbench)

Describe an experiment in TOML and run the whole sweep with one command:

fedbench run benchmarks/robustness.toml      # attack × defense matrix
fedbench run benchmarks/impossibility.toml   # privacy × robustness frontier
fedbench run benchmarks/privacy.toml         # DP utility cost

Each run writes a results CSV and a Markdown leaderboard (NaN cells = incompatible combinations, e.g. masking secure-aggregation × order-statistic defense). The committed benchmarks/STUDY.md interprets the three — reproducible byte-for-byte under the configs' fixed seeds.

Optional: Fully Homomorphic Encryption (FHE)

The [fhe] optional extra installs Concrete ML (Zama's FHE library). This requires Python 3.11 or 3.12 (concrete-ml does not yet support 3.13+). When installed, custom EncryptionScheme subclasses can perform genuine ciphertext-level operations during aggregation. Without it the framework operates entirely in plaintext — which is correct for educational purposes.


Project Structure

fed-playground/
├── fed_playground/             # Installable Python package (import from here)
│   ├── __init__.py             # Public API + name registry (__all__)
│   └── src/
│       ├── models.py           # Model ABC + 11 regressors/classifiers
│       ├── aggregation.py      # AggregationStrategy ABC + FedAvg & 7 robust rules
│       ├── encryption.py       # EncryptionScheme ABC + DP / secret-sharing / masking
│       ├── attacks.py          # Attack ABC + Byzantine poisoning strategies
│       ├── environment.py      # Environment: high-level simulation driver
│       ├── orchestrator.py     # Orchestrator: broadcast + aggregate (+ attack hook)
│       ├── party.py            # Party: local training + encrypted updates
│       ├── dataloader.py       # DataLoader + load_dataset (synthetic/sklearn/openml/csv)
│       ├── utils_data.py       # IID + Dirichlet non-IID partitioners
│       ├── benchmark.py        # run_benchmark grid sweep + Markdown leaderboard
│       ├── cli.py              # `fedbench` CLI (run / list-components)
│       └── visualization.py    # Training / Comparison / Divergence / PrivacyUtility plots
├── examples/                   # Runnable demos (example_*.py) + bundled toy CSV
├── benchmarks/                 # TOML configs + generated leaderboards + STUDY.md
├── docs/                       # MkDocs site (api / extending / study) + design specs
├── tests/                      # pytest suite (mirrors src/ layout)
├── .github/workflows/          # CI, docs deploy, PyPI release
├── pyproject.toml              # Metadata, dependencies, tool config
├── mkdocs.yml                  # Docs site config
└── LICENSE                     # MIT

Requirements

  • Python ≥ 3.11, < 3.13
  • System: no compiled extensions required for the core library
  • Optional FHE: concrete-ml ≥ 1.9.0 (Python 3.11 or 3.12 only, macOS/Linux)

Core Python dependencies (installed automatically):

Package Purpose
numpy ≥ 1.24 Numerical computing
pandas ≥ 2.0 Data loading and benchmark tables
matplotlib ≥ 3.7 Visualizations

Optional extras: [examples] (scikit-learn, tqdm), [dev] (pytest, ruff, black, mypy), [docs] (mkdocs-material, mkdocstrings), [fhe] (concrete-ml).


Installation

uv is the fastest way to get started — it manages the Python version and virtual environment automatically.

# 1. Clone the repository
git clone https://github.com/thecola13/fed-playground.git
cd fed-playground

# 2. Install dependencies and create the virtual environment
uv sync

# 3. (Optional) Include development tools
uv sync --extra dev

# 4. (Optional) Include FHE support (Python 3.11 or 3.12 required)
uv sync --extra fhe

Run scripts directly without activating the environment:

uv run python examples/basic_simulation.py --parties 4 --rounds 10
uv run pytest

Or activate the environment first:

source .venv/bin/activate          # Windows: .venv\Scripts\activate
python examples/basic_simulation.py
pytest

Using pip (alternative)

# 1. Clone the repository
git clone https://github.com/thecola13/fed-playground.git
cd fed-playground

# 2. Create and activate a virtual environment
python3.11 -m venv .venv
source .venv/bin/activate          # Windows: .venv\Scripts\activate

# 3. Install the library in editable mode
pip install -e .

# 4. (Optional) Install development tools
pip install -e ".[dev]"

# 5. (Optional) FHE support
pip install -e ".[fhe]"

Verify the installation:

python -c "import fed_playground; print('fed-playground installed successfully')"

Configuration

The library reads a small number of optional environment variables. Copy .env.example to .env and edit as needed — the file is git-ignored.

Variable Required Default Description
THESIS_DATA_DIR No — Path to an external research data directory. Used by private example scripts only; not needed for the published examples.
FED_LOG_LEVEL No WARNING Python logging level for the fed_playground logger (DEBUG, INFO, WARNING, ERROR).

The library uses Python's standard logging module. To see round-by-round progress, set FED_LOG_LEVEL=INFO or configure logging in your script:

import logging
logging.basicConfig(level=logging.INFO)

Usage

Basic simulation

from fed_playground import (
    Environment,
    NoEncryption,
    MeanAggregation,
    ClosedFormLinearRegressionModel,
    DataLoader,
)

# Load data from a CSV file
loader = DataLoader(file_path="examples/test_data.csv", target_column="target")

# Build and run a 3-party federated simulation for 10 rounds
env = Environment(
    n_parties=3,
    encryption_scheme=NoEncryption(),
    aggregation_strategy=MeanAggregation(),
    model_class=ClosedFormLinearRegressionModel,
    data_loader=loader,
)

history = env.run_simulation(rounds=10)

print(history["global_loss"])   # per-round MSE on the held-out test set
print(history["party_loss"])    # per-round average local training MSE

Using synthetic data

env = Environment(
    n_parties=5,
    n_features=10,
    n_samples=500,
    encryption_scheme=NoEncryption(),
    aggregation_strategy=MeanAggregation(),
    model_class=ClosedFormLinearRegressionModel,
)
history = env.run_simulation(rounds=20)

Visualizing results

from fed_playground import TrainingHistoryVisualizer, ComparisonVisualizer

# Plot training curves (displayed interactively)
viz = TrainingHistoryVisualizer()
viz.plot(
    data={"Global Loss": history["global_loss"], "Party Loss": history["party_loss"]},
    title="Federated Training",
    xlabel="Round",
    ylabel="MSE",
)

# Save to a file instead
viz_save = TrainingHistoryVisualizer(save_dir="./plots")
viz_save.plot(data=..., filename="training.png")

Extending with a custom model

import numpy as np
from fed_playground import Model, Environment, NoEncryption, MeanAggregation

class MyRidgeModel(Model):  # the framework already ships RidgeRegressionModel
    def __init__(self, input_dim: int, alpha: float = 0.01) -> None:
        self.input_dim = input_dim
        self.alpha = alpha
        self.params = np.zeros(input_dim + 1)

    def train(self, X, y):
        n = X.shape[0]
        X_b = np.hstack([X, np.ones((n, 1))])
        I = np.eye(X_b.shape[1])
        I[-1, -1] = 0  # do not regularize bias term
        self.params = np.linalg.solve(X_b.T @ X_b + self.alpha * I, X_b.T @ y)

    def get_parameters(self): return self.params
    def set_parameters(self, p): self.params = p
    def predict(self, X): return np.hstack([X, np.ones((X.shape[0], 1))]) @ self.params
    def evaluate(self, X, y): return float(np.mean((y - self.predict(X)) ** 2))

env = Environment(
    n_parties=4,
    n_features=5,
    n_samples=200,
    model_class=MyRidgeModel,
    model_params={"alpha": 0.1},
)
env.run_simulation(rounds=5)

CLI example scripts

# Basic simulation with a table of per-round metrics
python examples/basic_simulation.py --parties 4 --rounds 10

# Divergence analysis: vary party count, display plots interactively
python examples/divergence_analysis.py \
    --data-path examples/test_data.csv \
    --features feature_1 feature_2 feature_3 feature_4 feature_5 \
    --target target \
    --instances-diff --min-instances 2 --max-instances 8

# Save plots to disk instead of showing them
python examples/divergence_analysis.py \
    --data-path examples/test_data.csv \
    --features feature_1 feature_2 feature_3 feature_4 feature_5 \
    --target target \
    --instances-diff \
    --save-dir ./results

Running Tests

# Run the full suite
uv run pytest

# Run a specific module
uv run pytest tests/test_environment.py

# Run with coverage report
uv run pytest --cov=fed_playground --cov-report=term-missing

A passing run covers the whole suite (≈160 tests across the src/ modules):

tests/test_aggregation.py ...  tests/test_attacks.py ...  tests/test_benchmark.py ...
tests/test_dataloader.py ...   tests/test_encryption.py ...  tests/test_environment.py ...
tests/test_models.py ...       tests/test_orchestrator.py ...  tests/test_party.py ...
tests/test_phase2.py ...       tests/test_utils_data.py ...  tests/test_visualization.py ...

Contributing

Setting up a dev environment

git clone https://github.com/thecola13/fed-playground.git
cd fed-playground
uv sync --extra dev

Branch naming

Type Prefix Example
New feature feat/ feat/add-dp-noise
Bug fix fix/ fix/dataloader-elif
Documentation docs/ docs/update-readme
Refactoring refactor/ refactor/split-orchestrator

Commit style

Follow Conventional Commits:

feat(aggregation): add weighted FedAvg strategy
fix(dataloader): correct elif branch for DataFrame input
docs(readme): add custom model example

Pull request checklist

  • pytest passes with zero failures
  • ruff check . reports zero violations
  • black --check . reports no formatting issues
  • New public functions/classes have Google-style docstrings
  • New behaviour is covered by at least one test

License

This project is licensed under the MIT License — see LICENSE for the full text.

Metadata

Release files for fed-playground 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for fed-playground 0.2.1
File Size Uploaded Provenance Actions
fed_playground-0.2.1.tar.gz 64.2 kB With provenance Details for fed_playground-0.2.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for fed-playground 0.2.1
File Interpreter ABI Platform Actions
fed_playground-0.2.1-py3-none-any.whl Python 3 none any Details for fed_playground-0.2.1-py3-none-any.whl

Total release size: 115.7 kB

Release files / fed_playground-0.2.1.tar.gz

Download URL fed_playground-0.2.1.tar.gz
Size 64.2 kB
Tags Source
SHA-256 checksum
How to use checksums
e03d87506b8c8026fd25c57cb5fd51c064cd134a6bb1931167a1527362729a30
BLAKE2b-256 checksum
How to use checksums
db05318fc6c6711cdf971e4e3bde5385569c1cd8925cd1cc6f70e225cf3d66f6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 17, 2026.

Transparency log

Release files / fed_playground-0.2.1-py3-none-any.whl

Download URL fed_playground-0.2.1-py3-none-any.whl
Size 51.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d8efc7887c6646bcf15e6dd11a03d38dcaaf3e7cf04020d723536b763694cfa4
BLAKE2b-256 checksum
How to use checksums
42dac10c8ea670eb4d8c3b73e08c4dcd9f64a95ef6453bb25a22b6596c802dc2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 17, 2026.

Transparency log

Security for fed-playground 0.2.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for fed_playground-0.2.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 17, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.2.1 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page