VLM: support passing --mm-process-config for all models (#18467)
This commit is contained in:
@@ -184,6 +184,11 @@ class BaseMultimodalProcessor(ABC):
|
||||
self.server_args = server_args
|
||||
self.transport_mode = transport_mode
|
||||
|
||||
mm_process_config = self.server_args.mm_process_config
|
||||
self.image_config = mm_process_config.get("image", {})
|
||||
self.video_config = mm_process_config.get("video", {})
|
||||
self.audio_config = mm_process_config.get("audio", {})
|
||||
|
||||
# Resolve tokenizer: some processors (e.g. InternVL) pass a tokenizer
|
||||
# directly as _processor rather than a processor that wraps a tokenizer.
|
||||
if hasattr(self._processor, "tokenizer"):
|
||||
@@ -381,8 +386,12 @@ class BaseMultimodalProcessor(ABC):
|
||||
"""
|
||||
if images:
|
||||
kwargs["images"] = images
|
||||
if self.image_config:
|
||||
kwargs.setdefault("images_kwargs", {}).update(self.image_config)
|
||||
if videos:
|
||||
kwargs["videos"] = videos
|
||||
if self.video_config:
|
||||
kwargs.setdefault("videos_kwargs", {}).update(self.video_config)
|
||||
if audios:
|
||||
if self._processor.__class__.__name__ in {
|
||||
"Gemma3nProcessor",
|
||||
@@ -394,10 +403,12 @@ class BaseMultimodalProcessor(ABC):
|
||||
}:
|
||||
# Note(Xinyuan): for gemma3n, ref: https://github.com/huggingface/transformers/blob/ccf2ca162e33f381e454cdb74bf4b41a51ab976d/src/transformers/models/gemma3n/processing_gemma3n.py#L107
|
||||
kwargs["audio"] = audios
|
||||
kwargs["audio_kwargs"] = {}
|
||||
kwargs.setdefault("audio_kwargs", {})
|
||||
kwargs["audio_kwargs"].setdefault("truncation", False)
|
||||
else:
|
||||
kwargs["audios"] = audios
|
||||
if self.audio_config:
|
||||
kwargs.setdefault("audio_kwargs", {}).update(self.audio_config)
|
||||
|
||||
processor = self._processor
|
||||
if (
|
||||
|
||||
@@ -292,8 +292,12 @@ class Ernie4_5_VLImageProcessor(SGLangBaseProcessor):
|
||||
"""
|
||||
if images:
|
||||
kwargs["images"] = images
|
||||
if self.image_config:
|
||||
kwargs.setdefault("images_kwargs", {}).update(self.image_config)
|
||||
if videos:
|
||||
kwargs["videos"] = videos
|
||||
if self.video_config:
|
||||
kwargs.setdefault("videos_kwargs", {}).update(self.video_config)
|
||||
|
||||
processor = self._processor
|
||||
if (
|
||||
|
||||
@@ -57,8 +57,10 @@ class MiDashengLMMultimodalProcessor(BaseMultimodalProcessor):
|
||||
kwargs["videos"] = videos
|
||||
if audios:
|
||||
kwargs["audio"] = audios
|
||||
kwargs["audio_kwargs"] = {}
|
||||
kwargs.setdefault("audio_kwargs", {})
|
||||
kwargs["audio_kwargs"].setdefault("truncation", False)
|
||||
if self.audio_config:
|
||||
kwargs["audio_kwargs"].update(self.audio_config)
|
||||
|
||||
processor = self._processor
|
||||
result = processor.__call__(
|
||||
|
||||
@@ -267,9 +267,6 @@ class QwenVLImageProcessor(SGLangBaseProcessor):
|
||||
self.audio_start_token_id = getattr(hf_config, "audio_start_token_id", None)
|
||||
self.audio_token_id = getattr(hf_config, "audio_token_id", None)
|
||||
|
||||
self.image_config = server_args.mm_process_config.get("image", {})
|
||||
self.video_config = server_args.mm_process_config.get("video", {})
|
||||
|
||||
self.mm_tokens = MultimodalSpecialTokens(
|
||||
image_token="<|vision_start|><|image_pad|><|vision_end|>",
|
||||
image_token_id=hf_config.image_token_id,
|
||||
|
||||
@@ -762,6 +762,8 @@ class ServerArgs:
|
||||
# Normalize load balancing defaults early (before dummy-model short-circuit).
|
||||
self._handle_load_balance_method()
|
||||
|
||||
# Validate mm_process_config before dummy-model early return.
|
||||
self._handle_multimodal()
|
||||
# Validate SSL arguments early (before dummy-model short-circuit).
|
||||
self._handle_ssl_validation()
|
||||
|
||||
@@ -938,18 +940,37 @@ class ServerArgs:
|
||||
"--enable-http2 requires the 'granian' package. "
|
||||
'Install it with: pip install "sglang[http2]"'
|
||||
)
|
||||
|
||||
if self.enable_ssl_refresh:
|
||||
raise ValueError(
|
||||
"--enable-ssl-refresh is not supported with --enable-http2. "
|
||||
"Granian does not support SSL certificate hot-reloading. "
|
||||
"Use Uvicorn (the default) or handle certificate rotation externally."
|
||||
)
|
||||
|
||||
if self.tokenizer_worker_num > 1:
|
||||
raise ValueError(
|
||||
"--enable-http2 does not yet support --tokenizer-worker-num > 1. "
|
||||
"Multi-worker HTTP/2 support will be added in a future release."
|
||||
)
|
||||
|
||||
def _handle_multimodal(self):
|
||||
"""Validate mm_process_config structure before model loading."""
|
||||
if self.mm_process_config is not None:
|
||||
if not isinstance(self.mm_process_config, dict):
|
||||
raise TypeError(
|
||||
f"mm_process_config must be a dict, "
|
||||
f"but got {type(self.mm_process_config)}"
|
||||
)
|
||||
for key in ("image", "video", "audio"):
|
||||
if key in self.mm_process_config and not isinstance(
|
||||
self.mm_process_config[key], dict
|
||||
):
|
||||
raise TypeError(
|
||||
f"mm_process_config['{key}'] must be a dict, "
|
||||
f"but got {type(self.mm_process_config[key])}"
|
||||
)
|
||||
|
||||
def _handle_deprecated_args(self):
|
||||
# Handle deprecated tool call parsers
|
||||
deprecated_tool_call_parsers = {"qwen25": "qwen", "glm45": "glm"}
|
||||
|
||||
Reference in New Issue
Block a user