Flower: A Friendly Federated AI Framework

1.29.0 · active · verified Fri Apr 17

Flower (flwr) is an open-source framework for building federated learning systems. It enables collaborative training of machine learning models across decentralized datasets without exchanging raw data. Currently at version 1.29.0, Flower maintains a rapid release cadence, often releasing minor versions monthly with new features and improvements.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to set up a basic federated learning simulation using Flower. It defines a `NumPyClient` subclass with dummy model logic for parameter exchange, training, and evaluation. It then configures a `FedAvg` strategy and launches a local simulation using `flwr.simulation.start_simulation`, which manages multiple clients and the server within a single process for easy testing.

import flwr as fw
import numpy as np
from collections import OrderedDict

# 1. Define a Flower Client (inheriting from NumPyClient)
class CifarClient(fw.client.NumPyClient):
    def __init__(self):
        # In a real scenario, you'd load your actual ML model here
        # For this quickstart, we'll use a dummy model with NumPy arrays.
        self.model = {
            "layer1": np.random.rand(10, 10).astype(np.float32),
            "layer2": np.random.rand(10, 1).astype(np.float32)
        }

    def get_parameters(self, config):
        """Return model parameters as a list of NumPy arrays."""
        return [v for v in self.model.values()]

    def set_parameters(self, parameters):
        """Set model parameters from a list of NumPy arrays."""
        params_dict = zip(self.model.keys(), parameters)
        self.model = OrderedDict({k: v for k, v in params_dict})

    def fit(self, parameters, config):
        """Simulate training and return updated parameters, number of examples, and metrics."""
        self.set_parameters(parameters)
        # Simulate training: update weights slightly
        new_weights = {k: v + np.random.rand(*v.shape).astype(np.float32) * 0.1 for k, v in self.model.items()}
        self.model = OrderedDict(new_weights)
        num_examples = 100
        metrics = {"accuracy": float(np.random.rand())}
        return self.get_parameters({}), num_examples, metrics

    def evaluate(self, parameters, config):
        """Simulate evaluation and return loss, number of examples, and metrics."""
        self.set_parameters(parameters)
        # Simulate evaluation
        loss = float(np.random.rand() * 0.5 + 0.5) # Loss between 0.5 and 1.0
        accuracy = float(np.random.rand() * 0.2 + 0.7) # Accuracy between 0.7 and 0.9
        num_examples = 50
        return loss, num_examples, {"accuracy": accuracy}

# 2. Define a Flower Server Strategy
# FedAvg (Federated Averaging) is a common choice.
strategy = fw.server.strategy.FedAvg(
    fraction_fit=1.0,         # Sample 100% of available clients for training
    fraction_evaluate=1.0,    # Sample 100% of available clients for evaluation
    min_fit_clients=2,        # Wait for at least 2 clients to participate in fit
    min_evaluate_clients=2,   # Wait for at least 2 clients to participate in evaluate
    min_available_clients=2,  # Total number of clients that need to be connected
)

# 3. Define the client factory function for the simulation
def client_fn(cid: str):
    """Returns a Flower Client for a given client ID."""
    print(f"Creating client {cid}...")
    return CifarClient().to_client()

# 4. Start the Flower Simulation
print("Starting Flower simulation with 2 clients for 3 rounds...")
fw.simulation.start_simulation(
    client_fn=client_fn,
    num_clients=2,
    config=fw.server.ServerConfig(num_rounds=3),
    strategy=strategy,
)
print("Simulation finished.")

view raw JSON →