Nearly double the hit-rate#223
Conversation
|
Thank you for this β I ran it on our reference box and I owe you the numbers, because they're interesting in a way that isn't "yes" or "no". What I measuredABA (dev β dev+223 β dev), same prompt, same env,
Identical to the decimal. The SLRU changes nothing here β not "a little", exactly nothing. Why, and why it isn't your bugThree slots per layer, eight experts wanted per token. With three seats and eight arrivals, every eviction policy loses identically β there's no room left to be clever. Your algorithm isn't failing; it has nothing to work with. You ran The ask: what's the lowest cap at which cloxcache starts to win? If it's ~6+, this is a good PR for large-memory hosts and should say so β the README line would be "on hosts with cache headroom" rather than a general claim. That's a much stronger PR than one that quietly does nothing for the low-RAM users this engine targets. The other half, which is the useful part for both of usLook at the decode column: 251s, 393s, 785s. A1 and A2 are the same binary, same prompt, same machine, twenty minutes apart β a 3.1Γ spread. Which means: had I run only A1βB, I'd have posted "#223 is 56% slower, regression." Had I run only A2βB, I'd have posted "#223 is 2Γ faster, merging." Both would have been garbage, and B's 393s sits neatly between two runs of the same code. On a disk-bound box wall-clock is noise. The only stable signals are One small thing while I'm here: the title says "nearly double the hit-rate", but 9.4% β 15.1% is +60%, not double. I'd retitle β the real result doesn't need the help, and this repo has had a rough week with numbers that promised more than they delivered (see #303). Where this leaves itI'm not merging it yet, and I want to be straight about why: it adds real surface ( It's a judgment call about scope, not correctness, and it's an easy yes the moment we know the cap threshold. If you can give me that number β or a run at a cap this class of hardware can actually reach β I'll take it. Genuinely appreciate the rigour, and the fact that this is the safe kind of change: it touches eviction only, never which expert gets selected, so it cannot alter output. That distinction matters a lot around here lately. |
|
Following the ABA results β two things from a code-level read of the eviction path on dev that bear directly on the cap-threshold question:
|
Signed-off-by: Robert Landers <landers.robert@gmail.com>
Signed-off-by: Robert Landers <landers.robert@gmail.com>
Signed-off-by: Robert Landers <landers.robert@gmail.com>
Signed-off-by: Robert Landers <landers.robert@gmail.com>
Signed-off-by: Robert Landers <landers.robert@gmail.com>
Signed-off-by: Robert Landers <landers.robert@gmail.com>
The honest answer is a ratio, not a cap: it starts winning when cap exceeds roughly a third of the per-token unique expert demand per layer, peaks around 0.4β0.8Γ, and thins out again above 1Γ (where plain recency already holds the working set). Your box makes the arithmetic concrete: 876.5/75 β 11.7 loads/layer/token at 3.8% hit β ~12 unique experts demanded per layer per token, against 3 slots. That's a 4Γ full flush every token β no resident survives to the next token under any policy, so "identical to the decimal" is the expected outcome, not a near-miss. You're right that it isn't my bug, and right that it isn't your refutation: cap 3 against demand 12 is ratio 0.25, below the floor. My RAM_GB=32 number sits at cap 8 against the same demand β ratio 0.66, mid-sweet-spot. Both measurements are the same curve. And you don't have to take the curve from me, because:
β is correct, and I won't argue with it. Since the PR I built an offline replayer that removes the hardware from the measurement entirely, and it's on the branch: capture a routing trace during any normal run (one env var, one line per routing decision, negligible overhead), then replay the identical request stream through plain LRU, this PR's SLRU, and Belady's clairvoyant OPT: ROUTE_TRACE=run.trace ./glm Run any cap, including the ones your RAM can't reach. It also scores each eviction decision against hindsight (was the victim re-requested before another resident would have been?), which is the metric hit rate can't see. For calibration, my traced workload (256 experts/layer, demand β 8/layer/token, -p 0 matching your AUTOPIN=0): By your scaling (~2 GB/cap between RAM_GB=22βcap 3 and 32βcap 8), cap 4β5 is RAM_GB β 24β26, so cap 4 may even be physically reachable on the 25.4 GB box if you want confirmation β but the simulator will tell you the answer for your routing distribution either way. The OPT column is worth a look independently of this PR: it prices exactly what each additional GB of cache budget buys on your workload before anyone tunes another heuristic.
Agreed, and I'd go further β proposed wording: "SLRU eviction improves expert-cache hit rate when per-layer cache capacity exceeds ~β of per-token expert demand (measured +60% hit rate at cap/demand β 0.65); below that threshold the cache fully flushes each token and the policy is provably inert β identical residency to LRU, zero cost, zero risk." The inertness your A/B demonstrated is worth stating as the safety property it is.
Also agreed, no defense offered. "+60% hit rate" it is. One relevant note: the branch has moved since you tested. Building the simulator caught two real defects in my own implementation (ghost-eviction ordering that silently destroyed ghost memory under exactly the LRU-victim pattern; adaptation windows mis-paced so the hit-rate feedback learned from noise) and added eviction-driven frequency decay, which the replayer shows matters most at small caps β the regime you care about. All verified against OPT on trace replay; test_tier covers each. Worth retesting from head rather than the revision you benchmarked β though at cap 3, I expect and now predict on the record that you'll still measure exactly nothing. Happy to have the merge gate on the documented threshold; it's the right bar. Run the replay on your trace and the number in the README can be yours rather than mine. |
The expert lookup counted a hit identically whether the pinned hot-store or the LRU ecache served it β both Phase C branches bumped the single `m->hits`. With a warm pin profile the pin tier absorbs most hot experts, so the ecache could be serving anywhere from ~0% to most hits and the logs couldn't tell which. That made every cache-policy question unanswerable, including #223's "at what cap does the eviction policy start to win?" (a flat A/B can mean "pin absorbed everything" or "genuine floor" and the lumped counter can't distinguish them). Two counters `hit_pin`/`hit_ecache` bumped at the two lookup branches (the existing `m->hits++` stays, so all existing math is unchanged), snapshotted in ProfBase and reset alongside `hits`. Surfaced in the human-readable summaries: decode: expert hit rate 31.3% (pin 22.1% + lru 9.2%) [PROF]: hit 31.3% (X pin + Y lru / Z load) tiny: hit rate 88.1% (0 pin + 74 lru / 10 miss) The serve-mux STAT protocol line is untouched (openai_server.py parses it positionally). Invariant hit_pin + hit_ecache == hits holds by construction β exactly two sites bump hits and each also bumps one split counter, nothing else mutates hits. Verified numerically on the tiny oracle: 0 pin + 74 lru = 74 hits, 88.1%. Zero cost: two increments on paths that already increment. Reported-by: KingIcyCreamProjects <#336> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Summary
I saw a video on YouTube about this project and realized the problems you're trying to solve are very similar to ours over on Swytch (A leaderless distributed cache with serializable guarantees). The caching algorithm that makes it possible is called "cloxcache" and we're currently writing a paper on it. The caching family would be CLOCK-LRU-K -- and it adapts LFU/LRU on-the-fly. I've adapted it from Go to C, and your cache structures. To our knowledge, it's the most performant cache-eviction algorithm currently in existence on large caches, outperforming other eviction algorithms and ~99.998% as good as a perfect cache can ever be.
Anyway, enough with the marketing speak, here's the data:
Reproduction:
Finals:
Hardware:
Validation
make -C c checkmake -C c cuda-test(if applicable)Compatibility