Hyperloom Remote Demo — Multi-Node Inference Optimization#
Optimize inference on a multi-node GPU cluster (--nodes >= 2): Hyperloom
benchmarks a long-lived remote server, restarts it with new settings each round,
and improves throughput.
To run it, hand the agent (or Primus-Claw) the
workload skill,
which carries the exact optimize flags and environment for either backend,
and the agent launches and monitors the run for you. This page explains what
that skill contains and what each variable means.
Two backends#
Pick one; both serve the same model, differ in control plane:
infera: GPU pods idle with sshd; Hyperloom SSHes in to (re)launch sglang each round. Supports PD disaggregation (separate prefill / decode pods).
rayjob: pods run under Ray; restarts go through the Ray dashboard.
Requires --mn-image pointing at an operator-supplied image
(<INFERA_SSHD_IMAGE> must include sshd; <RAYJOB_IMAGE> is a standard Ray
image).
Two ways to connect the cluster#
Path A: SaFE-managed (default): The optimizer runs in a Primus-SaFE sandbox with
SAFE_API_URL+SAFE_API_KEY(both auto-injected by the platform). Hyperloom creates the GPU pods (create-infera/create-rayjob) and tears them down withstop-multi-job. Primus-SaFE is AMD’s open-source training and inference management platform.Path B: External: The cluster is already running with no SaFE API; you point Hyperloom at it with
HYPERLOOM_MN_EXT_*env vars (see below).
If both SaFE creds and HYPERLOOM_MN_EXT_* are set, SaFE wins (Path A).
What the agent produces#
A session under $USER_DATA_PATH/<model_basename>/<UTC_timestamp>/ with launcher
logs and a persisted state.json (holds phase, cumulative_gain,
crash_count, stop_reason) for status and --resume. $USER_DATA_PATH comes
from the environment (platform-injected under SaFE).
The workload skill (what you hand the agent)#
Give the agent the pinned skill:
Use the skill at docs/how-to/multi-node/hyperloom-remote-mn-qwen3-30b/SKILL.md
It contains two ready-to-run blocks — Workload A (infera + PD) and
Workload B (rayjob) — each a FLAGS list plus an Environment block. The
agent runs inference_optimizer optimize with them, reports session id / log /
PID, and monitors state.json until a terminal stop_reason.
Variables in those blocks#
FLAGS (passed to optimize):
Flag |
Meaning |
|---|---|
|
Model path under |
|
Node count ( |
|
|
|
Container image ( |
|
Per-pod resources (default GPUs 8) |
|
Tensor / expert parallel (MoE: often |
|
Benchmark input/output length and concurrency (flags only — |
|
Target GPU (e.g. |
|
|
|
Optimization goal and time budget |
|
infera PD split (prefill + decode roles; node counts sum to |
|
PD KV transfer plane (prefer |
|
rayjob shared sglang args (applied each restart) |
|
Skip the framework-tuning agent |
Environment (exported before optimize; sandbox-side):
Var |
Meaning |
|---|---|
|
Benchmark sequence-length jitter (env has a fallback; |
|
Tool checkouts under |
|
Optional |
|
Enable + persist the aiter kernel path |
|
PD bootstrap / wait timeouts (infera PD only) |
Platform-injected (do not set): SAFE_API_URL, SAFE_API_KEY,
SAFE_WORKSPACE, WORKLOAD_ID, DISPLAY_NAME, and USER_DATA_PATH.
Path B — External mode (no SaFE)#
Same run as Path A, but you point Hyperloom at an already-running cluster instead
of letting SaFE provision it. Unset the SaFE creds, set
HYPERLOOM_MN_EXT_SERVICE_URL, and Hyperloom skips provisioning and benchmarks
that URL directly. The same FLAGS / Environment blocks apply.
Variable |
Backend |
Required |
Meaning |
|---|---|---|---|
|
both |
yes |
Benchmark frontend URL ( |
|
infera |
PD |
Prefill / decode pod IPs (comma-separated) |
|
infera |
aggregated |
Worker pod IPs (comma-separated) |
|
infera |
yes |
Private SSH key already authorized on the pods |
|
infera |
no |
SSH base port (default |
|
infera |
no |
known_hosts path (else relaxed host-key check) |
|
rayjob |
no |
Ray head IP (Dashboard |
|
rayjob |
no |
Ray Dashboard auth token if required |
infera requires
SSH_KEY+ at least one*_IPS, elseoptimizefails fast (sys.exit(2)).rayjob uses
HEAD_IPfor restarts (not SSH); without it, benchmark-only.
Example (infera + PD disaggregated):
unset SAFE_API_URL SAFE_API_KEY
export HYPERLOOM_MN_EXT_SERVICE_URL=http://<frontend-host>:8000
export HYPERLOOM_MN_EXT_PREFILL_IPS=<prefill-ip> HYPERLOOM_MN_EXT_DECODE_IPS=<decode-ip>
export HYPERLOOM_MN_EXT_SSH_KEY=/path/to/id_ed25519
inference_optimizer optimize --model ${NFS_SHARED_ROOT}/models/Qwen3-30B-A3B \
--nodes 2 --mn-backend infera --pd-mode disaggregated \
--pd-prefill-nodes 1 --pd-decode-nodes 1 --tp 8 --ep 8 \
--pd-transfer-backend mooncake ...
For rayjob, swap --mn-backend rayjob and set HYPERLOOM_MN_EXT_HEAD_IP instead
of the SSH/IPs vars.