Add exact hash provider - #1
Open
krakhit wants to merge 2 commits into
Open
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
Follow-on to sgl-project#31057 ("semantic KV cache reuse via a pluggable fuzzy-match
radix backend").
SemanticEmbeddingProvider(the existing provider) findsdonor KV by semantic similarity — matches merely-similar content and is
explicitly not lossless. This PR adds a second
FuzzyMatchProviderimplementation,
ExactHashProvider, for the narrower but common case wherecontent is byte-identical to the current prompt's unmatched tail but
sits at a different offset than where it was originally computed — e.g.
repeated tool schemas, retrieved documents, or system-prompt boilerplate
reappearing later in a different position. It has no external dependency
(no embedding model, unlike
SemanticEmbedding'ssemblendrequirement)and is lossless: a token-ID equality check on every hash hit is mandatory,
so a fingerprint collision never gets served as a false match.
The content-defined chunking parameters (Gear-hash rolling window, boundary
bits, min/max chunk clamp, sink-token carve-out) follow the methodology
described in Irminsul: MLA-Native Position-Independent Caching for Agentic
LLM Serving (Ma, Eitzinger, Köstler; arXiv:2605.05696).
That paper's own mechanism (RoPE delta-rotation over MLA's decomposed
k_nope/k_rope) is specific to MLA architectures and is not usedhere;
ExactHashProviderreuses only its public, architecture-agnosticCDC/chunking layer, and works against any KV pool
realizer.pysupports(currently MHA-style pools), independent of MLA.
Modifications
chunker.py(new): content-defined chunking over token-ID sequences.Gear-hash rolling boundaries (64-token window, 7 boundary bits, chunks
clamped to
[32, 512]tokens, xxHash64 fingerprints with a blake2bfallback), so identical content chunks identically regardless of what
precedes it — the property fixed-boundary chunking structurally lacks.
The first
SINK_TOKENS=32positions are never used as a chunk-registration start, since attention-sink positions absorb a
disproportionate, content-independent share of attention and aren't a
trustworthy content signal.
exact_hash_provider.py(new):ExactHashProvider(FuzzyMatchProvider).Registers donor chunks keyed by
(extra_key, fingerprint), and on aprefix miss looks up the first chunk of the unmatched tail. Every
candidate is confirmed by token-ID equality before being returned as a
match — the fingerprint alone is never trusted. Current limitation:
single-chunk, non-segmented matches only (
FuzzyMatchResult.segments=None);multi-chunk / N:M segment matching is a natural follow-up, not required
for the mechanism to be correct.
fuzzy_match_provider.py,config.py,server_args.py: wire"ExactHash"in as a selectable--fuzzy-match-providervalue alongside"SemanticEmbedding".realizer.py: generalized_resolve_rotary_embto scan every decoderlayer (not just layer 0's
self_attn) for arotary_emb, since hybridarchitectures mix layer types across
model.model.layersand don'tuniformly expose it in the same place. Also unwraps
HybridLinearKVPool(full-attention + linear-attention hybrids) to its
full_kv_poolbeforerunning correction, since the linear-attention layers hold irreversible
recurrent state, not addressable per-token K.
fuzzy_radix_cache.py: rejects hybrid-SSM models explicitly atbackend construction (
is_hybrid_ssmguard) rather than failingconfusingly later.
environ.py: addsSGLANG_TEST_FUZZY_FORCE_HASH_COLLISION, atest-only hook that forces every chunk fingerprint to collide, used to
test the equality-check fallback without waiting on an astronomically
unlikely real collision.
README.md(mem_cache/fuzzy_match/): documentsExactHashas asecond provider option, its no-external-dependency launch command, and
its lossless-by-construction guarantee vs.
SemanticEmbedding's lossy one.test/registered/unit/mem_cache/fuzzy_match/test_chunker.py,test_exact_hash_provider.py,test/registered/fuzzy_match/test_exact_hash_shifted_offset_kl.py,test_exact_hash_e2e_safety.py.Accuracy Tests
Run on a single H100, model
Qwen/Qwen2.5-7B-Instruct-AWQ(the samecheckpoint sgl-project#31057 was itself tested against) for the E2E tests.
test_chunker.py(4 cases)test_exact_hash_provider.py(4 cases)test_fuzzy_match_providers.py+test_fuzzy_radix_cache.py— sgl-project#31057's own existing unit tests, run to confirm no regression from therealizer.py/fuzzy_radix_cache.pychanges (26 cases)test_exact_hash_shifted_offset_kl.py— E2E, shifted-offset reuse vs. full recomputetest_exact_hash_e2e_safety.py— E2E, forced hash-collision disambiguation + cross-tenant isolation37/37 test cases pass, including a full regression run of PR sgl-project#31057's
own pre-existing test suite.
Reproduce:
Benchmarking and Profiling
Ran a single-H100 TTFT comparison,
Qwen/Qwen2.5-7B-Instruct-AWQ: registera 4000-token donor behind a
SINK_TOKENS-length prefix, then query itbehind a different, longer, exact-matched prefix (5 trials each, 1 warm-up
trial discarded), timing
max_new_tokens=1as a TTFT proxy.fuzzy_match+ExactHashNo measurable speedup at this scale (0.98x — within noise). The
server's own instrumentation explains why:
ExactHashProvideronly matchesthe first CDC chunk of the unmatched tail (see Modifications above —
FuzzyMatchResult.segments=None, no multi-chunk matching yet). A chunk iscapped at
MAX_CHUNK_TOKENS=512, averaging ~128 tokens. So regardless ofhow large the donor content is, only one chunk's worth gets reused per
query — in this run, 65–259 tokens out of every ~4300-token request
(2–6%), confirmed directly from the prefill batch log
(
#cached-token/#fuzzy-tokencounts):That small a fraction of a request's prefill work doesn't clear the fixed
per-request overhead (tokenization, scheduling, HTTP round-trip) on an
H100, where raw prefill compute for a few hundred tokens is sub-
millisecond. This isn't a correctness issue — the KL-divergence results
above confirm the reused span is numerically valid — it's a real, current
ceiling on this PR's latency upside: today it's capped at ~512 tokens of
avoided prefill per request no matter the donor size. Multi-chunk / N:M
segment matching (the follow-up already flagged in
exact_hash_provider.py's docstring) is what would need to land beforethis mechanism shows up in end-to-end throughput/TTFT numbers.
Checklist
black,isort(black profile),ruff --select=F401,F821,UP037, andcodespellall pass on every changed file (fullpre-commitwasn't installed in this environment; ran the underlying tools directly, pinned to the versions in.pre-commit-config.yaml).mem_cache/fuzzy_match/README.mdupdated.