diff --git a/vllm/multimodal/video.py b/vllm/multimodal/video.py index 874745e714..aab8bfd3b3 100644 --- a/vllm/multimodal/video.py +++ b/vllm/multimodal/video.py @@ -15,7 +15,7 @@ import torch from vllm import envs from vllm.logger import init_logger -from vllm.utils.import_utils import PlaceholderModule +from vllm.utils.import_utils import PlaceholderModule, check_torchcodec_available from vllm.utils.mem_constants import MiB_bytes from vllm.utils.registry import ExtensionManager @@ -33,7 +33,7 @@ except ImportError: try: from torchcodec.decoders import VideoDecoder -except ImportError: +except (ImportError, RuntimeError): VideoDecoder = PlaceholderModule("torchcodec").placeholder_attr( # type: ignore[assignment] "decoders.VideoDecoder" ) @@ -956,6 +956,7 @@ class VideoBackend( assert not frame_recovery, ( "frame_recovery is only available for `opencv` backend" ) + check_torchcodec_available() decoder = cls.make_torchcodec_decoder( data, num_ffmpeg_threads=num_ffmpeg_threads, diff --git a/vllm/utils/import_utils.py b/vllm/utils/import_utils.py index 78dcde6f06..812adb59e6 100644 --- a/vllm/utils/import_utils.py +++ b/vllm/utils/import_utils.py @@ -552,3 +552,21 @@ def has_cutedsl() -> bool: def has_humming() -> bool: """Whether the optional `humming` package is available.""" return _has_module("humming") + + +def check_torchcodec_available(): + """Whether the optional `torchcodec` package is available.""" + try: + import torchcodec # noqa: F401 + except RuntimeError as e: + # torchcodec will raise RuntimeError during import instead + # of ImportError when system ffmpeg unavailable, with a + # message that can leak sensitive system information. + # Trim it down to avoid it. + marker = ( + "The following exceptions were raised as we tried to load libtorchcodec:" + ) + message = str(e) + if marker in message: + raise RuntimeError(message.split(marker, 1)[0].rstrip()) from None + raise e