Skip to content

Commit 0d1d5bf

Browse files
authored
[BugFix] isolate KV cache from sleep cleanup with dedicated memory tag for hadamard matrix (vllm-project#10775)
### What this PR does / why we need it? Use a dedicated memory tag for KV cache used by DSA Hadamard, instead of the shared tag that was previously being cleaned up during sleep(). This ensures the Hadamard tensor is properly tagged and excluded from sleep-mode memory release. Fixes vllm-project#10684 ### Does this PR introduce _any_ user-facing change? No. ### How was this patch tested? - vLLM version: v0.23.0 - vLLM main: vllm-project/vllm@967c5c3 --------- Signed-off-by: yangjinyang <yangjinyang5@huawei.com> Signed-off-by: yjyang62 <yangjinyang5@huawei.com> Co-authored-by: yjyang62 <yjyang62@users.noreply.github.com>
1 parent d059da0 commit 0d1d5bf

3 files changed

Lines changed: 46 additions & 6 deletions

File tree

vllm_ascend/attention/context_parallel/dsa_cp.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -189,9 +189,20 @@ def __init__(
189189
) from e
190190
log_dim = math.ceil(math.log2(indexer_head_dim))
191191
dim_padded = 2**log_dim
192-
AscendDSACPMetadataBuilder.hadamard = torch.tensor(
193-
hadamard(dim_padded, dtype=float), dtype=torch.float, device=self.device
194-
).to(torch.bfloat16)
192+
if self.vllm_config.model_config.enable_sleep_mode:
193+
# Sleep mode allocates KV inside CaMemAllocator; tag Hadamard so
194+
# sleep/wake does not treat it as KV cache.
195+
from vllm_ascend.device_allocator.camem import CaMemAllocator
196+
197+
allocator = CaMemAllocator.get_instance()
198+
with allocator.use_allocation_tag(CaMemAllocator.sleep_persistent_tag):
199+
AscendDSACPMetadataBuilder.hadamard = torch.tensor(
200+
hadamard(dim_padded, dtype=float), dtype=torch.float, device=self.device
201+
).to(torch.bfloat16)
202+
else:
203+
AscendDSACPMetadataBuilder.hadamard = torch.tensor(
204+
hadamard(dim_padded, dtype=float), dtype=torch.float, device=self.device
205+
).to(torch.bfloat16)
195206
self.start_pos_prefill = torch.zeros(scheduler_config.max_num_seqs, dtype=torch.int32, device=self.device)
196207
self.req_sas_metadata = torch.zeros(1024, dtype=torch.int32, device=self.device)
197208
self.req_qli_metadata = torch.zeros(1024, dtype=torch.int32, device=self.device)

vllm_ascend/attention/dsa_v1.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -424,9 +424,20 @@ def __init__(
424424
raise ImportError("Please install scipy") from e
425425
log_dim = math.ceil(math.log2(indexer_head_dim))
426426
dim_padded = 2**log_dim
427-
AscendDSAMetadataBuilder.hadamard = torch.tensor(
428-
hadamard(dim_padded, dtype=float), dtype=torch.float, device=self.device
429-
).to(torch.bfloat16)
427+
if self.vllm_config.model_config.enable_sleep_mode:
428+
# Sleep mode allocates KV inside CaMemAllocator; tag Hadamard so
429+
# sleep/wake does not treat it as KV cache.
430+
from vllm_ascend.device_allocator.camem import CaMemAllocator
431+
432+
allocator = CaMemAllocator.get_instance()
433+
with allocator.use_allocation_tag(CaMemAllocator.sleep_persistent_tag):
434+
AscendDSAMetadataBuilder.hadamard = torch.tensor(
435+
hadamard(dim_padded, dtype=float), dtype=torch.float, device=self.device
436+
).to(torch.bfloat16)
437+
else:
438+
AscendDSAMetadataBuilder.hadamard = torch.tensor(
439+
hadamard(dim_padded, dtype=float), dtype=torch.float, device=self.device
440+
).to(torch.bfloat16)
430441
self.start_pos_prefill = torch.zeros(scheduler_config.max_num_seqs, dtype=torch.int32, device=self.device)
431442
self.start_pos_decode = torch.zeros(scheduler_config.max_num_seqs, dtype=torch.int32, device=self.device)
432443
self.decode_sas_metadata = torch.zeros(1024, dtype=torch.int32, device=self.device)

vllm_ascend/device_allocator/camem.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ class CaMemAllocator:
134134

135135
instance = None
136136
default_tag: str = "default"
137+
# Allocations with this tag stay mapped across sleep/wake cycles.
138+
sleep_persistent_tag: str = "sleep_persistent"
137139

138140
@staticmethod
139141
def get_instance() -> "CaMemAllocator":
@@ -200,6 +202,9 @@ def sleep(self, offload_tags: tuple[str, ...] | str | None = None) -> None:
200202
offload_tags,
201203
)
202204
for ptr, data in self.pointer_to_data.items():
205+
if data.tag == CaMemAllocator.sleep_persistent_tag:
206+
# This memory is not offloaded or released during sleep.
207+
continue
203208
handle = data.handle
204209
if data.tag in offload_tags:
205210
size_in_bytes = handle[1]
@@ -227,6 +232,9 @@ def wake_up(self, tags: list[str] | None = None) -> None:
227232
tags or "all",
228233
)
229234
for ptr, data in self.pointer_to_data.items():
235+
if data.tag == CaMemAllocator.sleep_persistent_tag:
236+
# It was never released in sleep(), so there is nothing to remap.
237+
continue
230238
if tags is None or data.tag in tags:
231239
handle = data.handle
232240
create_and_map(handle)
@@ -240,6 +248,16 @@ def wake_up(self, tags: list[str] | None = None) -> None:
240248
memcpy(ptr, dest_max, cpu_ptr, size_in_bytes, ACL_MEMCPY_HOST_TO_DEVICE)
241249
data.cpu_backup_tensor = None
242250

251+
@contextmanager
252+
def use_allocation_tag(self, tag: str):
253+
"""Temporarily override the tag assigned to new allocations."""
254+
old_tag = self.current_tag
255+
self.current_tag = tag
256+
try:
257+
yield
258+
finally:
259+
self.current_tag = old_tag
260+
243261
@contextmanager
244262
def use_memory_pool(self, tag: str | None = None):
245263
"""

0 commit comments

Comments
 (0)