Skip to content

[#17158][fix] Reject NaN top_p, min_p and temperature in SamplingParams - #17159

Merged
zhaoyangwang-nvidia merged 2 commits into
NVIDIA:mainfrom
Yigtwxx:fix/sampling-params-non-finite
Aug 5, 2026
Merged

[#17158][fix] Reject NaN top_p, min_p and temperature in SamplingParams#17159
zhaoyangwang-nvidia merged 2 commits into
NVIDIA:mainfrom
Yigtwxx:fix/sampling-params-non-finite

Conversation

@Yigtwxx

@Yigtwxx Yigtwxx commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Description

Fixes #17158.

SamplingParams._validate() bounded top_p, min_p and temperature with positive
range checks of the form value < low or value > high. Every comparison against NaN
evaluates to False, so SamplingParams(top_p=float("nan")) and its min_p /
temperature equivalents passed validation unchanged and were forwarded to the sampling
backend, which applies no guard of its own — sampler_strategy.py:325-337 divides the
logits by the raw temperature tensor and ops/flashinfer.py:216 hands it to the fused
softmax. The user got a request sampling from an undefined distribution rather than a
clear error at the API boundary.

The three checks are rewritten as negated range checks (not 0 <= top_p <= 1,
not 0 <= min_p <= 1, not temperature >= 0). This rejects NaN and leaves the accepted
set otherwise identical, with the existing error messages unchanged. It is also the form
the top_p_decay and top_p_min checks a few lines below already use — those two
consequently reject NaN today, which is what made the file inconsistent with itself.

Deliberately out of scope: temperature=float("inf") is still accepted. It flattens the
distribution rather than corrupting it, so rejecting it would be a behavior change to
input that currently works. #15715, which asks for very small non-zero temperatures to be
clamped, is likewise a separate discussion about valid input and is not addressed here.

No API signature changes; tests/unittest/api_stability is unaffected.

Test Coverage

tests/unittest/llmapi/test_sampling_params.py (CPU-only, no model weights):

  • test_sampling_params_rejects_nan — parametrized over top_p, min_p, temperature;
    each must raise ValueError. This is the regression guard: all three cases fail
    against main, where NaN is accepted, and pass with this change.
  • test_sampling_params_rejects_out_of_range — the previously covered rejections
    (-0.1, 1.1, temperature=-1.0) still raise, confirming the rewrite did not narrow
    the checks.
  • test_sampling_params_accepts_in_range_values — boundary and typical values (0.0,
    0.9, 1.0, 0.5, temperature=0.0, temperature=1.0) are still accepted and round
    trip unchanged.

Results: 16 cases, all passing on this branch. Against main with only the test changes
applied, exactly the 3 NaN cases fail and the other 13 pass, so the accepted set is
otherwise unchanged.

PR Checklist

Please review the following before submitting your PR:

  • PR description clearly explains what and why. If using CodeRabbit's summary, please make sure it makes sense.

  • PR Follows TRT-LLM CODING GUIDELINES to the best of your knowledge.

  • Test cases are provided for new code paths (see test instructions)

  • If PR introduces API changes, an appropriate PR label is added - either api-compatible or api-breaking. For api-breaking, include BREAKING in the PR title.

  • Any new dependencies have been scanned for license and vulnerabilities

  • CODEOWNERS updated if ownership changes

  • Documentation updated as needed

  • Update tava architecture diagram if there is a significant design change in PR.

  • The reviewers assigned automatically/manually are appropriate for the PR.

  • Please check this after reviewing the above items as appropriate for this PR.

GitHub Bot Help

To see a list of available CI bot commands, please comment /bot help.

Dev Engineer Review

  • SamplingParams._validate() now rejects NaN for top_p, min_p, and temperature.
  • Existing error messages and valid range behavior remain unchanged.
  • top_k validation is unchanged.
  • No public API changes are introduced.
  • The test-list entry uses the correct test path and does not expand test scope beyond the CPU-only unit test.

Verdict: sufficient

QA Engineer Review

  • Added coverage for:
    • NaN rejection for top_p, min_p, and temperature.
    • Existing out-of-range rejection.
    • Accepted boundary values.
    • Accepted representative in-range values.
  • The test file is registered in tests/integration/test_lists/test-db/l0_cpu.yml.
  • CI coverage is sufficient for the added regression tests.

Verdict: sufficient

Summary

  • Rejects NaN for top_p, min_p, and temperature in SamplingParams._validate().
  • Preserves existing validation errors and behavior for valid and previously rejected values.
  • Adds validation tests and registers them in the CPU test suite.
  • No public API changes.
  • Positive-infinite temperature and small-temperature clamping remain out of scope.

Dev Engineer Review

  • The negated range checks correctly reject NaN because comparisons with NaN evaluate to false.
  • top_k validation remains unchanged.
  • The change preserves valid boundary values and existing out-of-range behavior.
  • The CPU test registration uses the correct test path and has no unintended scope change.
  • No performance or API consistency concerns were identified.
  • Local tests, test-list AST validation, and pre-commit checks passed.
  • CI failed, but reported failures appeared related to shared pipeline or infrastructure issues.

QA Engineer Review

  • Added coverage for:
    • NaN rejection for top_p, min_p, and temperature.
    • Out-of-range values.
    • Boundary and representative valid values.
  • The test file is registered in tests/integration/test_lists/test-db/l0_cpu.yml.
  • The test coverage is included in the CPU CI suite.
  • Verdict: sufficient.

@Yigtwxx
Yigtwxx requested a review from a team as a code owner August 1, 2026 10:10
@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

SamplingParams._validate now uses negated range checks for top_p, min_p, and temperature. These checks reject NaN values while keeping existing boundary validation for normal values. New tests cover NaN rejection, out-of-range rejection, and valid value acceptance. The test file is added to the CPU test suite.

Changes

Sampling parameter validation

Layer / File(s) Summary
NaN rejection in range checks
tensorrt_llm/sampling_params.py
top_p and min_p checks use not 0 <= value <= 1 instead of value < 0 or value > 1. temperature check uses not self.temperature >= 0 instead of self.temperature < 0. Both forms reject NaN; top_k validation is unchanged.
Validation tests and CI wiring
tests/unittest/llmapi/test_sampling_params.py, tests/integration/test_lists/test-db/l0_cpu.yml
Parameterized tests confirm ValueError for NaN and out-of-range top_p, min_p, and temperature, and confirm acceptance of boundary and representative valid values. The CPU test list adds the new test file.

Estimated code review effort: 1 (Trivial) | ~5 minutes

Suggested reviewers: qijune, brnguyen2

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes satisfy [#17158] by rejecting NaN while preserving valid ranges, existing errors, and positive-infinite temperature support.
Out of Scope Changes check ✅ Passed All code, tests, and test-list updates directly support the linked issue and stated objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check ✅ Passed The title clearly identifies the fix, affected parameters, and issue number using the required format.
Description check ✅ Passed The description explains the issue, solution, scope, test coverage, and checklist status in sufficient detail.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/unittest/llmapi/test_sampling_params.py`:
- Around line 118-121: Add tests/unittest/llmapi/test_sampling_params.py to both
the CI test-db lists and the QA test lists, using the existing list conventions
and preserving the newly added SamplingParams coverage.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 613ef542-c6f1-435d-abf2-587812ac16e1

📥 Commits

Reviewing files that changed from the base of the PR and between a9544e0 and 73888bc.

📒 Files selected for processing (2)
  • tensorrt_llm/sampling_params.py
  • tests/unittest/llmapi/test_sampling_params.py

Comment thread tests/unittest/llmapi/test_sampling_params.py

@BowenFu BowenFu left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified the rewrite is exactly equivalent to the old checks for every non-NaN input, including the 0/1 boundaries and ±inf, so the only behavior change is that NaN now raises. test_sampling_params_accepts_in_range_values is the right guard against over-tightening.

Not blocking: tests/unittest/llmapi/test_sampling_params.py isn't in any test-db/ list, so these tests won't actually run in pre-merge L0. Worth registering.

@Yigtwxx

Yigtwxx commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

/bot run

@Yigtwxx

Yigtwxx commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

Could a maintainer trigger CI on this one with /bot run?

I posted /bot run yesterday but it didn't start a pipeline — I don't have write access on this repo, so the bot appears to ignore the command from me. The head commit 5fdb20a currently has DCO as its only check and no Jenkins status, which is what keeps the PR in a blocked state.

Everything else looks settled: the review feedback about registering the test module in the test lists was addressed in 5fdb20a (added to the # llmapi group of tests/integration/test_lists/test-db/l0_a10.yml) and confirmed resolved, and the PR has two approvals. Nothing is pending on my side.

The change is CPU-only and touches SamplingParams._validate() plus one test-list entry, so a standard /bot run should be sufficient.

@zhaoyangwang-nvidia

Copy link
Copy Markdown
Collaborator

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63699 [ run ] triggered by Bot. Commit: 5fdb20a Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63699 [ run ] completed with state FAILURE. Commit: 5fdb20a
/LLM/main/L0_MergeRequest_PR pipeline #51648 completed with status: 'FAILURE'

CI Report

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

CI Agent Failure Analysis

Link to invocation

@Yigtwxx

Yigtwxx commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for triggering CI @zhaoyangwang-nvidia. I can't open the failure report or the Jenkins job (both are on the internal network), so could you share which stage/test L0_MergeRequest_PR pipeline #51648 failed on?

Meanwhile, some evidence that suggests the failure isn't specific to this PR: in the 2026-08-03 → 2026-08-05 window, 13 of 13 completed L0_MergeRequest_PR pipelines failed across 5 unrelated PRs from 5 different authors (#17107, #17165, #17213, #17230, #16992), covering unrelated areas — flashinfer attention autotuner, Jenkins groovy, EXAONE config, Mamba cache + disagg transfer, CuTe DSL kernels. #17107 re-triggered the same commit (30fdacf) three times (#51616, #51669, #51713) and all three failed. The oldest red run I found is from 2026-07-29, so this looks like it predates my branch.

One thing worth noting for anyone skimming: in the tensorrt-cicd comments, PR_Github #NNNNN [ run ] completed with state SUCCESS refers to the outer helper job, not the pipeline — in 7 of those 13 cases the helper said SUCCESS while the L0_MergeRequest_PR pipeline line in the same comment said 'FAILURE'.

On this PR's side, the change is CPU-only: three comparisons in SamplingParams._validate() plus one test-list entry. I ran the new tests locally (17/17 pass), covering NaN rejection, out-of-range rejection, in-range acceptance, and that temperature=inf is still accepted. I also grepped tensorrt_llm/ and tests/ and found no call site that passes NaN to top_p/min_p/temperature, so the stricter check can only reject values that previously slipped through silently.

The branch is currently 58 commits behind main. Happy to rebase onto latest main and have CI re-triggered if that helps — just let me know.

Yigtwxx added 2 commits August 4, 2026 17:14
…ngParams

The range checks for these three parameters were written in positive form,
as `value < low or value > high`. Every comparison against NaN is False,
so NaN passed validation and reached the sampling backend, which applies
no guard of its own.

Rewrite the three checks as negated range checks, which rejects NaN while
leaving all other values unchanged. This is the form the neighbouring
top_p_decay and top_p_min checks already use.

Signed-off-by: Yigtwxx <yigiterdogan023@gmail.com>
…re-merge list

The module was absent from every test list, so none of its cases -- including
the NaN regression tests added in this branch -- ran in CI. Add it to the
llmapi group of the CPU pre-merge stage, alongside the other CPU-only llmapi
unit tests such as test_reasoning_parser.py. The tests need no GPU: they only
construct SamplingParams and assert on validation.

Signed-off-by: Yigtwxx <yigiterdogan023@gmail.com>
@Yigtwxx
Yigtwxx force-pushed the fix/sampling-params-non-finite branch from 5fdb20a to 30897c3 Compare August 4, 2026 14:17
@Yigtwxx

Yigtwxx commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

Rebased onto current main (fd0b4bb) — the branch had gone into a conflicting state. New head is 30897c3.

The conflict was only in the test-list file, and resolving it turned out to be a real change rather than a mechanical one: main has since split the CPU-only llmapi unit tests out of l0_a10.yml into the new l0_cpu.yml (test_llm_utils, test_gc_utils, test_reasoning_parser, test_serialization, test_utils, test_kv_cache_dtype_override, test_request_priority all moved). Since test_sampling_params.py is CPU-only — the tests just construct SamplingParams and assert on validation — the registration now goes in l0_cpu.yml instead, inserted alphabetically between test_request_priority.py and test_serialization.py. l0_a10.yml is left exactly as main has it. I updated the PR description accordingly.

sampling_params.py and the test file rebased cleanly; the fix itself is unchanged, and the comment it adds still holds — top_p_decay / top_p_min on current main still use the negated form.

Verified after the rebase: the new tests still pass locally (16 cases in the file), and pre-commit is clean on the diff, including the Validate test list entries exist in source files (AST) hook that checks the new l0_cpu.yml entry resolves.

Ready for /bot run whenever someone can trigger it. My earlier question still stands if the next run also fails — I can't see which stage failed, so I'd need that from whoever triggers it.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/integration/test_lists/test-db/l0_cpu.yml (1)

1-1: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add the required NVIDIA copyright header.

The supplied new file starts with version: 0.0.1 and has no NVIDIA copyright header. Add the repository-standard header before the YAML content.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/integration/test_lists/test-db/l0_cpu.yml` at line 1, Add the
repository-standard NVIDIA copyright header at the beginning of the YAML file,
before the existing version declaration; leave the version and remaining YAML
content unchanged.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@tests/integration/test_lists/test-db/l0_cpu.yml`:
- Line 1: Add the repository-standard NVIDIA copyright header at the beginning
of the YAML file, before the existing version declaration; leave the version and
remaining YAML content unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 70fbfe0a-265b-4ed5-acc1-568f33593077

📥 Commits

Reviewing files that changed from the base of the PR and between 5fdb20a and 30897c3.

📒 Files selected for processing (2)
  • tensorrt_llm/sampling_params.py
  • tests/integration/test_lists/test-db/l0_cpu.yml
🚧 Files skipped from review as they are similar to previous changes (1)
  • tensorrt_llm/sampling_params.py

@Yigtwxx

Yigtwxx commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai Re: the outside-diff finding on tests/integration/test_lists/test-db/l0_cpu.yml — not applying it. Two reasons:

  1. It is not a new file. GitHub reports it as status: modified, +1/-0; this PR's commit is index 3bb62ffd3b..5a1a08f2e1, a single added line (unittest/llmapi/test_sampling_params.py) in the existing # llmapi group. The file existed before this branch. l0_cpu_x86.yml and l0_cpu_arm.yml were consolidated into l0_cpu.yml upstream, not here — that is likely what made it look newly supplied.

  2. The header would break the convention, not restore it. 50 of the 51 files under tests/integration/test_lists/test-db/ start directly with version: 0.0.1 and carry no copyright header (l0_b200_perf_sanity.yml is the lone exception). There is also no insert-license hook in .pre-commit-config.yaml covering YAML. Adding a header to this one file as a side effect of a one-line test registration would be an unrelated, inconsistent change and out of scope for this PR.

Happy to be corrected if a maintainer wants headers rolled out across test-db/ — but that belongs in its own PR, not this one.

@Yigtwxx

Yigtwxx commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

@zhaoyangwang-nvidia — quick ping since you triggered the last run: the branch has been rebased onto current main (fd0b4bb), so the head is now 30897c3 and the earlier #63699 result on 5fdb20a no longer applies. 30897c3 has DCO as its only check.

Could you re-trigger /bot run when you get a chance? My own /bot run comments don't start a pipeline — I don't have write access here, so the bot ignores them.

And if this run also comes back red, could you paste which stage/test failed? The report and Jenkins links are internal-only, so I can't see them from outside.

No other blockers on my side: four approvals, review feedback addressed, and the CodeRabbit copyright-header finding answered above.

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

file='tests/integration/test_lists/test-db/l0_cpu.yml'

echo '--- changed files and status against base ---'
git diff --name-status "$(git merge-base HEAD origin/main)" HEAD -- "$file" || true

echo '--- diff for the test-list file ---'
git diff --unified=3 "$(git merge-base HEAD origin/main)" HEAD -- "$file" || true

echo '--- first line of each test-db YAML file ---'
fd --type f --extension yml . tests/integration/test_lists/test-db \
  | sort \
  | while IFS= read -r candidate; do
      printf '%s\t%s\n' "$(head -n 1 "$candidate")" "$candidate"
    done

echo '--- YAML license/header hook references ---'
rg -n -i -C2 'insert-license|license' .pre-commit-config.yaml || true

Length of output: 6350


@Yigtwxx You are correct. I verified the PR diff.

tests/integration/test_lists/test-db/l0_cpu.yml is modified, not added. The PR adds only unittest/llmapi/test_sampling_params.py.

The existing test-list convention does not require a copyright header. All other listed YAML files except l0_b200_perf_sanity.yml begin with version: 0.0.1. The pre-commit configuration has no YAML license-header hook.

I withdraw the finding.
🐇


✏️ Learnings added
Learnt from: Yigtwxx
URL: https://github.com/NVIDIA/TensorRT-LLM/pull/17159

Timestamp: 2026-08-04T14:36:05.460Z
Learning: In `tests/integration/test_lists/test-db/`, YAML test-list files normally start with `version: 0.0.1` and do not contain copyright headers. Do not request a copyright header for a modified test-list YAML file unless a repository-wide convention or applicable validation hook requires it. `tests/integration/test_lists/test-db/l0_b200_perf_sanity.yml` is an exception.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

You are interacting with an AI system.

@Yigtwxx

Yigtwxx commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

Correction to my earlier comment (#17159 (comment)): the "13 of 13 completed pipelines failed" figure in it is wrong. Retracting it, since I'd rather it not feed into anyone's triage.

I redid the count over a much larger sample — 70 PRs, every tensorrt-cicd comment between 2026-08-03 00:00Z and 2026-08-04 15:30Z — reading the inner L0_MergeRequest_PR pipeline #N completed with status: '...' line rather than the outer PR_Github #N [ run ] completed with state ... line (those two disagree, 25 times in this sample), and excluding [ skip ] invocations, which report success without running any tests:

Pipelines reporting a status 129
SUCCESS 24 (18.6%)
FAILURE 102
UNSTABLE 3
PRs that ran a pipeline 45
— with at least one green run 24
— never green 21

So L0_MergeRequest_PR is red for most runs in that window, but green is plainly reachable, and four of the five PRs I cited (#17107, #17165, #17213, #17230) did have green runs in the same window — #17213 in pipelines 63480 and 63757, for instance. My original number came from an ~8-PR sample, which is biased in an obvious way once pointed out: a failing PR gets re-run repeatedly and keeps appearing, while a passing one merges and drops out.

That removes the "this isn't specific to my PR" inference, so the ask stands on its own merits rather than on that claim:

@zhaoyangwang-nvidia — could you re-trigger /bot run when you have a moment? The branch was rebased onto fd0b4bb, so the head is now 30897c3 and the #63699 result on 5fdb20a no longer applies. And if the new run comes back red, could you paste which stage/test failed? The CI report and Jenkins links are internal-only, so I can't read them from outside.

@zhaoyangwang-nvidia

Copy link
Copy Markdown
Collaborator

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63869 [ run ] triggered by Bot. Commit: 30897c3 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63869 [ run ] completed with state SUCCESS. Commit: 30897c3
/LLM/main/L0_MergeRequest_PR pipeline #51808 completed with status: 'FAILURE'

CI Report

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

CI Agent Failure Analysis

Link to invocation

@zhaoyangwang-nvidia

Copy link
Copy Markdown
Collaborator

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63908 [ run ] triggered by Bot. Commit: 30897c3 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63908 [ run ] completed with state SUCCESS. Commit: 30897c3
/LLM/main/L0_MergeRequest_PR pipeline #51843 completed with status: 'SUCCESS'
Pipeline passed with automatic retried tests. Check the rerun report for details.

CI Report

Link to invocation

@zhaoyangwang-nvidia
zhaoyangwang-nvidia merged commit 7608520 into NVIDIA:main Aug 5, 2026
13 checks passed
@Yigtwxx
Yigtwxx deleted the fix/sampling-params-non-finite branch August 5, 2026 06:29
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.

[Bug]: SamplingParams accepts NaN for top_p, min_p and temperature

7 participants