Official source code for AdaFed, accepted at the International Conference on Ubiquitous and Future Networks (ICUFN).
AdaFed is a federated-learning algorithm for architecturally heterogeneous autonomous-driving stacks. Seven end-to-end driving models — TCP, TransFuser, InterFuser, LAV, ReasonNet, VAD, UniAD — collaborate by sharing only the layers that match across stacks (ResNet-34/50 backbones and BEV encoders/lifters). On top of partial weight averaging, AdaFed adds three mechanisms:
- Tier-adaptive aggregation — picks the best base FL strategy per sharing tier (SCAFFOLD / FedAvg / FedProx).
- Soft alpha blending —
w_new = α · w_avg + (1 - α) · w_local, instead of overwriting local weights. - Validation-based rollback with α adaptation — if a round worsens a client's ADE, the round is undone and α is decreased; otherwise α is increased.
All seven heterogeneous driving stacks running concurrently in one CARLA world (main.py). Each tile shows that agent's front camera, speed, and live throttle/steer/brake bars; the right-most panel is the global HUD.
- Results
- Repository layout
- Installation
- Data collection
- Training pipeline
- Reproducing the paper
- Running the multi-agent simulation
- Citation
- License
- Acknowledgements
Average Displacement Error (ADE, meters; lower is better) on the held-out CARLA episodes 12–14, starting from the IL baseline weights and running 10 federated rounds with local epochs = 2.
| Model | IL baseline | FedAvg | FedProx | SCAFFOLD | FedMD | FedDF | AdaFed | Best FL | AdaFed − prev. best |
|---|---|---|---|---|---|---|---|---|---|
| TCP | 1.70 | 3.17 | 3.04 | 2.39 | 4.19 | 3.26 | 2.54 | scaffold (2.39) | +0.15 |
| TransFuser | 1.72 | 2.54 | 2.57 | 2.30 | 2.68 | 2.32 | 3.04 | scaffold (2.30) | +0.74 |
| InterFuser | 1.27 | 1.33 | 1.34 | 2.25 | 1.69 | 2.26 | 1.36 | fedavg (1.33) | +0.03 |
| LAV | 2.09 | 2.63 | 2.67 | 2.46 | 3.03 | 3.04 | 3.06 | scaffold (2.46) | +0.60 |
| ReasonNet | 1.30 | 1.35 | 1.35 | 2.06 | 3.15 | 2.77 | 1.46 | fedavg (1.35) | +0.11 |
| VAD | 1.55 | 2.42 | 2.31 | 5.55 | 5.75 | 4.41 | 2.05 | adafed (2.05) | −0.26 |
| UniAD | 1.44 | 1.57 | 1.64 | 2.25 | 2.80 | 2.34 | 1.52 | adafed (1.52) | −0.05 |
Raw per-round logs: results/. A full ablation discussion is in EXPERIMENTS.md.
Take-away. On the
bev_lifttier (VAD, UniAD), where FedAvg and SCAFFOLD both fail (SCAFFOLD: 5.55 m on VAD), AdaFed's tier-adaptive choice + rollback delivers the best FL score and beats every baseline. For tiers where a single strategy already works, AdaFed remains close to the best while still being safer (it cannot diverge thanks to rollback).
AdaFed/
├── main.py # Multi-agent CARLA demo (7 driving models live)
├── Final.py # AdaFed training + IL/FL summary table
├── EXPERIMENTS.md # Full experimental write-up (Korean)
├── requirements.txt
├── LICENSE # Apache 2.0
├── CITATION.cff
│
├── hete_fl/ # Library
│ ├── carla_env/ # CARLA world / sensors / sync wrapper
│ ├── config/ # YAML configs
│ ├── dataset/driving_dataset.py
│ ├── models/ # 7 model implementations + shared blocks
│ │ ├── common/ # Reused encoders (ResNet, BEVEncoder, …)
│ │ ├── tcp/ transfuser/ interfuser/ lav/
│ │ ├── reasonnet/ vad/ uniad/
│ │ └── basic_driving_agent.py
│ ├── fl/
│ │ ├── client.py # Local trainer / validator
│ │ ├── server.py # Round orchestration
│ │ ├── utils.py # Tier definitions + canonical key remap
│ │ └── strategies/
│ │ ├── fedavg.py fedprox.py scaffold.py
│ │ ├── fedmd.py feddf.py
│ │ └── adafed.py # ◀── this paper
│ ├── safety/traffic_handler.py
│ ├── ui/display.py # Pygame HUD
│ └── utils/ # PID controller, transforms
│
├── scripts/
│ ├── run_carla_server.bat
│ ├── download_weights.py # Fetch upstream pretrained weights
│ ├── collect_driving_data.py # Expert demonstrations on CARLA
│ ├── collect_tl_data.py # Traffic-light classifier data
│ ├── train_tl_classifier.py
│ ├── train_imitation.py # IL baselines (per-model)
│ ├── train_fl.py # Six FL strategies (incl. AdaFed)
│ ├── evaluate_models.py
│ └── compare_il_fl.py
│
├── results/ # Per-round CSVs + final comparison
└── weights/ # Checkpoints (excluded from Git, see below)
| Tier | Members | Base strategy used by AdaFed |
|---|---|---|
resnet34_backbone |
TCP, TransFuser, LAV | SCAFFOLD |
resnet50_backbone |
InterFuser, ReasonNet, VAD, UniAD | FedAvg |
bev_encoder |
TransFuser, InterFuser, LAV, ReasonNet | FedAvg |
bev_lift |
VAD, UniAD | FedProx (μ = 0.01) |
Tier definitions and the canonical key remapping that lets weights from different architectures be averaged live in hete_fl/fl/utils.py.
Download CARLA 0.9.16 from the official release page and extract it next to the repo (or anywhere on disk). Either:
- place it at
./CARLA_0.9.16/, or - create a symlink:
ln -s /path/to/CARLA_0.9.16 ./CARLA_0.9.16
The training and main scripts add CARLA_0.9.16/PythonAPI/carla to sys.path, so make sure the folder name matches.
# Conda (recommended — CARLA 0.9.16 ships a Python 3.12 wheel)
conda create -n hete_fl python=3.12 -y
conda activate hete_fl
# PyTorch (CUDA 12.4 build used in the paper)
pip install torch==2.6.0 torchvision==0.21.0 --index-url https://download.pytorch.org/whl/cu124
# Everything else
pip install -r requirements.txtIf you do not have a CUDA-capable GPU, install the CPU-only PyTorch wheel from pytorch.org and expect substantially longer training times — all experiments in the paper were run on a single GPU.
For models that ship upstream pretrained checkpoints (UniAD, VAD, TransFuser), grab them via:
python scripts/download_weights.py --model all
# or selectively:
python scripts/download_weights.py --model transfuser uniad_e2e vad_baseThe IL baseline and FL .pth files in weights/ are not committed to Git — they are produced locally by scripts/train_imitation.py and scripts/train_fl.py. The small per-model training histories (il_baseline_history.{csv,json}) are kept so you can inspect convergence without downloading multi-gigabyte checkpoints.
# 1. Start the simulator
scripts/run_carla_server.bat # Windows
# (or run CarlaUE4.sh on Linux)
# 2. Drive an expert (CARLA BasicAgent) and dump RGB / LiDAR / state
python scripts/collect_driving_data.py \
--episodes 15 \
--output data/drivingThe paper uses 15 episodes (~29,475 frames) on Town03: episodes 0–11 for training (with 10–11 also serving as the public set for FedMD / FedDF), and 12–14 held out for validation.
A small auxiliary traffic-light classifier dataset can be collected via scripts/collect_tl_data.py and trained with scripts/train_tl_classifier.py; it is only required for the main.py live demo, not for the FL benchmark.
python scripts/train_imitation.py # all 7 models, sequential
python scripts/train_imitation.py --models TCP VAD # subset
python scripts/train_imitation.py --epochs 30 # override training budgetOutputs weights/{model}/il_baseline.pth plus a training history JSON/CSV per model.
python scripts/train_fl.py --strategy fedavg --rounds 10
python scripts/train_fl.py --strategy fedprox --mu 0.01
python scripts/train_fl.py --strategy scaffold
python scripts/train_fl.py --strategy fedmd --kd-weight 1.0
python scripts/train_fl.py --strategy feddf --kd-weight 1.0 --temperature 1.0
python scripts/train_fl.py --strategy adafed --rounds 10 --alpha-init 0.5 --mu 0.01
python scripts/train_fl.py --strategy all # run every baselineEach strategy writes weights/{model}/fl_{strategy}.pth (best checkpoint by validation ADE) and results/fl_{strategy}_{training,summary}.csv.
python Final.py # train AdaFed and print the comparison
python Final.py --skip-training # just regenerate results/final_comparison.csv
python Final.py --rounds 5# 1) Collect data (~15 episodes, Town03)
python scripts/collect_driving_data.py --episodes 15 --output data/driving
# 2) Train all IL baselines (~12 h on a single RTX-class GPU)
python scripts/train_imitation.py
# 3) Train every FL strategy at 10 rounds × 2 local epochs (~60 h)
python scripts/train_fl.py --strategy all --rounds 10 --local-epochs 2
# 4) Re-train AdaFed (≈2.5 h) and emit the comparison table
python Final.py --rounds 10Per-round CSVs land in results/. The summary tables in this README and in the paper are produced from results/final_comparison.csv.
Note on determinism. Training is not exactly reproducible from a fixed seed because CARLA's non-deterministic spawn order changes the data distribution. Numbers should be expected to fall within ±0.05 m of the values reported here when retrained.
main.py spawns all seven trained agents in a single CARLA world plus NPC traffic, with a Pygame chase camera and live HUD (see the hero screenshot above).
# Terminal 1: start the simulator
scripts/run_carla_server.bat
# Terminal 2: run the demo (loads weights/{model}/fl_adafed.pth by default)
conda activate hete_fl
python main.pyControls: Tab to switch the chase camera between agents, Esc to quit.
If you find this code or the paper useful, please cite:
@inproceedings{hwang2026adafed,
title = {{AdaFed}: Adaptive Selective Federated Learning for Heterogeneous Autonomous Driving Models},
author = {Hwang, Sunjun and <CO_AUTHORS>},
booktitle = {Proceedings of the International Conference on Ubiquitous and Future Networks (ICUFN)},
year = {2026},
note = {To appear}
}A machine-readable CITATION.cff is also provided — once the proceedings are published, please replace the placeholders with the canonical DOI, page numbers, and full author list.
Released under the Apache License 2.0. Note that the upstream pretrained weights downloaded by scripts/download_weights.py (UniAD, VAD, TransFuser, …) remain governed by their respective original licenses — please check each project's repository before redistribution.
The seven driving stacks reimplemented under hete_fl/models/ are based on the publicly released code and pretrained weights of:
- TCP — OpenPerceptionX/TCP
- TransFuser — autonomousvision/transfuser
- InterFuser — opendilab/InterFuser
- LAV — dotchen/LAV
- ReasonNet — autonomousvision/reasonnet
- VAD — hustvl/VAD
- UniAD — OpenDriveLab/UniAD
The simulation environment is built on top of CARLA 0.9.16.