HiCache: avoid unnecessary all-reduce in check_prefetch_progress (#36425)
This commit is contained in:
@@ -1792,13 +1792,27 @@ class UnifiedRadixCache(BasePrefixCache):
|
|||||||
+ len(operation.hash_value) * self.prefetch_timeout_per_page
|
+ len(operation.hash_value) * self.prefetch_timeout_per_page
|
||||||
)
|
)
|
||||||
|
|
||||||
def can_terminate_prefetch(self, operation: PrefetchOperation) -> bool:
|
@rank_consensus(same_results=True)
|
||||||
|
def _can_terminate_prefetch(self, operation: PrefetchOperation) -> bool:
|
||||||
if self.prefetch_stop_policy == "best_effort":
|
if self.prefetch_stop_policy == "best_effort":
|
||||||
return True
|
return True
|
||||||
if self.prefetch_stop_policy == "wait_complete":
|
if self.prefetch_stop_policy == "wait_complete":
|
||||||
return False
|
return False
|
||||||
elif self.prefetch_stop_policy == "timeout":
|
elif self.prefetch_stop_policy == "timeout":
|
||||||
return self._prefetch_timeout_check_linear_func(operation)
|
# Wall-clock time may differ among ranks, all-reduce is needed to ensure
|
||||||
|
# all ranks reach the same final result. Otherwise PP/TP ranks will diverge.
|
||||||
|
#
|
||||||
|
# For TP, if any rank reaches the timeout, the final result is timeout.
|
||||||
|
#
|
||||||
|
# For PP, PP0 makes the decision and other ranks follow PP0's decision.
|
||||||
|
should_terminate = False
|
||||||
|
if self.pp_rank == 0:
|
||||||
|
should_terminate = self._prefetch_timeout_check_linear_func(operation)
|
||||||
|
should_terminate_tensor = torch.tensor(
|
||||||
|
int(should_terminate), dtype=torch.int, device="cpu"
|
||||||
|
)
|
||||||
|
self._all_reduce(should_terminate_tensor, torch.distributed.ReduceOp.MAX)
|
||||||
|
return should_terminate_tensor.item() == 1
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -1809,18 +1823,10 @@ class UnifiedRadixCache(BasePrefixCache):
|
|||||||
|
|
||||||
_, _, _, operation, _, _ = self.ongoing_prefetch[req_id]
|
_, _, _, operation, _, _ = self.ongoing_prefetch[req_id]
|
||||||
|
|
||||||
# Determine whether or not we should terminate this prefetch request. Make all
|
# Determine whether or not we should terminate this prefetch request.
|
||||||
# ranks agree on the decision. When running with PP, PPn will follow PP0's decision.
|
should_terminate = operation.is_terminated() or self._can_terminate_prefetch(
|
||||||
should_terminate = False
|
operation
|
||||||
if self.pp_rank == 0:
|
|
||||||
should_terminate = operation.is_terminated() or self.can_terminate_prefetch(
|
|
||||||
operation
|
|
||||||
)
|
|
||||||
should_terminate_tensor = torch.tensor(
|
|
||||||
int(should_terminate), dtype=torch.int, device="cpu"
|
|
||||||
)
|
)
|
||||||
self._all_reduce(should_terminate_tensor, torch.distributed.ReduceOp.MAX)
|
|
||||||
should_terminate = should_terminate_tensor.item() == 1
|
|
||||||
|
|
||||||
if not should_terminate:
|
if not should_terminate:
|
||||||
return False
|
return False
|
||||||
|
|||||||
@@ -7626,7 +7626,7 @@ class TestPrefetchCommitOrdering(CustomTestCase):
|
|||||||
cache._check_hybrid_prefetch_result.return_value = 8
|
cache._check_hybrid_prefetch_result.return_value = 8
|
||||||
cache.cache_controller.prefetch_tokens_occupied = 100
|
cache.cache_controller.prefetch_tokens_occupied = 100
|
||||||
cache.prefetch_loaded_tokens_by_reqid = {}
|
cache.prefetch_loaded_tokens_by_reqid = {}
|
||||||
cache.can_terminate_prefetch.return_value = True
|
cache._can_terminate_prefetch.return_value = True
|
||||||
cache.pp_rank = 0
|
cache.pp_rank = 0
|
||||||
|
|
||||||
order = mock.MagicMock()
|
order = mock.MagicMock()
|
||||||
@@ -7799,7 +7799,7 @@ class TestUnifiedRadixPrefetchCorruption(CustomTestCase):
|
|||||||
operation.hash_value = hashes
|
operation.hash_value = hashes
|
||||||
|
|
||||||
with (
|
with (
|
||||||
mock.patch.object(cache, "can_terminate_prefetch", return_value=True),
|
mock.patch.object(cache, "_can_terminate_prefetch", return_value=True),
|
||||||
# Isolate the drop-release branch under test from the hybrid-sync
|
# Isolate the drop-release branch under test from the hybrid-sync
|
||||||
# step: treat the whole fetched prefix as usable so the insert runs.
|
# step: treat the whole fetched prefix as usable so the insert runs.
|
||||||
mock.patch.object(
|
mock.patch.object(
|
||||||
|
|||||||
Reference in New Issue
Block a user