multimodalart's picture
multimodalart HF Staff
Initial GreenWAM demo
a1833c8 verified
Raw History Blame Contribute Delete
3.78 kB
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: OpenMDW-1.1
"""Abstract interfaces for persistent memory in the MoT transformer stack.
``MemoryState`` is a *mutable* Python object that lives **outside** the
``torch.compile`` boundary. It is responsible for reading cached tensors
(``read_for_layer``) and writing new tensors back (``write_for_layer``).
``MemoryValue`` is a *read-only* tensor container that is safe to pass
**into** a compiled decoder layer. Concrete implementations are plain
dataclasses whose fields are tensors (or None). No methods on
``MemoryValue`` should mutate state.
``KVToStore`` is a type alias for the 4-tuple of tensors
``(gen_k, gen_v, und_k, und_v)`` returned by each compiled layer so
the caller can write them back into the cache outside the compile boundary.
"""
from __future__ import annotations
from abc import ABC, abstractmethod
from dataclasses import dataclass
import torch
# (gen_k, gen_v, und_k, und_v) returned by each compiled layer for the caller
# to write back into the cache outside the torch.compile boundary.
KVToStore = tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]
@dataclass
class MemoryValue(ABC):
"""Read-only tensor container safe to pass into ``torch.compile``.
Concrete subclasses (e.g. ``ARMemoryValue``, ``KVTrainMemoryValue``)
are plain dataclasses of tensors. No methods on this class should
mutate state or perform non-trivial computation.
"""
@property
def supports_context_parallel_attention(self) -> bool:
"""Whether this memory value is compatible with context-parallel attention.
Overridden by ``KVTrainMemoryValue`` to return ``False``. Used by
``ContextParallelDispatch`` to reject an unsupported combination
without importing the concrete subclass.
"""
return True
class MemoryState(ABC):
"""Mutable persistent memory that lives outside ``torch.compile``.
The outer loop in ``_impl_forward`` calls ``read_for_layer`` before
each decoder layer and ``write_for_layer`` after. The ``MemoryState``
object itself is **never** passed into a compiled region.
"""
@abstractmethod
def init(self, hidden_states: dict, device: torch.device) -> None:
"""Initialization per training step.
Called once before any transformer layers are processed.
Args:
hidden_states: The packed sequence (``SequencePack``).
device: Target device for any new tensors.
"""
@abstractmethod
def read_for_layer(self, layer_idx: int) -> MemoryValue:
"""Produce a read-only tensor snapshot for *layer_idx*.
Used to retrieve KV values from the cache.
The returned ``MemoryValue`` is passed into the compiled decoder
layer as ``memory_value``.
"""
@abstractmethod
def write_for_layer(self, layer_idx: int, kv_to_store: KVToStore) -> None:
"""Store the K/V tensors produced by *layer_idx* back into the cache.
Called outside the ``torch.compile`` boundary.
"""
@abstractmethod
def is_gen_only(self) -> bool:
"""Return ``True`` when only the generation pathway should run.
When ``True``, the decoder layer assumes that the text caption has
already been processed and cached in the MemoryState object.
Used for autoregressive frame-by-frame generation of video.
"""
def requires_natten_metadata(self) -> bool:
"""Whether the packed-sequence builder should create NATTEN metadata.
Memory paths whose attention implementation handles temporal
visibility itself return ``False``.
"""
return True