Phase 2 of the worker decouple initiative. Final slice.
Scope
Extract the decode loop (worker:5592–6427 + decode-side of PAGE BOUNDARY, ~1500 LOC) into batchgen/worker/decode.py.
Design
class ModelExecutorBackend(Protocol): # reused from Slice 6
def forward_decode(self, batch) -> DecodeOutputs: ...
@dataclass(frozen=True)
class DecodeStepRequest:
active_uuids: tuple[str, ...]
cache_seqlens: torch.Tensor
position_ids: torch.Tensor
cuda_graph_decision: GraphDecision # from Glm5CudaGraphAdapter (Phase A/B/C)
class DecodeScheduler:
def __init__(self, *, executor: ModelExecutorBackend, sync: SyncCoordinator): ...
def step(self, req: DecodeStepRequest) -> DecodeStepResult: ...
Composes with the cuda-graph adapter that already exists (Phase A/B/C Glm5CudaGraphAdapter). The handler's step calls adapter.eligibility(batch_state) → adapter.prepare_replay_inputs(...) → manager.replay(...) exactly as the current worker does.
3-PR plan
- PR-9.1 Port.
- PR-9.2 Dual-path gate + compare-mode + H20 L2-2048 + L2-4096 back-to-back (critical: this is the hottest path).
- PR-9.3 Cleanup. After this PR the worker is ~6,000 LOC.
Pre-merge checklist (from scheduler-split Step 9 fix-up commits)
Design source reference
origin/tairan/scheduler-split:batchgen/worker/decode.py (878 LOC).
origin/tairan/worker-reextract:batchgen/worker/decode/ (decomposed into 9 sub-files) — out of scope here; single-file form for now.
Design: /Users/andrew/.claude/plans/the-task-for-this-declarative-melody.md (POIS-local). Builds on the Phase A/B/C cuda-graph contract pattern (PR #162/#163/#164, merged 2026-05-27).
Phase 2 of the worker decouple initiative. Final slice.
Scope
Extract the decode loop (worker:5592–6427 + decode-side of PAGE BOUNDARY, ~1500 LOC) into
batchgen/worker/decode.py.Design
Composes with the cuda-graph adapter that already exists (Phase A/B/C
Glm5CudaGraphAdapter). The handler'sstepcallsadapter.eligibility(batch_state)→adapter.prepare_replay_inputs(...)→manager.replay(...)exactly as the current worker does.3-PR plan
Pre-merge checklist (from
scheduler-splitStep 9 fix-up commits)self.modelrefs translated to backend-injected handle.DualKVCacheCoordinatorimport resolved.configure_decoding.parallel_manageraccess via Protocol, nothasattr(self, 'parallel_manager')._put_sequences_on_holdrouted throughHostKVRebalancer(Slice 7).Design source reference
origin/tairan/scheduler-split:batchgen/worker/decode.py(878 LOC).origin/tairan/worker-reextract:batchgen/worker/decode/(decomposed into 9 sub-files) — out of scope here; single-file form for now.Design:
/Users/andrew/.claude/plans/the-task-for-this-declarative-melody.md(POIS-local). Builds on the Phase A/B/C cuda-graph contract pattern (PR #162/#163/#164, merged 2026-05-27).