@tduncan / Nvidia-Optimization-Stack-VLLM Mirror · read-only / commits / ce884756f0
Fork 0

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,