Communication-aware split inference for Vision-Language-Action models.
A mobile robot cannot run a 7B VLA on board, so perception is split from reasoning across a wireless link. That link then sits inside the control loop. The source is variable-bit-rate — LightVLA's cross-attention pruner emits 63–89 unique visual tokens depending on scene complexity — while the channel carries whatever the instantaneous SNR allows. When demand exceeds capacity, something has to decide which tokens to drop, every 50 ms.
ComVLA reads that decision off a signal the model already computes. Each of the
512 task-informed query patches votes, via argmax, for the original patch it
most agrees with. The resulting vote histogram is a zero-cost priority
metric: patches many queries agree on carry the task-relevant content. Sorting
by vote count and cutting at the channel's budget is training-free and needs no
change to the VLA.
On LIBERO, transmitting 32 of 512 tokens retains 95.4% average task success against 96.9% for full OpenVLA-OFT, at 68 KB/step instead of 1088 KB and 2.3 TFLOPs instead of 8.8. Dropping the same number of tokens at random scores 55.7%.
ComVLA: Communication-Aware Split Inference for VLA Models in 6G-Connected Robotics. B. Liu, W. Y. Poe, J. Di, R. Trivisonno, G. Caire. IEEE GLOBECOM 2026.
This repository is also the implementation base for Communication-Aware Robotic Foundation Models for 6G Mobile Robots, a EuroHPC AI Factories allocation request for JUPITER Booster. See what runs today for an honest split between the two.
Every claim below is checkable on a laptop in about a minute. No CUDA, no LIBERO, no model weights, no submodules.
git clone https://github.com/BL-Liu/ComVLA && cd ComVLA
pip install -e ".[dev]"
make test # 150+ CPU tests
make verify-golden # regenerate the published channel traces and diff
make budget # re-derive the 49,000 node-hour request
make verify-golden replays the channel realisations recorded alongside the GPU
evaluation that produced Table IV — 16,000 episodes, 364,717 control steps —
and asserts every reported SNR, capacity and token budget reproduces exactly:
32 traces | 16000 episodes | 364717 steps | 0 mismatches
tests/test_legacy_compat.py closes the loop the rest of the way: it recomputes
the mean token budget from those realisations, checks it against the committed
results/*/sweep_summary.csv to 1e-6, and checks the four-suite average against
the Avg K column of the published table:
| Mean SNR | Rayleigh: regenerated → CSV → paper | Rician: regenerated → CSV → paper |
|---|---|---|
| 5 dB | 48.1614 → 48.1614 → 48.2 | 53.2331 → 53.2331 → 53.2 |
| 10 dB | 82.4891 → 82.4891 → 82.5 | 90.4883 → 90.4883 → 90.5 |
| 15 dB | 123.6407 → 123.6407 → 123.6 | 133.6899 → 133.6899 → 133.7 |
| 20 dB | 168.4208 → 168.4208 → 168.4 | 179.6439 → 179.6439 → 179.6 |
Code → CSV → published table, on CPU, in one command.
The proposal's wireless abstraction is implemented, not sketched. One control period is four phases, and the split between what is true and what the transmitter knows is structural rather than incidental:
physical.step(pose) -> PhysicalState ground truth; the policy never sees this
link.observe(physical) -> LinkObservation delayed, noisy CSI + ACK/NACK feedback
policy.decide(obs, robot) -> SemanticAction (K tokens, quantization level)
link.transmit(action, phys) -> LinkOutcome truncation, erasure, retransmission, outage
| Layer | Module | What it does |
|---|---|---|
| Physical | comvla/channel/physical.py | Jake's Rayleigh/Rician/static fading (the published model), plus a mobility-conditioned path: pose and velocity drive pathloss, a temporally-correlated LOS/NLOS Markov chain, Gudmundson shadowing and Poisson blockage. Doppler is derived from speed, f_d = v·f_c/c. |
| Scenarios | comvla/channel/scenarios.py | TR 38.901-compatible InH-Office and UMi-Street-Canyon parameterizations. |
| Link | comvla/channel/link.py | A named DelayLine for stale CSI, linear-domain CSI estimation noise, a BLER curve, HARQ with a control deadline. |
| Semantic | comvla/channel/semantic.py | The Shannon budget policy plus all five evaluation controls, behind one Policy protocol. |
| Replay | comvla/channel/replay.py | Deterministic columnar traces so training and evaluation see identical channels — and so the oracle-future-CSI bound is definable at all. |
comvla-channel gen --fading rayleigh --mean-snr-db 10 --steps 300
comvla-channel gen --scenario umi_street_canyon --walk-speed 1.5 \
--blockage-rate-hz 0.3 --csi-delay-ms 100 --erasure sigmoid \
--steps 600 -o traces/umi
Pure NumPy, no torch. The refactor is guarded by
comvla/channel/_reference.py, a frozen copy of
the published implementation that the layered version is asserted bit-identical
to across 432 configurations.
Being explicit about this, because the repository backs a funding request:
| Status | |
|---|---|
| Three-layer channel package, replay, all policies | Implemented, CPU-only, 150+ tests |
| Token selection, vote histogram, quantization | Implemented, extracted from the model so it is testable on plain tensors |
| Static-K and CSI-driven evaluation | Implemented (needs GPU + LIBERO) |
| Analysis, figures, LaTeX tables | Implemented |
| A–G run grids, node-hour budget, Slurm templates, containers | Implemented |
| Channel-aware LoRA post-training (C-1, C-2) | Specified and budgeted, not implemented |
| Wireless-Robotic World Model training (D, E) | Specified and budgeted, not implemented |
The unimplemented drivers are declared as implemented: false in
configs/runs/, so comvla-matrix budgets them while
slurm/templates/_common.sh refuses to pretend to run them. Nothing in the
CPU-verifiable path above depends on them.
comvla-matrix budget --check expands every grid, asserts each declared count,
and reconciles the total against the proposal:
| Type | Phase | Runs | Nodes | Walltime | Node-hours |
|---|---|---|---|---|---|
| A | port / baseline profiling | 80 | 1 | 3 h | 240 |
| B | channel / trace validation | 120 | 1 | 8 h | 960 |
| C-1 | channel-aware LoRA factorial | 180 | 2 | 18 h | 6,480 |
| C-2 | larger / full VLA adaptation | 48 | 8 | 24+12 h | 13,824 |
| D | Wireless-Robotic World Model | 36 | 8 | 24+24+8 h | 16,128 |
| E | predictive decision / ablations | 36 | 4 | 24+12 h | 5,184 |
| F | held-out closed-loop evaluation | 220 | 1 | 4 h | 880 |
| G | robustness / trace reruns | 100 | 2 | 4 h | 800 |
| buffer (restarts, follow-up) | 4,504 | ||||
| total | 49,000 |
Evaluation-only phases are 1,680 node-hours, 3.4% — inside the 10% limit. Summed walltimes are dependency chains, so no single job exceeds a 24 h cap.
comvla-matrix expand configs/runs/C1_lora_factorial.yaml --out manifests/C1.jsonl
slurm/submit.sh C1 manifests/C1.jsonl
Each manifest line is a fully-resolved run with a content-derived run_id that
doubles as its output directory, so --only-missing restarts exactly the runs
whose DONE marker is absent.
export COMVLA_SITE=jupiter
$EDITOR slurm/sites/jupiter.sh # set SLURM_ACCOUNT
bash container/build.sh gh200
slurm/stage_assets.sh # login node: compute nodes have no network
slurm/stage_assets.sh --verify
All site-specific paths live in slurm/sites/; no absolute path
or account name appears anywhere else. See
docs/jupiter-quickstart.md.
The published torch version cannot be reproduced on GH200. LightVLA pins
torch==2.2.0+cu121, for which no aarch64 CUDA wheel exists or will exist. The
GPU image therefore builds on NGC PyTorch (which ships a real arm64/sbsa build
with CUDA 12.6 and a prebuilt flash-attn) and installs LightVLA with --no-deps
so pip cannot downgrade it.
Success is consequently not defined as version identity. It is defined as the
four LIBERO baselines reproducing within 1 percentage point on the aarch64 stack
— which is exactly what run type A's 240 budgeted node-hours exist to establish,
with the criterion written into
configs/runs/A_port_baseline.yaml. The
fallback ladder is in docs/porting.md.
Note that the CPU image, which covers the entire reviewable deliverable above,
builds on aarch64 today with none of this risk — and CI proves it on an aarch64
runner on every push.
comvla/channel/ three-layer channel, replay, policies (numpy only)
comvla/edge/ token selection, vote histogram, quantization
comvla/eval/ static-K and CSI-driven evaluation (needs GPU + LIBERO)
comvla/analysis/ figures, LaTeX tables, result manifest
comvla/configs/ the A-G matrix generator
configs/ declarative run grids + allocation.yaml
slurm/ env.sh, sites/, templates/, submit.sh, stage_assets.sh
legacy/ - the original scripts, kept for provenance
container/ Apptainer definitions (CPU + GH200)
tests/ the five named test areas + golden traces
results/ 83 sweep_summary.csv + manifest.csv
paper/ LaTeX tables and figures
docs/ porting, channel, results, milestones, migration
| docs/channel.md | Layer contracts, RNG discipline, what reproducibility is and is not promised |
| docs/porting.md | The aarch64/GH200 risk ladder |
| docs/jupiter-quickstart.md | First allocation day, step by step |
| docs/results.md | Which directory produced which table, and known caveats |
| docs/milestones.md | M1–M6 against run types A–G |
| docs/architecture.md | Edge/cloud split and the voting mechanism |
| docs/migration.md | semantic_flow → comvla |
@inproceedings{liu2026comvla,
title = {{ComVLA}: Communication-Aware Split Inference for {VLA} Models
in {6G}-Connected Robotics},
author = {Liu, Boliang and Poe, Wint Yi and Di, Jieqi and
Trivisonno, Riccardo and Caire, Giuseppe},
booktitle = {IEEE Global Communications Conference (GLOBECOM)},
year = {2026}
}
MIT. LightVLA, OpenVLA-OFT and LIBERO are MIT-licensed upstream projects; see third_party/PROVENANCE.md for exactly what we changed (two files, 75 lines, shipped as patches rather than a fork).
Python
80.6%
Shell
18.1%
TeX
1.1%
Communication-aware split inference for Vision-Language-Action models.
A mobile robot cannot run a 7B VLA on board, so perception is split from reasoning across a wireless link. That link then sits inside the control loop. The source is variable-bit-rate — LightVLA's cross-attention pruner emits 63–89 unique visual tokens depending on scene complexity — while the channel carries whatever the instantaneous SNR allows. When demand exceeds capacity, something has to decide which tokens to drop, every 50 ms.
ComVLA reads that decision off a signal the model already computes. Each of the
512 task-informed query patches votes, via argmax, for the original patch it
most agrees with. The resulting vote histogram is a zero-cost priority
metric: patches many queries agree on carry the task-relevant content. Sorting
by vote count and cutting at the channel's budget is training-free and needs no
change to the VLA.
On LIBERO, transmitting 32 of 512 tokens retains 95.4% average task success against 96.9% for full OpenVLA-OFT, at 68 KB/step instead of 1088 KB and 2.3 TFLOPs instead of 8.8. Dropping the same number of tokens at random scores 55.7%.
ComVLA: Communication-Aware Split Inference for VLA Models in 6G-Connected Robotics. B. Liu, W. Y. Poe, J. Di, R. Trivisonno, G. Caire. IEEE GLOBECOM 2026.
This repository is also the implementation base for Communication-Aware Robotic Foundation Models for 6G Mobile Robots, a EuroHPC AI Factories allocation request for JUPITER Booster. See what runs today for an honest split between the two.
Every claim below is checkable on a laptop in about a minute. No CUDA, no LIBERO, no model weights, no submodules.
git clone https://github.com/BL-Liu/ComVLA && cd ComVLA
pip install -e ".[dev]"
make test # 150+ CPU tests
make verify-golden # regenerate the published channel traces and diff
make budget # re-derive the 49,000 node-hour request
make verify-golden replays the channel realisations recorded alongside the GPU
evaluation that produced Table IV — 16,000 episodes, 364,717 control steps —
and asserts every reported SNR, capacity and token budget reproduces exactly:
32 traces | 16000 episodes | 364717 steps | 0 mismatches
tests/test_legacy_compat.py closes the loop the rest of the way: it recomputes
the mean token budget from those realisations, checks it against the committed
results/*/sweep_summary.csv to 1e-6, and checks the four-suite average against
the Avg K column of the published table:
| Mean SNR | Rayleigh: regenerated → CSV → paper | Rician: regenerated → CSV → paper |
|---|---|---|
| 5 dB | 48.1614 → 48.1614 → 48.2 | 53.2331 → 53.2331 → 53.2 |
| 10 dB | 82.4891 → 82.4891 → 82.5 | 90.4883 → 90.4883 → 90.5 |
| 15 dB | 123.6407 → 123.6407 → 123.6 | 133.6899 → 133.6899 → 133.7 |
| 20 dB | 168.4208 → 168.4208 → 168.4 | 179.6439 → 179.6439 → 179.6 |
Code → CSV → published table, on CPU, in one command.
The proposal's wireless abstraction is implemented, not sketched. One control period is four phases, and the split between what is true and what the transmitter knows is structural rather than incidental:
physical.step(pose) -> PhysicalState ground truth; the policy never sees this
link.observe(physical) -> LinkObservation delayed, noisy CSI + ACK/NACK feedback
policy.decide(obs, robot) -> SemanticAction (K tokens, quantization level)
link.transmit(action, phys) -> LinkOutcome truncation, erasure, retransmission, outage
| Layer | Module | What it does |
|---|---|---|
| Physical | comvla/channel/physical.py | Jake's Rayleigh/Rician/static fading (the published model), plus a mobility-conditioned path: pose and velocity drive pathloss, a temporally-correlated LOS/NLOS Markov chain, Gudmundson shadowing and Poisson blockage. Doppler is derived from speed, f_d = v·f_c/c. |
| Scenarios | comvla/channel/scenarios.py | TR 38.901-compatible InH-Office and UMi-Street-Canyon parameterizations. |
| Link | comvla/channel/link.py | A named DelayLine for stale CSI, linear-domain CSI estimation noise, a BLER curve, HARQ with a control deadline. |
| Semantic | comvla/channel/semantic.py | The Shannon budget policy plus all five evaluation controls, behind one Policy protocol. |
| Replay | comvla/channel/replay.py | Deterministic columnar traces so training and evaluation see identical channels — and so the oracle-future-CSI bound is definable at all. |
comvla-channel gen --fading rayleigh --mean-snr-db 10 --steps 300
comvla-channel gen --scenario umi_street_canyon --walk-speed 1.5 \
--blockage-rate-hz 0.3 --csi-delay-ms 100 --erasure sigmoid \
--steps 600 -o traces/umi
Pure NumPy, no torch. The refactor is guarded by
comvla/channel/_reference.py, a frozen copy of
the published implementation that the layered version is asserted bit-identical
to across 432 configurations.
Being explicit about this, because the repository backs a funding request:
| Status | |
|---|---|
| Three-layer channel package, replay, all policies | Implemented, CPU-only, 150+ tests |
| Token selection, vote histogram, quantization | Implemented, extracted from the model so it is testable on plain tensors |
| Static-K and CSI-driven evaluation | Implemented (needs GPU + LIBERO) |
| Analysis, figures, LaTeX tables | Implemented |
| A–G run grids, node-hour budget, Slurm templates, containers | Implemented |
| Channel-aware LoRA post-training (C-1, C-2) | Specified and budgeted, not implemented |
| Wireless-Robotic World Model training (D, E) | Specified and budgeted, not implemented |
The unimplemented drivers are declared as implemented: false in
configs/runs/, so comvla-matrix budgets them while
slurm/templates/_common.sh refuses to pretend to run them. Nothing in the
CPU-verifiable path above depends on them.
comvla-matrix budget --check expands every grid, asserts each declared count,
and reconciles the total against the proposal:
| Type | Phase | Runs | Nodes | Walltime | Node-hours |
|---|---|---|---|---|---|
| A | port / baseline profiling | 80 | 1 | 3 h | 240 |
| B | channel / trace validation | 120 | 1 | 8 h | 960 |
| C-1 | channel-aware LoRA factorial | 180 | 2 | 18 h | 6,480 |
| C-2 | larger / full VLA adaptation | 48 | 8 | 24+12 h | 13,824 |
| D | Wireless-Robotic World Model | 36 | 8 | 24+24+8 h | 16,128 |
| E | predictive decision / ablations | 36 | 4 | 24+12 h | 5,184 |
| F | held-out closed-loop evaluation | 220 | 1 | 4 h | 880 |
| G | robustness / trace reruns | 100 | 2 | 4 h | 800 |
| buffer (restarts, follow-up) | 4,504 | ||||
| total | 49,000 |
Evaluation-only phases are 1,680 node-hours, 3.4% — inside the 10% limit. Summed walltimes are dependency chains, so no single job exceeds a 24 h cap.
comvla-matrix expand configs/runs/C1_lora_factorial.yaml --out manifests/C1.jsonl
slurm/submit.sh C1 manifests/C1.jsonl
Each manifest line is a fully-resolved run with a content-derived run_id that
doubles as its output directory, so --only-missing restarts exactly the runs
whose DONE marker is absent.
export COMVLA_SITE=jupiter
$EDITOR slurm/sites/jupiter.sh # set SLURM_ACCOUNT
bash container/build.sh gh200
slurm/stage_assets.sh # login node: compute nodes have no network
slurm/stage_assets.sh --verify
All site-specific paths live in slurm/sites/; no absolute path
or account name appears anywhere else. See
docs/jupiter-quickstart.md.
The published torch version cannot be reproduced on GH200. LightVLA pins
torch==2.2.0+cu121, for which no aarch64 CUDA wheel exists or will exist. The
GPU image therefore builds on NGC PyTorch (which ships a real arm64/sbsa build
with CUDA 12.6 and a prebuilt flash-attn) and installs LightVLA with --no-deps
so pip cannot downgrade it.
Success is consequently not defined as version identity. It is defined as the
four LIBERO baselines reproducing within 1 percentage point on the aarch64 stack
— which is exactly what run type A's 240 budgeted node-hours exist to establish,
with the criterion written into
configs/runs/A_port_baseline.yaml. The
fallback ladder is in docs/porting.md.
Note that the CPU image, which covers the entire reviewable deliverable above,
builds on aarch64 today with none of this risk — and CI proves it on an aarch64
runner on every push.
comvla/channel/ three-layer channel, replay, policies (numpy only)
comvla/edge/ token selection, vote histogram, quantization
comvla/eval/ static-K and CSI-driven evaluation (needs GPU + LIBERO)
comvla/analysis/ figures, LaTeX tables, result manifest
comvla/configs/ the A-G matrix generator
configs/ declarative run grids + allocation.yaml
slurm/ env.sh, sites/, templates/, submit.sh, stage_assets.sh
legacy/ - the original scripts, kept for provenance
container/ Apptainer definitions (CPU + GH200)
tests/ the five named test areas + golden traces
results/ 83 sweep_summary.csv + manifest.csv
paper/ LaTeX tables and figures
docs/ porting, channel, results, milestones, migration
| docs/channel.md | Layer contracts, RNG discipline, what reproducibility is and is not promised |
| docs/porting.md | The aarch64/GH200 risk ladder |
| docs/jupiter-quickstart.md | First allocation day, step by step |
| docs/results.md | Which directory produced which table, and known caveats |
| docs/milestones.md | M1–M6 against run types A–G |
| docs/architecture.md | Edge/cloud split and the voting mechanism |
| docs/migration.md | semantic_flow → comvla |
@inproceedings{liu2026comvla,
title = {{ComVLA}: Communication-Aware Split Inference for {VLA} Models
in {6G}-Connected Robotics},
author = {Liu, Boliang and Poe, Wint Yi and Di, Jieqi and
Trivisonno, Riccardo and Caire, Giuseppe},
booktitle = {IEEE Global Communications Conference (GLOBECOM)},
year = {2026}
}
MIT. LightVLA, OpenVLA-OFT and LIBERO are MIT-licensed upstream projects; see third_party/PROVENANCE.md for exactly what we changed (two files, 75 lines, shipped as patches rather than a fork).
Python
80.6%
Shell
18.1%
TeX
1.1%