Model Capacity Audit
Use this command before enabling the global model scheduler. It compares the
configured worker roster with live Ollama /api/ps responses from the serving
nodes, reports loaded model residency, and suggests resident-weight settings
when a roster model is currently loaded on a node.
By default the command is read-only. It does not place work, mutate Valkey state, or change model residency.
Command
python -m aibs_backend.interfaces.cli.audit_model_capacity
Optional ad-hoc node inspection:
python -m aibs_backend.interfaces.cli.audit_model_capacity \
--node-url http://10.4.3.16:11434 \
--node-url http://10.4.3.17:11434
Machine-readable output:
python -m aibs_backend.interfaces.cli.audit_model_capacity --json
Active warm-up measurement:
python -m aibs_backend.interfaces.cli.audit_model_capacity \
--warmup \
--warmup-node-id box-c \
--json
--warmup deliberately sends a tiny non-streaming Ollama request for each
configured worker model, samples /api/ps while that model is resident, and
then unloads the model with keep_alive=0. Use it only during an operator
measurement window because it consumes model slots and may evict currently
loaded models. Omit --warmup-node-id to measure every configured node.
What It Checks
AIBS_MODEL_ADMISSION_WORKER_ROSTERremains the source of model lanes and roles. The audit does not introduce a second model catalog.Each worker should have measured
resident_weight_gbandactive_parameter_billions.Ollama
/api/pssuppliessize_vramandsize; the audit reports those as resident-weight suggestions for matching workers. It does not infer active parameter counts.--warmupcan produce resident-weight suggestions even when the boxes are idle and the configured worker models are cold.Each configured cluster node should expose live
/api/psstate.The
ready_to_enable_global_schedulergate is independent ofAIBS_MODEL_CLUSTER_ENABLED. That lets operators audit first, then enable only after Valkey coordination, node budgets, worker measurements, and the node-residency monitor are present.
Optional Host Telemetry Agent
For richer System Health charts, install the lightweight host telemetry agent on each AI box and expose it only on the trusted management network:
python scripts/aibs_node_telemetry_agent.py --host 0.0.0.0 --port 8765
The agent is read-only. It reports CPU, memory, GPU busy, raw VRAM, raw GTT, and
combined GPU memory from Linux /proc and DRM sysfs. AMD APU/iGPU deployments
can place model buffers in GTT, so operator-facing capacity should use combined
GPU memory rather than raw VRAM alone. The agent does not run model calls,
mutate Valkey, or make placement decisions. The backend polls the URLs
configured through AIBS_MODEL_CLUSTER_NODE_HOST_TELEMETRY_URLS and stores
those values beside the fenced residency snapshots for operator visibility.
If the agent is not configured or unavailable, the node remains schedulable when its fenced residency facts are fresh. System Health will show host telemetry as unavailable for that node.
Valkey Placement Test Gate
The global placement primitive requires Valkey 8+. The Valkey Lua
scripts use server-side TIME while writing placement state so all API
processes share one clock authority. Do not enable the global scheduler against
older Redis-compatible deployments.
Run the atomic placement tests against a real Valkey instance:
AIBS_TEST_VALKEY_URL=redis://localhost:6379/15 \
python -m pytest tests/infrastructure/model_scheduling/test_redis_atomic_placement.py
Without AIBS_TEST_VALKEY_URL, the real Valkey behavior test is skipped and
only the deterministic in-memory/fake-client tests run. The legacy
AIBS_TEST_REDIS_URL name remains a temporary compatibility fallback.
Residency Monitor Takeover Gate
Before enabling AIBS_MODEL_CLUSTER_ENABLED=true, prove that the elected
residency monitor can die without leaving stale node health trusted by the
placement scheduler:
python -m aibs_backend.interfaces.cli.prove_model_monitor_takeover --json
The proof command:
creates an isolated Valkey namespace;
starts monitor owner A as a subprocess;
waits for owner A to publish healthy samples for every enabled model node;
starts monitor owner B as a standby;
hard-kills owner A, without graceful lease release;
waits for owner B to publish newer healthy samples;
verifies correctness: no pre-kill owner loss and no successful fenced writes from a deposed owner;
measures handover duration separately from correctness;
fails the availability gate unless the target deployment topology observes fresh replacement samples inside
AIBS_MODEL_CLUSTER_MAX_RESIDENCY_STALENESS_MS;captures owner stderr and classifies expected shutdown artifacts separately from real owner churn;
deletes the isolated proof namespace so proof scheduler hashes do not accumulate in Valkey.
The safe timing bound is:
residency_monitor_poll_interval
+ residency_monitor_lease_ttl
+ residency_monitor_standby_retry
+ 2 * residency_monitor_poll_timeout
<= max_residency_staleness
With the current recommended values, 3 + 6 + 1 + 2 * 2 = 14s, which fits
inside the 15s staleness window.
For deployment-grade evidence, run the proof repeatedly and require every run to pass:
python -m aibs_backend.interfaces.cli.prove_model_monitor_takeover --json --repeat 3
When running from the local dev machine through an SSH tunnel to Valkey, use the split contract explicitly:
python -m aibs_backend.interfaces.cli.prove_model_monitor_takeover \
--json --repeat 3 --handover-gate report-only
In that mode, correctness still gates the result. Long handover duration is reported as an availability finding because the dev tunnel is not the production transport. On the demo topology, where the backend runs on an AI box and reaches Valkey over LAN, use the default strict handover gate before enabling shared traffic.
Treat passed=true as a scheduler liveness gate, not as full production
approval. It proves election/failover and fresh node telemetry. It does not
prove answer quality or routed LLM behavior under real user load.
If correctness fails, do not enable the cluster scheduler. If only the dev
tunnel handover report fails, document the admission-pause duration and rerun
the strict proof from the target topology.
Controlled Enable Smoke Test
After the audit and takeover proof are green, enable the scheduler only in the target test environment:
AIBS_MODEL_CLUSTER_ENABLED=true
Then restart the API process. Do not rely on --reload to notice a .env-only
change; some reload configurations watch Python files but not environment
files.
Run:
python -m aibs_backend.interfaces.cli.audit_model_capacity --json
Expected enable-state result:
cluster_enabled=trueready_to_enable_global_scheduler=trueready_for_global_scheduler=true
Then run the real API path:
one narrow or single-document query;
one broad or agentic query;
two concurrent broad queries from separate conversations or users when possible.
Acceptance evidence:
global placement acquisition/release logs appear;
leases include
node_idandnode_base_url;answer quality does not regress;
no request remains stuck in answering state after completion/cancel;
Valkey active leases are released or expire according to TTL.
If placement acquisition works but release warnings appear, stop before demo and inspect the placement release path. A scheduler that admits work but leaks capacity is not enterprise-stable.