Skip to content

[Bug]: trtllm-bench multi-turn acceptance statistics use only the last turn's decoding iterations #21519

Open

Description

@codebreaker77

System info

Current main b7a1594ba215e8000094dd9b857f146c76b56074.
The finding concerns CPU benchmark accounting, not model inference or kernel correctness.

Problem

LlmManager._process_multi_turn_request appends output tokens from every turn, but emits
PerfItemTuple(decoding_iteration=last_response.decoding_iter). StatsKeeper treats that field
as a zero-based index for the whole record, adding one to compute its iteration count.
The numerator therefore covers the whole conversation while the denominator covers only its last turn.

For two mocked, completed turns with (output tokens, decoding_iter) values (4, 1) and (6, 2):

Measurement Current Expected
Output tokens 10 10
Decoding iterations 3 5
Acceptance length 10 / 3 = 3.3333 10 / 5 = 2.0
Draft acceptance rate with max_draft_tokens=2 (10 - 3) / (2 * 3) = 1.1667 (10 - 5) / (2 * 5) = 0.5

This produces a draft acceptance rate above 100% without an invalid per-turn result.
The inputs describe a component reproduction; no actual model inference or end-to-end CLI run is claimed.

Reproduction and validation

Drive LlmManager.process_request with an InferenceRequest(turns=["q1", "q2"]), a mock tokenizer
returning fixed input IDs, and a mock LLM returning the two completed responses above.
Read the emitted outbox item and pass it to StatsKeeper.register_request_perf_item, then
generate_statistics_summary(max_draft_tokens=2, batch_size=1).

Locally, regression tests execute the current manager/keeper/request definitions extracted unchanged
from source, real Pydantic statistics models and stdlib asyncio, with the LLM/SamplingParams/PostprocParams
boundaries substituted. Three multi-turn cases fail on baseline and a single-turn control passes.
The proposed accumulation makes those four pass; six existing duration/cancellation/truncation
component tests also pass (10 total).

Normal package pytest collection is blocked in this Windows environment by missing native
tensorrt_llm/libs. Matching-build unit coverage and actual CLI/GPU integration remain unvalidated.

Proposed scope

Sum response.decoding_iter + 1 across completed turns, then store total_iterations - 1 in the
conversation's existing zero-based PerfItemTuple field. Keep single-turn behavior and deadline-truncated
conversation handling unchanged. Add regression coverage to the existing CPU-listed test_bench_async.py.

This fixes the iteration denominator only; it does not claim to redesign all multi-turn latency,
generation-token or request-count semantics.

The prepared regression cases and proposed fix are on the signed fork commit.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions