Repository navigation
generate: probe the real host->device bandwidth for pcie_frac - #44
Conversation
pcie_frac's defaults (0.55 native / 0.2 canonical) were measured on a PCIe 4.0 x16 link. A x8 card in a x8 slot carries about half of that, and the copy engine's share then waits for DMA that arrived late. Probe the H2D bandwidth once at startup the way the engine uses it (DMA reads from pinned host memory) and scale the default by it: an RTX 5060 Ti at x8 probes 14.1 GB/s -> pcie_frac 0.29 instead of 0.55. --pcie-frac still wins when given, and a machine that cannot run the probe keeps the current default.
|
Thanks. Two things before I take it: 0.1.14 moves the native packs' PCIe share from DMA to the copy kernel (#31: the host could hang inside
|
|
Ran it on 0.1.14 as asked — same box (RTX 5060 Ti 16 GB at PCIe 4.0 x8, Ryzen 7 5700X3D), fixed prompt,
The lower share wins, by ~10.2 ms/round (~17%). The engine's own instrumentation shows why, and it is the mechanism you described: at 0.55 it streams 3.30 experts per layer over the wire, at 0.30 only 1.60. The CPU pool pays for that — gate/up +4.3, down +1.6, The probe on this box now prints On your threshold point — agreed, and I'd take it. Measured 25-26 GB/s on x16 PCIe 4.0 means today's default is the right one there, and scaling it down by 25/26 is a behaviour change for no measured gain. So: if (bw >= 20.0) o.pcie_frac = base; // x16-class link: keep exactly today's default
else o.pcie_frac = std::min(base, std::max(0.05, base * (bw / 26.0)));Say the word and I'll push that as a second commit on this branch (the 20 GB/s cut-off sits between the 13.7 measured here and the 25-26 you cite, so both populations keep the behaviour that measures right for them). Two caveats, stated plainly: 5 runs per arm after dropping the cold one, and this machine drifts ~6% slower under ~40 min of sustained AVX load — the per-pair interleaving is what I lean on (6/6 same sign), not the medians. The 17% is well above that drift, but I am not claiming a third decimal. |
…s only, the share is read by SMs Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0154bwiad8gY7wRehCXy27pN
|
Thanks @pipeob0 - your 6/6 A/B on the x8 card was convincing. Merged in v0.1.20 with the follow-ups you offered: from 20 GB/s up the measured default stays (x16 links), the comment now says the share is read by the SMs over the link (the copy kernel since 0.1.14), and the probe runs for native packs only (the canonical pack's 0.2 was never measured against the link). |
Brings in engine 0.1.13-0.1.20 and upstream PRs Niko1221#42-Niko1221#44, Niko1221#54, Niko1221#59, Niko1221#62-Niko1221#65, Niko1221#67, Niko1221#69 on top of the fork's experimental multi-GPU expert caches. Host test suites pass (expert placement 5935 checks, conversation cache, setup GPU selection, GPU telemetry, IQ pack, calibration); CUDA build and GPU parity remain pending hardware validation.
The PCIe probe sets the share of the missed experts the GPU reads over the link (--pcie-frac): the native default 0.55 from 20 GB/s up, less on a slower link (#44). On Windows HIP it timed its copies with events that do not bracket them there: an RX 6800 read between 3,348 and 25,999 GB/s in 24 engine starts, so every link kept the x16 share. A standalone copy of the probe on that card: its events measure 0.13 ms for the 1 GiB, the host clock 43 ms (25.1 GB/s). On Windows HIP the probe now times the same copies on the host, between two synchronizes (1 GiB, tens of milliseconds): the same RX 6800 on PCIe 4.0 x16 reads 27.2 GB/s in every run, which keeps 0.55 there. On a PCIe 4.0 x8 or 3.0 x16 link the share now shrinks as #44 intended. CUDA and Linux keep the events. Claude-Session: https://claude.ai/code/session_015Ld5YDzuKW1hgMVwwgRZDP Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… bandwidth for the PCIe share
…ive packs only, the share is read by SMs
The PCIe probe sets the share of the missed experts the GPU reads over the link (--pcie-frac): the native default 0.55 from 20 GB/s up, less on a slower link (#44). On Windows HIP it timed its copies with events that do not bracket them there: an RX 6800 read between 3,348 and 25,999 GB/s in 24 engine starts, so every link kept the x16 share. A standalone copy of the probe on that card: its events measure 0.13 ms for the 1 GiB, the host clock 43 ms (25.1 GB/s). On Windows HIP the probe now times the same copies on the host, between two synchronizes (1 GiB, tens of milliseconds): the same RX 6800 on PCIe 4.0 x16 reads 27.2 GB/s in every run, which keeps 0.55 there. On a PCIe 4.0 x8 or 3.0 x16 link the share now shrinks as #44 intended. CUDA and Linux keep the events.
… bandwidth for the PCIe share
…ive packs only, the share is read by SMs
The PCIe probe sets the share of the missed experts the GPU reads over the link (--pcie-frac): the native default 0.55 from 20 GB/s up, less on a slower link (Niko1221#44). On Windows HIP it timed its copies with events that do not bracket them there: an RX 6800 read between 3,348 and 25,999 GB/s in 24 engine starts, so every link kept the x16 share. A standalone copy of the probe on that card: its events measure 0.13 ms for the 1 GiB, the host clock 43 ms (25.1 GB/s). On Windows HIP the probe now times the same copies on the host, between two synchronizes (1 GiB, tens of milliseconds): the same RX 6800 on PCIe 4.0 x16 reads 27.2 GB/s in every run, which keeps 0.55 there. On a PCIe 4.0 x8 or 3.0 x16 link the share now shrinks as Niko1221#44 intended. CUDA and Linux keep the events.
… bandwidth for the PCIe share
…ive packs only, the share is read by SMs Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0154bwiad8gY7wRehCXy27pN
The PCIe probe sets the share of the missed experts the GPU reads over the link (--pcie-frac): the native default 0.55 from 20 GB/s up, less on a slower link (Niko1221#44). On Windows HIP it timed its copies with events that do not bracket them there: an RX 6800 read between 3,348 and 25,999 GB/s in 24 engine starts, so every link kept the x16 share. A standalone copy of the probe on that card: its events measure 0.13 ms for the 1 GiB, the host clock 43 ms (25.1 GB/s). On Windows HIP the probe now times the same copies on the host, between two synchronizes (1 GiB, tens of milliseconds): the same RX 6800 on PCIe 4.0 x16 reads 27.2 GB/s in every run, which keeps 0.55 there. On a PCIe 4.0 x8 or 3.0 x16 link the share now shrinks as Niko1221#44 intended. CUDA and Linux keep the events. Claude-Session: https://claude.ai/code/session_015Ld5YDzuKW1hgMVwwgRZDP Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Integrate v0.1.40.2 V100 performance changes and CPU prefill
…speed table measured on a third-party quant, and the setup's --prefill tips without another repository's issue numbers
…to takes up to 32768 tokens on one GPU and 8192 on a split (one V100, 26K-token prompts: 559 tok/s at 32768 against 367 at 8192 - v1.0.20's speed; two V100s: 709 at 8192 against 551 at 32768); CPU pinning is on by default only with two NUMA nodes or more (one 14-core Xeon, two V100s: 25.8 tok/s unpinned against 24.7 pinned; STRATA_GLM_CPU_PIN=1/0 forces it); the setup's --prefill tips are for splits
…e the GPUs have dropped the old one: the driver frees an ended engine's tens of GB of VRAM and its pinned RAM tier a few seconds after the process is gone, and Niko1221#44's split search measures the cards before anything loads - the 16K reload's engine found 0.09 GB free and failed. The server waits until no GPU lists the old process (NVML), or 5 s where NVML can't say; 2 tests
… build on AMD (Niko1221#52) By @boxwrench: cudaDeviceGetPCIBusId, cudaDevAttrMemoryClockRate and cudaDevAttrGlobalMemoryBusWidth in include/strata/hip_compat/cuda_runtime.h (HIP builds only; CUDA unchanged). Built for gfx1100;gfx1201;gfx1151 with ROCm 7.2.1 and run end to end on a Strix Halo.
Independent of #43 — no stacking needed. It applies on plain
main: it adds one function and replaces thepcie_fracdefault line, while #43 touches only theexpert kernels run onnotice a few lines below. Verified by cherry-picking this commit ontoorigin/mainwith no conflicts.Why
pcie_frac's defaults (0.55 native / 0.2 canonical) were measured on a PCIe 4.0 x16 link (~26 GB/s).The comment right above them says the copy engine's share has to shrink with the link — but nothing measured
the link, and a x8 card in a x8 slot is very common: it is what a 16 GB card with a big expert cache lands on
on most AM4/AM5 boards. There the share was being set to 2× what the wire can carry, so the GPU waits for DMA
that has not arrived. The only user-facing knob was
--pcie-frac, i.e. a per-user guess.What
Probe the host→device bandwidth once at startup, the way the engine actually uses it — DMA reads from
pinned host memory, 4 × 256 MiB, copy engine warmed — then scale the default by it:
Clamped so it can only shrink the share relative to the measured link and never below 0.05, and never above
the current default (a x16 machine keeps exactly today's behaviour).
--pcie-fracstill wins when given, andif the probe cannot run at all the default is kept and the log says so.
On this box (RTX 5060 Ti 16 GB at PCIe 4.0 x8):
Cost and risk
One-time at startup: ~1 GB of copies over a 14 GB/s link ≈ 75 ms, plus a 256 MiB pinned buffer and a 256 MiB
device allocation that are freed again before the arena is built. If either allocation fails, the probe
returns "could not run" and nothing changes. The probe runs after CUDA context setup, so it measures the same
path the expert fetches use.
Behaviour change is confined to machines whose link is slower than x16 PCIe 4.0 — the population the current
default is wrong for. It is also self-documenting: the log now states the measured bandwidth and both the
probed and the stock value, so a report can say whether the share was probed or guessed.
Not claimed: an end-to-end speed number for this. It moves the copy-engine share on x8 links; the round-time
effect on this machine was inside the noise of the other work in progress, so I am not attaching a number
that the method (±5% acceptance-driven round counts) cannot support.