Repository: lucidrains/x-transformers

Issue:
[Bug] Custom alibi position fails for flash attention
Hi! I've been revisiting the custom position alibi again, and I found that setting `attn_flash=True` will fail. It looks like the following line forgot to account for the attention bias being 4D when custom positions are passed in. Should be an easy fix?
https://github.com/lucidrains/x-transformers/blob/57efd7770f2f5df0ff7b4ffcbd623750b584e850/x_transformers/attend.py#L373

Discussion:
@lucidrains: haha yes indeed, my bad 

I'm off for the holidays and will be back mid next week

If you want to attempt a PR for this, by all means!

Solution patch:
diff --git a/x_transformers/attend.py b/x_transformers/attend.py
index d354f91..c2bad98 100644
--- a/x_transformers/attend.py
+++ b/x_transformers/attend.py
@@ -370,7 +370,7 @@ class Attend(Module):
         # convert from bool to float
 
         if exists(attn_bias):
-            attn_bias = rearrange(attn_bias, 'h i j -> 1 h i j').expand(batch, heads, -1, -1)
+            attn_bias = attn_bias.expand(batch, heads, -1, -1)
 
             # if mask given, the mask would already contain the causal mask from above logic
             # otherwise, if no mask given but still causal, mask out alibi positional bias to a large negative number


Test patch:
diff --git a/tests/test_x_transformers.py b/tests/test_x_transformers.py
index cd1be33..18c03b4 100644
--- a/tests/test_x_transformers.py
+++ b/tests/test_x_transformers.py
@@ -388,7 +388,8 @@ def test_neo_mlp():
     out = mlp(x)
     assert out.shape == (3, 7)
 
-def test_custom_alibi():
+@pytest.mark.parametrize('flash', (True, False))
+def test_custom_alibi(flash: bool):
 
     model = TransformerWrapper(
         num_tokens = 20_000,
@@ -397,7 +398,8 @@ def test_custom_alibi():
             dim = 512,
             depth = 2,
             heads = 8,
-            alibi_pos_bias = True
+            alibi_pos_bias = True,
+            attn_flash = flash
         )
     )
 
@@ -407,7 +409,8 @@ def test_custom_alibi():
 
     logits = model(x, pos = pos)
 
-def test_custom_alibi_across_heads():
+@pytest.mark.parametrize('flash', (True, False))
+def test_custom_alibi_across_heads(flash: bool):
 
     model = Decoder(
         dim = 512,
@@ -417,6 +420,7 @@ def test_custom_alibi_across_heads():
         rel_pos_kwargs = dict(
             slopes = [1, 1]
         ),
+        attn_flash = flash
     )
 
     x = torch.randn(2, 4, 512)