[VLM] replace deprecated image processor use_fast (#34175)

This commit is contained in:
Mick
2026-08-12 00:14:07 +08:00
committed by GitHub
parent b20c375c10
commit 8267d76c2c
21 changed files with 281 additions and 98 deletions
@@ -142,6 +142,41 @@ class TestMmEncoderDataParallelLogging(CustomTestCase):
self.assertIn("high-resolution or multi-image", logs.output[0])
class TestImageProcessorBackend(CustomTestCase):
def test_new_backend_does_not_set_legacy_flag(self):
server_args = ServerArgs(model_path="dummy", image_processor_backend="pil")
server_args._handle_deprecated_args()
self.assertEqual(server_args.image_processor_backend, "pil")
self.assertFalse(server_args.disable_fast_image_processor)
def test_legacy_flag_maps_to_pil_with_one_warning(self):
server_args = ServerArgs(model_path="dummy", disable_fast_image_processor=True)
with self.assertLogs(server_args_module.logger, level="WARNING") as logs:
server_args._handle_deprecated_args()
self.assertEqual(server_args.image_processor_backend, "pil")
self.assertTrue(server_args.disable_fast_image_processor)
self.assertEqual(
sum(
"--disable-fast-image-processor is deprecated" in x for x in logs.output
),
1,
)
def test_legacy_flag_rejects_torchvision_backend(self):
server_args = ServerArgs(
model_path="dummy",
image_processor_backend="torchvision",
disable_fast_image_processor=True,
)
with self.assertRaisesRegex(ValueError, "conflicts.*torchvision"):
server_args._handle_deprecated_args()
class TestMultimodalFeatureTransport(CustomTestCase):
@staticmethod
def _set_model_type(server_args, *, is_multimodal):
@@ -87,6 +87,12 @@ class TestServerArgsAnnotatedCli(CustomTestCase):
self.assertEqual(sa.deepep_mode, "low_latency")
self.assertEqual(sa.elastic_ep_backend, "none")
def test_image_processor_backend_choices(self):
for backend in ("auto", "torchvision", "pil"):
with self.subTest(backend=backend):
sa = self._parse(["--image-processor-backend", backend])
self.assertEqual(sa.image_processor_backend, backend)
def test_deprecated_flags_still_work(self):
"""Deprecated flags set the correct dest field."""
sa = self._parse(["--stream-output"])
@@ -39,6 +39,72 @@ register_cpu_ci(est_time=6, suite="base-a-test-cpu")
class TestGetProcessor(unittest.TestCase):
def test_does_not_forward_backend_to_auto_processor(self):
config = SimpleNamespace(model_type="test_vlm", auto_map={})
loaded_processor = MagicMock()
loaded_processor.image_processor.backend = "torchvision"
loaded_processor.tokenizer.chat_template = "template"
auto_config = MagicMock()
auto_config.from_pretrained.return_value = config
auto_processor = MagicMock()
auto_processor.from_pretrained.return_value = loaded_processor
auto_image_processor = MagicMock()
with patch.multiple(
processor_utils,
AutoConfig=auto_config,
AutoProcessor=auto_processor,
AutoImageProcessor=auto_image_processor,
):
processor_utils.get_processor(
"test-model", image_processor_backend="torchvision"
)
call_kwargs = auto_processor.from_pretrained.call_args.kwargs
self.assertNotIn("backend", call_kwargs)
self.assertNotIn("use_fast", call_kwargs)
auto_image_processor.from_pretrained.assert_not_called()
def test_applies_pil_backend_only_to_image_processor(self):
config = SimpleNamespace(model_type="test_vlm", auto_map={})
for processor_kwargs in (
{"image_processor_backend": "pil"},
{"use_fast": False},
):
with self.subTest(processor_kwargs=processor_kwargs):
loaded_processor = MagicMock()
loaded_processor.image_processor.backend = "torchvision"
loaded_processor.tokenizer.chat_template = "template"
pil_processor = MagicMock(backend="pil")
auto_config = MagicMock()
auto_config.from_pretrained.return_value = config
auto_processor = MagicMock()
auto_processor.from_pretrained.return_value = loaded_processor
auto_image_processor = MagicMock()
auto_image_processor.from_pretrained.return_value = pil_processor
with patch.multiple(
processor_utils,
AutoConfig=auto_config,
AutoProcessor=auto_processor,
AutoImageProcessor=auto_image_processor,
):
processor = processor_utils.get_processor(
"test-model", **processor_kwargs
)
call_kwargs = auto_processor.from_pretrained.call_args.kwargs
self.assertNotIn("backend", call_kwargs)
self.assertNotIn("use_fast", call_kwargs)
auto_image_processor.from_pretrained.assert_called_once_with(
"test-model",
trust_remote_code=False,
revision=None,
backend="pil",
)
self.assertIs(processor.image_processor, pil_processor)
def test_resolves_model_name_before_loading_config(self):
remote_model = "s3://bucket/model"
local_model = "/cache/model"
@@ -53,9 +53,7 @@ def _build_drift_prompt(model, image_token):
token), followed by one image placeholder. drift_delta is how many extra
tokens the non-canonical form carries vs. the canonical re-tokenization.
"""
tok = AutoProcessor.from_pretrained(
model, trust_remote_code=True, use_fast=True
).tokenizer
tok = AutoProcessor.from_pretrained(model, trust_remote_code=True).tokenizer
def enc(text):
return tok.encode(text, add_special_tokens=False)
@@ -14,7 +14,7 @@ class TestQwen3OmniServer(OmniOpenAITestMixin):
extra_args = [ # workaround to fit into H100
"--mem-fraction-static=0.90",
"--disable-cuda-graph",
"--disable-fast-image-processor",
"--image-processor-backend=pil",
"--grammar-backend=none",
]
+1 -1
View File
@@ -74,7 +74,7 @@ class VLMInputTestBase:
cls.main_image.append(Image.open(BytesIO(response.content)))
cls.processor = AutoProcessor.from_pretrained(
cls.model_path, trust_remote_code=True, use_fast=True
cls.model_path, trust_remote_code=True
)
_fix_added_tokens_encoding(cls.processor.tokenizer)
cls._init_visual()