[V1][Metrics] Preserve prefix-cache stats on zero-output steps (#48668)

Signed-off-by: Rishi Puri <riship@nvidia.com> Signed-off-by: Rishi Puri <puririshi98@berkeley.edu> Signed-off-by: Nick Hill <nickhill123@gmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Nick Hill <nickhill123@gmail.com>

Rishi Puri committed Aug 8, 2026 at 22:58 UTC dedbf6be8b1afa17a6220473b9c8c98242ac1c03
1 file changed +7 -7
vllm/v1/engine/llm_engine.py
+7 -7
@@ -307,7 +307,9 @@ class LLMEngine:
307
308 # 2) Process EngineCoreOutputs.
309 with record_function_or_nullcontext("llm_engine step: process_outputs"):
310 - iteration_stats = IterationStats() if self.log_stats else None
310 + iteration_stats = (
311 + IterationStats() if self.log_stats and outputs.outputs else None
312 + )
313 processed_outputs = self.output_processor.process_outputs(
314 outputs.outputs,
315 engine_core_timestamp=outputs.timestamp,
@@ -321,17 +323,15 @@ class LLMEngine:
323
324 # 4) Record stats
325 with record_function_or_nullcontext("llm_engine step: record_stats"):
324 - if (
325 - self.logger_manager is not None
326 - and outputs.scheduler_stats is not None
327 - and len(outputs.outputs) > 0
328 - ):
326 + if self.logger_manager is not None and outputs.scheduler_stats is not None:
327 + # Record even when this step produced no request outputs.
328 self.logger_manager.record(
329 scheduler_stats=outputs.scheduler_stats,
330 iteration_stats=iteration_stats,
331 mm_cache_stats=self.renderer.stat_mm_cache(),
332 )
334 - self.do_log_stats_with_interval()
333 + if outputs.outputs:
334 + self.do_log_stats_with_interval()
335
336 return processed_outputs.request_outputs
337