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 11, 06:15 UTC
[ROCm][Bugfix] fix(structured_output): Skip guidance backend for schemas with patternProperties (#30730)
Signed-off-by: Andreas Karatzas <akaratza@amd.com>
Andreas Karatzas committed
Dec 18, 2025 at 01:04 UTC
be2ad5f92060b66788740e2e8302a490fbd226f4
2 files changed
+45
-2
vllm/v1/engine/input_processor.py
+19
-2
@@ -24,7 +24,10 @@ from vllm.tokenizers.mistral import MistralTokenizer
24
from vllm.utils import length_from_prompt_token_ids_or_embeds
25
from vllm.v1.engine import EngineCoreRequest
26
from vllm.v1.metrics.stats import MultiModalCacheStats
27
-from vllm.v1.structured_output.backend_guidance import validate_guidance_grammar
27
+from vllm.v1.structured_output.backend_guidance import (
28
+ has_guidance_unsupported_json_features,
29
+ validate_guidance_grammar,
30
+)
31
from vllm.v1.structured_output.backend_lm_format_enforcer import (
32
validate_structured_output_request_lm_format_enforcer,
33
)
@@ -340,8 +343,22 @@ class InputProcessor:
343
# The request either failed validation
344
# or includes some jsonschema feature(s) that
345
# are not supported in xgrammar.
343
- if isinstance(self.tokenizer, MistralTokenizer):
346
+
347
+ # Check if schema has features unsupported by guidance
348
+ so_params = params.structured_outputs
349
+ skip_guidance = False
350
+ if so_params.json:
351
+ if isinstance(so_params.json, str):
352
+ import json
353
+
354
+ schema = json.loads(so_params.json)
355
+ else:
356
+ schema = so_params.json
357
+ skip_guidance = has_guidance_unsupported_json_features(schema)
358
+
359
+ if isinstance(self.tokenizer, MistralTokenizer) or skip_guidance:
360
# Fall back to outlines if the tokenizer is Mistral
361
+ # or if schema contains features unsupported by guidance
362
validate_structured_output_request_outlines(params)
363
params.structured_outputs._backend = "outlines"
364
else:
vllm/v1/structured_output/backend_guidance.py
+26
@@ -44,6 +44,32 @@ def _walk_json_for_additional_properties(data: object):
44
_walk_json_for_additional_properties(item)
45
46
47
+def has_guidance_unsupported_json_features(schema: dict[str, Any]) -> bool:
48
+ """Check if JSON schema contains features unsupported by guidance/llguidance."""
49
+
50
+ def check_object(obj: dict[str, Any]) -> bool:
51
+ if not isinstance(obj, dict):
52
+ return False
53
+
54
+ # patternProperties is not supported by llguidance
55
+ if "patternProperties" in obj:
56
+ return True
57
+
58
+ # Recursively check all nested objects and arrays
59
+ for value in obj.values():
60
+ if isinstance(value, dict):
61
+ if check_object(value):
62
+ return True
63
+ elif isinstance(value, list):
64
+ for item in value:
65
+ if isinstance(item, dict) and check_object(item):
66
+ return True
67
+
68
+ return False
69
+
70
+ return check_object(schema)
71
+
72
+
73
def process_for_additional_properties(
74
guide_json: str | dict[str, Any],
75
) -> dict[str, Any]: