Text Generation
Transformers
Safetensors
Upper Grand Valley Dani
evo1
DNA
language-model
StripedHyena
Evo
long-context
custom_code
Instructions to use Taykhoom/Evo1-1-7B-131K with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use Taykhoom/Evo1-1-7B-131K with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="Taykhoom/Evo1-1-7B-131K", trust_remote_code=True)# Load model directly from transformers import AutoModelForCausalLM model = AutoModelForCausalLM.from_pretrained("Taykhoom/Evo1-1-7B-131K", trust_remote_code=True, dtype="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use Taykhoom/Evo1-1-7B-131K with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "Taykhoom/Evo1-1-7B-131K" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Taykhoom/Evo1-1-7B-131K", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker
docker model run hf.co/Taykhoom/Evo1-1-7B-131K
- SGLang
How to use Taykhoom/Evo1-1-7B-131K 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 "Taykhoom/Evo1-1-7B-131K" \ --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": "Taykhoom/Evo1-1-7B-131K", "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 "Taykhoom/Evo1-1-7B-131K" \ --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": "Taykhoom/Evo1-1-7B-131K", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }' - Docker Model Runner
How to use Taykhoom/Evo1-1-7B-131K with Docker Model Runner:
docker model run hf.co/Taykhoom/Evo1-1-7B-131K
File size: 12,614 Bytes
9e26fe9 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 | # Copyright (c) Together / Apache 2.0.
#
# Minimal multi-head attention block for the Evo1 HF port.
#
# Replaces flash_attn.modules.mha.MHA with a small, dependency-light
# implementation that:
# - keeps the same parameter names (Wqkv, out_proj, rotary_emb.inv_freq)
# so existing checkpoints load directly,
# - supports attn_implementation in {"eager", "sdpa", "flash_attention_2"},
# - returns attention weights when output_attentions=True (eager path),
# - falls back to eager when output_attentions=True for sdpa/flash backends
# (per the standard HuggingFace dispatch convention),
# - keeps a one-method KV cache compatible with the existing
# InferenceParams dataclass for autoregressive generation.
#
# Math is causal, single-stream (no cross-attention), no ALiBi, no sliding
# window. Evo1 only ever exercised the qkv-packed self-attention path.
from __future__ import annotations
import math
import torch
import torch.nn as nn
import torch.nn.functional as F
from .rotary import RotaryEmbedding
def _flash_attn_required():
try:
from flash_attn import flash_attn_func, flash_attn_varlen_func # noqa: F401
from flash_attn.bert_padding import pad_input, unpad_input # noqa: F401
except ImportError as exc: # pragma: no cover - optional dep
raise ImportError(
"attn_implementation='flash_attention_2' requires the flash-attn "
"package. Install with `pip install flash-attn --no-build-isolation`."
) from exc
def _update_kv_cache(kv: torch.Tensor, inference_params, layer_idx: int) -> torch.Tensor:
"""Append `kv` to inference_params.key_value_memory_dict[layer_idx].
kv: (B, S, 2, H_kv, D) where S is the new-token chunk length (may be 1).
Returns the cumulative kv up to the current sequence position.
"""
num_heads, head_dim = kv.shape[-2:]
if layer_idx not in inference_params.key_value_memory_dict:
kv_cache = torch.empty(
inference_params.max_batch_size,
inference_params.max_seqlen,
2,
num_heads,
head_dim,
dtype=kv.dtype,
device=kv.device,
)
inference_params.key_value_memory_dict[layer_idx] = kv_cache
else:
kv_cache = inference_params.key_value_memory_dict[layer_idx]
batch_start = inference_params.batch_size_offset
batch_end = batch_start + kv.shape[0]
sequence_start = inference_params.seqlen_offset
sequence_end = sequence_start + kv.shape[1]
kv_cache[batch_start:batch_end, sequence_start:sequence_end, ...] = kv
return kv_cache[batch_start:batch_end, :sequence_end, ...]
class MHA(nn.Module):
"""Multi-head self-attention with backend-dispatch.
Constructor signature is a strict subset of flash_attn.modules.mha.MHA so
that the existing AttentionBlock instantiation site is left untouched.
Unsupported kwargs (cross_attn, dwconv, alibi, window_size, ...) are
accepted and ignored or hard-asserted: Evo1 never exercises them.
"""
def __init__(
self,
embed_dim: int,
num_heads: int,
num_heads_kv: int | None = None,
cross_attn: bool = False,
qkv_proj_bias: bool = True,
out_proj_bias: bool = True,
dropout: float = 0.0,
softmax_scale: float | None = None,
causal: bool = False,
layer_idx: int | None = None,
rotary_emb_dim: int = 0,
rotary_emb_base: float = 10000.0,
rotary_emb_scale_base: float | None = None,
rotary_emb_interleaved: bool = False,
use_flash_attn: bool = False, # legacy kwarg, kept for ctor compatibility
attn_implementation: str = "eager",
device=None,
dtype=None,
) -> None:
super().__init__()
if cross_attn:
raise NotImplementedError("Cross-attention is not supported in this minimal MHA.")
factory_kwargs = {"device": device, "dtype": dtype}
self.embed_dim = embed_dim
self.num_heads = num_heads
self.num_heads_kv = num_heads_kv if num_heads_kv is not None else num_heads
if self.embed_dim % num_heads != 0:
raise ValueError("embed_dim must be divisible by num_heads")
if self.num_heads % self.num_heads_kv != 0:
raise ValueError("num_heads must be divisible by num_heads_kv")
self.head_dim = self.embed_dim // num_heads
self.causal = causal
self.softmax_scale = softmax_scale
self.layer_idx = layer_idx
self.rotary_emb_dim = rotary_emb_dim
self.attn_implementation = attn_implementation
self.dropout_p = dropout
if self.rotary_emb_dim > 0:
self.rotary_emb = RotaryEmbedding(
self.rotary_emb_dim,
base=rotary_emb_base,
interleaved=rotary_emb_interleaved,
scale_base=rotary_emb_scale_base,
device=device,
)
qkv_dim = self.head_dim * (self.num_heads + 2 * self.num_heads_kv)
self.Wqkv = nn.Linear(embed_dim, qkv_dim, bias=qkv_proj_bias, **factory_kwargs)
self.out_proj = nn.Linear(embed_dim, embed_dim, bias=out_proj_bias, **factory_kwargs)
def allocate_inference_cache(self, batch_size, max_seqlen, dtype=None):
dtype = self.out_proj.weight.dtype if dtype is None else dtype
device = self.out_proj.weight.device
return torch.empty(
batch_size, max_seqlen, 2, self.num_heads_kv, self.head_dim,
dtype=dtype, device=device,
)
def _project_qkv(self, x: torch.Tensor) -> torch.Tensor:
"""Compute Wqkv(x) and reshape to (B, T, 3, H, D) when MHA, or
return (q, kv) tuple-like layout when GQA. Returns the packed qkv
tensor in either case (kv heads broadcast for SDPA/flash later).
For Evo1 we have num_heads_kv == num_heads (proj_groups=1), so the
common-case packed layout is fine; we keep a GQA branch for future
flexibility but assert MHA at construction time.
"""
qkv = self.Wqkv(x)
if self.num_heads_kv == self.num_heads:
return qkv.view(*qkv.shape[:-1], 3, self.num_heads, self.head_dim)
# GQA path (unused by Evo1):
q = qkv[..., : self.num_heads * self.head_dim]
kv = qkv[..., self.num_heads * self.head_dim:]
q = q.view(*q.shape[:-1], self.num_heads, self.head_dim)
kv = kv.view(*kv.shape[:-1], 2, self.num_heads_kv, self.head_dim)
return q, kv # type: ignore[return-value]
# ------------------------------------------------------------------ eager
def _forward_eager(
self,
qkv: torch.Tensor,
output_attentions: bool,
) -> tuple[torch.Tensor, torch.Tensor | None]:
# qkv: (B, T, 3, H, D). Match flash_attn / sdpa numerical behaviour by
# doing the attention math in fp32 internally (q*scale, QK^T matmul,
# softmax, attn @ V). Without this, the bf16 matmuls accumulate
# ~1e-2 absolute error per attention block and diverge meaningfully
# from flash_attn (which always accumulates in fp32 inside its CUDA
# kernel). Output is cast back to the original dtype for the residual
# add.
orig_dtype = qkv.dtype
q, k, v = qkv.unbind(dim=2)
q = q.permute(0, 2, 1, 3).float() # (B, H, T, D), fp32
k = k.permute(0, 2, 1, 3).float()
v = v.permute(0, 2, 1, 3).float()
scale = self.softmax_scale if self.softmax_scale is not None else 1.0 / math.sqrt(self.head_dim)
scores = torch.matmul(q, k.transpose(-2, -1)) * scale
if self.causal:
T = q.shape[-2]
mask = torch.triu(
torch.ones(T, T, device=scores.device, dtype=torch.bool), diagonal=1
)
scores = scores.masked_fill(mask, float("-inf"))
attn = F.softmax(scores, dim=-1)
if self.training and self.dropout_p > 0:
attn = F.dropout(attn, p=self.dropout_p)
out = torch.matmul(attn, v).permute(0, 2, 1, 3) # (B, T, H, D), fp32
out = out.to(orig_dtype)
return out, (attn.to(orig_dtype) if output_attentions else None)
# -------------------------------------------------------------------- sdpa
def _forward_sdpa(self, qkv: torch.Tensor) -> torch.Tensor:
q, k, v = qkv.unbind(dim=2)
q = q.permute(0, 2, 1, 3) # (B, H, T, D)
k = k.permute(0, 2, 1, 3)
v = v.permute(0, 2, 1, 3)
scale = self.softmax_scale if self.softmax_scale is not None else None
out = F.scaled_dot_product_attention(
q, k, v,
attn_mask=None,
dropout_p=self.dropout_p if self.training else 0.0,
is_causal=self.causal,
scale=scale,
)
return out.permute(0, 2, 1, 3) # (B, T, H, D)
# -------------------------------------------------------- flash_attention_2
def _forward_flash(self, qkv: torch.Tensor) -> torch.Tensor:
_flash_attn_required()
from flash_attn import flash_attn_qkvpacked_func
# flash_attn expects (B, T, 3, H, D) in fp16/bf16 already; Evo1 attn
# blocks already cast to bf16 in __init__.
out = flash_attn_qkvpacked_func(
qkv,
dropout_p=self.dropout_p if self.training else 0.0,
softmax_scale=self.softmax_scale,
causal=self.causal,
)
return out # (B, T, H, D)
# ----------------------------------------------------------- KV-cache path
def _forward_with_cache(
self,
qkv: torch.Tensor,
inference_params,
) -> torch.Tensor:
# qkv: (B, T, 3, H, D). Apply rotary at the current offset, append kv
# to cache, attend over the cumulative kv. For correctness we use SDPA
# which has stable behaviour at all sequence lengths.
if self.rotary_emb_dim > 0:
qkv = self.rotary_emb(
qkv,
seqlen_offset=inference_params.seqlen_offset,
max_seqlen=inference_params.max_seqlen,
)
q, k, v = qkv.unbind(dim=2)
kv = torch.stack((k, v), dim=2) # (B, T, 2, H, D)
kv = _update_kv_cache(kv, inference_params, self.layer_idx)
k_full, v_full = kv.unbind(dim=2) # (B, S_total, H, D)
q = q.permute(0, 2, 1, 3)
k_full = k_full.permute(0, 2, 1, 3)
v_full = v_full.permute(0, 2, 1, 3)
scale = self.softmax_scale if self.softmax_scale is not None else None
is_causal = self.causal and q.shape[-2] == k_full.shape[-2]
out = F.scaled_dot_product_attention(
q, k_full, v_full, is_causal=is_causal, scale=scale,
)
return out.permute(0, 2, 1, 3) # (B, T, H, D)
# ---------------------------------------------------------------- forward
def forward(
self,
x: torch.Tensor,
inference_params=None,
output_attentions: bool = False,
**_unused,
) -> tuple[torch.Tensor, torch.Tensor | None]:
"""Returns (out, attn_weights_or_None) where out is (B, T, embed_dim)."""
if self.num_heads_kv != self.num_heads:
raise NotImplementedError("GQA is not exercised by Evo1; please file an issue if needed.")
qkv = self._project_qkv(x) # (B, T, 3, H, D)
if inference_params is not None:
out_btd = self._forward_with_cache(qkv, inference_params)
attn_weights = None
else:
if self.rotary_emb_dim > 0:
qkv = self.rotary_emb(qkv, seqlen_offset=0, max_seqlen=qkv.shape[1])
backend = self.attn_implementation
if output_attentions and backend != "eager":
# Standard HF behaviour: silently fall back to eager so we can
# actually compute and return the attention matrix.
backend = "eager"
if backend == "eager":
out_btd, attn_weights = self._forward_eager(qkv, output_attentions=output_attentions)
elif backend == "sdpa":
out_btd = self._forward_sdpa(qkv)
attn_weights = None
elif backend == "flash_attention_2":
out_btd = self._forward_flash(qkv)
attn_weights = None
else:
raise ValueError(f"Unknown attn_implementation: {backend!r}")
# (B, T, H, D) -> (B, T, embed_dim)
B, T, H, D = out_btd.shape
out_flat = out_btd.reshape(B, T, H * D)
return self.out_proj(out_flat), attn_weights
|