From ffeb28ba6fb79407ce2d6cb94e9839855952c492 Mon Sep 17 00:00:00 2001 From: SijiaYang Date: Wed, 12 Nov 2025 18:08:40 +0800 Subject: [PATCH] fix: duplicate resize images logic of qwen-vl series models (#12458) Signed-off-by: yangsijia.614 --- .../srt/multimodal/processors/dots_vlm.py | 16 -------- .../multimodal/processors/points_v15_chat.py | 12 +----- .../srt/multimodal/processors/qwen_vl.py | 40 ------------------- 3 files changed, 1 insertion(+), 67 deletions(-) diff --git a/python/sglang/srt/multimodal/processors/dots_vlm.py b/python/sglang/srt/multimodal/processors/dots_vlm.py index 5f095d150..65752244d 100644 --- a/python/sglang/srt/multimodal/processors/dots_vlm.py +++ b/python/sglang/srt/multimodal/processors/dots_vlm.py @@ -1,16 +1,12 @@ -import asyncio import re from typing import Dict, List, Union -from PIL import Image - from sglang.srt.models.dots_ocr import DotsOCRForCausalLM from sglang.srt.models.dots_vlm import DotsVLMForCausalLM from sglang.srt.multimodal.processors.base_processor import ( BaseMultimodalProcessor, MultimodalSpecialTokens, ) -from sglang.srt.multimodal.processors.qwen_vl import resize_image_async class DotsVLMImageProcessor(BaseMultimodalProcessor): @@ -70,18 +66,6 @@ class DotsVLMImageProcessor(BaseMultimodalProcessor): multimodal_tokens=self.mm_tokens, ) - # Qwen-specific: resize images if they are raw Image objects - if base_output.images and isinstance(base_output.images[0], Image.Image): - resize_tasks = [ - resize_image_async( - image, - min_pixels=self.MIN_PIXELS, - max_pixels=self.MAX_PIXELS, - size_factor=self.IMAGE_FACTOR, - ) - for image in base_output.images - ] - base_output.images = await asyncio.gather(*resize_tasks) combined_mm_item, input_ids, _ = self.process_and_combine_mm_data( base_output, self.mm_tokens ) diff --git a/python/sglang/srt/multimodal/processors/points_v15_chat.py b/python/sglang/srt/multimodal/processors/points_v15_chat.py index 7acc1eee9..be23c28db 100644 --- a/python/sglang/srt/multimodal/processors/points_v15_chat.py +++ b/python/sglang/srt/multimodal/processors/points_v15_chat.py @@ -1,15 +1,9 @@ # Copy from qwen_vl.py, adapted for points-v15-chat -import asyncio from typing import List, Union -from PIL import Image - from sglang.srt.models.points_v15_chat import POINTSV15ChatModel -from sglang.srt.multimodal.processors.qwen_vl import ( - QwenVLImageProcessor, - resize_image_async, -) +from sglang.srt.multimodal.processors.qwen_vl import QwenVLImageProcessor class POINTSV15ChatProcessor(QwenVLImageProcessor): @@ -37,10 +31,6 @@ class POINTSV15ChatProcessor(QwenVLImageProcessor): multimodal_tokens=self.mm_tokens, ) - if base_output.images and isinstance(base_output.images[0], Image.Image): - resize_tasks = [resize_image_async(image) for image in base_output.images] - base_output.images = await asyncio.gather(*resize_tasks) - mm_items, input_ids, _ = self.process_and_combine_mm_data( base_output, self.mm_tokens ) diff --git a/python/sglang/srt/multimodal/processors/qwen_vl.py b/python/sglang/srt/multimodal/processors/qwen_vl.py index 1e50a4ca4..1f91993e7 100644 --- a/python/sglang/srt/multimodal/processors/qwen_vl.py +++ b/python/sglang/srt/multimodal/processors/qwen_vl.py @@ -1,4 +1,3 @@ -import asyncio import math import os import re @@ -79,26 +78,6 @@ def smart_resize( return h_bar, w_bar -def resize_image( - image, - min_pixels: int = MIN_PIXELS, - max_pixels: int = MAX_PIXELS, - size_factor: int = IMAGE_FACTOR, -) -> Image.Image: - width, height = image.size - min_pixels = min_pixels - max_pixels = max_pixels - resized_height, resized_width = smart_resize( - height, - width, - factor=size_factor, - min_pixels=min_pixels, - max_pixels=max_pixels, - ) - image = image.resize((resized_width, resized_height), resample=RESIZE_RESAMPLE) - return image - - def round_by_factor(number: int, factor: int) -> int: """Returns the closest integer to 'number' that is divisible by 'factor'.""" return round(number / factor) * factor @@ -114,15 +93,6 @@ def floor_by_factor(number: int, factor: int) -> int: return math.floor(number / factor) * factor -async def resize_image_async( - image, - min_pixels: int = MIN_PIXELS, - max_pixels: int = MAX_PIXELS, - size_factor: int = IMAGE_FACTOR, -): - return resize_image(image, min_pixels, max_pixels, size_factor) - - def smart_nframes( ele: dict, total_frames: int, @@ -266,11 +236,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.NUM_TOKEN_PER_FRAME = 770 - self.IMAGE_FACTOR = 28 - self.MIN_PIXELS = 4 * 28 * 28 - self.MAX_PIXELS = 16384 * 28 * 28 - self.MAX_RATIO = 200 self.mm_tokens = MultimodalSpecialTokens( image_token="<|vision_start|><|image_pad|><|vision_end|>", image_token_id=hf_config.image_token_id, @@ -301,11 +266,6 @@ class QwenVLImageProcessor(SGLangBaseProcessor): load_time = time.perf_counter() rid = getattr(request_obj, "rid", "anonymous_rid") - # Qwen-specific: resize images if they are raw Image objects - if base_output.images and isinstance(base_output.images[0], Image.Image): - resize_tasks = [resize_image_async(image) for image in base_output.images] - base_output.images = await asyncio.gather(*resize_tasks) - video_metadata = None if base_output.videos: videos_processed = [