A high-throughput and memory-efficient inference and serving engine for LLMs
Mirrored from https://github.com/tduncan-lum/Nvidia-Optimization-Stack---VLLM.git
Synced Nov 10, 22:45 UTC
[Perf] Add skip_clone to SamplingParams for internal request handling (#31041)
Signed-off-by: mgoin <mgoin64@gmail.com>
Michael Goin committed
Dec 24, 2025 at 17:35 UTC
bc5ef333e09166e26ada29121804a207758c102e
5 files changed
+25
-2
vllm/entrypoints/api_server.py
+2
-1
@@ -60,7 +60,8 @@ async def generate(request: Request) -> Response:
60
async def _generate(request_dict: dict, raw_request: Request) -> Response:
61
prompt = request_dict.pop("prompt")
62
stream = request_dict.pop("stream", False)
63
- sampling_params = SamplingParams(**request_dict)
63
+ # Since SamplingParams is created fresh per request, safe to skip clone
64
+ sampling_params = SamplingParams(**request_dict, skip_clone=True)
65
request_id = random_uuid()
66
67
assert engine is not None
vllm/entrypoints/llm.py
+4
-1
@@ -642,7 +642,10 @@ class LLM:
642
# following the huggingface transformers implementation
643
# at https://github.com/huggingface/transformers/blob/e15687fffe5c9d20598a19aeab721ae0a7580f8a/src/transformers/generation/beam_search.py#L534 # noqa
644
beam_search_params = SamplingParams(
645
- logprobs=2 * beam_width, max_tokens=1, temperature=temperature
645
+ logprobs=2 * beam_width,
646
+ max_tokens=1,
647
+ temperature=temperature,
648
+ skip_clone=True, # Internal beam search, safe to skip clone
649
)
650
instances: list[BeamSearchInstance] = []
651
vllm/entrypoints/openai/protocol.py
+5
@@ -474,6 +474,7 @@ class ResponsesRequest(OpenAIBaseModel):
474
),
475
structured_outputs=structured_outputs,
476
logit_bias=self.logit_bias,
477
+ skip_clone=True, # Created fresh per request, safe to skip clone
478
)
479
480
def is_include_output_logprobs(self) -> bool:
@@ -876,6 +877,7 @@ class ChatCompletionRequest(OpenAIBaseModel):
877
bad_words=self.bad_words,
878
allowed_token_ids=self.allowed_token_ids,
879
extra_args=extra_args or None,
880
+ skip_clone=True, # Created fresh per request, safe to skip clone
881
)
882
883
@model_validator(mode="before")
@@ -1316,6 +1318,7 @@ class CompletionRequest(OpenAIBaseModel):
1318
logit_bias=self.logit_bias,
1319
allowed_token_ids=self.allowed_token_ids,
1320
extra_args=extra_args or None,
1321
+ skip_clone=True, # Created fresh per request, safe to skip clone
1322
)
1323
1324
@model_validator(mode="before")
@@ -2182,6 +2185,7 @@ class TranscriptionRequest(OpenAIBaseModel):
2185
if self.stream
2186
else RequestOutputKind.FINAL_ONLY,
2187
extra_args=self.vllm_xargs,
2188
+ skip_clone=True, # Created fresh per request, safe to skip clone
2189
)
2190
2191
@model_validator(mode="before")
@@ -2409,6 +2413,7 @@ class TranslationRequest(OpenAIBaseModel):
2413
output_kind=RequestOutputKind.DELTA
2414
if self.stream
2415
else RequestOutputKind.FINAL_ONLY,
2416
+ skip_clone=True, # Created fresh per request, safe to skip clone
2417
)
2418
2419
@model_validator(mode="before")
vllm/entrypoints/openai/speech_to_text.py
+1
@@ -219,6 +219,7 @@ class OpenAISpeechToText(OpenAIServing):
219
dummy_params = SamplingParams(
220
max_tokens=1,
221
temperature=0.0,
222
+ skip_clone=True, # Internal warmup, safe to skip clone
223
)
224
225
# Process the dummy input through the input processor
vllm/sampling_params.py
+13
@@ -211,6 +211,12 @@ class SamplingParams(
211
set to an integer k, will use only the last k tokens from the prompt
212
(i.e., left truncation). If set to `None`, truncation is disabled."""
213
output_kind: RequestOutputKind = RequestOutputKind.CUMULATIVE
214
+ skip_clone: bool = False
215
+ """Internal flag indicating that this SamplingParams instance is safe to
216
+ reuse without cloning. When True, clone() will return self without
217
+ performing a deep copy. This should only be set when the params object
218
+ is guaranteed to be dedicated to a single request and won't be modified
219
+ in ways that would affect other uses."""
220
221
# The below fields are not supposed to be used as an input.
222
# They are set in post_init.
@@ -270,6 +276,7 @@ class SamplingParams(
276
logit_bias: dict[int, float] | dict[str, float] | None = None,
277
allowed_token_ids: list[int] | None = None,
278
extra_args: dict[str, Any] | None = None,
279
+ skip_clone: bool = False,
280
) -> "SamplingParams":
281
if logit_bias is not None:
282
# Convert token_id to integer
@@ -310,6 +317,7 @@ class SamplingParams(
317
logit_bias=logit_bias,
318
allowed_token_ids=allowed_token_ids,
319
extra_args=extra_args,
320
+ skip_clone=skip_clone,
321
)
322
323
def __post_init__(self) -> None:
@@ -540,8 +548,13 @@ class SamplingParams(
548
data that is expensive to copy. However, if not copied, the processor
549
needs to support parallel decoding for multiple sequences
550
See https://github.com/vllm-project/vllm/issues/3087
551
+
552
+ If skip_clone is True, uses shallow copy instead of deep copy.
553
"""
554
555
+ if self.skip_clone:
556
+ return copy.copy(self)
557
+
558
logit_processor_refs = (
559
None
560
if self.logits_processors is None