Module neuralops.tests.test_lola_attention_comprehensive
Functions
def test_lola_4d_masks()-
Expand source code
def test_lola_4d_masks(): cfg = MockConfig() attn = LoLAAttention(config=cfg, rank=16) x = torch.randn(2, 4, 64) # 4D boolean mask [B, 1, N, N] bool_mask = torch.ones(2, 1, 4, 4, dtype=torch.bool) bool_mask[:, :, :, 3] = False # mask out last token out_bool, _ = attn(x, attention_mask=bool_mask) assert out_bool.shape == (2, 4, 64) # 4D float additive mask float_mask = torch.zeros(2, 1, 4, 4, dtype=torch.float32) float_mask[:, :, :, 3] = -10000.0 out_float, _ = attn(x, attention_mask=float_mask) assert out_float.shape == (2, 4, 64) def test_lola_base_layer_peft_unwrapping()-
Expand source code
def test_lola_base_layer_peft_unwrapping(): class DummyLoRALikeWrapper(nn.Module): def __init__(self, in_dim, out_dim): super().__init__() self.base_layer = nn.Linear(in_dim, out_dim) @property def weight(self): return self.base_layer.weight @property def bias(self): return self.base_layer.bias class DummyWrappedGPT2Attention(nn.Module): def __init__(self, dim=64): super().__init__() self.c_attn = DummyLoRALikeWrapper(dim, 3 * dim) self.c_proj = DummyLoRALikeWrapper(dim, dim) cfg = MockConfig(is_decoder=True, model_type="gpt2") wrapped_attn = DummyWrappedGPT2Attention(64) attn = LoLAAttention(config=cfg, rank=16, pretrained_attn=wrapped_attn) assert attn.is_decoder x = torch.randn(2, 8, 64) out, _ = attn(x) assert out.shape == (2, 8, 64) def test_lola_basic()-
Expand source code
def test_lola_basic(): cfg = MockConfig() attn = LoLAAttention(config=cfg, rank=16) x = torch.randn(2, 8, 64) out, _ = attn(x) assert out.shape == (2, 8, 64) def test_lola_causal_mask_enforcement()-
Expand source code
def test_lola_causal_mask_enforcement(): cfg = MockConfig(is_decoder=True, model_type="gpt2") attn = LoLAAttention(config=cfg, rank=16) x = torch.randn(2, 6, 64) out, weights = attn(x, output_attentions=True) assert weights is not None # Future positions must have probability zero for i in range(6): for j in range(i + 1, 6): assert torch.all(weights[:, :, i, j] == 0.0) def test_lola_config_none_safe()-
Expand source code
def test_lola_config_none_safe(): attn = LoLAAttention(config=None, rank=16, hidden_size=64, num_heads=4) assert attn.hidden_size == 64 assert attn.num_heads == 4 x = torch.randn(2, 8, 64) out, _ = attn(x) assert out.shape == (2, 8, 64) def test_lola_distilbert_weight_copy()-
Expand source code
def test_lola_distilbert_weight_copy(): cfg = MockConfig() old_attn = DummyDistilBertAttention(64) attn = LoLAAttention(config=cfg, rank=16, pretrained_attn=old_attn) x = torch.randn(2, 8, 64) out, _ = attn(x) assert out.shape == (2, 8, 64) def test_lola_gpt2_weight_copy()-
Expand source code
def test_lola_gpt2_weight_copy(): cfg = MockConfig(is_decoder=True, model_type="gpt2") old_attn = DummyGPT2Attention(64) attn = LoLAAttention(config=cfg, rank=16, pretrained_attn=old_attn) assert attn.is_decoder x = torch.randn(2, 8, 64) out, _ = attn(x) assert out.shape == (2, 8, 64) def test_lola_inject_safe()-
Expand source code
def test_lola_inject_safe(): class DummyLayer(nn.Module): def __init__(self): super().__init__() self.attention = DummyDistilBertAttention(64) layer = DummyLayer() res = inject_lola_attention(layer=layer, model_config=MockConfig(), old_attn=layer.attention) assert res is not None x = torch.randn(2, 8, 64) out, _ = layer.attention(x) assert out.shape == (2, 8, 64) def test_lola_lora_trainable()-
Expand source code
def test_lola_lora_trainable(): cfg = MockConfig(lora_rank=8) attn = LoLAAttention(config=cfg, rank=16) assert attn.q_proj.U.requires_grad is False assert attn.q_proj.V.requires_grad is False assert attn.q_proj.lora_A.requires_grad is True assert attn.q_proj.lora_B.requires_grad is True def test_lola_lowrank_cache_batch_and_heads()-
Expand source code
def test_lola_lowrank_cache_batch_and_heads(): from neuralops.attentions.lola_attention import LowRankCache cache = LowRankCache(max_len=16, low_rank_k=4) B, H, N, D = 2, 4, 8, 16 K = torch.randn(B, H, N, D) V = torch.randn(B, H, N, D) cache.update(K, V) k_cached, v_cached = cache.get_cached() assert k_cached is not None and v_cached is not None # Shape must be [B*H, C, D] assert k_cached.shape[0] == B * H assert k_cached.shape[2] == D assert v_cached.shape[0] == B * H assert v_cached.shape[2] == D # Test cache reset cache.reset() k_empty, v_empty = cache.get_cached() assert k_empty is None and v_empty is None def test_lola_nested_encoder_injection()-
Expand source code
def test_lola_nested_encoder_injection(): class DummyBertSelf(nn.Module): def __init__(self): super().__init__() self.query = nn.Linear(64, 64) self.key = nn.Linear(64, 64) self.value = nn.Linear(64, 64) class DummyBertAttention(nn.Module): def __init__(self): super().__init__() self.self = DummyBertSelf() self.output = nn.Module() self.output.dense = nn.Linear(64, 64) class DummyBertLayer(nn.Module): def __init__(self): super().__init__() self.attention = DummyBertAttention() class DummyLlamaLayer(nn.Module): def __init__(self): super().__init__() self.self_attn = DummyQwenAttention(64) bert_layer = DummyBertLayer() injected_bert = inject_lola_attention(bert_layer, model_config=MockConfig(), old_attn=bert_layer.attention.self) assert injected_bert.is_nested_encoder is True llama_layer = DummyLlamaLayer() injected_llama = inject_lola_attention(llama_layer, model_config=MockConfig(), old_attn=llama_layer.self_attn) assert injected_llama.is_nested_encoder is False def test_lola_no_output_scale()-
Expand source code
def test_lola_no_output_scale(): cfg = MockConfig() attn = LoLAAttention(config=cfg, rank=16) assert not hasattr(attn, "output_scale") def test_lola_qwen3_5_head_dim()-
Expand source code
def test_lola_qwen3_5_head_dim(): class Qwen35Config: hidden_size = 1024 num_attention_heads = 8 num_key_value_heads = 8 head_dim = 256 model_type = "qwen3_5" is_decoder = True attn = LoLAAttention(config=Qwen35Config(), rank=16) assert attn.head_dim == 256 assert attn.all_head_size == 2048 assert attn.hidden_size == 1024 assert attn.is_decoder is True x = torch.randn(2, 4, 1024) out, _ = attn(x) assert out.shape == (2, 4, 1024) def test_lola_qwen_gqa_and_rope()-
Expand source code
def test_lola_qwen_gqa_and_rope(): cfg = MockConfig(hidden_size=64, num_attention_heads=4, num_key_value_heads=2, head_dim=16, is_decoder=True, model_type="qwen2") old_attn = DummyQwenAttention(dim=64, num_kv_heads=2, head_dim=16) attn = LoLAAttention(config=cfg, rank=16, pretrained_attn=old_attn) assert attn.kv_repeat == 2 x = torch.randn(2, 8, 64) cos = torch.randn(2, 8, 16) sin = torch.randn(2, 8, 16) out, _ = attn(x, position_embeddings=(cos, sin)) assert out.shape == (2, 8, 64) def test_lola_roberta_weight_copy()-
Expand source code
def test_lola_roberta_weight_copy(): cfg = MockConfig() old_attn = DummyRobertaAttention(64) attn = LoLAAttention(config=cfg, rank=16, pretrained_attn=old_attn) assert attn.is_nested_encoder x = torch.randn(2, 8, 64) out, _ = attn(x) assert out.shape == (2, 8, 64)
Classes
class DummyGPT2Attention (dim=64)-
Expand source code
class DummyGPT2Attention(nn.Module): def __init__(self, dim=64): super().__init__() self.c_attn = nn.Linear(dim, 3 * dim) self.c_proj = nn.Linear(dim, dim)Base class for all neural network modules.
Your models should also subclass this class.
Modules can also contain other Modules, allowing them to be nested in a tree structure. You can assign the submodules as regular attributes::
import torch.nn as nn import torch.nn.functional as F class Model(nn.Module): def __init__(self) -> None: super().__init__() self.conv1 = nn.Conv2d(1, 20, 5) self.conv2 = nn.Conv2d(20, 20, 5) def forward(self, x): x = F.relu(self.conv1(x)) return F.relu(self.conv2(x))Submodules assigned in this way will be registered, and will also have their parameters converted when you call :meth:
to, etc.Note
As per the example above, an
__init__()call to the parent class must be made before assignment on the child.:ivar training: Boolean represents whether this module is in training or evaluation mode. :vartype training: bool
Initialize internal Module state, shared by both nn.Module and ScriptModule.
Ancestors
- torch.nn.modules.module.Module
class DummyQwenAttention (dim=64, num_kv_heads=2, head_dim=16)-
Expand source code
class DummyQwenAttention(nn.Module): def __init__(self, dim=64, num_kv_heads=2, head_dim=16): super().__init__() self.q_proj = nn.Linear(dim, dim) self.k_proj = nn.Linear(dim, num_kv_heads * head_dim) self.v_proj = nn.Linear(dim, num_kv_heads * head_dim) self.o_proj = nn.Linear(dim, dim)Base class for all neural network modules.
Your models should also subclass this class.
Modules can also contain other Modules, allowing them to be nested in a tree structure. You can assign the submodules as regular attributes::
import torch.nn as nn import torch.nn.functional as F class Model(nn.Module): def __init__(self) -> None: super().__init__() self.conv1 = nn.Conv2d(1, 20, 5) self.conv2 = nn.Conv2d(20, 20, 5) def forward(self, x): x = F.relu(self.conv1(x)) return F.relu(self.conv2(x))Submodules assigned in this way will be registered, and will also have their parameters converted when you call :meth:
to, etc.Note
As per the example above, an
__init__()call to the parent class must be made before assignment on the child.:ivar training: Boolean represents whether this module is in training or evaluation mode. :vartype training: bool
Initialize internal Module state, shared by both nn.Module and ScriptModule.
Ancestors
- torch.nn.modules.module.Module
class DummyRobertaAttention (dim=64)-
Expand source code
class DummyRobertaAttention(nn.Module): def __init__(self, dim=64): super().__init__() self.self = DummyRobertaSelfAttention(dim) self.output = nn.Module() self.output.dense = nn.Linear(dim, dim)Base class for all neural network modules.
Your models should also subclass this class.
Modules can also contain other Modules, allowing them to be nested in a tree structure. You can assign the submodules as regular attributes::
import torch.nn as nn import torch.nn.functional as F class Model(nn.Module): def __init__(self) -> None: super().__init__() self.conv1 = nn.Conv2d(1, 20, 5) self.conv2 = nn.Conv2d(20, 20, 5) def forward(self, x): x = F.relu(self.conv1(x)) return F.relu(self.conv2(x))Submodules assigned in this way will be registered, and will also have their parameters converted when you call :meth:
to, etc.Note
As per the example above, an
__init__()call to the parent class must be made before assignment on the child.:ivar training: Boolean represents whether this module is in training or evaluation mode. :vartype training: bool
Initialize internal Module state, shared by both nn.Module and ScriptModule.
Ancestors
- torch.nn.modules.module.Module
class DummyRobertaSelfAttention (dim=64)-
Expand source code
class DummyRobertaSelfAttention(nn.Module): def __init__(self, dim=64): super().__init__() self.query = nn.Linear(dim, dim) self.key = nn.Linear(dim, dim) self.value = nn.Linear(dim, dim)Base class for all neural network modules.
Your models should also subclass this class.
Modules can also contain other Modules, allowing them to be nested in a tree structure. You can assign the submodules as regular attributes::
import torch.nn as nn import torch.nn.functional as F class Model(nn.Module): def __init__(self) -> None: super().__init__() self.conv1 = nn.Conv2d(1, 20, 5) self.conv2 = nn.Conv2d(20, 20, 5) def forward(self, x): x = F.relu(self.conv1(x)) return F.relu(self.conv2(x))Submodules assigned in this way will be registered, and will also have their parameters converted when you call :meth:
to, etc.Note
As per the example above, an
__init__()call to the parent class must be made before assignment on the child.:ivar training: Boolean represents whether this module is in training or evaluation mode. :vartype training: bool
Initialize internal Module state, shared by both nn.Module and ScriptModule.
Ancestors
- torch.nn.modules.module.Module