[VLM] Support request level max_dynamic_patch for OpenAI request (#16268)
Co-authored-by: luoyuan.luo <luoyuan.luo@antgroup.com>
This commit is contained in:
@@ -339,10 +339,14 @@ class ChatCompletionMessageContentTextPart(BaseModel):
|
||||
class ChatCompletionMessageContentImageURL(BaseModel):
|
||||
url: str
|
||||
detail: Optional[Literal["auto", "low", "high"]] = "auto"
|
||||
max_dynamic_patch: Optional[int] = None
|
||||
min_dynamic_patch: Optional[int] = None
|
||||
|
||||
|
||||
class ChatCompletionMessageContentVideoURL(BaseModel):
|
||||
url: str
|
||||
max_dynamic_patch: Optional[int] = None
|
||||
min_dynamic_patch: Optional[int] = None
|
||||
|
||||
|
||||
class ChatCompletionMessageContentAudioURL(BaseModel):
|
||||
@@ -516,6 +520,10 @@ class ChatCompletionRequest(BaseModel):
|
||||
stream_reasoning: bool = True
|
||||
chat_template_kwargs: Optional[Dict] = None
|
||||
|
||||
# SGLang multimodal tiling controls (extensions)
|
||||
max_dynamic_patch: Optional[int] = None
|
||||
min_dynamic_patch: Optional[int] = None
|
||||
|
||||
# Custom logit processor for advanced sampling control
|
||||
custom_logit_processor: Optional[Union[List[Optional[str]], str]] = None
|
||||
custom_params: Optional[Dict] = None
|
||||
|
||||
@@ -55,6 +55,32 @@ if TYPE_CHECKING:
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _extract_max_dynamic_patch(request: ChatCompletionRequest):
|
||||
img_vals = []
|
||||
vid_vals = []
|
||||
for msg in request.messages or []:
|
||||
content = getattr(msg, "content", None)
|
||||
if not isinstance(content, list):
|
||||
continue
|
||||
for part in content:
|
||||
# pydantic object or dict type
|
||||
if getattr(part, "type", None) == "image_url":
|
||||
iu = getattr(part, "image_url", None)
|
||||
mdp = getattr(iu, "max_dynamic_patch", None) if iu else None
|
||||
if mdp is not None:
|
||||
img_vals.append(int(mdp))
|
||||
elif getattr(part, "type", None) == "video_url":
|
||||
vu = getattr(part, "video_url", None)
|
||||
mdp = getattr(vu, "max_dynamic_patch", None) if vu else None
|
||||
if mdp is not None:
|
||||
vid_vals.append(int(mdp))
|
||||
|
||||
# TODO(yuan-luo): per-item max_dynamic_patch for both image and video
|
||||
img_max_dynamic_patch = min(img_vals) if img_vals else None
|
||||
vid_max_dynamic_patch = min(vid_vals) if vid_vals else None
|
||||
return img_max_dynamic_patch, vid_max_dynamic_patch
|
||||
|
||||
|
||||
class OpenAIServingChat(OpenAIServingBase):
|
||||
"""Handler for /v1/chat/completions requests"""
|
||||
|
||||
@@ -195,6 +221,9 @@ class OpenAIServingChat(OpenAIServingBase):
|
||||
if first_adapter:
|
||||
self._validate_lora_enabled(first_adapter)
|
||||
|
||||
img_max_dynamic_patch, vid_max_dynamic_patch = _extract_max_dynamic_patch(
|
||||
request
|
||||
)
|
||||
adapted_request = GenerateReqInput(
|
||||
**prompt_kwargs,
|
||||
image_data=processed_messages.image_data,
|
||||
@@ -219,6 +248,9 @@ class OpenAIServingChat(OpenAIServingBase):
|
||||
priority=request.priority,
|
||||
custom_labels=custom_labels,
|
||||
custom_logit_processor=request.custom_logit_processor,
|
||||
image_max_dynamic_patch=img_max_dynamic_patch,
|
||||
video_max_dynamic_patch=vid_max_dynamic_patch,
|
||||
max_dynamic_patch=getattr(request, "max_dynamic_patch", None),
|
||||
)
|
||||
|
||||
return adapted_request, request
|
||||
|
||||
Reference in New Issue
Block a user