Compare commits
7
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c2de222aa3 | ||
|
|
88d64448f4 | ||
|
|
aef79c52cc | ||
|
|
aeb03ccd3f | ||
|
|
0d556d62ad | ||
|
|
1337c7bea5 | ||
|
|
666d1381db |
@@ -1,6 +1,5 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
|
||||
import numpy as np
|
||||
import torch
|
||||
|
||||
from vllm.sampling_params import SamplingParams
|
||||
@@ -73,15 +72,10 @@ class BadWordsState:
|
||||
self,
|
||||
logits: torch.Tensor,
|
||||
expanded_idx_mapping: torch.Tensor,
|
||||
idx_mapping_np: np.ndarray,
|
||||
input_ids: torch.Tensor,
|
||||
expanded_local_pos: torch.Tensor,
|
||||
max_num_bad_words: int,
|
||||
) -> None:
|
||||
max_num_bad_words = int(self.num_bad_words.np[idx_mapping_np].max())
|
||||
if max_num_bad_words == 0:
|
||||
# No request uses bad words. Skip the kernel launch.
|
||||
return
|
||||
|
||||
apply_bad_words(
|
||||
logits,
|
||||
expanded_idx_mapping,
|
||||
|
||||
@@ -122,13 +122,8 @@ class LogitBiasState:
|
||||
self,
|
||||
logits: torch.Tensor,
|
||||
expanded_idx_mapping: torch.Tensor,
|
||||
idx_mapping_np: np.ndarray,
|
||||
pos: torch.Tensor,
|
||||
) -> None:
|
||||
if not np.any(self.use_logit_bias[idx_mapping_np]):
|
||||
# No request uses logit bias. Skip the kernel launch.
|
||||
return
|
||||
|
||||
apply_logit_bias(
|
||||
logits,
|
||||
expanded_idx_mapping,
|
||||
|
||||
@@ -82,14 +82,9 @@ class PenaltiesState:
|
||||
self,
|
||||
logits: torch.Tensor,
|
||||
expanded_idx_mapping: torch.Tensor,
|
||||
idx_mapping_np: np.ndarray,
|
||||
input_ids: torch.Tensor,
|
||||
expanded_local_pos: torch.Tensor,
|
||||
) -> None:
|
||||
if not np.any(self.use_penalty[idx_mapping_np]):
|
||||
# No request uses penalties. Skip the kernel launch.
|
||||
return
|
||||
|
||||
apply_penalties(
|
||||
logits,
|
||||
expanded_idx_mapping,
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
import numpy as np
|
||||
import torch
|
||||
|
||||
@@ -22,6 +24,34 @@ from vllm.v1.worker.gpu.sample.states import NO_LOGPROBS, SamplingStates
|
||||
from vllm.v1.worker.gpu.states import RequestState
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class _LogitsProcessingPlan:
|
||||
logit_bias: bool
|
||||
penalties: bool
|
||||
bad_words: bool
|
||||
temperature: bool
|
||||
min_p: bool
|
||||
top_k: bool
|
||||
top_p: bool
|
||||
max_num_bad_words: int
|
||||
|
||||
@property
|
||||
def requires_processing(self) -> bool:
|
||||
return (
|
||||
self.logit_bias
|
||||
or self.penalties
|
||||
or self.bad_words
|
||||
or self.temperature
|
||||
or self.min_p
|
||||
or self.top_k
|
||||
or self.top_p
|
||||
)
|
||||
|
||||
@property
|
||||
def top_k_top_p(self) -> bool:
|
||||
return self.top_k or self.top_p
|
||||
|
||||
|
||||
class Sampler:
|
||||
def __init__(
|
||||
self,
|
||||
@@ -62,6 +92,82 @@ class Sampler:
|
||||
self.bad_words_state.apply_staged_writes()
|
||||
self.logprob_token_ids_state.apply_staged_writes()
|
||||
|
||||
def _build_logits_processing_plan(
|
||||
self, idx_mapping_np: np.ndarray
|
||||
) -> _LogitsProcessingPlan:
|
||||
max_num_bad_words = int(
|
||||
self.bad_words_state.num_bad_words.np[idx_mapping_np].max()
|
||||
)
|
||||
temperature = self.sampling_states.temperature.np[idx_mapping_np]
|
||||
return _LogitsProcessingPlan(
|
||||
logit_bias=np.any(self.logit_bias_state.use_logit_bias[idx_mapping_np]),
|
||||
penalties=np.any(self.penalties_state.use_penalty[idx_mapping_np]),
|
||||
bad_words=max_num_bad_words > 0,
|
||||
temperature=not np.all((temperature == 0.0) | (temperature == 1.0)),
|
||||
min_p=np.any(self.sampling_states.min_p.np[idx_mapping_np] != 0.0),
|
||||
top_k=np.any(
|
||||
self.sampling_states.top_k.np[idx_mapping_np]
|
||||
!= self.sampling_states.vocab_size
|
||||
),
|
||||
top_p=np.any(self.sampling_states.top_p.np[idx_mapping_np] != 1.0),
|
||||
max_num_bad_words=max_num_bad_words,
|
||||
)
|
||||
|
||||
def _apply_logits_processing(
|
||||
self,
|
||||
logits: torch.Tensor,
|
||||
expanded_idx_mapping: torch.Tensor,
|
||||
plan: _LogitsProcessingPlan,
|
||||
pos: torch.Tensor,
|
||||
input_ids: torch.Tensor,
|
||||
expanded_local_pos: torch.Tensor,
|
||||
) -> torch.Tensor:
|
||||
# Apply logit bias (e.g., allowed_token_ids, min_tokens) in place.
|
||||
if plan.logit_bias:
|
||||
self.logit_bias_state.apply_logit_bias(
|
||||
logits,
|
||||
expanded_idx_mapping,
|
||||
pos,
|
||||
)
|
||||
|
||||
# Apply penalties in place.
|
||||
if plan.penalties:
|
||||
self.penalties_state.apply_penalties(
|
||||
logits,
|
||||
expanded_idx_mapping,
|
||||
input_ids,
|
||||
expanded_local_pos,
|
||||
)
|
||||
|
||||
# Apply bad words masking in place.
|
||||
if plan.bad_words:
|
||||
self.bad_words_state.apply_bad_words(
|
||||
logits,
|
||||
expanded_idx_mapping,
|
||||
input_ids,
|
||||
expanded_local_pos,
|
||||
plan.max_num_bad_words,
|
||||
)
|
||||
|
||||
# Apply temperature in place.
|
||||
if plan.temperature:
|
||||
self.sampling_states.apply_temperature(logits, expanded_idx_mapping)
|
||||
|
||||
# Apply min_p in place.
|
||||
if plan.min_p:
|
||||
self.sampling_states.apply_min_p(logits, expanded_idx_mapping)
|
||||
|
||||
# Apply top_k and/or top_p. This might or might not return a new tensor.
|
||||
if plan.top_k_top_p:
|
||||
logits = self.sampling_states.apply_top_k_top_p(
|
||||
logits,
|
||||
expanded_idx_mapping,
|
||||
plan.top_k,
|
||||
plan.top_p,
|
||||
)
|
||||
|
||||
return logits
|
||||
|
||||
def __call__(
|
||||
self,
|
||||
logits: torch.Tensor,
|
||||
@@ -129,44 +235,19 @@ class Sampler:
|
||||
input_ids: torch.Tensor,
|
||||
expanded_local_pos: torch.Tensor,
|
||||
) -> torch.Tensor:
|
||||
# Copy logits to a new FP32 tensor.
|
||||
logits = torch.empty_like(logits, dtype=torch.float32).copy_(logits)
|
||||
|
||||
# Apply logit bias (e.g., allowed_token_ids, min_tokens) in place.
|
||||
self.logit_bias_state.apply_logit_bias(
|
||||
logits, expanded_idx_mapping, idx_mapping_np, pos
|
||||
)
|
||||
|
||||
# Apply penalties in place.
|
||||
self.penalties_state.apply_penalties(
|
||||
logits,
|
||||
expanded_idx_mapping,
|
||||
idx_mapping_np,
|
||||
input_ids,
|
||||
expanded_local_pos,
|
||||
)
|
||||
|
||||
# Apply bad words masking in place.
|
||||
self.bad_words_state.apply_bad_words(
|
||||
logits,
|
||||
expanded_idx_mapping,
|
||||
idx_mapping_np,
|
||||
input_ids,
|
||||
expanded_local_pos,
|
||||
)
|
||||
|
||||
# Apply temperature in place.
|
||||
self.sampling_states.apply_temperature(
|
||||
logits, expanded_idx_mapping, idx_mapping_np
|
||||
)
|
||||
|
||||
# Apply min_p in place.
|
||||
self.sampling_states.apply_min_p(logits, expanded_idx_mapping, idx_mapping_np)
|
||||
|
||||
# Apply top_k and/or top_p. This might or might not return a new tensor.
|
||||
return self.sampling_states.apply_top_k_top_p(
|
||||
logits, expanded_idx_mapping, idx_mapping_np
|
||||
)
|
||||
processing_plan = self._build_logits_processing_plan(idx_mapping_np)
|
||||
if processing_plan.requires_processing:
|
||||
# Copy logits to a new FP32 tensor.
|
||||
logits = torch.empty_like(logits, dtype=torch.float32).copy_(logits)
|
||||
logits = self._apply_logits_processing(
|
||||
logits,
|
||||
expanded_idx_mapping,
|
||||
processing_plan,
|
||||
pos,
|
||||
input_ids,
|
||||
expanded_local_pos,
|
||||
)
|
||||
return logits
|
||||
|
||||
def sample(
|
||||
self,
|
||||
|
||||
@@ -65,34 +65,23 @@ class SamplingStates:
|
||||
self,
|
||||
logits: torch.Tensor,
|
||||
expanded_idx_mapping: torch.Tensor,
|
||||
idx_mapping_np: np.ndarray,
|
||||
) -> None:
|
||||
temp_np = self.temperature.np[idx_mapping_np]
|
||||
if np.all((temp_np == 0.0) | (temp_np == 1.0)):
|
||||
# No request requires temperature. Skip the kernel launch.
|
||||
return
|
||||
|
||||
apply_temperature(logits, expanded_idx_mapping, self.temperature.gpu)
|
||||
|
||||
def apply_min_p(
|
||||
self,
|
||||
logits: torch.Tensor,
|
||||
expanded_idx_mapping: torch.Tensor,
|
||||
idx_mapping_np: np.ndarray,
|
||||
) -> None:
|
||||
if np.all(self.min_p.np[idx_mapping_np] == 0.0):
|
||||
# No request uses min_p. Skip the kernel launch.
|
||||
return
|
||||
apply_min_p(logits, expanded_idx_mapping, self.min_p.gpu)
|
||||
|
||||
def apply_top_k_top_p(
|
||||
self,
|
||||
logits: torch.Tensor,
|
||||
expanded_idx_mapping: torch.Tensor,
|
||||
idx_mapping_np: np.ndarray,
|
||||
do_top_k: bool,
|
||||
do_top_p: bool,
|
||||
) -> torch.Tensor:
|
||||
do_top_k = np.any(self.top_k.np[idx_mapping_np] != self.vocab_size)
|
||||
do_top_p = np.any(self.top_p.np[idx_mapping_np] != 1.0)
|
||||
if not (do_top_k or do_top_p):
|
||||
return logits
|
||||
|
||||
|
||||
Reference in New Issue
Block a user