[Bugfix][EPD] Preserve explicit multimodal UUIDs with caches disabled (#56432)

Signed-off-by: Tianyu Guo <guoty@inferact.ai>

Tianyu Guo committed Sep 13, 2026 at 18:08 UTC fa1b3b1922ccb2d7a597925765c4bec7f358d748
2 files changed +38 -26
tests/renderers/test_process_multi_modal_uuids.py
+27 -17
@@ -176,9 +176,32 @@ def test_multi_modal_uuids_accepts_empty(
176 assert processed_mm_uuids == mm_uuids
177
178
179 -def test_multi_modal_uuids_ignored_when_caching_disabled():
180 - # When both processor cache is 0 and prefix caching disabled, the
181 - # processor builds overrides from request id instead of using user UUIDs.
179 +@pytest.mark.parametrize(
180 + "mm_uuids, expected",
181 + [
182 + (
183 + {"image": ["hash_cherry", "hash_stop"], "video": ["hash_video"]},
184 + {"image": ["hash_cherry", "hash_stop"], "video": ["hash_video"]},
185 + ),
186 + (
187 + {"image": [None, "hash_stop"], "video": None},
188 + {"image": ["req-42-image-0", "hash_stop"], "video": ["req-42-video-0"]},
189 + ),
190 + (
191 + {"image": ["", None]},
192 + {"image": ["", "req-42-image-1"], "video": ["req-42-video-0"]},
193 + ),
194 + (
195 + {},
196 + {
197 + "image": ["req-42-image-0", "req-42-image-1"],
198 + "video": ["req-42-video-0"],
199 + },
200 + ),
201 + ],
202 +)
203 +def test_multi_modal_uuids_preserved_when_caching_disabled(mm_uuids, expected):
204 + """Only missing UUIDs get request-local IDs when both caches are disabled."""
205 renderer = _build_renderer(mm_cache_gb=0.0, enable_prefix_caching=False)
206
207 request_id = "req-42"
@@ -186,7 +209,6 @@ def test_multi_modal_uuids_ignored_when_caching_disabled():
209 "image": [cherry_pil_image, stop_pil_image],
210 "video": baby_reading_np_ndarrays,
211 }
189 - mm_uuids = {"image": ["hash_cherry", "hash_stop"], "video": ["hash_video"]}
212
213 mm_processor = renderer.get_mm_processor()
214 mm_data_items = mm_processor.info.parse_mm_data(mm_data)
@@ -196,16 +218,4 @@ def test_multi_modal_uuids_ignored_when_caching_disabled():
218 mm_data, mm_data_items, mm_uuid_items, request_id
219 )
220
199 - # Expect request-id-based overrides are passed through
200 - assert set(mm_uuids.keys()) == {"image", "video"}
201 - assert len(mm_uuids["image"]) == 2
202 - assert len(mm_uuids["video"]) == 1
203 - assert processed_mm_uuids["image"][0].startswith(
204 - f"{request_id}-image-"
205 - ) and processed_mm_uuids["image"][0].endswith("-0")
206 - assert processed_mm_uuids["image"][1].startswith(
207 - f"{request_id}-image-"
208 - ) and processed_mm_uuids["image"][1].endswith("-1")
209 - assert processed_mm_uuids["video"][0].startswith(
210 - f"{request_id}-video-"
211 - ) and processed_mm_uuids["video"][0].endswith("-0")
221 + assert processed_mm_uuids == expected
vllm/renderers/base.py
+11 -9
@@ -824,20 +824,22 @@ class BaseRenderer(ABC, Generic[_T]):
824 ) -> MultiModalUUIDItems:
825 model_config = self.model_config
826
827 - # NOTE: When users explicitly turn off BOTH prefix caching and input
828 - # processing caching, no multimodal features or embeddings will be
829 - # reused across requests, therefore identifying multimodal data items
830 - # by their content is no longer necessary, and we create uuids with
831 - # `<mm_req_id>-<modality>-<index>`, overriding even user-provided ones.
827 + # Skip content hashing when both caches are disabled, but preserve
828 + # explicit UUIDs used to identify embeddings across EC instances.
829 if (
830 model_config.multimodal_config
831 and model_config.multimodal_config.mm_processor_cache_gb == 0
832 and not self.config.cache_config.enable_prefix_caching
833 ):
837 - mm_uuid_items = {
838 - modality: [f"{mm_req_id}-{modality}-{i}" for i in range(data_count)]
839 - for modality, data_count in mm_data_items.get_all_counts().items()
840 - }
834 + mm_uuid_items = dict(mm_uuid_items)
835 + for modality, data_count in mm_data_items.get_all_counts().items():
836 + uuids = mm_uuid_items.get(modality)
837 + if uuids is None:
838 + uuids = [None] * data_count
839 + mm_uuid_items[modality] = [
840 + uuid if uuid is not None else f"{mm_req_id}-{modality}-{i}"
841 + for i, uuid in enumerate(uuids)
842 + ]
843
844 self._validate_mm_uuids(mm_data, mm_data_items, mm_uuid_items)
845