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 logging
|
||||
import re
|
||||
import sys
|
||||
from array import array
|
||||
from concurrent.futures import Future
|
||||
from enum import Enum, auto
|
||||
@@ -2552,21 +2553,13 @@ class ScheduleBatch(ScheduleBatchDisaggregationDecodeMixin):
|
||||
self, server_args: ServerArgs
|
||||
) -> Tuple[List[Req], float, List[Req]]:
|
||||
"""Retract the decoding requests when there is not enough memory."""
|
||||
sorted_indices = list(range(len(self.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 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,
|
||||
)
|
||||
sorted_indices = self._get_decode_retraction_order(
|
||||
self.reqs,
|
||||
server_args,
|
||||
allow_policy_sort=(
|
||||
self.spec_algorithm is None or self.spec_algorithm.is_none()
|
||||
),
|
||||
)
|
||||
|
||||
retracted_reqs = []
|
||||
first_iter = True
|
||||
@@ -2612,6 +2605,52 @@ class ScheduleBatch(ScheduleBatchDisaggregationDecodeMixin):
|
||||
|
||||
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):
|
||||
release_req(
|
||||
req=self.reqs[idx],
|
||||
|
||||
@@ -292,6 +292,7 @@ FP4_GEMM_RUNNER_BACKEND_CHOICES = [
|
||||
BF16_GEMM_BACKEND_CHOICES = ["auto", "cutedsl"]
|
||||
|
||||
RADIX_EVICTION_POLICY_CHOICES = ["lru", "lfu", "slru", "priority"]
|
||||
RETRACTION_POLICY_CHOICES = ["length", "priority"]
|
||||
|
||||
RL_ON_POLICY_TARGET_CHOICES = ["fsdp"]
|
||||
|
||||
@@ -736,6 +737,19 @@ class ServerArgs:
|
||||
int,
|
||||
"Minimum difference in priorities for an incoming request to have to preempt running request(s).",
|
||||
] = 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[
|
||||
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.",
|
||||
@@ -7004,6 +7018,10 @@ class ServerArgs:
|
||||
logger.warning(
|
||||
"--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
|
||||
# Moved to the resolution pipeline (arg_groups/overrides.py:
|
||||
|
||||
Reference in New Issue
Block a user