Skip to content

fix(roberta): load unprefixed encoder weights - #1597

Open
JiaxinD wants to merge 3 commits into
NVIDIA:mainfrom
JiaxinD:fix/roberta-unprefixed-checkpoints
Open

JiaxinD wants to merge 3 commits into
NVIDIA:mainfrom
JiaxinD:fix/roberta-unprefixed-checkpoints

Conversation

@JiaxinD

@JiaxinD JiaxinD commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Background

RoBERTa rejects bare encoder checkpoints saved by Hugging Face RobertaModel, XLMRobertaModel and CamembertModel: it requests a roberta. prefix absent from these files. The pinned multilingual-e5-large checkpoint has this layout. Existing family E2E covers encoding only, without E5's mean-pooled embedding contract.

Exit Criteria

  • Load bare tensors while preserving both prefixed layouts and every mapped tensor.
  • Exercise the pinned E5 checkpoint through native embedding and official masked-mean, L2-normalized reference paths.
  • Preserve encoding's CLS reference and existing acceptance criteria.

Implementation

  • Detect model.roberta., roberta. or an empty root for encoder/pooler reads; fail when no root matches.
  • Compare real tiny HF safetensors across three model types, namespaces and pooler states.
  • Add English query and Chinese passage cases, with English selected for premerge.
  • Dispatch native embed, honor the manifest sequence limit, and retain encode/CLS for encoding.
  • Use 0.999 cosine for new cases, matching existing RoBERTa cases, plus a unit-norm assertion.

All changes are family-local. No public API, SDK ABI, bundle format, dependency or deployment-order change. No pretrained weights are distributed.

Change categories

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

Validation

Commands and Results

Check Result
Original loader tests against unchanged loader 6 bare-layout failures, 12 prefixed passes
New CPU regressions before changes 5 failed, 1 passed
CPU family suite excluding unchanged activation tests 70 passed, 10 opt-in E2E skipped
Independent focused review; architecture/impact/metadata/hygiene 8 passed; 99 passed
python -m pytest families/roberta/tests/test_e2e.py --e2e-model multilingual-e5-large -q Real H200: 2 passed
English FP16 native versus FP32 reference cosine 0.999998494, norm 0.999999871, 1024 dimensions
Chinese FP16 native versus FP32 reference cosine 0.999993803, norm 1.000000163, 1024 dimensions
model-ci, test-impact, Ruff, diff check Passed

The GPU run built real engines and CLI/backend/family targets, used actual tokenizers and CUDA references, and retained the original assertions. The separate CPU launcher uses import-only TensorRT and redirects tiny HF tensor transfers to CPU.

Hardware, Environment, and Revisions

Code 473e32861f3776538dc9a84ede1ee145e3c9d2b1; E5 3d7cfbdacd47fdda877c5cd8a79fbcc4f2a574f3. H200 SM90, driver 595.71.05, repository Dockerfile.dev.x86 pinned TensorRT 26.07 image, TRT11.1.0.106/CUDA13.3.73, Torch2.12.0+cu130, Transformers5.2.0, Hub1.33.0. Model SHA256: 020afdebf2762b29fcaf286629a96c3b3b65af241f6a08226b1cfee60a21def6. Earlier Windows CPU evidence used Transformers5.11.0.

Not Run / Remaining Gaps

No TRT11.4 root-image, BF16, TP4, throughput, latency or memory comparison. Two unchanged Windows activation tests lacked TensorRT enums. Filtered-cache completeness initially failed before GPU build; the existing explicit model-directory override selected the same pinned files. Image restart emitted a compatibility warning; actual CUDA execution passed in the recorded environment only.

Contributor Self-Review

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

Notes For Future Readers

This fixes the existing family without another E5 owner. Review loader mapping, then task-specific reference and cases. Publisher card declares MIT. GPU evidence belongs only to the frozen head and recorded environment. Protected CI was requested once for this head after public CPU/Stable/Dev passed.

Risk level

  • Low
  • Medium
  • High

Only key-root selection changes production behavior; graph construction and existing thresholds remain untouched.

Signed-off-by: JiaxinD <djx2048@gmail.com>
@coderabbitai

coderabbitai Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between 76d83ad and 473e328.

Files selected for processing: 6
  • families/roberta/model.py
  • families/roberta/tests/manifests/multilingual-e5-large.json
  • families/roberta/tests/test_e2e.py
  • families/roberta/tests/test_embedding_e2e_contract.py
  • families/roberta/tests/thresholds/multilingual-e5-large-passage-zh.json
  • families/roberta/tests/thresholds/multilingual-e5-large-query-en.json

Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 10 remain after this review.

📝 Summary

Summary

RoBERTa-family loading now detects model.roberta., roberta., and bare tensor roots. It raises KeyError if no matching word-embedding tensor exists. The loader uses the detected root for embeddings, encoder layers, and pooler weights.

Tests cover RoBERTa, XLM-RoBERTa, and CamemBERT checkpoints across all three roots, with and without a pooler. They verify loaded keys, values, dtype, and memory layout.

The E2E tests now cover embedding and encoding tasks. The multilingual-E5-large manifest adds English-query and Chinese-passage cases. The embedding reference uses attention-mask-weighted mean pooling and L2 normalization. The configured cosine threshold is 0.999, and native embeddings must have unit length.

Reported validation includes 70 CPU-suite passes and 10 opt-in GPU cases skipped, plus 8 passes in a focused E2E review. The PR also reports passing architecture, impact, metadata, hygiene, model-ci, test-impact, Ruff, and git diff --check validations. TensorRT build and native inference, actual E5 tokenizer parity, GPU numerical parity, and performance remain untested. The two excluded activation tests could not run because the Windows launcher lacked TensorRT enums. Current review-finding severity counts are unavailable.

Architecture impact

  • Family-owned files: The implementation, manifest, thresholds, and tests changed under families/roberta/. The loader behavior and E5 reference logic remain within the RoBERTa family.
  • Changed shared surfaces: No shared implementation or public API change is identified in the supplied evidence.
  • New dependency directions: No new cross-family or shared-code dependency is identified.
  • Affected consumers: _RobertaModel.load_weights serves the RoBERTa-family loading path. The E2E harness routes this family’s embedding manifests to native embed; encoding manifests continue to use encode.
  • Unresolved blast-radius questions: The supplied evidence does not establish TensorRT build or native runtime behavior for the added checkpoint, or GPU parity and performance. It also does not establish compatibility with checkpoint layouts beyond the three tested roots.

Outcome: HUMAN REVIEW REQUIRED. Runtime and checkpoint compatibility questions remain unresolved. This outcome does not assert a violation.

The RoBERTa loader now detects prefixed and unprefixed checkpoint tensor names. RoBERTa end-to-end tests now support embedding tasks and include multilingual E5 query and passage cases.

Changes: RoBERTa model coverage

Layer / File(s) Summary
Detect namespaces and load checkpoint tensors
families/roberta/model.py, families/roberta/tests/test_checkpoint_weights.py
The loader detects model.roberta., roberta., or no prefix. Tests compare loaded tensors across RoBERTa, XLM-RoBERTa, and CamemBERT checkpoints, including variants with and without pooler tensors.
Add embedding end-to-end coverage
families/roberta/tests/test_e2e.py, families/roberta/tests/test_embedding_e2e_contract.py, families/roberta/tests/manifests/multilingual-e5-large.json, families/roberta/tests/thresholds/multilingual-e5-large-*.json
End-to-end helpers dispatch embedding tasks and calculate masked mean pooling with L2 normalization. The multilingual E5 manifest defines English-query and Chinese-passage cases. Contract tests check dispatch, reference outputs, parity, and case selection; threshold overrides set cosine thresholds to 0.999.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Possibly related issues

  • NVIDIA/TensorRT-Model-Connect issue 1508: The checkpoint tests cover prefixed and unprefixed checkpoint layouts, and the PR adds real-checkpoint E2E cases. The PR does not implement the requested Task SDK migration.
Merge Risk: Minimal · up to 473e3

No actionable merge-blocking risk was identified. Native GPU parity remains untested.

Pre-merge checks: Passed 8 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentat… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 8 passed
Check name Status Explanation
Title check Passed The title is concise, specific, and accurately identifies the main change: loading unprefixed RoBERTa encoder weights.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Family Ownership Boundary Passed The pull request changes only families/roberta/**. The new tests import families.roberta.config, families.roberta.model, and families.roberta.tests.test_e2e; they do not import another reposit…
Shared Semantic Neutrality Passed PASS. The pull request changes only families/roberta/model.py and RoBERTa-owned test, manifest, and threshold files. No shared code outside the model-owned Python, E2E, or family-owned test/config a…
Benchmark Validation Integrity Passed PASS. The PR changes E2E validation semantics, but the compared paths remain equivalent. families/roberta/tests/test_e2e.py:251-282 dispatches embedding to embed and encoding to encode; its …
Shared Change Blast Radius Passed The pull request changes only families/roberta/model.py and RoBERTa-local tests, manifests, and thresholds. It does not modify shared runtime code, shared contracts, common tooling, examples, benchm…
Description check Passed The description covers all required sections, including motivation, exit criteria, implementation scope, change category, validation results, environment and revisions, remaining gaps, self-review, fu…
Full details: Family Ownership Boundary

Explanation

The pull request changes only families/roberta/**. The new tests import families.roberta.config, families.roberta.model, and families.roberta.tests.test_e2e; they do not import another repository family. RobertaModel, XLMRobertaModel, and CamembertModel are external Transformers fixtures used to test model types already owned by the RoBERTa family, as shown by families/roberta/support.py accepting camembert, roberta, and xlm-roberta. The manifest and threshold files are also under families/roberta/tests/. No other family or central registry, switch, source list, or strategy map is changed.

Full details: Shared Semantic Neutrality

Explanation

PASS. The pull request changes only families/roberta/model.py and RoBERTa-owned test, manifest, and threshold files. No shared code outside the model-owned Python, E2E, or family-owned test/config areas changed. The model-specific prefix handling and embedding reference behavior remain within the RoBERTa family implementation and its family tests.

Full details: Benchmark Validation Integrity

Explanation

PASS. The PR changes E2E validation semantics, but the compared paths remain equivalent. families/roberta/tests/test_e2e.py:251-282 dispatches embedding to embed and encoding to encode; its reference uses the same task split, manifest truncation, attention-mask mean pooling, and L2 normalization. The native embed contract is independently documented in apps/perf_serving/trtmc_perf_serving/backends/reference/text.py:201-250 with the same pooling and normalization meaning. test_embedding_e2e_contract.py:14-113 covers both dispatch paths, masked pooling, normalization, cosine direction, and selector behavior. No benchmark timing, shard/sample accounting, serialization, or one-sided synchronization/transfer accounting changed.

Full details: Shared Change Blast Radius

Explanation

The pull request changes only families/roberta/model.py and RoBERTa-local tests, manifests, and thresholds. It does not modify shared runtime code, shared contracts, common tooling, examples, benchmarks, catalogs, or repository-wide validation infrastructure. The loader change is scoped to _RobertaModel, and the added embedding validation is implemented in families/roberta/tests/test_e2e.py and family-local tests. Therefore the shared change blast-radius check is not applicable.

Full details: Description check

Explanation

The description covers all required sections, including motivation, exit criteria, implementation scope, change category, validation results, environment and revisions, remaining gaps, self-review, future notes, and risk rationale. It provides strong test evidence and clearly states compatibility and deployment boundaries. Some validation entries do not include exact commands, but the description is otherwise complete.

Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 12 functions across 4 files. (3 skipped: 3 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

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

@JiaxinD

JiaxinD commented Oct 8, 2026

Copy link
Copy Markdown
Contributor Author

@yifeif-nv #1597 is ready for protected CI at 76d83ade: Community CPU, Stable and Dev passed, and contributor self-review is complete. Could you trigger Internal CI for this head?

@yifeif-nv yifeif-nv added the run-internal-ci Maintainer-approved dispatch to internal CI label Oct 12, 2026
@yifeif-nv

Copy link
Copy Markdown
Collaborator

Internal CI trigger

@github-actions github-actions Bot removed the run-internal-ci Maintainer-approved dispatch to internal CI label Oct 12, 2026
@JiaxinD
JiaxinD marked this pull request as ready for review October 29, 2026 16:04
@JiaxinD
JiaxinD requested a review from yifeif-nv as a code owner October 29, 2026 16:04
…xed-checkpoints

Signed-off-by: JiaxinD <djx2048@gmail.com>
Signed-off-by: JiaxinD <djx2048@gmail.com>
@JiaxinD

JiaxinD commented Oct 31, 2026

Copy link
Copy Markdown
Contributor Author

@yifeif-nv Community CPU / Required, Stable and Dev passed for 473e328. Please trigger protected CI for this head, including the new multilingual-e5-large premerge case.

This branch has not been deployed

No deployments
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.

2 participants