Repository navigation
Add a dry-run pool placement planner (lloom pool plan) - #59
Closed
data-angel wants to merge 1 commit into
Closed
data-angel wants to merge 1 commit into
data-angel wants to merge 1 commit into
Conversation
Treat every cluster node as one pool and propose which model lanes run where, with which residency, and how each alias routes, plus the diff from what runs now. Phase 1 is read-only: nothing is started, stopped or rerouted, and per-node admission stays the safety layer. - Node inventory (/gateway/node?inventory=1, cached): structured compute archs, memory domains, model-root disk, cached recipe weights, commands and Docker images, and NVIDIA Sync fabric links. - Model-centric catalog from managed runtimes, federated targets, unmanaged lanes declared with a model `pool` block, external models and (opt-in) bundled recipes, with measured footprint and live-metric or benchmark performance. - Pure planner: memory per domain with headroom, TP only across directly linked nodes, arch/platform/accelerator matching, pins and cordons as hard constraints; lexicographic objective (coverage, external fallback, SLOs, demand-weighted latency plus load-time churn); greedy placement plus single-workload local search. Models sharing a runtime share one placement. - Per-alias demand: /gateway/metrics adds `requested` buckets. - Recipes may declare requirements.computeArchs, requirements.tensorParallel and settings.maxSequences (schema, validator, example). - Admission and pool planning share one memory-budget helper. Fixture tests reproduce the three-Spark fleet: all nodes give the sparkqwen-pair-rc16 profile; cordoning the pair gives standalone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
Author
|
Superseded by #74, which integrates the planner together with the rest of the pool feature set against current main. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Phase 1 of making LLooM a pool head. Every cluster node is treated as one pool, and
lloom pool planproposes:It is dry-run only: nothing is started, stopped or rerouted. Per-node admission (
runtime-policy.mjs) stays the safety layer underneath. Full description indocs/pool-planning.md.Node inventory.
GET /gateway/node?inventory=1andGET /gateway/cluster?inventory=1report:sm_121,apple-metal);The inventory is collected on request and cached for 5 minutes, with in-flight requests sharing one collection. Older gateways fall back to their machine profile.
Model-centric catalog (
src/pool-catalog.mjs). Variants come from:node/placement;poolblock (e.g. a hand-run TP2 server);--consider-installs, bundled recipes.Each variant has structured requirements: node count, TP, archs, backend, context and sequences. Memory is the configured estimate raised to the measured RSS when that is larger. Performance comes from live gateway metrics, falling back to the best matching benchmark.
Pure planner (
src/pool-planner.mjs).headroomGb;node/placement,keepWarm,pool.pins,--pin,--profile;Per-alias demand.
/gateway/metrics(live snapshots and the persisted history file) addsrequestedbuckets keyed by the requested id. Older gateways fall back to splitting each model's demand across the aliases routed to it.Recipe schema (additive, backward compatible):
requirements.computeArchs,requirements.tensorParallel,models[].settings.maxSequences. Validator and interchange example updated. When the fields are absent, they are inferred from launch settings (CUTE_DSL_ARCH,TORCH_CUDA_ARCH_LIST,--tensor-parallel-size,MAX_NUM_SEQS).Shared helper. Admission and pool planning now use one memory-budget helper (
resource-fit.mjs).Evidence
test/fixtures/pool/spark-fleet.json(anonymized node names) reproduces the three-Spark fleet:sparkqwen-pair-rc16profile's routes and residency, with no diff.standalone. Cognition aliases move to the 27B on spark-node-03 with residencyalways, and the unmanaged pair lane gets a manual stop.Against this Mac's installed config and live gateway,
lloom pool planreports no changes, which matches what is running. Offline mode (config plus local inventory) also works.Tests
node --test test/pool-planner.test.mjs test/pool-catalog.test.mjs test/pool-inventory.test.mjs test/pool-cli.test.mjs: 35 pass. These cover linked-TP sets, arch mismatch, headroom, per-domain memory, local search, external fallback, SLOs, churn hysteresis, shared runtimes, inventory probes and the cache, the gateway inventory flag, CLI fallback and offline JSON.test:cluster;runtime-policy,runtime-policy-configandruntime-memory-safety;metrics-persistence,stream-metrics,server-resilience,dashboard-statusandsecurity;cli-diagnosticsandconfig-profiles;interchangeandinterchange:check;resource-fit;smoke;check:js,lint(only pre-existing warnings),format:checkandgit diff --check.npm test.Security notes
admin-read(/gateway/*GET). It adds model-root paths, image names and fabric peer addresses to what admins can already read: the profile already exposesx-local-modelRoot.runCommandcalls (which,docker image ls) plusstatfs. There is no shell interpolation.Not in this PR
There is no apply or reconcile step, no node self-enrollment or heartbeat, and nothing has been deployed or touched on the live fleet.
🤖 Generated with Claude Code