# EdgeFlowerTune participant guide

Current website: https://47.85.216.164 · Public guide revision: 20261024-concise-guide.

Main path: download/install → pinned assets and policy → section 5 FedAvg A/B/C
→ complete evaluated ZIP → Submit → completed/published. Sections 6–8 also document
custom integrations; native MF and short developer checks are optional appendices.

## 1. What is ranked

**The leaderboard ranks checkpoint quality and calibrated simulations of system costs.** Train your model, evaluate its saved checkpoints, and use the common Evaluator to calculate device and network costs. Client counts describe the simulated device mix.

You can also collect real-device measurements for local research. Label each measurement by its source and scope, and use JSON null / N/A for unavailable readings.

The handoff has two sibling folders:

- `EdgeFlowerTune/`: training source, including the updated vendored MF
  operators. No separate `MobileFineTuner_upstream` is needed.
- `EdgeFlowerTune_Benchmark_Site/`: website, Logger, Quality Runner, Evaluator,
  adapters and packaging tools.

Download the **participant tools**, **training runtime source**, and **release-pair.json** from the website. Keep both original ZIPs and the manifest together. After extracting the participant tools, verify the pair:

```bash
python participant_toolkit/verify_download_pair.py \
  --manifest /path/to/downloads/release-pair.json --directory /path/to/downloads
```

Extract the runtime into `EdgeFlowerTune/`. The pair manifest identifies the matching training and participant-tools release by SHA-256. See `MODEL_DOWNLOADS.md` for model downloads, immutable revisions, and the seven reference dataset pairs. Save `benchmark-release.json` and the policy snapshot with your experiment. Use the `--reference` commands to prepare the pinned model files and `participant_toolkit/prepare_reference_datasets.py` to reconstruct the datasets.

For a single-GPU installation check, see [the six-method integration guide](../integrations/pytorch/VIRTUAL_FEDERATED.md). For a full submission, follow section 5 below.

## 2. Register and install

Open `/register/`, enter your email, request a code, and verify it within ten minutes. Save the submission token shown on screen. Re-verifying the same email replaces its token and keeps the same team account. Use the `X-Submission-Token` header for API uploads. Keep the token private and out of uploaded ZIPs. Use HTTPS for registration and uploads.

Extract the whole participant ZIP. Python 3.9+ supports the core tools; use a
Python version supported by your chosen PyTorch/Transformers runtime for training.

```bash
python3 participant_toolkit/install_tools.py
source .venv/bin/activate
export EFT_ROOT="$PWD"
python -m edgeflowertune_logger.cli --help
python -m edgeflowertune_evaluator.cli evaluate-run --help
```

Windows: run `python participant_toolkit\install_tools.py`, then use
`.venv\Scripts\python.exe`. Bash/native examples below require macOS or Linux.
Successful installation prints `All five command checks passed`.

## 3. Registered matrix

All A/B/C protocols cover Qwen2.5-0.5B, Gemma 3-270M, Gemma 3-1B and seven tasks. Formal submissions use the fixed sequence lengths below and effective batch size 8. The complete matrix is `webapp/data/benchmark_matrix.v1.json`.

| Dataset | Logger ID | Quality task | Sequence |
|---|---|---|---|
| BoolQ | `boolq` | boolq | 128 |
| QNLI | `qnli` | qnli | 64 |
| PIQA | `piqa` | piqa | 64 |
| HellaSwag | `hellaswag` | hellaswag | 64 |
| SocialIQA | `socialqa` | socialiqa | 64 |
| ARC-Easy | `arc_e` | arc_easy | 64 |
| WinoGrande | `winogrande` | winogrande | 64 |

Logger benchmark IDs follow `{model}_{logger_id}_b8_s{seq_len}_v1`.
Logger models are `qwen2_5_0_5b`, `gemma3_270m`, `gemma3_1b`;
the website calls the Qwen model `qwen25_05b`. Effective batch is 8.

Each final upload is one protocol + one model + one method:

- A: seven independent dataset runs.
- B: seven checkpoint curves, one for each dataset.
- C: seven datasets × (one nominal baseline + eight perturbations) = 63 runs.
  Publication contains 56 perturbed rows and their baseline comparisons.

### 3.1. Protocol B scoring and reference accuracies

**Protocol B keeps three registered accuracy targets per model/dataset.**
For each target, the server selects the first evaluated checkpoint that reaches
or exceeds it, then ranks cumulative time, communication, energy and peak memory
separately (lower cost is better). One checkpoint curve supplies all three target comparisons.
A complete seven-dataset B package produces 21 target results. An unreached
target has no cost or rank; it contributes no points to an otherwise active
scoring item. An item with no valid participants has zero weight.

Use the three registered accuracy targets from the paper's Protocol B tables
(Appendix B), as listed in `protocol_b_targets` with their `target_level`
identifiers. Policy: **protocol-b-paper-tables-20261022-v1**.
Qwen / BoolQ uses **71%, 75%, 78%**; Qwen / ARC-Easy uses **75%, 76%, 77%**.
Use the registered targets and keep L1/L2/L3 distinct
even when the published accuracy values are equal.

| Model | Dataset | L1 (%) | L2 (%) | L3 (%) |
|---|---|---:|---:|---:|
| Qwen2.5-0.5B | BoolQ | 71.00 | 75.00 | 78.00 |
| Qwen2.5-0.5B | QNLI | 62.00 | 63.00 | 64.00 |
| Qwen2.5-0.5B | PIQA | 63.00 | 64.00 | 65.00 |
| Qwen2.5-0.5B | HellaSwag | 30.00 | 32.00 | 33.00 |
| Qwen2.5-0.5B | SocialIQA | 62.00 | 64.00 | 66.00 |
| Qwen2.5-0.5B | ARC-Easy | 75.00 | 76.00 | 77.00 |
| Qwen2.5-0.5B | WinoGrande | 57.00 | 60.00 | 62.00 |
| Gemma 3-270M | BoolQ | 62.00 | 63.00 | 64.00 |
| Gemma 3-270M | QNLI | 61.00 | 65.00 | 69.00 |
| Gemma 3-270M | PIQA | 52.00 | 53.00 | 53.00 |
| Gemma 3-270M | HellaSwag | 25.00 | 25.00 | 25.00 |
| Gemma 3-270M | SocialIQA | 38.00 | 39.00 | 40.00 |
| Gemma 3-270M | ARC-Easy | 28.00 | 29.00 | 30.00 |
| Gemma 3-270M | WinoGrande | 51.00 | 51.00 | 51.00 |
| Gemma 3-1B | BoolQ | 62.00 | 63.00 | 64.00 |
| Gemma 3-1B | QNLI | 57.00 | 60.00 | 63.00 |
| Gemma 3-1B | PIQA | 53.00 | 53.00 | 54.00 |
| Gemma 3-1B | HellaSwag | 25.00 | 25.00 | 25.00 |
| Gemma 3-1B | SocialIQA | 40.00 | 42.00 | 45.00 |
| Gemma 3-1B | ARC-Easy | 27.00 | 27.00 | 28.00 |
| Gemma 3-1B | WinoGrande | 51.00 | 51.00 | 51.00 |

**Local Only and Centralized provide historical accuracy references.** Centralized uses the ID `centroid` in code and some tables. Both reference methods are excluded from competitive scoring; submissions are ranked by the protocol rules below.

The table below lists accuracy references from `webapp/data/editable/protocol_a_results.csv`. Each model has Local Only and Centralized columns. Protocol B uses its own registered target table above.

| Dataset | Qwen2.5-0.5B Local | Qwen2.5-0.5B Centralized | Gemma 3-270M Local | Gemma 3-270M Centralized | Gemma 3-1B Local | Gemma 3-1B Centralized |
|---|---:|---:|---:|---:|---:|---:|
| BoolQ | 71.99 | 80.24 | 60.28 | 69.66 | OOM | 70.00 |
| QNLI | 63.88 | 85.76 | 62.93 | 78.29 | OOM | 68.00 |
| PIQA | 61.22 | 65.45 | 50.24 | 50.87 | OOM | 57.02 |
| HellaSwag | 26.06 | 35.13 | 24.73 | 25.20 | OOM | 31.65 |
| SocialIQA | 59.31 | 68.07 | 37.86 | 44.98 | OOM | 49.03 |
| ARC-Easy | 74.53 | 79.47 | 29.26 | 30.00 | OOM | 28.25 |
| WinoGrande | 56.69 | 63.93 | 50.43 | 50.59 | OOM | 51.22 |

OOM marks a run that exceeded the evaluated edge client pool’s memory capacity. Its accuracy reference is unavailable.

### 3.2. How scores are computed

- A: rank best-checkpoint accuracy (higher is better) and loss (lower is better)
  separately. There is no resource-limit gate.
- B: at each frozen target, rank time, communication, energy and peak memory
  separately (lower is better).
- C: rank absolute deltas from the independent nominal baseline for accuracy,
  time, communication, energy and memory separately (smaller is better).
- Metric rank r earns 11-r points for ranks 1 through 10, and zero above 10.
  Equal metric values share competition ranks, for example 1, 1, 3.
- For each active model/dataset/metric comparison (also target for B, condition
  for C), n is its valid non-reference participant count. A protocol score is
  sum(n * points) / sum(n). Every method uses the same denominator: missing
  results, OOM and unreached targets contribute zero to active comparisons.
  A comparison with no valid ranked results has zero weight. Per-model scores
  use the same rule restricted to that model.
- Final score is (A + B + C) / 3 with the current 1:1:1 weights. A missing protocol
  contributes zero; the remaining weights are not renormalized. Scores are
  reported by the API to four decimal places; the page displays two. Ties at API
  precision are ordered by method name; equal-looking two-decimal values can
  still differ. 
- Centralized and Local Only are excluded from competitive ranks. A method with
  no scored comparison has no ranked result. A nominal C run supplies a baseline
  for the scored perturbations.

Example: two active comparisons have n=4 and n=2. A method earning 10 and 8
points scores (4*10 + 2*8)/(4+2) = 9.3333. If its second result is missing,
it scores (4*10 + 2*0)/6 = 6.6667. Ranks and weights update as new valid participants join.

## 4. Fetch one server policy snapshot

```bash
export EDGEFLOWERTUNE_URL="https://47.85.216.164"
export SUBMISSION_CONFIG_FILE=/absolute/path/to/edgeflowertune-server-config.json
curl -fsS "$EDGEFLOWERTUNE_URL/api/submissions/config" \
  -o "$SUBMISSION_CONFIG_FILE"
export PROTOCOL_POLICY_FILE=/absolute/path/to/edgeflowertune-protocol-policy.json
curl -fsS "$EDGEFLOWERTUNE_URL/api/submissions/protocol-policy" \
  -o "$PROTOCOL_POLICY_FILE"
python participant_toolkit/verify_benchmark_release.py \
  --protocol-policy "$PROTOCOL_POLICY_FILE" --server-config "$SUBMISSION_CONFIG_FILE"
```

Use https://47.85.216.164 on the standard HTTPS port. The release check verifies that the tools, policy and server configuration match before training. Final packaging checks the ZIP against the saved server capacity configuration.

Use the same policy snapshot throughout training, evaluation and packaging. Set `protocol_policy` in the suite JSON or `PROTOCOL_POLICY_FILE`. The suite saves the snapshot and its SHA-256 in the run directory and passes it to each subprocess. An explicit `--protocol-policy` overrides the environment setting. Download the current policy from the server for formal submissions.

If the server policy changes during an experiment, contact the organizer to resolve the version mismatch before uploading.

Before final packaging, save the current `/api/submissions/config` response and set `SUBMISSION_CONFIG_FILE` to its absolute path, or pass `--server-config` to `pack_protocol.py`. The packager checks ZIP size, extracted size and file count against those limits. Contact the organizer if a complete suite exceeds them. Refresh the snapshot when server limits change.

## 5. FedAvg: the main single-GPU user workflow

Train on your allocated CUDA GPU, then upload the evaluated results. Virtual clients execute sequentially, keep separate data and adapter states, and aggregate on the same machine. For single-host CPU training, use Appendix A and `integrations/pytorch/README.md`. The built-in virtual-client runner uses PyTorch; native MF integration is described separately in Appendix A.

From the extracted participant-tools directory, prepare a training environment.
The short acceptance environment used Python 3.13, PyTorch 2.8.0+cu128,
Transformers 4.57.1, PEFT 0.18.0 and Flower 1.27.0. Use a CUDA build appropriate
to your driver. Existing training environments may skip the venv creation.

```bash
export EFT_ROOT="$PWD"
python3 -m venv .venv-training
source .venv-training/bin/activate
python participant_toolkit/install_tools.py --env-dir "$VIRTUAL_ENV"
python -m pip install -r integrations/pytorch/requirements-tested.txt
python -m pip install flwr==1.27.0 PyYAML==6.0.2
export TRAINING_ROOT=/absolute/path/to/EdgeFlowerTune
export MODEL=qwen25_05b
export MODEL_DIR=/absolute/path/to/Qwen2.5-0.5B
export REFERENCE_DATA_ROOT=/absolute/path/to/reference-data
export METHOD_ID="fedavg_$(python -c 'import uuid; print(uuid.uuid4().hex[:12])')"
export OUTPUT_A=/absolute/path/to/new-fedavg-A
export OUTPUT_B=/absolute/path/to/new-fedavg-B
export OUTPUT_C=/absolute/path/to/new-fedavg-C
# Set these for your experiment:
: "${CUDA_VISIBLE_DEVICES:?Set your allocated GPU index or UUID}"
: "${CLIENTS:?Set at least 2 virtual clients}"
: "${SEED:?Set a nonnegative seed}"
: "${ROUNDS:?Set training rounds}"
: "${LOCAL_STEPS:?Set local optimizer updates per round}"
```

METHOD_ID is your unique published identity, separate from the algorithm selector.
Generate it once, save it with your settings and retain it across A/B/C for the
same method. Do not use reserved baseline IDs such as fedavg. Generate a different
ID for a different algorithm or method version.
Custom IDs must be 3–64 lowercase letters/digits with single underscores between
segments (for example, team_a_fedavg_v1). Uppercase, hyphens, leading/trailing
underscores and reserved baseline aliases are rejected during preflight, before
training. The generated ID above already follows these rules.

Use MODEL_DOWNLOADS.md to prepare the pinned model and seven original CSV pairs.
The data root contains boolq/, qnli/, piqa/, hellaswag/, socialiqa/, arce/ and
winogrande/, each with train.csv and validation.csv. Preserve the policy and
capacity snapshots from section 4. No nonzero subset limits are allowed below.

Choose the protocol you want to submit. Each command initially performs only
preflight. After it succeeds, remove only `--preflight` and repeat to execute.
The runner performs training, Logger validation, checkpoint reload,
quality evaluation, calibrated simulation and complete evaluated packaging.

### 5.1. Protocol A: quality

Seven datasets produce seven evaluated runs. Select the best evaluated checkpoint for each dataset; accuracy and loss are ranked separately.

```bash
python integrations/pytorch/run_reference_matrix.py \
  --training-root "$TRAINING_ROOT" \
  --model "$MODEL" --model-dir "$MODEL_DIR" \
  --data-root "$REFERENCE_DATA_ROOT" --output-dir "$OUTPUT_A" \
  --methods fedavg --datasets all \
  --clients "$CLIENTS" --seed "$SEED" \
  --rounds "$ROUNDS" --local-steps "$LOCAL_STEPS" \
  --protocol A --protocol-policy "$PROTOCOL_POLICY_FILE" \
  --submission-id "$METHOD_ID" --for-submission --preflight
```

Output after execution: `$OUTPUT_A/edgeflowertune_protocol_A.zip`.

### 5.2. Protocol B: cost to target

Seven dataset checkpoint curves produce 21 target comparisons. The first evaluated checkpoint reaching each frozen target supplies its cumulative costs. Unreached targets stay unscored;

```bash
python integrations/pytorch/run_reference_matrix.py \
  --training-root "$TRAINING_ROOT" \
  --model "$MODEL" --model-dir "$MODEL_DIR" \
  --data-root "$REFERENCE_DATA_ROOT" --output-dir "$OUTPUT_B" \
  --methods fedavg --datasets all \
  --clients "$CLIENTS" --seed "$SEED" \
  --rounds "$ROUNDS" --local-steps "$LOCAL_STEPS" \
  --protocol B --protocol-policy "$PROTOCOL_POLICY_FILE" \
  --submission-id "$METHOD_ID" --for-submission --preflight
```

Output after execution: `$OUTPUT_B/edgeflowertune_protocol_B.zip`.

### 5.3. Protocol C: robustness

Seven datasets each run one nominal baseline and eight registered perturbations: 63 independent runs, publishing 56 condition rows. Dropout affects actual participation; device and bandwidth costs use the common calibration. No physical sensors are required.

```bash
python integrations/pytorch/run_reference_matrix.py \
  --training-root "$TRAINING_ROOT" \
  --model "$MODEL" --model-dir "$MODEL_DIR" \
  --data-root "$REFERENCE_DATA_ROOT" --output-dir "$OUTPUT_C" \
  --methods fedavg --datasets all \
  --clients "$CLIENTS" --seed "$SEED" \
  --rounds "$ROUNDS" --local-steps "$LOCAL_STEPS" \
  --protocol C --protocol-policy "$PROTOCOL_POLICY_FILE" \
  --submission-id "$METHOD_ID" --for-submission --preflight
```

Output after execution: `$OUTPUT_C/edgeflowertune_protocol_C.zip`.

### 5.4. Check the ZIP and continue to Submit

```bash
export PROTOCOL_PACKAGE="$OUTPUT_B/edgeflowertune_protocol_B.zip"
python -m zipfile -t "$PROTOCOL_PACKAGE"
```

Choose the A/C output when appropriate. Check `ledger.json` for successful stages and keep `SUBMISSION_CONFIG_FILE` set for packaging. Contact the organizer if a complete suite exceeds the upload capacity.

The built-in runner handles the training, evaluation and packaging described in sections 6–8. Continue to section 8 to upload its output. Those sections also document custom integrations; section 10 provides an optional local interface demo.

For another model, use `gemma3_270m` or `gemma3_1b` and its pinned `MODEL_DIR`. For another method, select `fedprox`, `hetero`, `split`, `centroid` or `local`. Each formal suite runs one method; FedProx requires at least two local updates. Centralized supports A/B. Centralized and Local Only are local reference analyses: omit `--submission-id` for them. Use a new output directory for every protocol/model/method.

Use the short subset check in `integrations/pytorch/REFERENCE_MATRIX.md` to verify installation. Start a full-input run with `--for-submission` for the formal suite.

## 6. Formal simulation evidence

For the six built-in methods, the reference matrix runner's explicit
full-input submission mode automates training and steps 6–8 below. Centralized
is A/B-only. See `integrations/pytorch/REFERENCE_MATRIX.md` for the exact command.

For a custom method, connect its client updates and aggregation to `EdgeTuneRecorder`. Record client, round and step IDs, effective batch, sequence length, trainable parameters, checkpoint boundaries and transmitted bytes. The common simulation calculates ranked system costs. Label any additional sensor readings by source and measurement scope.

```bash
python -m edgeflowertune_logger.cli validate-run \
  --run-dir "$RUN_DIR" --strict-system-metrics
python participant_toolkit/quality/official_quality_runner.py \
  --run-dir "$RUN_DIR" --output "$QUALITY_FILE" \
  --task boolq --dataset "$OFFICIAL_BOOLQ_JSONL" \
  --predict-command "$PREDICT_COMMAND"
python -m edgeflowertune_evaluator.cli evaluate-run \
  --run-dir "$RUN_DIR" --output "$EVALUATOR_DIR" \
  --quality-metrics "$QUALITY_FILE" --model qwen2_5_0_5b --dataset boolq \
  --protocol A --system 20J20I20P20M20N \
  --protocol-policy "$PROTOCOL_POLICY_FILE" --include-checkpoints
```

Use `--protocol B` for a B checkpoint curve. Formal runs require the full evaluation split, checkpoint files and hashes, execution trace, and model/data locks. Package a run after all stages succeed.

Protocol A selects the highest-accuracy evaluated checkpoint, breaking ties by lower loss, lower simulated wall time, earlier logical step, then record index. Missing loss sorts after finite loss at equal accuracy. Record the calibrated system costs alongside quality.

## 7. Protocol C: simulated device and network conditions

Device-mix counts specify simulated clients. The common calibration calculates device and communication costs from the execution trace, bandwidth multipliers and `segment_seconds` schedule.

Apply the policy’s dropout schedule to client participation in each round and record it with `log_client_selection`. Run an independent nominal baseline with the same model, dataset and method.

Evaluator condition arguments, in addition to the common arguments above:

```bash
# Baseline
--protocol C --scenario nominal --condition-label 20J+20I+20P+20M+20N
# A registered heterogeneous condition (use matching --system 100J)
--protocol C --scenario heterogeneity --condition-label 100J
```

Exact condition names, systems and policies come from the downloaded JSON.
The evaluated `protocol_c_claim` and policy digest are checked by the server.
You can attach real-device measurements as an additional research report.

## 8. Run a suite, pack and upload

