Skip to content

feat(groot): GR00T N1.6 Thor parity fixes and opt-in 28.5 ms profile - #177

Open
DXICM wants to merge 6 commits into
flashrt-project:mainfrom
DXICM:feat/groot-n16-thor
Open

feat(groot): GR00T N1.6 Thor parity fixes and opt-in 28.5 ms profile#177
DXICM wants to merge 6 commits into
flashrt-project:mainfrom
DXICM:feat/groot-n16-thor

Conversation

@DXICM

@DXICM DXICM commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Summary

GR00T N1.6-3B support for Jetson AGX Thor (SM110), including HF-alignment fixes, CUDA Graph lifecycle handling, and an explicit opt-in FA4/NVFP4 performance profile.

The existing public route remains the default: use_fp8=True, image_size=224, and parity=False. The new HF-native parity path and approximate FP4/FA4 tiers do not activate unless requested.

The reported opt-in profile measured 28.5 ms E2E on Thor (median 27.7 ms, p95 28.5 ms) with denormalized action cosine 0.999933 versus HF eager. These are the contributor's original Thor measurements; the audit follow-up below validated build and maintenance contracts but could not rerun Thor E2E while that machine was offline.

Audit follow-up

Commits eb01fa8d and 4c830e89 close the merge blockers found during review:

  • Gates the qk_norm_rope_rotate_half_bf16 header and pybind symbol with the same FLASHRT_HAVE_THOR_VLA_KERNELS definition as its SM100/SM110 source.
  • Keeps CUTE_DSL_ARCH=sm_101a as a CuTe-DSL compilation alias without overriding FLASH_ATTENTION_ARCH; runtime FA4 dispatch now sees the physical SM110 capability and does not enter the SM100-only hd256 kernel.
  • Restores the pre-existing N1.6 defaults and makes FLASHRT_N16_DIT_FP4, FLASHRT_N16_QWEN3_FP4, FLASHRT_N16_SIGLIP_FP4, and FLASHRT_N16_FA4 opt-in.
  • Routes the HF-native backbone and DiT only when parity=True, and rejects the unsupported FP8-backbone/Torch-DiT hybrid configuration.
  • Implements prompt switching by resetting graph-owned state and recapturing on the next inference. FP4 patch state is reset with the graph runtime.
  • Uses row-wise concat2_bf16 in DiT calibration, matching the production action/time embedding layout.
  • Resolves Eagle remote code only from the checkpoint or an explicitly pinned FLASHRT_N16_EAGLE_DIR; no arbitrary Hugging Face cache revision is selected.
  • Adds focused maintenance coverage for compile gates, FA4 runtime dispatch, defaults, prompt lifecycle, calibration layout, and remote-code resolution.

Opt-in performance profile

Construct the parity frontend explicitly with the model's 252x252 evaluation resolution, then enable the measured tiers:

export FLASHRT_N16_DIT_FP4=1
export FLASHRT_N16_QWEN3_FP4=1
export FLASHRT_N16_SIGLIP_FP4=1
export FLASHRT_N16_FA4=1
frontend = GrootTorchFrontendThor(
    checkpoint,
    use_fp8=False,
    image_size=252,
    parity=True,
)

All four tiers independently fall back to BF16/Torch when disabled or unavailable. FLASHRT_N16_DIT_STEPS remains 4; reducing diffusion steps is experimental and is not part of the reported profile.

Validation

  • 24 passed across the N1.6 maintenance, prompt lifecycle, attention backend, calibration, and precision contract subset.
  • Python compileall: passed.
  • git diff --check: passed.
  • SM89 flash_rt_kernels: full compile, link, and import passed; Thor-only binding absent.
  • SM120 flash_rt_kernels: full compile, link, and import passed; Thor-only binding absent.
  • SM110 flash_rt_kernels and flash_rt_fp4: full cross-compile, link, and import passed; Thor-only binding present.
  • CMake inventory confirms the qk-norm source and binding macro are present only for SM100/SM110.

