feat: add manual attention fallback for older CUDA architectures
Browse files- sage/model.py +15 -1
- sage_single.py +10 -1
sage/model.py
CHANGED
|
@@ -77,7 +77,21 @@ class CausalSelfAttention(nn.Module):
|
|
| 77 |
|
| 78 |
# Flash attention natively supported via scaled_dot_product_attention
|
| 79 |
is_causal = (kv_cache is None and T > 1)
|
| 80 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 81 |
|
| 82 |
y = y.transpose(1, 2).contiguous().view(B, T, C)
|
| 83 |
y = self.resid_dropout(self.wo(y))
|
|
|
|
| 77 |
|
| 78 |
# Flash attention natively supported via scaled_dot_product_attention
|
| 79 |
is_causal = (kv_cache is None and T > 1)
|
| 80 |
+
try:
|
| 81 |
+
y = F.scaled_dot_product_attention(q, k, v, attn_mask=None, dropout_p=0.0 if not self.training else 0.1, is_causal=is_causal)
|
| 82 |
+
except Exception:
|
| 83 |
+
# Manual attention fallback for older architectures (like P100 sm_60)
|
| 84 |
+
attn_weights = (q @ k.transpose(-2, -1)) * (1.0 / math.sqrt(k.size(-1)))
|
| 85 |
+
if is_causal:
|
| 86 |
+
# Use a causal mask
|
| 87 |
+
causal_mask = torch.tril(torch.ones(T, T, device=q.device)).view(1, 1, T, T)
|
| 88 |
+
attn_weights = attn_weights.masked_fill(causal_mask == 0, float('-inf'))
|
| 89 |
+
|
| 90 |
+
attn_weights = F.softmax(attn_weights, dim=-1)
|
| 91 |
+
if self.training:
|
| 92 |
+
attn_weights = F.dropout(attn_weights, p=0.1)
|
| 93 |
+
|
| 94 |
+
y = attn_weights @ v
|
| 95 |
|
| 96 |
y = y.transpose(1, 2).contiguous().view(B, T, C)
|
| 97 |
y = self.resid_dropout(self.wo(y))
|
sage_single.py
CHANGED
|
@@ -175,7 +175,16 @@ class CausalSelfAttention(nn.Module):
|
|
| 175 |
new_kv = None
|
| 176 |
q, k, v = q.transpose(1, 2), k.transpose(1, 2), v.transpose(1, 2)
|
| 177 |
is_causal = kv_cache is None and T > 1
|
| 178 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 179 |
y = y.transpose(1, 2).contiguous().view(B, T, C)
|
| 180 |
return self.resid_dropout(self.wo(y)), new_kv
|
| 181 |
|
|
|
|
| 175 |
new_kv = None
|
| 176 |
q, k, v = q.transpose(1, 2), k.transpose(1, 2), v.transpose(1, 2)
|
| 177 |
is_causal = kv_cache is None and T > 1
|
| 178 |
+
try:
|
| 179 |
+
y = F.scaled_dot_product_attention(q, k, v, dropout_p=0.0 if not self.training else 0.1, is_causal=is_causal)
|
| 180 |
+
except Exception:
|
| 181 |
+
attn = (q @ k.transpose(-2, -1)) * (self.head_dim ** -0.5)
|
| 182 |
+
if is_causal:
|
| 183 |
+
mask = torch.tril(torch.ones(T, T, device=q.device)).view(1, 1, T, T)
|
| 184 |
+
attn = attn.masked_fill(mask == 0, float('-inf'))
|
| 185 |
+
attn = F.softmax(attn, dim=-1)
|
| 186 |
+
if self.training: attn = F.dropout(attn, p=0.1)
|
| 187 |
+
y = attn @ v
|
| 188 |
y = y.transpose(1, 2).contiguous().view(B, T, C)
|
| 189 |
return self.resid_dropout(self.wo(y)), new_kv
|
| 190 |
|