Copy `participant_toolkit/suite_config.example.json` and configure seven
official evaluation files, real training and predictor commands, the policy
snapshot and a NEW output directory. Trainer placeholders are `{run_dir}`,
`{model}`, `{dataset}`, `{protocol}`, `{sequence_length}`,
`{condition_config}`, `{system_mix}`, `{protocol_policy}`.
The trainer must create a completed Logger run. Predictor placeholders are
`{checkpoint}`, `{dataset}`, `{output}`, `{task}`.
Use this template to connect your training and prediction commands.
Replace every example path with your actual training/prediction implementation.
Relative dataset, output, policy and working-directory paths are resolved from
the suite JSON's directory, not the terminal's current directory. Training
commands run in `training_cwd`; predictors run in `predict_cwd`; both default
to the JSON directory. Relative script paths follow their respective working
directories. `~` in executable/script paths is expanded before execution.
Use absolute paths for other command arguments. Preflight checks use the same
resolved commands as the actual run. Pack to a new ZIP filename: existing
packages are never overwritten.
The standalone Qwen example includes Logger hooks. For physical-device methods, connect training, transfer and aggregation events before building the seven-dataset suite.

```bash
python participant_toolkit/run_protocol_suite.py --config /path/to/suite.json --preflight
python participant_toolkit/run_protocol_suite.py --config /path/to/suite.json
# Or collect already completed evaluated runs:
python participant_toolkit/pack_protocol.py --protocol B --model qwen25_05b \
  --input-dir /path/to/seven-dataset-runs --output /path/to/protocol_B.zip \
  --protocol-policy "$PROTOCOL_POLICY_FILE"
```

Upload the final protocol ZIP at `/submit/` with your team token, protocol, model, method name and description. Check for `completed / published` to confirm publication. The server validates each complete package before publishing it.

For a direct API upload, send `submission_scope=protocol-model` and `model_id`
along with `protocol`, the ZIP and the `X-Submission-Token` header. The official
website rejects missing or `task` scope; single-task development uploads are
only supported by the isolated demo workflow below.

## 9. Release prerequisites

Prepare the reference models and fourteen source CSVs using `MODEL_DOWNLOADS.md`. Choose the client count, seed and training schedule for your run. The reference integration records partitioning and preprocessing, trains each task, and evaluates its saved checkpoints.

The reference catalog is `participant_toolkit/reference_assets.v1.json`, also available at `/downloads/reference-assets.json`. `MODEL_DOWNLOADS.md` lists model revisions, verification commands and dataset reconstruction steps.

## 10. Local publication

The `/submit/` form is for a formal `official/local-signed` website and complete
protocol/model packages. In a local `demo` server it is disabled; task-level
development submissions still use the existing API/scripts. From the extracted
tools folder, after installing `webapp/requirements.txt`, run:

```bash
bash examples/qwen25_boolq/run_isolated_publication_demo.sh
```

The demo starts a local website with an isolated database and test credentials to exercise upload and publication. Use section 5 for training and formal submissions.

## Appendix A. Optional development and native MF examples

### Interface-only fixture

```bash
bash examples/qwen25_boolq/run_contract_smoke.sh
```

The fixture uses generated checkpoints and a small sample dataset to exercise the tools’ interfaces.

`run_isolated_publication_demo.sh` tests HTTP publication on a local server with temporary credentials.

### Current native MF example

Build the shipped `standalone/qwen_lora_finetune` runtime with a current Rust/Cargo toolchain and the listed build dependencies. Check `rustc --version` and `cargo --version` in the build shell. See https://rust-lang.org/tools/install/ for installation.

```bash
export MFT_ROOT=/absolute/path/to/EdgeFlowerTune
cmake -S "$MFT_ROOT/standalone/qwen_lora_finetune" \
  -B "$MFT_ROOT/standalone/qwen_lora_finetune/build-release" \
  -DCMAKE_BUILD_TYPE=Release -DQWEN_USE_HF_TOKENIZERS=ON
cmake --build "$MFT_ROOT/standalone/qwen_lora_finetune/build-release" --target train -j 4
export MFT_BIN="$MFT_ROOT/standalone/qwen_lora_finetune/build-release/train"
python integrations/mobilefinetuner/check_external.py
# Set model and Arrow paths using MODEL_DOWNLOADS.md first.
bash examples/qwen25_boolq/run_real_mobilefinetuner_10step.sh
```

The script runs ten updates and saves `lora.safetensors`. Rebuild the shipped trainer to record per-step timing.

The example produces a development package (`official_artifact=false`) from a small public subset. Timing covers complete optimizer updates; RSS covers the whole process. Supply power readings or estimates with their measurement scope.

The SocialIQA/B and ARC-Easy/C examples use the same single-host development workflow.

### PyTorch example and optional real-device hooks

See `integrations/pytorch/README.md` for Qwen/BoolQ training, PEFT checkpoint evaluation and development packaging. `TrainingMonitor` records optimizer updates and exposes hooks for real transfers, aggregation and optional power sensors.
