Skip to content

ajbarea/velocity-fl

Repository files navigation

⚡ Velocity-FL (vFL)

Velocity-FL

Tests Documentation Codecov CodSpeed

Velocity-FL is a federated learning orchestration project with a Rust core and a Python-first interface.


What is this? 🧭

Velocity-FL provides:

  • 🦀 Rust core (vfl-core) for aggregation, attack simulation, and round orchestration
  • 🐍 Python package (python/velocity) for researcher-facing APIs and a fallback pure-Python orchestrator
  • 🖥️ Typer CLI (velocity) for local experimentation and quick capability inspection
  • 🤖 MCP server (velocity.mcp_app) exposing the framework to a Claude agent as MCP tools
  • 📚 Zensical docs (docs/) deployed via GitHub Actions

Current capabilities ✅

Aggregation strategies

All real implementations in vfl-core/src/strategy.rs with paper-cited algorithms and unit-test fixtures derived from each paper.

  • FedAvg — sample-weighted mean (McMahan et al., AISTATS 2017)
  • FedProx — FedAvg aggregation + proximal term in client training (Li et al., MLSys 2020)
  • FedMedian — coordinate-wise median (Yin et al., ICML 2018)
  • TrimmedMean — drop-k extremes per coordinate (Yin et al., ICML 2018)
  • Krum — single closest by Krum score (Blanchard et al., NeurIPS 2017)
  • MultiKrum — top-m by Krum score (El Mhamdi et al., ICML 2018)
  • Bulyan — Multi-Krum → trimmed-mean composition (El Mhamdi et al., ICML 2018)
  • GeometricMedian — RFA Weiszfeld iteration, sample-weighted (Pillutla et al., IEEE TSP 2022)
  • ArKrum — parameter-free Byzantine-robust Krum; estimates the adversary count per round, no f to tune (Yang, Imam, et al. 2025, arXiv:2505.17226)

Round-level attacks (velocity.attacks)

  • model_poisoning — sign-flip a fraction of one client's weights
  • sybil_nodes — inject count synthetic Byzantine clients
  • gaussian_noise — add N(0, σ²) noise to global weights

Data-pipeline attacks (velocity.data_attacks)

  • apply_label_flipping — bijective derangement of the label space (Biggio et al., ICML 2012)
  • apply_targeted_label_flipping — source→target with flip_ratio (Tolpegin et al., ESORICS 2020)

Experiment store & attack arena

  • Persistent run store (velocity.db) — every run is recorded; velocity sweep runs strategy × attack matrices (a TOML spec or ad-hoc flags) across seeds in parallel.
  • velocity leaderboard ranks stored runs on seven axes: accuracy, rounds-to-target, wall-clock, communication cost (total bytes sent), the accuracy-vs-cost Pareto frontier (--cost selects wall-clock or communication), its per-(dataset × attack) slices, and robustness (accuracy drop under attack).
  • Attack arena (docs/leaderboard.md) — five aggregators (FedAvg baseline, Krum, MultiKrum, Bulyan, ArKrum) ranked against a fixed six-attack Byzantine corpus (Gaussian, IPM, label-flip, sign-flip, ALIE, Fang-Krum).

Quick start 🚀

1) Clone and install

git clone https://github.com/ajbarea/velocity-fl.git
cd velocity-fl

uv sync
uv run maturin develop

2) Run a minimal Python example

The fastest path is the built-in simulator — useful for checking the install and the attack surface before wiring up real data. The simulator generates synthetic client updates (it tests round plumbing, not actual training); for end-to-end FL on real data, see step 3 below.

from velocity import VelocityServer, FedAvg

server = VelocityServer(
    model_id="demo/model",
    dataset="demo/dataset",  # record-keeping string; real loading is below
    strategy=FedAvg(),
)

server.simulate_attack("gaussian_noise", intensity=0.05)
summaries = server.run(min_clients=1, rounds=1)
print(summaries)

For a real federated round on a real model + dataset, install the [hf,torch] extras and use load_federated:

