Repository navigation
Conversation
…M) pool Two interfaces, following the scheduler / runner process split: - KVBlockPool (BlockManager): which block is next, what each block holds, what is evicted. BlockPool is the default implementation, logic unchanged. - KVPoolMemory (ModelRunner): where the pool's bytes come from, how they divide into blocks, when the GPU has finished writing them. The default is today's torch allocation. ATOM_KV_POOL_BACKEND=umbp selects the MORI-UMBP backend (atom/model_engine/umbp_block_pool.py): UMBP allocates each rank's pool on that rank's GPU, the runner maps it, and kernels read and write it in place. UMBP keeps the slot table and one index across the ranks' pools, so a prefix another DP rank holds is copied into the requesting rank's own pool before the prefix walk and then hit locally. The default backend is unchanged behaviour. RFC: ROCm#3259 Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Contributor
🏷️ CI GuideRuns automatically on every eligible PR before approval:
Heavy model tests:
|
… stops early Two defects in the pluggable KV pool change: - EngineCore called `self.scheduler.block_manager.kv.flush()` after `schedule()` and `postprocess()`. PrefillScheduler has no block manager (`block_manager = None`), so a disaggregated prefill engine would have raised there, and so did every test that drives an engine step over a stand-in scheduler. The flush now lives in `Scheduler.schedule()` and `Scheduler.postprocess()`, the scheduler that owns a BlockManager. - `UmbpBlockPool.fetch` matched the keys UMBP reported evicted against the slots it returned. UMBP empties its destinations before it fills them, so a fetch that stops part-way (a failed copy) has evicted content from slots it does not return, and the pool raised "local view diverged". Evicted keys are now applied on their own. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
This branch has not been deployed
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.
Summary
Proof of concept for the RFC in #3259: a pluggable KV pool backend, with MORI-UMBP owning the L1 (HBM) pool so DP ranks share it. The UMBP side is ROCm/mori#994.
The default backend is today's behaviour. Nothing changes unless
ATOM_KV_POOL_BACKEND=umbpis set.Opened as a draft: this is a base version to go with the RFC discussion, not a finished feature.
Changes
atom/model_engine/kv_block_pool.py), following the scheduler / runner process split:KVBlockPool, used byBlockManager: which block is next, what each block holds, what is evicted.BlockPoolbecomes the default implementation with its logic unchanged. Three optional hooks (prepare,fetch,flush) default to no-ops.KVPoolMemory, used byModelRunner: where the pool's bytes come from, how they divide into blocks, and when the GPU has finished writing them. The default is today's torch allocation.block_manager.py: builds the pool throughmake_block_pool, asks a content-sharing pool for a sequence's prefix once before its first walk, and tells the pool how many fresh blocks anallocateis about to take.model_runner.py: takes the paged pool's buffer fromKVPoolMemory, hands it the block layout, and notes each forward's writes in_record_kv_cache_ready.scheduler.py: flushes the pool at the end ofScheduler.schedule()andScheduler.postprocess(), the scheduler that owns aBlockManager.block_pool.py,envs.py: the base class, andATOM_KV_POOL_BACKEND,ATOM_UMBP_L1_ADDRESS,ATOM_UMBP_L1_NAMESPACE,ATOM_UMBP_L1_GROUP,ATOM_UMBP_L1_FETCH.docs/environment_variables.md: a "KV pool backend" section for the new variables.atom/model_engine/umbp_block_pool.py), imported only when selected:UmbpBlockPoolkeeps an exact local view of this rank's pool. Slot decisions (next slot, eviction, fetch) come from UMBP, and updates are batched into one call per flush.UmbpPoolMemorymaps the HBM that UMBP allocated (hip_ipc.open_ipc_handle), so kernels read and write it in place. After each forward it records a stream event and reports to UMBP when the GPU has finished.Tests
tests/test_umbp_block_pool.py: 48 tests. The pool runs against a Python model of the service and, whenmori_umbp_l1is built, against the real one over a Unix socket. They cover step-for-step parity withBlockPool, grants, fetch, the write-completion rules, and twoBlockManagers sharing a prefix.BlockManager,BlockPoolor the runner's pool pass (1,987 passed, 69 skipped).Known limits
🤖 Generated with Claude Code