Spaces:
Running on Zero
Running on Zero
Download jeeves_src/model/model.py from hugging-apps/jeeves-9b: direct link, hf CLI and curl.
- Browser
- Download file 47.5 kB
-
https://huggingface.co/spaces/hugging-apps/jeeves-9b/resolve/main/jeeves_src/model/model.py
- Command line
-
hf download hf://spaces/hugging-apps/jeeves-9b/jeeves_src/model/model.py
-
curl -L -o model.py https://huggingface.co/spaces/hugging-apps/jeeves-9b/resolve/main/jeeves_src/model/model.py
47.5 kB
| from __future__ import annotations | |
| import contextlib | |
| import json | |
| import os | |
| from dataclasses import dataclass | |
| from typing import Iterator | |
| import torch | |
| import torch.nn as nn | |
| import torch.nn.functional as F | |
| from huggingface_hub import snapshot_download | |
| from safetensors import safe_open | |
| from torch.nn.attention import SDPBackend, sdpa_kernel | |
| from torch.utils.checkpoint import checkpoint | |
| from . import metal | |
| from .config import LINEAR, Qwen3_5_9BConfig | |
| from .lora import LoRAAdapter, LoRAConfig, LoRALinear, inject_lora, mark_only_lora_trainable | |
| try: | |
| from fla.ops.gated_delta_rule import chunk_gated_delta_rule as _fla_chunk_gdr | |
| from fla.ops.gated_delta_rule import fused_recurrent_gated_delta_rule as _fla_recurrent_gdr | |
| except ImportError: | |
| _fla_chunk_gdr = _fla_recurrent_gdr = None | |
| try: | |
| from . import fla_inplace | |
| except ImportError: | |
| fla_inplace = None | |
| try: | |
| from . import triton_kernels | |
| except ImportError: | |
| triton_kernels = None | |
| try: | |
| from fla.modules.layernorm import rms_norm as _fla_rms_norm | |
| except ImportError: | |
| _fla_rms_norm = None | |
| try: | |
| from fla.modules.fused_norm_gate import rms_norm_gated as _fla_rms_norm_gated | |
| except ImportError: | |
| _fla_rms_norm_gated = None | |
| try: | |
| from fla.modules.activations import swiglu as _fla_swiglu | |
| except ImportError: | |
| _fla_swiglu = None | |
| try: | |
| from fla.modules.rotary import rotary_embedding as _fla_rotary | |
| except ImportError: | |
| _fla_rotary = None | |
| try: | |
| from fla.modules.fused_linear_cross_entropy import FusedLinearCrossEntropyLoss as _FlaFusedLCE | |
| except ImportError: | |
| _FlaFusedLCE = None | |
| try: | |
| from fla.modules.convolution import causal_conv1d as _fla_causal_conv1d | |
| from fla.modules.convolution import causal_conv1d_update as _fla_causal_conv1d_update | |
| except ImportError: | |
| _fla_causal_conv1d = _fla_causal_conv1d_update = None | |
| try: | |
| from flash_attn import flash_attn_func as _flash_attn_func | |
| except ImportError: | |
| _flash_attn_func = None | |
| _AVAILABLE = { | |
| "gdn": _fla_chunk_gdr is not None and _fla_recurrent_gdr is not None, | |
| "rms_norm": _fla_rms_norm is not None, | |
| "rms_norm_gated": _fla_rms_norm_gated is not None, | |
| "swiglu": _fla_swiglu is not None, | |
| "rotary": _fla_rotary is not None, | |
| "fused_lce": _FlaFusedLCE is not None, | |
| "causal_conv1d": _fla_causal_conv1d is not None and _fla_causal_conv1d_update is not None, | |
| "flash_attn": _flash_attn_func is not None, | |
| "metal": torch.backends.mps.is_available(), | |
| "triton_inference": triton_kernels is not None, | |
| } | |
| _ENABLED_BY_ENV = os.environ.get("QWEN35_KERNELS", "1") not in ("0", "false", "False") | |
| KERNELS = {k: v and _ENABLED_BY_ENV for k, v in _AVAILABLE.items()} | |
| EFFICIENT = [SDPBackend.EFFICIENT_ATTENTION] | |
| def set_kernels(**flags: bool) -> dict[str, bool]: | |
| if "all" in flags: | |
| on = flags.pop("all") | |
| for k in KERNELS: | |
| KERNELS[k] = on and _AVAILABLE[k] | |
| for k, on in flags.items(): | |
| if k not in KERNELS: | |
| raise KeyError(f"unknown kernel {k!r}; choose from {sorted(KERNELS)}") | |
| KERNELS[k] = on and _AVAILABLE[k] | |
| return dict(KERNELS) | |
| def _on(name: str, x: torch.Tensor) -> bool: | |
| return KERNELS[name] and x.is_cuda | |
| def _needs_grad(*xs: torch.Tensor) -> bool: | |
| return torch.is_grad_enabled() and any(x.requires_grad for x in xs) | |
| def metal_enabled() -> bool: | |
| return KERNELS["metal"] and not torch.compiler.is_compiling() | |
| def _on_metal(*xs: torch.Tensor) -> bool: | |
| return metal_enabled() and all(x.is_mps and x.dtype == torch.bfloat16 for x in xs) and not _needs_grad(*xs) | |
| def _on_triton_inference(x: torch.Tensor, *others: torch.Tensor) -> bool: | |
| return _on("triton_inference", x) and x.dtype == torch.bfloat16 and not torch.compiler.is_compiling() and not _needs_grad(x, *others) | |
| class RMSNorm(nn.Module): | |
| def __init__(self, dim: int, eps: float = 1e-6): | |
| super().__init__() | |
| self.eps = eps | |
| self.weight = nn.Parameter(torch.zeros(dim)) | |
| def forward(self, x: torch.Tensor) -> torch.Tensor: | |
| if _on("rms_norm", x): | |
| return _fla_rms_norm(x, 1.0 + self.weight.float(), None, eps=self.eps) | |
| if _on_metal(x, self.weight): | |
| return metal.rms_norm(x, self.weight, self.eps) | |
| xf = x.float() | |
| xf = xf * torch.rsqrt(xf.pow(2).mean(-1, keepdim=True) + self.eps) | |
| return (xf * (1.0 + self.weight.float())).type_as(x) | |
| def extra_repr(self) -> str: | |
| return f"{tuple(self.weight.shape)}, eps={self.eps}" | |
| class FrozenRMSNorm(RMSNorm): | |
| def __init__(self, norm: RMSNorm): | |
| super().__init__(norm.weight.shape[0], norm.eps) | |
| self.weight = norm.weight | |
| self.register_buffer("shifted_weight", 1.0 + norm.weight.detach().float(), persistent=False) | |
| def forward(self, x: torch.Tensor) -> torch.Tensor: | |
| if _on("rms_norm", x): | |
| return _fla_rms_norm(x, self.shifted_weight, None, eps=self.eps) | |
| return super().forward(x) | |
| class GatedRMSNorm(nn.Module): | |
| def __init__(self, dim: int, eps: float = 1e-6): | |
| super().__init__() | |
| self.eps = eps | |
| self.weight = nn.Parameter(torch.ones(dim)) | |
| def forward(self, x: torch.Tensor, z: torch.Tensor) -> torch.Tensor: | |
| if _on("rms_norm_gated", x): | |
| return _fla_rms_norm_gated(x, z, self.weight, None, activation="swish", eps=self.eps) | |
| if x.shape == z.shape and _on_metal(x, z, self.weight): | |
| return metal.gated_rms_norm(x, z, self.weight, self.eps) | |
| xf = x.float() | |
| xf = xf * torch.rsqrt(xf.pow(2).mean(-1, keepdim=True) + self.eps) | |
| y = self.weight * xf.to(x.dtype) | |
| return (y * F.silu(z.float())).to(x.dtype) | |
| def extra_repr(self) -> str: | |
| return f"{tuple(self.weight.shape)}, eps={self.eps}" | |
| class RotaryEmbedding(nn.Module): | |
| def __init__(self, cfg: Qwen3_5_9BConfig): | |
| super().__init__() | |
| self.dim = cfg.rotary_dim | |
| inv_freq = 1.0 / (cfg.rope_theta ** (torch.arange(0, self.dim, 2, dtype=torch.float32) / self.dim)) | |
| self.register_buffer("inv_freq", inv_freq, persistent=False) | |
| def forward(self, position_ids: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]: | |
| freqs = position_ids.to(torch.float32).unsqueeze(-1) * self.inv_freq.to(position_ids.device) | |
| return freqs.cos(), freqs.sin() | |
| def _rotate_half(x: torch.Tensor) -> torch.Tensor: | |
| x1, x2 = x.chunk(2, dim=-1) | |
| return torch.cat((-x2, x1), dim=-1) | |
| def apply_rotary(x: torch.Tensor, cos: torch.Tensor, sin: torch.Tensor) -> torch.Tensor: | |
| if x.dim() == 4 and _on_metal(x) and not _needs_grad(cos, sin): | |
| return metal.rotary(x, cos, sin) | |
| # Only for per-row positions (3-D cos), where the kernel replaces the eager path. fla's rotary serves 2-D cos and rounds differently. | |
| if x.dim() == 4 and cos.dim() == 3 and _on_triton_inference(x, cos, sin): | |
| return triton_kernels.rotary(x, cos, sin) | |
| cos, sin = cos.to(x.dtype), sin.to(x.dtype) | |
| if cos.dim() == 2 and _on("rotary", x): | |
| return _fla_rotary(x, cos, sin, interleaved=False) | |
| rd = 2 * cos.shape[-1] | |
| cos = torch.cat((cos, cos), dim=-1).unsqueeze(-2) | |
| sin = torch.cat((sin, sin), dim=-1).unsqueeze(-2) | |
| x_rot, x_pass = x[..., :rd], x[..., rd:] | |
| x_rot = x_rot * cos + _rotate_half(x_rot) * sin | |
| return torch.cat((x_rot, x_pass), dim=-1) | |
| def causal_conv1d(x: torch.Tensor, weight: torch.Tensor) -> torch.Tensor: | |
| if _on("causal_conv1d", x): | |
| return _fla_causal_conv1d(x, weight, None, activation="silu")[0] | |
| K = weight.shape[-1] | |
| y = F.conv1d(x.transpose(1, 2), weight.unsqueeze(1), None, padding=K - 1, groups=x.shape[-1]) | |
| return F.silu(y[..., : x.shape[1]]).transpose(1, 2) | |
| def causal_conv1d_step(x: torch.Tensor, state: torch.Tensor, weight: torch.Tensor) -> torch.Tensor: | |
| if _on("causal_conv1d", x) and not _needs_grad(x, weight): | |
| return _fla_causal_conv1d_update(x, state, None, weight, None, "silu")[0] | |
| K = weight.shape[-1] | |
| window = torch.cat((state, x.to(state.dtype)[..., None]), dim=-1)[..., -K:] | |
| state.copy_(window) | |
| y = (window * weight.unsqueeze(0)).sum(-1) | |
| return F.silu(y).to(x.dtype) | |
| def _l2norm(x: torch.Tensor, eps: float = 1e-6) -> torch.Tensor: | |
| return x * torch.rsqrt((x * x).sum(-1, keepdim=True) + eps) | |
| def torch_recurrent_gated_delta_rule(q, k, v, g, beta, initial_state=None, output_final_state=False): | |
| dtype = q.dtype | |
| q, k = _l2norm(q.float()), _l2norm(k.float()) | |
| v, g, beta = v.float(), g.float(), beta.float() | |
| B, T, H, Dk = k.shape | |
| Dv = v.shape[-1] | |
| q = q * Dk**-0.5 | |
| S = torch.zeros(B, H, Dk, Dv, dtype=torch.float32, device=q.device) if initial_state is None \ | |
| else initial_state.to(torch.float32) | |
| outs = [] | |
| for t in range(T): | |
| S = S * g[:, t].exp()[..., None, None] | |
| k_t, v_t, q_t = k[:, t], v[:, t], q[:, t] | |
| retrieved = torch.einsum("bhk,bhkv->bhv", k_t, S) | |
| delta = beta[:, t, :, None] * (v_t - retrieved) | |
| S = S + torch.einsum("bhk,bhv->bhkv", k_t, delta) | |
| outs.append(torch.einsum("bhk,bhkv->bhv", q_t, S)) | |
| out = torch.stack(outs, dim=1) | |
| return out.to(dtype), (S if output_final_state else None) | |
| def torch_chunk_gated_delta_rule(q, k, v, g, beta, chunk_size=64, initial_state=None, output_final_state=False): | |
| dtype = q.dtype | |
| q, k = _l2norm(q.float()), _l2norm(k.float()) | |
| v, g, beta = v.float(), g.float(), beta.float() | |
| B, T, H, Dk = k.shape | |
| Dv = v.shape[-1] | |
| C = chunk_size | |
| pad = (-T) % C | |
| if pad: | |
| q, k, v = (F.pad(x, (0, 0, 0, 0, 0, pad)) for x in (q, k, v)) | |
| g, beta = (F.pad(x, (0, 0, 0, pad)) for x in (g, beta)) | |
| N = (T + pad) // C | |
| q = (q * Dk**-0.5).transpose(1, 2).reshape(B, H, N, C, Dk) | |
| k = k.transpose(1, 2).reshape(B, H, N, C, Dk) | |
| v = v.transpose(1, 2).reshape(B, H, N, C, Dv) | |
| g = g.transpose(1, 2).reshape(B, H, N, C) | |
| beta = beta.transpose(1, 2).reshape(B, H, N, C) | |
| gc = g.cumsum(-1) | |
| lower = torch.tril(torch.ones(C, C, dtype=torch.bool, device=q.device)) | |
| strict = torch.tril(torch.ones(C, C, dtype=torch.bool, device=q.device), diagonal=-1) | |
| decay = (gc[..., :, None] - gc[..., None, :]).masked_fill(~lower, 0).exp().masked_fill(~lower, 0) | |
| k_beta = k * beta[..., None] | |
| v_beta = v * beta[..., None] | |
| L = (k_beta @ k.transpose(-1, -2) * decay).masked_fill(~strict, 0) | |
| L = L + torch.eye(C, dtype=L.dtype, device=L.device) | |
| u = torch.linalg.solve_triangular(L, v_beta, upper=False, unitriangular=True) | |
| w = torch.linalg.solve_triangular(L, k_beta * gc.exp()[..., None], upper=False, unitriangular=True) | |
| S = torch.zeros(B, H, Dk, Dv, dtype=torch.float32, device=q.device) if initial_state is None \ | |
| else initial_state.to(torch.float32) | |
| outs = [] | |
| for n in range(N): | |
| q_n, k_n, gc_n = q[:, :, n], k[:, :, n], gc[:, :, n] | |
| v_new = u[:, :, n] - w[:, :, n] @ S | |
| intra = (q_n @ k_n.transpose(-1, -2) * decay[:, :, n]) @ v_new | |
| inter = (q_n * gc_n.exp()[..., None]) @ S | |
| outs.append(inter + intra) | |
| g_last = gc_n[..., -1] | |
| S = S * g_last.exp()[..., None, None] + \ | |
| (k_n * (g_last[..., None] - gc_n).exp()[..., None]).transpose(-1, -2) @ v_new | |
| out = torch.stack(outs, dim=2).reshape(B, H, N * C, Dv)[:, :, :T].transpose(1, 2) | |
| return out.to(dtype), (S if output_final_state else None) | |
| def gated_delta_rule_chunk(q, k, v, g, beta, initial_state=None, output_final_state=False): | |
| if _on("gdn", q): | |
| return _fla_chunk_gdr(q, k, v, g=g, beta=beta, initial_state=initial_state, | |
| output_final_state=output_final_state, use_qk_l2norm_in_kernel=True) | |
| return torch_chunk_gated_delta_rule(q, k, v, g, beta, initial_state=initial_state, | |
| output_final_state=output_final_state) | |
| def gated_delta_rule_step(q, k, v, g, beta, initial_state=None, output_final_state=True): | |
| if _on("gdn", q) and not _needs_grad(q, k, v, g, beta): | |
| return _fla_recurrent_gdr(q, k, v, g=g, beta=beta, initial_state=initial_state, | |
| output_final_state=output_final_state, use_qk_l2norm_in_kernel=True) | |
| return torch_recurrent_gated_delta_rule(q, k, v, g, beta, initial_state=initial_state, | |
| output_final_state=output_final_state) | |
| def gated_delta_rule_advance_inplace(k, v, g, beta, state, steps) -> None: | |
| # The kernel rounds like fla's, so it runs only where the fallback would run fla. | |
| if _on("gdn", k) and fla_inplace is not None and _on_triton_inference(k, v, g, beta): | |
| fla_inplace.gated_delta_rule_advance_inplace(k, v, g, beta, state, steps) | |
| return | |
| keep = (torch.arange(k.shape[1], device=k.device)[None] < steps[:, None]).float()[..., None] | |
| state.copy_(gated_delta_rule_step(torch.zeros_like(k), k, v, g * keep, beta * keep.to(beta.dtype), initial_state=state)[1]) | |
| def delta_gates(b, a, dt_bias, log_decay_rate, valid=None) -> tuple[torch.Tensor, torch.Tensor]: | |
| if _on_triton_inference(b, a, dt_bias, log_decay_rate): | |
| return triton_kernels.delta_gates(b, a, dt_bias, log_decay_rate, valid) | |
| beta, g = b.sigmoid(), log_decay_rate * F.softplus(a.float() + dt_bias) | |
| if valid is None: | |
| return beta, g | |
| kept = valid[..., None] | |
| return beta * kept.to(beta.dtype), g * kept.float() | |
| def eager_conv_step(state, qkv, weight, key_dim: int, value_dim: int, head_k_dim: int, head_v_dim: int, ext_out=None): | |
| B, T, C = qkv.shape | |
| ext = torch.cat((state, qkv.transpose(1, 2)), dim=-1, out=ext_out) | |
| conv = F.silu(F.conv1d(ext, weight, groups=C)[..., -T:]).transpose(1, 2) | |
| q, k, v = conv.split([key_dim, key_dim, value_dim], dim=-1) | |
| k_heads, v_heads = key_dim // head_k_dim, value_dim // head_v_dim | |
| q = q.reshape(B, T, k_heads, head_k_dim).repeat_interleave(v_heads // k_heads, dim=2) | |
| k = k.reshape(B, T, k_heads, head_k_dim).repeat_interleave(v_heads // k_heads, dim=2) | |
| return ext, q, k, v.reshape(B, T, v_heads, head_v_dim) | |
| def conv_step(state, qkv, weight, key_dim: int, value_dim: int, head_k_dim: int, head_v_dim: int, ext_out=None): | |
| if _on_triton_inference(qkv, state, weight): | |
| return triton_kernels.conv_step(state, qkv, weight, key_dim, value_dim, head_k_dim, head_v_dim, ext_out) | |
| ext, q, k, v = eager_conv_step(state, qkv, weight, key_dim, value_dim, head_k_dim, head_v_dim, ext_out) | |
| return ext, q, k, v.contiguous() | |
| def rotate_into_cache(k, v, qm, km, vm, cos_c, sin_c, cos_m, sin_m, k_cache, v_cache, rows, positions, tail_start: int) -> torch.Tensor: | |
| if _on_triton_inference(k, v, qm, km, vm) and k_cache.dtype == k.dtype: | |
| return triton_kernels.rotate_into_cache(k, v, qm, km, vm, cos_c, sin_c, cos_m, sin_m, k_cache, v_cache, rows, positions, tail_start) | |
| k_cache[rows, positions] = apply_rotary(k, cos_c, sin_c) | |
| v_cache[rows, positions] = v | |
| B, M = qm.shape[:2] | |
| q = apply_rotary(qm, cos_m, sin_m) | |
| k_cache[:B, tail_start:tail_start + M] = apply_rotary(km, cos_m, sin_m) | |
| v_cache[:B, tail_start:tail_start + M] = vm | |
| return q | |
| def decode_attention(q, k_cache, v_cache, mask, scale: float) -> torch.Tensor: | |
| if _on_triton_inference(q, k_cache, v_cache) and triton_kernels.decode_attention_supported(q, k_cache, v_cache, mask): | |
| return triton_kernels.decode_attention(q, k_cache, v_cache, mask, scale) | |
| B, length = q.shape[0], mask.shape[-1] | |
| keys, vals = k_cache[:B, :length], v_cache[:B, :length] | |
| # Space patch: expand KV heads instead of enable_gqa (the efficient kernel rejects GQA on this torch build). | |
| if q.shape[2] != keys.shape[2]: | |
| rep = q.shape[2] // keys.shape[2] | |
| keys, vals = keys.repeat_interleave(rep, dim=2), vals.repeat_interleave(rep, dim=2) | |
| with sdpa_kernel(EFFICIENT): | |
| return F.scaled_dot_product_attention(q.transpose(1, 2), keys.transpose(1, 2), vals.transpose(1, 2), attn_mask=mask, | |
| scale=scale).transpose(1, 2) | |
| class Cache: | |
| def __init__(self, num_layers: int): | |
| self.kv: list[tuple[torch.Tensor, torch.Tensor] | None] = [None] * num_layers | |
| self.conv: list[torch.Tensor | None] = [None] * num_layers | |
| self.rec: list[torch.Tensor | None] = [None] * num_layers | |
| self.seen_tokens = 0 | |
| def has_state(self, layer: int) -> bool: | |
| return self.kv[layer] is not None or self.rec[layer] is not None | |
| def update_kv(self, layer: int, k: torch.Tensor, v: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]: | |
| if self.kv[layer] is not None: | |
| k = torch.cat((self.kv[layer][0], k), dim=1) | |
| v = torch.cat((self.kv[layer][1], v), dim=1) | |
| self.kv[layer] = (k, v) | |
| return k, v | |
| def reorder(self, idx: torch.Tensor) -> None: | |
| for i in range(len(self.kv)): | |
| if self.kv[i] is not None: | |
| self.kv[i] = (self.kv[i][0][idx], self.kv[i][1][idx]) | |
| if self.conv[i] is not None: | |
| self.conv[i] = self.conv[i][idx] | |
| if self.rec[i] is not None: | |
| self.rec[i] = self.rec[i][idx] | |
| class StaticCache: | |
| def __init__(self, cfg: Qwen3_5_9BConfig, batch: int, max_len: int, device: torch.device, dtype: torch.dtype): | |
| self.max_len = max_len | |
| self.prefilled = False | |
| self.k: dict[int, torch.Tensor] = {} | |
| self.v: dict[int, torch.Tensor] = {} | |
| self.conv: dict[int, torch.Tensor] = {} | |
| self.rec: dict[int, torch.Tensor] = {} | |
| for i, kind in enumerate(cfg.layer_types): | |
| if kind == LINEAR: | |
| self.conv[i] = torch.zeros(batch, cfg.linear_conv_dim, cfg.linear_conv_kernel_dim, device=device, dtype=dtype) | |
| self.rec[i] = torch.zeros(batch, cfg.linear_num_value_heads, cfg.linear_key_head_dim, cfg.linear_value_head_dim, | |
| device=device, dtype=torch.float32) | |
| else: | |
| self.k[i] = torch.zeros(batch, max_len, cfg.num_key_value_heads, cfg.head_dim, device=device, dtype=dtype) | |
| self.v[i] = torch.zeros(batch, max_len, cfg.num_key_value_heads, cfg.head_dim, device=device, dtype=dtype) | |
| self.valid = torch.zeros(batch, max_len, dtype=torch.bool, device=device) | |
| self.write_idx = torch.zeros(1, dtype=torch.long, device=device) | |
| self.window = max_len | |
| def decoding(self, T: int) -> bool: | |
| return self.prefilled and T == 1 | |
| def compact(self, rows: torch.Tensor) -> None: | |
| for d in (self.k, self.v, self.conv, self.rec): | |
| for i in d: | |
| d[i] = d[i].index_select(0, rows).contiguous() | |
| self.valid = self.valid.index_select(0, rows).contiguous() | |
| def finish_prefill(self, T: int, attention_mask: torch.Tensor | None) -> None: | |
| self.valid[:, :T] = True if attention_mask is None else attention_mask.bool() | |
| self.write_idx.fill_(T) | |
| self.prefilled = True | |
| def begin_step(self) -> None: | |
| self.valid.index_fill_(1, self.write_idx, True) | |
| def advance(self) -> None: | |
| self.write_idx += 1 | |
| class GatedDeltaNet(nn.Module): | |
| def __init__(self, cfg: Qwen3_5_9BConfig, layer_idx: int): | |
| super().__init__() | |
| self.layer_idx = layer_idx | |
| self.num_k_heads, self.num_v_heads = cfg.linear_num_key_heads, cfg.linear_num_value_heads | |
| self.head_k_dim, self.head_v_dim = cfg.linear_key_head_dim, cfg.linear_value_head_dim | |
| self.key_dim, self.value_dim = cfg.linear_key_dim, cfg.linear_value_dim | |
| self.conv_dim, self.conv_kernel = cfg.linear_conv_dim, cfg.linear_conv_kernel_dim | |
| hs = cfg.hidden_size | |
| self.in_proj_qkv = nn.Linear(hs, self.conv_dim, bias=False) | |
| self.in_proj_z = nn.Linear(hs, self.value_dim, bias=False) | |
| self.in_proj_b = nn.Linear(hs, self.num_v_heads, bias=False) | |
| self.in_proj_a = nn.Linear(hs, self.num_v_heads, bias=False) | |
| self.conv1d = nn.Conv1d(self.conv_dim, self.conv_dim, self.conv_kernel, groups=self.conv_dim, | |
| padding=self.conv_kernel - 1, bias=False) | |
| self.dt_bias = nn.Parameter(torch.ones(self.num_v_heads)) | |
| self.A_log = nn.Parameter(torch.empty(self.num_v_heads).uniform_(0, 16).log_()) | |
| self.norm = GatedRMSNorm(self.head_v_dim, eps=cfg.rms_norm_eps) | |
| self.out_proj = nn.Linear(self.value_dim, hs, bias=False) | |
| def forward(self, x: torch.Tensor, cache: Cache | None = None, | |
| padding_mask: torch.Tensor | None = None) -> torch.Tensor: | |
| B, T, _ = x.shape | |
| if padding_mask is not None: | |
| x = (x * padding_mask[:, :, None]).to(x.dtype) | |
| qkv = self.in_proj_qkv(x) | |
| z = self.in_proj_z(x).view(B, T, self.num_v_heads, self.head_v_dim) | |
| b = self.in_proj_b(x) | |
| a = self.in_proj_a(x) | |
| conv_w = self.conv1d.weight.squeeze(1) | |
| if isinstance(cache, StaticCache): | |
| if cache.decoding(T): | |
| qkv = causal_conv1d_step(qkv[:, 0], cache.conv[self.layer_idx], conv_w)[:, None] | |
| else: | |
| cache.conv[self.layer_idx].copy_(F.pad(qkv.transpose(1, 2), (self.conv_kernel - T, 0))) | |
| qkv = causal_conv1d(qkv, conv_w) | |
| cached = cache.prefilled | |
| else: | |
| cached = cache is not None and cache.has_state(self.layer_idx) | |
| if cached and T == 1: | |
| qkv = causal_conv1d_step(qkv[:, 0], cache.conv[self.layer_idx], conv_w)[:, None] | |
| else: | |
| if cached: | |
| qkv = torch.cat((cache.conv[self.layer_idx].transpose(1, 2), qkv), dim=1) | |
| if cache is not None: | |
| cache.conv[self.layer_idx] = F.pad(qkv.transpose(1, 2), (self.conv_kernel - qkv.shape[1], 0)).contiguous() | |
| qkv = causal_conv1d(qkv, conv_w)[:, -T:] | |
| q, k, v = qkv.split([self.key_dim, self.key_dim, self.value_dim], dim=-1) | |
| q = q.reshape(B, T, self.num_k_heads, self.head_k_dim) | |
| k = k.reshape(B, T, self.num_k_heads, self.head_k_dim) | |
| v = v.reshape(B, T, self.num_v_heads, self.head_v_dim) | |
| if self.num_v_heads != self.num_k_heads: | |
| rep = self.num_v_heads // self.num_k_heads | |
| q = q.repeat_interleave(rep, dim=2) | |
| k = k.repeat_interleave(rep, dim=2) | |
| beta = b.sigmoid() | |
| g = -self.A_log.float().exp() * F.softplus(a.float() + self.dt_bias) | |
| if isinstance(cache, StaticCache): | |
| if cache.decoding(T): | |
| if _on("gdn", q) and fla_inplace is not None and not _needs_grad(q, k, v, g, beta): | |
| o = fla_inplace.gated_delta_rule_step_inplace(q.contiguous(), k.contiguous(), v.contiguous(), g.contiguous(), | |
| beta.contiguous(), cache.rec[self.layer_idx]) | |
| else: | |
| o, state = gated_delta_rule_step(q, k, v, g, beta, initial_state=cache.rec[self.layer_idx], output_final_state=True) | |
| cache.rec[self.layer_idx].copy_(state) | |
| else: | |
| o, state = gated_delta_rule_chunk(q, k, v, g, beta, initial_state=None, output_final_state=True) | |
| cache.rec[self.layer_idx].copy_(state) | |
| else: | |
| state = cache.rec[self.layer_idx] if cached else None | |
| if cached and T == 1: | |
| o, state = gated_delta_rule_step(q, k, v, g, beta, initial_state=state, output_final_state=True) | |
| else: | |
| o, state = gated_delta_rule_chunk(q, k, v, g, beta, initial_state=state, | |
| output_final_state=cache is not None) | |
| if cache is not None: | |
| cache.rec[self.layer_idx] = state | |
| o = self.norm(o.reshape(-1, self.head_v_dim), z.reshape(-1, self.head_v_dim)) | |
| return self.out_proj(o.view(B, T, self.value_dim)) | |
| class GatedAttention(nn.Module): | |
| def __init__(self, cfg: Qwen3_5_9BConfig, layer_idx: int): | |
| super().__init__() | |
| self.layer_idx = layer_idx | |
| self.num_heads, self.num_kv_heads, self.head_dim = cfg.num_attention_heads, cfg.num_key_value_heads, cfg.head_dim | |
| self.scaling = self.head_dim**-0.5 | |
| hs, hd = cfg.hidden_size, cfg.head_dim | |
| self.q_proj = nn.Linear(hs, self.num_heads * hd * 2, bias=cfg.attention_bias) | |
| self.k_proj = nn.Linear(hs, self.num_kv_heads * hd, bias=cfg.attention_bias) | |
| self.v_proj = nn.Linear(hs, self.num_kv_heads * hd, bias=cfg.attention_bias) | |
| self.o_proj = nn.Linear(self.num_heads * hd, hs, bias=cfg.attention_bias) | |
| self.q_norm = RMSNorm(hd, eps=cfg.rms_norm_eps) | |
| self.k_norm = RMSNorm(hd, eps=cfg.rms_norm_eps) | |
| def forward(self, x: torch.Tensor, cos: torch.Tensor, sin: torch.Tensor, | |
| attn_mask: torch.Tensor | None = None, cache: Cache | None = None) -> torch.Tensor: | |
| B, T, _ = x.shape | |
| H, Hkv, D = self.num_heads, self.num_kv_heads, self.head_dim | |
| q, gate = self.q_proj(x).view(B, T, H, 2 * D).chunk(2, dim=-1) | |
| gate = gate.reshape(B, T, H * D) | |
| q = self.q_norm(q) | |
| k = self.k_norm(self.k_proj(x).view(B, T, Hkv, D)) | |
| v = self.v_proj(x).view(B, T, Hkv, D) | |
| q, k = apply_rotary(q, cos, sin), apply_rotary(k, cos, sin) | |
| if isinstance(cache, StaticCache): | |
| if cache.decoding(T): | |
| cache.k[self.layer_idx].index_copy_(1, cache.write_idx, k) | |
| cache.v[self.layer_idx].index_copy_(1, cache.write_idx, v) | |
| k, v = cache.k[self.layer_idx][:, :cache.window], cache.v[self.layer_idx][:, :cache.window] | |
| attn_mask = cache.valid[:, None, None, :cache.window] | |
| else: | |
| cache.k[self.layer_idx][:, :T].copy_(k) | |
| cache.v[self.layer_idx][:, :T].copy_(v) | |
| elif cache is not None: | |
| k, v = cache.update_kv(self.layer_idx, k, v) | |
| Tk = k.shape[1] | |
| causal = T > 1 and attn_mask is None | |
| if attn_mask is None and _on("flash_attn", q) and q.dtype in (torch.float16, torch.bfloat16): | |
| o = _flash_attn_func(q, k, v, softmax_scale=self.scaling, causal=causal) | |
| else: | |
| qt, kt, vt = (t.transpose(1, 2) for t in (q, k, v)) | |
| if attn_mask is None and T > 1 and T != Tk: | |
| attn_mask = torch.ones(T, Tk, dtype=torch.bool, device=q.device).tril(Tk - T) | |
| causal = False | |
| o = F.scaled_dot_product_attention(qt, kt, vt, attn_mask=attn_mask, is_causal=causal, | |
| scale=self.scaling, enable_gqa=True) | |
| o = o.transpose(1, 2) | |
| o = o.reshape(B, T, H * D) * torch.sigmoid(gate) | |
| return self.o_proj(o) | |
| class SwiGLU(nn.Module): | |
| def __init__(self, cfg: Qwen3_5_9BConfig): | |
| super().__init__() | |
| self.gate_proj = nn.Linear(cfg.hidden_size, cfg.intermediate_size, bias=False) | |
| self.up_proj = nn.Linear(cfg.hidden_size, cfg.intermediate_size, bias=False) | |
| self.down_proj = nn.Linear(cfg.intermediate_size, cfg.hidden_size, bias=False) | |
| def forward(self, x: torch.Tensor) -> torch.Tensor: | |
| gate, up = self.gate_proj(x), self.up_proj(x) | |
| h = _fla_swiglu(gate, up) if _on("swiglu", x) else F.silu(gate) * up | |
| return self.down_proj(h) | |
| class DecoderLayer(nn.Module): | |
| def __init__(self, cfg: Qwen3_5_9BConfig, layer_idx: int): | |
| super().__init__() | |
| self.layer_type = cfg.layer_types[layer_idx] | |
| if self.layer_type == LINEAR: | |
| self.linear_attn = GatedDeltaNet(cfg, layer_idx) | |
| else: | |
| self.self_attn = GatedAttention(cfg, layer_idx) | |
| self.mlp = SwiGLU(cfg) | |
| self.input_layernorm = RMSNorm(cfg.hidden_size, eps=cfg.rms_norm_eps) | |
| self.post_attention_layernorm = RMSNorm(cfg.hidden_size, eps=cfg.rms_norm_eps) | |
| def forward(self, x, cos, sin, attn_mask, padding_mask, cache=None): | |
| h = self.input_layernorm(x) | |
| if self.layer_type == LINEAR: | |
| h = self.linear_attn(h, cache=cache, padding_mask=padding_mask) | |
| else: | |
| h = self.self_attn(h, cos, sin, attn_mask=attn_mask, cache=cache) | |
| x = x + h | |
| return x + self.mlp(self.post_attention_layernorm(x)) | |
| class Qwen3_5Model(nn.Module): | |
| def __init__(self, cfg: Qwen3_5_9BConfig): | |
| super().__init__() | |
| self.cfg = cfg | |
| self.embed_tokens = nn.Embedding(cfg.vocab_size, cfg.hidden_size, cfg.pad_token_id) | |
| self.layers = nn.ModuleList(DecoderLayer(cfg, i) for i in range(cfg.num_hidden_layers)) | |
| self.norm = RMSNorm(cfg.hidden_size, eps=cfg.rms_norm_eps) | |
| self.rotary_emb = RotaryEmbedding(cfg) | |
| self.gradient_checkpointing = False | |
| self.compiled_layers: list | None = None | |
| def forward(self, input_ids: torch.Tensor | None = None, attention_mask: torch.Tensor | None = None, | |
| position_ids: torch.Tensor | None = None, cache: Cache | None = None, | |
| inputs_embeds: torch.Tensor | None = None, normed: bool = True) -> torch.Tensor: | |
| if (input_ids is None) == (inputs_embeds is None): | |
| raise ValueError("pass exactly one of input_ids / inputs_embeds") | |
| x = self.embed_tokens(input_ids) if inputs_embeds is None else inputs_embeds | |
| B, T, _ = x.shape | |
| static = isinstance(cache, StaticCache) | |
| past = cache.seen_tokens if cache is not None and not static else 0 | |
| if position_ids is None: | |
| pos = torch.arange(past, past + T, device=x.device) | |
| else: | |
| pos = position_ids | |
| if pos.dim() == 2 and pos.shape[0] == 1: | |
| pos = pos[0] | |
| cos, sin = self.rotary_emb(pos) | |
| attn_mask = padding_mask = None | |
| if attention_mask is not None: | |
| padding_mask = attention_mask.to(x.dtype) | |
| key_valid = attention_mask.bool() | |
| if past and key_valid.shape[1] == T: | |
| key_valid = torch.cat((torch.ones(B, past, dtype=torch.bool, device=x.device), key_valid), 1) | |
| Tk = key_valid.shape[1] | |
| causal = torch.ones(T, Tk, dtype=torch.bool, device=x.device).tril(Tk - T) | |
| attn_mask = causal[None, None] & key_valid[:, None, None, :] | |
| if past: | |
| padding_mask = None | |
| if static and cache.decoding(T): | |
| cache.begin_step() | |
| use_ckpt = self.gradient_checkpointing and torch.is_grad_enabled() and cache is None | |
| layers = self.compiled_layers if self.compiled_layers is not None and cache is None else self.layers | |
| for layer in layers: | |
| if use_ckpt: | |
| x = checkpoint(layer, x, cos, sin, attn_mask, padding_mask, use_reentrant=False) | |
| else: | |
| x = layer(x, cos, sin, attn_mask, padding_mask, cache=cache) | |
| if static: | |
| if cache.decoding(T): | |
| cache.advance() | |
| else: | |
| cache.finish_prefill(T, attention_mask) | |
| elif cache is not None: | |
| cache.seen_tokens += T | |
| return self.norm(x) if normed else x | |
| class CausalLMOutput: | |
| logits: torch.Tensor | None = None | |
| loss: torch.Tensor | None = None | |
| cache: Cache | None = None | |
| class Qwen3_5ForCausalLM(nn.Module): | |
| def __init__(self, cfg: Qwen3_5_9BConfig | None = None, lora: LoRAConfig | None = None): | |
| super().__init__() | |
| self.cfg = cfg or Qwen3_5_9BConfig() | |
| self.model = Qwen3_5Model(self.cfg) | |
| self.lm_head = nn.Linear(self.cfg.hidden_size, self.cfg.vocab_size, bias=False) | |
| if self.cfg.tie_word_embeddings: | |
| self.lm_head.weight = self.model.embed_tokens.weight | |
| self.lora: LoRAAdapter | None = None | |
| self.freeze() | |
| if lora is not None: | |
| self.add_lora(lora) | |
| def freeze(self) -> "Qwen3_5ForCausalLM": | |
| for p in self.parameters(): | |
| p.requires_grad_(False) | |
| if self.lora is not None: | |
| self.lora.requires_grad_(True) | |
| return self.eval() | |
| def add_lora(self, cfg: LoRAConfig | None = None) -> LoRAAdapter: | |
| if self.lora is not None: | |
| raise RuntimeError("LoRA already attached; call remove_lora() first") | |
| cfg = cfg or LoRAConfig() | |
| modules = inject_lora(self, cfg) | |
| mark_only_lora_trainable(self) | |
| self.lora = LoRAAdapter(modules, cfg) | |
| return self.lora | |
| def remove_lora(self, merge: bool = False) -> None: | |
| if self.lora is None: | |
| return | |
| for name, wrapped in self.lora.modules(): | |
| if merge: | |
| wrapped.merge() | |
| parent_name, _, attr = name.rpartition(".") | |
| setattr(self.get_submodule(parent_name) if parent_name else self, attr, wrapped.base) | |
| self.lora = None | |
| self.freeze() | |
| def trainable_parameters(self) -> Iterator[nn.Parameter]: | |
| return (p for p in self.parameters() if p.requires_grad) | |
| def num_parameters(self, trainable_only: bool = False) -> int: | |
| seen, total = set(), 0 | |
| for p in self.parameters(): | |
| if id(p) in seen or (trainable_only and not p.requires_grad): | |
| continue | |
| seen.add(id(p)) | |
| total += p.numel() | |
| return total | |
| def gradient_checkpointing_enable(self, on: bool = True) -> None: | |
| self.model.gradient_checkpointing = on | |
| def compile_layers(self, dynamic: bool = True, mode: str | None = None) -> None: | |
| self.model.compiled_layers = [torch.compile(layer, dynamic=dynamic, mode=mode) for layer in self.model.layers] | |
| def hidden_states(self, input_ids: torch.Tensor, attention_mask: torch.Tensor | None = None, | |
| position_ids: torch.Tensor | None = None, cache: Cache | None = None) -> torch.Tensor: | |
| return self.model(input_ids, attention_mask=attention_mask, position_ids=position_ids, cache=cache) | |
| def token_logprobs(self, hidden: torch.Tensor, targets: torch.Tensor, chunk_size: int = 128, | |
| temperature: float = 1.0, logit_bias: torch.Tensor | None = None) -> torch.Tensor: | |
| weight = self.lm_head.weight | |
| out = [] | |
| for start in range(0, hidden.shape[1], chunk_size): | |
| h = hidden[:, start:start + chunk_size] | |
| t = targets[:, start:start + chunk_size] | |
| out.append(checkpoint(_chunk_logprobs, h, t, weight, temperature, logit_bias, use_reentrant=False) if torch.is_grad_enabled() | |
| else _chunk_logprobs(h, t, weight, temperature, logit_bias)) | |
| return torch.cat(out, dim=1) | |
| def forward(self, input_ids: torch.Tensor | None = None, attention_mask: torch.Tensor | None = None, | |
| position_ids: torch.Tensor | None = None, cache: Cache | None = None, | |
| inputs_embeds: torch.Tensor | None = None, labels: torch.Tensor | None = None, | |
| logits_to_keep: int = 0, return_logits: bool | None = None) -> CausalLMOutput: | |
| h = self.model(input_ids, attention_mask=attention_mask, position_ids=position_ids, cache=cache, | |
| inputs_embeds=inputs_embeds) | |
| if logits_to_keep: | |
| h = h[:, -logits_to_keep:] | |
| if return_logits is None: | |
| return_logits = labels is None | |
| loss = logits = None | |
| if labels is not None: | |
| h_s, y = h[:, :-1], labels[:, 1:] | |
| if not return_logits and _on("fused_lce", h) and type(self.lm_head) is nn.Linear: | |
| loss = _FlaFusedLCE(ignore_index=-100)(h_s.reshape(-1, h_s.shape[-1]), y.reshape(-1), | |
| self.lm_head.weight, self.lm_head.bias) | |
| else: | |
| logits = self.lm_head(h) | |
| loss = F.cross_entropy(logits[:, :-1].float().reshape(-1, logits.shape[-1]), y.reshape(-1), | |
| ignore_index=-100) | |
| if return_logits and logits is None: | |
| logits = self.lm_head(h) | |
| return CausalLMOutput(logits=logits, loss=loss, cache=cache) | |
| def generate(self, input_ids: torch.Tensor, max_new_tokens: int = 64, attention_mask: torch.Tensor | None = None, | |
| temperature: float = 0.0, top_p: float = 1.0, eos_token_id: int | None = None, | |
| stop_on_eos: bool = True, sync_every: int = 8, logit_bias: torch.Tensor | None = None) -> torch.Tensor: | |
| eos = self.cfg.eos_token_id if eos_token_id is None else eos_token_id | |
| B = input_ids.shape[0] | |
| cache = Cache(self.cfg.num_hidden_layers) | |
| position_ids = None | |
| if attention_mask is not None: | |
| m = attention_mask.bool() | |
| if bool((m[:, :-1] & ~m[:, 1:]).any()) or not bool(m[:, -1].all()): | |
| raise ValueError("generate expects left padding: each attention_mask row must be 0...01...1") | |
| position_ids = (attention_mask.long().cumsum(-1) - 1).clamp(min=0) | |
| out = self(input_ids, attention_mask=attention_mask, position_ids=position_ids, cache=cache, logits_to_keep=1) | |
| next_pos = (position_ids[:, -1] if position_ids is not None | |
| else torch.full((B,), input_ids.shape[1] - 1, device=input_ids.device)) | |
| tokens = [input_ids] | |
| done = torch.zeros(B, dtype=torch.bool, device=input_ids.device) | |
| for i in range(max_new_tokens): | |
| lg = out.logits[:, -1].float() | |
| if logit_bias is not None: | |
| lg = lg + logit_bias | |
| nxt = self._sample(lg, temperature, top_p) | |
| nxt = torch.where(done, torch.full_like(nxt, eos), nxt) | |
| tokens.append(nxt[:, None]) | |
| done |= nxt == eos | |
| if stop_on_eos and (i + 1) % sync_every == 0 and bool(done.all()): | |
| break | |
| next_pos = next_pos + 1 | |
| if attention_mask is not None: | |
| attention_mask = torch.cat((attention_mask, torch.ones(B, 1, dtype=attention_mask.dtype, | |
| device=attention_mask.device)), 1) | |
| out = self(nxt[:, None], attention_mask=attention_mask, position_ids=next_pos[:, None], cache=cache, | |
| logits_to_keep=1) | |
| return torch.cat(tokens, dim=1) | |
| def generate_graphed(self, input_ids: torch.Tensor, max_new_tokens: int = 64, attention_mask: torch.Tensor | None = None, | |
| temperature: float = 1.0, eos_token_id: int | None = None, stop_on_eos: bool = True, | |
| sync_every: int = 16, warmup_steps: int = 2, window_step: int = 512, | |
| compact_below: float = 0.75, return_logprobs: bool = False, | |
| capture_lock=None, | |
| logit_bias: torch.Tensor | None = None): | |
| eos = self.cfg.eos_token_id if eos_token_id is None else eos_token_id | |
| B, T = input_ids.shape | |
| device = input_ids.device | |
| if attention_mask is not None: | |
| m = attention_mask.bool() | |
| if bool((m[:, :-1] & ~m[:, 1:]).any()) or not bool(m[:, -1].all()): | |
| raise ValueError("generate expects left padding: each attention_mask row must be 0...01...1") | |
| position_ids = (attention_mask.long().cumsum(-1) - 1).clamp(min=0) | |
| else: | |
| position_ids = torch.arange(T, device=device)[None].expand(B, T) | |
| max_len = T + max_new_tokens | |
| cache = StaticCache(self.cfg, B, max_len, device, self.model.embed_tokens.weight.dtype) | |
| h = self.model(input_ids, attention_mask=attention_mask, position_ids=position_ids, cache=cache) | |
| logits = self.lm_head(h[:, -1]).float() | |
| if logit_bias is not None: | |
| logits = logits + logit_bias | |
| cache.window = min(max_len, -(-(T + 1) // window_step) * window_step) | |
| st = {"tok": torch.zeros(B, 1, dtype=torch.long, device=device), "pos": (position_ids[:, -1:] + 1).contiguous(), | |
| "done": torch.zeros(B, dtype=torch.bool, device=device), "rows": torch.arange(B, device=device), | |
| "lp": torch.zeros(B, dtype=torch.float32, device=device)} | |
| out = torch.full((B, max_new_tokens), eos, dtype=torch.long, device=device) | |
| out_lp = torch.zeros(B, max_new_tokens, dtype=torch.float32, device=device) | |
| inv_t = 1.0 / temperature if temperature > 0 else 1.0 | |
| def sample(lg: torch.Tensor) -> torch.Tensor: | |
| if temperature <= 0: | |
| return lg.argmax(-1) | |
| return (lg * inv_t - torch.empty_like(lg).exponential_().log()).argmax(-1) | |
| def commit(lg: torch.Tensor, nxt: torch.Tensor) -> None: | |
| nxt = torch.where(st["done"], torch.full_like(nxt, eos), nxt) | |
| scaled = lg * inv_t | |
| st["lp"].copy_(scaled.gather(1, nxt[:, None]).squeeze(1) - torch.logsumexp(scaled, dim=-1)) | |
| st["done"].logical_or_(nxt == eos) | |
| st["tok"].copy_(nxt[:, None]) | |
| commit(logits, sample(logits)) | |
| def step() -> None: | |
| hs = self.model(st["tok"], position_ids=st["pos"], cache=cache) | |
| lg = self.lm_head(hs[:, -1]).float() | |
| if logit_bias is not None: | |
| lg = lg + logit_bias | |
| commit(lg, sample(lg)) | |
| st["pos"].add_(1) | |
| def capture() -> torch.cuda.CUDAGraph: | |
| stream = torch.cuda.Stream() | |
| stream.wait_stream(torch.cuda.current_stream()) | |
| with torch.cuda.stream(stream): | |
| step() | |
| torch.cuda.current_stream().wait_stream(stream) | |
| g = torch.cuda.CUDAGraph() | |
| lock = capture_lock if capture_lock is not None else contextlib.nullcontext() | |
| with lock: | |
| torch.cuda.synchronize() | |
| with torch.cuda.graph(g, capture_error_mode="thread_local"): | |
| step() | |
| torch.cuda.synchronize() | |
| return g | |
| graph = None | |
| for i in range(max_new_tokens): | |
| out[st["rows"], i] = st["tok"][:, 0] | |
| out_lp[st["rows"], i] = st["lp"] | |
| if i == max_new_tokens - 1: | |
| break | |
| if T + i + 2 > cache.window: | |
| cache.window = min(max_len, cache.window + window_step) | |
| alive = (~st["done"]).nonzero().squeeze(1) | |
| if alive.numel() == 0 and stop_on_eos: | |
| break | |
| if alive.numel() < compact_below * st["rows"].numel(): | |
| cache.compact(alive) | |
| for key in ("tok", "pos", "done", "rows", "lp"): | |
| st[key] = st[key].index_select(0, alive).contiguous() | |
| graph = None | |
| elif stop_on_eos and (i + 1) % sync_every == 0 and bool(st["done"].all()): | |
| break | |
| if i < warmup_steps: | |
| step() | |
| elif graph is None: | |
| graph = capture() | |
| else: | |
| graph.replay() | |
| full = torch.cat((input_ids, out), dim=1) | |
| return (full, out_lp) if return_logprobs else full | |
| def _sample(logits: torch.Tensor, temperature: float, top_p: float) -> torch.Tensor: | |
| if temperature <= 0: | |
| return logits.argmax(-1) | |
| probs = torch.softmax(logits / temperature, dim=-1) | |
| if top_p < 1.0: | |
| sp, si = probs.sort(-1, descending=True) | |
| keep = (sp.cumsum(-1) - sp) < top_p | |
| sp = sp * keep | |
| probs = torch.zeros_like(probs).scatter(-1, si, sp / sp.sum(-1, keepdim=True)) | |
| return torch.multinomial(probs, 1).squeeze(-1) | |
| def from_pretrained(cls, path_or_repo: str = "Qwen/Qwen3.5-9B", cfg: Qwen3_5_9BConfig | None = None, | |
| device: str | torch.device = "cuda", dtype: torch.dtype = torch.bfloat16, | |
| lora: LoRAConfig | None = None, strict: bool = True) -> "Qwen3_5ForCausalLM": | |
| path = resolve_checkpoint(path_or_repo) | |
| cfg = cfg or Qwen3_5_9BConfig.from_json(path) | |
| with torch.device(device), _default_dtype(dtype): | |
| model = cls(cfg) | |
| load_qwen_weights(model, path, strict=strict) | |
| if lora is not None: | |
| model.add_lora(lora) | |
| return model.freeze() | |
| def _chunk_logprobs(h: torch.Tensor, t: torch.Tensor, weight: torch.Tensor, temperature: float = 1.0, | |
| logit_bias: torch.Tensor | None = None) -> torch.Tensor: | |
| logits = F.linear(h, weight).float() | |
| if temperature != 1.0: | |
| logits = logits / temperature | |
| if logit_bias is not None: | |
| logits = logits + logit_bias | |
| return logits.gather(-1, t.unsqueeze(-1)).squeeze(-1) - torch.logsumexp(logits, dim=-1) | |
| def _default_dtype(dtype: torch.dtype): | |
| prev = torch.get_default_dtype() | |
| torch.set_default_dtype(dtype) | |
| try: | |
| yield | |
| finally: | |
| torch.set_default_dtype(prev) | |
| def resolve_checkpoint(path_or_repo: str) -> str: | |
| if os.path.isdir(path_or_repo): | |
| return path_or_repo | |
| return snapshot_download(path_or_repo, allow_patterns=["*.safetensors", "*.json"]) | |
| _SKIP_PREFIXES = ("model.visual.", "mtp.") | |
| _RENAMES = (("model.language_model.", "model."),) | |
| def map_checkpoint_key(key: str) -> str | None: | |
| if key.startswith(_SKIP_PREFIXES): | |
| return None | |
| for old, new in _RENAMES: | |
| if key.startswith(old): | |
| return new + key[len(old):] | |
| return key | |
| def load_qwen_weights(model: Qwen3_5ForCausalLM, path: str, strict: bool = True) -> dict[str, list[str]]: | |
| index = os.path.join(path, "model.safetensors.index.json") | |
| if os.path.exists(index): | |
| with open(index) as fh: | |
| shards = sorted(set(json.load(fh)["weight_map"].values())) | |
| else: | |
| shards = sorted(f for f in os.listdir(path) if f.endswith(".safetensors")) | |
| if not shards: | |
| raise FileNotFoundError(f"no safetensors found under {path}") | |
| params = dict(model.named_parameters()) | |
| params.update(model.named_buffers()) | |
| loaded, unexpected = set(), [] | |
| for shard in shards: | |
| with safe_open(os.path.join(path, shard), framework="pt", device="cpu") as fh: | |
| for key in fh.keys(): | |
| name = map_checkpoint_key(key) | |
| if name is None: | |
| continue | |
| if name not in params: | |
| unexpected.append(key) | |
| continue | |
| dst = params[name] | |
| src = fh.get_tensor(key) | |
| if src.shape != dst.shape: | |
| raise ValueError(f"{key}: checkpoint {tuple(src.shape)} vs model {tuple(dst.shape)}") | |
| dst.copy_(src.to(device=dst.device, dtype=dst.dtype), non_blocking=True) | |
| loaded.add(name) | |
| if "lm_head.weight" not in loaded and "model.embed_tokens.weight" in loaded: | |
| model.lm_head.weight = model.model.embed_tokens.weight | |
| loaded.add("lm_head.weight") | |
| missing = sorted(k for k in params if k not in loaded and not k.endswith("inv_freq")) | |
| if strict and (missing or unexpected): | |
| raise RuntimeError(f"weight loading mismatch.\n missing: {missing[:8]}\n unexpected: {unexpected[:8]}") | |
| if torch.cuda.is_available(): | |
| torch.cuda.synchronize() | |
| return {"missing": missing, "unexpected": unexpected} | |
| __all__ = ["Qwen3_5ForCausalLM", "Qwen3_5Model", "Cache", "CausalLMOutput", "load_qwen_weights", | |
| "resolve_checkpoint", "set_kernels", "KERNELS", "LoRAConfig", "LoRAAdapter", "LoRALinear"] | |