|
Download README.md from flashrt/adaptive-layernorm-producers: direct link, hf CLI and curl.
- Browser
- Download file 6.36 kB
-
https://huggingface.co/kernels/flashrt/adaptive-layernorm-producers/resolve/v1/README.md
- Command line
-
hf download hf://flashrt/adaptive-layernorm-producers@v1/README.md
-
curl -L -o README.md https://huggingface.co/kernels/flashrt/adaptive-layernorm-producers/resolve/v1/README.md
6.36 kB
| # adaptive-layernorm-producers | |
| FlashRT native CUDA producer kernels for DiT/Wan-style adaptive LayerNorm | |
| blocks. | |
| This package fuses the producer side of the block: | |
| ```text | |
| LayerNorm / adaptive LayerNorm modulation -> low-precision activation | |
| ``` | |
| into a single Kernel Hub operator. It is intended for transformer and diffuser | |
| runtimes where the following GEMM already consumes FP8 or NVFP4 activations. | |
| Without this fusion, the runtime pays for separate normalization, modulation, | |
| BF16 materialization, and quantization launches before the GEMM. | |
| The source kernels are derived from the production FlashRT runtime: | |
| - `official/FlashRT/csrc/quantize/ada_layer_norm_fp8.cu` | |
| - `official/FlashRT/csrc/kernels/dit_bf16.cu::layer_norm_no_affine_fp8_static_bf16` | |
| The full FlashRT model runtime and serving pipeline live upstream at | |
| [LiangSu8899/FlashRT](https://github.com/LiangSu8899/FlashRT). | |
| ## Available Functions | |
| - `ada_layer_norm_quant_fp8_bf16(x, scale, shift, act_scale, eps=1e-5, out=None)` | |
| - `ada_layer_norm_quant_fp8_ptok_bf16(x, scale, shift, act_scale, eps=1e-5, out=None)` | |
| - `ada_layer_norm_quant_fp8_ptok_table_bf16(x, temb, table, act_scale, shift_idx, scale_idx, eps=1e-5, out=None)` | |
| - `ada_layer_norm_quant_fp8_modfp8_bf16(x, scale_fp8, shift_fp8, scale_deq, shift_deq, act_scale, eps=1e-5, out=None)` | |
| - `awq_ada_layer_norm_quant_fp8_bf16(x, scale, shift, inv_s, act_scale, eps=1e-5, out=None)` | |
| - `ada_layer_norm_quant_nvfp4_swizzled_bf16(x, scale, shift, eps=1e-5, packed=None, sf_swizzled=None)` | |
| - `ada_layer_norm_quant_nvfp4_swizzled_modfp8_bf16(x, scale_fp8, shift_fp8, scale_deq, shift_deq, eps=1e-5, packed=None, sf_swizzled=None)` | |
| - `layer_norm_no_affine_quant_fp8_static_bf16(x, act_scale, eps=1e-5, out=None)` | |
| - `layer_norm_no_affine_quant_nvfp4_swizzled_bf16(x, eps=1e-5, packed=None, sf_swizzled=None)` | |
| - `adaln_modulation6_bf16(adaln_params, layer_modulation, out=None)` | |
| - `swizzled_sf_size(rows, dim)` | |
| ## Tensor Contract | |
| - `x`: contiguous CUDA `torch.bfloat16`, shape `(rows, dim)`. | |
| - Broadcast `scale`, `shift`, and `inv_s`: contiguous CUDA | |
| `torch.bfloat16`, shape `(dim,)`. | |
| - Per-token `scale` and `shift`: contiguous CUDA `torch.bfloat16`, shape | |
| `(rows, dim)`. | |
| - Table form `temb`: contiguous CUDA `torch.bfloat16`, shape | |
| `(rows, chunks, dim)`; `table`: contiguous CUDA `torch.float32`, shape | |
| `(chunks, dim)`. | |
| - `scale_fp8`, `shift_fp8`: contiguous CUDA `torch.float8_e4m3fn`, shape `(dim,)`. | |
| - `scale_deq`, `shift_deq`, `act_scale`: CUDA `torch.float32` scalar tensors. | |
| - FP8 outputs use `torch.float8_e4m3fn`, shape `(rows, dim)`. | |
| - NVFP4 packed output uses `torch.uint8`, shape `(rows, dim // 2)`. | |
| - NVFP4 scale output uses the FlashRT/CUTLASS 128x4 swizzled uint8 scale | |
| layout. Allocate with `swizzled_sf_size(rows, dim)`. | |
| - `dim` must be even for FP8 outputs and divisible by 16 for NVFP4 outputs. | |
| - The package targets CUDA 12.8+ and Blackwell-class deployment paths. | |
| - `adaln_modulation6_bf16` takes FP32 `(batch, sequence, 6, dim)` parameters | |
| plus FP32 `(6, dim)` layer modulation and returns six BF16 | |
| `(batch, sequence, dim)` tensors. | |
| ## Minimal Usage | |
| ```python | |
| from kernels import get_kernel | |
| import torch | |
| ops = get_kernel("flashrt/adaptive-layernorm-producers", version=1, trust_remote_code=True) | |
| rows, dim = 2520, 3072 | |
| x = torch.randn((rows, dim), device="cuda", dtype=torch.bfloat16) | |
| scale = torch.zeros((dim,), device="cuda", dtype=torch.bfloat16) | |
| shift = torch.zeros((dim,), device="cuda", dtype=torch.bfloat16) | |
| act_scale = torch.tensor([0.025], device="cuda", dtype=torch.float32) | |
| x_fp8 = ops.ada_layer_norm_quant_fp8_bf16(x, scale, shift, act_scale) | |
| ``` | |
| Per-token modulation without materializing a broadcast buffer: | |
| ```python | |
| ptok_scale = torch.zeros_like(x) | |
| ptok_shift = torch.zeros_like(x) | |
| x_fp8 = ops.ada_layer_norm_quant_fp8_ptok_bf16( | |
| x, ptok_scale, ptok_shift, act_scale | |
| ) | |
| ``` | |
| Fused host modulation table add and chunk selection: | |
| ```python | |
| chunks = 6 | |
| temb = torch.zeros((rows, chunks, dim), device="cuda", dtype=torch.bfloat16) | |
| table = torch.zeros((chunks, dim), device="cuda", dtype=torch.float32) | |
| x_fp8 = ops.ada_layer_norm_quant_fp8_ptok_table_bf16( | |
| x, temb, table, act_scale, shift_idx=0, scale_idx=1 | |
| ) | |
| ``` | |
| Static-buffer usage for CUDA Graph capture: | |
| ```python | |
| out = torch.empty_like(x, dtype=torch.float8_e4m3fn) | |
| ops.ada_layer_norm_quant_fp8_bf16(x, scale, shift, act_scale, out=out) | |
| ``` | |
| NVFP4 producer: | |
| ```python | |
| packed, sf = ops.ada_layer_norm_quant_nvfp4_swizzled_bf16(x, scale, shift) | |
| # GROOT N1.7 pre-FFN producer on Thor. | |
| packed_ln, sf_ln = ops.layer_norm_no_affine_quant_nvfp4_swizzled_bf16(x) | |
| ``` | |
| Six-way DiT modulation: | |
| ```python | |
| params = torch.randn((1, rows, 6, dim), device="cuda", dtype=torch.float32) | |
| modulation = torch.randn((6, dim), device="cuda", dtype=torch.float32) | |
| outputs = ops.adaln_modulation6_bf16(params, modulation) | |
| ``` | |
| ## Validation | |
| ```bash | |
| python adaptive-layernorm-producers/tests/test_adaptive_layernorm_producers.py --backend source --mode full | |
| python adaptive-layernorm-producers/benchmarks/benchmark.py --backend source --iters 100 | |
| ``` | |
| The validation suite checks exact FP8 output for small producer shapes, exact | |
| NVFP4 packed/scalefactor output against the native staged BF16-norm plus FP4 | |
| quantizer contract on SM110, and strict FP8 | |
| boundary accounting for long video shapes. The long-shape policy requires | |
| `p99_abs == 0` and only a tiny count of adjacent FP8-code boundary differences | |
| against the eager reference. | |
| See `VALIDATION.md` and `benchmarks/RESULTS.md` for the current local RTX 5090 | |
| source-build results. | |
| The SM110 FP4 producer uses the native GROOT N1.7 contract from FlashRT commit | |
| `24df793f4fa2d50780aea03b644208c6e0cb4162`. Its scale conversion and FP4 bin | |
| boundaries intentionally differ from the older SM120 producer; release tests | |
| compare each architecture against its own production contract. | |
| The aarch64 release variant `torch211-cxx11-cu130-aarch64-linux` contains | |
| native SM87 and SM110a code objects. Its SM110a path was validated on NVIDIA | |
| Thor from the exact Hub-downloaded artifact over decode, DiT, vision, and | |
| 2K/4K video rows. The two per-token entry points were also compared directly | |
| with their raw registered ops using A-B-B-A timing; all six wrapper/raw rows | |
| were bit-exact and the measured ratio was `0.997-1.000`. SM87 runtime | |
| validation remains pending on Jetson AGX Orin hardware. | |