fix: stop merged KV caches being silently discarded on transformers >= 4.57 - #2314
fix: stop merged KV caches being silently discarded on transformers >= 4.57#2314jeojdi1 wants to merge 1 commit into
Conversation
…= 4.57
`_concat_caches` builds each merged layer with `layer_cls()` and then assigns
`.keys` / `.values` directly. A layer constructed that way is never marked
initialized, and on transformers >= 4.57 `DynamicLayer.get_seq_length()`
short-circuits on that flag:
if not self.is_initialized or self.keys.numel() == 0:
return 0
So a correctly concatenated cache reports a length of 0, the model treats it as
empty, and every merged token is dropped on the first forward pass. No error is
raised and no warning is emitted -- the activation memory simply has no effect.
Initialize the layer through its public `lazy_initialization` path before
assigning, guarded by `hasattr` so the older `key_cache` layout is untouched.
Also repairs the test fixture, which is what hid this. `make_filled_cache`
appended to `cache.key_cache`, removed in 4.57, so `test_get_cache_merge` and
`test_delete_and_get_all` failed with AttributeError on any current install and
were being written off as version noise (see PR MemTensor#2204's description). Rebuilding
the fixture on the public `update` API makes those two tests pass again *and*
makes them exercise the `layers` path, which the old fixture never did.
Adds `test_concat_caches_preserves_seq_length`, which fails on the current code
and passes with this change.
🤖 Open Code ReviewTarget: PR #2314 🔍 OpenCodeReview found 2 issue(s) in this PR. 1.
|
|
Description
Fixes #2313.
_concat_cachesbuilds each merged layer withlayer_cls()and then assigns.keys/.valuesdirectly. A layer constructed that way is never marked initialized, and ontransformers >= 4.57DynamicLayer.get_seq_length()short-circuits on that flag:So a correctly concatenated cache reports a length of 0, the model treats it as empty, and every merged token is dropped on the first forward pass. No exception, no warning — activation memory simply has no effect, and the only symptom is that the model behaves as if the memory were never loaded.
The fix initializes the layer through its public
lazy_initializationpath before assigning, guarded byhasattrso the olderkey_cachelayout is untouched.This PR also repairs the test fixture, which is what hid the bug.
make_filled_cacheappended tocache.key_cache, removed in 4.57, sotest_get_cache_mergeandtest_delete_and_get_allfailed withAttributeErroron any current install. PR #2204's description notes these as "pre-existingtest_kv.pyfailures … transformers-API-version issues unrelated to this patch" — they are version issues, but rebuilding the fixture on the publicupdateAPI both makes them pass and makes them exercise thelayerspath, which the old fixture never did. That is what surfaces the real bug.Related Issue (Required): #2313
Type of change
How Has This Been Tested?
Added
test_concat_caches_preserves_seq_length, which builds two caches through the publicupdateAPI, merges them, and asserts the merged length is the sum.Verified against the requirement that a bug fix ships a regression test that fails on the old code and passes on the new, on
transformers 5.16.1:Whole file, before and after:
Checklist
A note on the target branch
CONTRIBUTING.md:283says to branch offdevand open PRs againstdev, but there is no plaindevbranch on this repository — the branches aremainplusdev-v2.0.28…dev-v2.0.32. This PR targetsmain, which is the default branch, where I verified the behaviour, and where 11 of the last 15 merged PRs landed.src/memos/memories/activation/kv.pyis byte-identical onmainanddev-v2.0.30, so the rebase is trivial either way — happy to retarget to whichever branch you prefer, just say which.Relationship to the other KV cache PRs
This is one of three independent fixes to
src/memos/memories/activation/kv.py, each kept to a single logical change perCONTRIBUTING.md. They touch adjacent lines and are easiest to review in this order:get_cachehands out the stored cache by reference, so it grows every turn (The stored activation DynamicCache is mutated in place by generation, so activation memory grows every turn #2301)Happy to rebase them into whatever order suits review.