fix(spec_v2): support EAGLE with spec_v2
1. add pass for spec_v2 in base_attn 2. fix: EAGLE with spec_v2 overlap Grammar accept_token failed Signed-off-by: wxiwnd <wxiwnd@outlook.com>
This commit is contained in:
@@ -137,9 +137,9 @@ class DecodeReqToTokenPool:
|
||||
# Indices of reqs that already have a req_pool_idx and will reuse
|
||||
# their existing slot (e.g. chunked prefill continuing across chunks).
|
||||
reusing = [i for i, r in enumerate(reqs) if r.req_pool_idx is not None]
|
||||
assert (
|
||||
len(reusing) <= 1
|
||||
), "only one chunked request may reuse req_pool_idx in a batch"
|
||||
assert len(reusing) <= 1, (
|
||||
"only one chunked request may reuse req_pool_idx in a batch"
|
||||
)
|
||||
assert all(
|
||||
reqs[i].is_chunked > 0 or reqs[i].kv_committed_len > 0 for i in reusing
|
||||
), "reusing request must be chunked or have committed KV"
|
||||
@@ -166,7 +166,6 @@ class DecodeReqToTokenPool:
|
||||
|
||||
|
||||
class HybridMambaDecodeReqToTokenPool(HybridReqToTokenPool):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
size: int,
|
||||
@@ -793,9 +792,9 @@ class DecodePreallocQueue:
|
||||
"""Pre-allocate the memory for req_to_token and token_kv_pool"""
|
||||
req_pool_indices = self.req_to_token_pool.alloc([req])
|
||||
|
||||
assert (
|
||||
req_pool_indices is not None
|
||||
), "req_pool_indices is full! There is a bug in memory estimation."
|
||||
assert req_pool_indices is not None, (
|
||||
"req_pool_indices is full! There is a bug in memory estimation."
|
||||
)
|
||||
|
||||
# Alloc all tokens for the prebuilt req (except for the reserved input token for decoding)
|
||||
fill_len = len(req.origin_input_ids) + max(len(req.output_ids) - 1, 0)
|
||||
@@ -814,9 +813,9 @@ class DecodePreallocQueue:
|
||||
extend_num_tokens=fill_len,
|
||||
)
|
||||
|
||||
assert (
|
||||
kv_loc is not None
|
||||
), "KV cache is full! There is a bug in memory estimation."
|
||||
assert kv_loc is not None, (
|
||||
"KV cache is full! There is a bug in memory estimation."
|
||||
)
|
||||
|
||||
self.req_to_token_pool.write((req.req_pool_idx, slice(0, len(kv_loc))), kv_loc)
|
||||
|
||||
@@ -1008,7 +1007,6 @@ class DecodeTransferQueue:
|
||||
|
||||
|
||||
class SchedulerDisaggregationDecodeMixin:
|
||||
|
||||
@torch.no_grad()
|
||||
def event_loop_normal_disagg_decode(self: Scheduler):
|
||||
"""A normal scheduler loop for decode worker in disaggregation mode."""
|
||||
@@ -1023,6 +1021,18 @@ class SchedulerDisaggregationDecodeMixin:
|
||||
# Get the next batch to run
|
||||
batch = self.get_next_disagg_decode_batch_to_run()
|
||||
self.cur_batch = batch
|
||||
disable_overlap_for_batch = self.is_disable_overlap_for_batch(batch)
|
||||
|
||||
def pop_and_process():
|
||||
# Process the results of the last batch
|
||||
tmp_batch, tmp_result = self.result_queue.popleft()
|
||||
self.process_batch_result(tmp_batch, tmp_result)
|
||||
|
||||
# If we need grammar sync (spec + grammar), process the last batch
|
||||
# results first so that the grammar state is up-to-date before
|
||||
# generating the bitmask for the current batch.
|
||||
if disable_overlap_for_batch:
|
||||
pop_and_process()
|
||||
|
||||
# Launch the current batch
|
||||
if batch:
|
||||
@@ -1040,6 +1050,11 @@ class SchedulerDisaggregationDecodeMixin:
|
||||
self.result_queue = deque()
|
||||
self.last_batch: Optional[ScheduleBatch] = None
|
||||
|
||||
def pop_and_process():
|
||||
# Process the results of the last batch
|
||||
tmp_batch, tmp_result = self.result_queue.popleft()
|
||||
self.process_batch_result(tmp_batch, tmp_result)
|
||||
|
||||
while True:
|
||||
# Receive requests
|
||||
recv_reqs = self.recv_requests()
|
||||
@@ -1050,6 +1065,13 @@ class SchedulerDisaggregationDecodeMixin:
|
||||
# Get the next batch to run
|
||||
batch = self.get_next_disagg_decode_batch_to_run()
|
||||
self.cur_batch = batch
|
||||
disable_overlap_for_batch = self.is_disable_overlap_for_batch(batch)
|
||||
|
||||
# If we need grammar sync (spec + grammar), process the last batch
|
||||
# results first so that the grammar state is up-to-date before
|
||||
# generating the bitmask for the current batch.
|
||||
if self.last_batch and disable_overlap_for_batch:
|
||||
pop_and_process()
|
||||
|
||||
# Launch the current batch
|
||||
if batch:
|
||||
@@ -1060,8 +1082,8 @@ class SchedulerDisaggregationDecodeMixin:
|
||||
|
||||
# Process the last batch
|
||||
if self.last_batch:
|
||||
tmp_batch, tmp_result = self.result_queue.popleft()
|
||||
self.process_batch_result(tmp_batch, tmp_result)
|
||||
if not disable_overlap_for_batch:
|
||||
pop_and_process()
|
||||
elif batch is None:
|
||||
self.self_check_during_idle()
|
||||
|
||||
|
||||
@@ -75,7 +75,10 @@ class AttentionBackend(ABC):
|
||||
Here, we need to redo the computation of all metadata of the attention backend
|
||||
that depends on tree mask and position buffers.
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
# if self.topk <= 1:
|
||||
# return
|
||||
# raise NotImplementedError()
|
||||
pass
|
||||
|
||||
@debug_kernel_api
|
||||
def forward(
|
||||
|
||||
Reference in New Issue
Block a user