Fix issue with flash linear attention in docker image
This commit is contained in:
1 parent
31f4d92f88
commit
2d4c89d392
3 files changed
+30
-7
No files matched your search
@@ -78,6 +78,12 @@ RUN pip install --no-cache-dir --break-system-packages -U \
|
|||||||
https://github.com/mjun0812/flash-attention-prebuild-wheels/releases/download/v0.9.47/flash_attn-2.8.3+cu130torch2.13-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl && \
|
https://github.com/mjun0812/flash-attention-prebuild-wheels/releases/download/v0.9.47/flash_attn-2.8.3+cu130torch2.13-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl && \
|
||||||
python -c "import flash_attn, natten, torchcodec; print('accelerators OK:', flash_attn.__version__, natten.__version__, torchcodec.__version__)"
|
python -c "import flash_attn, natten, torchcodec; print('accelerators OK:', flash_attn.__version__, natten.__version__, torchcodec.__version__)"
|
||||||
|
|
||||||
|
# flash-linear-attention (DeltaNet kernels for Qwen3.5/3.8), matching manager/spec.py FLA.
|
||||||
|
# Pure-Python Triton package installed bare and WITHOUT -U: its unpinned transformers
|
||||||
|
# requirement must not upgrade the pinned transformers from requirements_base.txt.
|
||||||
|
RUN pip install --no-cache-dir --break-system-packages flash-linear-attention==0.5.2 && \
|
||||||
|
python -c "import fla, transformers; print('fla OK:', fla.__version__, 'transformers', transformers.__version__)"
|
||||||
|
|
||||||
# Install Node dependencies (only re-runs when package.json / package-lock.json change)
|
# Install Node dependencies (only re-runs when package.json / package-lock.json change)
|
||||||
COPY ui/package.json ui/package-lock.json /app/ai-toolkit/ui/
|
COPY ui/package.json ui/package-lock.json /app/ai-toolkit/ui/
|
||||||
RUN cd /app/ai-toolkit/ui && npm ci
|
RUN cd /app/ai-toolkit/ui && npm ci
|
||||||
|
|||||||
@@ -24,14 +24,31 @@ import torch
|
|||||||
import torch.nn as nn
|
import torch.nn as nn
|
||||||
import torch.nn.functional as F
|
import torch.nn.functional as F
|
||||||
import torch.utils.checkpoint
|
import torch.utils.checkpoint
|
||||||
from fla.modules import FusedRMSNormGated
|
|
||||||
from fla.ops.gated_delta_rule import chunk_gated_delta_rule, fused_recurrent_gated_delta_rule
|
|
||||||
from transformers.models.qwen3_5.modeling_qwen3_5 import Qwen3_5VisionModel
|
from transformers.models.qwen3_5.modeling_qwen3_5 import Qwen3_5VisionModel
|
||||||
|
|
||||||
from toolkit.util.convrot_w4a8_quant import apply_forward_hooks, module_hooks_only, w4a8_grouped_linear
|
from toolkit.util.convrot_w4a8_quant import apply_forward_hooks, module_hooks_only, w4a8_grouped_linear
|
||||||
|
|
||||||
from .qwen38_kernels import _conv_step_op, _decode_attn_op, add_rmsnorm, decode_attention_fused_ok, rmsnorm, swiglu
|
from .qwen38_kernels import _conv_step_op, _decode_attn_op, add_rmsnorm, decode_attention_fused_ok, rmsnorm, swiglu
|
||||||
|
|
||||||
|
_FLA = None
|
||||||
|
|
||||||
|
|
||||||
|
def _fla():
|
||||||
|
"""flash-linear-attention, imported on first use so the extension registry loads
|
||||||
|
without it; the DeltaNet layers need its kernels at model build time."""
|
||||||
|
global _FLA
|
||||||
|
if _FLA is None:
|
||||||
|
try:
|
||||||
|
from fla.modules import FusedRMSNormGated
|
||||||
|
from fla.ops.gated_delta_rule import chunk_gated_delta_rule, fused_recurrent_gated_delta_rule
|
||||||
|
except ImportError as e:
|
||||||
|
raise ImportError(
|
||||||
|
"qwen38 needs the flash-linear-attention package (pip install flash-linear-attention)"
|
||||||
|
) from e
|
||||||
|
_FLA = (FusedRMSNormGated, chunk_gated_delta_rule, fused_recurrent_gated_delta_rule)
|
||||||
|
return _FLA
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------ norms / rope
|
# ------------------------------------------------------------------ norms / rope
|
||||||
|
|
||||||
|
|
||||||
@@ -173,7 +190,7 @@ class GatedDeltaNet(nn.Module):
|
|||||||
)
|
)
|
||||||
self.dt_bias = nn.Parameter(torch.ones(self.num_v_heads))
|
self.dt_bias = nn.Parameter(torch.ones(self.num_v_heads))
|
||||||
self.A_log = nn.Parameter(torch.zeros(self.num_v_heads))
|
self.A_log = nn.Parameter(torch.zeros(self.num_v_heads))
|
||||||
self.norm = FusedRMSNormGated(self.head_v_dim, eps=cfg.rms_norm_eps, activation="silu")
|
self.norm = _fla()[0](self.head_v_dim, eps=cfg.rms_norm_eps, activation="silu")
|
||||||
self.out_proj = nn.Linear(self.value_dim, self.hidden_size, bias=False)
|
self.out_proj = nn.Linear(self.value_dim, self.hidden_size, bias=False)
|
||||||
self.in_proj_qkv = nn.Linear(self.hidden_size, self.conv_dim, bias=False)
|
self.in_proj_qkv = nn.Linear(self.hidden_size, self.conv_dim, bias=False)
|
||||||
self.in_proj_z = nn.Linear(self.hidden_size, self.value_dim, bias=False)
|
self.in_proj_z = nn.Linear(self.hidden_size, self.value_dim, bias=False)
|
||||||
@@ -233,7 +250,7 @@ class GatedDeltaNet(nn.Module):
|
|||||||
cache.conv.copy_(F.pad(xt, (max(ks - t, 0), 0))[:, :, -ks:])
|
cache.conv.copy_(F.pad(xt, (max(ks - t, 0), 0))[:, :, -ks:])
|
||||||
conv = F.silu(F.conv1d(xt, self.conv1d.weight, None, padding=self.conv_kernel_size - 1, groups=self.conv_dim)[:, :, :t])
|
conv = F.silu(F.conv1d(xt, self.conv1d.weight, None, padding=self.conv_kernel_size - 1, groups=self.conv_dim)[:, :, :t])
|
||||||
q, k, v = self._heads(conv.transpose(1, 2))
|
q, k, v = self._heads(conv.transpose(1, 2))
|
||||||
core, final = chunk_gated_delta_rule(
|
core, final = _fla()[1](
|
||||||
q, k, v, g=g, beta=beta, initial_state=None, output_final_state=cache is not None,
|
q, k, v, g=g, beta=beta, initial_state=None, output_final_state=cache is not None,
|
||||||
use_qk_l2norm_in_kernel=True,
|
use_qk_l2norm_in_kernel=True,
|
||||||
)
|
)
|
||||||
@@ -249,7 +266,7 @@ class GatedDeltaNet(nn.Module):
|
|||||||
conv = _conv_step_op(cache.conv, mixed, self.conv1d.weight, ctx.commit) # [B, M, C]
|
conv = _conv_step_op(cache.conv, mixed, self.conv1d.weight, ctx.commit) # [B, M, C]
|
||||||
q, k, v = self._heads(conv)
|
q, k, v = self._heads(conv)
|
||||||
# the decay / beta activations run inside the recurrent kernel
|
# the decay / beta activations run inside the recurrent kernel
|
||||||
core, final = fused_recurrent_gated_delta_rule(
|
core, final = _fla()[2](
|
||||||
q, k, v, g=a_raw.float(), beta=b_raw, initial_state=cache.rec, output_final_state=True,
|
q, k, v, g=a_raw.float(), beta=b_raw, initial_state=cache.rec, output_final_state=True,
|
||||||
use_qk_l2norm_in_kernel=True, use_gate_in_kernel=True, A_log=self.A_log.float(),
|
use_qk_l2norm_in_kernel=True, use_gate_in_kernel=True, A_log=self.A_log.float(),
|
||||||
dt_bias=self.dt_bias.float(), use_beta_sigmoid_in_kernel=True,
|
dt_bias=self.dt_bias.float(), use_beta_sigmoid_in_kernel=True,
|
||||||
@@ -268,7 +285,7 @@ class GatedDeltaNet(nn.Module):
|
|||||||
full = torch.cat([cache.conv, mixed.transpose(1, 2)], dim=-1) # [B, C, ks-1+M]
|
full = torch.cat([cache.conv, mixed.transpose(1, 2)], dim=-1) # [B, C, ks-1+M]
|
||||||
beta, g = self._gates(a_raw, b_raw)
|
beta, g = self._gates(a_raw, b_raw)
|
||||||
keep_h = keep.view(1, -1, 1).to(g.dtype)
|
keep_h = keep.view(1, -1, 1).to(g.dtype)
|
||||||
_, final = fused_recurrent_gated_delta_rule(
|
_, final = _fla()[2](
|
||||||
q, k, v, g=g * keep_h, beta=beta * keep_h.to(beta.dtype), initial_state=cache.rec,
|
q, k, v, g=g * keep_h, beta=beta * keep_h.to(beta.dtype), initial_state=cache.rec,
|
||||||
output_final_state=True, use_qk_l2norm_in_kernel=True,
|
output_final_state=True, use_qk_l2norm_in_kernel=True,
|
||||||
)
|
)
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
VERSION = "0.13.33"
|
VERSION = "0.13.34"
|
||||||
Reference in new issue
Block a user