Skip to content

[feat]: fp8 PV mode for the FA4-FP4 attention path - #1654

Open
SolitaryThinker wants to merge 1 commit into
mainfrom
swe-fa4-fp8-pv
Open

[feat]: fp8 PV mode for the FA4-FP4 attention path#1654
SolitaryThinker wants to merge 1 commit into
mainfrom
swe-fa4-fp8-pv

Conversation

@SolitaryThinker

@SolitaryThinker SolitaryThinker commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

Problem

The FA4-FP4 attention path always keeps V in BF16 — there is no supported way to select the PV precision. Kernel-level measurements show an fp8 (e4m3) V can be faster at large shapes, but a naive in-forward .to(torch.float8_e4m3fn) cast graph-breaks under torch.compile, and the resolution receipt hardcoded pv_mode=bf16 as a string literal (it would silently misreport the moment fp8 V flowed).

What this changes

  • fastvideo::fa4_v_to_fp8 custom op: the elementwise e4m3 cast behind a registered-op boundary — one opaque graph node, so fullgraph compilation keeps working. The kernel contract was verified against the FP4 kernel source before shipping: with block-scaled Q/K, plain fp8 V is consumed directly (no scale-factor tensor, no dequant scale, standard layout).
  • fa4_pv_mode knob ("bf16" default / "fp8") on the attention impl options, validated at construction, plumbed to both FA4-FP4 consumers. The FASTVIDEO_FA4_PV_MODE env var is the user-reachable path (model code constructs attention with fixed literals); explicit kwargs win over the environment.
  • Derived receipt: pv_mode in the resolution receipt now reports the configured mode (env-aware from the first line), and the actually-observed V dtype is logged once at the first forward — receipts describe runtime state, not intent.
  • Output-dtype fake correction: the FA4 kernel-op's registered fake followed V's dtype, but the block-scaled kernel always writes BF16 — with fp8 V that fake would bake the wrong output dtype into compiled artifacts. The fake now always reports BF16 (byte-identical for bf16 V).

Status: [target] — confirmed by the end-to-end compiled benchmark

fp8-PV is an end-to-end wash:

shape fp8PV vs bf16PV (e2e) per-step peak alloc
720p 1.0018x (+0.2%, noise) +4.0% +0.001 GiB
1080p 0.9735x (−2.7%) −3.5% +0.000 GiB

The kernel-level +6.9% does not translate end-to-end (attention is a fraction of the step; the unscaled V cast adds work), and fp8-PV changes numerics (MS-SSIM 0.8958 @720p / 0.7442 @1080p vs bf16-PV) — so it ships opt-in, default-off. All six benchmark cells completed rc=0 with 7 graph breaks each (equal to the bf16 control); receipts confirmed live (pv_mode=fp8(e4m3) on fp8 cells). W&B runs: hvo1y96a, wo3ovz5a, tnaty1wr, f5jkt3t4, kmlwcfx8, yp114bvh.

Test evidence

  • torch.library.opcheck on the new op (CPU kernel in-test; contiguous and transposed inputs; forward-only suites) — fake-vs-real consistency including strides.
  • fullgraph trace test for the fp8 path (knob=fp8, op-backed cast + quantize, mocked kernel): fullgraph=True compiles with zero graph breaks.
  • Env-bridge regression (env reaches the impl; kwargs beat env), knob-typo fail-fast (both impls), derived-receipt unit.
  • pre-commit green on all changed files.

Blast radius

Shared-forward attention path — inference (both FA4-FP4 consumers) and training only via the validation-time ATTN_QAT_INFER swap. With the default knob the change is behavior-neutral (the only functional delta is the corrected fake output dtype, which matches what the real kernel already did). With fa4_pv_mode=fp8: quality-changing until gated — hence [target] and default-off.

@SolitaryThinker SolitaryThinker added the scope: attention Attention backends (VSA, STA, Flash, etc.) label Jul 28, 2026
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@mergify mergify Bot added type: feat New feature or capability scope: infra CI, tests, Docker, build scope: docs Documentation labels Jul 28, 2026
@mergify

mergify Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Merge Protections

🔴 1 of 1 protections blocking · waiting on 👀 reviews and 🤖 CI

Protection Waiting on
🔴 PR merge requirements 👀 reviews and 🤖 CI

🔴 PR merge requirements

Waiting for

  • #approved-reviews-by>=1
  • check-success=full-suite-passed
This rule is failing.
  • #approved-reviews-by>=1
  • check-success=full-suite-passed
  • check-success=fastcheck-passed
  • check-success~=pre-commit
  • title~=(?i)^\[(feat|feature|bugfix|fix|refactor|perf|ci|doc|docs|misc|chore|kernel|new.?model|skill|skills|infra)\]

Adds an opt-in fa4_pv_mode knob (bf16 default / fp8) to the FA4-FP4
attention path on datacenter Blackwell:

* fastvideo::fa4_v_to_fp8 custom op: unscaled e4m3 cast of V behind a
  torch.compile-opaque boundary (a naive in-forward .to() graph-breaks),
  register_fake mirroring .to()'s preserve_format layout. The kernel's
  plain-fp8 PV contract needs no mSFV scale factors and no v_descale
  (implicit dequant scale 1.0) and keeps the output BF16.
* fa4_pv_mode extra_impl_args knob consumed by both
  FlashAttentionImpl._forward_nvfp4 and AttnQatInferImpl._forward_fa4_fp4,
  validated at construction (fail fast on typos). Default bf16 keeps
  behavior byte-identical.
* attn_qat_infer_receipt() now derives pv_mode from the configured knob
  instead of a literal, plus a once-per-process log of the V dtype
  actually fed to the kernel on the first FA4 forward.
* _flash_attn_cute_fp4_forward fake fixed to always report BF16 output
  (the block-scaled kernel never follows V's dtype).
* CPU regressions: opcheck on the new op (incl. non-contiguous strides),
  fullgraph trace of the fp8 path with mocked kernels, knob-typo
  validation for both consumers, derived-receipt coverage.
* docs: fp8 PV documented as opt-in [target] pending an end-to-end
  compiled benchmark and a quality gate.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

scope: attention Attention backends (VSA, STA, Flash, etc.) scope: docs Documentation scope: infra CI, tests, Docker, build type: feat New feature or capability

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant