From a67a31aa81d23bbd83be9f8a921474d48d73ad36 Mon Sep 17 00:00:00 2001 From: YanbingJiang Date: Wed, 9 Sep 2026 09:22:58 +0800 Subject: [PATCH] [CPU] Support Qwen3.8 text+video: adding torchcodec, ffmpeg and removing pin_memory (#35492) --- docker/xeon.Dockerfile | 1 + python/pyproject_cpu.toml | 1 + python/sglang/srt/multimodal/processors/qwen_vl.py | 3 ++- python/sglang/srt/utils/video_decoder.py | 14 +++++++++++++- 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/docker/xeon.Dockerfile b/docker/xeon.Dockerfile index 7c22ebbb2..5d99806e2 100644 --- a/docker/xeon.Dockerfile +++ b/docker/xeon.Dockerfile @@ -8,6 +8,7 @@ RUN apt-get update && \ apt-get full-upgrade -y && \ DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ ca-certificates \ + ffmpeg \ git \ curl \ wget \ diff --git a/python/pyproject_cpu.toml b/python/pyproject_cpu.toml index 571c89ef5..7ee090217 100644 --- a/python/pyproject_cpu.toml +++ b/python/pyproject_cpu.toml @@ -62,6 +62,7 @@ dependencies = [ "timm==1.0.16", "torch==2.12.0", "torchaudio==2.11.0", + "torchcodec==0.12.0 ; sys_platform != 'linux' or (sys_platform == 'linux' and platform_machine != 'aarch64' and platform_machine != 'arm64' and platform_machine != 'armv7l')", "torchvision==0.27.0", "tqdm", "transformers==5.12.1", diff --git a/python/sglang/srt/multimodal/processors/qwen_vl.py b/python/sglang/srt/multimodal/processors/qwen_vl.py index eba723827..e911611d5 100644 --- a/python/sglang/srt/multimodal/processors/qwen_vl.py +++ b/python/sglang/srt/multimodal/processors/qwen_vl.py @@ -268,7 +268,8 @@ async def preprocess_video( [resized_height, resized_width], interpolation=InterpolationMode.BILINEAR, ) - video = video.pin_memory() + if not is_cpu(): + video = video.pin_memory() video_metadata = { "fps": video_fps, "duration": total_frames / video_fps, diff --git a/python/sglang/srt/utils/video_decoder.py b/python/sglang/srt/utils/video_decoder.py index 3b398b58e..13cfff5cd 100644 --- a/python/sglang/srt/utils/video_decoder.py +++ b/python/sglang/srt/utils/video_decoder.py @@ -33,6 +33,13 @@ def _try_cuda_backend() -> bool: return _cuda_backend_enabled +def _is_cpu_engine() -> bool: + # Lazy import to avoid circular dependency issues and unnecessary imports on module load + from sglang.srt.utils.common import is_cpu + + return is_cpu() + + class VideoDecoderWrapper: """Unified video decoder that uses torchcodec when available, decord as fallback. @@ -140,10 +147,13 @@ class VideoDecoderWrapper: if _BACKEND == "torchcodec": batch = self._decoder.get_frames_at(indices) + if _is_cpu_engine(): + return batch.data return batch.data if batch.data.is_cuda else batch.data.pin_memory() else: arr = self._decoder.get_batch(indices).asnumpy() - return torch.from_numpy(arr).pin_memory() + output = torch.from_numpy(arr) + return output if _is_cpu_engine() else output.pin_memory() def _parallel_decode(self, indices, num_threads): """Decode frames using multiple VideoDecoder instances in parallel threads.""" @@ -177,6 +187,8 @@ class VideoDecoderWrapper: results[idx] = future.result() output = torch.cat(results, dim=0) + if _is_cpu_engine(): + return output return output if output.is_cuda else output.pin_memory() @property