Back to Blog
LoongForgeVLALingBot-VATraining Acceleration

Accelerating LingBot-VA Training: A Technical Walkthrough

2026-10-15 · The LoongForge Team

LingBot-VA is an embodied-AI model that jointly models video and action. Its training suffers from redundant parameter communication, unbalanced load from variable-length samples, per-layer chains of small kernels that slow the backward pass, and GPUs that frequently wait on CPU scheduling. LoongForge applies system-level optimization across the whole training path and achieves 2.20x training throughput and a 54.5% shorter step time.

1. Background: new training challenges from joint video-action modeling

In embodied AI, models that jointly model a "video-generation backbone + action branch" (WAM-style models) are quickly becoming mainstream. Instead of simply chaining a vision encoder and an action head, they predict both how the scene will evolve and how the robot should act, grounding control in an understanding of physical dynamics. This markedly improves long-horizon task success and sample efficiency. LingBot-VA is a representative example: it uses a large pretrained video diffusion model as its backbone, interleaves video latents and action tokens into one unified sequence, and performs autoregressive flow-matching generation. It reports leading success rates on simulation benchmarks such as RoboTwin 2.0 and LIBERO.

But this architecture puts very different pressure on the training system than a conventional VLA does:

The net effect: when training with the community open-source implementation, the GPU spends a large share of its time not computing but waiting for communication, waiting for masks, and waiting for the slowest GPU.

2. Overview: start from "what is the GPU waiting for?"

To improve LingBot-VA training efficiency, the Baidu Baige team restructured its training path at the system level on LoongForge, our open-source omni-modal training framework. We did not start by "swapping in a faster kernel". We started by using profiling to answer one question: where does the time in a step actually go?

Based on NSys timelines and NVTX ranges, we split step time into three kinds of waste that can be optimized independently:

On top of these comes a load problem tied directly to the model: rank stragglers caused by variable-length samples.

Along these four directions, with the same model structure, data, and hyperparameters, LoongForge raises training throughput to 2.20x that of the community open-source implementation. The key techniques behind this follow.

3. Under the hood: four engineering optimizations behind the 2.2x

Optimization 1: FSDP parameter communication — from one all-gather per microbatch to one per step

The default semantics of sharded-parameter training are: all-gather the full parameters before forward, reshard immediately after use to free memory, and all-gather again for backward. This is reasonable with a single microbatch, but it degrades under gradient accumulation: every microbatch in a step repeats "all-gather → compute → reshard", even though all of them use exactly the same parameters.

LoongForge postpones resharding from "after every forward/backward" to "after the optimizer update". When wrapping with FSDP, we turn off reshard_after_forward so the parameters stay unsharded for the whole step and are reused by every microbatch. We also register a step post-hook on the optimizer so that, once the parameter update is done, everything is resharded in one go and the memory is returned. The number of parameter all-gathers per step drops from "number of microbatches × 2 (one each for forward and backward)" to 1.

Parameter communication comparison: the framework default does an AllGather and a reshard for every microbatch (5 AllGathers + 5 reshards); LoongForge does a single AllGather per step and reshards after optimizer.step(), saving a stretch of step time
Figure 1: Parameter communication — one all-gather per microbatch vs. one per step.

An ablation quantifies this item: turning the optimization off increases step time by 21.16%. It also explains why the gain scales linearly with the number of gradient-accumulation steps: the more steps, the more repeated communication is saved.

A companion change concerns gradient-reduction precision. We align reduce_dtype in the FSDP mixed-precision policy with the parameter precision (BF16), which removes the precision conversions around reduce-scatter and the larger communication payload. This alone is worth about 2%, and it matches the community implementation exactly under the accuracy gate.

Optimization 2: load balancing for variable-length samples — cost-balanced sampling and microbatch alignment

Sample lengths in embodied data are naturally uneven. The default distributed sampler slices samples to ranks in index order, so some ranks get a batch of long samples and others a batch of short ones. Because gradient synchronization is a global barrier, each step takes as long as the slowest rank, and all the time saved by the short-sample ranks turns into idle waiting.

LoongForge implements a cost-balanced distributed sampler:

Variable-length embodied samples: with a sequential partition the ranks carry very different loads and most wait a long time at the gradient-sync barrier; with a cost-balanced partition and a cost-aligned order, all ranks reach the barrier at almost the same time
Figure 2: With variable-length samples, the slowest rank sets the time of every step. Left: sequential partition. Right: cost-balanced partition plus cost-aligned microbatch order (hatched areas are ranks idling at the barrier).

The effect is again verified with end-to-end time: with cost-balanced sampling on, step time drops by 7.4% (a 1.079x speedup). This gain changes no operator implementation and comes purely from data orchestration, which is exactly the part that operator-only optimization cannot reach.

Note that balancing changes the sample-to-rank mapping, so we must prove that it does not change training semantics. For this we built a SHA256 gate on sample order: we export the actual sampling order of every rank in every epoch and check it file by file against an archived baseline; if any single file differs, the gate fails.

Optimization 3: per-layer kernel-chain fusion — hand-written Triton RoPE, fused QK RMSNorm, compiled modulation prologue

The "small operations" inside the 30 blocks are the easiest cost to overlook. Each takes only a few microseconds, but it runs in every layer, for every microbatch, and leaves a trail of intermediate tensors in backward. LoongForge does three things here:

A hand-written Triton RoPE kernel. In eager mode, rotary position embedding expands into a chain of mul / add / cat / copy kernels, once for Q and once for K. We use a single Triton kernel to rotate Q and K pairwise at the same time, and we implement the backward ourselves: the backward rotation shares the same kernel as the forward and just negates the rotation direction, so no extra intermediate tensors need to be saved and the operator chain does not have to be rebuilt in backward. The cos/sin components are cached by shape and reused. In the ablation, turning this group off raises total elementwise time to 1.76x, adds about 5,100 kernels per step, and increases step time by 7.29%. About 98% of the gain comes from backward, which is exactly where writing our own backward pays off.

A fused QK RMSNorm. If Q/K normalization uses the framework's native implementation, it adds extra contiguous copies and dtype conversions before and after attention. We switch to TransformerEngine's fused RMSNorm. In the ablation, turning it off increases end-to-end step time by 6.46%, which confirms its value.

A compiled per-layer modulation prologue with a fixed BF16 compute domain. The per-layer time modulation (shift / scale / gate) plus LayerNorm is a typical memory-bound short chain. We treat it as one compilation unit so the compiler performs modulation and normalization in a single kernel, and we keep the intermediate expressions inside the block in BF16 with no up- and down-casting. Turning off the compiled prologue increases step time by 7.78% and raises total elementwise time to 1.9x; fixing the BF16 compute domain adds a further gain of about 1.4%.

Per-layer kernel-chain comparison: in the baseline each layer is a chain of small kernels (cast, mul, add, cat, copy, layer norm, mul, add) across 30 layers; in LoongForge each layer has just three stages: Triton RoPE (forward + backward), fused QK RMSNorm, and a compiled modulation prologue (BF16)
Figure 3: Per-layer kernel chains — fuse the whole chain, not just the matmul. The fused path uses one kernel per stage with no dtype/layout round trips, and backward keeps its intermediates inside the kernel.

Optimization 4: rescuing the GPU from "waiting for the host" — mask compilation and GC suppression

The first three items all reduce the work the GPU has to do. But profiling exposed another kind of waste: the GPU has work to do and yet sits idle waiting for the host.

The criterion is three structural NSys metrics: the share of GPU busy time, GPU idle time, and the total length of the "visible gaps of at least 10 microseconds" between kernels. If a change leaves the kernel count and per-category kernel time almost unchanged, but idle time and large gaps rise significantly together, it is a host-side bottleneck. Such a bottleneck cannot be fixed by optimizing operators; the host-side computation has to be moved off the critical path.

GPU timeline comparison: when host-bound, Python-side mask construction, automatic full GC, and loss synchronization leave the GPU waiting intermittently, with GPU busy at 94.8% and launch gaps about 10x longer; after optimization, a compiled block mask, suppressed generation-2 GC, and device-side loss handling bring GPU busy to 99.0% and squeeze out the gaps
Figure 4: GPU timeline — launch gaps are step time, not free time.

Using this criterion, we mainly located and fixed two kinds of host-side bottleneck:

4. Measured performance

We tested LingBot-VA with default training parameters (gradient accumulation = 10) on the LIBERO dataset, on Baidu Baige hpas.lgn7ib instances. With identical model structure, data, and hyperparameters, LoongForge achieves 2.20x the training throughput of the community open-source implementation and a 54.5% shorter step time, while the training loss stays aligned with the community implementation (mean relative error 0.171%).

Training loss over the first 50 LIBERO steps: the community baseline and LoongForge curves for video loss, action loss, and total loss nearly coincide, with mean relative errors of 0.017%, 0.418%, and 0.171%
Figure 5: Loss alignment over the first 50 LIBERO steps. From top to bottom: video loss, action loss, and total loss. The community baseline and LoongForge curves nearly coincide, with mean relative errors of 0.017%, 0.418%, and 0.171%.

From the perspective of optimization mechanisms, the size of each contribution is also clear:

It is worth noting that once GPU busy reaches 99.0%, there is less than 1% left to gain on the host side. Further speedups must come from the kernels themselves (GEMM currently accounts for about 63.7% of kernel time) and from communication overlap. That is the direction of our next stage.

5. Summary: turning the GPU from "passively waiting" into "continuously computing"

Looking back over the whole effort, the 2.20x improvement comes from four paths of different nature: redesigning communication semantics (parameters reused within a step), load balancing through data orchestration (cost alignment of variable-length samples), hand-written and fused operators (Triton RoPE and per-layer chain fusion), and cleaning up the host-side critical path (mask compilation and the GC strategy). They address four kinds of waste, namely communication, load, compute, and scheduling, and dropping any one of them forfeits part of the gain.

What supports these conclusions is a methodology of "quantify the bottleneck first, design the optimization next, and accept it by ablation last": every conclusion comes from reproducible timeline evidence and item-by-item ablation, and every performance gain passes an accuracy gate that is aligned with the community implementation iteration by iteration.

All of these optimizations are now integrated into LoongForge, our omni-modal training framework. We welcome researchers and developers in embodied AI to explore more efficient VLA training together.

← Previous: TAOT Topology-Aware Expert Placement All posts →