# SPDX-License-Identifier: Apache-2.0 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project """Engram: n-gram hash lookups gated into the hyper-connection stream. Port of the reference ``inference/engram.py`` + ``Engram`` / ``ParallelEngramEmbedding`` from ``inference/model.py`` (DeepSeek V4.1 checkpoint layout). Engram modules live on the backbone layers listed in ``engram_layer_ids`` only. Two pieces of cross-forward state are needed because vLLM streams tokens chunk-by-chunk while an n-gram at position ``p`` needs the token ids at ``p-1..p-3``: - ``token_map``: token id -> compressed vocab id, built once from the model's tokenizer at init (deterministic; asserted against ``engram_compressed_vocab_size``). - ``hash_cache``: one int32 slot per KV slot of the first local layer's sliding-window cache, holding the compressed id (or DEAD) of the token last written to that slot. Slots are stable per (request, position) — the block table pins a position to a physical slot, prefix-cache hits reuse both the physical blocks and the identical token ids, and spec-decode rollbacks rewrite the same slots — so lookbacks read back exactly what the owning request wrote. Lookback depth (3) is far inside the sliding window (128), so window eviction never frees a block a live lookback still needs. Slots are not part of the KV cache, so KV loaded from another instance (P/D, offload connectors) leaves them unwritten. The runner therefore passes ``lookback_token_ids``, the ids just before each request's chunk start, which take precedence over the slots. The V2 runner reads them from its device-resident token history and needs no slot cache; the V1 runner's CPU token table holds placeholders for generated tokens under async scheduling, so it passes prompt positions only and keeps the slot cache for the rest. """ import weakref import numpy as np import torch from torch import nn # --- Tech2Wild/Kai 2026-09-10: disk-backed Engram tables for DGX Spark (UMA) --- import json as _kai_json import os as _kai_os import struct as _kai_struct from concurrent.futures import ThreadPoolExecutor as _KaiPool from vllm.config import VllmConfig, get_current_vllm_config from vllm.distributed import ( get_tensor_model_parallel_rank, get_tensor_model_parallel_world_size, tensor_model_parallel_all_gather, ) from vllm.logger import init_logger from vllm.model_executor.layers.linear import ReplicatedLinear from vllm.model_executor.layers.quantization import QuantizationConfig from vllm.model_executor.utils import set_weight_attrs from vllm.triton_utils import tl, triton from vllm.utils.platform_utils import is_uva_available from vllm.utils.torch_utils import get_accelerator_view_from_cpu_tensor logger = init_logger(__name__) # Cache value for tokens that take no part in an n-gram (image spans). DEAD_ID = -1 def _is_prime(n: int) -> bool: """Deterministic Miller-Rabin for n < 2**32 (avoids a sympy import).""" if n < 2: return False for p in (2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37): if n % p == 0: return n == p d = n - 1 r = 0 while d % 2 == 0: d //= 2 r += 1 for a in (2, 7, 61): x = pow(a, d, n) if x in (1, n - 1): continue for _ in range(r - 1): x = x * x % n if x == n - 1: break else: return False return True def find_next_prime(start: int, seen_primes: set[int]) -> int: """The smallest prime above `start` that has not been handed out yet.""" candidate = start + 1 while not _is_prime(candidate) or candidate in seen_primes: candidate += 1 return candidate def build_compressed_token_map(tokenizer) -> tuple[list[int], int]: """Map every token id onto a smaller id space where tokens that normalize alike collapse together. N-grams are hashed over these compressed ids, so " The", "the" and "THE" all hash the same way. The compressed size matters beyond bounds checking: every hash multiplier is derived from it. """ from tokenizers import Regex, normalizers # A private-use char, so a token that is exactly one space survives # Strip() instead of collapsing to the empty string and merging with # unrelated tokens. sentinel = "\ue000" normalizer = normalizers.Sequence( [ normalizers.NFKC(), normalizers.NFD(), normalizers.StripAccents(), normalizers.Lowercase(), normalizers.Replace(Regex(r"[ \t\r\n]+"), " "), normalizers.Replace(Regex(r"^ $"), sentinel), normalizers.Strip(), normalizers.Replace(sentinel, " "), ] ) # The raw Rust tokenizer, matching what training decodes with # (no clean_up_tokenization_spaces). backend = tokenizer.backend_tokenizer key_to_new: dict[str, int] = {} lookup = [0] * len(tokenizer) for token_id in range(len(tokenizer)): text = backend.decode([token_id], skip_special_tokens=False) if "\ufffd" in text: # A partial UTF-8 byte token: nothing to normalize, so key it # by its raw form. key = backend.id_to_token(token_id) else: normalized = normalizer.normalize_str(text) key = normalized if normalized else text new_id = key_to_new.get(key) if new_id is None: new_id = len(key_to_new) key_to_new[key] = new_id lookup[token_id] = new_id return lookup, len(key_to_new) def compute_hash_multipliers( layer_ids: tuple[int, ...], max_ngram_size: int, compressed_vocab_size: int ) -> torch.Tensor: """One multiplier per (layer, lookback), from a per-layer RNG so layers hash differently. Kept odd and bounded so `token_id * multiplier` cannot overflow int64. """ max_long = np.iinfo(np.int64).max multiplier_bound = max(1, (max_long // compressed_vocab_size) // 2) rows = [] for layer_id in layer_ids: generator = np.random.default_rng(10007 * layer_id) values = generator.integers( low=0, high=multiplier_bound, size=(max_ngram_size,), dtype=np.int64, ) rows.append(torch.tensor(values * 2 + 1)) return torch.stack(rows) class EngramLayout: """Bucket layout of the n-gram hash tables. A position is hashed as `max_ngram_size - 1` n-grams (2-gram .. max), each split over `n_heads` heads. Every (n-gram size, head) pair owns its own prime-sized bucket range in the layer's table; the primes are drawn in order and never reused, which keeps the ranges disjoint. """ def __init__(self, config) -> None: self.layer_ids: tuple[int, ...] = tuple(config.engram_layer_ids) self.num_embeddings: tuple[int, ...] = tuple(config.engram_num_embeddings) self.max_ngram_size: int = config.engram_max_ngram_size self.n_heads: int = config.engram_n_heads self.head_dim: int = config.engram_head_dim self.compressed_vocab_size: int = config.engram_compressed_vocab_size self.pad_token_id: int = config.engram_pad_token_id assert len(self.layer_ids) == len(self.num_embeddings) primes = [] seen: set[int] = set() for _ in self.layer_ids: per_ngram = [] for _ in range(self.max_ngram_size - 1): sizes, current = [], config.engram_vocab_size - 1 for _ in range(self.n_heads): current = find_next_prime(current, seen) seen.add(current) sizes.append(current) per_ngram.append(tuple(sizes)) primes.append(tuple(per_ngram)) self.primes: tuple[tuple[tuple[int, ...], ...], ...] = tuple(primes) self.n_hash_cols = (self.max_ngram_size - 1) * self.n_heads flat = [[p for per_ngram in layer for p in per_ngram] for layer in primes] offsets = [np.cumsum([0, *sizes[:-1]]) for sizes in flat] self.offsets = torch.tensor(np.array(offsets)) # [n_layers, n_hash_cols] @classmethod def from_config(cls, config) -> "EngramLayout | None": if not getattr(config, "engram_layer_ids", None): return None return cls(config) @triton.jit(do_not_specialize=["num_tokens"]) def _write_hash_cache_kernel( input_ids, token_map, dead_mask, slot_mapping, cache, num_tokens, input_stride, mask_stride, slot_stride, BLOCK_SIZE: tl.constexpr, dead_id, ): token_idx = tl.program_id(0) * BLOCK_SIZE + tl.arange(0, BLOCK_SIZE) slot = tl.load( slot_mapping + token_idx * slot_stride, token_idx < num_tokens, other=-1 ).to(tl.int64) valid = (token_idx < num_tokens) & (slot >= 0) token = tl.load(input_ids + token_idx * input_stride, valid, other=0) value = tl.load(token_map + token, valid, other=0) dead = tl.load(dead_mask + token_idx * mask_stride, valid, other=False) value = tl.where(dead, dead_id, value) tl.store(cache + slot, value, valid) @triton.jit( do_not_specialize=[ "num_tokens", "num_slots", "num_query_rows", "num_table_rows", "max_blocks", ] ) def _hash_ids_kernel( input_ids, token_map, dead_mask, positions, block_table, query_start_loc, multipliers, primes, offsets, cache, lookback_token_ids, lookback_dead_mask, output, num_tokens, num_slots, pad_id, input_stride, mask_stride, position_stride, table_stride, table_col_stride, query_stride, num_query_rows, num_table_rows, max_blocks, cache_block_size, MAX_NGRAM: tl.constexpr, num_heads, BLOCK_T: tl.constexpr, BLOCK_H: tl.constexpr, dead_id, lookback_depth, lookback_row_stride, lookback_col_stride, lookback_mask_row_stride, lookback_mask_col_stride, ): token = tl.program_id(0) * BLOCK_T + tl.arange(0, BLOCK_T) layer = tl.program_id(1) num_layers = tl.num_programs(1) valid = token < num_tokens # Upper bound in query_start_loc[1:], including repeated padding boundaries. lo = tl.full((BLOCK_T,), 0, tl.int32) hi = tl.full((BLOCK_T,), num_query_rows, tl.int32) while tl.sum((lo < hi).to(tl.int32), 0) > 0: mid = (lo + hi) // 2 end = tl.load( query_start_loc + (mid + 1) * query_stride, lo < hi, other=0, ) right = token >= end active = lo < hi lo = tl.where(active & right, mid + 1, lo) hi = tl.where(active & ~right, mid, hi) req = tl.minimum(lo, num_query_rows - 1).to(tl.int64) chunk_idx = tl.load(query_start_loc + req * query_stride) chunk_idx = tl.minimum(chunk_idx, num_tokens - 1).to(tl.int64) chunk_start = tl.load(positions + chunk_idx * position_stride) position = tl.load(positions + token * position_stride, valid, other=0).to(tl.int64) head = tl.arange(0, BLOCK_H) blocked = tl.full((BLOCK_T,), False, tl.int1) rolling = tl.full((BLOCK_T,), 0, tl.int64) for shift in tl.static_range(MAX_NGRAM): lookback = position - shift in_batch = lookback >= chunk_start batch_idx = tl.maximum(token - shift, 0) batch_token = tl.load( input_ids + batch_idx * input_stride, valid & in_batch, other=0 ) batch_source = tl.load(token_map + batch_token, valid & in_batch, other=0) batch_dead = tl.load( dead_mask + batch_idx * mask_stride, valid & in_batch, other=False ) batch_source = tl.where(batch_dead, dead_id, batch_source) col = chunk_start - 1 - lookback in_window = valid & ~in_batch & (col >= 0) & (col < lookback_depth) col = tl.minimum(tl.maximum(col, 0), lookback_depth - 1) window_token = tl.load( lookback_token_ids + req * lookback_row_stride + col * lookback_col_stride, in_window, other=-1, ) known = in_window & (window_token >= 0) window_source = tl.load(token_map + window_token, known, other=0) window_dead = tl.load( lookback_dead_mask + req * lookback_mask_row_stride + col * lookback_mask_col_stride, known, other=False, ) window_source = tl.where(window_dead, dead_id, window_source) if cache is not None: clamped = tl.minimum( tl.maximum(lookback, 0), max_blocks * cache_block_size - 1 ) block_row = tl.minimum(req, num_table_rows - 1) needs_cache = valid & ~in_batch & ~known block = tl.load( block_table + block_row * table_stride + (clamped // cache_block_size) * table_col_stride, needs_cache, other=0, ).to(tl.int64) slot = tl.minimum( tl.maximum(block * cache_block_size + clamped % cache_block_size, 0), num_slots - 1, ) fallback = tl.load(cache + slot, needs_cache, other=0) else: fallback = tl.full((BLOCK_T,), pad_id, tl.int32) source = tl.where( in_batch, batch_source, tl.where(known, window_source, fallback) ).to(tl.int64) blocked |= (lookback < 0) | (source == dead_id) value = tl.where(blocked, pad_id, source) multiplier = tl.load(multipliers + layer * MAX_NGRAM + shift) rolling ^= value * multiplier if shift > 0: col = (shift - 1) * num_heads + head param_offset = layer * (MAX_NGRAM - 1) * num_heads + col prime = tl.load(primes + param_offset, head < num_heads, other=1) offset = tl.load(offsets + param_offset, head < num_heads, other=0) hashed = rolling[:, None] % prime[None, :] + offset[None, :] out_offset = (token.to(tl.int64) * num_layers + layer)[:, None] * ( (MAX_NGRAM - 1) * num_heads ) + col[None, :] tl.store(output + out_offset, hashed, valid[:, None] & (head < num_heads)) class NgramHashState(nn.Module): """Maps each position to the hash ids of the n-grams ending there. Stateless on the V2 runner, which supplies every lookback token id. On the V1 runner it also keeps `hash_cache`, the slot-keyed rolling store of compressed ids (see module docstring), for generated tokens. """ def __init__( self, vllm_config: VllmConfig, layout: EngramLayout, swa_cache_module: nn.Module, ) -> None: super().__init__() self.layout = layout self.swa_cache_module = swa_cache_module self.block_size: int = swa_cache_module.block_size self.lookback_depth: int = layout.max_ngram_size - 1 self.use_slot_cache: bool = not vllm_config.use_v2_model_runner self._cache: torch.Tensor | None = None self._kv_cache_ref: weakref.ReferenceType[torch.Tensor] | None = None model_config = vllm_config.model_config from transformers import AutoTokenizer tokenizer = AutoTokenizer.from_pretrained( model_config.tokenizer, trust_remote_code=model_config.trust_remote_code, revision=model_config.revision, ) token_map, vocab_size = build_compressed_token_map(tokenizer) if vocab_size != layout.compressed_vocab_size: raise ValueError( f"Compressed vocab size mismatch: built {vocab_size} from the " f"tokenizer, config expects {layout.compressed_vocab_size}; " "every hash multiplier derives from it, so the engram tables " "would be silently rehashed." ) self.pad_id = token_map[layout.pad_token_id] multipliers = compute_hash_multipliers( layout.layer_ids, layout.max_ngram_size, vocab_size ) self.register_buffer( "token_map", torch.tensor(token_map, dtype=torch.int32), persistent=False ) self.register_buffer("primes", torch.tensor(layout.primes), persistent=False) self.register_buffer("offsets", layout.offsets, persistent=False) self.register_buffer("multipliers", multipliers, persistent=False) logger.info( "Built engram token map (%d -> %d ids) for layers %s", len(token_map), vocab_size, layout.layer_ids, ) def ensure_cache(self) -> bool: """Lazily size the slot-keyed cache from the bound SWA KV cache. Returns False while the KV cache is unbound (profile run); the caller skips engram hashing then. Without the slot cache only that check remains. """ kv_cache = self.swa_cache_module.kv_cache if kv_cache.numel() == 0: self._cache = None self._kv_cache_ref = None return False if not self.use_slot_cache: return True if self._kv_cache_ref is not None and self._kv_cache_ref() is kv_cache: return True # Graph memory profiling binds a temporary, smaller KV cache first. # Rebinding must discard its hash history without retaining KV storage. self._cache = torch.zeros( kv_cache.shape[0] * self.block_size, dtype=torch.int32, device=kv_cache.device, ) self._kv_cache_ref = weakref.ref(kv_cache) return True def forward( self, input_ids: torch.Tensor, positions: torch.Tensor, query_start_loc: torch.Tensor, dead_mask: torch.Tensor, lookback_token_ids: torch.Tensor, lookback_dead_mask: torch.Tensor, slot_mapping: torch.Tensor | None, block_table: torch.Tensor | None, ) -> torch.Tensor: """Compute [tokens, layers, hash columns] int32 n-gram hashes. History comes from the current chunk, then the runner's lookback window, then the optional V1 slot cache. V2 needs only one launch. """ cache = self._cache if self.use_slot_cache else None num_tokens = input_ids.shape[0] num_layers, max_ngram = self.multipliers.shape num_heads = self.primes.shape[-1] output = input_ids.new_empty( (num_tokens, num_layers, (max_ngram - 1) * num_heads), dtype=torch.int32 ) if num_tokens == 0: return output if self.use_slot_cache: assert cache is not None and slot_mapping is not None assert block_table is not None # Finish writes before other thread blocks read fallback history. _write_hash_cache_kernel[(triton.cdiv(num_tokens, 256),)]( input_ids, self.token_map, dead_mask, slot_mapping, cache, num_tokens, input_ids.stride(0), dead_mask.stride(0), slot_mapping.stride(0), 256, DEAD_ID, ) _hash_ids_kernel[(triton.cdiv(num_tokens, 32), num_layers)]( input_ids, self.token_map, dead_mask, positions, block_table, query_start_loc, self.multipliers, self.primes, self.offsets, cache, lookback_token_ids, lookback_dead_mask, output, num_tokens, cache.shape[0] if cache is not None else 0, self.pad_id, input_stride=input_ids.stride(0), mask_stride=dead_mask.stride(0), position_stride=positions.stride(0), table_stride=block_table.stride(0) if block_table is not None else 0, table_col_stride=block_table.stride(1) if block_table is not None else 0, query_stride=query_start_loc.stride(0), num_query_rows=query_start_loc.numel() - 1, num_table_rows=block_table.shape[0] if block_table is not None else 0, max_blocks=block_table.shape[1] if block_table is not None else 0, cache_block_size=self.block_size, MAX_NGRAM=max_ngram, num_heads=num_heads, BLOCK_T=32, BLOCK_H=triton.next_power_of_2(num_heads), dead_id=DEAD_ID, lookback_depth=lookback_token_ids.shape[1], lookback_row_stride=lookback_token_ids.stride(0), lookback_col_stride=lookback_token_ids.stride(1), lookback_mask_row_stride=lookback_dead_mask.stride(0), lookback_mask_col_stride=lookback_dead_mask.stride(1), num_warps=4, ) return output def _engram_head_shard_weight_loader( param: torch.nn.Parameter, loaded_weight: torch.Tensor ) -> None: """Load this rank's complete head buckets. ue8m0 scales arrive as float8_e8m0fnu; keep the raw bytes (the param stores uint8).""" part_rows = param.shape[0] if loaded_weight.dtype == torch.float8_e8m0fnu: loaded_weight = loaded_weight.view(torch.uint8) shard = loaded_weight.narrow(0, param.engram_vocab_start, part_rows) assert shard.shape == param.shape, ( f"engram shard {tuple(shard.shape)} does not fit param {tuple(param.shape)}" ) param.data.copy_(shard) @triton.jit def _engram_lookup_kernel( weight, scales, ids, out, vocab_start, vocab_end, num_rows, ids_stride_t, ids_stride_h, HEAD_START: tl.constexpr, LOCAL_HEADS: tl.constexpr, TOTAL_HEADS: tl.constexpr, DIM: tl.constexpr, QUANT_BLOCK: tl.constexpr, BLOCK_R: tl.constexpr, GRID: tl.constexpr, ): """Gather fp8 rows, apply their ue8m0 block scales, write bf16. Only this rank's heads are read; padded heads write zeros for all-gather. `weight`/`scales` may address pinned host memory through UVA. """ cols = tl.arange(0, DIM) scale_cols = cols // QUANT_BLOCK for base in tl.range(tl.program_id(0) * BLOCK_R, num_rows, GRID * BLOCK_R): rows = base + tl.arange(0, BLOCK_R) valid = rows < num_rows head = HEAD_START + rows % LOCAL_HEADS token = (rows // LOCAL_HEADS).to(tl.int64) index = tl.load( ids + token * ids_stride_t + head * ids_stride_h, mask=valid & (head < TOTAL_HEADS), other=-1, ).to(tl.int64) owned = valid & (head < TOTAL_HEADS) owned &= (index >= vocab_start) & (index < vocab_end) local = tl.where(owned, index - vocab_start, 0) values = tl.load( weight + local[:, None] * DIM + cols[None, :], mask=owned[:, None], other=0.0, ) scale = tl.load( scales + local[:, None] * (DIM // QUANT_BLOCK) + scale_cols[None, :], mask=owned[:, None], other=0, ) # ue8m0 is a power of two, so its byte *is* the fp32 exponent field. scale = (scale.to(tl.int32) << 23).to(tl.float32, bitcast=True) tl.store( out + rows[:, None] * DIM + cols[None, :], (values.to(tl.float32) * scale).to(tl.bfloat16), mask=valid[:, None], ) _DSV41_ENGRAM_DISK = _kai_os.environ.get("DSV41_ENGRAM_DISK", "0") == "1" # --- Tech2Wild/Kai 2026-09-10 (CUDA graphs): one process-wide read pool shared # by every DiskEngramTable. A step's reads for BOTH engram layers (weight and # scale rows) go out as one batch, so decode latency is ~one pread instead of # 24 serial ones (measured on Reddie: 7.7 ms serial vs 3.1 ms parallel, C1). _KAI_THREADS = int(_kai_os.environ.get("DSV41_ENGRAM_DISK_THREADS", "32")) _KAI_CHUNK = int(_kai_os.environ.get("DSV41_ENGRAM_DISK_CHUNK", "16")) _KAI_POOL: _KaiPool | None = None def _kai_pool() -> _KaiPool: global _KAI_POOL if _KAI_POOL is None: _KAI_POOL = _KaiPool(max_workers=_KAI_THREADS, thread_name_prefix="engram-disk") return _KAI_POOL def _kai_pread_rows( fd: int, base: int, rel: list, lo: int, hi: int, row_bytes: int, buf ) -> None: for i in range(lo, hi): off = base + rel[i] * row_bytes view = buf[i * row_bytes : (i + 1) * row_bytes] got = 0 while got < row_bytes: n = _kai_os.preadv(fd, [view[got:]], off + got) if n <= 0: raise OSError("engram disk table: short read") got += n def _kai_parallel_read(jobs: list) -> None: """jobs: [(fd, base, rel_list, row_bytes, memoryview)]. Every row of every job is in flight at once: a task carries ceil(total / threads) rows (1 row at decode sizes), capped at DSV41_ENGRAM_DISK_CHUNK for prefill-sized batches. Only the calling thread submits, so the shared pool cannot deadlock.""" total = sum(len(job[2]) for job in jobs) if total == 0: return if total == 1: for fd, base, rel, row_bytes, buf in jobs: _kai_pread_rows(fd, base, rel, 0, len(rel), row_bytes, buf) return chunk = max(1, min(_KAI_CHUNK, -(-total // _KAI_THREADS))) pool = _kai_pool() futs = [ pool.submit( _kai_pread_rows, fd, base, rel, lo, min(lo + chunk, len(rel)), row_bytes, buf ) for fd, base, rel, row_bytes, buf in jobs for lo in range(0, len(rel), chunk) ] for fut in futs: fut.result() def _dsv41_engram_local_dir(model_dir: str, layer_id: int, row_start: int, num_rows) -> str: """Tech2Wild 2026-09-10: node-local Engram rows. DSV41_ENGRAM_DIR points at a sparse copy of the Engram shards holding only this rank's rows at the original byte offsets, plus engram-local.json with the copied row range per layer (tools/engram_local.py). It is used only when that range covers this table's rows; otherwise the table reads model_dir as before, so a changed rank map can never read the copy's empty holes.""" local = _kai_os.environ.get("DSV41_ENGRAM_DIR", "") if not local: return model_dir try: with open(_kai_os.path.join(local, "engram-local.json")) as f: lo, hi = _kai_json.load(f)["layers"][str(layer_id)] except Exception as e: # noqa: BLE001 logger.warning("DSV41_ENGRAM_DIR=%s unusable for layer %d (%s); reading %s", local, layer_id, e, model_dir) return model_dir if num_rows is None or not (lo <= row_start and row_start + num_rows <= hi): logger.warning("DSV41_ENGRAM_DIR=%s holds layer %d rows [%d, %d), this rank needs " "[%d, +%s); reading %s", local, layer_id, lo, hi, row_start, num_rows, model_dir) return model_dir logger.info("Engram layer %d rows [%d, %d) read from node-local %s", layer_id, row_start, row_start + num_rows, local) return local class DiskEngramTable: """Tech2Wild/Kai 2026-09-10: read Engram rows straight from the safetensors shards with positional preads on a thread pool, so the per-rank Engram shard (~47 GiB at TP4) never occupies memory. Built for DGX Spark, where "pinned host memory" is the same 128 GB pool the GPU uses. Rows are dequantized on the CPU (fp8 e4m3 x ue8m0 block scales -> bf16) and copied into the GPU staging buffer. Enable with DSV41_ENGRAM_DISK=1. Lineage: our own PLE-on-disk patch for Qwen3.8-Flash-Next (2026-09-05). """ def __init__( self, model_dir: str, layer_id: int, dim: int, block_size: int, row_start: int = 0, num_rows: int | None = None, ): model_dir = _dsv41_engram_local_dir(model_dir, layer_id, row_start, num_rows) idx_path = _kai_os.path.join(model_dir, "model.safetensors.index.json") with open(idx_path) as f: weight_map = _kai_json.load(f)["weight_map"] wname = f"layers.{layer_id}.engram.embed.weight" sname = f"layers.{layer_id}.engram.embed.scale" self.w_fd, self.w_off, self.w_shape = self._open(model_dir, weight_map[wname], wname) self.s_fd, self.s_off, self.s_shape = self._open(model_dir, weight_map[sname], sname) self.dim = dim self.sb = dim // block_size assert self.w_shape[1] == dim, (self.w_shape, dim) assert self.s_shape[1] == self.sb, (self.s_shape, self.sb) assert self.s_shape[0] == self.w_shape[0], (self.s_shape, self.w_shape) # The checkpoint holds the FULL table (every TP rank's hash heads) per layer, # while callers pass rank-local row ids (global - vocab_start), so reads must # start at this rank's first row. if num_rows is None: num_rows = self.w_shape[0] - row_start assert 0 <= row_start and row_start + num_rows <= self.w_shape[0], ( row_start, num_rows, self.w_shape) self.w_off += row_start * dim self.s_off += row_start * self.sb self.row_start = row_start self.num_rows = num_rows self.threads = _KAI_THREADS self.chunk = _KAI_CHUNK self.pool = _kai_pool() # shared by all tables (was one pool per table) logger.info( "Engram DISK mode: layer %d rows [%d, %d) read from %s (off=%d) and %s (off=%d); " "%d threads, chunk %d", layer_id, row_start, row_start + num_rows, weight_map[wname], self.w_off, weight_map[sname], self.s_off, self.threads, self.chunk, ) @staticmethod def _open(model_dir: str, fname: str, tname: str): path = _kai_os.path.join(model_dir, fname) fd = _kai_os.open(path, _kai_os.O_RDONLY) try: _kai_os.posix_fadvise(fd, 0, 0, _kai_os.POSIX_FADV_RANDOM) except Exception: # noqa: BLE001 pass with open(path, "rb") as f: n = _kai_struct.unpack(" None: _kai_parallel_read([(fd, base, rel, row_bytes, buf)]) def read_jobs(self, rel_l: list, w: torch.Tensor, s: torch.Tensor) -> list: """Read jobs for rank-local rows `rel_l` into uint8 w [R, dim], s [R, sb].""" return [ (self.w_fd, self.w_off, rel_l, self.dim, memoryview(w.numpy()).cast("B")), (self.s_fd, self.s_off, rel_l, self.sb, memoryview(s.numpy()).cast("B")), ] def dequant(self, w: torch.Tensor, s: torch.Tensor) -> torch.Tensor: """fp8 e4m3 rows (as uint8) x ue8m0 block scales -> [R, dim] fp32.""" R = w.shape[0] vals = w.view(torch.float8_e4m3fn).to(torch.float32).view( R, self.sb, self.dim // self.sb ) # ue8m0 byte is the fp32 exponent field: 2^(e-127) scale = (s.to(torch.int32) << 23).view(torch.float32) return (vals * scale[:, :, None]).reshape(R, self.dim) def gather_dequant(self, rel: torch.Tensor, owned: torch.Tensor) -> torch.Tensor: """rel: [R] int64 CPU local row ids; owned: [R] bool. Returns [R, dim] bf16 CPU.""" return gather_dequant_many([(self, rel, owned)])[0] def gather_dequant_many(requests: list) -> list[torch.Tensor]: """Tech2Wild/Kai 2026-09-10: requests = [(DiskEngramTable, rel [R] int64 CPU, owned [R] bool)] -> one [R, dim] bf16 CPU tensor per request. Rows are de-duplicated per table (repeated n-grams, zero-filled dummy batches) and the reads of every table go out in ONE parallel batch. Same math as before.""" plans, jobs = [], [] for table, rel, owned in requests: uniq, inverse = torch.unique(rel, return_inverse=True) w = torch.empty((uniq.numel(), table.dim), dtype=torch.uint8) s = torch.empty((uniq.numel(), table.sb), dtype=torch.uint8) jobs += table.read_jobs(uniq.tolist(), w, s) plans.append((table, w, s, inverse, owned)) _kai_parallel_read(jobs) outs = [] for table, w, s, inverse, owned in plans: out = table.dequant(w, s)[inverse] out[~owned] = 0 outs.append(out.to(torch.bfloat16)) return outs class ParallelEngramEmbedding(nn.Module): """The n-gram hash table, sharded by complete hash heads over TP ranks. Rows stay fp8 and are dequantized with ue8m0 per-32 scales on lookup. With `cpu_offload` the shard lives in pinned host memory and is read over UVA instead of HBM; the TP sharding is unchanged either way. """ def __init__( self, num_embeddings: int, dim: int, head_sizes: tuple[int, ...], block_size: int = 32, cpu_offload: bool = False, model_dir: str | None = None, layer_id: int | None = None, ): super().__init__() self.disk: DiskEngramTable | None = None if _DSV41_ENGRAM_DISK: cpu_offload = False tp_size = get_tensor_model_parallel_world_size() tp_rank = get_tensor_model_parallel_rank() assert head_sizes and all(size > 0 for size in head_sizes) assert sum(head_sizes) <= num_embeddings if cpu_offload and not is_uva_available(): raise RuntimeError("Engram CPU offload requires UVA support") self.num_embeddings = num_embeddings self.dim = dim self.block_size = block_size self.n_hash_cols = len(head_sizes) self.part_n_hash_cols = triton.cdiv(self.n_hash_cols, tp_size) self.head_start = tp_rank * self.part_n_hash_cols head_end = self.head_start + self.part_n_hash_cols self.vocab_start_idx = sum(head_sizes[: self.head_start]) self.vocab_end_idx = sum(head_sizes[:head_end]) self.part_num_embeddings = self.vocab_end_idx - self.vocab_start_idx self.tp_size = tp_size self.cpu_offload = cpu_offload self._views: tuple[torch.Tensor, torch.Tensor] | None = None self._view_src: tuple[int, int] | None = None self._num_sms = torch.cuda.get_device_properties( torch.accelerator.current_device_index() ).multi_processor_count # Explicit device: model init runs under a `torch.device("cuda")` # context, which would otherwise put the shard in HBM. kwargs = {"device": "cpu", "pin_memory": True} if cpu_offload else {} if _DSV41_ENGRAM_DISK: assert model_dir is not None and layer_id is not None self.disk = DiskEngramTable( model_dir, layer_id, dim, block_size, row_start=self.vocab_start_idx, num_rows=self.part_num_embeddings, ) # 1-row placeholders as BUFFERS (not Parameters): the checkpoint # rows are skipped by the weights iterator and must not trip the # "weights not initialized" check. self.register_buffer("weight", torch.zeros(1, dim, dtype=torch.float8_e4m3fn, device="cpu"), persistent=False) self.register_buffer("weight_scale_inv", torch.zeros(1, dim // block_size, dtype=torch.uint8, device="cpu"), persistent=False) logger.info( "Engram table DISK-backed: %d rows x %d per rank stay on disk (%.2f GiB not allocated)", self.part_num_embeddings, dim, self.part_num_embeddings * (dim + dim // block_size) / 1024**3, ) return self.weight = nn.Parameter( torch.empty( self.part_num_embeddings, dim, dtype=torch.float8_e4m3fn, **kwargs ), requires_grad=False, ) self.weight_scale_inv = nn.Parameter( torch.empty( self.part_num_embeddings, dim // block_size, dtype=torch.uint8, **kwargs, ), requires_grad=False, ) for param in (self.weight, self.weight_scale_inv): set_weight_attrs( param, { "weight_loader": _engram_head_shard_weight_loader, "engram_vocab_start": self.vocab_start_idx, }, ) if cpu_offload: logger.info( "Engram table offloaded to pinned host memory: %d rows x %d, " "%.2f GiB per rank", self.part_num_embeddings, dim, self.part_num_embeddings * (dim + dim // block_size) / 1024**3, ) def _storage(self) -> tuple[torch.Tensor, torch.Tensor]: """Parameters when resident, else cached UVA views of the pinned shard. Rebuilt if anything swaps `.data`, so a stale device pointer cannot survive silently. """ if not self.cpu_offload: return self.weight.data, self.weight_scale_inv.data src = (self.weight.data_ptr(), self.weight_scale_inv.data_ptr()) if self._view_src != src: self._views = ( get_accelerator_view_from_cpu_tensor(self.weight.data), get_accelerator_view_from_cpu_tensor(self.weight_scale_inv.data), ) self._view_src = src assert self._views is not None return self._views def lookup( self, indices: torch.Tensor, out: torch.Tensor, background: bool = False ) -> None: """Look up local heads of [T, heads] into [T, local_heads, dim] bf16. `background` limits the grid to leave SMs for concurrent work. """ rows = indices.shape[0] * self.part_n_hash_cols if not rows: return if self.disk is not None: self._disk_lookup(indices, out) return weight, scales = self._storage() # The table dwarfs TLB reach, so a persistent grid near the SM count # beats one program per row; halve it to leave SMs for the main stream. tiles = triton.cdiv(rows, 16) grid = min(tiles, self._num_sms // 2 if background else self._num_sms) _engram_lookup_kernel[(grid,)]( weight, scales, indices, out, self.vocab_start_idx, self.vocab_end_idx, rows, indices.stride(0), indices.stride(1), HEAD_START=self.head_start, LOCAL_HEADS=self.part_n_hash_cols, TOTAL_HEADS=self.n_hash_cols, DIM=self.dim, QUANT_BLOCK=self.block_size, BLOCK_R=16, GRID=grid, ) def disk_rel_owned(self, local: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]: """local: [T, <=L] int64 CPU hash ids of this rank's heads -> flat (rel [T*L] rank-local row ids, owned [T*L] bool). Padded heads (beyond TOTAL_HEADS) and ids outside this rank's range are not owned (zeros).""" T = local.shape[0] L = self.part_n_hash_cols if local.shape[1] < L: pad = torch.full((T, L - local.shape[1]), -1, dtype=torch.int64) local = torch.cat([local, pad], dim=1) rows = local.reshape(-1) owned = (rows >= self.vocab_start_idx) & (rows < self.vocab_end_idx) rel = torch.where(owned, rows - self.vocab_start_idx, torch.zeros_like(rows)) return rel, owned def _disk_lookup(self, indices: torch.Tensor, out: torch.Tensor) -> None: """Host-side gather + dequant for DISK mode, then H2D into `out` ([T, local_heads, dim] bf16). Padded heads (beyond TOTAL_HEADS) and rows outside this rank's range write zeros, matching the kernel. In-forward fallback only (V1 runner / eager). Under the V2 runner the rows are staged by EngramDiskStager before the forward instead.""" if torch.cuda.is_available() and torch.cuda.is_current_stream_capturing(): raise RuntimeError( "Engram DISK lookup reached a CUDA-graph capture: it needs a host " "round trip. Stage rows before the forward (EngramDiskStager, V2 " "runner + patched nvidia/model_state.py) or run --enforce-eager." ) T = indices.shape[0] L = self.part_n_hash_cols ids = indices.detach().to("cpu", dtype=torch.int64) head_end = min(self.head_start + L, self.n_hash_cols) rel, owned = self.disk_rel_owned(ids[:, self.head_start:head_end]) assert self.disk is not None deq = self.disk.gather_dequant(rel, owned) out[:T].copy_(deq.view(T, L, self.dim)) def forward(self, indices: torch.Tensor) -> torch.Tensor: """indices: [num_tokens, n_hash_cols] -> [num_tokens, n_hash_cols, dim] bf16, gathered from all TP shards.""" out = torch.empty( (indices.shape[0], self.part_n_hash_cols, self.dim), dtype=torch.bfloat16, device=indices.device, ) self.lookup(indices, out) if self.tp_size > 1: out = tensor_model_parallel_all_gather(out, dim=1) out = out[:, : self.n_hash_cols] return out @triton.jit(do_not_specialize=["num_kv_tokens"]) def _fused_engram_post_wkv_kernel( hidden_states, kv, q_weight, k_weight, token_mask, output, num_kv_tokens, hidden_stride_t, hidden_stride_h, hidden_stride_d, kv_stride_t, kv_stride_d, q_stride_h, q_stride_d, k_stride_h, k_stride_d, mask_stride, output_stride_t, output_stride_h, output_stride_d, eps, clamp_value, DIM: tl.constexpr, HC_MULT: tl.constexpr, BLOCK_SIZE: tl.constexpr, HAS_MASK: tl.constexpr, ): program_idx = tl.program_id(0) token_idx = program_idx // HC_MULT hc_idx = program_idx % HC_MULT token_idx = token_idx.to(tl.int64) source_idx = token_idx source_valid = source_idx < num_kv_tokens dim_offsets = tl.arange(0, BLOCK_SIZE) dim_valid = dim_offsets < DIM hidden = tl.load( hidden_states + token_idx * hidden_stride_t + hc_idx * hidden_stride_h + dim_offsets * hidden_stride_d, mask=dim_valid, other=0.0, ).to(tl.float32) key = tl.load( kv + source_idx * kv_stride_t + (hc_idx * DIM + dim_offsets) * kv_stride_d, mask=source_valid & dim_valid, other=0.0, ).to(tl.float32) q = tl.load( q_weight + hc_idx * q_stride_h + dim_offsets * q_stride_d, mask=dim_valid, other=0.0, ).to(tl.float32) k = tl.load( k_weight + hc_idx * k_stride_h + dim_offsets * k_stride_d, mask=dim_valid, other=0.0, ).to(tl.float32) hidden_rms = tl.rsqrt(tl.sum(hidden * hidden, axis=0) / DIM + eps) key_rms = tl.rsqrt(tl.sum(key * key, axis=0) / DIM + eps) dot = tl.sum(hidden * q * k * key, axis=0) dot *= hidden_rms * key_rms * tl.rsqrt(DIM * 1.0) gate_input = tl.sqrt(tl.maximum(tl.abs(dot), clamp_value)) gate_input = tl.where(dot < 0.0, -gate_input, gate_input) gate = tl.sigmoid(gate_input) if HAS_MASK: active = tl.load( token_mask + source_idx * mask_stride, mask=source_valid, other=0, ) gate = tl.where(active, gate, 0.0) value = tl.load( kv + source_idx * kv_stride_t + (HC_MULT * DIM + dim_offsets) * kv_stride_d, mask=source_valid & dim_valid, other=0.0, ).to(tl.float32) tl.store( output + token_idx * output_stride_t + hc_idx * output_stride_h + dim_offsets * output_stride_d, hidden + gate * value, mask=dim_valid, ) @triton.jit(do_not_specialize=["num_tokens", "token_start", "num_elements"]) def _engram_sp_rows_kernel( gathered, output, num_tokens, token_start, num_elements, LOCAL_WIDTH: tl.constexpr, WIDTH: tl.constexpr, BLOCK_SIZE: tl.constexpr, ): offsets = tl.program_id(0).to(tl.int64) * BLOCK_SIZE + tl.arange(0, BLOCK_SIZE) tokens = token_start + offsets // WIDTH cols = offsets % WIDTH source = (cols // LOCAL_WIDTH * num_tokens + tokens) * LOCAL_WIDTH source += cols % LOCAL_WIDTH values = tl.load( gathered + source, (offsets < num_elements) & (tokens < num_tokens), other=0 ) tl.store(output + offsets, values, offsets < num_elements) class Engram(nn.Module): """Writes an n-gram lookup into the residual stream, gated by how well it matches that stream. The hash ids fetch `n_hash_cols` rows; `wkv` turns them into one key per hc copy plus a shared value. The gate is a normalized dot product of the stream against the key, signed-sqrt'ed before the sigmoid (matching the training kernel). """ def __init__( self, config, quant_config: QuantizationConfig | None, layout: EngramLayout, layer_hash_index: int, use_sequence_parallel: bool, prefix: str, ) -> None: super().__init__() self.layer_hash_index = layer_hash_index self.dim = config.hidden_size self.hc_mult = config.hc_mult self.eps = config.rms_norm_eps self.clamp_value = 1e-6 self.use_sequence_parallel = use_sequence_parallel # Named ``embed_tokens`` so the checkpoint's ``engram.embed.weight`` # survives the mapper's ``embed.weight`` -> ``embed_tokens.weight`` # suffix rule. engram_config = get_current_vllm_config().engram_config self.embed_tokens = ParallelEngramEmbedding( layout.num_embeddings[layer_hash_index], layout.head_dim, tuple(size for order in layout.primes[layer_hash_index] for size in order), cpu_offload=engram_config.cpu_offload if engram_config else True, model_dir=get_current_vllm_config().model_config.model, layer_id=layout.layer_ids[layer_hash_index], ) n_hash_cols = (layout.max_ngram_size - 1) * layout.n_heads self.wkv = ReplicatedLinear( n_hash_cols * layout.head_dim, self.dim * (self.hc_mult + 1), bias=False, quant_config=quant_config, return_bias=False, prefix=f"{prefix}.wkv", ) self.q_weight = nn.Parameter( torch.empty(self.hc_mult, self.dim, dtype=torch.bfloat16), requires_grad=False, ) self.k_weight = nn.Parameter( torch.empty(self.hc_mult, self.dim, dtype=torch.bfloat16), requires_grad=False, ) max_tokens = get_current_vllm_config().scheduler_config.max_num_batched_tokens # Tech2Wild/Kai 2026-09-10 (CUDA graphs): under the V2 runner a DISK # table is staged by the model state (EngramDiskStager) BEFORE the # forward, so the forward holds no host round trip and can be captured # (FULL decode graphs included). The V1 runner keeps the in-forward path. self.prestage = self.embed_tokens.disk is not None and bool( getattr(get_current_vllm_config(), "use_v2_model_runner", False) ) # Keep lookup results alive across breakable graph segments. Zeroed so # rows of cudagraph padding tokens (never staged) stay finite. self.staged_rows = torch.zeros( max_tokens, self.embed_tokens.part_n_hash_cols, layout.head_dim, dtype=torch.bfloat16, ) def prepare_embeddings(self, hash_ids: torch.Tensor) -> None: """Gather this layer's rows on the main stream before decoder layers.""" if self.prestage: # Already staged for this step by EngramDiskStager.stage(). return self.embed_tokens.lookup(hash_ids, self.staged_rows[: hash_ids.shape[0]]) def embed(self, hash_ids: torch.Tensor) -> torch.Tensor: """Gather heads, returning only local tokens when SP is enabled.""" rows = self.staged_rows[: hash_ids.shape[0]] if self.embed_tokens.tp_size == 1: return rows if self.use_sequence_parallel: tp_size = self.embed_tokens.tp_size num_tokens, local_heads, dim = rows.shape gathered = tensor_model_parallel_all_gather(rows, dim=0) chunk = (num_tokens + tp_size - 1) // tp_size rows = rows.new_empty((chunk, self.embed_tokens.n_hash_cols, dim)) _engram_sp_rows_kernel[(triton.cdiv(rows.numel(), 1024),)]( gathered, rows, num_tokens, get_tensor_model_parallel_rank() * chunk, rows.numel(), local_heads * dim, self.embed_tokens.n_hash_cols * dim, BLOCK_SIZE=1024, ) return rows rows = tensor_model_parallel_all_gather(rows, dim=1) return rows[:, : self.embed_tokens.n_hash_cols] def forward( self, hidden_states: torch.Tensor, hash_ids: torch.Tensor, token_mask: torch.Tensor | None = None, ) -> torch.Tensor: """hidden_states: [T, hc_mult, dim]; hash_ids: [T, n_hash_cols] (all tokens, pre sequence-parallel shard); token_mask: [T], False shuts the gate so those positions pass through untouched.""" kv = self.wkv(self.embed(hash_ids).flatten(-2)) num_kv_tokens = hash_ids.shape[0] assert token_mask is None or token_mask.shape == (num_kv_tokens,) if self.use_sequence_parallel: tp_size = get_tensor_model_parallel_world_size() tp_rank = get_tensor_model_parallel_rank() shard_size = (num_kv_tokens + tp_size - 1) // tp_size assert hidden_states.shape[0] == shard_size start = min(tp_rank * shard_size, num_kv_tokens) num_kv_tokens = min(shard_size, num_kv_tokens - start) if token_mask is not None: token_mask = token_mask[start : start + num_kv_tokens] num_tokens, hc_mult, dim = hidden_states.shape assert hc_mult == self.hc_mult and dim == self.dim assert kv.ndim == 2 and kv.shape[1] == (hc_mult + 1) * dim output = torch.empty_like(hidden_states) if num_tokens == 0: return output block_size = triton.next_power_of_2(dim) num_warps = 8 if block_size >= 2048 else 4 mask = token_mask if token_mask is not None else hidden_states _fused_engram_post_wkv_kernel[(num_tokens * hc_mult,)]( hidden_states, kv, self.q_weight, self.k_weight, mask, output, num_kv_tokens, hidden_states.stride(0), hidden_states.stride(1), hidden_states.stride(2), kv.stride(0), kv.stride(1), self.q_weight.stride(0), self.q_weight.stride(1), self.k_weight.stride(0), self.k_weight.stride(1), token_mask.stride(0) if token_mask is not None else 0, output.stride(0), output.stride(1), output.stride(2), self.eps, self.clamp_value, DIM=dim, HC_MULT=hc_mult, BLOCK_SIZE=block_size, HAS_MASK=token_mask is not None, num_warps=num_warps, ) return output class EngramDiskStager: """Tech2Wild/Kai 2026-09-10 (CUDA graphs): stage DISK-mode Engram rows OUTSIDE the model forward. The V2 model state calls :meth:`stage` from ``prepare_inputs`` once per step, after the runner has written this step's input ids, positions and query_start_loc (all on the current stream). It hashes the step on the GPU (same kernel, same inputs as the forward), copies only this rank's hash columns to pinned host memory, waits on ONE event, reads every row of every engram layer in one parallel batch, dequantizes on the CPU exactly like the in-forward path, and copies (async, from pinned memory) into each layer's persistent ``staged_rows``. The forward (eager, breakable PIECEWISE or FULL graph) only reads ``staged_rows``, so it never needs the host. """ def __init__(self, hash_state: NgramHashState, engrams: list["Engram"]) -> None: assert engrams and all(e.embed_tokens.disk is not None for e in engrams) self.hash_state = hash_state self.engrams = sorted(engrams, key=lambda e: e.layer_hash_index) emb = self.engrams[0].embed_tokens self.local_heads = emb.part_n_hash_cols self.head_start = emb.head_start self.head_end = min(emb.head_start + emb.part_n_hash_cols, emb.n_hash_cols) self.dim = emb.dim self.max_tokens = self.engrams[0].staged_rows.shape[0] num_layers = hash_state.multipliers.shape[0] self.hash_host = torch.empty( (self.max_tokens, num_layers, self.head_end - self.head_start), dtype=torch.int32, device="cpu", pin_memory=True, ) self.rows_host = [ torch.empty( (self.max_tokens, self.local_heads, self.dim), dtype=torch.bfloat16, device="cpu", pin_memory=True, ) for _ in self.engrams ] self.hashes_ready = torch.cuda.Event() self.num_staged = 0 logger.info( "Engram DISK rows staged before the forward (graph-safe): %d layers, " "heads [%d, %d) of %d, up to %d tokens/step, %d read threads", len(self.engrams), self.head_start, self.head_end, emb.n_hash_cols, self.max_tokens, _KAI_THREADS, ) @torch.inference_mode() def stage( self, input_ids: torch.Tensor, positions: torch.Tensor, query_start_loc: torch.Tensor, lookback_token_ids: torch.Tensor, num_tokens: int, ) -> int: """Stage rows for the first `num_tokens` (unpadded) tokens of this step. Returns the number staged; 0 while the KV cache is unbound (profiling), matching the forward, which skips engram then.""" n = min(int(num_tokens), self.max_tokens) if n <= 0 or not self.hash_state.ensure_cache(): return 0 from .mm_preprocess import image_sentinel_mask ids = input_ids[:n] hashes = self.hash_state( ids, positions[:n], query_start_loc, image_sentinel_mask(ids), lookback_token_ids, image_sentinel_mask(lookback_token_ids), None, None, ) host = self.hash_host[:n] host.copy_(hashes[:, :, self.head_start : self.head_end], non_blocking=True) self.hashes_ready.record() # The one host sync per step. It also orders this step's rewrite of the # pinned buffers after the previous step's async H2D copies from them. self.hashes_ready.synchronize() requests = [] for engram in self.engrams: local = host[:, engram.layer_hash_index, :].to(torch.int64) rel, owned = engram.embed_tokens.disk_rel_owned(local) requests.append((engram.embed_tokens.disk, rel, owned)) rows_per_layer = gather_dequant_many(requests) for engram, rows, buf in zip(self.engrams, rows_per_layer, self.rows_host): staged = buf[:n] staged.copy_(rows.view(n, self.local_heads, self.dim)) engram.staged_rows[:n].copy_(staged, non_blocking=True) self.num_staged = n return n