Skip to content

[feat]: Add NVFP4QAT linear layer (Attn-QAT 3/12) - #1350

Merged
SolitaryThinker merged 2 commits into
mainfrom
pr1225_s3
May 16, 2026
Merged

[feat]: Add NVFP4QAT linear layer (Attn-QAT 3/12)#1350
SolitaryThinker merged 2 commits into
mainfrom
pr1225_s3

Conversation

@SolitaryThinker

Copy link
Copy Markdown
Collaborator

Summary

Slice 3 of 12 in the decomposition of #1225 ([feat] Upstream Attn-QAT Video Diffusion Code). Adds the FastVideo-native FP4 linear forward helper module extracted from PR-1225.

Pure deadcode: no existing code path imports fp4_linear_forward yet. The QAT attention backends (Slice 4) and beyond will wire it up; activation lands in Slice 12.

Stacking

Naming family

Files

  • fastvideo/layers/fp4linear.py (NEW, 115 LOC) — source PR-1225 module. The extracted file does not define a public Fp4Linear* class or import Fp4Config, so no class/file rename or config-import substitution was applied.

Provenance

Extracted from PR #1225 by @RandNMR73 (source SHA: 3f818d0f). Git author is @SolitaryThinker; @jzhang38 and @RandNMR73 are co-authored via commit trailers.

Test plan

  • No behavior change (deadcode). pre-commit run --files fastvideo/layers/fp4linear.py passes.
  • Unit-test coverage for the FP4 linear helper lands in a later slice once a caller exists.

Adds NVFP4QATConfig — the Attn-QAT flavor of FP4 quantization. Distinct
from main's NVFP4Config (NVIDIA Blackwell hardware FP4 inference); this
config is for the QAT training side of the Attn-QAT stack.

Pure deadcode: no existing code path imports NVFP4QATConfig yet.
The `nvfp4_qat` method literal in QuantizationMethods makes it
selectable, but the caller lands in slice 3+.

Renamed from PR-1225's original `Fp4Config` / `fp4_config.py` /
`"fp4"` literal to avoid collision with PR #1334's NVFP4 plumbing
already merged to main.

Extracted from PR #1225 (#1225) by @RandNMR73.
Source SHA: 3f818d0

Attn-QAT-Stack: 2/12

Co-Authored-By: jzhang38 <42993249+jzhang38@users.noreply.github.com>
Co-Authored-By: RandNMR73 <99706358+RandNMR73@users.noreply.github.com>
@mergify mergify Bot added type: feat New feature or capability scope: model Model architecture (DiTs, encoders, VAEs) labels May 14, 2026
Base automatically changed from pr1225_s2 to main May 14, 2026 23:53
@mergify

mergify Bot commented May 14, 2026

Copy link
Copy Markdown
Contributor

Merge Protections

Your pull request matches the following merge protections and will not be merged until they are valid.

🔴 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)\]

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces an FP4 linear layer implementation leveraging the flashinfer library. It includes a custom autograd function, _LinearFWD4BWD16Fn, which handles FP4 quantization and matrix multiplication in the forward pass, while maintaining standard precision for the backward pass. The review feedback suggests optimizing the _global_sf helper function by moving it to the module level to avoid re-definition overhead during each forward pass and using the more idiomatic .clamp() method for numerical stability.

return flashinfer


class _LinearFWD4BWD16Fn(torch.autograd.Function):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Move the _global_sf helper to the module level and decorate it with @torch.compile there. Defining and decorating a function inside the forward method of an autograd.Function is highly inefficient as it causes the function to be re-defined (and potentially re-compiled or cache-checked) on every forward pass, leading to significant overhead. Additionally, using .clamp(min=...) is more idiomatic and efficient than torch.maximum with a newly created tensor.

@torch.compile
def _global_sf(t: torch.Tensor) -> torch.Tensor:
    maxabs = t.float().abs().nan_to_num().max()
    maxabs = maxabs.clamp(min=1e-12)
    return (448.0 * 6.0) / maxabs


class _LinearFWD4BWD16Fn(torch.autograd.Function):

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in dbc9e7c. Hoisted _global_sf to module level with @torch.compile and switched to .clamp(min=1e-12). Thanks for the catch.

Comment thread fastvideo/layers/fp4linear.py Outdated
Comment on lines +41 to +46
@torch.compile
def _global_sf(t: torch.Tensor) -> torch.Tensor:
maxabs = t.float().abs().nan_to_num().max()
maxabs = torch.maximum(maxabs, torch.tensor(1e-12, device=t.device, dtype=maxabs.dtype))
return (448.0 * 6.0) / maxabs

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Remove the local definition of _global_sf as it should be moved to the module level for better performance and to avoid re-definition overhead during every forward pass.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in dbc9e7c. Hoisted _global_sf to module level with @torch.compile and switched to .clamp(min=1e-12). Thanks for the catch.

Adds the FastVideo-native FP4 linear forward helper module extracted from
PR-1225. The source module does not define a public Fp4Linear class, so this
slice keeps the original fp4linear.py filename and helper names.

Pure deadcode: no existing code path imports this helper yet. Activation
lands in Slice-12 of the decomposition.

Extracted from PR #1225 (#1225)
by @RandNMR73. Source SHA: 3f818d0.

Attn-QAT-Stack: 3/12

Co-Authored-By: jzhang38 <42993249+jzhang38@users.noreply.github.com>
Co-Authored-By: RandNMR73 <99706358+RandNMR73@users.noreply.github.com>
@SolitaryThinker

Copy link
Copy Markdown
Collaborator Author

/merge

@github-actions github-actions Bot added the ready PR is ready to merge label May 15, 2026
@SolitaryThinker
SolitaryThinker merged commit 460f6e3 into main May 16, 2026
17 of 22 checks passed
@SolitaryThinker
SolitaryThinker deleted the pr1225_s3 branch May 16, 2026 01:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready PR is ready to merge scope: model Model architecture (DiTs, encoders, VAEs) type: feat New feature or capability

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant