Skip to content

logprobs=-1 crashes the engine: the sampler's raw-vocab shape is read as the gathered one #231

Description

@localai-bot

logprobs=-1 ("give me every vocab entry") is accepted by SamplingParams and
reaches the sampler, which takes a different tensor shape for it than for any
logprobs=k — and the engine-side consumer reads that shape out of bounds.

Where it breaks

src/vllm/v1/sample/sampler.cpp:344-352 — for num_logprobs == -1 the sampler
builds a LogprobsTensors that carries ONLY logprobs (the raw [n, vocab]
block), leaving logprob_token_ids and selected_token_ranks empty, with
num_tokens_per_position = vocab:

LogprobsTensors lt;
lt.num_positions = static_cast<int>(n);
lt.num_tokens_per_position = static_cast<int>(vocab);
lt.logprobs = raw_logprobs;          // ids + ranks deliberately left empty
logprobs_tensors = std::move(lt);

src/vllm/v1/engine/logprobs.cpp:51-73 (UpdateSampleLogprobs) then indexes all
three arrays for every position:

const int width = lists.num_tokens_per_position;
if (width <= 0) return;              // the only guard -- vocab is > 0, so it passes
const int32_t* id_row = &lists.logprob_token_ids[base];      // EMPTY -> OOB
const int rank = lists.selected_token_ranks[pos];            // EMPTY -> OOB

The guard at :55 says "the num_logprobs==-1 raw-vocab shape is not wired", but
it only catches width <= 0, which this shape never is.

Repro

Any request through the engine with SamplingParams::logprobs = -1:

SamplingParams sp;  sp.temperature = 0.0;  sp.max_tokens = 1;
sp.logprobs = -1;
engine.generate(prompt_token_ids, sp, "req");   // SIGSEGV

Observed as SIGSEGV in test_llm_engine while writing the gate for
#223; the -1 prompt-logprobs
path is unaffected (the runner widens -1 to vocab_size before gathering, so it
produces the ordinary k+1 shape).

Expected

vLLM's sampling_params.py treats logprobs=-1 as "all logprobs" and
gpu_input_batch.py:435-440 stores vocab_size, so the sampler produces the
same [n, vocab+1] gathered shape as any other k and nothing downstream needs a
special case. Either mirror that (widen at admission, drop the special shape) or
teach UpdateSampleLogprobs the raw shape. The first is what upstream does.

Row: SAMPLE-LOGPROBS / SAMPLE-LOGPROB-TOKEN-IDS (.agents/engine-matrix.md:131,133).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions