Skip to content

Use Fused Kernels for Depthwise Striding Subsampler: up to 1.5x faster training - #16114

Open
MahmoudAshraf97 wants to merge 12 commits into
NVIDIA-NeMo:mainfrom
MahmoudAshraf97:fast-pre-encoder
Open

Use Fused Kernels for Depthwise Striding Subsampler: up to 1.5x faster training#16114
MahmoudAshraf97 wants to merge 12 commits into
NVIDIA-NeMo:mainfrom
MahmoudAshraf97:fast-pre-encoder

Conversation

@MahmoudAshraf97

Copy link
Copy Markdown
Contributor

Important

The Update branch button must only be pressed in very rare occassions.
An outdated branch is never blocking the merge of a PR.
Please reach out to the automation team before pressing that button.

What does this PR do ?

This PR implements triton kernels for the subsampler in ConformerEncoder, profiling showed that the subsampler is heavily bottlenecked by memory bandwidth, so the fused kernels focus on reducing memory bandwidth by removing intermediary tensors

The first kernel implements:

mel input: [B, T, F, 1]
    ⇩
conv0 output: [B, T/2, F/2, 256] 
    ⇩
ReLU: [B, T/2, F/2, 256] 
    ⇩
Masking: [B, T/2, F/2, 256] 
    ⇩
conv_dw1 output: [B, T/4, F/4, 256]

it cuts memory bandwidth by more than 350x and even more in causal mode since it includes an extra padding layer, this fusion is not possible with torch.compile since it does not fuse the activation, the bias, or the masking into the convolution kernels, this kernel is most of the speedup

The second kernel is a general depthwise conv2d kernel, it's faster than torch kernel in forward since it fuses the pre and post masking and the causal padding, it has the most impact on M and L models, almost no impact on XL models because the encoder layers dominate the runtime, it is also faster than torch backward by 2x for the same reason

below are the speedup numbers expressed in relative speedup in E2E encoder step fwd+bwd, it uses the optimization in #16052 in both arms of the comparison

Eager

size fwd bwd e2e
M 1.38x 1.44x 1.42x
L 1.36x 1.36x 1.36x
XL 1.05x 1.20x 1.14x

torch.compile (max-autotune-no-cudagraphs)

size fwd bwd e2e
M 1.28x 1.63x 1.50x
L 1.22x 1.47x 1.39x
XL 1.11x 1.23x 1.19x

Collection: ASR

Usage

Defaults to enabled if triton is installed, otherwise disabled, can also be controlled using the training config:

model:
  encoder:
    use_triton: false

GitHub Actions CI

The Jenkins CI system has been replaced by GitHub Actions self-hosted runners.

Trusted PRs run automatically through copy-pr-bot. For an untrusted PR, a maintainer can trigger CI by commenting
/ok to test <head-sha>; repeat this after a new push if the PR remains untrusted.

Before your PR is "Ready for review"

Pre checks:

  • Make sure you read and followed Contributor guidelines
  • Did you write any new necessary tests?
  • Did you add or update any necessary documentation?
  • Does the PR affect components that are optional to install? (Ex: Numba, Pynini, Apex etc)
    • Reviewer: Does the PR have correct import guards for all optional libraries?

PR Type:

  • New Feature
  • Bugfix
  • Documentation

If you haven't finished some of the above items you can still open "Draft" PR.

Who can review?

@pzelasko @nithinraok

@MahmoudAshraf97
MahmoudAshraf97 requested a review from a team as a code owner August 19, 2026 15:40
@copy-pr-bot

copy-pr-bot Bot commented Aug 19, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a972c7eda8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread pyproject.toml
sync_max_audio_length: bool = True,
rope_base: float = 10000.0,
rotary_fraction: float = 1.0,
use_triton: bool | None = None,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Document the Triton default and YAML opt-out

For every existing dw_striding configuration in an environment with Triton installed, this new option silently changes the default execution path, yet none of the user-facing ASR documentation or example YAML configurations explains that behavior or shows use_triton: false. Add the new default, eligibility constraints, and opt-out to the relevant FastConformer documentation/config examples so users can discover and control the behavior.

AGENTS.md reference: AGENTS.md:L58-L63

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

this is similar to the use_pytorch_sdpa option, where it only exists in the module docstring and the configs only, not the documentation

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

yes please add to docs. we should have added use_pytorch_sdpa info to docs as well.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

added the documentation

mel_freq,
pad_start,
)
relu_out = tl.dot(conv_taps, feats) + conv_bias[:, None]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Respect the caller's disabled-TF32 setting

When an fp32 caller disables TF32 through torch.backends.cudnn.allow_tf32 = False and torch.backends.cuda.matmul.allow_tf32 = False for numerical accuracy, this tl.dot still uses Triton's default TF32 input precision. Because the Triton path is now enabled automatically, such callers silently receive reduced-precision convolution results despite explicitly disabling TF32; select IEEE input precision or fall back to the PyTorch path when TF32 is disabled.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Most training is in either mixed precision or half precision, where TF32 has no effect at all, regardless leaving this for the maintainers call

@svcnvidia-nemo-ci svcnvidia-nemo-ci added the waiting-on-maintainers Waiting on maintainers to respond label Aug 21, 2026
Signed-off-by: MahmoudAshraf97 <hassouna97.ma@gmail.com>
Signed-off-by: MahmoudAshraf97 <hassouna97.ma@gmail.com>
Signed-off-by: MahmoudAshraf97 <hassouna97.ma@gmail.com>
Signed-off-by: MahmoudAshraf97 <hassouna97.ma@gmail.com>
Signed-off-by: MahmoudAshraf97 <hassouna97.ma@gmail.com>
Signed-off-by: MahmoudAshraf97 <hassouna97.ma@gmail.com>
Signed-off-by: MahmoudAshraf97 <hassouna97.ma@gmail.com>
Signed-off-by: MahmoudAshraf97 <hassouna97.ma@gmail.com>
Signed-off-by: MahmoudAshraf97 <hassouna97.ma@gmail.com>
Signed-off-by: MahmoudAshraf97 <hassouna97.ma@gmail.com>

@nithinraok nithinraok left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Great work, couple of comments.

sync_max_audio_length: bool = True,
rope_base: float = 10000.0,
rotary_fraction: float = 1.0,
use_triton: bool | None = None,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

yes please add to docs. we should have added use_pytorch_sdpa info to docs as well.

use_triton = TRITON_AVAILABLE
self.conv.fuse_triton = (
use_triton and subsampling == 'dw_striding' and self._sampling_num >= 2 and isinstance(activation, nn.ReLU)
)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

but if user requests use_triton and striding, then code currently silently skips use of triton. Could you raise warning instead.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

added a warning for all non-eligible configs

from torch.nn import LayerNorm

from nemo.collections.asr.parts.submodules.causal_convs import CausalConv1D, CausalConv2D
from nemo.collections.asr.parts.triton.depthwise_conv import dw_conv2d

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

wouldn;t this raise error, when triton is not available?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

No, since all triton code in that file are guarded with TRITON_AVAILABLE flag, the alternative is to remove the gating and gate this import only

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

rewritten the files to follow the same pattern used in the ngram triton implementation, the indentation is gone and it raises on the first forward if use_triton=True was explicitly requested

@svcnvidia-nemo-ci svcnvidia-nemo-ci added waiting-on-customer Waiting on the original author to respond and removed waiting-on-maintainers Waiting on maintainers to respond labels Aug 24, 2026
Signed-off-by: MahmoudAshraf97 <hassouna97.ma@gmail.com>
Signed-off-by: MahmoudAshraf97 <hassouna97.ma@gmail.com>
@svcnvidia-nemo-ci svcnvidia-nemo-ci removed the waiting-on-customer Waiting on the original author to respond label Aug 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants