[Core][Diffusion] Add pause_generation(mode="keep") for diffusion stages (#7685)

Signed-off-by: cr-gao <gaochenrui@sjtu.edu.cn>
This commit is contained in:
vOv authored and GitHub committed 2026-09-22 01:31:22 +08:00
1 parent 62b15142bd
commit d8d162d810
17 files changed
+1383 -65

No files matched your search

@@ -497,3 +497,99 @@ class TestWorkerProcShutdown:
result_mq.shutdown.assert_called_once_with()
assert proc.mq is None
assert proc.result_mq is None
class TestSynchronizeDeviceBarrier:
"""The pause barrier must not report a quiet device while outputs still pack."""
@staticmethod
def _rpc(timeout):
return {
"method": "synchronize_device",
"args": (),
"kwargs": {"timeout": timeout},
"output_rank": 0,
"exec_all_ranks": False,
"collect_rank_status": False,
}
def test_rejects_undrained_output(self, mocker):
proc = _make_worker_proc(step_execution=False)
proc.worker = MagicMock()
mocker.patch.object(proc, "drain_async_outputs", return_value=False)
with pytest.raises(TimeoutError, match="did not drain"):
proc._execute_rpc(self._rpc(0.01))
proc.worker.execute_method.assert_not_called()
@pytest.mark.parametrize("timeout", [0.5, None])
def test_drains_with_the_call_timeout_then_synchronizes(self, mocker, timeout):
proc = _make_worker_proc(step_execution=False)
proc.worker = MagicMock()
call_order: list = []
mocker.patch.object(
proc,
"drain_async_outputs",
side_effect=lambda **kw: call_order.append(("drain", kw)) or True,
)
proc.worker.execute_method.side_effect = lambda *a, **kw: call_order.append(("sync", a, kw))
_, should_reply = proc._execute_rpc(self._rpc(timeout))
assert call_order == [
("drain", {"timeout": timeout}),
("sync", ("synchronize_device",), {"timeout": timeout}),
]
assert should_reply is True
def test_completes_only_after_output_ready_is_published(self, mocker):
proc = _make_worker_proc(step_execution=False)
proc.worker = MagicMock()
mock_platform = mocker.MagicMock()
mock_platform.record_device_event.return_value = MagicMock()
mocker.patch(
"vllm_omni.diffusion.worker.diffusion_worker.current_omni_platform",
mock_platform,
)
mock_torch = mocker.MagicMock()
mock_torch.accelerator.current_accelerator.return_value.type = "cpu"
mocker.patch("vllm_omni.diffusion.worker.diffusion_worker.torch", mock_torch)
release = threading.Event()
mocker.patch(
"vllm_omni.diffusion.worker.diffusion_worker.pack_diffusion_output_shm",
side_effect=lambda *a, **kw: release.wait(timeout=5.0),
)
proc._return_result(DiffusionOutput(output="data"), rpc_id="1")
loop_thread = threading.Thread(target=proc._async_output_loop, daemon=True)
loop_thread.start()
barrier_done = threading.Event()
def run_barrier():
proc._execute_rpc(self._rpc(5.0))
barrier_done.set()
barrier_thread = threading.Thread(target=run_barrier, daemon=True)
barrier_thread.start()
try:
assert not barrier_done.wait(timeout=0.2)
proc.worker.execute_method.assert_not_called()
release.set()
assert barrier_done.wait(timeout=5.0)
kinds = [
call.args[0].kind
for call in proc.result_mq.enqueue.call_args_list
if isinstance(call.args[0], AsyncDiffusionOutput)
]
assert kinds == [AsyncOutputKind.COMPUTE_DONE, AsyncOutputKind.OUTPUT_READY]
proc.worker.execute_method.assert_called_once_with("synchronize_device", timeout=5.0)
finally:
release.set()
proc._async_output_queue.put(None)
loop_thread.join(timeout=2.0)
barrier_thread.join(timeout=2.0)