Skip to content

[XCS][ttx] optimize ResidualAddLayerNorm operater performance - #404

Open
Quamaly wants to merge 1 commit into
XPU-Forces:masterfrom
Quamaly:xcs-add_layer_norm_ops-opt
Open

[XCS][ttx] optimize ResidualAddLayerNorm operater performance#404
Quamaly wants to merge 1 commit into
XPU-Forces:masterfrom
Quamaly:xcs-add_layer_norm_ops-opt

Conversation

@Quamaly

@Quamaly Quamaly commented Jul 15, 2026

Copy link
Copy Markdown

TLE ResidualAddLayerNorm

case TLE kernel us torch-npu kernel us baseline TTX kernel us TLE vs torch-npu TLE vs baseline TTX acc
small_pre_float32_128x128 3.7881 8.5250 6.9132 2.250x 1.825x PASS
small_post_float32_128x128 3.7486 8.4874 6.9400 2.264x 1.851x PASS
small_pre_float16_128x128 3.8524 7.8888 6.8924 2.048x 1.789x PASS
small_post_float16_128x128 3.8097 7.9033 6.8411 2.075x 1.796x PASS
small_pre_bfloat16_128x128 3.8559 8.6396 7.0624 2.241x 1.832x PASS
small_post_bfloat16_128x128 3.8293 8.6692 7.0329 2.264x 1.837x PASS
small_pre_float32_64x256 2.4285 7.2996 6.7227 3.006x 2.768x PASS
small_post_float32_64x256 2.4034 7.3519 6.7319 3.059x 2.801x PASS
small_pre_float16_64x256 2.4325 6.2769 6.8462 2.580x 2.814x PASS
small_post_float16_64x256 2.4175 6.1791 6.6967 2.556x 2.770x PASS
small_pre_bfloat16_64x256 2.5427 7.4457 6.7627 2.928x 2.660x PASS
small_post_bfloat16_64x256 2.5302 7.2871 6.8210 2.880x 2.696x PASS
small_pre_float32_32x512 2.5248 6.3283 6.8209 2.506x 2.702x PASS
small_post_float32_32x512 2.5161 6.2341 6.8352 2.478x 2.717x PASS
small_pre_float16_32x512 2.5124 6.4256 6.7529 2.558x 2.688x PASS
small_post_float16_32x512 2.5155 6.3262 6.8000 2.515x 2.703x PASS
small_pre_bfloat16_32x512 2.6094 6.2525 6.8252 2.396x 2.616x PASS
small_post_bfloat16_32x512 2.5369 6.2527 6.8717 2.465x 2.709x PASS
large_pre_float16_256x2048 7.2325 11.6943 11.3206 1.617x 1.565x PASS
large_post_float16_256x2048 7.2008 11.8746 11.3648 1.649x 1.578x PASS
large_pre_bfloat16_256x2048 7.6098 11.7164 11.8163 1.540x 1.553x PASS
large_post_bfloat16_256x2048 7.6010 11.7665 11.7920 1.548x 1.551x PASS
large_pre_float16_128x4096 7.8026 11.9142 10.6572 1.527x 1.366x PASS
large_post_float16_128x4096 7.8157 11.8200 10.6604 1.512x 1.364x PASS
large_pre_bfloat16_128x4096 8.1098 12.0671 11.0574 1.488x 1.363x PASS
large_post_bfloat16_128x4096 8.1292 11.7011 11.0020 1.439x 1.353x PASS
large_pre_float16_64x8192 8.7541 9.7516 14.8927 1.114x 1.701x PASS
large_post_float16_64x8192 8.6772 9.6314 14.9341 1.110x 1.721x PASS
large_pre_bfloat16_64x8192 9.3406 9.9220 15.6548 1.062x 1.676x PASS
large_post_bfloat16_64x8192 9.3194 9.7258 15.7357 1.044x 1.688x PASS
large_pre_float16_57x7338 9.7007 9.3650 16.0366 0.965x 1.653x PASS
large_post_float16_57x7338 9.8298 9.1898 15.9411 0.935x 1.622x PASS
large_pre_bfloat16_57x7338 10.1686 9.5410 16.2323 0.938x 1.596x PASS
large_post_bfloat16_57x7338 10.3196 9.3059 16.2465 0.902x 1.574x PASS

@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 a new NPU-optimized Triton kernel implementation for fused residual add and layer normalization (fused_add_layernorm_tle_infer_impl) and integrates it into the TTXResidualAddLayerNorm operator. The feedback highlights two important improvements: first, ensuring input tensors are contiguous before passing them to the Triton kernel to prevent memory access bugs; second, wrapping the Triton driver device property retrieval in a try-except block with a safe fallback to avoid potential initialization crashes.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +538 to +544
use_2d_fast_wrapper = hidden_states.dim() == 2 and residual.dim() == 2
if use_2d_fast_wrapper:
X_2d = hidden_states
R_2d = residual
else:
X_2d = hidden_states.reshape(-1, dim)
R_2d = residual.reshape(-1, dim)

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

When hidden_states is a 2D non-contiguous tensor (e.g., after a transpose or slice), reshape(-1, dim) is a no-op and returns the same non-contiguous tensor. This causes the Triton kernel to read incorrect memory locations because it assumes a contiguous layout (column stride of 1) via X_ptr_row_block + cols_off[None, :].

To prevent silent correctness bugs or out-of-bounds memory accesses, we should:

  1. Ensure use_2d_fast_wrapper only triggers when both tensors are contiguous.
  2. Explicitly call .contiguous() on the reshaped tensors in the fallback path.
Suggested change
use_2d_fast_wrapper = hidden_states.dim() == 2 and residual.dim() == 2
if use_2d_fast_wrapper:
X_2d = hidden_states
R_2d = residual
else:
X_2d = hidden_states.reshape(-1, dim)
R_2d = residual.reshape(-1, dim)
use_2d_fast_wrapper = (
hidden_states.dim() == 2
and residual.dim() == 2
and hidden_states.is_contiguous()
and residual.is_contiguous()
)
if use_2d_fast_wrapper:
X_2d = hidden_states
R_2d = residual
else:
X_2d = hidden_states.reshape(-1, dim).contiguous()
R_2d = residual.reshape(-1, dim).contiguous()
References
  1. When performing pointer arithmetic to verify tensor adjacency in memory for kernel optimizations, ensure the calculation correctly accounts for the tensor's strides and the specific dimensions being checked.


block_size_m = layer_norm_fwd_heuristics({"n_cols": n_cols})
num_row_tasks = ceil_div(n_rows, block_size_m)
num_vectorcores = triton.runtime.driver.active.utils.get_device_properties("npu")["num_vectorcore"]

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.

medium

Accessing triton.runtime.driver.active directly can raise an AttributeError if the Triton driver has not been initialized yet (e.g., if this is the first Triton operation in the process). Additionally, the dictionary returned by get_device_properties might not always contain the 'num_vectorcore' key depending on the environment or Triton version.

Wrapping this in a try-except block with a safe fallback (e.g., 32 vector cores) prevents potential runtime crashes during initialization.

Suggested change
num_vectorcores = triton.runtime.driver.active.utils.get_device_properties("npu")["num_vectorcore"]
try:
num_vectorcores = triton.runtime.driver.active.utils.get_device_properties('npu')['num_vectorcore']
except Exception:
num_vectorcores = 32

@Quamaly Quamaly changed the title [XCS]optimize ResidualAddLayerNorm operater performance [XCS][ttx] optimize ResidualAddLayerNorm operater performance Jul 15, 2026
@Quamaly
Quamaly force-pushed the xcs-add_layer_norm_ops-opt branch from 36fa938 to c24d7bd Compare July 17, 2026 09:52
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.

1 participant