Structural repair: - 13 pages were the same document twice (each exactly 2x its HEAD size), a second frontmatter block whose closing fence had been glued onto a body line by a frontmatter rewrite that re-read its own output. Un-doubled by cutting at the second frontmatter and keeping the copy whose body is a superset; the orphan census reports 0 lost tokens against HEAD. - log.md: one entry per date, bare `## YYYY-MM-DD` headings, newest first — 66 dated headings merged into 34, titles demoted to bold leads, every content line verified present. The file had been descending at the head and ascending at the tail. Ownership moves: - New `LLM/frank-medium.md` is the locator for the retired Dankserver endpoint: era windows quoted from each era page's own banner, no numbers restated, and the two unresolved date conflicts recorded instead of silently resolved. `frank-archon.md` links to it instead of restating the pre-rename window. - The four Pipeline-Parallelism stubs (frontmatter only, no body) are gone; `Multi-Node Runtimes.md` owns runtime construction, launch, mixed-vendor verdicts and cross-split spec decode, and the four links that pointed at the stubs were repointed at it or at the drafter page. - Authentik's three stub pages fold into `Authentik.md`, with the process detail and the outpost reference split out so the parent stays under the length hint. Verified corrections (host census + live probe, 2026-10-19): - The MXFP4 checkpoint two pages called the "on-disk rollback" is gone: /home/dank/models/ holds StillDeadcode, rad and tpl.jinja. Stated once, on the era page that owns that payload; the swap page now links to it. - frank-medium-radiance-mxfp4: the 4.24/7 accept rate belongs to the DFlash2 arm measured on the FP8 target, not to the MXFP4 era; the 3-family soak run census is kept once (155 requests) instead of twice (~120 and 155). - Fleet shapes re-confirmed against the live endpoints before touching any page: 3x200000 fp8 KV, 2x200704, 2x262144. Index rows are regenerated, not hand-carved. Net -1,849 vault lines.
16 KiB
type, title, description, tags, timestamp
| type | title | description | tags | timestamp | ||||
|---|---|---|---|---|---|---|---|---|
| reference | Multi-Node Runtimes | How each two-machine runtime is built and launched, what it can combine with, and the mixed-vendor verdicts. |
|
2026-10-19 |
Multi-Node Runtimes
Two runtimes can put one model on two machines: llama.cpp over the ggml-rpc backend, and vLLM with pipeline parallelism. This page owns the cross-runtime facts — how each is built and launched, what each can and cannot be combined with, and the mixed-vendor verdicts. Facts owned by a sibling page are linked, not restated. Bytes-per-token arithmetic and link budgets belong to Ethernet Bandwidth Math, throughput estimates to Expected Performance, the real deployment and its verified gotchas to Qwen3.8 PP Deployment, the educational scripts to Sample Script Set, drafter mechanisms to DFlash DSpark Speculative Decoding, single-host multi-GPU placement to Llama Cpp Multi-Device Splits.
What each runtime is
Both distribute by layers, not inside layers.
| llama.cpp over ggml-rpc | vLLM pipeline parallelism | |
|---|---|---|
| unit of distribution | a contiguous slice of layers (--split-mode layer, the default) |
a contiguous slice of layers (--pipeline-parallel-size) |
| process model | one llama-server/llama-cli on the head; a ggml-rpc-server per worker |
one vllm serve per node, one engine across them |
| what crosses the wire | whatever graph work the head offloads to the remote devices | the hidden state at each stage boundary, point to point |
| KV cache | distributed with the weights; the KV of a layer lives with the owner of that layer | each stage holds the KV of the layers it owns |
| speculation together with the split | yes in llama.cpp (see below) | no, per vLLM's own docs |
Upstream's own summary is why layer-wise is the ethernet choice: pipeline parallel "minimizes data transfers between GPUs but requires many tokens to scale well", while tensor parallel "does multiple cross-GPU reductions per layer … much more bottlenecked by the GPU interconnect speed".
Do not carry the tensor path across machines: --split-mode tensor is
experimental, needs flash attention, rejects quantized KV, and is not
implemented for the MoE and hybrid architectures the guide lists — and
per-tensor placement across vendors is not expressible (§1 of Llama Cpp Multi-Device Splits).
llama.cpp over ggml-rpc
Build and launch
Both sides take -DGGML_RPC=ON next to that host's own backend:
cmake .. -DGGML_CUDA=ON -DGGML_RPC=ON # a CUDA worker; -DGGML_HIP=ON for an AMD one
cmake --build . --config Release
Worker side — ggml-rpc-server exposes ggml devices on the remote host:
bin/ggml-rpc-server # endpoint 127.0.0.1:50052 by default
bin/ggml-rpc-server --device CUDA0 -c # or CUDA_VISIBLE_DEVICES=0; -c = local cache
- It exposes every accelerator it can see; a host with no accelerator exposes a
single
CPUdevice.--deviceandCUDA_VISIBLE_DEVICESare equivalent ways to narrow that set. -ckeeps large tensors in$HOME/.cache/llama.cpp/rpc(redirect withLLAMA_CACHE) so a big model does not re-stream per load; that cache filling the worker disk is a recorded fleet incident (Qwen3.8 PP Deployment).
Head side — build the local backends plus -DGGML_RPC=ON, then name the
workers:
llama-server -m model.gguf --rpc 192.168.88.10:50052,192.168.88.11:50052 -ngl 99
--rpc is a comma-separated list of host:port, one entry per
ggml-rpc-server; the head's own devices stay in the pool next to the remote
ones. Launch scripts for this shape: Sample Script Set.
Split, context, KV
- Default placement: weights and KV across all devices, local and remote,
"in proportion to each device's available memory". Override with
--tensor-split, whose proportions follow the order in--device. Why the fleet always pins it (a Strix reports a huge GTT window, so the automatic split lands on the slow device) is Qwen3.8 PP Deployment's. -sm layer(the default) is pipeline parallelism: each device holds a contiguous slice of layers and the KV cache of a layer lives on the device that owns that layer.- KV types are the usual
-ctk/-ctv,f16by default.--fitis on by default and sizes unset arguments to device memory; turn it off to hold a context you set on purpose. Context is one global--ctx-size— the RPC README documents no per-node context or per-node KV knob. - Upstream's out-of-memory ladder (stated for tensor mode, useful order
anyway): lower
--ctx-size, then--parallel, then--n-gpu-layers. - Transport is TCP; RDMA is negotiated at the handshake with no flag changes
and falls back to TCP unless both peers can use it (Linux RoCEv2 via
libibverbs, macOS RDMA over Thunderbolt 5 vialibrdma). It is point to point — name the peer's RDMA-capable address in--rpcor the session stays on TCP.GGML_RPC_NO_RDMA=1forces TCP;GGML_RPC_DEBUGtraces the backend.
Upstream calls the backend a proof of concept, "fragile and insecure" (see the Security section). Two limits shape the design: decode is bound by the per-step round trip, not by the link's bytes (Ethernet Bandwidth Math), and every node must run the identical build or the handshake hangs (Qwen3.8 PP Deployment).
vLLM pipeline parallelism
Provenance. Flags and mechanics below were recorded 2026-08-14 and are not re-checked upstream in this pass (see "Unverified in this pass"); the incompatibility lines, the method catalog and the issue history are re-verified.
--pipeline-parallel-sizedivides the layers into contiguous stages;--tensor-parallel-sizestill works inside a node, so the canonical two-node shape is tp = GPUs per node, pp = nodes.- Two backends: Ray (
--distributed-executor-backend ray, the worker joining aray start --head) or multiprocessing (--distributed-executor-backend mpwith--nnodes,--node-rank,--master-addr,--headlesson the follower).mpavoids the Ray dependency; Ray brings the cluster manager. - What the interconnect must carry: one activation tensor per stage boundary
per forward pass, point to point — not a per-layer reduction. That is the
whole cross-node traffic story; the byte arithmetic and link budgets are
Ethernet Bandwidth Math. Pin the NIC vLLM talks on
(
NCCL_SOCKET_IFNAME) rather than letting it guess an interface. - The PP bubble: with N stages and one sequence in flight, one stage works while N-1 idle, so pp=2 costs half the machine at batch one. Batching is the cure — pipeline parallelism "requires many tokens to scale well" — and the microbatch formula is Ethernet Bandwidth Math §5.3.
- KV and context: each stage keeps the KV of its own layers, so the pool grows
with the stage count, and
--max-model-lenis not reduced by the split (recorded 2026-08-14, unverified here). - What it cannot combine with, in vLLM's words: "Pipeline parallelism is not
composable with speculative decoding as of
vllm<=0.15.0", and "Speculative decoding with a draft models is not supported invllm<=0.10.0". Composing the two has been requested since 2024 and closed stale (#6911, #10615); PP also carries a Qwen3.5 bug report closed stale without a fix (#36643). - Method catalog at v0.25.1: EAGLE, MTP, draft model, PARD, MLP, n-gram, suffix
decoding, hidden-state extraction, a custom proposer class, dynamic
speculative decoding;
dflashis an acceptedmethodvalue.
Speculative decoding across the split
llama.cpp chains several implementations behind one comma-separated
--spec-type list; the split does not change the chain, only where its passes
run. Mechanisms, chaining laws and drafter KV sizing are
DFlash DSpark Speculative Decoding's; only the split interaction is here.
| Method | llama.cpp type | Over ggml-rpc | With vLLM PP | Why |
|---|---|---|---|---|
| MTP | draft-mtp |
works; not documented upstream, but run this way on this fleet's split head with acceptance measured (Qwen3.8 PP Deployment) | no | Context-backed drafter: it needs a draft context and runs in the head process, so RPC devices are simply more devices under it |
| DFlash | draft-dflash |
same gate, same status as MTP | no | Same draft-context gate (ctx_dft); the drafter's KV lands on whichever device the draft context is built on — the one thing to check on a split |
| ngram-mod | ngram-mod |
safest of the four: no draft model, no draft context, no remote draft pass | no | Draftless — proposals come from cached token n-grams in the head, so the split adds no device work |
| DSpark | draft-dspark |
unproven over RPC — not a missing feature | no | draft-dspark exists upstream; nobody has measured it with the target split across two machines |
Correction (2026-10-19). A retired stub in this directory asserted "DSpark
is vLLM-only." False. draft-dspark is in upstream llama.cpp — parsed in
common/arg.cpp, mapped to COMMON_SPECULATIVE_TYPE_DRAFT_DSPARK in
common/speculative.cpp, where it carries a Markov head and an anchor-first
block layout and aborts with DSpark draft has no confidence head: please set --spec-draft-p-min 0 when the drafter has no confidence head. What is unproven
is running it over RPC, and that is the honest limit of the claim.
The vLLM column is uniform because that statement is blanket: it names pipeline parallelism, not a method, so n-gram and suffix are excluded as written. vLLM gives no mechanism with it; "the drafter must sit next to the target's layers, which a stage split separates" is a reading, not upstream's words.
Upstream likewise documents neither for nor against --rpc plus
--spec-type. What the implementation does say is structural: every
speculative implementation is built in the head process against the head's
device set, and draftless types need no draft context at all. Routing draft
passes to a remote worker, however, has never been tested.
Mixed-vendor reality
What works today:
- One vendor per node. RPC is backend-agnostic by construction: upstream's
own diagram has a host exposing CUDA0+CUDA1, a host exposing Metal, and a
host exposing CUDA0+CPU, all driven by one main host over TCP. Each node
builds its own backend plus
-DGGML_RPC=ON; nothing speaks CUDA-to-ROCm. - Identical build tag on every node, worker restarted before head. The verified version-skew gotcha is Qwen3.8 PP Deployment's.
- Speculation on the head while the split carries the target (table above).
- RDMA when both peers have it, auto-negotiated at the handshake; the size of the gain is third-party and unverified here.
Unproven or broken:
- One binary holding both CUDA and ROCm for a same-host layer split: reported to compile and then list only CUDA devices (issue #11506, third-party, unverified). Vulkan is the reported single-binary cross-vendor path, and single-host placement is Llama Cpp Multi-Device Splits's, whose verdict is that per-tensor placement across a vendor mix never works.
- vLLM across a CUDA node and a ROCm node: no known experiment; both ends run the same backend (recorded 2026-08-14). AMD's own two-Halo clustering guide is tensor parallelism over RCCL, not a mixed-vendor split.
- DSpark over RPC: unproven, see the correction above.
- The exact NVIDIA-desktop + Strix-Halo-NUC pair has no published benchmark, and the third-party mixed-vendor figures it is estimated from (Metal+CUDA over 10 GbE, two Strix Halos over USB4, a three-card CUDA+ROCm set over 1 GbE, a Vulkan triple in one box, an AMD four-node Strix cluster) live on Expected Performance and Ethernet Bandwidth Math, each named with its model and hardware. None was re-verified in this pass.
Security
ggml-rpc-server has no authentication and no encryption. Upstream's own
warning: the backend is "in a proof-of-concept development stage. As such, the
functionality is fragile and insecure. Never run the RPC server on an open
network or in a sensitive environment!" It binds 127.0.0.1:50052 by default —
safe by accident. Bind a routable address and any host that can reach the port
can allocate memory there and supply the tensors it computes on. Trusted LAN
only, firewalled or tunnelled; never a public address.
Unverified in this pass
Every item was first recorded 2026-08-14, in the research that preceded this page. Nothing is silently deleted; none is backed by the sources cited below.
- RPC protocol version and handshake rule — recorded as protocol
5.0.0with "major must match, server minor must be ≥ client". The README's own banner printsStarting RPC server v3.0.0; the conflict is unresolved. - RPC internals — a hard cap of 16 servers, synchronous graph compute, no
tensor copy between two RPC servers, workers loading tensors on first use, a
hash-keyed cache above roughly 10 MB, asserts on quantized tensors whose rows
are not 512-aligned, and
-rpconllama-bench(the README names onlyllama-cliandllama-server). - vLLM flag surface —
--pipeline-parallel-size,--tensor-parallel-size,--distributed-executor-backend {ray,mp},--nnodes,--node-rank,--master-addr,--headless, theray start --headjoin,NCCL_SOCKET_IFNAME. - vLLM mechanics — one activation handoff per stage boundary per forward
pass, a worked ~512 MB handoff for a hidden-5120 model at batch 8 and 2048
positions,
--max-model-lenunchanged by PP, ~50% idle at pp=2 batch one. - vLLM throughput verdicts for a 27B across two nodes over gigabit-class links; superseded as an estimate by Expected Performance.
- Mixed-vendor claims — a CUDA+HIP build listing only CUDA devices (#11506), Vulkan as the universal cross-vendor backend, AMD's two-Halo clustering guide being RCCL tensor parallelism, WiFi costing about ten times wired, the slowest hop setting the decode pace, RDMA worth a few percent.
- Draft over RPC — that the draft model stays on the head, and that routing draft passes to a remote worker has never been confirmed.
Citations
- llama.cpp RPC README, accessed 2026-10-19 — server usage and device exposure,
-DGGML_RPC=ONon both sides, the--rpc host:portlist, proportional weight+KV split and--tensor-split, the-clocal cache, RDMA negotiation andGGML_RPC_NO_RDMA, the proof-of-concept and no-authentication warning. - llama.cpp multi-GPU guide, accessed 2026-10-19 — split modes (
-sm layer= pipeline parallelism, KV with the layer owner),-ts/-ngl/-ctk/-ctv/-fit, the pipeline-versus-tensor summary, the tensor-mode limits. - vLLM speculative decoding docs, v0.25.1, accessed 2026-10-19 — the pipeline-parallelism incompatibility statement, the draft-model version floor, the method catalog.
- llama.cpp
common/speculative.cpp, accessed 2026-10-19 — the speculative implementation set includingdraft-dspark, its draft-context gate, its confidence-head error. - vLLM issue #6911, "[Feature]: Combine pipeline parallelism with speculative decoding", opened 2024-07-29, closed not-planned 2025-03-28, accessed 2026-10-19.
- vLLM issue #10615, "[Usage]: Does speculative decoding support pipeline parallelism?", opened 2024-11-25, closed not-planned 2025-04-18, accessed 2026-10-19.
- vLLM issue #36643, "[Bug]: Qwen3.5 does not work with pipeline parallelism", opened 2026-03-10, closed not-planned 2026-09-24, accessed 2026-10-19.