Note
The entire system, its motivation, and experimental results are described in detail in the accompanying master's thesis.
If you use this work in your research, please cite it as:
@mastersthesis{rosendal2025fldisagreementresolution,
author = {Daan E. Rosendal},
title = {Resolution Strategies for Client-Level Disagreement Scenarios in Federated Learning},
school = {University of Amsterdam},
year = {2025},
type = {Master's thesis},
url = {https://github.com/DaanRosendal/fl-disagreement-resolution}
}
This project addresses a critical limitation in standard Federated Learning (FL): the assumption of unconditional collaboration amongst all clients. In real-world scenarios (e.g., competing companies, regulatory constraints), clients may need to exclude each other's data or model updates due to client-level disagreements.
Our solution introduces a robust multi-track resolution approach that creates and manages multiple, isolated model update paths called "tracks". Each track corresponds to a unique set of client exclusion preferences, guaranteeing strict client exclusion and preventing cross-contamination and unfairness issues.
This visualisation demonstrates temporal disagreement resolution (Scenario 4) where Client 0 "inbound" excludes Client 1 from rounds 1-3, creating a separate track that automatically becomes inactive once the disagreement period expires.
- Python 3.12 or higher
- uv - Python package and project manager
-
Install uv (if not already installed):
# On macOS and Linux curl -LsSf https://astral.sh/uv/install.sh | sh # On Windows powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
-
Clone the repository:
git clone https://github.com/DaanRosendal/fl-disagreement-resolution.git cd fl-disagreement-resolution
-
Create and activate virtual environment, then install dependencies:
uv venv # On Unix/macOS source .venv/bin/activate # On Windows .venv\Scripts\activate uv sync
MNIST: Handled automatically by using the -s
flag on first run.
N-CMAPSS: Requires manual preparation using the N-CMAPSS Data Preparation repository. After preparation, organise your data/n-cmapss/
folder as shown in the project structure below (β€6 clients only).
Run a simple federated learning experiment with disagreement resolution:
# First run with MNIST - automatically sets up data
uv run scripts/run_fl.py -S 1 -e mnist -r 5 -l 1 -s
# Subsequent MNIST runs (data already prepared)
uv run scripts/run_fl.py -S 1 -e mnist -r 5 -l 1
# Run scenario 3 with N-CMAPSS dataset (requires manual data preparation first)
uv run scripts/run_fl.py -S 3 -e n_cmapss -r 5 -l 1
# Run all scenarios with MNIST dataset
uv run scripts/run_fl.py -S all -e mnist -r 5 -l 1
# Run with custom client configuration
uv run scripts/run_fl.py -S 1 -e mnist -c 4 -r 10 -l 2
# Run with IID data distribution
uv run scripts/run_fl.py -S 1 -e mnist -c 6 -s -i
-S, --scenario <num>
: Scenario number (0-34) or 'all'-e, --experiment <type>
: Dataset type ('mnist' or 'n_cmapss')-c, --clients <ids>
: Number of clients or specific client IDs-r, --rounds <num>
: Number of FL rounds (default: 3)-l, --local-epochs <num>
: Local training epochs (default: 5)-s, --setup-data
: Set up MNIST data (first run only, not needed for N-CMAPSS)-i, --iid
: Use IID data distribution--verbose-plots
: Generate comprehensive visualisations
The system uses a DYNAMOS-inspired configuration approach with JSON files in the mock_etcd/
directory:
{
"experiment": {
"type": "mnist",
"fl_rounds": 5,
"client_ids": [0, 1, 2, 3, 4, 5]
},
"disagreement": {
"initiation_mechanism": "shallow",
"lifting_mechanism": "shallow",
"deep_lifting_finetune_rounds": 3
},
"training": {
"batch_size": 64,
"local_epochs": 10,
"learning_rate": 0.001
}
}
Scenarios define specific disagreement patterns:
{
"name": "Simple Inbound Exclusion",
"description": "Client 0 excludes client 1 from round 1 onwards",
"num_clients": 6,
"disagreements": {
"client_0": [{
"type": "inbound",
"target": "client_1",
"active_rounds": {"start": 1, "end": null}
}]
}
}
Available disagreement types:
- inbound: Exclude another client's updates from your model
- outbound: Prevent your updates from reaching another client
- bidirectional: Mutual exclusion between two clients
- full: Complete isolation from all other clients
Run the comprehensive test suite to validate disagreement resolution across all scenarios:
# Test all scenarios with MNIST
uv run scripts/test_disagreement_scenarios.py all -e mnist -r 5 -l 1
# Test specific scenario
uv run scripts/test_disagreement_scenarios.py 1 -e mnist -r 10 -l 2
# Test with N-CMAPSS dataset (limited to β€6 clients)
uv run scripts/test_disagreement_scenarios.py all -e n_cmapss -r 5 -l 1
# Test with verbose output and comprehensive plots
uv run scripts/test_disagreement_scenarios.py 5 -v --verbose-plots
The test suite automatically:
- β Validates track creation matches expected patterns
- β Verifies client isolation is properly enforced
- β Checks temporal disagreement handling
Evaluate system performance across multiple scenarios:
#!/bin/bash
# Run the first set of scalability scenarios (S7-S12) with MNIST dataset
for run in {1..5}; do
for S in {7..12}; do # or, e.g., "for S in 25 26 29 30 31; do"
uv run scripts/run_fl.py -S "$S" -e mnist -r 5 -l 1 # or "-e n_cmapss" for S13-S19
done
done
output_dirs=($(find results -maxdepth 1 -type d ! -name . ! -name results ! -name comparisons ! -name collected_outputs -printf "results/%f\n" | sort))
# assuming the results directory contains only relevant results, i.e., was empty before executing the run_fl.py command
uv run scripts/compare_fl_runs.py "${output_dirs[@]}"
Generate comprehensive analysis plots:
# Create track contribution visualisations (runs automatically at the end of each run)
uv run scripts/visualize_track_contributions.py results/fl_simulation_*
# Gather and compare outputs across scenarios (mostly useful for scalability testing)
uv run scripts/gather_simulation_outputs.py
Core Framework:
- Python 3.12+: Main programming language
- PyTorch 2.7+: Deep learning framework for model training
- NumPy 2.2+: Numerical computing for data handling
Machine Learning:
- scikit-learn 1.6+: ML utilities and metrics
- torchvision 0.22+: Computer vision datasets and transforms
Visualisation & analysis:
- matplotlib 3.10+: Plotting and visualisation
- seaborn 0.13+: Statistical data visualisation
- brokenaxes 0.6+: Advanced plot formatting
Datasets:
- MNIST: Classic handwritten digit recognition
- N-CMAPSS: NASA Commercial Modular Aero-Propulsion System Simulation for predictive maintenance of aircraft engines
This project is licensed under the MIT License - see the LICENSE file for details.
This repository contains the complete implementation for the Master's thesis:
"Resolution Strategies for Client-Level Disagreement Scenarios in Federated Learning" By Daan Eduard Rosendal University of Amsterdam, 2025
The work serves as a proof-of-concept for handling realistic federated learning scenarios where unconditional client collaboration cannot be assumed.
- DYNAMOS: Microservice orchestration middleware that inspired our configuration architecture
- N-CMAPSS Data Preparation: Toolkit for preparing the NASA turbofan engine dataset
fl-disagreement-resolution/
βββ π data/ # Dataset storage
β βββ π MNIST/ # MNIST dataset (auto-downloaded)
β β βββ π raw/ # Raw MNIST files
β βββ π n-cmapss/ # N-CMAPSS dataset (manual preparation required)
β βββ π test/ # Test data (.npz files)
β β βββ Unit11_win50_str1_smp10.npz
β β βββ Unit14_win50_str1_smp10.npz
β β βββ Unit15_win50_str1_smp10.npz
β βββ π train/ # Training data organised by client
β βββ π client_0/ # Client 0 training data
β β βββ Unit2_win50_str1_smp10.npz
β βββ π client_1/ # Client 1 training data
β β βββ Unit5_win50_str1_smp10.npz
β βββ π client_2/ # Client 2 training data
β β βββ Unit10_win50_str1_smp10.npz
β βββ π client_3/ # Client 3 training data
β β βββ Unit16_win50_str1_smp10.npz
β βββ π client_4/ # Client 4 training data
β β βββ Unit18_win50_str1_smp10.npz
β βββ π client_5/ # Client 5 training data
β βββ Unit20_win50_str1_smp10.npz
β
βββ π docs/ # Documentation and technical diagrams
β βββ FL_Disagreement_Resolution_Thesis_DaanRosendal.pdf # Master's thesis
β βββ π drawio/ # Technical architecture diagrams
β βββ data_exchange_archetypes.drawio
β βββ dynamos-design.drawio
β βββ fl-disagreement-resolution-design.drawio
β βββ fl-disagreements-graph.drawio
β βββ resolution-strategies.drawio
β βββ system_flow.drawio # Overall system architecture
β βββ π disagreement-scenarios-visualisations/
β βββ bidirectional-*.drawio # Various bidirectional patterns
β βββ combination*.drawio # Combination scenarios
β βββ full-exclusion.drawio
β βββ inbound-*.drawio # Inbound exclusion patterns
β βββ legend.drawio # Visualisation legend
β βββ outbound-*.drawio # Outbound exclusion patterns
β βββ partial-data-exclusion.drawio
β βββ template-scenario-*.drawio
β
βββ π fl_client/ # Client-side federated learning implementation
β βββ __init__.py
β βββ client.py # Core FL client logic and communication
β βββ main.py # Client application entry point
β βββ training.py # Local model training procedures
β βββ utils.py # Client utility functions
β
βββ π fl_module/ # Dataset handlers and ML models
β βββ __init__.py
β βββ base.py # Base classes for datasets and models
β βββ models.py # Neural network architectures (CNN, MLP, LSTM)
β βββ π mnist/ # MNIST dataset implementation
β β βββ __init__.py
β β βββ dataset.py # MNIST data loading and preprocessing
β β βββ utils.py # MNIST-specific utilities
β βββ π n_cmapss/ # N-CMAPSS dataset implementation
β βββ __init__.py
β βββ dataset.py # N-CMAPSS data loading and preprocessing
β βββ utils.py # N-CMAPSS-specific utilities
β
βββ π fl_server/ # Server-side coordination and aggregation
β βββ __init__.py
β βββ aggregation.py # Multi-track model aggregation strategies
β βββ disagreement.py # Disagreement detection and resolution logic
β βββ evaluation.py # Model evaluation and metrics collection
β βββ main.py # Server application entry point
β βββ server.py # Core FL server orchestration
β βββ utils.py # Server utility functions
β
βββ π logs/ # Runtime logs and debugging output
βββ π mock_etcd/ # Configuration and scenario management
β βββ configuration.json # Main system configuration
β βββ disagreements.json # Disagreement definitions and rules
β βββ etcd_loader.py # Configuration loading utilities
β βββ π scenarios/ # Disagreement scenario definitions (35 scenarios)
β βββ scenario0.json # Baseline: no disagreements
β βββ scenario1.json # Simple inbound exclusion
β βββ scenario4.json # Temporal disagreement (featured example)
β βββ ... # Scenarios 2-34 covering various patterns
β βββ π archive/ # Legacy scenario definitions
β
βββ π results/ # Experimental outputs and analysis
β βββ π collected_outputs/ # Aggregated visualisation outputs
β βββ s1_mnist_track_contributions.png
β βββ s4_mnist_track_contributions.png
β βββ s*_scalability_comparison.png
β βββ ... # Generated plots for all scenarios
β
βββ π scripts/ # CLI tools and automation scripts
β βββ compare_fl_runs.py # Compare results across multiple FL runs
β βββ gather_simulation_outputs.py # Collect and organize experimental outputs
β βββ run_fl.py # Main experiment runner (scenarios 0-34)
β βββ test_disagreement_scenarios.py # Validation suite for disagreement resolution
β βββ visualize_track_contributions.py # Generate track contribution plots
β
βββ fl_orchestrator.py # High-level orchestration coordinator
βββ LICENSE # MIT license
βββ pyproject.toml # Python project configuration and dependencies
βββ README.md # This comprehensive documentation
βββ uv.lock # Dependency lock file
π― Ready to explore federated learning with realistic client disagreements? Start with scenario 1:
# First run - sets up MNIST data automatically with IID data distribution
uv run scripts/run_fl.py -S 1 -e mnist -r 5 -l 1 -s -i