Skip to main content

A Federated Learning Framework for Erlang-Python Integration

Project description

fedlang-py

Python Library for Federated Learning Experiments under the fedlang Framework

License Python Version

Overview

fedlang-py defines a set of Python classes required for implementing Federated Learning experiments under the fedlang framework [1]. Built on an actor-oriented middleware architecture, it provides a declarative approach to defining federated learning workflows through JSON-based configuration files, enabling researchers and practitioners to focus on algorithm design rather than distributed system implementation.

The library supports seamless integration with Erlang-based distributed systems and provides both local testing capabilities and distributed deployment options.

Key Features

  • Declarative Orchestration: Define complete federated learning workflows using JSON configuration files
  • Actor-Based Architecture: Clean separation between server and client entities with standardized communication patterns
  • Flexible Execution Models: Support for both iterative and one-shot execution stages
  • Erlang Interoperability: Built-in support for integration with Erlang-based distributed messaging systems
  • Local Testing: Run and debug federated learning experiments locally before deployment
  • Extensible Design: Easy integration of custom federated learning algorithms
  • Lightweight: No external dependencies for core functionality
University of Pisa - Department of Information Engineering FAIR - Future Artificial Intelligence Research

Installation

Using pip

pip install fedlang-py

From Source

git clone https://github.com/jlcorcuera/fedlang-py.git
cd fedlang-py
pip install -e .

Requirements

  • Python 3.9 or higher
  • No external dependencies for core functionality

Quick Start

1. Define Your Federation Plan

Create a JSON file that describes your federated learning workflow:

{
  "name": "My Federated Algorithm",
  "server_class": "my_package.server.MyServer",
  "client_class": "my_package.client.MyClient",
  "stages": [
    {
      "name": "Initialization",
      "type": "run_once",
      "pipeline": [
        { "entity": "#server", "method": "initialize" },
        { "entity": "#available_clients", "method": "setup" }
      ]
    },
    {
      "name": "Training Loop",
      "type": "run_many",
      "stop_condition": "is_converged",
      "pipeline": [
        { "entity": "#server", "method": "broadcast_model" },
        { "entity": "#available_clients", "method": "train_local" },
        { "entity": "#server", "method": "aggregate_updates" }
      ]
    }
  ]
}

2. Implement Server and Client Classes

from fedlangpy.core.entities import FedlangEntity, pickle_io

class MyServer(FedlangEntity):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.global_model = None
        self.round_count = 0

    def initialize(self, _):
        """Initialize the global model"""
        self.global_model = self._create_initial_model()
        return self.global_model

    @pickle_io
    def broadcast_model(self, _):
        """Send current model to clients"""
        return self.global_model

    @pickle_io
    def aggregate_updates(self, client_updates):
        """Aggregate updates from clients"""
        self.global_model = self._average_models(client_updates)
        self.round_count += 1
        return self.global_model

    def is_converged(self):
        """Check if training should stop"""
        return self.round_count >= self.parameters.get("max_rounds", 100)


class MyClient(FedlangEntity):
    def __init__(self, data=None, **kwargs):
        super().__init__(**kwargs)
        self.local_data = data
        self.local_model = None

    def setup(self, _):
        """Initialize client state"""
        self.local_model = None

    @pickle_io
    def train_local(self, global_model):
        """Train model on local data"""
        self.local_model = self._train(global_model, self.local_data)
        return self.local_model

3. Run the Experiment

from fedlangpy.core.utils import load_plan, run_experiment
from my_package.server import MyServer
from my_package.client import MyClient

# Load the federation plan
plan = load_plan('./my_plan.json')

# Create server and clients
server = MyServer(type='server')
clients = [
    MyClient(type='client', id=i, data=datasets[i])
    for i in range(num_clients)
]

# Define execution parameters
parameters = {
    "learning_rate": 0.01,
    "batch_size": 32,
    "max_rounds": 50
}

# Execute the federated learning experiment
run_experiment(plan, server, clients, parameters)

Architecture

Core Components

The framework consists of three main components:

1. Federation Plans (models.py)

Federation plans are structured configurations that define:

  • FLPlan: Top-level configuration specifying server/client classes and execution stages
  • FLStage: Individual stages that can be run_once or run_many (iterative)
  • FLPipeline: Specific method invocations within each stage

2. Federated Entities (entities.py)

  • FedlangEntity: Base class for server and client implementations

    • Provides call() method for dynamic method invocation
    • Handles parameter management via set_parameters()
    • Supports Erlang interoperability (byte array/list conversion)
    • Tracks current round number
  • @pickle_io Decorator: Automatically serializes/deserializes complex data structures passed between entities

3. Execution Engine (utils.py)

  • load_plan(): Loads and validates federation plans from JSON

    • Verifies class existence and importability
    • Validates method signatures
    • Checks stop conditions for iterative stages
  • run_experiment(): Orchestrates the federated learning execution

    • Manages execution context (server, clients, parameters)
    • Routes method calls to appropriate entities
    • Handles iterative execution with stop conditions
    • Supports client selection filtering

Entity Types

The framework recognizes these entity types in pipeline definitions:

Entity Description
#server The single server instance
#available_clients All registered client instances
#selected_clients Filtered subset of clients (populated via pipeline outputs)
#parameters Execution parameters dictionary

Execution Flow

  1. Plan Loading: Federation plan is parsed and validated
  2. Initialization: Server and clients are instantiated with parameters
  3. Stage Execution: For each stage in sequence:
    • run_once stages: Execute pipeline once
    • run_many stages: Execute pipeline iteratively until stop condition is met
  4. Pipeline Processing: For each step in the pipeline:
    • Identify target entity (server or client collection)
    • Invoke specified method with input from previous step
    • Store output in context for subsequent steps
  5. Completion: Return control after all stages complete

Implementation Guidelines

Class Requirements

Requirement Description
Inheritance All server and client classes must extend FedlangEntity
Type Declaration Instantiate with type='server' or type='client'
Method Signatures Pipeline methods accept one argument; stop conditions accept none
Serialization Use @pickle_io for methods exchanging complex objects
Parameters Access via self.parameters["key"]

Example: Federated Averaging

from fedlangpy.core.entities import FedlangEntity, pickle_io
import numpy as np

class FedAvgServer(FedlangEntity):
    def init(self, _):
        self.model_weights = self._initialize_model()
        return self.model_weights

    @pickle_io
    def aggregate(self, client_weights):
        # Simple averaging
        self.model_weights = np.mean(client_weights, axis=0)
        return self.model_weights

    def should_stop(self):
        current_round = self.get_current_round()
        max_rounds = self.parameters["num_rounds"]
        return current_round >= max_rounds

class FedAvgClient(FedlangEntity):
    def __init__(self, data, labels, **kwargs):
        super().__init__(**kwargs)
        self.X = data
        self.y = labels

    @pickle_io
    def local_train(self, global_weights):
        # Train for specified epochs
        local_weights = self._sgd_train(
            global_weights,
            self.X,
            self.y,
            epochs=self.parameters["local_epochs"]
        )
        return local_weights

Advanced Features

Client Selection

Use pipeline outputs to filter clients dynamically:

{
  "pipeline": [
    {
      "entity": "#server",
      "method": "select_clients",
      "output": "#selected_clients"
    },
    {
      "entity": "#selected_clients",
      "method": "train"
    }
  ]
}

The server's select_clients() method should return a list of client IDs.

Input/Output Chaining

Pass data between pipeline steps using input/output specifications:

{
  "pipeline": [
    {
      "entity": "#server",
      "method": "prepare_task",
      "output": "task_data"
    },
    {
      "entity": "#available_clients",
      "method": "process_task",
      "input": "task_data"
    }
  ]
}

Round Tracking

Access the current iteration number in any entity:

def my_method(self, data):
    current_round = self.get_current_round()
    # Use round number for scheduling, logging, etc.

Erlang Integration

fedlang-py is designed to integrate with Erlang-based distributed systems. The framework handles conversion between Python and Erlang data types:

  • Strings: Automatically converts between Python strings and Erlang character lists
  • Binary Data: Handles byte arrays for complex object serialization
  • Method Invocation: Supports dynamic method dispatch from Erlang nodes

Contributors

Citation

If you use fedlang-py in your research, please cite:

Paper:

A. Bechini, J. L. Corcuera Bárcena, "Devising an actor-based middleware support to federated learning experiments and systems", Future Generation Computer Systems, Volume 166, 2025, 107646. DOI: 10.1016/j.future.2024.107646

BibTeX:

@article{bechini2025devising,
  title={Devising an actor-based middleware support to federated learning experiments and systems},
  author={Bechini, Alessio and Corcuera Barcena, Jose Luis},
  journal={Future Generation Computer Systems},
  volume={166},
  pages={107646},
  year={2025},
  publisher={Elsevier},
  doi={10.1016/j.future.2024.107646}
}

Acknowledgments

This work has been partially funded by:

  • PNRR - Tuscany Health Ecosystem (THE) - Spoke 6 - Precision Medicine & Personalized Healthcare (CUP I53C22000780001) under the NextGeneration EU programme
  • PNRR - M4C2 - Investimento 1.3, Partenariato Esteso PE00000013 - FAIR - Future Artificial Intelligence Research - Spoke 1 "Human-centered AI"
  • PON 2014-2021 - "Research and Innovation", DM MUR 1062/2021, Project: "Progettazione e sperimentazione di algoritmi di federated learning per data stream mining"
  • Italian Ministry of University and Research (MUR) - FoReLab and CrossLab projects (Departments of Excellence)

License

This project is licensed under the Apache License 2.0. See the LICENSE file for details.


Built at the University of Pisa for the Federated Learning Research Community

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

fedlang_py-0.0.1.tar.gz (15.9 kB view details)

Uploaded Source

Built Distribution

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

fedlang_py-0.0.1-py3-none-any.whl (14.9 kB view details)

Uploaded Python 3

File details

Details for the file fedlang_py-0.0.1.tar.gz.

File metadata

  • Download URL: fedlang_py-0.0.1.tar.gz
  • Upload date:
  • Size: 15.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.2.1 CPython/3.11.12 Linux/6.8.0-87-generic

File hashes

Hashes for fedlang_py-0.0.1.tar.gz
Algorithm Hash digest
SHA256 9f7e05295dd9ebdc9cf22abe9ebfa0d60cab863fb6e379f9b550707c7e7cc10d
MD5 905c488762ce726315cb03c306f6b19e
BLAKE2b-256 2d4f4a10d3586330482249630890041bba1e9a4d0f49cd81f87cc39cebcea5aa

See more details on using hashes here.

File details

Details for the file fedlang_py-0.0.1-py3-none-any.whl.

File metadata

  • Download URL: fedlang_py-0.0.1-py3-none-any.whl
  • Upload date:
  • Size: 14.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.2.1 CPython/3.11.12 Linux/6.8.0-87-generic

File hashes

Hashes for fedlang_py-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 9ee6bcff22660fc1d0c8d8e68bc512392f70d541b1bcd7a2d7b242b5d27255cb
MD5 448c5f80f92c46da498857e0a50c945f
BLAKE2b-256 e85fadaceeee1a3069b464898ec3e0864d6abc441da2c96fddee271010446aca

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