uv pip install 'velocity-fl[hf,torch]'
from velocity.datasets import load_federated

split = load_federated(
    "ylecun/mnist",
    num_clients=5,
    partition="shard",
    shards_per_client=2,  # McMahan-style non-IID — ~2 digit classes per client
    batch_size=64,
    seed=0,
)
print([c.num_samples for c in split.clients])

End-to-end runs live at examples/mnist_fedavg.py (shard partition) and examples/cifar10_fedavg_dirichlet.py (Dirichlet-α partition). Observed convergence is snapshotted in docs/convergence.md.

3) Use the CLI

velocity --help
velocity version
velocity strategies
velocity run --model-id test/model --dataset test/dataset --rounds 1 --min-clients 1
velocity simulate-attack model_poisoning --intensity 0.2
velocity sweep --strategies FedAvg,Krum --attacks gaussian_noise --rounds 5
velocity leaderboard --metric robustness
velocity archive out/<ts>-sweep -o run.crate.zip   # bundle a sweep into a reproducibility archive
velocity reproduce run.crate.zip --check            # re-run it elsewhere and verify results match

CLI reference (quick) 💻

  • velocity version — print package version
  • velocity strategies — list available strategies
  • velocity run ... — run rounds and print JSON summaries
  • velocity simulate-attack ... — register one attack and run a round
  • velocity sweep ... — run a strategy × attack matrix across seeds (see docs/sweep-spec.md)
  • velocity leaderboard ... — rank stored runs (accuracy / rounds-to-target / wall-clock / comm-cost / pareto / pareto-slices / robustness)
  • velocity archive ... — package a sweep output into a single-file reproducibility archive (RO-Crate)
  • velocity reproduce ... — re-run an archived sweep (--check verifies results within tolerance)

Full reference: docs/cli.md


Development 🧪

Run tests

# Rust
cargo test --all

# Python
uv run pytest tests/ -v

Build docs locally

uv run zensical build --clean

Documentation 📚

Published site: https://ajbarea.github.io/velocity-fl/


Repository layout 🗂️

velocity-fl/
├── vfl-core/                 # Rust crate and PyO3 bindings
├── python/velocity/          # Python package + CLI
├── examples/                 # End-to-end demos (e.g. MNIST FedAvg)
├── tests/                    # Python test suite
├── docs/                     # Zensical documentation source
├── .github/workflows/        # CI workflows (tests + docs)
├── pyproject.toml            # Python packaging and tooling
├── Cargo.toml                # Rust workspace manifest
└── zensical.toml             # Docs build config

Performance 📊

The claim vFL defends is on aggregation — the one step the library owns. Client-side local training is PyTorch's territory; we don't time it and we don't claim to speed it up.

On a 1M-parameter model with 10 clients, the Rust aggregation kernel runs ~135× faster than the pure-Python fallback (4.0 ms vs 545 ms, FedAvg). At 10M params, Rust aggregates in ~42 ms versus pure Python's ~5.8 s (~138×).

End-to-end, this matters less than the raw ratio suggests: on the MNIST FedAvg demo (5 clients, ~109K params), aggregation is ~10 ms of a ~1.3-second round — the rest is torch local training. The aggregation-speedup lever compounds at robust-aggregator (Krum, Bulyan), high-client-count, and small-update scales, not at small-model simulation.

Full methodology, all shape tiers, and honest caveats (PyO3 marshaling overhead, FedMedian's sort cost, WSL noise) live in docs/benchmarks.md. Convergence evidence lives in docs/convergence.md. Reproduce with make bench (kernel) and uv run python examples/mnist_fedavg.py (end-to-end).


Coverage 📈

Codecov

Sunburst Grid Icicle


Why "velocity"

Latin velocitas: speed. The whole reason the framework exists — a Rust core under a Python-first API, so the hot loops of federated aggregation run at compiled speed, not Python's.

License

MIT


  2026 AJ Barea

About

The uv of federated learning — Rust core for aggregation and attack sim, Python API for HuggingFace, PEFT, and PyTorch.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Contributors

Languages