Skip to content

feat: add fused rms_norm_rope operator (per-head RMSNorm + RoPE; CPU, NVIDIA) - #1567

Open
shsaihdsaiudh wants to merge 2 commits into
InfiniTensor:mainfrom
shsaihdsaiudh:feat/rms-norm-rope
Open

shsaihdsaiudh wants to merge 2 commits into
InfiniTensor:mainfrom
shsaihdsaiudh:feat/rms-norm-rope

Conversation

@shsaihdsaiudh

@shsaihdsaiudh shsaihdsaiudh commented Sep 20, 2026

Copy link
Copy Markdown

Summary

Add a fused rms_norm_rope operator: per-head RMSNorm + RoPE in a single kernel, consumed by InfiniLM's Qwen3 paged attention path (companion PR to InfiniLM, linked below).

Note on layout: this branch is based on the pre-split monolithic layout (src/infiniop/ops/...), developed before the unified component architecture refactor (#1406). The op itself (dispatcher, CPU kernel, NVIDIA CUDA kernel) is self-contained and ports mechanically to the new InfiniOps structure.

Content

  • include/infiniop/ops/rms_norm_rope.h — C API (infiniopRMSNormRoPEDescriptor_t, create/plan/run)
  • include/infinicore/ops/rms_norm_rope.hpp — C++ API (infinicore::op::rms_norm_rope_, in-place)
  • src/infiniop/ops/rms_norm_rope/operator.cc — device dispatch
  • src/infiniop/ops/rms_norm_rope/cpu/ — CPU implementation
  • src/infiniop/ops/rms_norm_rope/nvidia/ + cuda/kernel.cuh — NVIDIA CUDA implementation

Semantics: for each token, x = rms_norm(x) * weight per head, then RoPE with the given pos_ids and precomputed sin/cos tables. Full-rotary only (head_dim == 2 * table_dim).

Platform status

Platform Status
CPU Implemented + tested
NVIDIA (CUDA) Implemented + tested (RTX 5090, sm_120)
Cambricon / Ascend / Metax / Moore / Kunlun Not implemented — InfiniLM call site gates by device and falls back to the unfused chain

Verification

  • Op-level numeric check: fused op vs unfused rms_norm→rope chain on identical inputs (harness: dev_perf/op_check_rms_norm_rope.cpp in the InfiniLM PR), results within fp tolerance.
  • End-to-end in InfiniLM Qwen3-0.6B paged path, greedy decoding token-exact vs unfused chain; ABBA e2e -4%~-8% on RTX 5090 (-4%~-23% on RTX 5060 Ti 16GB WSL2). Full measurement log: dev_perf/gap_analysis.md v5/v6 in the InfiniLM PR.

Reproduce

  1. Build InfiniCore from this branch, install to $INFINI_ROOT.
  2. Build InfiniLM against it, run python dev_perf/bench.py --engine infinilm --model Qwen/Qwen3-0.6B --attn-backend hybrid (fused) vs the unfused fallback path.
  3. Op-level check: compile dev_perf/op_check_rms_norm_rope.cpp against the installed InfiniCore (commands in the file header).

Companion InfiniLM PR: InfiniTensor/InfiniLM#585

silasyyyang added 2 commits August 24, 2026 19:39
Single-kernel fusion of the per-head q/k RMSNorm + RoPE chain used by
attention blocks: 2 kernel launches + 2 memory round-trips per tensor
become 1 in-place pass.

- infiniop C layer: descriptor/workspace/calculate entry points with
  CPU + NVIDIA dispatch; info validation enforces full-rotary
  (head_dim == 2 x table_dim), pos I32/I64, sin/cos F32 contiguous
- CUDA kernel: fp32 accumulation for the sum-of-squares, rsqrtf, rounds
  to data type first, then rotates -- replicating the standalone rope
  kernel's rounding path per variant (GPT_J/NEOX x half/bf16)
- infinicore bridge: op::rms_norm_rope_ with graph-op support
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