Skip to content

fix(nemotron-v3): support THD with input_embeds instead of input_ids#2185

Open
pzelasko wants to merge 2 commits intomainfrom
pzelasko/fix/squeeze-input-for-thd-inputs-embeds
Open

fix(nemotron-v3): support THD with input_embeds instead of input_ids#2185
pzelasko wants to merge 2 commits intomainfrom
pzelasko/fix/squeeze-input-for-thd-inputs-embeds

Conversation

@pzelasko
Copy link
Copy Markdown
Contributor

@pzelasko pzelasko commented May 7, 2026

What does this PR do ?

Support THD with input_embeds instead of input_ids.
Previously, it errored out on THD because the utilities implicitly assumed input_ids cannot be None.

Changelog

  • Support THD with input_embeds instead of input_ids.

Before your PR is "Ready for review"

Pre checks:

  • Make sure you read and followed Contributor guidelines
  • Did you write any new necessary tests?
  • Did you add or update any necessary documentation?

If you haven't finished some of the above items you can still open "Draft" PR.

Additional Information

  • Related to # (issue)

pzelasko and others added 2 commits May 1, 2026 21:32
`SALMAutomodel` and other multimodal callers feed the LLM through
`inputs_embeds` (audio frames spliced into the token stream have no
integer ID) and leave `input_ids=None`. Two bugs surfaced when running
that path under `qkv_format="thd"`:

1. `squeeze_input_for_thd` did `input_ids.squeeze(0)` unconditionally
   and crashed with `AttributeError: 'NoneType' object has no attribute
   'squeeze'`.  Add the same `is-not-None` guard the helper already uses
   for `padding_mask`; document `None` as a valid value.

2. `NemotronHForCausalLM.forward` did `logits = logits.unsqueeze(0)`
   whenever `is_thd`, producing `[1, 1, T, V]` for the
   `inputs_embeds` path because `NemotronHModel.forward` already
   restores the batch dim (`squeezed_for_thd` branch). Restrict the
   outer unsqueeze to the case where the inner returned 2D logits;
   the standard `input_ids` path still satisfies that.

Tests:
- `TestSqueezeInputForThd` (5 cases) covers the helper-level contract:
  standard `input_ids` path, `input_ids=None` path, `padding_mask=None`
  composition, 3D `[1, T, H]` embedding-via-`input_ids` slot path, and
  `cu_seqlens_padded` filtering.
- `TestNemotronHForCausalLM::test_causal_lm_thd_*` (2 cases) covers the
  outer logits-shape contract: `inputs_embeds`-only stays `[1, T, V]`
  (no double-unsqueeze), and `input_ids`-only still gets the batch dim
  re-added. The inner forward is stubbed via a tiny `nn.Module` because
  THD shapes only run end-to-end on TE/GPU.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@copy-pr-bot
Copy link
Copy Markdown

copy-pr-bot Bot commented May 7, 2026

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@pzelasko
Copy link
Copy Markdown
Contributor Author

pzelasko commented May 7, 2026

/ok to test 351806a

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