Configurable decode retraction order (#30573)
Co-authored-by: tanujtiwari1998 <168470992+tanujtiwari1998@users.noreply.github.com>
This commit is contained in:
co-authored by
tanujtiwari1998
parent
5be9c9f7c6
commit
32c8973ce8
@@ -40,6 +40,7 @@ import copy
|
|||||||
import dataclasses
|
import dataclasses
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
|
import sys
|
||||||
from array import array
|
from array import array
|
||||||
from concurrent.futures import Future
|
from concurrent.futures import Future
|
||||||
from enum import Enum, auto
|
from enum import Enum, auto
|
||||||
@@ -2552,21 +2553,13 @@ class ScheduleBatch(ScheduleBatchDisaggregationDecodeMixin):
|
|||||||
self, server_args: ServerArgs
|
self, server_args: ServerArgs
|
||||||
) -> Tuple[List[Req], float, List[Req]]:
|
) -> Tuple[List[Req], float, List[Req]]:
|
||||||
"""Retract the decoding requests when there is not enough memory."""
|
"""Retract the decoding requests when there is not enough memory."""
|
||||||
sorted_indices = list(range(len(self.reqs)))
|
sorted_indices = self._get_decode_retraction_order(
|
||||||
|
self.reqs,
|
||||||
# TODO(lsyin): improve retraction policy for radix cache
|
server_args,
|
||||||
# For spec decoding, filter_batch API can only filter
|
allow_policy_sort=(
|
||||||
# requests from the back, so we can only retract from the back.
|
self.spec_algorithm is None or self.spec_algorithm.is_none()
|
||||||
# TODO(sang): Clean up finish path and support better retract
|
),
|
||||||
# policy.
|
)
|
||||||
if not server_args.speculative_algorithm:
|
|
||||||
sorted_indices.sort(
|
|
||||||
key=lambda i: (
|
|
||||||
len(self.reqs[i].output_ids),
|
|
||||||
-len(self.reqs[i].origin_input_ids),
|
|
||||||
),
|
|
||||||
reverse=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
retracted_reqs = []
|
retracted_reqs = []
|
||||||
first_iter = True
|
first_iter = True
|
||||||
@@ -2612,6 +2605,52 @@ class ScheduleBatch(ScheduleBatchDisaggregationDecodeMixin):
|
|||||||
|
|
||||||
return retracted_reqs, new_estimate_ratio, reqs_to_abort
|
return retracted_reqs, new_estimate_ratio, reqs_to_abort
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _get_decode_retraction_order(
|
||||||
|
reqs: List[Req], server_args: ServerArgs, *, allow_policy_sort: bool
|
||||||
|
) -> List[int]:
|
||||||
|
"""Return indices ordered from most-preferred to least-preferred to keep.
|
||||||
|
|
||||||
|
The retraction loop pops from the end of this list, so the least-preferred
|
||||||
|
request is retracted first.
|
||||||
|
"""
|
||||||
|
sorted_indices = list(range(len(reqs)))
|
||||||
|
|
||||||
|
# TODO(lsyin): improve retraction policy for radix cache
|
||||||
|
# For spec decoding, filter_batch API can only filter requests from the
|
||||||
|
# back, so we can only retract from the back.
|
||||||
|
# TODO(sang): Clean up finish path and support better retract policy.
|
||||||
|
if not allow_policy_sort:
|
||||||
|
return sorted_indices
|
||||||
|
|
||||||
|
def length_key(req: Req) -> Tuple[int, int]:
|
||||||
|
return (len(req.output_ids), -len(req.origin_input_ids))
|
||||||
|
|
||||||
|
if server_args.retraction_policy == "priority":
|
||||||
|
priority_sign = 1 if server_args.schedule_low_priority_values_first else -1
|
||||||
|
|
||||||
|
def retraction_key(req: Req) -> Tuple[int, int, int]:
|
||||||
|
priority = req.priority
|
||||||
|
if priority is None:
|
||||||
|
priority = (
|
||||||
|
sys.maxsize
|
||||||
|
if server_args.schedule_low_priority_values_first
|
||||||
|
else -sys.maxsize - 1
|
||||||
|
)
|
||||||
|
return (priority * (-priority_sign), *length_key(req))
|
||||||
|
|
||||||
|
sorted_indices.sort(
|
||||||
|
key=lambda i: retraction_key(reqs[i]),
|
||||||
|
reverse=True,
|
||||||
|
)
|
||||||
|
return sorted_indices
|
||||||
|
|
||||||
|
sorted_indices.sort(
|
||||||
|
key=lambda i: length_key(reqs[i]),
|
||||||
|
reverse=True,
|
||||||
|
)
|
||||||
|
return sorted_indices
|
||||||
|
|
||||||
def release_req(self, idx: int, remaing_req_count: int, server_args: ServerArgs):
|
def release_req(self, idx: int, remaing_req_count: int, server_args: ServerArgs):
|
||||||
release_req(
|
release_req(
|
||||||
req=self.reqs[idx],
|
req=self.reqs[idx],
|
||||||
|
|||||||
@@ -292,6 +292,7 @@ FP4_GEMM_RUNNER_BACKEND_CHOICES = [
|
|||||||
BF16_GEMM_BACKEND_CHOICES = ["auto", "cutedsl"]
|
BF16_GEMM_BACKEND_CHOICES = ["auto", "cutedsl"]
|
||||||
|
|
||||||
RADIX_EVICTION_POLICY_CHOICES = ["lru", "lfu", "slru", "priority"]
|
RADIX_EVICTION_POLICY_CHOICES = ["lru", "lfu", "slru", "priority"]
|
||||||
|
RETRACTION_POLICY_CHOICES = ["length", "priority"]
|
||||||
|
|
||||||
RL_ON_POLICY_TARGET_CHOICES = ["fsdp"]
|
RL_ON_POLICY_TARGET_CHOICES = ["fsdp"]
|
||||||
|
|
||||||
@@ -736,6 +737,19 @@ class ServerArgs:
|
|||||||
int,
|
int,
|
||||||
"Minimum difference in priorities for an incoming request to have to preempt running request(s).",
|
"Minimum difference in priorities for an incoming request to have to preempt running request(s).",
|
||||||
] = 10
|
] = 10
|
||||||
|
retraction_policy: A[
|
||||||
|
str,
|
||||||
|
Arg(
|
||||||
|
help=(
|
||||||
|
"The decode retraction policy to use when the KV cache is full. "
|
||||||
|
"'length' preserves the existing behavior and retracts short-output, "
|
||||||
|
"long-input requests first. 'priority' retracts lower-priority "
|
||||||
|
"requests first, using the same priority direction as priority "
|
||||||
|
"scheduling."
|
||||||
|
),
|
||||||
|
choices=RETRACTION_POLICY_CHOICES,
|
||||||
|
),
|
||||||
|
] = "length"
|
||||||
schedule_conservativeness: A[
|
schedule_conservativeness: A[
|
||||||
float,
|
float,
|
||||||
"How conservative the schedule policy is. A larger value means more conservative scheduling. Use a larger value if you see requests being retracted frequently.",
|
"How conservative the schedule policy is. A larger value means more conservative scheduling. Use a larger value if you see requests being retracted frequently.",
|
||||||
@@ -7004,6 +7018,10 @@ class ServerArgs:
|
|||||||
logger.warning(
|
logger.warning(
|
||||||
"--default-priority-value has no effect without --enable-priority-scheduling"
|
"--default-priority-value has no effect without --enable-priority-scheduling"
|
||||||
)
|
)
|
||||||
|
if self.retraction_policy == "priority" and not self.enable_priority_scheduling:
|
||||||
|
raise ValueError(
|
||||||
|
"--retraction-policy priority requires --enable-priority-scheduling"
|
||||||
|
)
|
||||||
|
|
||||||
# Check hisparse
|
# Check hisparse
|
||||||
# Moved to the resolution pipeline (arg_groups/overrides.py:
|
# Moved to the resolution pipeline (arg_groups/overrides.py:
|
||||||
|
|||||||
Reference in New Issue
Block a user