Preserve chunked request affinity state

The affinity scheduler needs to know whether the current batch is led by a chunked request. The rebase carried call sites that referenced an old private field name, while PrefillAdder only retained a boolean flag, causing startup failure before scheduling could run.

Constraint: CP bs>1 affinity must classify a chunked-led batch without reopening chunked-tail mixing behavior.

Rejected: Recreate the old private _chunked_req_in_batch attribute | keeps a stale name and hides the public state transition in PrefillAdder.

Confidence: high

Scope-risk: narrow

Directive: Keep chunked_req_in_batch and has_chunked_req_in_batch updated together when adding new chunked admission paths.

Tested: Remote cjy-glm5-new: PYTHONPATH=python python -m pytest -q test/registered/unit/managers/test_prefill_adder.py -> 26 passed; combined run with scheduler load accounting tests -> 27 passed.

Not-tested: Full ETE restart after this commit alone.
This commit is contained in:
laoyao0822
2026-06-13 02:34:55 +08:00
parent ee843a946b
commit 69ca7045ea
3 changed files with 39 additions and 3 deletions

View File

@@ -500,6 +500,7 @@ class PrefillAdder:
self.can_run_list = []
self.preempt_list = []
self.new_chunked_req = None
self.chunked_req_in_batch = None
self.has_chunked_req_in_batch = False
self.log_hit_tokens = 0
# TODO(lsyin): report the real input tokens excluding page alignment
@@ -924,6 +925,7 @@ class PrefillAdder:
req.set_extend_input_len(min(req.extend_input_len, _rem_tokens))
req.fill_ids = req.fill_ids[: len(req.prefix_indices) + req.extend_input_len]
self.can_run_list.append(req)
self.chunked_req_in_batch = req
self.has_chunked_req_in_batch = True
# A continued chunk carries a real page-floored prefix. Keep that
# footprint in the CP cached/buffer admission state even though the
@@ -1187,6 +1189,7 @@ class PrefillAdder:
self.can_run_list.append(req)
self.new_chunked_req = req
self.chunked_req_in_batch = req
self.has_chunked_req_in_batch = True
self._req_inc_lock_ref(req)

View File

@@ -2584,13 +2584,13 @@ class Scheduler(
affinity_window_used = 0
affinity_head_pending = True # first classified candidate = FCFS head
affinity_batch_warm_led: Optional[bool] = None
if affinity_on and adder._chunked_req_in_batch is not None:
if affinity_on and adder.chunked_req_in_batch is not None:
# A chunked-led batch must carry the CHUNK's class: a 65536 first
# chunk is cold-led (further colds are free density and the caps
# bound them); a tail chunk over a big cached prefix is warm-led.
# Latching from the first loop candidate instead would invert
# cold-led-admits-everything and spuriously STOP the scan.
chunked = adder._chunked_req_in_batch
chunked = adder.chunked_req_in_batch
affinity_batch_warm_led = (
len(chunked.prefix_indices)
+ int(getattr(chunked, "host_hit_length", 0) or 0)
@@ -2656,7 +2656,7 @@ class Scheduler(
is_warm=req_is_warm,
batch_empty_for_affinity=(
len(adder.can_run_list)
- (1 if adder._chunked_req_in_batch is not None else 0)
- (1 if adder.chunked_req_in_batch is not None else 0)
== 0
),
# None = nothing admitted yet; only reachable together