@edgeflowertunegroup/edgeflowertune-flexlora
flwr new @edgeflowertunegroup/edgeflowertune-flexloraedgeflowertune-flexlora
PyTorch reference implementation, Apache-2.0, published by edgeflowertunegroup. This is not the historical MobileFineTuner native/mobile experiment implementation and does not reproduce its device measurements.
Different client ranks, weighted dense LoRA updates, SVD redistribution at each rank.
This release supports the pinned Qwen2.5-0.5B checkpoint, a real Flower ServerApp and ClientApp, Simulation and Deployment, and server-owned PEFT checkpoints. Data preparation and Logger are included as source under vendor/. No weights, private device configurations, credentials, or training data are included. Downloads keep their upstream licenses; Apache-2.0 covers this code, not the external models or datasets.
Quick start: two clients on one computer
Use Python 3.11 or 3.12. CPU is the default. Allow several GB of RAM for model weights and training (16 GB or more is recommended for the two-process setup). Run the following from the downloaded App directory:
python3 -m venv .venv source .venv/bin/activate python -m pip install -e . export FLWR_TELEMETRY_ENABLED=0 export RAY_USAGE_STATS_ENABLED=0 export FLWR_HOME="$PWD/.flwr" mkdir -p "$FLWR_HOME" cp -n flower-config.toml "$FLWR_HOME/config.toml" python vendor/toolkit/participant_toolkit/prepare_public_assets.py model \ --model qwen25_05b --reference --output "$PWD/assets/model" python vendor/toolkit/participant_toolkit/prepare_reference_datasets.py \ --dataset boolq --output "$PWD/assets/data" python vendor/toolkit/integrations/pytorch/reference_tasks.py \ --model qwen25_05b --dataset boolq --model-dir "$PWD/assets/model" \ --train-csv "$PWD/assets/data/boolq/train.csv" \ --validation-csv "$PWD/assets/data/boolq/validation.csv" \ --train-limit 32 --eval-limit 32 --output-dir "$PWD/assets/prepared" export EFT_MODEL_DIR="$PWD/assets/model" export EFT_PREPARED_DATA="$PWD/assets/prepared" export EFT_OUTPUT_ROOT="$PWD/outputs" python -m unittest discover -s tests -v flwr build python -m eft_flower.local_simulation
The default is 2 rounds, 3 effective-batch optimizer updates per client per round, batch 8, sequence 128, alpha 16, learning rate 0.0002, seed 42. FedAvg/FedProx use rank 8. FlexLoRA uses ranks 4 and 8, a rank-8 server adapter, and explicitly sends rank-specific adapters in the first round too. Standard client training accumulates eight microbatches of size 1. SplitLoRA does not perform client optimizer steps: each client uploads three batches of eight embeddings and the server makes three optimizer updates for that client.
The Simulation resource settings schedule one client worker at a time to limit RAM use. Both partitions still participate, and the server uses every client. The helper starts and stops its own loopback SuperLink, then checks that the run actually completed. This avoids Flower 1.27's background auto-started SuperLink retaining stale environment variables when switching Apps. For manual use, start flower-superlink --insecure --simulation --isolation subprocess --control-api-address 127.0.0.1:39193 --simulationio-api-address 127.0.0.1:39194 in a separate terminal, run flwr run . local-simulation --stream, and stop the SuperLink afterwards. Do not run multiple helpers on these same ports at once. num-clients, options.num-supernodes, each SuperNode's num-partitions and the number of client-ranks entries (FlexLoRA) must agree.
The shared config exposes other methods' parameters for source consistency: prox-mu only affects FedProx; client-ranks only affects FlexLoRA; split-temperature and split-queue-size only affect SplitLoRA. The method field is fixed to flexlora; use the other published App when changing algorithms. Example overrides that preserve this App's identity:
python -m eft_flower.local_simulation \ --run-config "num-server-rounds=3 local-steps=3 learning-rate=0.0001"
FedProx requires at least two local updates because its penalty is zero at the round-start reference. FlexLoRA aggregates (alpha/r) * B @ A, weighted by partition sample count, then uses a truncated SVD for each client rank. It does not pad and directly average differently shaped factors. SplitLoRA implements the existing cut-0 frozen-embedding design: hidden layers and all trainable LoRA parameters are on the server; dot-product contrastive loss uses positive answer embeddings, in-batch negatives and a bounded negative queue. It is not FedAvg, has no client embedding gradient, and has no LoRA downlink. Server clients are processed in partition order with one persistent server optimizer.
Prepared reference tasks include BoolQ, QNLI, PIQA, HellaSwag, SocialQA, ARC-E and WinoGrande; change --dataset in both preparation commands and match the prepared sequence length (128 for BoolQ, 64 for the other tasks). This release's end-to-end acceptance uses BoolQ, not a claim that all datasets/devices have been retested. Data and model files are verified against the included reference catalog, and mismatching task contracts fail instead of silently mixing inputs.
Deployment: same code, separate processes
For a local loopback test, open four terminals in the App directory. Activate the same environment and set the same FLWR_HOME, EFT_* variables as above in each terminal. Every remote machine must have its own local copy of those assets.
# Terminal 1 flower-superlink --insecure --fleet-api-address 127.0.0.1:9092 \ --control-api-address 127.0.0.1:9093 --serverappio-api-address 127.0.0.1:9091 # Terminal 2 flower-supernode --insecure --superlink 127.0.0.1:9092 \ --clientappio-api-address 127.0.0.1:9094 \ --node-config "partition-id=0 num-partitions=2" # Terminal 3 flower-supernode --insecure --superlink 127.0.0.1:9092 \ --clientappio-api-address 127.0.0.1:9095 \ --node-config "partition-id=1 num-partitions=2" # Terminal 4 flwr run . local-deployment --stream
Explicit partition IDs work identically in both runtimes and must be unique. Never expose these insecure loopback commands to the Internet. Use Flower TLS and authentication for a remote deployment. Stop your three local services with Ctrl-C when finished. CPU host tests are not Android/Termux tests.
Inspect results and reload a checkpoint
Outputs are in $EFT_OUTPUT_ROOT/<Flower-run-id>/. A successful run must have summary.json with status=completed, round-evidence.json, logger-run/, and one round-XXXX.zip per round. An exit code alone is not acceptance.
# Replace RUN_ID with the directory name printed by your run. export RUN="$EFT_OUTPUT_ROOT/RUN_ID" PYTHONPATH=vendor/toolkit/participant_toolkit/logger \ python -m edgeflowertune_logger.cli validate-run --run-dir "$RUN/logger-run" python vendor/toolkit/integrations/pytorch/virtual_predictor.py \ --model-dir "$EFT_MODEL_DIR" --checkpoint "$RUN/round-0002.zip" \ --dataset "$EFT_PREPARED_DATA/validation.jsonl" --task boolq \ --output "$RUN/predictions.jsonl"
The checkpoint contains real LoRA weights/configuration, not pre-trained model weights. It preserves the eft_virtual_checkpoint.v1 format and prediction head metadata. For SplitLoRA, prediction uses hidden-state/embedding dot products; the other three use the language-model head.
Measurement and competition limits
- Recorded: real step loss/time, current RSS and process-lifetime peak RSS, serialized tensor upload/download bytes, and parameter-aggregation time.
- Peak RSS is a process high-water mark, not the memory of LoRA weights alone; a reused worker can retain a higher peak from an earlier step.
- Upload/download durations and power are null, not estimated or zero: Flower strategy callbacks do not expose one-way network timing or a sensor. Tensor bytes exclude transport envelopes and acknowledgements.
- SplitLoRA records client embedding timings separately from server optimizer timings; it has zero parameter downlink bytes and no averaging operation. Its aggregation duration is not applicable, not a fabricated zero.
- Runs are explicitly development-only, not automatically valid competition scores. Ordinary Logger integrity checks are distinct from strict system measurement checks, which correctly reject the unavailable fields.
Publishing source does not submit a benchmark result. After producing a valid result through the organizer's current competition protocol, enter its matching Flower Hub App URL and version in the optional code fields. The leaderboard's Flower Hub Open badge is an open-code link, not Flower's official reviewer signature, a quality certificate, or permission to relabel old MFT results.
Source and publication
Code is released as Apache-2.0; see LICENSE. The vendored task preparation and Logger are project source, kept self-contained for reproducibility. External Flower, PyTorch, Transformers and PEFT packages are installed as dependencies, not relicensed here. Public authorship uses the project group only; runtime logs may contain your own machine metadata, so review logs before sharing them.
# Maintainer only, after reviewing files and testing this exact release python3 -m venv .publish-venv .publish-venv/bin/python -m pip install flwr==1.42.0 .publish-venv/bin/flwr login supergrid .publish-venv/bin/flwr app publish .
Publishing uses a separate current CLI because the historical 1.27 gRPC login endpoint is no longer compatible with the hosted service. Keep the tested training environment at 1.27; do not upgrade it in place just to log in.
Official guide: Publish an App on Flower Hub. Do not put private assets or outputs in the upload directory. Hub's public App name is immutable and published versions cannot be deleted.