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 14, 05:30 UTC
Add backward compatibility for `guided_...` API (#25615)
Signed-off-by: Harry Mellor <19981378+hmellor@users.noreply.github.com> Signed-off-by: Cyrus Leung <cyrus.tl.leung@gmail.com> Co-authored-by: Cyrus Leung <cyrus.tl.leung@gmail.com>
Harry Mellor committed
Sep 25, 2025 at 12:45 UTC
70fbdb26e99d7d0b0299acc108f83bd63626e589
2 files changed
+133
-2
docs/features/structured_outputs.md
+11
@@ -6,6 +6,17 @@ vLLM supports the generation of structured outputs using
6
This document shows you some examples of the different options that are
7
available to generate structured outputs.
8
9
+!!! warning
10
+ If you are still using the following deprecated API fields, please update your code to use `structured_outputs` as demonstrated in the rest of this document:
11
+
12
+ - `guided_json` -> `{"structured_outputs": {"json": ...}}` or `StructuredOutputsParams(json=...)`
13
+ - `guided_regex` -> `{"structured_outputs": {"regex": ...}}` or `StructuredOutputsParams(regex=...)`
14
+ - `guided_choice` -> `{"structured_outputs": {"choice": ...}}` or `StructuredOutputsParams(choice=...)`
15
+ - `guided_grammar` -> `{"structured_outputs": {"grammar": ...}}` or `StructuredOutputsParams(grammar=...)`
16
+ - `guided_whitespace_pattern` -> `{"structured_outputs": {"whitespace_pattern": ...}}` or `StructuredOutputsParams(whitespace_pattern=...)`
17
+ - `structural_tag` -> `{"structured_outputs": {"structural_tag": ...}}` or `StructuredOutputsParams(structural_tag=...)`
18
+ - `guided_decoding_backend` -> Remove this field from your request
19
+
20
## Online Serving (OpenAI API)
21
22
You can generate structured outputs using the OpenAI's [Completions](https://platform.openai.com/docs/api-reference/completions) and [Chat](https://platform.openai.com/docs/api-reference/chat) API.
vllm/entrypoints/openai/protocol.py
+122
-2
@@ -541,6 +541,56 @@ class ChatCompletionRequest(OpenAIBaseModel):
541
default=None,
542
description="Additional kwargs for structured outputs",
543
)
544
+ guided_json: Optional[Union[str, dict, BaseModel]] = Field(
545
+ default=None,
546
+ description=(
547
+ "`guided_json` is deprecated. "
548
+ "This will be removed in v0.12.0 or v1.0.0, whichever is soonest. "
549
+ "Please pass `json` to `structured_outputs` instead."),
550
+ )
551
+ guided_regex: Optional[str] = Field(
552
+ default=None,
553
+ description=(
554
+ "`guided_regex` is deprecated. "
555
+ "This will be removed in v0.12.0 or v1.0.0, whichever is soonest. "
556
+ "Please pass `regex` to `structured_outputs` instead."),
557
+ )
558
+ guided_choice: Optional[list[str]] = Field(
559
+ default=None,
560
+ description=(
561
+ "`guided_choice` is deprecated. "
562
+ "This will be removed in v0.12.0 or v1.0.0, whichever is soonest. "
563
+ "Please pass `choice` to `structured_outputs` instead."),
564
+ )
565
+ guided_grammar: Optional[str] = Field(
566
+ default=None,
567
+ description=(
568
+ "`guided_grammar` is deprecated. "
569
+ "This will be removed in v0.12.0 or v1.0.0, whichever is soonest. "
570
+ "Please pass `grammar` to `structured_outputs` instead."),
571
+ )
572
+ structural_tag: Optional[str] = Field(
573
+ default=None,
574
+ description=(
575
+ "`structural_tag` is deprecated. "
576
+ "This will be removed in v0.12.0 or v1.0.0, whichever is soonest. "
577
+ "Please pass `structural_tag` to `structured_outputs` instead."),
578
+ )
579
+ guided_decoding_backend: Optional[str] = Field(
580
+ default=None,
581
+ description=(
582
+ "`guided_decoding_backend` is deprecated. "
583
+ "This will be removed in v0.12.0 or v1.0.0, whichever is soonest. "
584
+ "Please remove it from your request."),
585
+ )
586
+ guided_whitespace_pattern: Optional[str] = Field(
587
+ default=None,
588
+ description=(
589
+ "`guided_whitespace_pattern` is deprecated. "
590
+ "This will be removed in v0.12.0 or v1.0.0, whichever is soonest. "
591
+ "Please pass `whitespace_pattern` to `structured_outputs` instead."
592
+ ),
593
+ )
594
priority: int = Field(
595
default=0,
596
description=(
@@ -658,6 +708,20 @@ class ChatCompletionRequest(OpenAIBaseModel):
708
if prompt_logprobs is None and self.echo:
709
prompt_logprobs = self.top_logprobs
710
711
+ # Forward deprecated guided_* parameters to structured_outputs
712
+ if self.structured_outputs is None:
713
+ kwargs = dict[str, Any](
714
+ json=self.guided_json,
715
+ regex=self.guided_regex,
716
+ choice=self.guided_choice,
717
+ grammar=self.guided_grammar,
718
+ whitespace_pattern=self.guided_whitespace_pattern,
719
+ structural_tag=self.structural_tag,
720
+ )
721
+ kwargs = {k: v for k, v in kwargs.items() if v is not None}
722
+ if len(kwargs) > 0:
723
+ self.structured_outputs = StructuredOutputsParams(**kwargs)
724
+
725
response_format = self.response_format
726
json_schema_from_tool = self._get_json_schema_from_tool()
727
if response_format is not None or json_schema_from_tool is not None:
@@ -839,7 +903,7 @@ class ChatCompletionRequest(OpenAIBaseModel):
903
if isinstance(data, ValueError):
904
raise data
905
842
- if "structured_outputs" not in data:
906
+ if data.get("structured_outputs", None) is None:
907
return data
908
909
structured_outputs_kwargs = data['structured_outputs']
@@ -1016,6 +1080,49 @@ class CompletionRequest(OpenAIBaseModel):
1080
default=None,
1081
description="Additional kwargs for structured outputs",
1082
)
1083
+ guided_json: Optional[Union[str, dict, BaseModel]] = Field(
1084
+ default=None,
1085
+ description=(
1086
+ "`guided_json` is deprecated. "
1087
+ "This will be removed in v0.12.0 or v1.0.0, whichever is soonest. "
1088
+ "Please pass `json` to `structured_outputs` instead."),
1089
+ )
1090
+ guided_regex: Optional[str] = Field(
1091
+ default=None,
1092
+ description=(
1093
+ "`guided_regex` is deprecated. "
1094
+ "This will be removed in v0.12.0 or v1.0.0, whichever is soonest. "
1095
+ "Please pass `regex` to `structured_outputs` instead."),
1096
+ )
1097
+ guided_choice: Optional[list[str]] = Field(
1098
+ default=None,
1099
+ description=(
1100
+ "`guided_choice` is deprecated. "
1101
+ "This will be removed in v0.12.0 or v1.0.0, whichever is soonest. "
1102
+ "Please pass `choice` to `structured_outputs` instead."),
1103
+ )
1104
+ guided_grammar: Optional[str] = Field(
1105
+ default=None,
1106
+ description=(
1107
+ "`guided_grammar` is deprecated. "
1108
+ "This will be removed in v0.12.0 or v1.0.0, whichever is soonest. "
1109
+ "Please pass `grammar` to `structured_outputs` instead."),
1110
+ )
1111
+ guided_decoding_backend: Optional[str] = Field(
1112
+ default=None,
1113
+ description=(
1114
+ "`guided_decoding_backend` is deprecated. "
1115
+ "This will be removed in v0.12.0 or v1.0.0, whichever is soonest. "
1116
+ "Please remove it from your request."),
1117
+ )
1118
+ guided_whitespace_pattern: Optional[str] = Field(
1119
+ default=None,
1120
+ description=(
1121
+ "`guided_whitespace_pattern` is deprecated. "
1122
+ "This will be removed in v0.12.0 or v1.0.0, whichever is soonest. "
1123
+ "Please pass `whitespace_pattern` to `structured_outputs` instead."
1124
+ ),
1125
+ )
1126
priority: int = Field(
1127
default=0,
1128
description=(
@@ -1145,6 +1252,19 @@ class CompletionRequest(OpenAIBaseModel):
1252
1253
echo_without_generation = self.echo and self.max_tokens == 0
1254
1255
+ # Forward deprecated guided_* parameters to structured_outputs
1256
+ if self.structured_outputs is None:
1257
+ kwargs = dict[str, Any](
1258
+ json=self.guided_json,
1259
+ regex=self.guided_regex,
1260
+ choice=self.guided_choice,
1261
+ grammar=self.guided_grammar,
1262
+ whitespace_pattern=self.guided_whitespace_pattern,
1263
+ )
1264
+ kwargs = {k: v for k, v in kwargs.items() if v is not None}
1265
+ if len(kwargs) > 0:
1266
+ self.structured_outputs = StructuredOutputsParams(**kwargs)
1267
+
1268
if (self.structured_outputs is not None
1269
and self.response_format is not None
1270
and self.response_format.type == "json_object"):
@@ -1189,7 +1309,7 @@ class CompletionRequest(OpenAIBaseModel):
1309
@model_validator(mode="before")
1310
@classmethod
1311
def check_structured_outputs_count(cls, data):
1192
- if "structured_outputs" not in data:
1312
+ if data.get("structured_outputs", None) is None:
1313
return data
1314
1315
structured_outputs_kwargs = data['structured_outputs']