Skip to content

fix(personaplex): preserve reference RoPE precision - #1791

Closed
chaofengw-nv wants to merge 2 commits into
NVIDIA:mainfrom
chaofengw-nv:fix/personaplex-fp32-rotary-20261018
Closed

chaofengw-nv wants to merge 2 commits into
NVIDIA:mainfrom
chaofengw-nv:fix/personaplex-fp32-rotary-20261018

Conversation

@chaofengw-nv

@chaofengw-nv chaofengw-nv commented Oct 18, 2026 •

Copy link
Copy Markdown
Collaborator

Background

PersonaPlex's decoder computes RoPE coefficients in FP64 before converting them, and its FP16 path further rounds the constants before rotating queries and keys. The pinned official implementation computes the frequencies, angles and rotation in FP32, then converts the result to the input dtype. For the adjacent pair (1, 1) at position 1, the current FP16 cached real component is -0.30078125 instead of -0.30126953125. Fixes #1790.

Exit Criteria

  • Preserve the official FP32 rotation boundary through the actual decoder's normal KV-cache output.
  • Preserve the model's original weight, hidden-state and cache dtypes.
  • Establish original/fixed numerical regression evidence on independent tiny-engine builds without changing any existing acceptance criterion.

Implementation

  • Keep FP32 cosine/sine tables in the single-step, dual-profile and tensor-parallel decoder builders.
  • Generate frequencies, angles and trigonometric tables using FP32 operations rather than FP64 evaluation followed by conversion. The family-owned table helper is also used by the Mimi encoder.
  • Perform native TensorRT rotary embedding on FP32 inputs and tables, then restore the query/key dtype before caching and attention.
  • Add a regression through the ordinary present_k_0 output: a constant key pair at position 1, independently evaluated with Torch FP32 rotation followed by the requested output conversion. Both FP16 and FP32 use exact assertions; each decode/prefill path is built three times. No debug outputs are added to the graph.

Change categories

  • Model or runtime behavior
  • Public API
  • ABI
  • Bundle or artifact format
  • Dependencies
  • Documentation only
  • CI or developer tooling

Validation

Commands and Results

  • ruff check --config ruff.toml families/personaplex/graph_ops.py families/personaplex/default_decoder.py families/personaplex/default_dual_profile_decoder.py families/personaplex/decoder_tp_builder.py families/personaplex/tests/test_rotary_precision.py: passed.
  • PYTHONPATH=core/builder:apps/benchmark:. python -m tools.model_ci validate and PYTHONPATH=core/builder:apps/benchmark:. python tools/test_impact.py --validate: passed, with GPU access disabled.
  • Independent CPU Torch control: FP32 rotation followed by FP16 conversion produces -0.30126953125; prematurely rounded constants produce -0.30078125.
  • python -m pytest -q families/personaplex/tests/test_rotary_precision.py: on the original base, all 12 cases fail numerical assertions; with the final five-file change, all 12 pass, with zero errors or skips. Both decoder paths and both FP16/FP32 precisions are each built three times. The identical test uses CUDA Torch FP32 as its independent oracle and exact rtol=0, atol=0 assertions. The original FP16 error is 0.00048828125; the original FP32 coefficient error is 5.960464477539063e-08.

Hardware, Environment, and Revisions

Base 88ceb9f5217a9f9318e3393a404761e09891194c; head 97197612aa3cb0eb762f7a26bba6147bdb4aa924. The GPU A/B verified the final five changed files by SHA-256. Target GPU validation uses NVIDIA GB300, Linux ARM64, CUDA 13, TensorRT 11.2.0.113 and PyTorch 2.12.0+cu130. The equation follows the pinned official Moshi implementation. The regression uses synthetic weights, position 1 and a two-entry KV cache; no downloaded checkpoint or speech dataset is required.

Not Run / Remaining Gaps

Full-model accuracy and performance for this focused change, Mimi codec code parity, distributed tensor-parallel execution, BF16, other hardware and exact-head premerge are unqualified. Matching the FP32 operator sequence does not guarantee bitwise equality of NumPy and CUDA transcendental functions at every angle. An additional ARM64 CPU comparison against captured Native CUDA tables at positions 0 through 3000 still finds 53,991 cosine and 57,378 sine differences out of 192,064 coefficients each; maximum absolute error is approximately 0.00024414. The position-1 regression proves the corrected boundary, rather than global table equality. The prior combined true-FP16 diagnostic failed on 2/20 original speech clips. A fresh combined true-FP16 build including this final RoPE change and the separate input/RMSNorm fixes still fails clip 7 at 5.58 dB against the unchanged Native FP16 reference (original maximum: 3 dB). That is combined diagnostic evidence, not a standalone full-model qualification of this PR. This PR does not replace the Native baseline or claim full-model acceptance.

Contributor Self-Review

  • I have completed a self-review of this change.

Reviewed all three decoder table-construction paths and the shared family rotary helper. The change remains inside PersonaPlex and uses TensorRT graph primitives without hardware/version branches, kernel implementations or tactic selection.

Notes For Future Readers

The half suffix in the cosine/sine table names denotes half of the rotary dimension. These tables retain FP32 values even when the model and cache are FP16. Rebuild affected engines to apply the change. Depth-input rounding and RMSNorm epsilon are separate corrections.

Risk level

  • Low
  • Medium
  • High

Rotated keys and therefore autoregressive outputs change. Small-engine regression evidence establishes the precision boundary; full-model acceptance remains a separate requirement.

Keep cosine and sine constants in FP32 in the single-step, dual-profile and tensor-parallel decoder builders. Rotate in FP32 and round queries and keys back before caching, matching the official model arithmetic boundaries.

Add an independent Torch regression through the normal KV-cache output, with repeated fresh tiny engines. The original Native FP16 benchmark and accuracy gates remain unchanged.

Fixes NVIDIA#1790

Signed-off-by: chaofengw <chaofengw@nvidia.com>
Match the reference frequency, angle and trigonometric evaluation precision. Evaluating in FP64 and only converting afterwards changes cached keys even for a decoder configured as FP32. The same family helper also supplies Mimi encoder tables.

The original and corrected decoders were each independently built three times per precision and graph path. All 12 original cases fail numerical assertions; all 12 corrected cases pass the identical CUDA Torch oracle without changing existing accuracy gates.

Refs: NVIDIA#1790
Signed-off-by: chaofengw <chaofengw@nvidia.com>
@chaofengw-nv chaofengw-nv self-assigned this Oct 18, 2026
@coderabbitai

coderabbitai Bot commented Oct 18, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

chaofengw-nv added a commit to chaofengw-nv/TensorRT-Model-Connect-fork that referenced this pull request Oct 20, 2026
Construct RoPE angles and rotation in FP32, then restore the input dtype across the family decoder variants.

Closes NVIDIA#1790
Refs NVIDIA#1791

Signed-off-by: chaofengw <chaofengw@nvidia.com>
@chaofengw-nv

Copy link
Copy Markdown
Collaborator Author

Superseded by #1751. This change and its regression coverage are preserved in commit b3a0872 of the consolidated PR. Original issue links and acceptance criteria remain tracked there.

chaofengw-nv added a commit to chaofengw-nv/TensorRT-Model-Connect-fork that referenced this pull request Oct 21, 2026
Construct RoPE angles and rotation in FP32, then restore the input dtype across the family decoder variants.

Closes NVIDIA#1790
Refs NVIDIA#1791

Signed-off-by: chaofengw <chaofengw@nvidia.com>
chaofengw-nv added a commit that referenced this pull request Oct 21, 2026
* fix(personaplex): decode with the FP32 Mimi codec

Build the Mimi decoder in FP32, matching the encoder and native codec for every language-model precision.

Closes #1750

Signed-off-by: chaofengw <chaofengw@nvidia.com>

* fix(personaplex): keep RMSNorm epsilon in FP32

Create RMSNorm epsilon in FP32 so the 1e-8 value survives Half network construction.

Closes #1779
Refs #1780

Signed-off-by: chaofengw <chaofengw@nvidia.com>

* fix(personaplex): preserve Half embedding additions

Sum audio embeddings before text and round each addition to Half for Half temporal engines.

Closes #1778
Refs #1781

Signed-off-by: chaofengw <chaofengw@nvidia.com>

* fix(personaplex): round the FP16 depth input like the reference

Round depth projection weights, inputs, projection output and token embedding additions at the reference Half boundaries.

Closes #1788
Refs #1789

Signed-off-by: chaofengw <chaofengw@nvidia.com>

* fix(personaplex): preserve reference RoPE precision

Construct RoPE angles and rotation in FP32, then restore the input dtype across the family decoder variants.

Closes #1790
Refs #1791

Signed-off-by: chaofengw <chaofengw@nvidia.com>

* fix(personaplex): round the SwiGLU gate product once

Evaluate SiLU and its gate product in FP32, casting the combined result to the projection dtype once.

Closes #1793
Refs #1794

Signed-off-by: chaofengw <chaofengw@nvidia.com>

* fix(personaplex): build the FP16 profile with a Half core

Remove component-promotion selectors from the primary FP16 manifest. Preserve the declared BF16 E2E reference and all existing thresholds.

Refs #1786
Refs #1795

Signed-off-by: chaofengw <chaofengw@nvidia.com>

* fix(personaplex): preserve residual input rounding

Preserve rounded branch outputs before residual addition across the family decoder variants.

Closes #1796
Refs #1797

Signed-off-by: chaofengw <chaofengw@nvidia.com>

* fix(personaplex): store RMSNorm weights in the model dtype

Round RMSNorm scale weights to the model dtype before the FP32 normalization computation.

Closes #1799
Refs #1800

Signed-off-by: chaofengw <chaofengw@nvidia.com>

---------

Signed-off-by: chaofengw <chaofengw@nvidia.com>
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.

[Accuracy] PersonaPlex RoPE uses different coefficient and rotation precision

1 participant