Skip to content

docs: serving one model across two DGX Sparks via llama.cpp RPC - #1620

Open
Defilan wants to merge 3 commits into
defilantech:mainfrom
Defilan:docs/spark-two-node-rpc
Open

docs: serving one model across two DGX Sparks via llama.cpp RPC#1620
Defilan wants to merge 3 commits into
defilantech:mainfrom
Defilan:docs/spark-two-node-rpc

Conversation

@Defilan

@Defilan Defilan commented Aug 20, 2026

Copy link
Copy Markdown
Member

What

Runbook for serving one model across two DGX Sparks via llama.cpp RPC: docs/dgx-spark-two-node-rpc.md, cross-linked from the existing Spark guide.

Why

Refs #1423

The pattern works and is in use (DeepSeek V4-Flash, 144GiB, spanning both Sparks), and its runtime half is built and CI-guarded (llmkube-runtimes #32: GGML_RPC=ON, ggml-rpc-server shipped in cuda-gb10, the deployed image). But the cluster-side wiring existed in no repository. Reconstructing it this week required archaeology across four repos, the NVIDIA clustering docs, and a commit message. The next use is immediate: Ornith-1.5-397B Q4_K_M is 224GiB, which no single Spark can hold.

How

The runbook covers the full chain, each layer sourced:

  • fabric addressing via dgx-rdma.yml and its verify play (RoCE /30s on the ConnectX-7 link)
  • the RPC worker pod: hand-pinned to the remote Spark, hostNetwork, bound to the fabric address only (the RPC protocol is unauthenticated; the point-to-point binding is the entire security model)
  • the InferenceService: normal single-node shape plus extraArgs: ["--rpc", ...], with the Model staging multi-artifact from MinIO via spec.files
  • wire verification: both GPUs resident, fabric traffic during decode, correct completion. Ready alone has fooled this fleet before
  • sizing (sum minus overheads, why MoE models are the ones worth spanning) and known limits

Every manual step is annotated as a requirement on #1423, which is the operator feature this runbook papers over: the worker is unplaced, unmonitored, and unhealthchecked by the operator today.

Checklist

  • Tests added/updated - n/a, documentation
  • make test passes locally - no code changed
  • make lint passes locally - no Go changed
  • Commit messages follow conventional commits
  • All commits are signed off (git commit -s) per DCO
  • AI assistance (if any) is disclosed above, per CONTRIBUTING.md
  • Documentation updated (if user-facing change) - this is the documentation

Assisted-by: Claude Opus 5 (reconstructed the wiring from the fabric role, the runtimes commit, the NVIDIA clustering doc, and the surviving cluster artifacts; wrote the runbook).

…pp RPC

The pattern is proven (DeepSeek V4-Flash, 144GiB, both Sparks) and the
runtime half is built and guarded (llmkube-runtimes defilantech#32: GGML_RPC=ON,
ggml-rpc-server shipped in cuda-gb10), but the cluster-side wiring lived in
no repo: the worker pod placement, the fabric-address security model, the
--rpc extraArgs shape, and the wire verification that distinguishes a real
two-node split from a Ready that quietly serves from one GPU.

Written now because the next use is immediate (Ornith-1.5-397B Q4_K_M at
224GiB, which no single Spark can hold) and because the pattern is the
two-node rehearsal for paired DGX-class hardware generally. Every manual
step is annotated as a requirement on defilantech#1423, which is the operator feature
this runbook papers over.

Refs defilantech#1423

Signed-off-by: Christopher Maher <chris@mahercode.io>
@codecov

codecov Bot commented Aug 20, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Caught by executing the runbook: the object form is rejected by the
apiserver with a strict decoding error. The manifest now matches what the
live serve actually accepted.

Signed-off-by: Christopher Maher <chris@mahercode.io>
…lure modes

Attempt one on Ornith-1.5-397B Q4_K_M (224GiB) OOM-killed the unbounded
worker mid-tensor-upload, which surfaced on the main side as a network-
looking RPC send failure, and the main node's mmap page cache stacked on
its UMA weight share drove ahazidgx1 unreachable. Three additions, all
paid for: worker memory bounds are mandatory, --no-mmap is mandatory at
this scale on unified memory (the Strix >64GB rule at twice the size),
and the real per-node budget is ~118GiB allocatable, not 128.

Also documents spec.resources.gpu as the taint-toleration trigger and the
Terminating-hang when a worker's peer dies mid-transfer.

Signed-off-by: Christopher Maher <chris@mahercode.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant