chore: add an unified server arg for multimodal inputs preprocess config(#12149)
Co-authored-by: bianfeng <bianfeng@pinduoduo.com> Co-authored-by: Xinyuan Tong <115166877+JustinTong0323@users.noreply.github.com>
This commit is contained in:
@@ -145,37 +145,44 @@ def smart_nframes(
|
||||
async def preprocess_video(
|
||||
vr,
|
||||
image_factor: int = IMAGE_FACTOR,
|
||||
# vr: VideoReader, image_factor: int = IMAGE_FACTOR
|
||||
video_config: dict = {},
|
||||
) -> torch.Tensor:
|
||||
entry_time = time.perf_counter()
|
||||
ele = {}
|
||||
|
||||
total_frames, video_fps = len(vr), vr.get_avg_fps()
|
||||
nframes = smart_nframes({}, total_frames=total_frames, video_fps=video_fps)
|
||||
nframes = smart_nframes(
|
||||
video_config, total_frames=total_frames, video_fps=video_fps
|
||||
)
|
||||
idx = np.linspace(0, total_frames - 1, num=nframes, dtype=np.int64)
|
||||
idx = np.unique(idx)
|
||||
video_np = vr.get_batch(idx).asnumpy()
|
||||
video = torch.from_numpy(video_np).pin_memory()
|
||||
video = video.permute(0, 3, 1, 2) # Convert to TCHW format
|
||||
|
||||
nframes, _, height, width = video.shape
|
||||
min_pixels = ele.get("min_pixels", VIDEO_MIN_PIXELS)
|
||||
total_pixels = ele.get("total_pixels", VIDEO_TOTAL_PIXELS)
|
||||
min_pixels = video_config.get("min_pixels", VIDEO_MIN_PIXELS)
|
||||
total_pixels = video_config.get("total_pixels", VIDEO_TOTAL_PIXELS)
|
||||
max_pixels = max(
|
||||
min(VIDEO_MAX_PIXELS, total_pixels / nframes * FRAME_FACTOR),
|
||||
min(
|
||||
video_config.get("max_pixels", VIDEO_MAX_PIXELS),
|
||||
total_pixels / nframes * FRAME_FACTOR,
|
||||
),
|
||||
int(min_pixels * 1.05),
|
||||
)
|
||||
|
||||
get_batch_time = time.perf_counter()
|
||||
|
||||
max_pixels_supposed = ele.get("max_pixels", max_pixels)
|
||||
max_pixels_supposed = video_config.get("max_pixels", max_pixels)
|
||||
|
||||
if max_pixels_supposed > max_pixels:
|
||||
logger.warning(
|
||||
f"The given max_pixels[{max_pixels_supposed}] exceeds limit[{max_pixels}]."
|
||||
)
|
||||
max_pixels = min(max_pixels_supposed, max_pixels)
|
||||
if "resized_height" in ele and "resized_width" in ele:
|
||||
if "resized_height" in video_config and "resized_width" in video_config:
|
||||
resized_height, resized_width = smart_resize(
|
||||
ele["resized_height"],
|
||||
ele["resized_width"],
|
||||
video_config["resized_height"],
|
||||
video_config["resized_width"],
|
||||
factor=image_factor,
|
||||
)
|
||||
else:
|
||||
@@ -236,6 +243,9 @@ 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,
|
||||
@@ -269,7 +279,8 @@ class QwenVLImageProcessor(SGLangBaseProcessor):
|
||||
video_metadata = None
|
||||
if base_output.videos:
|
||||
videos_processed = [
|
||||
await preprocess_video(video) for video in base_output.videos
|
||||
await preprocess_video(video, video_config=self.video_config)
|
||||
for video in base_output.videos
|
||||
]
|
||||
base_output.videos, video_metadata = map(list, zip(*videos_processed))
|
||||
|
||||
|
||||
@@ -297,6 +297,7 @@ class ServerArgs:
|
||||
base_gpu_id: int = 0
|
||||
gpu_id_step: int = 1
|
||||
sleep_on_idle: bool = False
|
||||
mm_process_config: Optional[Dict[str, Any]] = None
|
||||
|
||||
# Logging
|
||||
log_level: str = "info"
|
||||
@@ -682,6 +683,8 @@ class ServerArgs:
|
||||
self.device = get_device()
|
||||
if self.random_seed is None:
|
||||
self.random_seed = random.randint(0, 1 << 30)
|
||||
if self.mm_process_config is None:
|
||||
self.mm_process_config = {}
|
||||
|
||||
def _handle_gpu_memory_settings(self, gpu_mem):
|
||||
"""
|
||||
@@ -2351,6 +2354,12 @@ class ServerArgs:
|
||||
action="store_true",
|
||||
help="Reduce CPU usage when sglang is idle.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--mm-process-config",
|
||||
type=json.loads,
|
||||
default=ServerArgs.mm_process_config,
|
||||
help="Multimodal preprocessing config, a json config contains keys: `image`, `video`, `audio`",
|
||||
)
|
||||
|
||||
# Logging
|
||||
parser.add_argument(
|
||||
|
||||
Reference in New Issue
Block a user