← Back to project

VLM-3D Stage-1 · ~27× speedup, 31.3% MFU (fla + sequence packing)

Qwen3.5-2B AR pretraining on discrete 3D tokens · 8×H200 · 2026-06-30
trainingoptimizationstage-1mfu

1 · What Stage-1 is

Autoregressive pretraining of Qwen3.5-2B (native hybrid VLM: full-attention + linear-attention gated-delta-net layers) to predict discrete 3D tokens — a representation-shaping pretrain (VP1). The AR head is dropped at inference; a flow model generates in Stage-2. Bidirectional multi-task: understanding (3D→text) + generation (image/text→3D), with multimodal replay data mixed in to preserve the base VLM (anti-forgetting).

2 · Result — ~27× over naive, target MFU hit

39 → 5.7 → 1.43 s/it (~27× over naive) · MFU 1.2% → 8.6% → 31.3% · GPU util → ~90%
Metricnaive (bs1+sdpa)FA3 + bs4fla + packing
step time~39 s/it5.7 s/it1.43 s/it
MFU (H200 bf16)1.2%8.6%31.3%
GPU utillow40–50%~90%

The first two steps (FA3 + larger batch) are standard; the 3.6× jump from 8.6% → 31.3% MFU is the fla + packing work below.

Full optimization arc: naive bs1+sdpa → FA3+bs4 → fla+packing (8×H200, Qwen3.5-2B). Step time on log scale; MFU target line at 30%.

3 · The winning recipe (8.6% → 31.3%)

  1. transformers 5.9.0 — unlocks Qwen3.5 sequence packing (padding-free path requires ≥5.9).
  2. Sequence packing (uniform 8192-token sequences) — kills the DDP straggler & padding waste from the huge length variance (467↔6882 tokens), and gives fla a finite set of shapes so its kernels compile once.
  3. flash-linear-attention (fla) — fast-path kernels for the gated-delta-net layers; without it those layers fall back to a slow torch path (the real compute bottleneck).
  4. Triton cache on node-local NVMe — fla's compile cache off Lustre; the default ~/.triton on Lustre causes 8-rank contention that stalls the compile (D-state hangs).
  5. Clean GPU allocation — the node's keepalive holder yields only to a real Slurm job, not ssh/bash launches.

4 · The diagnostic journey (the lesson)

A clean per-step profile overturned the initial guess:

fla's first-step autotune is heavy (~2900 kernels, one-time) — cache it on NVMe and it's free on every relaunch.

5 · Takeaways

auto-generated · 8×H200 · single-node · measured over 70 steps post-convergence