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 5, 18:30 UTC
[Feature]: add presence_penalty and frequency_penalty fields to Responses API (#38613)
Signed-off-by: chaunceyjiang <chaunceyjiang@gmail.com>
Chauncey committed
Mar 31, 2026 at 16:45 UTC
ce884756f062072ce7a8e36ae70b4f74e4fd79fd
1 file changed
+47
vllm/entrypoints/openai/responses/protocol.py
+47
@@ -173,6 +173,24 @@ class ResponsesRequest(OpenAIBaseModel):
173
user: str | None = None
174
skip_special_tokens: bool = True
175
include_stop_str_in_output: bool = False
176
+ presence_penalty: float | None = Field(
177
+ default=None,
178
+ ge=-2.0,
179
+ le=2.0,
180
+ description=(
181
+ "The presence penalty that was used to penalize new tokens based on "
182
+ "whether they appear in the text so far."
183
+ ),
184
+ )
185
+ frequency_penalty: float | None = Field(
186
+ default=None,
187
+ ge=-2.0,
188
+ le=2.0,
189
+ description=(
190
+ "The frequency penalty that was used to penalize new tokens based on "
191
+ "their frequency in the text so far."
192
+ ),
193
+ )
194
prompt_cache_key: str | None = Field(
195
default=None,
196
description=(
@@ -328,6 +346,12 @@ class ResponsesRequest(OpenAIBaseModel):
346
if (repetition_penalty := self.repetition_penalty) is None:
347
repetition_penalty = default_sampling_params.get("repetition_penalty", 1.0)
348
349
+ if (presence_penalty := self.presence_penalty) is None:
350
+ presence_penalty = default_sampling_params.get("presence_penalty", 0.0)
351
+
352
+ if (frequency_penalty := self.frequency_penalty) is None:
353
+ frequency_penalty = default_sampling_params.get("frequency_penalty", 0.0)
354
+
355
stop_token_ids = default_sampling_params.get("stop_token_ids")
356
357
# Structured output
@@ -367,6 +391,8 @@ class ResponsesRequest(OpenAIBaseModel):
391
logprobs=self.top_logprobs if self.is_include_output_logprobs() else None,
392
stop_token_ids=stop_token_ids,
393
stop=stop,
394
+ frequency_penalty=frequency_penalty,
395
+ presence_penalty=presence_penalty,
396
repetition_penalty=repetition_penalty,
397
seed=self.seed,
398
ignore_eos=self.ignore_eos,
@@ -496,6 +522,25 @@ class ResponsesResponse(OpenAIBaseModel):
522
usage: ResponseUsage | None = None
523
user: str | None = None
524
525
+ presence_penalty: float | None = Field(
526
+ default=None,
527
+ ge=-2.0,
528
+ le=2.0,
529
+ description=(
530
+ "The presence penalty that was used to penalize new tokens based on "
531
+ "whether they appear in the text so far."
532
+ ),
533
+ )
534
+ frequency_penalty: float | None = Field(
535
+ default=None,
536
+ ge=-2.0,
537
+ le=2.0,
538
+ description=(
539
+ "The frequency penalty that was used to penalize new tokens based on "
540
+ "their frequency in the text so far."
541
+ ),
542
+ )
543
+
544
# vLLM-specific fields that are not in OpenAI spec
545
kv_transfer_params: dict[str, Any] | None = Field(
546
default=None, description="KVTransfer parameters."
@@ -574,6 +619,8 @@ class ResponsesResponse(OpenAIBaseModel):
619
prompt=request.prompt,
620
reasoning=request.reasoning,
621
service_tier=request.service_tier,
622
+ presence_penalty=sampling_params.presence_penalty,
623
+ frequency_penalty=sampling_params.frequency_penalty,
624
status=status,
625
text=request.text,
626
top_logprobs=sampling_params.logprobs,