[Bugfix][V1][Multimodal] Ignore stale same-step encoder cache evictions (#52482)
Signed-off-by: Tianyu Guo <guoty@inferact.ai>
Tianyu Guo committed
Aug 17, 2026 at 06:21 UTC
eee538d5daa0c8c969f20d0c48c972155a6f1859
2 files changed
+22
-1
tests/v1/core/test_encoder_cache_manager.py
+19
@@ -167,6 +167,25 @@ def test_get_freed_mm_hashes_clears_freed_list():
167
assert manager.get_freed_mm_hashes() == []
168
169
170
+def test_reallocated_hash_is_not_reported_as_freed():
171
+ manager = EncoderCacheManager(cache_size=8)
172
+ req_a = MockRequest("reqA", ["a"], [4])
173
+ req_b = MockRequest("reqB", ["b"], [4])
174
+ req_c = MockRequest("reqC", ["c"], [4])
175
+
176
+ manager.allocate(req_a, 0)
177
+ manager.allocate(req_b, 0)
178
+ manager.free(req_a)
179
+ manager.free(req_b)
180
+
181
+ assert manager.can_allocate(req_c, 0, int(1e9), 0)
182
+ manager.allocate(req_c, 0)
183
+ assert manager.can_allocate(req_a, 0, int(1e9), 0)
184
+ manager.allocate(req_a, 0)
185
+
186
+ assert manager.get_freed_mm_hashes() == ["b"]
187
+
188
+
189
def test_schedule_request_multi_images_respect_space_limit():
190
manager = EncoderCacheManager(cache_size=10)
191
req = MockRequest("reqA", ["a", "b"], [5, 6])
vllm/v1/core/encoder_cache_manager.py
+3
-1
@@ -269,7 +269,9 @@ class EncoderCacheManager:
269
encoder outputs can be removed from their caches. The internal
270
list is cleared after this call.
271
"""
272
- freed = self.freed
272
+ # An entry evicted early in the scheduling pass can be allocated again
273
+ # later in the same pass. Keep its worker-side tensor in that case.
274
+ freed = [mm_hash for mm_hash in self.freed if mm_hash not in self.cached]
275
self.freed = []
276
return freed
277