Skip to content

Review LMCache offload compatible connector and bounded staging#3

Open
yhl-amd wants to merge 27 commits into
review/lmcache-offload-base-release_rcfrom
feature/lmcache-default-chunk2
Open

Review LMCache offload compatible connector and bounded staging#3
yhl-amd wants to merge 27 commits into
review/lmcache-offload-base-release_rcfrom
feature/lmcache-default-chunk2

Conversation

@yhl-amd

@yhl-amd yhl-amd commented Jun 4, 2026

Copy link
Copy Markdown
Owner

Summary

This is a consolidated review PR for the LMCache KV offload stack.

The PR base is intentionally review/lmcache-offload-base-release_rc, a fork branch pointing at the original origin/release_rc snapshot. This avoids the noisy main history mismatch and makes GitHub show the full offload diff in one PR.

Existing stacked PRs are still useful for smaller slices:

This PR shows the whole stack through feature/lmcache-default-chunk2.

Key Changes

  • Add ATOM standalone LMCache CPU/NVMe offload connector and scheduler handoff path.
  • Add LMCache-compatible worker path using CacheEngine.store() / CacheEngine.retrieve() without modifying LMCache source.
  • Add ATOM raw-byte LMCache metadata and GPU connector for ATOM KV layout.
  • Add native chunk-major GPU staging for fused pack/unpack.
  • Add bounded multi-chunk staging with OFFLOAD_GPU_STAGING_CHUNKS.
  • Set the default OFFLOAD_GPU_STAGING_CHUNKS to 2.
  • Add offload profiling fields for chunks/groups/staging capacity/effective bandwidth.
  • Add/extend tests for connector store/load, metadata shape, staging grouping, and default chunk count.

Validation

docker exec yhl_kvoff_009 bash -lc 'cd /app/ATOM && python3 -m pytest tests/test_lmcache_offload_connector.py -q'
46 passed

Recent chunk2 CxS fixed-source runs are recorded in 18_SUMMARY_009_kv_offload.md outside this repo checkout:

64K c2/s4 chunk2 fixed-source:
  tag: lmcache_compat_m25_64k_c2s4_multichunk2_fixedsrc_20260603_215052
  LOAD/SAVE: 42 / 42
  load avg: 212.02ms

128K c2/s2 chunk2 fixed-source:
  tag: lmcache_compat_m25_128k_c2s2_multichunk2_fixedsrc_20260603_215357
  LOAD/SAVE: 14 / 72
  load avg: 805.32ms

Review Notes

chunk2 is the low-memory default, not the best performance point. The benchmark notes show that chunk32 is faster for non-layerwise bounded staging, but uses more resident staging memory. This branch defaults to chunk2 as requested.

yhl-amd and others added 27 commits May 31, 2026 22:22
…WIP)

New atom/kv_transfer/offload/ package: a standalone (non-vLLM) KV offload
connector that reuses LMCache as a storage tier (CPU LRU + NVMe L3) via
StorageManager + ChunkedTokenDatabase, with an opaque per-block byte codec
(ATOMKVByteCodec) that bypasses engine.store/retrieve to preserve AITER's
swizzled KV layout. Load/save run daemon-after-forward off the RPC thread;
cross-process hit lookup via LMCache's ZMQ LookupClient/LookupServer.

Engine hooks:
- disaggregation/factory.py: register the "lmcache_offload" connector.
- model_engine/scheduler.py: offload-wake branch (a parked
  WAITING_FOR_REMOTE_KVS seq resumes as a suffix prefill, not the P/D
  decode-jump) + offload_resume guard against re-allocate-on-populated-blocks.

TP=2 fixes (offload was non-functional at TP>1):
- config.py: lookup_server_worker_ids=[0]. The cross-rank ZMQ lookup took
  min() across ranks and rank!=0 returned 0 despite having stored the chunk
  (contains()=True) -> min(0,hit)=0 -> the load never fired. Only rank 0
  answers lookup now (both ranks save in lockstep, so rank 0 is authoritative).
- connector.py: split load/save into separate executors so a latency-critical
  reload never queues behind the fire-and-forget save backlog.

Verified end-to-end at TP=2 (MiniMax-M2.5 FP8, 2x MI325X): an evicted 32K
prompt reloads 32000 tokens from CPU and recomputes only the 5-token suffix
(Scheduled prefill cached:[32000], new:[5]); was a full recompute before.

Known issues (WIP):
- Reload latency high (~131s in the micro-bench): the per-block Python copy
  path is slow (~88ms/chunk) and the load waits on the storage_manager lock
  held by a save burst. Needs a bulk/batched copy rewrite of ATOMKVByteCodec.
  See ../OFFLOAD_TP2_FIXES.md and ../PHASE4_RESULTS.md.
- Verbose [OFFLOAD-*] diagnostic logging + an engine.lookup monkeypatch are
  still present and must be removed/demoted before benchmark/production use.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Apply Scheme A load semantics after allocation: skip small or unsafe CPU reloads, hand off unaligned HBM floors by prefill-to-boundary when enabled, and promote completed remote-KV waiters before fresh admissions.

Add scheduler and connector tests for aligned reloads, unaligned handoff, min-load skips, and deferred-output cleanup.
entries) and check `can_allocate` + token-budget, mirroring the
same checks the admission while-loop runs below.
"""
if self._partial_prefill_count > 0:

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

解决已有问题,如果只看waiting状态会有问题的

A prompt:
[chunk1 已算] [chunk2 未算] [chunk3 未算]

A 在 running
A.is_partial_prefill = True
_partial_prefill_count = 1

if num_new_tokens > self.max_num_batched_tokens:
if (
not self.enable_chunked_prefill
and num_new_tokens > self.max_num_batched_tokens

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

超长上下文超过了maxlen,也不支持标记为prefillable,防止 dp的时候认为他又能了

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant