-
-
Notifications
You must be signed in to change notification settings - Fork 19.1k
[Bugfix][V1/V2] Fix prompt_logprobs to respect logprobs_mode #47680
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,16 +5,18 @@ | |
| import numpy as np | ||
| import torch | ||
|
|
||
| from vllm.config.model import LogprobsMode | ||
| from vllm.sampling_params import SamplingParams | ||
| from vllm.triton_utils import tl, triton | ||
| from vllm.v1.outputs import LogprobsTensors | ||
| from vllm.v1.worker.gpu.input_batch import InputBatch | ||
| from vllm.v1.worker.gpu.sample.logprob import compute_topk_logprobs | ||
| from vllm.v1.worker.gpu.sample.logprob import compute_topk_scores | ||
|
|
||
|
|
||
| class PromptLogprobsWorker: | ||
| def __init__(self, max_num_reqs: int): | ||
| def __init__(self, max_num_reqs: int, logprobs_mode: LogprobsMode = "raw_logprobs"): | ||
| self.max_num_reqs = max_num_reqs | ||
| self.logprobs_mode = logprobs_mode | ||
|
|
||
| self.uses_prompt_logprobs = np.zeros(self.max_num_reqs, dtype=bool) | ||
| self.num_prompt_logprobs = np.zeros(self.max_num_reqs, dtype=np.int32) | ||
|
|
@@ -82,6 +84,7 @@ def compute_prompt_logprobs( | |
| hidden_states[: input_batch.num_tokens], | ||
| logits_fn, | ||
| max_num_prompt_logprobs, | ||
| self.logprobs_mode, | ||
| ) | ||
| ) | ||
|
|
||
|
|
@@ -206,33 +209,36 @@ def compute_prompt_logprobs_with_chunking( | |
| prompt_hidden_states: torch.Tensor, | ||
| logits_fn: Callable[[torch.Tensor], torch.Tensor], | ||
| num_prompt_logprobs: int, | ||
| logprobs_mode: LogprobsMode = "raw_logprobs", | ||
| ) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor]: | ||
| # Since materializing the full prompt logits can take too much memory, | ||
| # we compute it in chunks. | ||
| CHUNK_SIZE = 1024 | ||
| token_ids = [] | ||
| logprobs = [] | ||
| scores = [] | ||
| ranks = [] | ||
| logits_mode = logprobs_mode in ("raw_logits", "processed_logits") | ||
| prompt_token_ids = prompt_token_ids.to(torch.int64) | ||
| for start_idx in range(0, prompt_token_ids.shape[0], CHUNK_SIZE): | ||
| end_idx = start_idx + CHUNK_SIZE | ||
| # NOTE(woosuk): logits_fn can be slow because it involves all-gather. | ||
| prompt_logits = logits_fn(prompt_hidden_states[start_idx:end_idx]) | ||
| requested_num_prompt_logprobs = ( | ||
| requested_num = ( | ||
| prompt_logits.shape[-1] | ||
| if num_prompt_logprobs == -1 | ||
| else num_prompt_logprobs | ||
| ) | ||
| prompt_logprobs = compute_topk_logprobs( | ||
| result = compute_topk_scores( | ||
| prompt_logits, | ||
| requested_num_prompt_logprobs, | ||
| requested_num, | ||
| prompt_token_ids[start_idx:end_idx], | ||
| logits_mode=logits_mode, | ||
|
Comment on lines
+231
to
+235
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When a request uses Useful? React with 👍 / 👎. |
||
| ) | ||
| token_ids.append(prompt_logprobs.logprob_token_ids) | ||
| logprobs.append(prompt_logprobs.logprobs) | ||
| ranks.append(prompt_logprobs.selected_token_ranks) | ||
| token_ids.append(result.logprob_token_ids) | ||
| scores.append(result.logprobs) | ||
| ranks.append(result.selected_token_ranks) | ||
|
|
||
| token_ids = torch.cat(token_ids, dim=0) if len(token_ids) > 1 else token_ids[0] | ||
| logprobs = torch.cat(logprobs, dim=0) if len(logprobs) > 1 else logprobs[0] | ||
| scores = torch.cat(scores, dim=0) if len(scores) > 1 else scores[0] | ||
| ranks = torch.cat(ranks, dim=0) if len(ranks) > 1 else ranks[0] | ||
| return token_ids, logprobs, ranks | ||
| return token_ids, scores, ranks | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5593,10 +5593,15 @@ def _get_prompt_logprobs_dict( | |
| # to gather the logprob for. | ||
| tgt_token_ids = prompt_token_ids[start_tok : start_tok + num_logits] | ||
|
|
||
| # Compute prompt logprobs. | ||
| logprobs = self.sampler.compute_logprobs(logits) | ||
| # Compute prompt scores respecting logprobs_mode. | ||
| # NOTE: prompt tokens skip sampling processors, so | ||
| # processed_* and raw_* yield the same scores here. | ||
| if self.model_config.logprobs_mode in ("raw_logits", "processed_logits"): | ||
| scores = logits.to(torch.float32) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since both runners return raw unprocessed logits for processed_logits maybe worth to flag it somehow in the code/docstring or in the comments. |
||
| else: | ||
| scores = self.sampler.compute_logprobs(logits) | ||
| token_ids, logprobs, ranks, _ = self.sampler.gather_logprobs( | ||
| logprobs, num_prompt_logprobs, tgt_token_ids | ||
| scores, num_prompt_logprobs, tgt_token_ids | ||
| ) | ||
|
|
||
| # Transfer GPU->CPU async. | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When
logprobs_modeisprocessed_logitsorprocessed_logprobs, this path still feeds the unprocessedprompt_logitsdirectly intocompute_topk_scores; the new flag only switches between returning logits andlog_softmax. SinceModelConfig.logprobs_modedocuments processed modes forprompt_logprobsas after processors such as logit bias, bad words, temperature, and top_k/top_p, V2 requests withprompt_logprobsplus any such sampling processor will now be accepted but return the same raw prompt scores as the raw modes.Useful? React with 👍 / 👎.