ImageWAM Unitree-G1 two-task β€” W4A4 real packed INT4 at group 32, two arms

The ImageWAM-FLUX.2-4B Unitree-G1 two-task fine-tune (LGG100/imagewam-sc-10k, step 10000) quantised to INT4, group 32 for GPUs with 4-bit tensor cores, by two methods calibrated identically and packed identically β€” so they differ in their mathematics, not their plumbing.

Real quantisation, not a simulation of it. The weight ships PACKED at 4 bits, two output channels per byte, in the [K, N/2] layout the fused Triton kernels contract on β€” the same packing the FastWAM Unitree-G1 checkpoints use, so the arms are comparable across models.

sc_step10000_asp_w4a4_g32.pt sc_step10000_svdquant_w4a4_g32.pt
method AFQ / ASP, deflated form SVDQuant (Li et al., ICLR 2025)
rotation block Hadamard none
low-rank branch rank 32 on the action expert, from the action metric rank 32 on every layer, from the quantisation residual
BPW 4.5789 4.7523
resident weights 2.637 GiB (3.25x less than bf16) 2.716 GiB (3.16x)
vs bf16, mean 0.00326 0.00623
vs bf16, worst frame 0.01291 0.01485
vs recorded teleoperation 0.06588 0.06523

bf16's own distance to the demonstrator is 0.06592. ASP tracks the unquantised model to 0.00326 β€” half SVDQuant's movement β€” and lands within 4e-5 of bf16's own gap to the demonstrator, while spending 0.173 fewer bits per weight. (Both arms sitting either side of bf16 on the last row is noise; the row that separates them is movement against bf16.)

Both quantise the same 153 of 156 MoT Linears, 4.498 B parameters.

Calibration

The same 30 episodes as the FastWAM Unitree-G1 arms β€” 15 per task from item-classification-new and sort-tools-new, seed 42, all frames, 14,469 observations β€” so the two models' quantised rows are comparable. Activation absmax feeds SmoothQuant; an 800-row-per-layer reservoir of real layer inputs feeds the smoothing search, whose objective is SVDQuant's own OutputsError with the INT4 quantiser and the refitted low-rank branch inside the scored loop.

SVDQuant: 124 layers chose (alpha, 0), 30 (alpha, 1-alpha); split-half 69.5%; searching the smoothing is worth 1.076x over a fixed alpha = 0.5 and the rank-32 branch 1.061x over no branch.

ASP searches the smoothing and the subspace jointly, because the protected subspace is the top eigenspace of the metric in the coordinates being quantised and those coordinates move with the smoothing: split-half 77.3%, and its branch is worth 1.574x β€” half again as much as SVDQuant's, on the same model and the same activations.

Where the action metric points

G_l = E[J_l^T J_l], J_l = d(action chunk)/d(x_l) differentiated through all ten denoising steps, estimated with random probes over 905 frames x 12 probes. 97.9% of tr(G) sits in six layers, and none is a transformer block: single_stream_modulation 37.8%, double_stream_modulation_img 34.0%, action_encoder 15.7%, time_in.out_layer 8.0%, the two head layers 2.5%. Top-32 eigenvectors capture 99.93% of tr(G) on the dominant layer.

mixtures.action.time_in.in_layer gets rank 0, not rank 32: it consumes the timestep, not the action latents, so its Jacobian to the action is genuinely empty and a "protected subspace" there would be 32 directions chosen by LAPACK out of a zero matrix. 65 layers carry a subspace, 88 do not.

Verification

REAL β€” 153 packed Linears, all torch.int8 at [K, N/2]; 2413.1 MiB for 4.498 B weights is 4.50 bits/weight exactly (4 plus 16/32 for the per-group scale); zero dequantised weight copies anywhere in the module.

PACKING β€” per layer, on random inputs, against each method's own fake-quant formula written out directly. SVDQuant: worst layer 1.1e-2, 0.086% of codes differ by exactly 1 LSB, scales bit-identical. A wrong nibble pairing or a transposed scale shows up here and nowhere else, because at the model level it would still emit a plausible action chunk.

For ASP the criterion has to change, and the reason is worth stating. Bit-identical scales are achievable for SVDQuant, whose prologue is an elementwise multiply a fp32 reference reproduces exactly, and are not achievable for ASP, whose prologue is a tensor-core Hadamard: the rotated activation rounds differently, so its per-group amax does too. The honest criterion is distance to the unquantised layer, and ASP's kernel is at worst +0.8% further from the true bf16 layer than a fp32 reference β€” on layers where both sit at ~1.5e-1, because that is W4A4's own error. Codes are still within 1 LSB and scales within 5%.

ACCURATE β€” on episodes disjoint from the calibration selection: the table at the top. The model's own distance to the demonstrator is ~20x what ASP moved and ~10x what SVDQuant moved.

No closed-loop success rate has been measured. Open-loop agreement is necessary and not sufficient.

What is quantised

153 of 156 MoT Linears, 4.498 B weights β€” 99.6% of mot's parameters. Three stay bf16 and the checkpoint records them:

layer shape why
mixtures.action.action_encoder (1024, 16) K = 16 is below the kernel's group granularity of 32
mixtures.video.transformer.final_layer.linear (128, 3072) the video output head predicts the next frame; it never runs during action inference, so it has no calibration
…final_layer.adaLN_modulation.1 (6144, 3072) same

Running it

Needs triton and a GPU with INT4-on-INT8 tensor cores (built and verified on sm_89 and H100). The file is self-contained β€” the quantised Linears, every unquantised mot tensor and the proprio encoder β€” so the source checkpoint is not needed at inference. You still need the FLUX.2 klein-base-4B backbone and autoencoder, dataset_stats.json, and the pre-encoded prompt.

from iw_w4a4_runtime import load_quantized_model
model, cfg = load_quantized_model("sc_step10000_svdquant_w4a4_g32.pt", build_model=my_builder)

install_iw_w4a4 raises unless every name resolves to an nn.Linear, and dispatches on lowrank_mode: SVDQuant and deflated ASP produce the same shapes, so nothing else tells them apart, and running one through the other's class gives a well-formed GEMM of the wrong bilinear form that still emits a plausible action chunk.

The runtime files here are standalone copies of the in-repo versions, checked on real exported layers (see the note on reproducibility below).

Four things that will bite you

  1. The source checkpoint is in LoRA form. Its mot carries ...base.weight, ...lora_A and ...lora_B for every adapted video Linear, and only load_checkpoint merges them. Read the weights straight out of the file and you quantise the pretrain and silently drop the fine-tune β€” a checkpoint that loads, runs, emits plausible actions, and is the wrong model. This export reads module.weight.data off the live model after the merge, and turns load_checkpoint's missing/unexpected report (which it only logs at INFO) into an exception.
  2. The INT4 path is NOT bit-reproducible. The rank-r projection is a reduction over the whole contraction axis and its partial sums are combined with fp32 atomics, so the low bits depend on the order thread blocks finish in: the same runtime disagrees with itself between consecutive calls on identical input, by up to 4e-3 on a single element (1e-3 relative). That is far below the 4-bit grid's own ~1e-2, but it means an accuracy number will not reproduce to the last digit, and "bit-identical" is not an available acceptance criterion for this path.
  3. The MoT exposes the video expert twice. mixtures.video.X and mixtures.video.transformer.X are the same tensor β€” 140 of 267 storages carry two names. Deduplicate by storage or a "quantised" export comes out larger than the bf16 original.
  4. The mosaic is 288x256 (compact_288x256): cam_left_high at 256x192 on top, the two wrists at 128x96 side by side below, order [high, left, right], pixels mapped to (-1, 1). Actions are 16-D and are not padded or un-padded β€” this robot is natively 16-D, unlike the UR3 ImageWAM checkpoints which pad 14 to 16.

Tasks

Both recorded on Unitree_G1_Dex1_Sim, 100 episodes each, 30 fps, three cameras at 480x640, and both declaring the same instruction "pick up cube." in their own metadata.

Downloads last month

-

Downloads are not tracked for this model. How to track
Video Preview
loading

Model tree for arashakb/IMAGEWAM-Unitree-G1

Finetuned
(1)
this model

Datasets used to train arashakb/IMAGEWAM-Unitree-G1