Skip to content

fix(personaplex): preserve residual input rounding - #1797

Closed
chaofengw-nv wants to merge 1 commit into
NVIDIA:mainfrom
chaofengw-nv:fix/personaplex-residual-rounding-20261018
Closed

chaofengw-nv wants to merge 1 commit into
NVIDIA:mainfrom
chaofengw-nv:fix/personaplex-residual-rounding-20261018

Conversation

@chaofengw-nv

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

Copy link
Copy Markdown
Collaborator

Background

Fixes #1796. PersonaPlex's Half residual path produces a value consistent with combining an unrounded GEMM accumulator and the skip input; the exact fused-kernel mechanism has not been isolated. For a projection of 1 + 2^-12 and skip input -1, Native first rounds the projection to Half and returns zero; the current decoder returns 2^-12.

Exit Criteria

  • Preserve linear-output rounding before the residual sum through an actual decoder layer's normal output.
  • Retain Half weights, hidden states and KV caches and the existing FP32 graph behavior.
  • Change no benchmark data, reference baseline or accuracy gate.

Implementation

A family-local residual helper casts the already rounded branch outputs to FP32, adds them and restores the residual dtype. This is value-equivalent to the Half addition while preserving the producer's rounding boundary. Standard, dual-profile and tensor-parallel decoder residuals use the helper. No new kernel, tactic constraint, platform branch or dependency is introduced; affected engines require rebuilding.

Change categories

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

Validation

Commands and Results

  • python -m pytest -q families/personaplex/tests/test_residual_precision.py: identical original/fixed test, separate processes and three fresh engines per precision. Original: 3 numerical FP16 failures and 3 FP32 passes, zero errors or skips. Fixed: all 6 cases pass, zero errors or skips. The test SHA-256 is identical on both sides (e6616ed9d0d6d92015b2874cc5544e62afea8ffa92bae5c6b33739cbd7739916).
  • A separate dense-GEMM boundary probe at widths 1024 and 4096: original returns 2^-12 on all three builds per width; FP32 residual-sum candidate returns zero on all three per width, with zero setup failures. An earlier multi-engine probe crashed and is excluded from these completed results.
  • Recorded Native depth-layer data (16 codebooks x 6 layers at step 28): recomputing each attention and MLP residual from its rounded Half branch outputs matches the recorded Native tensors with zero differing bits across all 96 layers (CPU check of captured data).
  • ruff check and python -m py_compile on all five changed files: passed.
  • PYTHONPATH=core/builder:apps/benchmark:. python -m tools.model_ci validate, PYTHONPATH=core/builder:apps/benchmark:. python tools/test_impact.py --validate, and git diff --check: passed with CUDA hidden.

Hardware, Environment, and Revisions

Base 9a8b545f5e8c22c653c8029c95a999dc070b4f3f; tested head 30faad4b1a58d1b6acb57bc6ebf5ca28a3c06401. GB300, Linux ARM64, CUDA 13, TensorRT 11.2.0.113 and PyTorch 2.12.0+cu130. The GPU A/B verifies source and test hashes. Synthetic weights and inputs need no downloaded checkpoint or dataset. Native residual order follows the pinned official source.

Not Run / Remaining Gaps

The regression directly covers the attention-side residual in standard decode. The MLP-side residual, parallel residual, dynamic prefill and TP call sites were reviewed but are not directly exercised by that regression. A fresh original-20 run of the published integration stack plus this exact production patch remains 18/20 against both frozen and refreshed Native FP16: clip 11 is 6.89 dB and clip 18 is 3.78 dB under the unchanged 3 dB gate. All 20 output WAVs are bit-identical to the same stack without this patch, so this PR earns no whole-model accuracy credit in that build. Task P50 is Native 2201.01 ms and TRTMC 1492.99 ms (20 requests each); output sample counts and rates match on all requests. These are one-build measurements. Three-build model acceptance, BF16, distributed tensor-parallel execution, other hardware and exact-head premerge remain unqualified. This PR claims component correctness only.

Contributor Self-Review

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

Reviewed every standard, dynamic and TP residual call site and the new normal-output regression. Changes remain within PersonaPlex.

Notes For Future Readers

The important boundary is the linear result rounded to the model dtype before the residual addition. Promoting the entire core to FP32 changes the requested model precision; this helper retains model-dtype inputs and outputs. Supported call sites provide equally typed branch outputs; mixed-dtype helper calls are outside the supported contract. Independent input, RoPE, SwiGLU and profile fixes remain separate PRs.

Risk level

  • Low
  • Medium
  • High

Residual arithmetic changes across the family. Component evidence does not establish whole-model parity or performance.

Preserve the Half linear-output boundary before attention and MLP residual additions. The previous fused path can add the FP32 GEMM accumulator to the residual before rounding, unlike Native Half linear followed by Half addition.

Sum the already rounded branch outputs in FP32 and restore the model dtype in the standard, dual-profile and TP decoders. Half weights, hidden states and KV caches stay Half; the FP32 graph is unchanged.

The actual decoder-layer regression fails numerically on all three original Half builds and passes on all six corrected Half/Float controls, with identical assertions and zero errors or skips. Whole-model acceptance remains separate.

Fixes NVIDIA#1796

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
Preserve rounded branch outputs before residual addition across the family decoder variants.

Closes NVIDIA#1796
Refs NVIDIA#1797

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 50849eb 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
Preserve rounded branch outputs before residual addition across the family decoder variants.

Closes NVIDIA#1796
Refs NVIDIA#1797

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 FP16 residuals skip linear-output rounding

1 participant