[Scheduler] Add SGLANG_FORCE_COARSE_WAR_BARRIER opt-in for a whole-forward WAR barrier (#29353)

This commit is contained in:
Feng Yao
2026-07-19 00:28:49 -07:00
committed by GitHub
parent 609fe1c0d1
commit 942bf04ef9
4 changed files with 11 additions and 3 deletions
+3
View File
@@ -377,6 +377,9 @@ class Envs:
# even when is_cuda() is False (e.g. AMD/ROCm). On CUDA the barrier is # even when is_cuda() is False (e.g. AMD/ROCm). On CUDA the barrier is
# already enabled regardless of this flag (see start_event_loop). # already enabled regardless of this flag (see start_event_loop).
SGLANG_ENABLE_WAR_BARRIER = EnvBool(False) SGLANG_ENABLE_WAR_BARRIER = EnvBool(False)
# Force the WAR barrier to wait for the whole forward instead of the
# read-done fastpath event.
SGLANG_FORCE_COARSE_WAR_BARRIER = EnvBool(False)
# PP: skip output send/recv when the entire batch consists of non-final chunked prefill requests, # PP: skip output send/recv when the entire batch consists of non-final chunked prefill requests,
# since process_batch_result_prefill discards next_token_ids for those anyway. # since process_batch_result_prefill discards next_token_ids for those anyway.
SGLANG_PP_SKIP_PURE_CHUNKED_OUTPUT_COMM = EnvBool(False) SGLANG_PP_SKIP_PURE_CHUNKED_OUTPUT_COMM = EnvBool(False)
+4 -3
View File
@@ -1487,14 +1487,15 @@ class Scheduler(
# (result processing, next iteration's writes) behind the forward's # (result processing, next iteration's writes) behind the forward's
# shared-buffer reads. Fast path: wait on the read-done event the # shared-buffer reads. Fast path: wait on the read-done event the
# forward published after its snapshot (non-spec: decode graph; spec: # forward published after its snapshot (non-spec: decode graph; spec:
# draft_extend), then clear it. Else whole-forward wait_stream. # draft_extend), then clear it. Else whole-forward wait_stream
# (forceable via SGLANG_FORCE_COARSE_WAR_BARRIER).
if not self._war_barrier_enabled: if not self._war_barrier_enabled:
return return
runner = self.model_worker.war_fastpath_runner runner = self.model_worker.war_fastpath_runner
ev = runner.war_fastpath_read_done_event ev = runner.war_fastpath_read_done_event
if ev is not None:
self.schedule_stream.wait_event(ev)
runner.war_fastpath_read_done_event = None runner.war_fastpath_read_done_event = None
if ev is not None and not envs.SGLANG_FORCE_COARSE_WAR_BARRIER.get():
self.schedule_stream.wait_event(ev)
else: else:
self.schedule_stream.wait_stream(self.forward_stream) self.schedule_stream.wait_stream(self.forward_stream)
@@ -881,6 +881,8 @@ class UnifiedRadixCache(KVCacheEventMixin, BasePrefixCache):
req.cache_protected_len = len(new_indices) req.cache_protected_len = len(new_indices)
req.last_node = new_last_node req.last_node = new_last_node
req.swa_uuid_for_lock = lock_result.swa_uuid_for_lock req.swa_uuid_for_lock = lock_result.swa_uuid_for_lock
# The rematch acquired a new SWA prefix lock.
req.swa_prefix_lock_released = False
# cleanup # cleanup
for comp in self._components_tuple: for comp in self._components_tuple:
@@ -932,6 +932,7 @@ class UnifiedRadixCacheSuite:
req.last_node = cache.root_node req.last_node = cache.root_node
req.cache_protected_len = 0 req.cache_protected_len = 0
req.swa_uuid_for_lock = None req.swa_uuid_for_lock = None
req.swa_prefix_lock_released = True
req.extra_key = None req.extra_key = None
req.full_untruncated_fill_ids = array("q", tokens) req.full_untruncated_fill_ids = array("q", tokens)
req.set_extend_range( req.set_extend_range(
@@ -975,6 +976,7 @@ class UnifiedRadixCacheSuite:
self.assertGreater(len(req.prefix_indices), 0) self.assertGreater(len(req.prefix_indices), 0)
self.assertEqual(req.cache_protected_len, len(req.prefix_indices)) self.assertEqual(req.cache_protected_len, len(req.prefix_indices))
self.assertIsNotNone(req.last_node) self.assertIsNotNone(req.last_node)
self.assertFalse(req.swa_prefix_lock_released)
cache.dec_lock_ref( cache.dec_lock_ref(
req.last_node, req.last_node,