Repository navigation
perf(scheduler): cap the seats a shared claim may hold - #394
Conversation
Host memory bounds how many workers park on a node but says nothing about time: a time-sliced claim with six seats runs each worker's step six times slower while other GPUs sit idle. --max-seats-per-claim (OPEN_RL_MAX_SEATS_PER_CLAIM, default 0 for no limit) is a hard policy limit. A ledger at the limit is not a selection candidate, and the ledger CAS loop refuses a join past it so two joiners on one snapshot cannot both take the last seat. A worker that finds every eligible ledger full cuts its own claim; with no free device it stays Pending, the reason names the limit, and it waits until a node arrives or a seat frees.
1. [Medium] Multi-candidate race when a join loses the last seat on one claim while another claim still has roomLook at joinExistingClaim in workload_controller.go:527-538: And in assign() (under binpack, the default strategy): What happens under concurrency: • Workers w-3 and w-4 reconcile concurrently (MaxConcurrentReconciles = 4) against the same fleet snapshot. Note: This single-shot SelectClaim behavior existed previously for exclusive/tombstone contention, but with MaxSeatsPerClaim (e.g. 2), deterministic tie-breaking guarantees • Suggestion (Optional or Follow-up): Either remove target from fleet.Claims (or re-read the fleet) and loop in joinExistingClaim when err == errBookingContended, or note that 2. [Low] ensureSeat comment and design.md stale statements
────── |
|
Findings, most important first.
|
…dger, wake on freed seats The cap check in ensureSeat ran only for joins, so a re-book whose seat was gone could append past it; it now gates every write that adds a seat. joinExistingClaim drops a ledger that refuses the booking and selects again instead of cutting a dedicated claim another ledger could have spared. A ClaimLedger watch wakes waiting workers when a seat is released. Explain names the limit only for workers that could have shared, the flag rejects negatives, and the docs say the placement timeout applies to a worker waiting on the limit.
|
Thanks for the review, @droot. Pushed
|
Problem
Binpack seats time-sliced workers on a shared GPU until its host memory runs out. Nothing bounds how many share the GPU in time, so even with free GPUs elsewhere, three or six time-sliced full fine-tuning workers can land on one H100, and each waits through the others' turns.
Change
--max-seats-per-claim(OPEN_RL_MAX_SEATS_PER_CLAIM, default 0 for no limit) caps the workers on one shared claim. A claim at the limit is not offered for placement, and the ledger's compare-and-swap refuses any write that would add a seat past it, so two workers placed at the same time cannot both take the last seat. A worker that finds every eligible claim full moves on to the next ledger with room, and only cuts its own claim when none accepts it. With no free device it stays Pending, with the limit named in its reason, until a GPU or a seat frees up, or fails at the placement timeout like any worker waiting on capacity. A seat released on a shared claim wakes the waiting workers.