Thor hardware was offline during this audit follow-up, so the updated commit still requires one final Thor E2E rerun covering default fallback, the opt-in profile, prompt switching, finite outputs, and HF numerical comparison before merge.

Scope

The runtime changes are limited to the GR00T N1.6 Thor frontend and its isolated Thor FA4 backend. No new N1.6 path is enabled for other models or architectures.

DXICM added 4 commits August 18, 2026 11:51
Root-cause and fix 12 real bugs where the upstream N1.6 frontend
inherited openpi-family (Pi0/Pi0.5) vision/kernel assumptions that
do not hold for GR00T N1.6's HF behaviour:

 1. Tokenization: reproduce Eagle chat template (system/user headers,
    formalize, per-view image blocks) instead of bare encode()
 2. Resolution: HF eval chain outputs 252x252, not 224
 3. SigLIP attention scope: HF(sdpa) does cross-view full attention
    on the packed 648-token sequence, not per-view
 4. Patch flatten order: HF NaFlex uses (ph,pw,C), not (C,ph,pw)
 5. Strided FMHA divergence on non-power-of-2 seq with real data:
    parity mode routes SigLIP attention through torch sdpa
 6. CKernelQwen3 diverges from HF on real sequences: parity mode
    runs HF-native Qwen3Model (bf16, sdpa, graph-captured)
 7. Wild pointer after re-capture: Qwen3 graph-captured LN referenced
    local tensors; promote to persistent attributes + finiteness guard
 8. adaLN chunk order reversed: HF proj_out_1 is (shift, scale)
 9. Single-frame FP8 calibration too narrow: multi-frame calibrate
    (current + 7 synthetic frames, percentile=99.9)
10. Prompt switch rejected after graph bake: detect change, reset
    graph runtime, re-set prompt, re-capture
11. Idle-first-frame garbage: Thor GPU idle reset invalidates captured
    graphs; add replay finiteness self-check + re-capture retry
12. Prompt-switch re-capture device-side assert: stale DiT static
    buffers/indices not rebuilt; add to stale list

Precision vs HF eager: cos 0.999933 / maxd 0.059 (denormalized action).
No inference hyperparameters changed (4-step, 252x252, T=50, bf16).

Also adds tools/convert_groot_n16_hf_checkpoint.py for HF safetensors
to FlashRT layout conversion (Qwen3 16-layer truncation, DiT repack,
SigLIP mlp1 layout).
New CUDA kernels for the N1.6 Thor NVFP4 pipeline:

- fused_fp4/silu_mul_fp4_sfa_bf16: SiLU(gate)*up (bf16) direct to
  NVFP4+SFA, bit-exact vs torch two-step chain
- fused_fp4/dit_norm_fp4_sfa: AdaLN / no-affine LN / weighted RMSNorm
  direct to NVFP4+SFA (bf16 input variants)
- gemm/fp4/cutlass_fp4_gemm_bias_bf16_sm100: bias / bias+residual /
  bias+tanh-GELU+fp4out epilogue variants
- quantize/quantize_fp4_sfa_bf16: vectorized bf16 dynamic quantize
- kernels/qk_norm_rope_rotate_half_bf16: fused per-head RMSNorm +
  rotate-half RoPE (bf16, in-place, one launch per Q/K)

Performance rounds (no hyperparameter changes):
- DiT NVFP4 fused epilogue: 36.6 -> 15.7 ms (8 kernels/layer)
- Qwen3 fused norm/rope/GQA: 12.7 -> 5.0 ms (cos 0.999986)
- SigLIP FA4 + fp4 encoder: 10.3 -> 6.9 ms (cos 0.999988)
- SigLIP embeddings in-graph: 34 -> 28.5 ms (bit-exact)
- E2E total: 130 -> 28.5 ms (4-step, 2-camera, 252x252, T=50)

Bandwidth ceiling: Thor measured 252-255 GB/s (~93% of 273 spec);
DiT 15.2 ms is weight-bandwidth-bound floor for this config.

