Qora: Quorum-Oriented Robust Aggregation for Federated Learning
Project description
Qora-FL
Quorum-Oriented Robust Aggregation for Federated Learning
Problem
Federated learning systems are fragile under adversarial or faulty clients. Standard aggregation methods silently fail under model poisoning, gradient manipulation, or non-IID drift.
Qora-FL provides quorum-oriented, Byzantine-tolerant aggregation primitives designed for predictable behavior under adversarial conditions, with optional determinism and reputation-aware filtering. Replace FedAvg with a single line change and tolerate up to 30% malicious clients.
How Qora-FL Differs
Most "robust FL" implementations are paper artifacts or tightly coupled experiments. Qora-FL is designed as infrastructure, emphasizing:
- Explicit aggregation semantics -- each method has documented tolerance bounds, not just "robust"
- Measurable deviation signals -- reputation is derived from observable behavior, not assumed trust
- Deterministic execution paths -- Q16.16 fixed-point option for bit-perfect reproducibility
- Ecosystem integration -- drop-in Flower strategy, not a standalone experiment
- Benchmarked overhead -- sub-10ms aggregation for 100K parameters, not just accuracy claims
| Feature | FedAvg | Typical Robust FL | Qora-FL |
|---|---|---|---|
| Byzantine tolerance | -- | Paper-only | Validated (181-day deployment) |
| Deterministic option | -- | -- | Q16.16 fixed-point |
| Reputation tracking | -- | -- | Deviation-derived, persistent |
| Flower integration | Native | -- | Drop-in QoraStrategy |
| Benchmarked overhead | -- | -- | <10ms / 100K params |
| Production API | Partial | -- | Rust core + Python bindings |
Architecture
Clients produce model updates
│
▼
┌───────────────────────────┐
│ Qora Robust Aggregator │
│ │
│ ┌─────────────────────┐ │
│ │ Trimmed Mean (~30%) │ │
│ │ Median (~50%) │ │
│ │ Krum (n ≥ 2f+3) │ │
│ │ FedAvg (baseline) │ │
│ └─────────────────────┘ │
└─────────────┬─────────────┘
│
Deviation signal (not trust)
│
▼
┌─────────────────┐
│ Reputation │
│ Manager │
│ │
│ Scores / Gates │
│ / Weighting │
└────────┬────────┘
│
▼
Verified Global Update
flowchart LR
C1[Client 1] --> U[Client Updates]
C2[Client 2] --> U
Cn[Client N] --> U
U --> A[Qora Aggregator]
A -->|Deviation Signal| R[Reputation Manager]
R -->|Scores / Gates| A
A --> G[Aggregated Model]
style A fill:#f3f6ff,stroke:#4a6cf7,stroke-width:2px
style R fill:#fff7e6,stroke:#f59e0b,stroke-width:2px
Determinism & Reproducibility
Floating-point aggregation is not reproducible across platforms or runtimes. Qora-FL optionally supports deterministic aggregation paths via Q16.16 (I16F16) fixed-point arithmetic, enabling:
- Reproducible experiments -- identical results regardless of hardware, compiler, or optimization level
- Auditability -- any party can verify the exact aggregation result from the same inputs
- Consensus-style FL -- bit-perfect agreement required for regulated industries (healthcare, finance)
Deterministic modes trade numerical range for predictability and are explicitly surfaced in the API. The fixed-point Krum implementation was validated across ARM Cortex-M, Xtensa (ESP32), and x86_64 during the 181-day QRES deployment.
Reputation as a First-Class Primitive
Reputation in Qora-FL is not trust. It is a deviation-derived signal measuring how closely a client's update aligns with the emergent robust consensus.
Reputation may be used to:
- Weight aggregation contributions (cubic influence:
min(rep^3, 0.8)) - Gate participation (clients below threshold are excluded)
- Detect persistent outliers across rounds (not just per-round anomalies)
- Persist across server restarts via JSON serialization
The 0.8 influence cap prevents any single node from dominating consensus, even at maximum reputation. This mitigates the "Slander-Amplification" vulnerability identified during the QRES deployment.
Quick Start (Python + Flower)
pip install qora-fl[flower]
import flwr as fl
from qora import QoraStrategy
strategy = QoraStrategy(
aggregation_method="trimmed_mean",
trim_fraction=0.2,
min_fit_clients=5,
)
fl.server.start_server(
server_address="0.0.0.0:8080",
config=fl.server.ServerConfig(num_rounds=10),
strategy=strategy,
)
QoraStrategy inherits from FedAvg -- all standard Flower parameters (fraction_fit, min_fit_clients, initial_parameters, etc.) work as expected.
Python (Standalone)
pip install qora-fl
import numpy as np
from qora import ByzantineAggregator
agg = ByzantineAggregator("trimmed_mean", 0.3)
# 7 honest clients + 3 Byzantine attackers
updates = [np.array([[1.0, 2.0]], dtype=np.float32) for _ in range(7)]
updates += [np.array([[100.0, 200.0]], dtype=np.float32) for _ in range(3)]
result = agg.aggregate(updates)
# Result is [1.0, 2.0] -- attackers rejected
Reputation Tracking
from qora import ReputationManager
rep = ReputationManager(ban_threshold=0.2)
rep.reward("hospital_A", 0.02)
rep.penalize("hospital_bad", 0.08)
print(rep.is_banned("hospital_bad")) # True after enough penalties
print(rep.active_clients()) # Only non-banned clients
# Persist between server restarts
json_state = rep.to_json()
rep2 = ReputationManager.from_json(json_state, ban_threshold=0.2)
Rust
cargo add qora-fl
use qora_fl::{ByzantineAggregator, AggregationMethod};
use ndarray::array;
let mut agg = ByzantineAggregator::new(AggregationMethod::TrimmedMean, 0.3);
let updates = vec![
array![[1.0, 2.0]], // Honest
array![[1.1, 2.1]], // Honest
array![[0.9, 1.9]], // Honest
array![[100.0, 200.0]], // Byzantine attacker
];
let result = agg.aggregate(&updates, None).unwrap();
// Result is close to [1.0, 2.0], attacker ignored
Individual Functions
use qora_fl::{trimmed_mean, median, fedavg};
use ndarray::array;
let updates = vec![array![[1.0]], array![[2.0]], array![[3.0]]];
let tm = trimmed_mean(&updates, 0.2).unwrap();
let med = median(&updates).unwrap();
let avg = fedavg(&updates, None).unwrap();
Aggregation Methods
| Method | Byzantine Tolerance | Use Case |
|---|---|---|
TrimmedMean |
~30% of clients | Default choice for most FL deployments |
Median |
~50% of clients | When stronger robustness is needed |
Krum |
n >= 2f+3 | Fixed-point deterministic consensus |
FedAvg |
None | Baseline comparison only |
Benchmarks
Trimmed mean remains stable under ~30% label-flipping and gradient-scaling attacks, converging faster and to higher accuracy than undefended FedAvg. Aggregation overhead stays under 10ms for typical FL model sizes. At larger model sizes, aggregation cost becomes memory-bound, consistent with the behavior of coordinate-wise robust aggregation methods.
# Aggregation overhead (Python)
python examples/benchmark_overhead.py
# MNIST poisoning: FedAvg vs Qora-FL under 30% attack
pip install matplotlib scikit-learn
python examples/mnist_poisoning_demo.py
# Criterion benchmarks (Rust)
cargo bench
# Rust examples
cargo run --example quickstart
cargo run --example compare_methods
Background
Core algorithms validated in QRES (181-day autonomous IoT deployment with 30% Byzantine tolerance across ESP32 mesh networks). Qora-FL adapts this proven consensus to server-side federated learning with Rust-performance aggregation and Python/Flower integration.
Design Philosophy
Qora-FL treats aggregation as a decision process, not a statistical convenience. The system favors explicit constraints, observable signals, and predictable failure modes over opaque optimization.
Roadmap
- Weighted robust aggregation (reputation-scaled trimmed mean)
- Adaptive trim selection based on detected attack intensity
- TensorFlow Federated adapter
- Formal verification experiments for the deterministic path
License
Licensed under either of Apache License, Version 2.0 or MIT License at your option.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file qora_fl-0.3.1.tar.gz.
File metadata
- Download URL: qora_fl-0.3.1.tar.gz
- Upload date:
- Size: 155.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
662b73cc87ec0e3363e7e42774f7908fb660ff96b2570582cd6651b17a30c2e0
|
|
| MD5 |
c4eda7a594eb6ce20624fb4b53bc051d
|
|
| BLAKE2b-256 |
081a7b41641dfe6787fba9ef3eaf77ede1cc267a5928611ad5221f35d9ecc68a
|
Provenance
The following attestation bundles were made for qora_fl-0.3.1.tar.gz:
Publisher:
release.yml on CavinKrenik/qora-fl
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
qora_fl-0.3.1.tar.gz -
Subject digest:
662b73cc87ec0e3363e7e42774f7908fb660ff96b2570582cd6651b17a30c2e0 - Sigstore transparency entry: 928410194
- Sigstore integration time:
-
Permalink:
CavinKrenik/qora-fl@2a7059249a2f6753729ba3d9989dc60f2c1a1df3 -
Branch / Tag:
refs/tags/v0.3.1 - Owner: https://github.com/CavinKrenik
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@2a7059249a2f6753729ba3d9989dc60f2c1a1df3 -
Trigger Event:
release
-
Statement type:
File details
Details for the file qora_fl-0.3.1-cp38-abi3-win_amd64.whl.
File metadata
- Download URL: qora_fl-0.3.1-cp38-abi3-win_amd64.whl
- Upload date:
- Size: 315.0 kB
- Tags: CPython 3.8+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a15659d9ee6225f6d161cd2fe5283fdea3997d7af437da7d19106a3e5e142307
|
|
| MD5 |
88b8c3ad46072b20dbc2beae2e6b29a4
|
|
| BLAKE2b-256 |
b92bfc3fb76958d14e59f7dc7f150c4e62201791a9723fa28f4101d08b5f8f2d
|
Provenance
The following attestation bundles were made for qora_fl-0.3.1-cp38-abi3-win_amd64.whl:
Publisher:
release.yml on CavinKrenik/qora-fl
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
qora_fl-0.3.1-cp38-abi3-win_amd64.whl -
Subject digest:
a15659d9ee6225f6d161cd2fe5283fdea3997d7af437da7d19106a3e5e142307 - Sigstore transparency entry: 928410199
- Sigstore integration time:
-
Permalink:
CavinKrenik/qora-fl@2a7059249a2f6753729ba3d9989dc60f2c1a1df3 -
Branch / Tag:
refs/tags/v0.3.1 - Owner: https://github.com/CavinKrenik
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@2a7059249a2f6753729ba3d9989dc60f2c1a1df3 -
Trigger Event:
release
-
Statement type:
File details
Details for the file qora_fl-0.3.1-cp38-abi3-manylinux_2_34_x86_64.whl.
File metadata
- Download URL: qora_fl-0.3.1-cp38-abi3-manylinux_2_34_x86_64.whl
- Upload date:
- Size: 506.3 kB
- Tags: CPython 3.8+, manylinux: glibc 2.34+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
314135733ee0c7ba4025a462fa44b8c7fe8271ff2bb4b6115ff912fd591fc7d0
|
|
| MD5 |
e3d5d5294dcf73380ea61f784c237e9d
|
|
| BLAKE2b-256 |
3dc53b234a8d143e1a864fef7b2995929637f2a1b51a03d858a95f7f92bbfd9f
|
Provenance
The following attestation bundles were made for qora_fl-0.3.1-cp38-abi3-manylinux_2_34_x86_64.whl:
Publisher:
release.yml on CavinKrenik/qora-fl
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
qora_fl-0.3.1-cp38-abi3-manylinux_2_34_x86_64.whl -
Subject digest:
314135733ee0c7ba4025a462fa44b8c7fe8271ff2bb4b6115ff912fd591fc7d0 - Sigstore transparency entry: 928410197
- Sigstore integration time:
-
Permalink:
CavinKrenik/qora-fl@2a7059249a2f6753729ba3d9989dc60f2c1a1df3 -
Branch / Tag:
refs/tags/v0.3.1 - Owner: https://github.com/CavinKrenik
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@2a7059249a2f6753729ba3d9989dc60f2c1a1df3 -
Trigger Event:
release
-
Statement type:
File details
Details for the file qora_fl-0.3.1-cp38-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: qora_fl-0.3.1-cp38-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 432.2 kB
- Tags: CPython 3.8+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b1d02acade0c919d72fd8670c41f21ec8ba2c52d96d81d4fca15080e05325462
|
|
| MD5 |
03062172b9aca87e773558d6c7b95fb7
|
|
| BLAKE2b-256 |
1009199cbe475230a56ad541aa2c9dc64c9a8aea6035e378e21b0d16e5362050
|
Provenance
The following attestation bundles were made for qora_fl-0.3.1-cp38-abi3-macosx_11_0_arm64.whl:
Publisher:
release.yml on CavinKrenik/qora-fl
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
qora_fl-0.3.1-cp38-abi3-macosx_11_0_arm64.whl -
Subject digest:
b1d02acade0c919d72fd8670c41f21ec8ba2c52d96d81d4fca15080e05325462 - Sigstore transparency entry: 928410198
- Sigstore integration time:
-
Permalink:
CavinKrenik/qora-fl@2a7059249a2f6753729ba3d9989dc60f2c1a1df3 -
Branch / Tag:
refs/tags/v0.3.1 - Owner: https://github.com/CavinKrenik
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@2a7059249a2f6753729ba3d9989dc60f2c1a1df3 -
Trigger Event:
release
-
Statement type: