Text Generation
Transformers
Safetensors
Chinese
English
yunmo_next
chat
traditional-chinese
hybrid-attention
kimi-delta-attention
linear-attention
research
custom_code
Instructions to use yuhuanstudio/Yunmo-Next-1B-Instruct with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use yuhuanstudio/Yunmo-Next-1B-Instruct with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="yuhuanstudio/Yunmo-Next-1B-Instruct", trust_remote_code=True)# pip install -U transformers accelerate # Load model directly from transformers import AutoModelForCausalLM model = AutoModelForCausalLM.from_pretrained("yuhuanstudio/Yunmo-Next-1B-Instruct", trust_remote_code=True, device_map="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use yuhuanstudio/Yunmo-Next-1B-Instruct with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "yuhuanstudio/Yunmo-Next-1B-Instruct" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "yuhuanstudio/Yunmo-Next-1B-Instruct", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker
docker model run hf.co/yuhuanstudio/Yunmo-Next-1B-Instruct
- SGLang
How to use yuhuanstudio/Yunmo-Next-1B-Instruct with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "yuhuanstudio/Yunmo-Next-1B-Instruct" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "yuhuanstudio/Yunmo-Next-1B-Instruct", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "yuhuanstudio/Yunmo-Next-1B-Instruct" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "yuhuanstudio/Yunmo-Next-1B-Instruct", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }' - Docker Model Runner
How to use yuhuanstudio/Yunmo-Next-1B-Instruct with Docker Model Runner:
docker model run hf.co/yuhuanstudio/Yunmo-Next-1B-Instruct
Download code/yunmo_next/reference_recurrent.py from yuhuanstudio/Yunmo-Next-1B-Instruct: direct link, hf CLI and curl.
- Browser
- Download file 9.8 kB
-
https://huggingface.co/yuhuanstudio/Yunmo-Next-1B-Instruct/resolve/main/code/yunmo_next/reference_recurrent.py
- Command line
-
hf download hf://yuhuanstudio/Yunmo-Next-1B-Instruct/code/yunmo_next/reference_recurrent.py
-
curl -L -o reference_recurrent.py https://huggingface.co/yuhuanstudio/Yunmo-Next-1B-Instruct/resolve/main/code/yunmo_next/reference_recurrent.py
9.8 kB
| from __future__ import annotations | |
| import math | |
| import torch | |
| import torch.nn as nn | |
| import torch.nn.functional as F | |
| def causal_depthwise_conv1d( | |
| x: torch.Tensor, | |
| weight: torch.Tensor, | |
| bias: torch.Tensor | None = None, | |
| ) -> torch.Tensor: | |
| """Torch reference for FLA's causal depthwise short convolution.""" | |
| if x.ndim != 3 or weight.ndim != 3 or weight.shape[1] != 1: | |
| raise ValueError("expected x=[B,T,D] and depthwise weight=[D,1,W]") | |
| sequence = x.shape[1] | |
| channels = x.shape[2] | |
| if weight.shape[0] != channels: | |
| raise ValueError("convolution channels do not match the hidden projection") | |
| convolved = F.conv1d( | |
| x.transpose(1, 2), | |
| weight, | |
| bias, | |
| padding=weight.shape[-1] - 1, | |
| groups=channels, | |
| ) | |
| return convolved[:, :, :sequence].transpose(1, 2) | |
| def l2_normalize_sum(x: torch.Tensor, eps: float = 1e-6) -> torch.Tensor: | |
| """Match FLA's L2 normalization (sum, not mean, over head dim).""" | |
| normalized = x.float() * torch.rsqrt(x.float().square().sum(dim=-1, keepdim=True) + eps) | |
| return normalized.to(x.dtype) | |
| def recurrent_kda_reference( | |
| q: torch.Tensor, | |
| k: torch.Tensor, | |
| v: torch.Tensor, | |
| log_decay: torch.Tensor, | |
| beta: torch.Tensor, | |
| *, | |
| scale: float | None = None, | |
| initial_state: torch.Tensor | None = None, | |
| ) -> tuple[torch.Tensor, torch.Tensor]: | |
| """Differentiable token-loop KDA oracle following the published delta rule.""" | |
| if q.ndim != 4 or k.shape != q.shape or v.ndim != 4: | |
| raise ValueError("q/k/v must be [B,T,H,D] tensors") | |
| if v.shape[:3] != q.shape[:3] or log_decay.shape != q.shape: | |
| raise ValueError("KDA q/k/v/gate dimensions must match") | |
| if beta.shape != q.shape[:3]: | |
| raise ValueError("KDA beta must be [B,T,H]") | |
| batch, sequence, heads, key_dim = q.shape | |
| value_dim = v.shape[-1] | |
| state = q.new_zeros(batch, heads, key_dim, value_dim, dtype=torch.float32) | |
| if initial_state is not None: | |
| if initial_state.shape != state.shape: | |
| raise ValueError("KDA initial state has the wrong shape") | |
| state = state + initial_state.float() | |
| attention_scale = key_dim**-0.5 if scale is None else scale | |
| qf, kf, vf = q.float(), k.float(), v.float() | |
| gf, bf = log_decay.float(), beta.float() | |
| outputs: list[torch.Tensor] = [] | |
| for token in range(sequence): | |
| key = kf[:, token] | |
| state = state * gf[:, token].exp().unsqueeze(-1) | |
| prediction = torch.einsum("bhk,bhkv->bhv", key, state) | |
| residual = vf[:, token] - prediction | |
| state = state + torch.einsum( | |
| "bhk,bhv->bhkv", bf[:, token].unsqueeze(-1) * key, residual | |
| ) | |
| outputs.append( | |
| torch.einsum("bhk,bhkv->bhv", qf[:, token] * attention_scale, state) | |
| ) | |
| return torch.stack(outputs, dim=1).to(v.dtype), state | |
| class ReferenceRMSNormGated(nn.Module): | |
| def __init__(self, hidden_size: int, eps: float) -> None: | |
| super().__init__() | |
| self.weight = nn.Parameter(torch.ones(hidden_size)) | |
| self.eps = eps | |
| def forward(self, x: torch.Tensor, gate: torch.Tensor) -> torch.Tensor: | |
| normalized = x.float() * torch.rsqrt( | |
| x.float().square().mean(dim=-1, keepdim=True) + self.eps | |
| ) | |
| return ( | |
| normalized | |
| * self.weight.float() | |
| * torch.sigmoid(gate.float()) | |
| ).to(x.dtype) | |
| class ReferenceKimiDeltaAttention(nn.Module): | |
| """Correctness-first KDA layer for CPU/MPS probes. | |
| Parameter names and shapes intentionally match FLA's | |
| ``KimiDeltaAttention`` so a CUDA checkpoint can be loaded strictly. CUDA | |
| production must continue to use FLA; this token loop is an oracle, not an | |
| efficiency backend. | |
| """ | |
| def __init__( | |
| self, | |
| *, | |
| hidden_size: int, | |
| head_dim: int, | |
| num_heads: int, | |
| expand_v: float = 1.0, | |
| use_short_conv: bool = True, | |
| conv_size: int = 4, | |
| conv_bias: bool = False, | |
| layer_idx: int | None = None, | |
| norm_eps: float = 1e-5, | |
| safe_gate: bool = False, | |
| lower_bound: float | None = None, | |
| **_: object, | |
| ) -> None: | |
| super().__init__() | |
| self.hidden_size = hidden_size | |
| self.head_dim = head_dim | |
| self.num_heads = num_heads | |
| self.head_v_dim = int(head_dim * expand_v) | |
| self.key_dim = num_heads * head_dim | |
| self.value_dim = num_heads * self.head_v_dim | |
| self.gate_dim = num_heads * head_dim | |
| self.use_short_conv = use_short_conv | |
| self.layer_idx = layer_idx | |
| self.safe_gate = safe_gate | |
| self.lower_bound = lower_bound | |
| if safe_gate and (lower_bound is None or not -5.0 <= lower_bound < 0.0): | |
| raise ValueError("safe KDA gate requires lower_bound in [-5, 0)") | |
| if self.head_v_dim != head_dim: | |
| raise ValueError("reference KDA currently requires expand_v=1") | |
| self.q_proj = nn.Linear(hidden_size, self.key_dim, bias=False) | |
| self.k_proj = nn.Linear(hidden_size, self.key_dim, bias=False) | |
| self.v_proj = nn.Linear(hidden_size, self.value_dim, bias=False) | |
| if use_short_conv: | |
| self.q_conv1d = nn.Conv1d( | |
| self.key_dim, self.key_dim, conv_size, groups=self.key_dim, bias=conv_bias | |
| ) | |
| self.k_conv1d = nn.Conv1d( | |
| self.key_dim, self.key_dim, conv_size, groups=self.key_dim, bias=conv_bias | |
| ) | |
| self.v_conv1d = nn.Conv1d( | |
| self.value_dim, | |
| self.value_dim, | |
| conv_size, | |
| groups=self.value_dim, | |
| bias=conv_bias, | |
| ) | |
| self.f_proj = nn.Sequential( | |
| nn.Linear(hidden_size, self.head_v_dim, bias=False), | |
| nn.Linear(self.head_v_dim, self.gate_dim, bias=False), | |
| ) | |
| self.b_proj = nn.Linear(hidden_size, num_heads, bias=False) | |
| self.A_log = nn.Parameter( | |
| torch.zeros(num_heads) | |
| if safe_gate | |
| else torch.log(torch.empty(num_heads).uniform_(1, 16)) | |
| ) | |
| self.A_log._no_weight_decay = True # type: ignore[attr-defined] | |
| dt = torch.exp( | |
| torch.rand(self.gate_dim) * (math.log(0.1) - math.log(0.001)) | |
| + math.log(0.001) | |
| ).clamp(min=1e-4) | |
| self.dt_bias = nn.Parameter(dt + torch.log(-torch.expm1(-dt))) | |
| self.dt_bias._no_weight_decay = True # type: ignore[attr-defined] | |
| self.g_proj = nn.Sequential( | |
| nn.Linear(hidden_size, self.head_v_dim, bias=False), | |
| nn.Linear(self.head_v_dim, self.value_dim, bias=True), | |
| ) | |
| self.o_norm = ReferenceRMSNormGated(self.head_v_dim, norm_eps) | |
| self.o_proj = nn.Linear(self.value_dim, hidden_size, bias=False) | |
| def _project(self, projection: nn.Linear, convolution: nn.Conv1d, x: torch.Tensor) -> torch.Tensor: | |
| return F.silu(causal_depthwise_conv1d(projection(x), convolution.weight, convolution.bias)) | |
| def forward( | |
| self, | |
| hidden_states: torch.Tensor, | |
| attention_mask: torch.Tensor | None = None, | |
| past_key_values: object | None = None, | |
| use_cache: bool = False, | |
| output_attentions: bool = False, | |
| cu_seqlens: torch.Tensor | None = None, | |
| **_: object, | |
| ) -> tuple[torch.Tensor, None, None]: | |
| if attention_mask is not None or past_key_values is not None or use_cache: | |
| raise NotImplementedError("reference KDA currently supports training without cache/padding") | |
| if output_attentions: | |
| raise NotImplementedError("KDA does not materialize attention weights") | |
| if cu_seqlens is not None: | |
| if hidden_states.shape[0] != 1: | |
| raise ValueError("packed reference KDA requires batch size one") | |
| boundaries = [int(value) for value in cu_seqlens.detach().cpu().tolist()] | |
| pieces = [ | |
| self.forward(hidden_states[:, start:end])[0] | |
| for start, end in zip(boundaries[:-1], boundaries[1:], strict=True) | |
| if end > start | |
| ] | |
| return torch.cat(pieces, dim=1), None, None | |
| if self.use_short_conv: | |
| q = self._project(self.q_proj, self.q_conv1d, hidden_states) | |
| k = self._project(self.k_proj, self.k_conv1d, hidden_states) | |
| v = self._project(self.v_proj, self.v_conv1d, hidden_states) | |
| else: | |
| q, k, v = ( | |
| F.silu(projection(hidden_states)) | |
| for projection in (self.q_proj, self.k_proj, self.v_proj) | |
| ) | |
| batch, sequence, _ = hidden_states.shape | |
| shape = (batch, sequence, self.num_heads, self.head_dim) | |
| q = l2_normalize_sum(q.view(shape)) | |
| k = l2_normalize_sum(k.view(shape)) | |
| v = v.view(batch, sequence, self.num_heads, self.head_v_dim) | |
| raw_gate = self.f_proj(hidden_states).view(shape) | |
| gate_input = raw_gate.float() + self.dt_bias.float().view( | |
| 1, 1, self.num_heads, self.head_dim | |
| ) | |
| if self.safe_gate: | |
| log_decay = self.lower_bound * torch.sigmoid( | |
| self.A_log.float().exp().view(1, 1, self.num_heads, 1) | |
| * gate_input | |
| ) | |
| else: | |
| log_decay = -self.A_log.float().exp().view( | |
| 1, 1, self.num_heads, 1 | |
| ) * F.softplus(gate_input) | |
| beta = torch.sigmoid(self.b_proj(hidden_states)) | |
| output, _ = recurrent_kda_reference(q, k, v, log_decay, beta) | |
| gate = self.g_proj(hidden_states).view( | |
| batch, sequence, self.num_heads, self.head_v_dim | |
| ) | |
| output = self.o_norm(output, gate).reshape(batch, sequence, self.value_dim) | |
| return self.o_proj(output), None, None | |