Tier switches (all default ON, independently fall back):
  FLASHRT_N16_DIT_FP4, FLASHRT_N16_QWEN3_FP4,
  FLASHRT_N16_SIGLIP_FP4, FLASHRT_N16_FA4
- docs/groot_n16_thor_sm110.md: single authoritative document covering
  architecture facts, 12-bug root-cause table, falsified hypotheses,
  full optimization record (130 -> 28.5 ms), roofline/bandwidth ceiling
  analysis (252-255 GB/s, ~93% of spec), precision tier switches, and
  verification methodology.
- docs/groot_transformers5_weight_corruption.md: transformers>=5 silent
  weight corruption via _initialize_missing_keys re-randomizing SigLIP2
  vision tower (282 tensors). One-line fix + integrity guard.
- docs/thor_gpu_idle_reset_workaround.md: Thor GPU idle reset defect and
  three-layer CUDA Graph protection (keepalive, idle reinit, finiteness).
cutlass-dsl caches the device arch at import time. The previous code
imported cutlass to check its version, then set CUTE_DSL_ARCH=sm_101a
— too late; NVVM already cached sm_110a and ICEs on the hd256 2CTA
kernel (introduced in flashrt-project#164, commit 7fd75d2).

Fix: set CUTE_DSL_ARCH=sm_101a unconditionally before any cutlass
import. Also revert the hd256 2CTA dispatch to SM100-only (the
dedicated kernel was never validated on SM110) and restore the
_fa4_trimmed lazy loader for BlackwellFusedMultiHeadAttentionForward.

Verified: all-tier E2E on Thor — median 27.7 ms, p95 28.5 ms,
actions finite, cos 0.999933 vs HF eager.
@DXICM
DXICM force-pushed the feat/groot-n16-thor branch from 817cbf7 to 4cae6c0 Compare August 18, 2026 03:52
@LiangSu8899 LiangSu8899 changed the title feat(groot): GR00T N1.6 × Jetson Thor (SM110) — HF parity, 12 bug fixes, 130→28.5 ms feat(groot): GR00T N1.6 Thor parity fixes and opt-in 28.5 ms profile Aug 23, 2026
@LiangSu8899

LiangSu8899 commented Aug 23, 2026

Copy link
Copy Markdown
Member

Audit follow-up pushed in eb01fa8d and 4c830e89.

Resolved:

  • SM100/SM110 qk-norm source, header, and pybind now share one compile gate.
  • FA4 keeps the sm_101a DSL compilation alias but uses the physical GPU capability for runtime dispatch, so Thor hd256 cannot enter the SM100-only stub.
  • Existing N1.6 behavior is restored as the public default; parity and all FP4/FA4 tiers are explicit opt-ins.
  • HF-native capture is now controlled exclusively by parity=True; the unsupported FP8-backbone/Torch-DiT hybrid is rejected.
  • Prompt changes reset and recapture graph-owned state, including FP4 module patches.
  • DiT calibration now uses the same row-wise action/time concat as production.
  • Eagle remote code must be checkpoint-local or selected through an explicit pinned directory.

Validation completed:

  • 24 related contract tests passed.
  • compileall and git diff --check passed.
  • Full SM89 and SM120 flash_rt_kernels compile/link/import passed; the Thor-only binding is absent.
  • Full SM110 flash_rt_kernels + flash_rt_fp4 cross-compile/link/import passed; the Thor-only binding is present.
  • Merge simulation against current main is clean.

The Thor host was offline during this follow-up. I have therefore not represented the cross-build as a Thor runtime result; one final Thor E2E/default-fallback/prompt-switch numerical run remains before merge. The PR body now states this distinction and documents the opt-in 28.5 ms profile accurately.

@LiangSu8899

Copy link
Copy Markdown
Member

Great Work!! @DXICM Could you help test whether this Thor behaves as expected?
Then I think we ready to merge!
Thx!!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants