Taykhoom commited on
Commit
0eca2aa
·
0 Parent(s):

Initial release

Browse files
.gitattributes ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip filter=lfs diff=lfs merge=lfs -text
34
+ *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,234 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ language:
3
+ - dna
4
+ library_name: transformers
5
+ tags:
6
+ - DNA
7
+ - language-model
8
+ - StripedHyena
9
+ - Evo
10
+ - Evo1.5
11
+ license: apache-2.0
12
+ ---
13
+
14
+ # Evo1-1.5-7B-8K
15
+
16
+ A clean, minimal HuggingFace port of [Evo 1.5 (8k)](https://huggingface.co/evo-design/evo-1.5-8k-base), which extends Evo 1 (8k) by approximately 50% additional pretraining tokens. ~7B parameters. Native support for layer-by-layer hidden state extraction, attention-weight extraction, and a runtime-switchable attention backend.
17
+
18
+ ## Why this port?
19
+
20
+ [evo-design/evo-1.5-8k-base](https://huggingface.co/evo-design/evo-1.5-8k-base) ships a `trust_remote_code` HF implementation but it has four gaps that force every downstream user to monkey-patch the model:
21
+
22
+ 1. `output_hidden_states=True` is hardcoded to `None` (intermediate embeddings require forward hooks).
23
+ 2. `output_attentions=True` is unsupported (flash-attn discards the `(B, H, T, T)` matrix; users must patch the attention module).
24
+ 3. `attn_implementation` cannot be switched at load time - flash_attn is mandatory at every attention layer.
25
+ 4. The bare backbone is not exposed via `AutoModel.from_pretrained`; only the LM-head wrapper exists.
26
+
27
+ This repo fixes all four. The math is **bit-exact** with the evo-design reference (`max_abs_diff = 0.000e+00` at every layer; see [Parity Verification](#parity-verification)).
28
+
29
+ ## Architecture
30
+
31
+ | Parameter | Value |
32
+ |---|---|
33
+ | Total parameters | ~7B |
34
+ | Layers | 32 |
35
+ | Attention heads | 32 |
36
+ | Embedding dimension | 4096 |
37
+ | Inner MLP size | 10928 |
38
+ | Vocabulary size | 512 (UTF-8 byte-level) |
39
+ | Attention layer indices | [8, 16, 24] |
40
+ | Hyena layer indices | all others |
41
+ | Hyena state size | 8 |
42
+ | Positional encoding | RoPE (base = 10000) |
43
+ | Architecture | StripedHyena (alternating Hyena / MHA blocks) |
44
+ | Max sequence length | 8 192 |
45
+ | Training dtype | bfloat16 (Hyena modal-form `poles` / `residues` kept in fp32) |
46
+
47
+ Architecturally identical to `Evo1-1-7B-8K`; only the trained weights differ (Evo 1.5 = Evo 1 (8k) + ~50% more pretraining tokens).
48
+
49
+ ## Pretraining
50
+
51
+ - **Objective:** causal byte-level next-token prediction.
52
+ - **Data:** [OpenGenome](https://huggingface.co/datasets/LongSafari/open-genome), the prokaryotic whole-genome dataset assembled for Evo 1 (~80 000 prokaryotic genomes plus ~2 million phage and plasmid sequences), with training extended by an additional 50% - totaling **~450 billion tokens** (vs. ~300 B for Evo 1).
53
+ - **Initialization:** continued pretraining from `evo-1-8k-base` at 8 192-token context (i.e. Evo 1.5 is not trained from scratch; the additional ~150 B tokens are appended to Evo 1's 300 B-token training run).
54
+ - **Source checkpoint:** `evo-design/evo-1.5-8k-base@main`.
55
+
56
+ ### Downstream use
57
+
58
+ Evo 1.5 is the model used in [Merchant et al., 2025 (Nature)](https://doi.org/10.1038/s41586-025-09749-7) for *semantic mining* of functional de novo genes - generating new candidate genes conditioned on genomic context. It was used to produce [SynGenome](https://evodesign.org/syngenome/), the first large-scale AI-generated genomic database (over 120 B base pairs of synthetic DNA, organised by predicted function, protein domain, and host species).
59
+
60
+ ## Parity Verification
61
+
62
+ Hidden-state representations verified **bit-exact** (`max_abs_diff = 0.000e+00`) to the evo-design reference at all 33 representation levels (token embedding + each of the 32 transformer blocks + final RMSNorm), using `attn_implementation="flash_attention_2"` in bf16 (matches the reference's backend choice and the trained dtype). Logits from `Evo1ForCausalLM` were also verified bit-exact (top-1 agreement: 128/128 positions). Verified on H100 with PyTorch 2.7.1 / CUDA 12.9.
63
+
64
+ ### Numerical equivalence across attention backends
65
+
66
+ `flash_attention_2` is bit-exact with the original togethercomputer / evo-design implementations (same CUDA kernel). The `sdpa` and `eager` backends use different kernels (PyTorch's bundled flash kernel and pure-PyTorch matmul, respectively); these compute mathematically equivalent attention but accumulate floating-point operations in slightly different orders, producing per-block diffs at the bf16 noise floor (relative error roughly `1e-4` to `1e-2`).
67
+
68
+ Unlike a standard transformer, where attention is softmax-bounded and per-block diffs stay small through the stack, StripedHyena's Hyena layers use an unbounded-gain IIR filter (no softmax) - so any small per-attention-block diff gets amplified by Hyena's filter gain. Across 32 layers this compounds to ~1% relative error in the intermediate residual stream, though the final post-RMSNorm output is bounded. Use `flash_attention_2` if you need to match the reference's activations bit-for-bit.
69
+
70
+ ## Related Models
71
+
72
+ See the full [Evo1 collection](https://huggingface.co/collections/Taykhoom/evo1-6a24ae4a98f04906482db8c2) on the Hub.
73
+
74
+ | Model | Context | Notes |
75
+ |---|---|---|
76
+ | [Taykhoom/Evo1-1-7B-8K](https://huggingface.co/Taykhoom/Evo1-1-7B-8K) | 8 192 | Original Evo 1 base model (8k context). |
77
+ | [Taykhoom/Evo1-1-7B-131K](https://huggingface.co/Taykhoom/Evo1-1-7B-131K) | 131 072 | Long-context Evo 1 with linearly-scaled RoPE (131k context). |
78
+ | **[Taykhoom/Evo1-1.5-7B-8K](https://huggingface.co/Taykhoom/Evo1-1.5-7B-8K)** | 8 192 | Evo 1.5: Evo 1 (8k) further trained on ~50% more pretraining tokens. |
79
+
80
+ ## Usage
81
+
82
+ > **Note on dtype.** Evo1 was trained in **bfloat16**, with the Hyena `poles` / `residues` (modal-form filter parameters) kept in fp32 for numerical stability. **Passing `dtype=...` to `from_pretrained` only affects the initial load precision** (peak memory during loading) **and does not change the inference dtype** - `Evo1Model.__init__` and `Evo1ForCausalLM.__init__` unconditionally call `to_bfloat16_except_poles_residues()`, so the model always runs in bf16 with poles/residues in fp32. This is intentional: the trained activations are bf16-stable and fp16-unstable, and the modal-form filter requires fp32 for numerical stability - a single mixed config is the only valid one.
83
+
84
+ > **Note on attention backend.** By default, `from_pretrained` selects `attn_implementation="sdpa"` (PyTorch's bundled scaled-dot-product-attention) - this works out of the box without `flash_attn` installed. The original togethercomputer / evo-design implementations use `flash_attn` unconditionally; **for bit-exact reproduction of reference outputs, explicitly pass `attn_implementation="flash_attention_2"`** (and `pip install flash-attn`). See [Numerical equivalence across attention backends](#numerical-equivalence-across-attention-backends) for the magnitude of the difference.
85
+
86
+ ### Embedding generation (no LM head)
87
+
88
+ ```python
89
+ import torch
90
+ from transformers import AutoTokenizer, AutoModel
91
+
92
+ tokenizer = AutoTokenizer.from_pretrained("Taykhoom/Evo1-1.5-7B-8K", trust_remote_code=True)
93
+ model = AutoModel.from_pretrained(
94
+ "Taykhoom/Evo1-1.5-7B-8K",
95
+ trust_remote_code=True,
96
+ attn_implementation="flash_attention_2", # bit-exact with reference; or omit to default to "sdpa"
97
+ ).cuda().eval()
98
+
99
+ seqs = ["ACGTACGTACGT", "GGGTTTAAACCC"]
100
+ inputs = tokenizer(seqs, return_tensors="pt", padding=True).to(model.device)
101
+
102
+ with torch.no_grad():
103
+ out = model(**inputs, output_hidden_states=True)
104
+
105
+ last_hidden = out.last_hidden_state # (B, T, 4096)
106
+ all_layers = out.hidden_states # tuple of (B, T, 4096), len = 34 (embed + 32 blocks + post-norm)
107
+ layer_12_emb = all_layers[12] # often used as a "middle" representation
108
+ ```
109
+
110
+ ### LM logits
111
+
112
+ ```python
113
+ import torch
114
+ from transformers import AutoTokenizer, AutoModelForCausalLM
115
+
116
+ tokenizer = AutoTokenizer.from_pretrained("Taykhoom/Evo1-1.5-7B-8K", trust_remote_code=True)
117
+ model = AutoModelForCausalLM.from_pretrained(
118
+ "Taykhoom/Evo1-1.5-7B-8K",
119
+ trust_remote_code=True,
120
+ attn_implementation="flash_attention_2",
121
+ ).cuda().eval()
122
+
123
+ inputs = tokenizer(["ACGT"], return_tensors="pt").to(model.device)
124
+ with torch.no_grad():
125
+ logits = model(**inputs).logits # (1, T, 512)
126
+ ```
127
+
128
+ ### Generation
129
+
130
+ ```python
131
+ import torch
132
+ from transformers import AutoTokenizer, AutoModelForCausalLM
133
+
134
+ tokenizer = AutoTokenizer.from_pretrained("Taykhoom/Evo1-1.5-7B-8K", trust_remote_code=True)
135
+ model = AutoModelForCausalLM.from_pretrained(
136
+ "Taykhoom/Evo1-1.5-7B-8K",
137
+ trust_remote_code=True,
138
+ attn_implementation="flash_attention_2",
139
+ ).cuda().eval()
140
+
141
+ inputs = tokenizer(["ACGT"], return_tensors="pt").to(model.device)
142
+ out = model.generate(**inputs, max_new_tokens=128, do_sample=True, top_k=4, temperature=1.0)
143
+ print(tokenizer.decode(out[0]))
144
+ ```
145
+
146
+ `generation_config.json` ships with `eos_token_id = 0` (the EOD byte) and `pad_token_id = 1` so `model.generate()` stops naturally at the trained end-of-document token without needing extra kwargs. Note that the tokenizer itself does **not** add an EOS at encoding time - this matches the original Evo1 inference pipeline (only generation stops on EOS; embedding/scoring uses raw byte input).
147
+
148
+ ### Attention weights
149
+
150
+ ```python
151
+ import torch
152
+ from transformers import AutoTokenizer, AutoModel
153
+
154
+ tokenizer = AutoTokenizer.from_pretrained("Taykhoom/Evo1-1.5-7B-8K", trust_remote_code=True)
155
+ model = AutoModel.from_pretrained(
156
+ "Taykhoom/Evo1-1.5-7B-8K",
157
+ trust_remote_code=True,
158
+ attn_implementation="eager", # required for output_attentions to populate
159
+ ).cuda().eval()
160
+
161
+ inputs = tokenizer(["ACGTACGT"], return_tensors="pt").to(model.device)
162
+ with torch.no_grad():
163
+ out = model(**inputs, output_attentions=True)
164
+
165
+ # out.attentions is a tuple of length 32. Entries at indices not in [8, 16, 24]
166
+ # are None (Hyena blocks have no attention matrix). Entries at [8, 16, 24] are
167
+ # (B, num_heads, T, T) tensors.
168
+ attn_block_8 = out.attentions[8]
169
+ ```
170
+
171
+ ### Multi-GPU loading (optional)
172
+
173
+ Loading via `accelerate`'s `device_map` is supported (`_no_split_modules` is set so each `AttentionBlock` / `ParallelGatedConvBlock` stays atomic on one device, with hidden state automatically transferred across device boundaries):
174
+
175
+ ```python
176
+ import torch
177
+ from transformers import AutoTokenizer, AutoModel
178
+
179
+ tokenizer = AutoTokenizer.from_pretrained("Taykhoom/Evo1-1.5-7B-8K", trust_remote_code=True)
180
+ model = AutoModel.from_pretrained(
181
+ "Taykhoom/Evo1-1.5-7B-8K",
182
+ trust_remote_code=True,
183
+ attn_implementation="flash_attention_2",
184
+ device_map="auto", # auto-shard across all visible GPUs; falls back to single GPU if only one is present
185
+ ).eval()
186
+ ```
187
+
188
+ Requires `pip install accelerate`.
189
+
190
+ ### Fine-tuning
191
+
192
+ Standard HuggingFace conventions. For sequence-level tasks, take the final `last_hidden_state` (or any intermediate `hidden_states[i]`) and feed it into a downstream head.
193
+
194
+ ## Implementation Notes
195
+
196
+ - **Custom attention module (`attention.py`).** Replaces `flash_attn.modules.mha.MHA` with a small in-repo `MHA` class that supports `attn_implementation="eager"` / `"sdpa"` / `"flash_attention_2"`. Parameter names (`Wqkv`, `out_proj`, `rotary_emb.inv_freq`) are preserved so existing checkpoints load unchanged. When `output_attentions=True`, the sdpa and flash paths automatically fall back to eager so the attention matrix is materialized.
197
+ - **Custom rotary embedding (`rotary.py`).** When `flash_attn` is installed we delegate to its Triton kernel (faster on long sequences). The pure-PyTorch fallback does the rotary multiply in fp32 internally (then casts back) so it produces bit-exactly identical results to the Triton kernel - a bf16 multiply here introduces ~3e-2 error per layer that compounds to ~1% relative across 32 layers.
198
+ - **Hyena engine (`engine.py`).** Copied verbatim from the togethercomputer reference (FFT-based long convolution, modal-form prefill).
199
+ - **Cache subclass (`cache.py`).** `Evo1Cache(transformers.cache_utils.Cache)` wraps the two block-type-specific inference param dataclasses (`InferenceParams` for attention KV cache, `RecurrentInferenceParams` for Hyena FIR window + IIR modal state). Exposes `get_seq_length()` / `get_max_cache_shape()` so HF's `model.generate()` can introspect cache state; falls through to `cache["mha"]` / `cache["hyena"]` for the model internals.
200
+ - **Tokenizer (`tokenization_evo1.py`).** Byte-level UTF-8 with vocab_size = 512. Pad token is byte `\x01`. No CLS, no EOS appended at encoding time (matches original Evo1 inference). The `_decode` method is numpy-2.x compatible (the original `np.uint8.clip(min=32, max=512)` was an overflow on numpy 2).
201
+ - **Dependencies.** `torch`, `transformers`, `numpy`, `safetensors`, `huggingface_hub` (only for `from_pretrained` downloads). `flash_attn` is **only** required if you pass `attn_implementation="flash_attention_2"`.
202
+
203
+ ## Citation
204
+
205
+ ```bibtex
206
+ @article{merchant2025_evo_1_5,
207
+ title = {Semantic design of functional de novo genes from a genomic language model},
208
+ author = {Merchant, Aditi T. and King, Samuel H. and Nguyen, Eric and Hie, Brian L.},
209
+ journal = {Nature},
210
+ year = {2025},
211
+ doi = {10.1038/s41586-025-09749-7}
212
+ }
213
+
214
+ @article{nguyen2024_evo,
215
+ title = {Sequence modeling and design from molecular to genome scale with {Evo}},
216
+ author = {Nguyen, Eric and Poli, Michael and Durrant, Matthew G. and Kang, Brian and Katrekar, Dhruva and Li, David B. and Bartie, Liam J. and Thomas, Armin W. and King, Samuel H. and Brixi, Garyk and Sullivan, Jeremy and Ng, Madelena Y. and Lewis, Ashley and Lou, Aaron and Ermon, Stefano and Baccus, Stephen A. and Hernandez-Boussard, Tina and {R{\'e}}, Christopher and Hsu, Patrick D. and Hie, Brian L.},
217
+ journal = {Science},
218
+ volume = {386},
219
+ number = {6723},
220
+ pages = {eado9336},
221
+ year = {2024},
222
+ doi = {10.1126/science.ado9336}
223
+ }
224
+ ```
225
+
226
+ ## Credits
227
+
228
+ Original Evo / Evo 1.5 model and code by Nguyen et al. and Merchant et al. Source repo: [evo-design/evo](https://github.com/evo-design/evo). Source checkpoint: [evo-design/evo-1.5-8k-base](https://huggingface.co/evo-design/evo-1.5-8k-base).
229
+
230
+ The HuggingFace conversion code in this repo was authored primarily by [Claude](https://claude.ai/code) and reviewed manually by Taykhoom Dalal.
231
+
232
+ ## License
233
+
234
+ Apache 2.0, following the original Evo1 release.
attention.py ADDED
@@ -0,0 +1,294 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (c) Together / Apache 2.0.
2
+ #
3
+ # Minimal multi-head attention block for the Evo1 HF port.
4
+ #
5
+ # Replaces flash_attn.modules.mha.MHA with a small, dependency-light
6
+ # implementation that:
7
+ # - keeps the same parameter names (Wqkv, out_proj, rotary_emb.inv_freq)
8
+ # so existing checkpoints load directly,
9
+ # - supports attn_implementation in {"eager", "sdpa", "flash_attention_2"},
10
+ # - returns attention weights when output_attentions=True (eager path),
11
+ # - falls back to eager when output_attentions=True for sdpa/flash backends
12
+ # (per the standard HuggingFace dispatch convention),
13
+ # - keeps a one-method KV cache compatible with the existing
14
+ # InferenceParams dataclass for autoregressive generation.
15
+ #
16
+ # Math is causal, single-stream (no cross-attention), no ALiBi, no sliding
17
+ # window. Evo1 only ever exercised the qkv-packed self-attention path.
18
+
19
+ from __future__ import annotations
20
+
21
+ import math
22
+
23
+ import torch
24
+ import torch.nn as nn
25
+ import torch.nn.functional as F
26
+
27
+ from .rotary import RotaryEmbedding
28
+
29
+
30
+ def _flash_attn_required():
31
+ try:
32
+ from flash_attn import flash_attn_func, flash_attn_varlen_func # noqa: F401
33
+ from flash_attn.bert_padding import pad_input, unpad_input # noqa: F401
34
+ except ImportError as exc: # pragma: no cover - optional dep
35
+ raise ImportError(
36
+ "attn_implementation='flash_attention_2' requires the flash-attn "
37
+ "package. Install with `pip install flash-attn --no-build-isolation`."
38
+ ) from exc
39
+
40
+
41
+ def _update_kv_cache(kv: torch.Tensor, inference_params, layer_idx: int) -> torch.Tensor:
42
+ """Append `kv` to inference_params.key_value_memory_dict[layer_idx].
43
+
44
+ kv: (B, S, 2, H_kv, D) where S is the new-token chunk length (may be 1).
45
+ Returns the cumulative kv up to the current sequence position.
46
+ """
47
+ num_heads, head_dim = kv.shape[-2:]
48
+ if layer_idx not in inference_params.key_value_memory_dict:
49
+ kv_cache = torch.empty(
50
+ inference_params.max_batch_size,
51
+ inference_params.max_seqlen,
52
+ 2,
53
+ num_heads,
54
+ head_dim,
55
+ dtype=kv.dtype,
56
+ device=kv.device,
57
+ )
58
+ inference_params.key_value_memory_dict[layer_idx] = kv_cache
59
+ else:
60
+ kv_cache = inference_params.key_value_memory_dict[layer_idx]
61
+ batch_start = inference_params.batch_size_offset
62
+ batch_end = batch_start + kv.shape[0]
63
+ sequence_start = inference_params.seqlen_offset
64
+ sequence_end = sequence_start + kv.shape[1]
65
+ kv_cache[batch_start:batch_end, sequence_start:sequence_end, ...] = kv
66
+ return kv_cache[batch_start:batch_end, :sequence_end, ...]
67
+
68
+
69
+ class MHA(nn.Module):
70
+ """Multi-head self-attention with backend-dispatch.
71
+
72
+ Constructor signature is a strict subset of flash_attn.modules.mha.MHA so
73
+ that the existing AttentionBlock instantiation site is left untouched.
74
+ Unsupported kwargs (cross_attn, dwconv, alibi, window_size, ...) are
75
+ accepted and ignored or hard-asserted: Evo1 never exercises them.
76
+ """
77
+
78
+ def __init__(
79
+ self,
80
+ embed_dim: int,
81
+ num_heads: int,
82
+ num_heads_kv: int | None = None,
83
+ cross_attn: bool = False,
84
+ qkv_proj_bias: bool = True,
85
+ out_proj_bias: bool = True,
86
+ dropout: float = 0.0,
87
+ softmax_scale: float | None = None,
88
+ causal: bool = False,
89
+ layer_idx: int | None = None,
90
+ rotary_emb_dim: int = 0,
91
+ rotary_emb_base: float = 10000.0,
92
+ rotary_emb_scale_base: float | None = None,
93
+ rotary_emb_interleaved: bool = False,
94
+ use_flash_attn: bool = False, # legacy kwarg, kept for ctor compatibility
95
+ attn_implementation: str = "eager",
96
+ device=None,
97
+ dtype=None,
98
+ ) -> None:
99
+ super().__init__()
100
+ if cross_attn:
101
+ raise NotImplementedError("Cross-attention is not supported in this minimal MHA.")
102
+
103
+ factory_kwargs = {"device": device, "dtype": dtype}
104
+ self.embed_dim = embed_dim
105
+ self.num_heads = num_heads
106
+ self.num_heads_kv = num_heads_kv if num_heads_kv is not None else num_heads
107
+ if self.embed_dim % num_heads != 0:
108
+ raise ValueError("embed_dim must be divisible by num_heads")
109
+ if self.num_heads % self.num_heads_kv != 0:
110
+ raise ValueError("num_heads must be divisible by num_heads_kv")
111
+ self.head_dim = self.embed_dim // num_heads
112
+ self.causal = causal
113
+ self.softmax_scale = softmax_scale
114
+ self.layer_idx = layer_idx
115
+ self.rotary_emb_dim = rotary_emb_dim
116
+ self.attn_implementation = attn_implementation
117
+ self.dropout_p = dropout
118
+
119
+ if self.rotary_emb_dim > 0:
120
+ self.rotary_emb = RotaryEmbedding(
121
+ self.rotary_emb_dim,
122
+ base=rotary_emb_base,
123
+ interleaved=rotary_emb_interleaved,
124
+ scale_base=rotary_emb_scale_base,
125
+ device=device,
126
+ )
127
+
128
+ qkv_dim = self.head_dim * (self.num_heads + 2 * self.num_heads_kv)
129
+ self.Wqkv = nn.Linear(embed_dim, qkv_dim, bias=qkv_proj_bias, **factory_kwargs)
130
+ self.out_proj = nn.Linear(embed_dim, embed_dim, bias=out_proj_bias, **factory_kwargs)
131
+
132
+ def allocate_inference_cache(self, batch_size, max_seqlen, dtype=None):
133
+ dtype = self.out_proj.weight.dtype if dtype is None else dtype
134
+ device = self.out_proj.weight.device
135
+ return torch.empty(
136
+ batch_size, max_seqlen, 2, self.num_heads_kv, self.head_dim,
137
+ dtype=dtype, device=device,
138
+ )
139
+
140
+ def _project_qkv(self, x: torch.Tensor) -> torch.Tensor:
141
+ """Compute Wqkv(x) and reshape to (B, T, 3, H, D) when MHA, or
142
+ return (q, kv) tuple-like layout when GQA. Returns the packed qkv
143
+ tensor in either case (kv heads broadcast for SDPA/flash later).
144
+
145
+ For Evo1 we have num_heads_kv == num_heads (proj_groups=1), so the
146
+ common-case packed layout is fine; we keep a GQA branch for future
147
+ flexibility but assert MHA at construction time.
148
+ """
149
+ qkv = self.Wqkv(x)
150
+ if self.num_heads_kv == self.num_heads:
151
+ return qkv.view(*qkv.shape[:-1], 3, self.num_heads, self.head_dim)
152
+ # GQA path (unused by Evo1):
153
+ q = qkv[..., : self.num_heads * self.head_dim]
154
+ kv = qkv[..., self.num_heads * self.head_dim:]
155
+ q = q.view(*q.shape[:-1], self.num_heads, self.head_dim)
156
+ kv = kv.view(*kv.shape[:-1], 2, self.num_heads_kv, self.head_dim)
157
+ return q, kv # type: ignore[return-value]
158
+
159
+ # ------------------------------------------------------------------ eager
160
+ def _forward_eager(
161
+ self,
162
+ qkv: torch.Tensor,
163
+ output_attentions: bool,
164
+ ) -> tuple[torch.Tensor, torch.Tensor | None]:
165
+ # qkv: (B, T, 3, H, D). Match flash_attn / sdpa numerical behaviour by
166
+ # doing the attention math in fp32 internally (q*scale, QK^T matmul,
167
+ # softmax, attn @ V). Without this, the bf16 matmuls accumulate
168
+ # ~1e-2 absolute error per attention block and diverge meaningfully
169
+ # from flash_attn (which always accumulates in fp32 inside its CUDA
170
+ # kernel). Output is cast back to the original dtype for the residual
171
+ # add.
172
+ orig_dtype = qkv.dtype
173
+ q, k, v = qkv.unbind(dim=2)
174
+ q = q.permute(0, 2, 1, 3).float() # (B, H, T, D), fp32
175
+ k = k.permute(0, 2, 1, 3).float()
176
+ v = v.permute(0, 2, 1, 3).float()
177
+ scale = self.softmax_scale if self.softmax_scale is not None else 1.0 / math.sqrt(self.head_dim)
178
+
179
+ scores = torch.matmul(q, k.transpose(-2, -1)) * scale
180
+ if self.causal:
181
+ T = q.shape[-2]
182
+ mask = torch.triu(
183
+ torch.ones(T, T, device=scores.device, dtype=torch.bool), diagonal=1
184
+ )
185
+ scores = scores.masked_fill(mask, float("-inf"))
186
+ attn = F.softmax(scores, dim=-1)
187
+ if self.training and self.dropout_p > 0:
188
+ attn = F.dropout(attn, p=self.dropout_p)
189
+ out = torch.matmul(attn, v).permute(0, 2, 1, 3) # (B, T, H, D), fp32
190
+ out = out.to(orig_dtype)
191
+ return out, (attn.to(orig_dtype) if output_attentions else None)
192
+
193
+ # -------------------------------------------------------------------- sdpa
194
+ def _forward_sdpa(self, qkv: torch.Tensor) -> torch.Tensor:
195
+ q, k, v = qkv.unbind(dim=2)
196
+ q = q.permute(0, 2, 1, 3) # (B, H, T, D)
197
+ k = k.permute(0, 2, 1, 3)
198
+ v = v.permute(0, 2, 1, 3)
199
+ scale = self.softmax_scale if self.softmax_scale is not None else None
200
+ out = F.scaled_dot_product_attention(
201
+ q, k, v,
202
+ attn_mask=None,
203
+ dropout_p=self.dropout_p if self.training else 0.0,
204
+ is_causal=self.causal,
205
+ scale=scale,
206
+ )
207
+ return out.permute(0, 2, 1, 3) # (B, T, H, D)
208
+
209
+ # -------------------------------------------------------- flash_attention_2
210
+ def _forward_flash(self, qkv: torch.Tensor) -> torch.Tensor:
211
+ _flash_attn_required()
212
+ from flash_attn import flash_attn_qkvpacked_func
213
+ # flash_attn expects (B, T, 3, H, D) in fp16/bf16 already; Evo1 attn
214
+ # blocks already cast to bf16 in __init__.
215
+ out = flash_attn_qkvpacked_func(
216
+ qkv,
217
+ dropout_p=self.dropout_p if self.training else 0.0,
218
+ softmax_scale=self.softmax_scale,
219
+ causal=self.causal,
220
+ )
221
+ return out # (B, T, H, D)
222
+
223
+ # ----------------------------------------------------------- KV-cache path
224
+ def _forward_with_cache(
225
+ self,
226
+ qkv: torch.Tensor,
227
+ inference_params,
228
+ ) -> torch.Tensor:
229
+ # qkv: (B, T, 3, H, D). Apply rotary at the current offset, append kv
230
+ # to cache, attend over the cumulative kv. For correctness we use SDPA
231
+ # which has stable behaviour at all sequence lengths.
232
+ if self.rotary_emb_dim > 0:
233
+ qkv = self.rotary_emb(
234
+ qkv,
235
+ seqlen_offset=inference_params.seqlen_offset,
236
+ max_seqlen=inference_params.max_seqlen,
237
+ )
238
+ q, k, v = qkv.unbind(dim=2)
239
+ kv = torch.stack((k, v), dim=2) # (B, T, 2, H, D)
240
+ kv = _update_kv_cache(kv, inference_params, self.layer_idx)
241
+ k_full, v_full = kv.unbind(dim=2) # (B, S_total, H, D)
242
+
243
+ q = q.permute(0, 2, 1, 3)
244
+ k_full = k_full.permute(0, 2, 1, 3)
245
+ v_full = v_full.permute(0, 2, 1, 3)
246
+ scale = self.softmax_scale if self.softmax_scale is not None else None
247
+ is_causal = self.causal and q.shape[-2] == k_full.shape[-2]
248
+ out = F.scaled_dot_product_attention(
249
+ q, k_full, v_full, is_causal=is_causal, scale=scale,
250
+ )
251
+ return out.permute(0, 2, 1, 3) # (B, T, H, D)
252
+
253
+ # ---------------------------------------------------------------- forward
254
+ def forward(
255
+ self,
256
+ x: torch.Tensor,
257
+ inference_params=None,
258
+ output_attentions: bool = False,
259
+ **_unused,
260
+ ) -> tuple[torch.Tensor, torch.Tensor | None]:
261
+ """Returns (out, attn_weights_or_None) where out is (B, T, embed_dim)."""
262
+ if self.num_heads_kv != self.num_heads:
263
+ raise NotImplementedError("GQA is not exercised by Evo1; please file an issue if needed.")
264
+
265
+ qkv = self._project_qkv(x) # (B, T, 3, H, D)
266
+
267
+ if inference_params is not None:
268
+ out_btd = self._forward_with_cache(qkv, inference_params)
269
+ attn_weights = None
270
+ else:
271
+ if self.rotary_emb_dim > 0:
272
+ qkv = self.rotary_emb(qkv, seqlen_offset=0, max_seqlen=qkv.shape[1])
273
+
274
+ backend = self.attn_implementation
275
+ if output_attentions and backend != "eager":
276
+ # Standard HF behaviour: silently fall back to eager so we can
277
+ # actually compute and return the attention matrix.
278
+ backend = "eager"
279
+
280
+ if backend == "eager":
281
+ out_btd, attn_weights = self._forward_eager(qkv, output_attentions=output_attentions)
282
+ elif backend == "sdpa":
283
+ out_btd = self._forward_sdpa(qkv)
284
+ attn_weights = None
285
+ elif backend == "flash_attention_2":
286
+ out_btd = self._forward_flash(qkv)
287
+ attn_weights = None
288
+ else:
289
+ raise ValueError(f"Unknown attn_implementation: {backend!r}")
290
+
291
+ # (B, T, H, D) -> (B, T, embed_dim)
292
+ B, T, H, D = out_btd.shape
293
+ out_flat = out_btd.reshape(B, T, H * D)
294
+ return self.out_proj(out_flat), attn_weights
cache.py ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (c) Together
2
+ # Apache 2.0 - Author: Michael Poli
3
+ # Adapted for the minimal Evo1 HF port.
4
+
5
+ """Inference-time caches for Evo1 blocks.
6
+
7
+ Evo1 has two block types with different caching needs:
8
+
9
+ * `mha` blocks -> InferenceParams (standard KV cache)
10
+ * `hyena` blocks -> RecurrentInferenceParams (FIR window + IIR modal state)
11
+
12
+ Per-block dataclasses are wrapped in an HF ``Cache`` subclass (``Evo1Cache``)
13
+ so ``model.generate()`` can drive autoregressive decoding without the user
14
+ having to instantiate the two caches by hand, and so HF generation helpers
15
+ can introspect cache state (``get_seq_length``, ``get_max_cache_shape``).
16
+ """
17
+
18
+ from __future__ import annotations
19
+
20
+ from dataclasses import dataclass, field
21
+ from typing import Optional
22
+
23
+ from torch import Tensor
24
+ from transformers.cache_utils import Cache
25
+
26
+
27
+ @dataclass
28
+ class InferenceParams:
29
+ """KV-cache parameters for the attention blocks (mha branch)."""
30
+
31
+ max_seqlen: int
32
+ max_batch_size: int
33
+ seqlen_offset: int = 0
34
+ batch_size_offset: int = 0
35
+ key_value_memory_dict: dict = field(default_factory=dict)
36
+ lengths_per_sample: Optional[Tensor] = None
37
+
38
+ def reset(self, max_seqlen, max_batch_size):
39
+ self.max_seqlen = max_seqlen
40
+ self.max_batch_size = max_batch_size
41
+ self.seqlen_offset = 0
42
+ if self.lengths_per_sample is not None:
43
+ self.lengths_per_sample.zero_()
44
+
45
+
46
+ @dataclass
47
+ class RecurrentInferenceParams:
48
+ """SSM-cache parameters for the Hyena blocks (hyena branch)."""
49
+
50
+ fir_filter_length: int = 3
51
+ state_dim: int = 16
52
+ seqlen_offset: int = 0
53
+ fir_state_dict: dict = field(default_factory=dict)
54
+ state_dict: dict = field(default_factory=dict)
55
+
56
+ def reset(self):
57
+ self.fir_filter_length = 3
58
+ self.state_dim = 16
59
+ self.seqlen_offset = 0
60
+
61
+
62
+ class Evo1Cache(Cache):
63
+ """HF-compatible wrapper around the per-block inference params.
64
+
65
+ Internally holds two dataclasses keyed by block type. Exposes
66
+ ``seqlen_offset`` so HF generation helpers can read the current decoded
67
+ length, and implements ``get_seq_length()`` / ``get_max_cache_shape()``
68
+ per the transformers ``Cache`` interface.
69
+
70
+ The model internals (``StripedHyena.stateful_forward``) look up caches
71
+ via ``cache["mha"]`` and ``cache["hyena"]``; ``__getitem__`` is delegated
72
+ to attribute access so the original dict-keyed API keeps working.
73
+ """
74
+
75
+ is_compileable = False
76
+
77
+ def __init__(
78
+ self,
79
+ max_seqlen: int,
80
+ max_batch_size: int,
81
+ short_filter_length: int = 3,
82
+ state_size: int = 8,
83
+ ):
84
+ # transformers >= 4.55 Cache.__init__ requires either ``layers`` or
85
+ # ``layer_class_to_replicate``. We don't use HF's per-layer cache
86
+ # model (our two block-type-specific caches handle storage), so we
87
+ # pass an empty layers list.
88
+ super().__init__(layers=[])
89
+ self.mha = InferenceParams(
90
+ max_seqlen=max_seqlen,
91
+ max_batch_size=max_batch_size,
92
+ )
93
+ self.hyena = RecurrentInferenceParams(
94
+ fir_filter_length=short_filter_length,
95
+ state_dim=state_size,
96
+ )
97
+
98
+ # --- HF Cache interface ------------------------------------------------
99
+ @property
100
+ def seqlen_offset(self) -> int:
101
+ return self.mha.seqlen_offset
102
+
103
+ def get_seq_length(self, layer_idx: int = 0) -> int:
104
+ return self.mha.seqlen_offset
105
+
106
+ def get_max_cache_shape(self) -> int:
107
+ return self.mha.max_seqlen
108
+
109
+ def get_max_length(self) -> int:
110
+ # deprecated alias kept for older transformers versions
111
+ return self.mha.max_seqlen
112
+
113
+ # --- our convenience helpers ------------------------------------------
114
+ def advance(self, n: int = 1) -> None:
115
+ self.mha.seqlen_offset += n
116
+ self.hyena.seqlen_offset += n
117
+
118
+ def set_offset(self, offset: int) -> None:
119
+ self.mha.seqlen_offset = offset
120
+ self.hyena.seqlen_offset = offset
121
+
122
+ def reset(self) -> None:
123
+ self.mha.reset(self.mha.max_seqlen, self.mha.max_batch_size)
124
+ self.hyena.reset()
125
+
126
+ # --- dict-like access so existing call sites keep working --------------
127
+ def __getitem__(self, name: str):
128
+ return getattr(self, name)
129
+
130
+ def by_block_name(self, name: str):
131
+ return getattr(self, name)
132
+
config.json ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "Evo1ForCausalLM"
4
+ ],
5
+ "attn_layer_idxs": [
6
+ 8,
7
+ 16,
8
+ 24
9
+ ],
10
+ "auto_map": {
11
+ "AutoConfig": "configuration_evo1.Evo1Config",
12
+ "AutoModel": "modeling_evo1.Evo1Model",
13
+ "AutoModelForCausalLM": "modeling_evo1.Evo1ForCausalLM"
14
+ },
15
+ "column_split": false,
16
+ "column_split_hyena": true,
17
+ "dtype": "bfloat16",
18
+ "eps": 1e-06,
19
+ "final_norm": true,
20
+ "hidden_size": 4096,
21
+ "hyena_filter_groups": 1,
22
+ "hyena_layer_idxs": [
23
+ 0,
24
+ 1,
25
+ 2,
26
+ 3,
27
+ 4,
28
+ 5,
29
+ 6,
30
+ 7,
31
+ 9,
32
+ 10,
33
+ 11,
34
+ 12,
35
+ 13,
36
+ 14,
37
+ 15,
38
+ 17,
39
+ 18,
40
+ 19,
41
+ 20,
42
+ 21,
43
+ 22,
44
+ 23,
45
+ 25,
46
+ 26,
47
+ 27,
48
+ 28,
49
+ 29,
50
+ 30,
51
+ 31
52
+ ],
53
+ "inference_mode": false,
54
+ "inner_mlp_size": 10928,
55
+ "log_intermediate_values": false,
56
+ "make_vocab_size_divisible_by": 8,
57
+ "max_seqlen": 8192,
58
+ "mha_out_proj_bias": true,
59
+ "mlp_activation": "gelu",
60
+ "model_parallel_size": 1,
61
+ "model_type": "evo1",
62
+ "num_attention_heads": 32,
63
+ "num_filters": 4096,
64
+ "num_layers": 32,
65
+ "pipe_parallel_size": 1,
66
+ "prefill_style": "fft",
67
+ "proj_groups": 1,
68
+ "qkv_proj_bias": true,
69
+ "rotary_emb_base": 10000,
70
+ "rotary_emb_scaling_factor": 1.0,
71
+ "short_filter_bias": true,
72
+ "short_filter_length": 3,
73
+ "smeared_gqa": false,
74
+ "split_k0": true,
75
+ "state_size": 8,
76
+ "tie_embeddings": true,
77
+ "transformers_version": "4.57.6",
78
+ "use_cache": true,
79
+ "use_flash_attention_2": true,
80
+ "use_flash_attn": false,
81
+ "use_flash_depthwise": false,
82
+ "use_flash_rmsnorm": false,
83
+ "use_flashfft": false,
84
+ "use_interpolated_rotary_pos_emb": false,
85
+ "vocab_size": 512
86
+ }
configuration_evo1.py ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Apache 2.0 - port of togethercomputer's StripedHyenaConfig.
2
+ """Configuration for Evo1 (StripedHyena 7B family)."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import json
7
+
8
+ from transformers import PretrainedConfig
9
+
10
+
11
+ class Evo1Config(PretrainedConfig):
12
+ """Configuration for the Evo1 family.
13
+
14
+ Defaults match the evo-1-8k-base / evo-1-131k-base / evo-1.5-8k-base
15
+ checkpoints (32 layers, 4096 hidden, 32 heads, attn at idx [8, 16, 24]
16
+ and Hyena everywhere else, byte-level vocab_size=512). The 131k variant
17
+ overrides ``use_interpolated_rotary_pos_emb`` and ``rotary_emb_scaling_factor``
18
+ plus a longer ``max_seqlen``.
19
+ """
20
+
21
+ model_type = "evo1"
22
+
23
+ def __init__(
24
+ self,
25
+ # Architecture
26
+ vocab_size: int = 512,
27
+ hidden_size: int = 4096,
28
+ num_filters: int = 4096,
29
+ inner_mlp_size: int = 10928,
30
+ attn_layer_idxs=None,
31
+ hyena_layer_idxs=None,
32
+ num_layers: int = 32,
33
+ num_attention_heads: int = 32,
34
+ proj_groups: int = 1,
35
+ hyena_filter_groups: int = 1,
36
+ short_filter_length: int = 3,
37
+ short_filter_bias: bool = True,
38
+ state_size: int = 8,
39
+ column_split: bool = False,
40
+ column_split_hyena: bool = True,
41
+ split_k0: bool = True,
42
+ smeared_gqa: bool = False,
43
+ # Norms
44
+ eps: float = 1e-6,
45
+ final_norm: bool = True,
46
+ # Linear biases
47
+ mha_out_proj_bias: bool = True,
48
+ qkv_proj_bias: bool = True,
49
+ # Embeddings
50
+ tie_embeddings: bool = True,
51
+ make_vocab_size_divisible_by: int = 8,
52
+ # Activations
53
+ mlp_activation: str = "gelu",
54
+ # Sequence length / RoPE
55
+ max_seqlen: int = 8192,
56
+ rotary_emb_base: float = 10000,
57
+ use_interpolated_rotary_pos_emb: bool = False,
58
+ rotary_emb_scaling_factor: float = 1.0,
59
+ # Inference engine
60
+ prefill_style: str = "fft",
61
+ inference_mode: bool = False,
62
+ # Backend toggles
63
+ use_cache: bool = True,
64
+ use_flash_attention_2: bool = True,
65
+ use_flash_rmsnorm: bool = False,
66
+ use_flash_depthwise: bool = False,
67
+ use_flashfft: bool = False,
68
+ use_flash_attn: bool = False,
69
+ # Misc
70
+ log_intermediate_values: bool = False,
71
+ model_parallel_size: int = 1,
72
+ pipe_parallel_size: int = 1,
73
+ **kwargs,
74
+ ):
75
+ if attn_layer_idxs is None:
76
+ attn_layer_idxs = [8, 16, 24]
77
+ if hyena_layer_idxs is None:
78
+ hyena_layer_idxs = [i for i in range(num_layers) if i not in attn_layer_idxs]
79
+
80
+ # Architecture
81
+ self.vocab_size = vocab_size
82
+ self.hidden_size = hidden_size
83
+ self.num_filters = num_filters
84
+ self.inner_mlp_size = inner_mlp_size
85
+ self.attn_layer_idxs = attn_layer_idxs
86
+ self.hyena_layer_idxs = hyena_layer_idxs
87
+ self.num_layers = num_layers
88
+ self.num_attention_heads = num_attention_heads
89
+ self.proj_groups = proj_groups
90
+ self.hyena_filter_groups = hyena_filter_groups
91
+ self.short_filter_length = short_filter_length
92
+ self.short_filter_bias = short_filter_bias
93
+ self.state_size = state_size
94
+ self.column_split = column_split
95
+ self.column_split_hyena = column_split_hyena
96
+ self.split_k0 = split_k0
97
+ self.smeared_gqa = smeared_gqa
98
+ # Norms
99
+ self.eps = eps
100
+ self.final_norm = final_norm
101
+ # Biases
102
+ self.mha_out_proj_bias = mha_out_proj_bias
103
+ self.qkv_proj_bias = qkv_proj_bias
104
+ # Embeddings
105
+ self.tie_embeddings = tie_embeddings
106
+ self.make_vocab_size_divisible_by = make_vocab_size_divisible_by
107
+ # Activations
108
+ self.mlp_activation = mlp_activation
109
+ # Length / RoPE
110
+ self.max_seqlen = max_seqlen
111
+ self.rotary_emb_base = rotary_emb_base
112
+ self.use_interpolated_rotary_pos_emb = use_interpolated_rotary_pos_emb
113
+ self.rotary_emb_scaling_factor = rotary_emb_scaling_factor
114
+ # Engine
115
+ self.prefill_style = prefill_style
116
+ self.inference_mode = inference_mode
117
+ # Backend toggles
118
+ self.use_cache = use_cache
119
+ self.use_flash_attention_2 = use_flash_attention_2
120
+ self.use_flash_rmsnorm = use_flash_rmsnorm
121
+ self.use_flash_depthwise = use_flash_depthwise
122
+ self.use_flashfft = use_flashfft
123
+ self.use_flash_attn = use_flash_attn
124
+ # Misc
125
+ self.log_intermediate_values = log_intermediate_values
126
+ self.model_parallel_size = model_parallel_size
127
+ self.pipe_parallel_size = pipe_parallel_size
128
+ super().__init__(**kwargs)
129
+
130
+ # ------------------------------------------------------------------
131
+ # Backwards-compatible attribute access.
132
+ #
133
+ # The internal blocks (RMSNorm, ParallelGatedMLP, ...) call
134
+ # ``config.get(key, default)`` because they were originally written
135
+ # against a `dotdict`. PretrainedConfig has a different `.get`, so we
136
+ # provide a dict-like one that delegates to attribute access.
137
+ # ------------------------------------------------------------------
138
+ @property
139
+ def num_hidden_layers(self) -> int:
140
+ # HF generation utilities (DynamicCache, etc.) expect this name; we
141
+ # keep ``num_layers`` as the source of truth to match the upstream
142
+ # StripedHyena config.
143
+ return self.num_layers
144
+
145
+ def get(self, key, default=None):
146
+ # Dict-style access used by internal blocks (RMSNorm, MHA, ...).
147
+ return getattr(self, key, default)
148
+
149
+ @classmethod
150
+ def from_original_config(cls, config_path: str, **kwargs) -> "Evo1Config":
151
+ with open(config_path, "r") as f:
152
+ config = json.load(f)
153
+ return cls(**config, **kwargs)
engine.py ADDED
@@ -0,0 +1,388 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (c) Together
2
+ # This software is distributed under the terms of the Apache License, Version 2.0
3
+ # Author: Michael Poli
4
+
5
+ import gc
6
+
7
+ import torch
8
+ import torch.nn as nn
9
+ import torch.nn.functional as F
10
+
11
+ try:
12
+ import conv1d_cpp # noqa: F401
13
+ except Exception:
14
+ pass
15
+
16
+ IIR_PREFILL_MODES = [
17
+ "recurrence",
18
+ "modal-fft",
19
+ "hybrid-modal-recurrence",
20
+ "modal-scan",
21
+ "canonical-fft",
22
+ "iir-fir-caching",
23
+ ]
24
+
25
+
26
+ def canonicalize_modal_system(poles, residues):
27
+ """Canonicalize a modal system.
28
+
29
+ Args:
30
+ poles (Tensor): The poles of the system.
31
+ residues (Tensor): The residues of the system.
32
+
33
+ Returns:
34
+ Tuple[Tensor, Tensor]: The canonicalized poles and residues.
35
+ """
36
+ raise NotImplementedError
37
+
38
+
39
+ def list_tensors(idx):
40
+ for obj in gc.get_objects():
41
+ try:
42
+ if torch.is_tensor(obj) and isinstance(obj, torch.Tensor):
43
+ # dump to log
44
+ print(type(obj), obj.size())
45
+ el = obj[0]
46
+ with open(f"tensors_{idx}.txt", "a") as f:
47
+ f.write(f"{type(obj)} {obj.size()} {el}\n")
48
+ except Exception as e:
49
+ pass
50
+
51
+
52
+ class HyenaInferenceEngine:
53
+ def __init__(
54
+ self,
55
+ fir_fn=None,
56
+ iir_prefill_style="modal-fft",
57
+ layer_idx=None,
58
+ ) -> None:
59
+ self.fir_fn = fir_fn
60
+ assert iir_prefill_style in IIR_PREFILL_MODES, f"iir_prefill_style must be one of {IIR_PREFILL_MODES}"
61
+ self.iir_prefill_style = iir_prefill_style
62
+ self.layer_idx = layer_idx
63
+ self.low_mem_mode = False
64
+
65
+ def parallel_fir(
66
+ self,
67
+ fir_fn,
68
+ u,
69
+ weight,
70
+ bias,
71
+ L,
72
+ fir_length=3,
73
+ inference_params=None,
74
+ prefill_mode=None,
75
+ padding_mask=None,
76
+ ):
77
+ """Compute the output state of the long convolutional filter."""
78
+ # prepare input layout, dimensions and dispatch to fir kernel
79
+ if fir_fn != torch.nn.functional.conv1d:
80
+ z_pre = fir_fn(u)[:, :L] # B, L, D
81
+ z_pre = z_pre.permute(0, 2, 1)
82
+ else:
83
+ u = u.permute(0, 2, 1) # B, D, L
84
+ z_pre = fir_fn(
85
+ u,
86
+ weight,
87
+ bias=None, # don't pass it here, add manually instead! source of small error
88
+ stride=1,
89
+ padding=fir_length - 1,
90
+ groups=u.shape[1],
91
+ )[..., :L]
92
+
93
+ # add manually instead! source of small error
94
+ z_pre = z_pre + bias[None, :, None]
95
+
96
+ # handle padding post fir, the only place with biases
97
+ if type(padding_mask) == torch.Tensor:
98
+ z_pre = z_pre * padding_mask[:, None]
99
+
100
+ if inference_params is not None:
101
+ # handle seqlen last and dim last cases for `u`
102
+ if fir_fn != torch.nn.functional.conv1d:
103
+ fir_state = u[:, -fir_length + 1 :].permute(0, 2, 1)
104
+ else:
105
+ fir_state = u[..., -fir_length + 1 :]
106
+ else:
107
+ fir_state = None
108
+
109
+ return z_pre, fir_state
110
+
111
+ def parallel_iir(
112
+ self,
113
+ z_pre,
114
+ h,
115
+ D,
116
+ L,
117
+ poles,
118
+ residues,
119
+ t,
120
+ dims,
121
+ layer_idx,
122
+ inference_params=None,
123
+ prefill_style="fft",
124
+ fftconv_fn=None,
125
+ padding_mask=None,
126
+ use_flashfft=False,
127
+ column_split_hyena=False,
128
+ long_fir_threshold=None,
129
+ ):
130
+ """Compute the output state of the short convolutional filter."""
131
+ fft_size = 2 * L
132
+ hidden_size, num_attention_heads, hidden_size_per_attention_head, _, _ = dims
133
+ # Compatibility with training infra that column splits the projections
134
+ if column_split_hyena:
135
+ z = z_pre.reshape(
136
+ z_pre.shape[0],
137
+ num_attention_heads,
138
+ 3 * hidden_size_per_attention_head,
139
+ z_pre.shape[2],
140
+ )
141
+ x2, x1, v = (
142
+ z[:, :, :hidden_size_per_attention_head],
143
+ z[
144
+ :,
145
+ :,
146
+ hidden_size_per_attention_head : 2 * hidden_size_per_attention_head,
147
+ ],
148
+ z[:, :, 2 * hidden_size_per_attention_head :],
149
+ )
150
+ x2, x1, v = (
151
+ x2.reshape(x2.shape[0], -1, x2.shape[-1]),
152
+ x1.reshape(x1.shape[0], -1, x1.shape[-1]),
153
+ v.reshape(v.shape[0], -1, v.shape[-1]),
154
+ )
155
+ else:
156
+ x2, x1, v = z_pre.split([hidden_size, hidden_size, hidden_size], dim=1)
157
+
158
+ x1v = x1 * v
159
+
160
+ if inference_params is not None and prefill_style == "recurrence":
161
+ y = self.prefill_via_direct_recurrence(
162
+ inference_params=inference_params,
163
+ x1v=x1v,
164
+ L=L,
165
+ poles=poles,
166
+ residues=residues,
167
+ )
168
+
169
+ else:
170
+ if use_flashfft and (L % 2) == 0: # only works with even L
171
+ y = fftconv_fn(
172
+ x1v.to(dtype=torch.bfloat16).contiguous(),
173
+ h.to(dtype=torch.float32),
174
+ )
175
+ X_s = None
176
+
177
+ elif long_fir_threshold is None:
178
+ H = torch.fft.rfft(h.to(dtype=torch.float32), n=fft_size) / fft_size
179
+ X_s = torch.fft.fft(x1v.to(dtype=torch.float32), n=fft_size)
180
+ X = X_s[..., : H.shape[-1]]
181
+ if len(z_pre.shape) > 3:
182
+ H = H.unsqueeze(1)
183
+ y = torch.fft.irfft(X * H, n=fft_size, norm="forward")[..., :L]
184
+
185
+ else:
186
+ assert h.shape[0] == 1, "batch size must be 1 for long_fir_threshold"
187
+ h = h[0][:, None] # rearrange to d, 1, l for depthwise conv1d
188
+ h = h[..., :long_fir_threshold]
189
+ y = F.conv1d(
190
+ x1v,
191
+ h.to(dtype=x1v.dtype),
192
+ stride=1,
193
+ groups=x1v.shape[1],
194
+ padding=h.shape[-1] - 1,
195
+ )[..., :L]
196
+
197
+ y = y.to(dtype=x1v.dtype)
198
+ y = (y + x1v * D.unsqueeze(-1)) * x2
199
+
200
+ if inference_params is not None:
201
+ if prefill_style == "fft":
202
+ self.prefill_via_modal_fft(
203
+ inference_params=inference_params,
204
+ x1v=x1v,
205
+ X_s=X_s,
206
+ L=L,
207
+ t=t,
208
+ poles=poles,
209
+ dims=dims,
210
+ layer_idx=layer_idx,
211
+ use_flashfft=use_flashfft,
212
+ fftconv_fn=fftconv_fn,
213
+ )
214
+
215
+ elif prefill_style == "recurrence":
216
+ # recurrent prefill is done before
217
+ pass
218
+ else:
219
+ raise NotImplementedError
220
+ if self.low_mem_mode:
221
+ # TODO: smarter gc
222
+ del z_pre, x2, x1, v, x1v, h, poles, residues
223
+ torch.cuda.empty_cache()
224
+
225
+ return y.permute(0, 2, 1)
226
+
227
+ def step_fir(self, u, fir_state, weight, bias=None):
228
+ """Step the FIR filter.
229
+
230
+ Note:
231
+ `fir_state` contains the last `short_filter_length - 1` elements of `u`: `u_(L-2), u_{L-1), ...`
232
+ We assume dimensions of `short_filter_weight` to be `[d, 1, short_filter_len]` (SISO / multi SISO layout).
233
+ """
234
+ h0, h = weight[..., 0, -1], weight[..., 0, :-1]
235
+ h0, h = h0[None], h[None]
236
+ y = h0 * u + torch.sum(fir_state * h, dim=-1) + bias
237
+
238
+ # update
239
+ fir_state = torch.roll(fir_state, -1, dims=2)
240
+ fir_state[..., -1] = u
241
+ return y, fir_state
242
+
243
+ def step_iir(self, x2, x1, v, D, residues, poles, iir_state, iir_groups=1):
244
+ x1v = x1 * v
245
+
246
+ residues, poles = (
247
+ torch.view_as_complex(residues.to(torch.float32)),
248
+ torch.view_as_complex(poles.to(torch.float32)),
249
+ )
250
+ # squeeze the dummy seqlen dimension
251
+ # D, state_dim, 1 -> 1, D, state_dim
252
+ residues, poles = residues[..., 0][None], poles[..., 0][None]
253
+ iir_state = poles * iir_state + x1v[..., None]
254
+
255
+ res_state = torch.sum(residues * iir_state, dim=-1).real
256
+
257
+ if iir_groups > 1:
258
+ raise NotImplementedError
259
+ y = x2 * (res_state + D * x1v)
260
+
261
+ return y, iir_state
262
+
263
+ def prefill_via_fir_caching(self, u, inference_params, L, *args, **kwargs):
264
+ """Turns the IIR filter into a FIR and uses a cache for decoding."""
265
+ raise NotImplementedError(":)")
266
+
267
+ def prefill_via_direct_recurrence(
268
+ self, inference_params, x1v, L, residues, poles, *args, **kwargs
269
+ ) -> torch.Tensor:
270
+ """
271
+ Compute the IIR state via explicit SSM recurrence (modal form)
272
+
273
+ This is the most memory efficient prefilling method for Hyena filters.
274
+
275
+ Note:
276
+ dtypes: [state: float32, poles: float32, x1v: bfloat16, output: bfloat16]
277
+ """
278
+ state_dim = poles.shape[1]
279
+ x1v_ = x1v[..., None, None] # b, d, l, sdim, reim
280
+ x1v_ = x1v_.repeat(1, 1, 1, state_dim, 2) # b, d, l, sdim, reim
281
+ x1v_[..., 1] = 0
282
+
283
+ state = 0 * x1v_[:, :, 0]
284
+ output = 0 * x1v_[:, :, :, 0, 0] # b, d, l
285
+
286
+ # suppress dummy seqlen dimension
287
+ poles = poles[:, :, 0][None]
288
+ residues = residues[:, :, 0][None].repeat(x1v_.shape[0], 1, 1, 1) # b, d, sdim, reim
289
+
290
+ # state: b, d, sdim, reim
291
+ # poles: 1, d, sdim, reim
292
+ # x1v_: b, d, l, sdim, reim
293
+ for i in range(L):
294
+ state[..., 0] = poles[..., 0] * state[..., 0] - poles[..., 1] * state[..., 1] + x1v_[:, :, i, :, 0]
295
+ state[..., 1] = poles[..., 0] * state[..., 1] + poles[..., 1] * state[..., 0] + x1v_[:, :, i, :, 1]
296
+ output[:, :, i] = torch.sum(residues * state, dim=-2)[..., 0] # .real
297
+
298
+ inference_params.state_dict[self.layer_idx] = torch.view_as_complex(state.to(dtype=torch.float32))
299
+
300
+ return output
301
+
302
+ def prefill_via_hybrid_recurrence(self, inference_params, u, log_poles, x1v_f_a, L, *args, **kwargs):
303
+ """
304
+ Compute the IIR state via hybrid recurrence-convolution over blocks
305
+ """
306
+ raise NotImplementedError(":)")
307
+
308
+ def prefill_via_scan(self, u, inference_params=None, *args, **kwargs):
309
+ raise NotImplementedError
310
+
311
+ def prefill_via_canonical_fft(self, u, inference_params=None, *args, **kwargs):
312
+ """
313
+ Compute the IIR state via a single FFT with the denominator of the SSM in companion form.
314
+
315
+ This is the most memory efficient "parallelized" prefilling method for Hyena.
316
+
317
+ From: https://arxiv.org/abs/2310.18780
318
+ """
319
+ raise NotImplementedError(":)")
320
+
321
+ def prefill_via_modal_fft(
322
+ self,
323
+ inference_params,
324
+ x1v,
325
+ L,
326
+ poles,
327
+ t,
328
+ dims,
329
+ layer_idx,
330
+ X_s=None,
331
+ use_flashfft=False,
332
+ fftconv_fn=None,
333
+ state_dtype=torch.complex64,
334
+ *args,
335
+ **kwargs,
336
+ ):
337
+ """
338
+ Compute the IIR state via a single FFT, using the poles of the SSM in modal form.
339
+ """
340
+ # When the model has a long convolution derived from a SSM in modal form and prefill_style is "fft",
341
+ # we split the filter into poles and residues and reuse FFT computation on the input.
342
+ # This optimization is currently not supported when using flashfftconv.
343
+ hidden_size, _, _, state_size, hyena_filter_groups = dims
344
+
345
+ if use_flashfft:
346
+ # using real states
347
+ poles = poles.squeeze().reshape(poles.shape[0], -1)[..., None]
348
+
349
+ state_s = poles**t
350
+ if hyena_filter_groups > 1:
351
+ raise NotImplementedError
352
+
353
+ x1v = x1v[:, :, None].repeat(1, 1, 2 * state_size, 1)
354
+ x1v = x1v.reshape(x1v.shape[0], -1, x1v.shape[-1])
355
+ state_s = state_s[None]
356
+
357
+ state = fftconv_fn(
358
+ x1v.contiguous(),
359
+ state_s.to(dtype=torch.float32),
360
+ )
361
+ state = state[..., L - 1].reshape(x1v.shape[0], hidden_size, state_size, 2)
362
+ state = torch.view_as_complex(state.contiguous().to(dtype=torch.float32))
363
+ inference_params.state_dict[self.layer_idx] = state
364
+ else:
365
+ assert X_s is not None
366
+ bs = x1v.shape[0]
367
+ fft_size = 2 * L
368
+ poles = torch.view_as_complex(poles.to(torch.float32))
369
+ state_s = poles**t
370
+ state_S = torch.fft.fft(state_s, n=fft_size).repeat(bs, 1, 1, 1) # B, D, state_dim, 2 * L
371
+ if hyena_filter_groups > 1:
372
+ state_S = state_S.repeat_interleave(hidden_size // hyena_filter_groups, 1)
373
+ state = torch.fft.ifft(X_s[..., None, :] * state_S, n=fft_size)
374
+ inference_params.state_dict[layer_idx] = state[..., L - 1].to(dtype=state_dtype)
375
+
376
+ def _compute_state(self, log_poles, u, t, L, *args, **kwargs):
377
+ """
378
+ Compute the IIR state given an input `u` and log_poles of the modal system.
379
+ """
380
+ bs = u.shape[0]
381
+ fft_size = 2 * L
382
+ U = torch.fft.rfft(u.to(torch.float32), n=fft_size)
383
+ fft_size = 2 * L
384
+ x = (log_poles * t).exp()
385
+ # [batch, hidden_size, state_dim, 2 * seqlen]
386
+ X = torch.fft.fft(x, n=fft_size).repeat(bs, 1, 1, 1)
387
+ state = torch.fft.ifft(U[..., None, :] * X, n=fft_size)[..., :L]
388
+ return state
generation_config.json ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ {
2
+ "eos_token_id": 0,
3
+ "pad_token_id": 1,
4
+ "_from_model_config": true
5
+ }
layers.py ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (c) Together
2
+ # Apache 2.0 - Author: Michael Poli
3
+ # Adapted for the minimal Evo1 HF port.
4
+
5
+ import torch
6
+ import torch.nn as nn
7
+ import torch.nn.functional as F
8
+ from torch import Tensor
9
+
10
+
11
+ def grab_first_if_tuple(x):
12
+ if x.__class__.__name__ == "tuple":
13
+ return x[0]
14
+ return x
15
+
16
+
17
+ class RMSNorm(torch.nn.Module):
18
+ def __init__(self, config):
19
+ super().__init__()
20
+ self.eps = config.eps
21
+ self.hidden_size = config.hidden_size
22
+ self.scale = torch.nn.Parameter(torch.ones(self.hidden_size))
23
+ self.register_parameter("scale", self.scale)
24
+ self.use_flash_rmsnorm = config.get("use_flash_rmsnorm", False)
25
+ if self.use_flash_rmsnorm:
26
+ from flash_attn.ops.rms_norm import rms_norm as rmsnorm_func
27
+ self.rmsnorm_func = rmsnorm_func
28
+
29
+ def forward(self, x):
30
+ if self.use_flash_rmsnorm:
31
+ return self.rmsnorm_func(x, self.scale, self.eps)
32
+ y = x / (x.norm(2, dim=-1, keepdim=True) * self.hidden_size ** (-1.0 / 2) + self.eps)
33
+ return self.scale * y
34
+
35
+
36
+ class ParallelGatedMLP(nn.Module):
37
+ def __init__(self, config):
38
+ super().__init__()
39
+ multiple_of = config.get("inner_size_multiple_of", 64)
40
+ self.act_type = config.get("mlp_activation", "silu")
41
+ if self.act_type == "gelu":
42
+ self.act = F.gelu
43
+ elif self.act_type == "silu":
44
+ self.act = F.silu
45
+ else:
46
+ raise NotImplementedError(f"Unknown mlp_activation: {self.act_type}")
47
+
48
+ self.multiple_of = multiple_of * config.model_parallel_size
49
+ inner_size = int(2 * config.hidden_size * 4 / 3)
50
+ inner_size = self.multiple_of * ((inner_size + self.multiple_of - 1) // self.multiple_of)
51
+ if config.get("inner_mlp_size", None) is not None:
52
+ inner_size = config.inner_mlp_size
53
+
54
+ self.l1 = nn.Linear(config.hidden_size, inner_size, bias=False)
55
+ self.l2 = nn.Linear(config.hidden_size, inner_size, bias=False)
56
+ self.l3 = nn.Linear(inner_size, config.hidden_size, bias=False)
57
+
58
+ def forward(self, z):
59
+ z1, z2 = self.l1(z), self.l2(z)
60
+ z1, z2 = grab_first_if_tuple(z1), grab_first_if_tuple(z2)
61
+ y = self.l3(self.act(z1) * z2)
62
+ return grab_first_if_tuple(y)
63
+
64
+
65
+ class VocabParallelEmbedding(nn.Embedding):
66
+ """Single-process variant of the original VocabParallelEmbedding.
67
+
68
+ The original supports tensor-parallel embedding sharding. We keep the
69
+ naming so existing checkpoints load directly, but drop all distributed
70
+ paths since this minimal port runs on a single device.
71
+ """
72
+
73
+ def __init__(self, config):
74
+ vocab_size = config.vocab_size
75
+ padding_idx = config.get("padding_idx", None)
76
+ super().__init__(vocab_size, embedding_dim=config.hidden_size, padding_idx=padding_idx)
77
+
78
+ def embed(self, x: Tensor) -> Tensor:
79
+ return self.forward(x)
80
+
81
+ def unembed(self, u: Tensor) -> Tensor:
82
+ return u @ self.weight.T
model-00001-of-00003.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:bac7a0023292c7b07b32251b03ed1316c3e1a6d77d72ce34a813b8eee2593941
3
+ size 4985304472
model-00002-of-00003.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7f5ce86f31aaa6e14aee17cfb5da728d39cf7b2b2bf9083cab48e6216b2cb60a
3
+ size 4928275752
model-00003-of-00003.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:573e321dfe66a07a9fb2529be5ac9c406d081c7575405d5bb0620d742758a78d
3
+ size 2999633368
model.safetensors.index.json ADDED
@@ -0,0 +1,446 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "metadata": {
3
+ "total_parameters": 6452781056,
4
+ "total_size": 12913164672
5
+ },
6
+ "weight_map": {
7
+ "backbone.blocks.0.filter.D": "model-00001-of-00003.safetensors",
8
+ "backbone.blocks.0.filter.poles": "model-00001-of-00003.safetensors",
9
+ "backbone.blocks.0.filter.residues": "model-00001-of-00003.safetensors",
10
+ "backbone.blocks.0.filter.short_filter_bias": "model-00001-of-00003.safetensors",
11
+ "backbone.blocks.0.filter.short_filter_weight": "model-00001-of-00003.safetensors",
12
+ "backbone.blocks.0.mlp.l1.weight": "model-00001-of-00003.safetensors",
13
+ "backbone.blocks.0.mlp.l2.weight": "model-00001-of-00003.safetensors",
14
+ "backbone.blocks.0.mlp.l3.weight": "model-00001-of-00003.safetensors",
15
+ "backbone.blocks.0.out_filter_dense.bias": "model-00001-of-00003.safetensors",
16
+ "backbone.blocks.0.out_filter_dense.weight": "model-00001-of-00003.safetensors",
17
+ "backbone.blocks.0.post_norm.scale": "model-00001-of-00003.safetensors",
18
+ "backbone.blocks.0.pre_norm.scale": "model-00001-of-00003.safetensors",
19
+ "backbone.blocks.0.projections.bias": "model-00001-of-00003.safetensors",
20
+ "backbone.blocks.0.projections.weight": "model-00001-of-00003.safetensors",
21
+ "backbone.blocks.1.filter.D": "model-00001-of-00003.safetensors",
22
+ "backbone.blocks.1.filter.poles": "model-00001-of-00003.safetensors",
23
+ "backbone.blocks.1.filter.residues": "model-00001-of-00003.safetensors",
24
+ "backbone.blocks.1.filter.short_filter_bias": "model-00001-of-00003.safetensors",
25
+ "backbone.blocks.1.filter.short_filter_weight": "model-00001-of-00003.safetensors",
26
+ "backbone.blocks.1.mlp.l1.weight": "model-00001-of-00003.safetensors",
27
+ "backbone.blocks.1.mlp.l2.weight": "model-00001-of-00003.safetensors",
28
+ "backbone.blocks.1.mlp.l3.weight": "model-00001-of-00003.safetensors",
29
+ "backbone.blocks.1.out_filter_dense.bias": "model-00001-of-00003.safetensors",
30
+ "backbone.blocks.1.out_filter_dense.weight": "model-00001-of-00003.safetensors",
31
+ "backbone.blocks.1.post_norm.scale": "model-00001-of-00003.safetensors",
32
+ "backbone.blocks.1.pre_norm.scale": "model-00001-of-00003.safetensors",
33
+ "backbone.blocks.1.projections.bias": "model-00001-of-00003.safetensors",
34
+ "backbone.blocks.1.projections.weight": "model-00001-of-00003.safetensors",
35
+ "backbone.blocks.10.filter.D": "model-00001-of-00003.safetensors",
36
+ "backbone.blocks.10.filter.poles": "model-00001-of-00003.safetensors",
37
+ "backbone.blocks.10.filter.residues": "model-00001-of-00003.safetensors",
38
+ "backbone.blocks.10.filter.short_filter_bias": "model-00001-of-00003.safetensors",
39
+ "backbone.blocks.10.filter.short_filter_weight": "model-00001-of-00003.safetensors",
40
+ "backbone.blocks.10.mlp.l1.weight": "model-00001-of-00003.safetensors",
41
+ "backbone.blocks.10.mlp.l2.weight": "model-00001-of-00003.safetensors",
42
+ "backbone.blocks.10.mlp.l3.weight": "model-00001-of-00003.safetensors",
43
+ "backbone.blocks.10.out_filter_dense.bias": "model-00001-of-00003.safetensors",
44
+ "backbone.blocks.10.out_filter_dense.weight": "model-00001-of-00003.safetensors",
45
+ "backbone.blocks.10.post_norm.scale": "model-00001-of-00003.safetensors",
46
+ "backbone.blocks.10.pre_norm.scale": "model-00001-of-00003.safetensors",
47
+ "backbone.blocks.10.projections.bias": "model-00001-of-00003.safetensors",
48
+ "backbone.blocks.10.projections.weight": "model-00001-of-00003.safetensors",
49
+ "backbone.blocks.11.filter.D": "model-00001-of-00003.safetensors",
50
+ "backbone.blocks.11.filter.poles": "model-00001-of-00003.safetensors",
51
+ "backbone.blocks.11.filter.residues": "model-00001-of-00003.safetensors",
52
+ "backbone.blocks.11.filter.short_filter_bias": "model-00001-of-00003.safetensors",
53
+ "backbone.blocks.11.filter.short_filter_weight": "model-00001-of-00003.safetensors",
54
+ "backbone.blocks.11.mlp.l1.weight": "model-00001-of-00003.safetensors",
55
+ "backbone.blocks.11.mlp.l2.weight": "model-00001-of-00003.safetensors",
56
+ "backbone.blocks.11.mlp.l3.weight": "model-00001-of-00003.safetensors",
57
+ "backbone.blocks.11.out_filter_dense.bias": "model-00001-of-00003.safetensors",
58
+ "backbone.blocks.11.out_filter_dense.weight": "model-00001-of-00003.safetensors",
59
+ "backbone.blocks.11.post_norm.scale": "model-00001-of-00003.safetensors",
60
+ "backbone.blocks.11.pre_norm.scale": "model-00001-of-00003.safetensors",
61
+ "backbone.blocks.11.projections.bias": "model-00001-of-00003.safetensors",
62
+ "backbone.blocks.11.projections.weight": "model-00001-of-00003.safetensors",
63
+ "backbone.blocks.12.filter.D": "model-00001-of-00003.safetensors",
64
+ "backbone.blocks.12.filter.poles": "model-00001-of-00003.safetensors",
65
+ "backbone.blocks.12.filter.residues": "model-00001-of-00003.safetensors",
66
+ "backbone.blocks.12.filter.short_filter_bias": "model-00001-of-00003.safetensors",
67
+ "backbone.blocks.12.filter.short_filter_weight": "model-00001-of-00003.safetensors",
68
+ "backbone.blocks.12.mlp.l1.weight": "model-00002-of-00003.safetensors",
69
+ "backbone.blocks.12.mlp.l2.weight": "model-00002-of-00003.safetensors",
70
+ "backbone.blocks.12.mlp.l3.weight": "model-00002-of-00003.safetensors",
71
+ "backbone.blocks.12.out_filter_dense.bias": "model-00001-of-00003.safetensors",
72
+ "backbone.blocks.12.out_filter_dense.weight": "model-00001-of-00003.safetensors",
73
+ "backbone.blocks.12.post_norm.scale": "model-00001-of-00003.safetensors",
74
+ "backbone.blocks.12.pre_norm.scale": "model-00001-of-00003.safetensors",
75
+ "backbone.blocks.12.projections.bias": "model-00001-of-00003.safetensors",
76
+ "backbone.blocks.12.projections.weight": "model-00001-of-00003.safetensors",
77
+ "backbone.blocks.13.filter.D": "model-00002-of-00003.safetensors",
78
+ "backbone.blocks.13.filter.poles": "model-00001-of-00003.safetensors",
79
+ "backbone.blocks.13.filter.residues": "model-00001-of-00003.safetensors",
80
+ "backbone.blocks.13.filter.short_filter_bias": "model-00002-of-00003.safetensors",
81
+ "backbone.blocks.13.filter.short_filter_weight": "model-00002-of-00003.safetensors",
82
+ "backbone.blocks.13.mlp.l1.weight": "model-00002-of-00003.safetensors",
83
+ "backbone.blocks.13.mlp.l2.weight": "model-00002-of-00003.safetensors",
84
+ "backbone.blocks.13.mlp.l3.weight": "model-00002-of-00003.safetensors",
85
+ "backbone.blocks.13.out_filter_dense.bias": "model-00002-of-00003.safetensors",
86
+ "backbone.blocks.13.out_filter_dense.weight": "model-00002-of-00003.safetensors",
87
+ "backbone.blocks.13.post_norm.scale": "model-00002-of-00003.safetensors",
88
+ "backbone.blocks.13.pre_norm.scale": "model-00002-of-00003.safetensors",
89
+ "backbone.blocks.13.projections.bias": "model-00002-of-00003.safetensors",
90
+ "backbone.blocks.13.projections.weight": "model-00002-of-00003.safetensors",
91
+ "backbone.blocks.14.filter.D": "model-00002-of-00003.safetensors",
92
+ "backbone.blocks.14.filter.poles": "model-00001-of-00003.safetensors",
93
+ "backbone.blocks.14.filter.residues": "model-00001-of-00003.safetensors",
94
+ "backbone.blocks.14.filter.short_filter_bias": "model-00002-of-00003.safetensors",
95
+ "backbone.blocks.14.filter.short_filter_weight": "model-00002-of-00003.safetensors",
96
+ "backbone.blocks.14.mlp.l1.weight": "model-00002-of-00003.safetensors",
97
+ "backbone.blocks.14.mlp.l2.weight": "model-00002-of-00003.safetensors",
98
+ "backbone.blocks.14.mlp.l3.weight": "model-00002-of-00003.safetensors",
99
+ "backbone.blocks.14.out_filter_dense.bias": "model-00002-of-00003.safetensors",
100
+ "backbone.blocks.14.out_filter_dense.weight": "model-00002-of-00003.safetensors",
101
+ "backbone.blocks.14.post_norm.scale": "model-00002-of-00003.safetensors",
102
+ "backbone.blocks.14.pre_norm.scale": "model-00002-of-00003.safetensors",
103
+ "backbone.blocks.14.projections.bias": "model-00002-of-00003.safetensors",
104
+ "backbone.blocks.14.projections.weight": "model-00002-of-00003.safetensors",
105
+ "backbone.blocks.15.filter.D": "model-00002-of-00003.safetensors",
106
+ "backbone.blocks.15.filter.poles": "model-00001-of-00003.safetensors",
107
+ "backbone.blocks.15.filter.residues": "model-00001-of-00003.safetensors",
108
+ "backbone.blocks.15.filter.short_filter_bias": "model-00002-of-00003.safetensors",
109
+ "backbone.blocks.15.filter.short_filter_weight": "model-00002-of-00003.safetensors",
110
+ "backbone.blocks.15.mlp.l1.weight": "model-00002-of-00003.safetensors",
111
+ "backbone.blocks.15.mlp.l2.weight": "model-00002-of-00003.safetensors",
112
+ "backbone.blocks.15.mlp.l3.weight": "model-00002-of-00003.safetensors",
113
+ "backbone.blocks.15.out_filter_dense.bias": "model-00002-of-00003.safetensors",
114
+ "backbone.blocks.15.out_filter_dense.weight": "model-00002-of-00003.safetensors",
115
+ "backbone.blocks.15.post_norm.scale": "model-00002-of-00003.safetensors",
116
+ "backbone.blocks.15.pre_norm.scale": "model-00002-of-00003.safetensors",
117
+ "backbone.blocks.15.projections.bias": "model-00002-of-00003.safetensors",
118
+ "backbone.blocks.15.projections.weight": "model-00002-of-00003.safetensors",
119
+ "backbone.blocks.16.inner_mha_cls.Wqkv.bias": "model-00002-of-00003.safetensors",
120
+ "backbone.blocks.16.inner_mha_cls.Wqkv.weight": "model-00002-of-00003.safetensors",
121
+ "backbone.blocks.16.inner_mha_cls.out_proj.bias": "model-00002-of-00003.safetensors",
122
+ "backbone.blocks.16.inner_mha_cls.out_proj.weight": "model-00002-of-00003.safetensors",
123
+ "backbone.blocks.16.inner_mha_cls.rotary_emb.inv_freq": "model-00002-of-00003.safetensors",
124
+ "backbone.blocks.16.mlp.l1.weight": "model-00002-of-00003.safetensors",
125
+ "backbone.blocks.16.mlp.l2.weight": "model-00002-of-00003.safetensors",
126
+ "backbone.blocks.16.mlp.l3.weight": "model-00002-of-00003.safetensors",
127
+ "backbone.blocks.16.post_norm.scale": "model-00002-of-00003.safetensors",
128
+ "backbone.blocks.16.pre_norm.scale": "model-00002-of-00003.safetensors",
129
+ "backbone.blocks.17.filter.D": "model-00002-of-00003.safetensors",
130
+ "backbone.blocks.17.filter.poles": "model-00001-of-00003.safetensors",
131
+ "backbone.blocks.17.filter.residues": "model-00001-of-00003.safetensors",
132
+ "backbone.blocks.17.filter.short_filter_bias": "model-00002-of-00003.safetensors",
133
+ "backbone.blocks.17.filter.short_filter_weight": "model-00002-of-00003.safetensors",
134
+ "backbone.blocks.17.mlp.l1.weight": "model-00002-of-00003.safetensors",
135
+ "backbone.blocks.17.mlp.l2.weight": "model-00002-of-00003.safetensors",
136
+ "backbone.blocks.17.mlp.l3.weight": "model-00002-of-00003.safetensors",
137
+ "backbone.blocks.17.out_filter_dense.bias": "model-00002-of-00003.safetensors",
138
+ "backbone.blocks.17.out_filter_dense.weight": "model-00002-of-00003.safetensors",
139
+ "backbone.blocks.17.post_norm.scale": "model-00002-of-00003.safetensors",
140
+ "backbone.blocks.17.pre_norm.scale": "model-00002-of-00003.safetensors",
141
+ "backbone.blocks.17.projections.bias": "model-00002-of-00003.safetensors",
142
+ "backbone.blocks.17.projections.weight": "model-00002-of-00003.safetensors",
143
+ "backbone.blocks.18.filter.D": "model-00002-of-00003.safetensors",
144
+ "backbone.blocks.18.filter.poles": "model-00001-of-00003.safetensors",
145
+ "backbone.blocks.18.filter.residues": "model-00001-of-00003.safetensors",
146
+ "backbone.blocks.18.filter.short_filter_bias": "model-00002-of-00003.safetensors",
147
+ "backbone.blocks.18.filter.short_filter_weight": "model-00002-of-00003.safetensors",
148
+ "backbone.blocks.18.mlp.l1.weight": "model-00002-of-00003.safetensors",
149
+ "backbone.blocks.18.mlp.l2.weight": "model-00002-of-00003.safetensors",
150
+ "backbone.blocks.18.mlp.l3.weight": "model-00002-of-00003.safetensors",
151
+ "backbone.blocks.18.out_filter_dense.bias": "model-00002-of-00003.safetensors",
152
+ "backbone.blocks.18.out_filter_dense.weight": "model-00002-of-00003.safetensors",
153
+ "backbone.blocks.18.post_norm.scale": "model-00002-of-00003.safetensors",
154
+ "backbone.blocks.18.pre_norm.scale": "model-00002-of-00003.safetensors",
155
+ "backbone.blocks.18.projections.bias": "model-00002-of-00003.safetensors",
156
+ "backbone.blocks.18.projections.weight": "model-00002-of-00003.safetensors",
157
+ "backbone.blocks.19.filter.D": "model-00002-of-00003.safetensors",
158
+ "backbone.blocks.19.filter.poles": "model-00001-of-00003.safetensors",
159
+ "backbone.blocks.19.filter.residues": "model-00001-of-00003.safetensors",
160
+ "backbone.blocks.19.filter.short_filter_bias": "model-00002-of-00003.safetensors",
161
+ "backbone.blocks.19.filter.short_filter_weight": "model-00002-of-00003.safetensors",
162
+ "backbone.blocks.19.mlp.l1.weight": "model-00002-of-00003.safetensors",
163
+ "backbone.blocks.19.mlp.l2.weight": "model-00002-of-00003.safetensors",
164
+ "backbone.blocks.19.mlp.l3.weight": "model-00002-of-00003.safetensors",
165
+ "backbone.blocks.19.out_filter_dense.bias": "model-00002-of-00003.safetensors",
166
+ "backbone.blocks.19.out_filter_dense.weight": "model-00002-of-00003.safetensors",
167
+ "backbone.blocks.19.post_norm.scale": "model-00002-of-00003.safetensors",
168
+ "backbone.blocks.19.pre_norm.scale": "model-00002-of-00003.safetensors",
169
+ "backbone.blocks.19.projections.bias": "model-00002-of-00003.safetensors",
170
+ "backbone.blocks.19.projections.weight": "model-00002-of-00003.safetensors",
171
+ "backbone.blocks.2.filter.D": "model-00001-of-00003.safetensors",
172
+ "backbone.blocks.2.filter.poles": "model-00001-of-00003.safetensors",
173
+ "backbone.blocks.2.filter.residues": "model-00001-of-00003.safetensors",
174
+ "backbone.blocks.2.filter.short_filter_bias": "model-00001-of-00003.safetensors",
175
+ "backbone.blocks.2.filter.short_filter_weight": "model-00001-of-00003.safetensors",
176
+ "backbone.blocks.2.mlp.l1.weight": "model-00001-of-00003.safetensors",
177
+ "backbone.blocks.2.mlp.l2.weight": "model-00001-of-00003.safetensors",
178
+ "backbone.blocks.2.mlp.l3.weight": "model-00001-of-00003.safetensors",
179
+ "backbone.blocks.2.out_filter_dense.bias": "model-00001-of-00003.safetensors",
180
+ "backbone.blocks.2.out_filter_dense.weight": "model-00001-of-00003.safetensors",
181
+ "backbone.blocks.2.post_norm.scale": "model-00001-of-00003.safetensors",
182
+ "backbone.blocks.2.pre_norm.scale": "model-00001-of-00003.safetensors",
183
+ "backbone.blocks.2.projections.bias": "model-00001-of-00003.safetensors",
184
+ "backbone.blocks.2.projections.weight": "model-00001-of-00003.safetensors",
185
+ "backbone.blocks.20.filter.D": "model-00002-of-00003.safetensors",
186
+ "backbone.blocks.20.filter.poles": "model-00001-of-00003.safetensors",
187
+ "backbone.blocks.20.filter.residues": "model-00001-of-00003.safetensors",
188
+ "backbone.blocks.20.filter.short_filter_bias": "model-00002-of-00003.safetensors",
189
+ "backbone.blocks.20.filter.short_filter_weight": "model-00002-of-00003.safetensors",
190
+ "backbone.blocks.20.mlp.l1.weight": "model-00002-of-00003.safetensors",
191
+ "backbone.blocks.20.mlp.l2.weight": "model-00002-of-00003.safetensors",
192
+ "backbone.blocks.20.mlp.l3.weight": "model-00002-of-00003.safetensors",
193
+ "backbone.blocks.20.out_filter_dense.bias": "model-00002-of-00003.safetensors",
194
+ "backbone.blocks.20.out_filter_dense.weight": "model-00002-of-00003.safetensors",
195
+ "backbone.blocks.20.post_norm.scale": "model-00002-of-00003.safetensors",
196
+ "backbone.blocks.20.pre_norm.scale": "model-00002-of-00003.safetensors",
197
+ "backbone.blocks.20.projections.bias": "model-00002-of-00003.safetensors",
198
+ "backbone.blocks.20.projections.weight": "model-00002-of-00003.safetensors",
199
+ "backbone.blocks.21.filter.D": "model-00002-of-00003.safetensors",
200
+ "backbone.blocks.21.filter.poles": "model-00001-of-00003.safetensors",
201
+ "backbone.blocks.21.filter.residues": "model-00001-of-00003.safetensors",
202
+ "backbone.blocks.21.filter.short_filter_bias": "model-00002-of-00003.safetensors",
203
+ "backbone.blocks.21.filter.short_filter_weight": "model-00002-of-00003.safetensors",
204
+ "backbone.blocks.21.mlp.l1.weight": "model-00002-of-00003.safetensors",
205
+ "backbone.blocks.21.mlp.l2.weight": "model-00002-of-00003.safetensors",
206
+ "backbone.blocks.21.mlp.l3.weight": "model-00002-of-00003.safetensors",
207
+ "backbone.blocks.21.out_filter_dense.bias": "model-00002-of-00003.safetensors",
208
+ "backbone.blocks.21.out_filter_dense.weight": "model-00002-of-00003.safetensors",
209
+ "backbone.blocks.21.post_norm.scale": "model-00002-of-00003.safetensors",
210
+ "backbone.blocks.21.pre_norm.scale": "model-00002-of-00003.safetensors",
211
+ "backbone.blocks.21.projections.bias": "model-00002-of-00003.safetensors",
212
+ "backbone.blocks.21.projections.weight": "model-00002-of-00003.safetensors",
213
+ "backbone.blocks.22.filter.D": "model-00002-of-00003.safetensors",
214
+ "backbone.blocks.22.filter.poles": "model-00001-of-00003.safetensors",
215
+ "backbone.blocks.22.filter.residues": "model-00001-of-00003.safetensors",
216
+ "backbone.blocks.22.filter.short_filter_bias": "model-00002-of-00003.safetensors",
217
+ "backbone.blocks.22.filter.short_filter_weight": "model-00002-of-00003.safetensors",
218
+ "backbone.blocks.22.mlp.l1.weight": "model-00002-of-00003.safetensors",
219
+ "backbone.blocks.22.mlp.l2.weight": "model-00002-of-00003.safetensors",
220
+ "backbone.blocks.22.mlp.l3.weight": "model-00002-of-00003.safetensors",
221
+ "backbone.blocks.22.out_filter_dense.bias": "model-00002-of-00003.safetensors",
222
+ "backbone.blocks.22.out_filter_dense.weight": "model-00002-of-00003.safetensors",
223
+ "backbone.blocks.22.post_norm.scale": "model-00002-of-00003.safetensors",
224
+ "backbone.blocks.22.pre_norm.scale": "model-00002-of-00003.safetensors",
225
+ "backbone.blocks.22.projections.bias": "model-00002-of-00003.safetensors",
226
+ "backbone.blocks.22.projections.weight": "model-00002-of-00003.safetensors",
227
+ "backbone.blocks.23.filter.D": "model-00002-of-00003.safetensors",
228
+ "backbone.blocks.23.filter.poles": "model-00001-of-00003.safetensors",
229
+ "backbone.blocks.23.filter.residues": "model-00001-of-00003.safetensors",
230
+ "backbone.blocks.23.filter.short_filter_bias": "model-00002-of-00003.safetensors",
231
+ "backbone.blocks.23.filter.short_filter_weight": "model-00002-of-00003.safetensors",
232
+ "backbone.blocks.23.mlp.l1.weight": "model-00002-of-00003.safetensors",
233
+ "backbone.blocks.23.mlp.l2.weight": "model-00002-of-00003.safetensors",
234
+ "backbone.blocks.23.mlp.l3.weight": "model-00002-of-00003.safetensors",
235
+ "backbone.blocks.23.out_filter_dense.bias": "model-00002-of-00003.safetensors",
236
+ "backbone.blocks.23.out_filter_dense.weight": "model-00002-of-00003.safetensors",
237
+ "backbone.blocks.23.post_norm.scale": "model-00002-of-00003.safetensors",
238
+ "backbone.blocks.23.pre_norm.scale": "model-00002-of-00003.safetensors",
239
+ "backbone.blocks.23.projections.bias": "model-00002-of-00003.safetensors",
240
+ "backbone.blocks.23.projections.weight": "model-00002-of-00003.safetensors",
241
+ "backbone.blocks.24.inner_mha_cls.Wqkv.bias": "model-00002-of-00003.safetensors",
242
+ "backbone.blocks.24.inner_mha_cls.Wqkv.weight": "model-00002-of-00003.safetensors",
243
+ "backbone.blocks.24.inner_mha_cls.out_proj.bias": "model-00002-of-00003.safetensors",
244
+ "backbone.blocks.24.inner_mha_cls.out_proj.weight": "model-00002-of-00003.safetensors",
245
+ "backbone.blocks.24.inner_mha_cls.rotary_emb.inv_freq": "model-00002-of-00003.safetensors",
246
+ "backbone.blocks.24.mlp.l1.weight": "model-00002-of-00003.safetensors",
247
+ "backbone.blocks.24.mlp.l2.weight": "model-00003-of-00003.safetensors",
248
+ "backbone.blocks.24.mlp.l3.weight": "model-00003-of-00003.safetensors",
249
+ "backbone.blocks.24.post_norm.scale": "model-00002-of-00003.safetensors",
250
+ "backbone.blocks.24.pre_norm.scale": "model-00002-of-00003.safetensors",
251
+ "backbone.blocks.25.filter.D": "model-00003-of-00003.safetensors",
252
+ "backbone.blocks.25.filter.poles": "model-00002-of-00003.safetensors",
253
+ "backbone.blocks.25.filter.residues": "model-00002-of-00003.safetensors",
254
+ "backbone.blocks.25.filter.short_filter_bias": "model-00003-of-00003.safetensors",
255
+ "backbone.blocks.25.filter.short_filter_weight": "model-00003-of-00003.safetensors",
256
+ "backbone.blocks.25.mlp.l1.weight": "model-00003-of-00003.safetensors",
257
+ "backbone.blocks.25.mlp.l2.weight": "model-00003-of-00003.safetensors",
258
+ "backbone.blocks.25.mlp.l3.weight": "model-00003-of-00003.safetensors",
259
+ "backbone.blocks.25.out_filter_dense.bias": "model-00003-of-00003.safetensors",
260
+ "backbone.blocks.25.out_filter_dense.weight": "model-00003-of-00003.safetensors",
261
+ "backbone.blocks.25.post_norm.scale": "model-00003-of-00003.safetensors",
262
+ "backbone.blocks.25.pre_norm.scale": "model-00003-of-00003.safetensors",
263
+ "backbone.blocks.25.projections.bias": "model-00003-of-00003.safetensors",
264
+ "backbone.blocks.25.projections.weight": "model-00003-of-00003.safetensors",
265
+ "backbone.blocks.26.filter.D": "model-00003-of-00003.safetensors",
266
+ "backbone.blocks.26.filter.poles": "model-00002-of-00003.safetensors",
267
+ "backbone.blocks.26.filter.residues": "model-00002-of-00003.safetensors",
268
+ "backbone.blocks.26.filter.short_filter_bias": "model-00003-of-00003.safetensors",
269
+ "backbone.blocks.26.filter.short_filter_weight": "model-00003-of-00003.safetensors",
270
+ "backbone.blocks.26.mlp.l1.weight": "model-00003-of-00003.safetensors",
271
+ "backbone.blocks.26.mlp.l2.weight": "model-00003-of-00003.safetensors",
272
+ "backbone.blocks.26.mlp.l3.weight": "model-00003-of-00003.safetensors",
273
+ "backbone.blocks.26.out_filter_dense.bias": "model-00003-of-00003.safetensors",
274
+ "backbone.blocks.26.out_filter_dense.weight": "model-00003-of-00003.safetensors",
275
+ "backbone.blocks.26.post_norm.scale": "model-00003-of-00003.safetensors",
276
+ "backbone.blocks.26.pre_norm.scale": "model-00003-of-00003.safetensors",
277
+ "backbone.blocks.26.projections.bias": "model-00003-of-00003.safetensors",
278
+ "backbone.blocks.26.projections.weight": "model-00003-of-00003.safetensors",
279
+ "backbone.blocks.27.filter.D": "model-00003-of-00003.safetensors",
280
+ "backbone.blocks.27.filter.poles": "model-00002-of-00003.safetensors",
281
+ "backbone.blocks.27.filter.residues": "model-00002-of-00003.safetensors",
282
+ "backbone.blocks.27.filter.short_filter_bias": "model-00003-of-00003.safetensors",
283
+ "backbone.blocks.27.filter.short_filter_weight": "model-00003-of-00003.safetensors",
284
+ "backbone.blocks.27.mlp.l1.weight": "model-00003-of-00003.safetensors",
285
+ "backbone.blocks.27.mlp.l2.weight": "model-00003-of-00003.safetensors",
286
+ "backbone.blocks.27.mlp.l3.weight": "model-00003-of-00003.safetensors",
287
+ "backbone.blocks.27.out_filter_dense.bias": "model-00003-of-00003.safetensors",
288
+ "backbone.blocks.27.out_filter_dense.weight": "model-00003-of-00003.safetensors",
289
+ "backbone.blocks.27.post_norm.scale": "model-00003-of-00003.safetensors",
290
+ "backbone.blocks.27.pre_norm.scale": "model-00003-of-00003.safetensors",
291
+ "backbone.blocks.27.projections.bias": "model-00003-of-00003.safetensors",
292
+ "backbone.blocks.27.projections.weight": "model-00003-of-00003.safetensors",
293
+ "backbone.blocks.28.filter.D": "model-00003-of-00003.safetensors",
294
+ "backbone.blocks.28.filter.poles": "model-00002-of-00003.safetensors",
295
+ "backbone.blocks.28.filter.residues": "model-00002-of-00003.safetensors",
296
+ "backbone.blocks.28.filter.short_filter_bias": "model-00003-of-00003.safetensors",
297
+ "backbone.blocks.28.filter.short_filter_weight": "model-00003-of-00003.safetensors",
298
+ "backbone.blocks.28.mlp.l1.weight": "model-00003-of-00003.safetensors",
299
+ "backbone.blocks.28.mlp.l2.weight": "model-00003-of-00003.safetensors",
300
+ "backbone.blocks.28.mlp.l3.weight": "model-00003-of-00003.safetensors",
301
+ "backbone.blocks.28.out_filter_dense.bias": "model-00003-of-00003.safetensors",
302
+ "backbone.blocks.28.out_filter_dense.weight": "model-00003-of-00003.safetensors",
303
+ "backbone.blocks.28.post_norm.scale": "model-00003-of-00003.safetensors",
304
+ "backbone.blocks.28.pre_norm.scale": "model-00003-of-00003.safetensors",
305
+ "backbone.blocks.28.projections.bias": "model-00003-of-00003.safetensors",
306
+ "backbone.blocks.28.projections.weight": "model-00003-of-00003.safetensors",
307
+ "backbone.blocks.29.filter.D": "model-00003-of-00003.safetensors",
308
+ "backbone.blocks.29.filter.poles": "model-00002-of-00003.safetensors",
309
+ "backbone.blocks.29.filter.residues": "model-00002-of-00003.safetensors",
310
+ "backbone.blocks.29.filter.short_filter_bias": "model-00003-of-00003.safetensors",
311
+ "backbone.blocks.29.filter.short_filter_weight": "model-00003-of-00003.safetensors",
312
+ "backbone.blocks.29.mlp.l1.weight": "model-00003-of-00003.safetensors",
313
+ "backbone.blocks.29.mlp.l2.weight": "model-00003-of-00003.safetensors",
314
+ "backbone.blocks.29.mlp.l3.weight": "model-00003-of-00003.safetensors",
315
+ "backbone.blocks.29.out_filter_dense.bias": "model-00003-of-00003.safetensors",
316
+ "backbone.blocks.29.out_filter_dense.weight": "model-00003-of-00003.safetensors",
317
+ "backbone.blocks.29.post_norm.scale": "model-00003-of-00003.safetensors",
318
+ "backbone.blocks.29.pre_norm.scale": "model-00003-of-00003.safetensors",
319
+ "backbone.blocks.29.projections.bias": "model-00003-of-00003.safetensors",
320
+ "backbone.blocks.29.projections.weight": "model-00003-of-00003.safetensors",
321
+ "backbone.blocks.3.filter.D": "model-00001-of-00003.safetensors",
322
+ "backbone.blocks.3.filter.poles": "model-00001-of-00003.safetensors",
323
+ "backbone.blocks.3.filter.residues": "model-00001-of-00003.safetensors",
324
+ "backbone.blocks.3.filter.short_filter_bias": "model-00001-of-00003.safetensors",
325
+ "backbone.blocks.3.filter.short_filter_weight": "model-00001-of-00003.safetensors",
326
+ "backbone.blocks.3.mlp.l1.weight": "model-00001-of-00003.safetensors",
327
+ "backbone.blocks.3.mlp.l2.weight": "model-00001-of-00003.safetensors",
328
+ "backbone.blocks.3.mlp.l3.weight": "model-00001-of-00003.safetensors",
329
+ "backbone.blocks.3.out_filter_dense.bias": "model-00001-of-00003.safetensors",
330
+ "backbone.blocks.3.out_filter_dense.weight": "model-00001-of-00003.safetensors",
331
+ "backbone.blocks.3.post_norm.scale": "model-00001-of-00003.safetensors",
332
+ "backbone.blocks.3.pre_norm.scale": "model-00001-of-00003.safetensors",
333
+ "backbone.blocks.3.projections.bias": "model-00001-of-00003.safetensors",
334
+ "backbone.blocks.3.projections.weight": "model-00001-of-00003.safetensors",
335
+ "backbone.blocks.30.filter.D": "model-00003-of-00003.safetensors",
336
+ "backbone.blocks.30.filter.poles": "model-00002-of-00003.safetensors",
337
+ "backbone.blocks.30.filter.residues": "model-00002-of-00003.safetensors",
338
+ "backbone.blocks.30.filter.short_filter_bias": "model-00003-of-00003.safetensors",
339
+ "backbone.blocks.30.filter.short_filter_weight": "model-00003-of-00003.safetensors",
340
+ "backbone.blocks.30.mlp.l1.weight": "model-00003-of-00003.safetensors",
341
+ "backbone.blocks.30.mlp.l2.weight": "model-00003-of-00003.safetensors",
342
+ "backbone.blocks.30.mlp.l3.weight": "model-00003-of-00003.safetensors",
343
+ "backbone.blocks.30.out_filter_dense.bias": "model-00003-of-00003.safetensors",
344
+ "backbone.blocks.30.out_filter_dense.weight": "model-00003-of-00003.safetensors",
345
+ "backbone.blocks.30.post_norm.scale": "model-00003-of-00003.safetensors",
346
+ "backbone.blocks.30.pre_norm.scale": "model-00003-of-00003.safetensors",
347
+ "backbone.blocks.30.projections.bias": "model-00003-of-00003.safetensors",
348
+ "backbone.blocks.30.projections.weight": "model-00003-of-00003.safetensors",
349
+ "backbone.blocks.31.filter.D": "model-00003-of-00003.safetensors",
350
+ "backbone.blocks.31.filter.poles": "model-00002-of-00003.safetensors",
351
+ "backbone.blocks.31.filter.residues": "model-00002-of-00003.safetensors",
352
+ "backbone.blocks.31.filter.short_filter_bias": "model-00003-of-00003.safetensors",
353
+ "backbone.blocks.31.filter.short_filter_weight": "model-00003-of-00003.safetensors",
354
+ "backbone.blocks.31.mlp.l1.weight": "model-00003-of-00003.safetensors",
355
+ "backbone.blocks.31.mlp.l2.weight": "model-00003-of-00003.safetensors",
356
+ "backbone.blocks.31.mlp.l3.weight": "model-00003-of-00003.safetensors",
357
+ "backbone.blocks.31.out_filter_dense.bias": "model-00003-of-00003.safetensors",
358
+ "backbone.blocks.31.out_filter_dense.weight": "model-00003-of-00003.safetensors",
359
+ "backbone.blocks.31.post_norm.scale": "model-00003-of-00003.safetensors",
360
+ "backbone.blocks.31.pre_norm.scale": "model-00003-of-00003.safetensors",
361
+ "backbone.blocks.31.projections.bias": "model-00003-of-00003.safetensors",
362
+ "backbone.blocks.31.projections.weight": "model-00003-of-00003.safetensors",
363
+ "backbone.blocks.4.filter.D": "model-00001-of-00003.safetensors",
364
+ "backbone.blocks.4.filter.poles": "model-00001-of-00003.safetensors",
365
+ "backbone.blocks.4.filter.residues": "model-00001-of-00003.safetensors",
366
+ "backbone.blocks.4.filter.short_filter_bias": "model-00001-of-00003.safetensors",
367
+ "backbone.blocks.4.filter.short_filter_weight": "model-00001-of-00003.safetensors",
368
+ "backbone.blocks.4.mlp.l1.weight": "model-00001-of-00003.safetensors",
369
+ "backbone.blocks.4.mlp.l2.weight": "model-00001-of-00003.safetensors",
370
+ "backbone.blocks.4.mlp.l3.weight": "model-00001-of-00003.safetensors",
371
+ "backbone.blocks.4.out_filter_dense.bias": "model-00001-of-00003.safetensors",
372
+ "backbone.blocks.4.out_filter_dense.weight": "model-00001-of-00003.safetensors",
373
+ "backbone.blocks.4.post_norm.scale": "model-00001-of-00003.safetensors",
374
+ "backbone.blocks.4.pre_norm.scale": "model-00001-of-00003.safetensors",
375
+ "backbone.blocks.4.projections.bias": "model-00001-of-00003.safetensors",
376
+ "backbone.blocks.4.projections.weight": "model-00001-of-00003.safetensors",
377
+ "backbone.blocks.5.filter.D": "model-00001-of-00003.safetensors",
378
+ "backbone.blocks.5.filter.poles": "model-00001-of-00003.safetensors",
379
+ "backbone.blocks.5.filter.residues": "model-00001-of-00003.safetensors",
380
+ "backbone.blocks.5.filter.short_filter_bias": "model-00001-of-00003.safetensors",
381
+ "backbone.blocks.5.filter.short_filter_weight": "model-00001-of-00003.safetensors",
382
+ "backbone.blocks.5.mlp.l1.weight": "model-00001-of-00003.safetensors",
383
+ "backbone.blocks.5.mlp.l2.weight": "model-00001-of-00003.safetensors",
384
+ "backbone.blocks.5.mlp.l3.weight": "model-00001-of-00003.safetensors",
385
+ "backbone.blocks.5.out_filter_dense.bias": "model-00001-of-00003.safetensors",
386
+ "backbone.blocks.5.out_filter_dense.weight": "model-00001-of-00003.safetensors",
387
+ "backbone.blocks.5.post_norm.scale": "model-00001-of-00003.safetensors",
388
+ "backbone.blocks.5.pre_norm.scale": "model-00001-of-00003.safetensors",
389
+ "backbone.blocks.5.projections.bias": "model-00001-of-00003.safetensors",
390
+ "backbone.blocks.5.projections.weight": "model-00001-of-00003.safetensors",
391
+ "backbone.blocks.6.filter.D": "model-00001-of-00003.safetensors",
392
+ "backbone.blocks.6.filter.poles": "model-00001-of-00003.safetensors",
393
+ "backbone.blocks.6.filter.residues": "model-00001-of-00003.safetensors",
394
+ "backbone.blocks.6.filter.short_filter_bias": "model-00001-of-00003.safetensors",
395
+ "backbone.blocks.6.filter.short_filter_weight": "model-00001-of-00003.safetensors",
396
+ "backbone.blocks.6.mlp.l1.weight": "model-00001-of-00003.safetensors",
397
+ "backbone.blocks.6.mlp.l2.weight": "model-00001-of-00003.safetensors",
398
+ "backbone.blocks.6.mlp.l3.weight": "model-00001-of-00003.safetensors",
399
+ "backbone.blocks.6.out_filter_dense.bias": "model-00001-of-00003.safetensors",
400
+ "backbone.blocks.6.out_filter_dense.weight": "model-00001-of-00003.safetensors",
401
+ "backbone.blocks.6.post_norm.scale": "model-00001-of-00003.safetensors",
402
+ "backbone.blocks.6.pre_norm.scale": "model-00001-of-00003.safetensors",
403
+ "backbone.blocks.6.projections.bias": "model-00001-of-00003.safetensors",
404
+ "backbone.blocks.6.projections.weight": "model-00001-of-00003.safetensors",
405
+ "backbone.blocks.7.filter.D": "model-00001-of-00003.safetensors",
406
+ "backbone.blocks.7.filter.poles": "model-00001-of-00003.safetensors",
407
+ "backbone.blocks.7.filter.residues": "model-00001-of-00003.safetensors",
408
+ "backbone.blocks.7.filter.short_filter_bias": "model-00001-of-00003.safetensors",
409
+ "backbone.blocks.7.filter.short_filter_weight": "model-00001-of-00003.safetensors",
410
+ "backbone.blocks.7.mlp.l1.weight": "model-00001-of-00003.safetensors",
411
+ "backbone.blocks.7.mlp.l2.weight": "model-00001-of-00003.safetensors",
412
+ "backbone.blocks.7.mlp.l3.weight": "model-00001-of-00003.safetensors",
413
+ "backbone.blocks.7.out_filter_dense.bias": "model-00001-of-00003.safetensors",
414
+ "backbone.blocks.7.out_filter_dense.weight": "model-00001-of-00003.safetensors",
415
+ "backbone.blocks.7.post_norm.scale": "model-00001-of-00003.safetensors",
416
+ "backbone.blocks.7.pre_norm.scale": "model-00001-of-00003.safetensors",
417
+ "backbone.blocks.7.projections.bias": "model-00001-of-00003.safetensors",
418
+ "backbone.blocks.7.projections.weight": "model-00001-of-00003.safetensors",
419
+ "backbone.blocks.8.inner_mha_cls.Wqkv.bias": "model-00001-of-00003.safetensors",
420
+ "backbone.blocks.8.inner_mha_cls.Wqkv.weight": "model-00001-of-00003.safetensors",
421
+ "backbone.blocks.8.inner_mha_cls.out_proj.bias": "model-00001-of-00003.safetensors",
422
+ "backbone.blocks.8.inner_mha_cls.out_proj.weight": "model-00001-of-00003.safetensors",
423
+ "backbone.blocks.8.inner_mha_cls.rotary_emb.inv_freq": "model-00001-of-00003.safetensors",
424
+ "backbone.blocks.8.mlp.l1.weight": "model-00001-of-00003.safetensors",
425
+ "backbone.blocks.8.mlp.l2.weight": "model-00001-of-00003.safetensors",
426
+ "backbone.blocks.8.mlp.l3.weight": "model-00001-of-00003.safetensors",
427
+ "backbone.blocks.8.post_norm.scale": "model-00001-of-00003.safetensors",
428
+ "backbone.blocks.8.pre_norm.scale": "model-00001-of-00003.safetensors",
429
+ "backbone.blocks.9.filter.D": "model-00001-of-00003.safetensors",
430
+ "backbone.blocks.9.filter.poles": "model-00001-of-00003.safetensors",
431
+ "backbone.blocks.9.filter.residues": "model-00001-of-00003.safetensors",
432
+ "backbone.blocks.9.filter.short_filter_bias": "model-00001-of-00003.safetensors",
433
+ "backbone.blocks.9.filter.short_filter_weight": "model-00001-of-00003.safetensors",
434
+ "backbone.blocks.9.mlp.l1.weight": "model-00001-of-00003.safetensors",
435
+ "backbone.blocks.9.mlp.l2.weight": "model-00001-of-00003.safetensors",
436
+ "backbone.blocks.9.mlp.l3.weight": "model-00001-of-00003.safetensors",
437
+ "backbone.blocks.9.out_filter_dense.bias": "model-00001-of-00003.safetensors",
438
+ "backbone.blocks.9.out_filter_dense.weight": "model-00001-of-00003.safetensors",
439
+ "backbone.blocks.9.post_norm.scale": "model-00001-of-00003.safetensors",
440
+ "backbone.blocks.9.pre_norm.scale": "model-00001-of-00003.safetensors",
441
+ "backbone.blocks.9.projections.bias": "model-00001-of-00003.safetensors",
442
+ "backbone.blocks.9.projections.weight": "model-00001-of-00003.safetensors",
443
+ "backbone.embedding_layer.weight": "model-00001-of-00003.safetensors",
444
+ "backbone.norm.scale": "model-00001-of-00003.safetensors"
445
+ }
446
+ }
modeling_evo1.py ADDED
@@ -0,0 +1,764 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Minimal Evo1 (StripedHyena) HuggingFace port.
2
+
3
+ This module is a refactor of togethercomputer/evo-1-131k-base@1.1_fix's
4
+ ``modeling_hyena.py`` + ``model.py`` into a single self-contained file with:
5
+
6
+ * ``output_hidden_states`` and ``output_attentions`` plumbed end-to-end,
7
+ * ``attn_implementation`` switch (``eager`` / ``sdpa`` / ``flash_attention_2``),
8
+ * ``Evo1Model`` (no LM head, ``BaseModelOutputWithPast``) for ``AutoModel``,
9
+ * ``Evo1ForCausalLM`` (with logits, ``CausalLMOutputWithPast``)
10
+ for ``AutoModelForCausalLM``,
11
+ * minimal external imports (only ``torch`` + ``transformers``; ``flash-attn``
12
+ is loaded lazily and only when ``attn_implementation='flash_attention_2'``).
13
+
14
+ Hyena blocks have no attention matrix by construction, so they always emit
15
+ ``None`` in the per-layer ``attentions`` tuple. Attention blocks (layers 8,
16
+ 16, 24 for Evo1) emit the (B, H, T, T) softmax matrix when
17
+ ``output_attentions=True`` (this triggers a one-time fallback from sdpa /
18
+ flash_attention_2 to the eager backend).
19
+ """
20
+
21
+ from __future__ import annotations
22
+
23
+ from typing import Optional, Tuple, Union
24
+
25
+ import torch
26
+ import torch.nn as nn
27
+ import torch.nn.functional as F
28
+ from transformers import PreTrainedModel
29
+ from transformers.generation import GenerationMixin
30
+ from transformers.modeling_outputs import (
31
+ BaseModelOutputWithPast,
32
+ CausalLMOutputWithPast,
33
+ )
34
+ from transformers.utils import logging
35
+
36
+ from .attention import MHA
37
+ from .cache import Evo1Cache, InferenceParams, RecurrentInferenceParams
38
+ from .configuration_evo1 import Evo1Config
39
+ from .engine import HyenaInferenceEngine
40
+ from .layers import ParallelGatedMLP, RMSNorm, VocabParallelEmbedding
41
+ from .rotary import swap_mha_rope
42
+ # dummy import so that trust_remote_code bundles the tokenizer file
43
+ from .tokenization_evo1 import ByteTokenizer # noqa: F401
44
+
45
+ logger = logging.get_logger(__name__)
46
+
47
+
48
+ # =============================================================================
49
+ # Block: attention (used at layers config.attn_layer_idxs)
50
+ # =============================================================================
51
+
52
+
53
+ class AttentionBlock(nn.Module):
54
+ """Pre-norm Transformer block: norm -> MHA -> residual -> norm -> MLP -> residual."""
55
+
56
+ def __init__(self, config, layer_idx) -> None:
57
+ super().__init__()
58
+ self.config = config
59
+ self.layer_idx = layer_idx
60
+ self.pre_norm, self.post_norm = RMSNorm(config), RMSNorm(config)
61
+ self.proj_groups = config.get("proj_groups", 1)
62
+ dtype = config.get("attn_block_dtype", torch.bfloat16)
63
+ mlp_dtype = config.get("mlp_dtype", torch.bfloat16)
64
+ self.num_attention_heads = config.num_attention_heads
65
+ self.hidden_size_per_attention_head = (
66
+ config.hidden_size // config.num_attention_heads
67
+ )
68
+
69
+ attn_impl = getattr(config, "_attn_implementation", "eager")
70
+
71
+ self.inner_mha_cls = MHA(
72
+ embed_dim=config.hidden_size,
73
+ num_heads=config.num_attention_heads,
74
+ num_heads_kv=config.num_attention_heads // self.proj_groups,
75
+ rotary_emb_dim=config.hidden_size // config.num_attention_heads,
76
+ qkv_proj_bias=config.get("qkv_proj_bias", True),
77
+ rotary_emb_base=config.get("rotary_emb_base", 10000),
78
+ causal=True,
79
+ layer_idx=layer_idx,
80
+ out_proj_bias=config.get("mha_out_proj_bias", True),
81
+ attn_implementation=attn_impl,
82
+ ).to(dtype=dtype)
83
+
84
+ if config.get("use_interpolated_rotary_pos_emb", False):
85
+ swap_mha_rope(
86
+ mha=self.inner_mha_cls,
87
+ kwargs_new_rope={
88
+ "scaling_factor": config.get("rotary_emb_scaling_factor", 1.0)
89
+ },
90
+ )
91
+
92
+ if self.config.get("smeared_gqa", False):
93
+ self.inner_mha_cls.num_heads_kv = self.inner_mha_cls.num_heads
94
+ # Make sure the inv_freq buffer round-trips through to_bfloat16/state_dict.
95
+ self.inner_mha_cls.rotary_emb.register_buffer(
96
+ "inv_freq", self.inner_mha_cls.rotary_emb.inv_freq
97
+ )
98
+
99
+ self.mlp = ParallelGatedMLP(config).to(dtype=mlp_dtype)
100
+
101
+ def forward(
102
+ self,
103
+ u: torch.Tensor,
104
+ inference_params=None,
105
+ padding_mask: Optional[torch.Tensor] = None,
106
+ output_attentions: bool = False,
107
+ *args,
108
+ **kwargs,
109
+ ):
110
+ if isinstance(padding_mask, torch.Tensor):
111
+ # Workaround for masking with no qkv bias: this zeros the attended
112
+ # values at pad positions so they don't leak via attention.
113
+ u = u * padding_mask[..., None]
114
+
115
+ attn_out, attn_weights = self.inner_mha_cls(
116
+ self.pre_norm(u),
117
+ inference_params=inference_params,
118
+ output_attentions=output_attentions,
119
+ )
120
+ u = attn_out + u
121
+
122
+ if isinstance(padding_mask, torch.Tensor):
123
+ u = u * padding_mask[..., None]
124
+ u = self.mlp(self.post_norm(u)) + u
125
+ return u, attn_weights
126
+
127
+
128
+ # =============================================================================
129
+ # Block: Hyena (used at all other layers)
130
+ # =============================================================================
131
+
132
+
133
+ class ParallelHyenaFilter(nn.Module):
134
+ def __init__(self, config, layer_idx) -> None:
135
+ super().__init__()
136
+ self.config = config
137
+ self.layer_idx = layer_idx
138
+ self.hyena_filter_groups = config.get(
139
+ "hyena_filter_groups", self.config.hidden_size
140
+ )
141
+
142
+ self.use_flashfft = config.get("use_flashfft", False)
143
+ self.state_size = config.state_size
144
+ self.hidden_size = config.hidden_size
145
+ self.num_filters = config.num_filters
146
+ self.inference_mode = config.get("inference_mode", True)
147
+ self.column_split_hyena = config.get("column_split_hyena", True)
148
+
149
+ assert self.hidden_size % self.num_filters == 0
150
+ assert self.num_filters <= self.hidden_size
151
+
152
+ self.D = nn.Parameter(torch.zeros(self.hidden_size))
153
+
154
+ # heads only used to slice post-FIR projections like the checkpoint
155
+ self.num_attention_heads = config.num_attention_heads
156
+ self.hidden_size_per_attention_head = (
157
+ self.hidden_size // self.num_attention_heads
158
+ )
159
+
160
+ self.short_filter_length = config.short_filter_length
161
+ self.short_filter_weight = nn.Parameter(
162
+ torch.randn(3 * config.hidden_size, 1, config.short_filter_length)
163
+ )
164
+ self.short_filter_bias = (
165
+ nn.Parameter(torch.randn(3 * config.hidden_size))
166
+ if config.short_filter_bias
167
+ else None
168
+ )
169
+
170
+ self.engine = HyenaInferenceEngine(layer_idx=layer_idx)
171
+ self.use_flash_depthwise = config.get("use_flash_depthwise", False)
172
+ self.data_dtype = None
173
+
174
+ if self.use_flash_depthwise:
175
+ # importlib avoids the top-level static-import check that HF's
176
+ # dynamic_module_utils.check_imports performs against the file.
177
+ import importlib
178
+ FlashDepthwiseConv1d = importlib.import_module("flashfftconv").FlashDepthwiseConv1d
179
+ self.fir_fn = FlashDepthwiseConv1d(
180
+ channels=3 * self.hidden_size,
181
+ kernel_size=self.short_filter_length,
182
+ padding=self.short_filter_length - 1,
183
+ weights=self.short_filter_weight,
184
+ bias=self.short_filter_bias,
185
+ device=None,
186
+ dtype=self.config.get("depthwise_dtype", torch.bfloat16),
187
+ )
188
+ else:
189
+ self.fir_fn = F.conv1d
190
+
191
+ self.fftconv_fn = None
192
+ self.long_fir_threshold = config.get("long_fir_threshold", None)
193
+ if self.long_fir_threshold is not None:
194
+ assert self.use_flashfft is False, (
195
+ "long_fir_threshold not compatible with fused flashfft"
196
+ )
197
+
198
+ self.num_systems = self.hidden_size // self.hyena_filter_groups
199
+ poles = torch.randn(self.num_systems, self.state_size, 1, 2)
200
+ poles[..., 0] = 1e-2 * torch.randn(self.num_systems, self.state_size, 1)
201
+ poles[..., 1] = 1e-3 * torch.randn(self.num_systems, self.state_size, 1)
202
+ self.poles = nn.Parameter(poles)
203
+ self.residues = nn.Parameter(
204
+ torch.randn(self.num_systems, self.state_size, 1, 2)
205
+ )
206
+ self.h = None
207
+
208
+ def forward(self, u, inference_params=None, padding_mask=None, *args, **kwargs):
209
+ if (
210
+ inference_params is not None
211
+ and self.layer_idx in inference_params.fir_state_dict.keys()
212
+ ):
213
+ return self.sequential_forward(u, inference_params)
214
+ return self.parallel_forward(u, inference_params, padding_mask)
215
+
216
+ def parallel_forward(self, u, inference_params=None, padding_mask=None):
217
+ L = u.shape[1]
218
+ z_pre, fir_state = self.engine.parallel_fir(
219
+ self.fir_fn,
220
+ u,
221
+ self.short_filter_weight,
222
+ self.short_filter_bias,
223
+ L,
224
+ fir_length=self.short_filter_length,
225
+ inference_params=inference_params,
226
+ padding_mask=padding_mask,
227
+ )
228
+ if inference_params:
229
+ inference_params.fir_state_dict[self.layer_idx] = fir_state
230
+
231
+ if self.h is None:
232
+ h, _, _, _ = self.compute_filter(L, u.device)
233
+ else:
234
+ h = self.h
235
+
236
+ if self.hyena_filter_groups > 1:
237
+ h = h.repeat_interleave(self.hidden_size // self.hyena_filter_groups, 1)
238
+
239
+ dims = (
240
+ self.hidden_size,
241
+ self.num_attention_heads,
242
+ self.hidden_size_per_attention_head,
243
+ self.state_size,
244
+ self.hyena_filter_groups,
245
+ )
246
+ y = self.engine.parallel_iir(
247
+ z_pre,
248
+ h,
249
+ self.D,
250
+ L,
251
+ t=self.t,
252
+ poles=self.poles,
253
+ residues=self.residues,
254
+ dims=dims,
255
+ inference_params=inference_params,
256
+ layer_idx=self.layer_idx,
257
+ prefill_style=self.config.get("prefill_style", "fft"),
258
+ use_flashfft=self.use_flashfft,
259
+ fftconv_fn=self.fftconv_fn,
260
+ column_split_hyena=self.column_split_hyena,
261
+ long_fir_threshold=self.long_fir_threshold,
262
+ padding_mask=padding_mask,
263
+ )
264
+ return y, inference_params
265
+
266
+ def sequential_forward(self, u, inference_params):
267
+ if self.data_dtype is None:
268
+ self.data_dtype = u.dtype
269
+ if len(u.shape) > 2:
270
+ u = u[:, -1]
271
+
272
+ fir_state = inference_params.fir_state_dict[self.layer_idx]
273
+ iir_state = inference_params.state_dict[self.layer_idx]
274
+
275
+ z_pre, fir_state = self.engine.step_fir(
276
+ u, fir_state,
277
+ weight=self.short_filter_weight, bias=self.short_filter_bias,
278
+ )
279
+ if self.column_split_hyena:
280
+ x_reshaped = z_pre.reshape(
281
+ z_pre.shape[0],
282
+ self.num_attention_heads,
283
+ 3 * self.hidden_size_per_attention_head,
284
+ )
285
+ head = self.hidden_size_per_attention_head
286
+ x2 = x_reshaped[:, :, :head].reshape(z_pre.shape[0], -1)
287
+ x1 = x_reshaped[:, :, head : 2 * head].reshape(z_pre.shape[0], -1)
288
+ v = x_reshaped[:, :, 2 * head:].reshape(z_pre.shape[0], -1)
289
+ else:
290
+ x2, x1, v = z_pre.split(
291
+ [self.hidden_size, self.hidden_size, self.hidden_size], dim=1
292
+ )
293
+
294
+ y, iir_state = self.engine.step_iir(
295
+ x2, x1, v, self.D, self.residues, self.poles, iir_state,
296
+ iir_groups=self.hyena_filter_groups,
297
+ )
298
+ inference_params.fir_state_dict[self.layer_idx] = fir_state
299
+ inference_params.state_dict[self.layer_idx] = iir_state
300
+ y = y.to(dtype=self.data_dtype)
301
+ return y[:, None], inference_params
302
+
303
+ def update_time(self, L, device):
304
+ if not hasattr(self, "t"):
305
+ self.t = torch.arange(L, device=device)[None, None]
306
+ elif self.t.shape[-1] < L:
307
+ self.t = torch.arange(L, device=device)[None, None]
308
+ else:
309
+ self.t = self.t[..., :L]
310
+
311
+ def compute_filter(self, L, device):
312
+ self.update_time(L, device)
313
+ filter_dtype = torch.float32
314
+ residues = torch.view_as_complex(self.residues.to(filter_dtype))
315
+ log_poles = torch.view_as_complex(self.poles.to(filter_dtype)).log()
316
+ h = (residues * (log_poles * self.t).exp()).real.sum(1)[None]
317
+ return h, filter_dtype, log_poles, residues
318
+
319
+
320
+ class ParallelGatedConvBlock(nn.Module):
321
+ def __init__(self, config, layer_idx) -> None:
322
+ super().__init__()
323
+ self.config = config
324
+ self.layer_idx = layer_idx
325
+ self.low_mem_mode = config.get("low_mem_mode", False)
326
+ dtype = config.get("hyena_block_dtype", torch.float32)
327
+ mlp_dtype = config.get("mlp_dtype", torch.bfloat16)
328
+ self.pre_norm = RMSNorm(config).to(dtype=dtype)
329
+ self.post_norm = RMSNorm(config).to(dtype=dtype)
330
+ self.filter = ParallelHyenaFilter(config, layer_idx).to(dtype=dtype)
331
+ self.projections = nn.Linear(config.hidden_size, 3 * config.hidden_size)
332
+ self.out_filter_dense = nn.Linear(
333
+ config.hidden_size, config.hidden_size
334
+ ).to(dtype)
335
+ self.mlp = ParallelGatedMLP(config).to(dtype=mlp_dtype)
336
+
337
+ def forward(
338
+ self,
339
+ u,
340
+ inference_params=None,
341
+ padding_mask=None,
342
+ output_attentions: bool = False,
343
+ *args,
344
+ **kwargs,
345
+ ):
346
+ z = self.projections(self.pre_norm(u))
347
+
348
+ if isinstance(padding_mask, torch.Tensor):
349
+ z = z * padding_mask[..., None]
350
+
351
+ z, inference_params = self.filter(
352
+ z, inference_params=inference_params, padding_mask=padding_mask
353
+ )
354
+ z_in = self.out_filter_dense(z) + u
355
+
356
+ if isinstance(padding_mask, torch.Tensor):
357
+ z_in = z_in * padding_mask[..., None]
358
+
359
+ y = self.mlp(self.post_norm(z_in)) + z_in
360
+ # Hyena blocks have no attention matrix.
361
+ return y, None
362
+
363
+
364
+ def get_block(config, layer_idx, flash_fft=None):
365
+ if layer_idx in config.attn_layer_idxs:
366
+ return AttentionBlock(config, layer_idx)
367
+ if layer_idx in config.hyena_layer_idxs:
368
+ block = ParallelGatedConvBlock(config, layer_idx)
369
+ if config.get("use_flashfft", False):
370
+ block.filter.fftconv_fn = flash_fft
371
+ return block
372
+ raise NotImplementedError(f"layer_idx {layer_idx} not in attn or hyena indices")
373
+
374
+
375
+ # =============================================================================
376
+ # Backbone (StripedHyena)
377
+ # =============================================================================
378
+
379
+
380
+ class StripedHyena(nn.Module):
381
+ """Pure backbone: token embedding -> N blocks -> RMSNorm.
382
+
383
+ The unembed step is owned by the LM head wrapper, not here, so that
384
+ ``Evo1Model`` (no LM head) can return the post-norm hidden state as
385
+ ``last_hidden_state`` cleanly.
386
+ """
387
+
388
+ def __init__(self, config):
389
+ super().__init__()
390
+ self.config = config
391
+ self.embedding_layer = VocabParallelEmbedding(config)
392
+ self.norm = RMSNorm(config) if config.get("final_norm", True) else None
393
+
394
+ if config.get("use_flashfft", False):
395
+ import importlib
396
+ FlashFFTConv = importlib.import_module("flashfftconv").FlashFFTConv
397
+ # NOTE: the original togethercomputer reference had ``config.seqlen``
398
+ # here, which is a typo - that attribute doesn't exist on the
399
+ # config (it's ``max_seqlen``). The bug was unreachable upstream
400
+ # because ``use_flashfft`` defaults to False; we fix it so the
401
+ # path is at least loadable for users who do enable it.
402
+ # FlashFFTConv requires its build-time seqlen to be 2x the
403
+ # longest input it'll ever see (zero-padding for FFT).
404
+ self.flash_fft = FlashFFTConv(2 * config.max_seqlen, dtype=torch.bfloat16)
405
+ else:
406
+ self.flash_fft = None
407
+
408
+ self.blocks = nn.ModuleList(
409
+ get_block(config, i, flash_fft=self.flash_fft)
410
+ for i in range(config.num_layers)
411
+ )
412
+
413
+ def forward(
414
+ self,
415
+ x: torch.Tensor,
416
+ inference_params_dict=None,
417
+ padding_mask: Optional[torch.Tensor] = None,
418
+ output_hidden_states: bool = False,
419
+ output_attentions: bool = False,
420
+ ):
421
+ x = self.embedding_layer.embed(x)
422
+
423
+ all_hidden_states: list[torch.Tensor] = []
424
+ all_attentions: list[Optional[torch.Tensor]] = []
425
+ if output_hidden_states:
426
+ all_hidden_states.append(x)
427
+
428
+ if inference_params_dict is not None:
429
+ x, inference_params_dict_out = self._stateful_forward(
430
+ x, inference_params_dict,
431
+ all_hidden_states=all_hidden_states,
432
+ all_attentions=all_attentions,
433
+ output_hidden_states=output_hidden_states,
434
+ output_attentions=output_attentions,
435
+ )
436
+ else:
437
+ x, inference_params_dict_out = self._stateless_forward(
438
+ x, padding_mask=padding_mask,
439
+ all_hidden_states=all_hidden_states,
440
+ all_attentions=all_attentions,
441
+ output_hidden_states=output_hidden_states,
442
+ output_attentions=output_attentions,
443
+ )
444
+
445
+ if self.norm is not None:
446
+ x = self.norm(x)
447
+ if output_hidden_states:
448
+ all_hidden_states.append(x)
449
+
450
+ return x, inference_params_dict_out, all_hidden_states, all_attentions
451
+
452
+ def _stateful_forward(
453
+ self, x, inference_params_dict,
454
+ all_hidden_states, all_attentions,
455
+ output_hidden_states, output_attentions,
456
+ ):
457
+ for block_idx, block in enumerate(self.blocks):
458
+ block_name = (
459
+ "mha" if block_idx in self.config.attn_layer_idxs else "hyena"
460
+ )
461
+ inference_params = inference_params_dict[block_name]
462
+ x, attn = block(
463
+ x, inference_params=inference_params,
464
+ output_attentions=output_attentions,
465
+ )
466
+ if output_hidden_states:
467
+ all_hidden_states.append(x)
468
+ if output_attentions:
469
+ all_attentions.append(attn)
470
+ return x, inference_params_dict
471
+
472
+ def _stateless_forward(
473
+ self, x, padding_mask,
474
+ all_hidden_states, all_attentions,
475
+ output_hidden_states, output_attentions,
476
+ ):
477
+ if isinstance(padding_mask, torch.Tensor):
478
+ x = x * padding_mask[..., None]
479
+ for block in self.blocks:
480
+ x, attn = block(
481
+ x, inference_params=None, padding_mask=padding_mask,
482
+ output_attentions=output_attentions,
483
+ )
484
+ if output_hidden_states:
485
+ all_hidden_states.append(x)
486
+ if output_attentions:
487
+ all_attentions.append(attn)
488
+ return x, None
489
+
490
+ def initialize_inference_params(self, max_batch_size: int = 1) -> Evo1Cache:
491
+ return Evo1Cache(
492
+ max_seqlen=self.config.get("max_seqlen", 8192),
493
+ max_batch_size=max_batch_size,
494
+ short_filter_length=self.config.short_filter_length,
495
+ state_size=self.config.state_size,
496
+ )
497
+
498
+ def to_bfloat16_except_poles_residues(self):
499
+ """Cast all parameters to bfloat16 except Hyena poles/residues."""
500
+ for k, p in self.named_parameters():
501
+ if "poles" not in k and "residues" not in k:
502
+ p.data = p.data.to(torch.bfloat16)
503
+
504
+
505
+ # =============================================================================
506
+ # HuggingFace wrappers
507
+ # =============================================================================
508
+
509
+
510
+ class Evo1PreTrainedModel(PreTrainedModel):
511
+ config_class = Evo1Config
512
+ base_model_prefix = "backbone"
513
+ supports_gradient_checkpointing = False
514
+ _no_split_modules = ["AttentionBlock", "ParallelGatedConvBlock"]
515
+ _skip_keys_device_placement = "past_key_values"
516
+ _keys_to_ignore_on_load_missing = [r"freq", r"\.t$"]
517
+ _keys_to_ignore_on_load_unexpected = [r"fftconv", r"twiddle_factors"]
518
+ _supports_flash_attn_2 = True
519
+ _supports_sdpa = True
520
+ # Hyena filter SSM parameters (poles / residues) MUST stay in fp32: they
521
+ # parametrize a long-range modal-form filter whose stability collapses
522
+ # in bf16. HF will keep these in fp32 even when the rest of the model is
523
+ # loaded in bf16 (or fp16) via the dtype= kwarg of from_pretrained.
524
+ _keep_in_fp32_modules = ["poles", "residues"]
525
+
526
+ @classmethod
527
+ def from_pretrained(cls, *args, **kwargs):
528
+ # Evo1 was trained in bfloat16, with the modal-form filter parameters
529
+ # (Hyena poles / residues) kept in fp32 via _keep_in_fp32_modules.
530
+ # bf16 works correctly for all three attention backends (eager, sdpa,
531
+ # flash_attention_2). Default to bf16 so users don't have to pass it
532
+ # explicitly; this also silences HF's flash_attention_2 dtype warning
533
+ # (which inspects the model dtype before force_dtype() runs in __init__).
534
+ if "dtype" not in kwargs and "torch_dtype" not in kwargs:
535
+ kwargs["dtype"] = torch.bfloat16
536
+ return super().from_pretrained(*args, **kwargs)
537
+
538
+
539
+ class Evo1Model(Evo1PreTrainedModel):
540
+ """Bare backbone: returns ``BaseModelOutputWithPast``.
541
+
542
+ ``last_hidden_state`` is the final (post-RMSNorm) representation, ready
543
+ to be fed into a downstream head or unembed projection.
544
+ """
545
+
546
+ def __init__(self, config: Evo1Config):
547
+ super().__init__(config)
548
+ self.backbone = StripedHyena(config)
549
+ self.config = config
550
+ self.post_init()
551
+ self.force_dtype()
552
+
553
+ def force_dtype(self):
554
+ # Cast everything except poles/residues to bf16 (the trained dtype).
555
+ # This runs at __init__ time so the model is usable even without an
556
+ # explicit ``dtype=torch.bfloat16`` kwarg to ``from_pretrained``.
557
+ self.backbone.to_bfloat16_except_poles_residues()
558
+
559
+ def get_input_embeddings(self):
560
+ return self.backbone.embedding_layer
561
+
562
+ def set_input_embeddings(self, value):
563
+ self.backbone.embedding_layer = value
564
+
565
+ def forward(
566
+ self,
567
+ input_ids: torch.LongTensor = None,
568
+ attention_mask: Optional[torch.LongTensor] = None,
569
+ past_key_values=None,
570
+ use_cache: Optional[bool] = None,
571
+ output_attentions: Optional[bool] = None,
572
+ output_hidden_states: Optional[bool] = None,
573
+ return_dict: Optional[bool] = None,
574
+ ) -> Union[Tuple, BaseModelOutputWithPast]:
575
+ return_dict = (
576
+ return_dict if return_dict is not None else self.config.use_return_dict
577
+ )
578
+ output_attentions = (
579
+ output_attentions
580
+ if output_attentions is not None
581
+ else self.config.output_attentions
582
+ )
583
+ output_hidden_states = (
584
+ output_hidden_states
585
+ if output_hidden_states is not None
586
+ else self.config.output_hidden_states
587
+ )
588
+ # Evo1Model is the bare backbone (no LM head). Default to no caching:
589
+ # KV caches and Hyena recurrent state are only useful for autoregressive
590
+ # generation (Evo1ForCausalLM). For embedding extraction the caches
591
+ # have a large per-layer memory footprint with no benefit. The user
592
+ # can still opt-in by passing ``use_cache=True`` explicitly.
593
+ use_cache = use_cache if use_cache is not None else False
594
+ if use_cache and self.training:
595
+ use_cache = False
596
+
597
+ inputs = input_ids
598
+ if use_cache and past_key_values is None:
599
+ past_key_values = self.backbone.initialize_inference_params(
600
+ max_batch_size=input_ids.shape[0],
601
+ )
602
+
603
+ last_hidden, past_kv, hidden_states, attentions = self.backbone(
604
+ inputs,
605
+ padding_mask=attention_mask,
606
+ inference_params_dict=past_key_values if use_cache else None,
607
+ output_hidden_states=output_hidden_states,
608
+ output_attentions=output_attentions,
609
+ )
610
+
611
+ if not return_dict:
612
+ outputs = (last_hidden,)
613
+ if use_cache:
614
+ outputs += (past_kv,)
615
+ if output_hidden_states:
616
+ outputs += (tuple(hidden_states),)
617
+ if output_attentions:
618
+ outputs += (tuple(attentions),)
619
+ return outputs
620
+
621
+ return BaseModelOutputWithPast(
622
+ last_hidden_state=last_hidden,
623
+ past_key_values=past_kv if use_cache else None,
624
+ hidden_states=tuple(hidden_states) if output_hidden_states else None,
625
+ attentions=tuple(attentions) if output_attentions else None,
626
+ )
627
+
628
+
629
+ class Evo1ForCausalLM(Evo1PreTrainedModel, GenerationMixin):
630
+ """LM head wrapper. Tied to ``backbone.embedding_layer`` (Evo1 ties weights)."""
631
+
632
+ def __init__(self, config: Evo1Config, **kwargs):
633
+ super().__init__(config, **kwargs)
634
+ self.backbone = StripedHyena(config)
635
+ self.config = config
636
+
637
+ # Pad-to-multiple-of for the vocab (matches togethercomputer config).
638
+ vocab_size = config.vocab_size
639
+ if vocab_size % config.make_vocab_size_divisible_by != 0:
640
+ vocab_size += config.make_vocab_size_divisible_by - (
641
+ vocab_size % config.make_vocab_size_divisible_by
642
+ )
643
+ self.vocab_size = vocab_size
644
+ self.post_init()
645
+ self.force_dtype()
646
+
647
+ def force_dtype(self):
648
+ self.backbone.to_bfloat16_except_poles_residues()
649
+
650
+ def get_input_embeddings(self):
651
+ return self.backbone.embedding_layer
652
+
653
+ def set_input_embeddings(self, value):
654
+ self.backbone.embedding_layer = value
655
+
656
+ def get_output_embeddings(self):
657
+ return self.backbone.embedding_layer
658
+
659
+ def set_output_embeddings(self, value):
660
+ self.backbone.embedding_layer = value
661
+
662
+ def forward(
663
+ self,
664
+ input_ids: torch.LongTensor = None,
665
+ attention_mask: Optional[torch.LongTensor] = None,
666
+ labels: Optional[torch.LongTensor] = None,
667
+ past_key_values=None,
668
+ use_cache: Optional[bool] = None,
669
+ output_attentions: Optional[bool] = None,
670
+ output_hidden_states: Optional[bool] = None,
671
+ return_dict: Optional[bool] = None,
672
+ ) -> Union[Tuple, CausalLMOutputWithPast]:
673
+ return_dict = (
674
+ return_dict if return_dict is not None else self.config.use_return_dict
675
+ )
676
+ output_attentions = (
677
+ output_attentions
678
+ if output_attentions is not None
679
+ else self.config.output_attentions
680
+ )
681
+ output_hidden_states = (
682
+ output_hidden_states
683
+ if output_hidden_states is not None
684
+ else self.config.output_hidden_states
685
+ )
686
+ use_cache = use_cache if use_cache is not None else self.config.use_cache
687
+
688
+ if use_cache and labels is not None:
689
+ logger.warning_once(
690
+ "use_cache=True is incompatible with loss computation; "
691
+ "disabling cache."
692
+ )
693
+ use_cache = False
694
+
695
+ inputs = input_ids
696
+ if use_cache:
697
+ # If the user (or HF generation) didn't pass our Evo1Cache,
698
+ # initialize a fresh one on the first call.
699
+ if not isinstance(past_key_values, Evo1Cache):
700
+ past_key_values = self.backbone.initialize_inference_params(
701
+ max_batch_size=input_ids.shape[0],
702
+ )
703
+ else:
704
+ seqlen_offset = past_key_values.seqlen_offset
705
+ if seqlen_offset == 0:
706
+ # Prefill done; set offset to prompt length minus the one
707
+ # token we're about to consume (and that we'll keep
708
+ # consuming one-at-a-time below).
709
+ past_key_values.set_offset(input_ids.shape[-1] - 1)
710
+ else:
711
+ past_key_values.advance(1)
712
+ inputs = input_ids[:, -1:]
713
+
714
+ last_hidden, past_kv, hidden_states, attentions = self.backbone(
715
+ inputs,
716
+ padding_mask=attention_mask,
717
+ inference_params_dict=past_key_values if use_cache else None,
718
+ output_hidden_states=output_hidden_states,
719
+ output_attentions=output_attentions,
720
+ )
721
+
722
+ # Tied unembed: matmul against embedding weights.
723
+ logits = last_hidden @ self.backbone.embedding_layer.weight.T
724
+
725
+ loss = None
726
+ if labels is not None:
727
+ shift_logits = logits[..., :-1, :].contiguous()
728
+ shift_labels = labels[..., 1:].contiguous()
729
+ shift_logits = shift_logits.view(-1, self.config.vocab_size)
730
+ shift_labels = shift_labels.view(-1).to(shift_logits.device)
731
+ loss = F.cross_entropy(shift_logits, shift_labels)
732
+
733
+ if not return_dict:
734
+ outputs = (logits,)
735
+ if use_cache:
736
+ outputs += (past_kv,)
737
+ if output_hidden_states:
738
+ outputs += (tuple(hidden_states),)
739
+ if output_attentions:
740
+ outputs += (tuple(attentions),)
741
+ if loss is not None:
742
+ outputs = (loss,) + outputs
743
+ return outputs
744
+
745
+ return CausalLMOutputWithPast(
746
+ loss=loss,
747
+ logits=logits,
748
+ past_key_values=past_kv if use_cache else None,
749
+ hidden_states=tuple(hidden_states) if output_hidden_states else None,
750
+ attentions=tuple(attentions) if output_attentions else None,
751
+ )
752
+
753
+ @classmethod
754
+ def can_generate(cls) -> bool:
755
+ return True
756
+
757
+ def prepare_inputs_for_generation(
758
+ self, input_ids, attention_mask=None, past_key_values=None, **kwargs
759
+ ):
760
+ return {
761
+ "input_ids": input_ids,
762
+ "attention_mask": attention_mask,
763
+ "past_key_values": past_key_values,
764
+ }
rotary.py ADDED
@@ -0,0 +1,245 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Rotary embeddings for the Evo1 HF port.
2
+
3
+ Two modes:
4
+ * **Fast path** - when ``flash_attn`` is installed, we delegate to
5
+ ``flash_attn.layers.rotary.RotaryEmbedding``, whose Triton kernel does
6
+ the rotary multiply in fp32 internally (and is bit-exact with our
7
+ pure-PyTorch path below).
8
+ * **Fallback** - pure-PyTorch implementation, mathematically identical to
9
+ flash_attn's kernel (multiply done in fp32 then cast back to bf16). Used
10
+ when ``flash_attn`` isn't available.
11
+
12
+ The ``LinearlyScaledRotaryEmbedding`` subclass (used for the 131k variant)
13
+ overrides ``_update_cos_sin_cache`` to scale position indices, which works
14
+ identically against either parent class.
15
+ """
16
+
17
+ from __future__ import annotations
18
+
19
+ import torch
20
+ import torch.nn as nn
21
+
22
+
23
+ try:
24
+ from flash_attn.layers.rotary import RotaryEmbedding as _FlashRotaryEmbedding
25
+ _HAS_FLASH_ROTARY = True
26
+ except ImportError: # pragma: no cover - optional dep
27
+ _FlashRotaryEmbedding = None # type: ignore[assignment]
28
+ _HAS_FLASH_ROTARY = False
29
+
30
+
31
+ def _rotate_half(x: torch.Tensor) -> torch.Tensor:
32
+ """Rotate the second half of the last dim into the first half (with sign).
33
+
34
+ [x1, x2] -> [-x2, x1]
35
+ """
36
+ x1, x2 = x.chunk(2, dim=-1)
37
+ return torch.cat((-x2, x1), dim=-1)
38
+
39
+
40
+ def _apply_rotary(x: torch.Tensor, cos: torch.Tensor, sin: torch.Tensor) -> torch.Tensor:
41
+ """Apply non-interleaved RoPE to the last `2 * cos.shape[-1]` dims of x.
42
+
43
+ cos / sin shape: (T, rot_dim/2). x shape: (..., T, ..., D), where the rot
44
+ is applied along the last dim. We expand cos/sin to broadcast over the
45
+ leading dims.
46
+
47
+ The multiplication is performed in fp32 internally (then cast back to
48
+ x.dtype) to match flash_attn's Triton rotary kernel bit-exactly. Doing
49
+ the multiply in bf16 directly compounds rounding error of ~3e-2 per
50
+ layer, which becomes a ~1% relative error after 32 transformer blocks.
51
+ """
52
+ rot_dim = cos.shape[-1] * 2
53
+ x_rot = x[..., :rot_dim]
54
+ x_pass = x[..., rot_dim:]
55
+ orig_dtype = x.dtype
56
+ cos_full = torch.cat((cos, cos), dim=-1).float()
57
+ sin_full = torch.cat((sin, sin), dim=-1).float()
58
+ x_rot_f = x_rot.float()
59
+ rotated = (x_rot_f * cos_full) + (_rotate_half(x_rot_f) * sin_full)
60
+ rotated = rotated.to(orig_dtype)
61
+ return torch.cat((rotated, x_pass), dim=-1)
62
+
63
+
64
+ class _PureRotaryEmbedding(nn.Module):
65
+ """Pure-PyTorch fallback RoPE (used when flash_attn is unavailable).
66
+
67
+ Mirrors the public surface of ``flash_attn.layers.rotary.RotaryEmbedding``
68
+ for the subset used by the Evo1 attention block: exposes ``inv_freq`` as
69
+ a buffer (so it serializes/deserializes the same way) and a forward(qkv)
70
+ -> qkv method that rotates Q and K.
71
+ """
72
+
73
+ def __init__(
74
+ self,
75
+ dim: int,
76
+ base: float = 10000.0,
77
+ interleaved: bool = False,
78
+ scale_base: float | None = None,
79
+ pos_idx_in_fp32: bool = True,
80
+ device=None,
81
+ ):
82
+ super().__init__()
83
+ if interleaved:
84
+ raise NotImplementedError("Interleaved RoPE is not implemented.")
85
+ if scale_base is not None:
86
+ raise NotImplementedError("xPos scale_base is not implemented.")
87
+ self.dim = dim
88
+ self.base = float(base)
89
+ self.interleaved = interleaved
90
+ self.scale_base = scale_base
91
+ self.pos_idx_in_fp32 = pos_idx_in_fp32
92
+
93
+ inv_freq = self._compute_inv_freq(device=device)
94
+ self.register_buffer("inv_freq", inv_freq, persistent=False)
95
+ self.scale = None # xPos slot kept for swap_mha_rope compatibility
96
+
97
+ self._seq_len_cached = 0
98
+ self._cos_cached: torch.Tensor | None = None
99
+ self._sin_cached: torch.Tensor | None = None
100
+
101
+ def _compute_inv_freq(self, device=None) -> torch.Tensor:
102
+ return 1.0 / (
103
+ self.base
104
+ ** (torch.arange(0, self.dim, 2, device=device, dtype=torch.float32) / self.dim)
105
+ )
106
+
107
+ def _update_cos_sin_cache(self, seqlen: int, device=None, dtype=None):
108
+ if (
109
+ seqlen > self._seq_len_cached
110
+ or self._cos_cached is None
111
+ or self._cos_cached.device != device
112
+ or self._cos_cached.dtype != dtype
113
+ or (self.training and self._cos_cached.is_inference())
114
+ ):
115
+ self._seq_len_cached = seqlen
116
+ if self.pos_idx_in_fp32:
117
+ t = torch.arange(seqlen, device=device, dtype=torch.float32)
118
+ if self.inv_freq.dtype != torch.float32:
119
+ inv_freq = self._compute_inv_freq(device=device)
120
+ else:
121
+ inv_freq = self.inv_freq
122
+ else:
123
+ t = torch.arange(seqlen, device=device, dtype=self.inv_freq.dtype)
124
+ inv_freq = self.inv_freq
125
+
126
+ freqs = torch.outer(t, inv_freq)
127
+ self._cos_cached = torch.cos(freqs).to(dtype)
128
+ self._sin_cached = torch.sin(freqs).to(dtype)
129
+
130
+ def forward(
131
+ self,
132
+ qkv: torch.Tensor,
133
+ seqlen_offset: int | torch.Tensor = 0,
134
+ max_seqlen: int | None = None,
135
+ ) -> torch.Tensor:
136
+ """Rotate Q and K of a packed (B, T, 3, H, D) qkv tensor.
137
+
138
+ seqlen_offset is supported as int only (no per-sample offsets); for
139
+ the inference KV-cache fast path we fall back to int(seqlen_offset).
140
+ """
141
+ if isinstance(seqlen_offset, torch.Tensor):
142
+ seqlen_offset = int(seqlen_offset.max().item())
143
+ T = qkv.shape[1]
144
+ seqlen = max_seqlen if max_seqlen is not None else (T + seqlen_offset)
145
+ self._update_cos_sin_cache(seqlen, device=qkv.device, dtype=qkv.dtype)
146
+
147
+ cos = self._cos_cached[seqlen_offset : seqlen_offset + T]
148
+ sin = self._sin_cached[seqlen_offset : seqlen_offset + T]
149
+ q, k, v = qkv.unbind(dim=2)
150
+ cos_b = cos[None, :, None, :]
151
+ sin_b = sin[None, :, None, :]
152
+ q = _apply_rotary(q, cos_b, sin_b)
153
+ k = _apply_rotary(k, cos_b, sin_b)
154
+ return torch.stack((q, k, v), dim=2)
155
+
156
+
157
+ # Public ``RotaryEmbedding``: delegates to flash_attn's Triton kernel when
158
+ # available, falls back to our pure-PyTorch implementation otherwise.
159
+ RotaryEmbedding: type = (
160
+ _FlashRotaryEmbedding if _HAS_FLASH_ROTARY else _PureRotaryEmbedding
161
+ )
162
+
163
+
164
+ class LinearlyScaledRotaryEmbedding(RotaryEmbedding):
165
+ """RoPE with linear interpolation of position indices.
166
+
167
+ Used for evo-1-131k-base: positions are divided by ``scaling_factor``
168
+ before the cos/sin tables are computed, effectively stretching the
169
+ trained context. The override is the same shape regardless of whether
170
+ the parent class is flash_attn's RotaryEmbedding or our pure-PyTorch
171
+ fallback (both expose the same ``_update_cos_sin_cache`` hook).
172
+ """
173
+
174
+ def __init__(self, dim: int, scaling_factor: float = 1.0, **kwargs):
175
+ super().__init__(dim=dim, **kwargs)
176
+ self._linear_scaling_factor = float(scaling_factor)
177
+
178
+ def _update_cos_sin_cache(self, seqlen, device=None, dtype=None):
179
+ # Mirrors the parent body but divides position indices by the linear
180
+ # scaling factor before computing the cos/sin tables.
181
+ if (
182
+ seqlen <= self._seq_len_cached
183
+ and self._cos_cached is not None
184
+ and self._cos_cached.device == device
185
+ and self._cos_cached.dtype == dtype
186
+ and not (self.training and self._cos_cached.is_inference())
187
+ ):
188
+ return
189
+
190
+ self._seq_len_cached = seqlen
191
+ if self.pos_idx_in_fp32:
192
+ t = torch.arange(seqlen, device=device, dtype=torch.float32)
193
+ t = t / self._linear_scaling_factor
194
+ if self.inv_freq.dtype != torch.float32:
195
+ inv_freq = self._compute_inv_freq(device=device) \
196
+ if hasattr(self, "_compute_inv_freq") \
197
+ else self.inv_freq.float()
198
+ else:
199
+ inv_freq = self.inv_freq
200
+ else:
201
+ t = torch.arange(seqlen, device=device, dtype=self.inv_freq.dtype)
202
+ t = t / self._linear_scaling_factor
203
+ inv_freq = self.inv_freq
204
+
205
+ freqs = torch.outer(t, inv_freq)
206
+ if self.scale is None:
207
+ self._cos_cached = torch.cos(freqs).to(dtype)
208
+ self._sin_cached = torch.sin(freqs).to(dtype)
209
+ else: # pragma: no cover - xPos not used by Evo1
210
+ from einops import rearrange
211
+ power = (
212
+ torch.arange(seqlen, dtype=self.scale.dtype, device=self.scale.device)
213
+ - seqlen // 2
214
+ ) / self.scale_base
215
+ scale = self.scale.to(device=power.device) ** rearrange(power, "s -> s 1")
216
+ self._cos_cached = (torch.cos(freqs) * scale).to(dtype)
217
+ self._sin_cached = (torch.sin(freqs) * scale).to(dtype)
218
+ self._cos_k_cached = (torch.cos(freqs) / scale).to(dtype)
219
+ self._sin_k_cached = (torch.sin(freqs) / scale).to(dtype)
220
+
221
+
222
+ def swap_mha_rope(mha, new_rope=LinearlyScaledRotaryEmbedding, kwargs_new_rope=None):
223
+ """Replace ``mha.rotary_emb`` with a freshly-constructed scaled RoPE.
224
+
225
+ Mirrors ``stripedhyena.positional_embeddings.swap_mha_rope``: inherits
226
+ dim/base/interleaved/scale_base/pos_idx_in_fp32 from the existing rope,
227
+ deletes the old module, and attaches a new one of ``new_rope`` type
228
+ configured with ``kwargs_new_rope``.
229
+ """
230
+ weight_attr = "Wq" if getattr(mha, "cross_attn", False) else "Wqkv"
231
+ weight = getattr(mha, weight_attr).weight
232
+ dtype = weight.dtype
233
+ kwargs_old_rope = dict(
234
+ dim=mha.rotary_emb.dim,
235
+ base=mha.rotary_emb.base,
236
+ interleaved=mha.rotary_emb.interleaved,
237
+ scale_base=mha.rotary_emb.scale_base,
238
+ pos_idx_in_fp32=mha.rotary_emb.pos_idx_in_fp32,
239
+ device=mha.rotary_emb.inv_freq.device,
240
+ )
241
+ del mha.rotary_emb
242
+ kwargs_new_rope = kwargs_new_rope or {"scaling_factor": 1.0}
243
+ scaled = new_rope(**kwargs_new_rope, **kwargs_old_rope).to(dtype)
244
+ mha.rotary_emb = scaled
245
+ return mha
special_tokens_map.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {}
tokenization_evo1.py ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Based on togethercomputer/evo-1-131k-base/tokenizer.py (Apache 2.0).
2
+ # Adapted: minor fix (typing), Dict -> dict for forward-compatibility.
3
+ """ByteTokenizer for Evo1.
4
+
5
+ Maps text to/from raw UTF-8 byte values, vocab_size = 512 (no real vocab,
6
+ just the byte range padded out).
7
+ """
8
+ from __future__ import annotations
9
+
10
+ from os import PathLike
11
+ from typing import List, Tuple
12
+
13
+ import numpy as np
14
+
15
+ from transformers.tokenization_utils import PreTrainedTokenizer
16
+ from transformers.tokenization_utils_base import BatchEncoding, TruncationStrategy
17
+ from transformers.utils.generic import PaddingStrategy
18
+
19
+
20
+ EMPTY: str = ""
21
+
22
+
23
+ class ByteTokenizer(PreTrainedTokenizer):
24
+ """UTF-8 byte-level tokenizer (vocab_size = 512).
25
+
26
+ Special tokens follow the original ``CharLevelTokenizer`` convention:
27
+ * ``\x00`` (chr(0)) is end-of-document / end-of-sequence.
28
+ * ``\x01`` (chr(1)) is the padding token.
29
+
30
+ These are wired up so ``HF`` tokenization helpers (``padding=True``,
31
+ ``model_max_length``, etc.) work with this tokenizer.
32
+ """
33
+
34
+ def __init__(self, byte_level: bool = True, **kwargs):
35
+ # Defaults; ``tokenizer_config.json`` may override via kwargs.
36
+ # Padding token: byte 0x01 (matches the original CharLevelTokenizer
37
+ # pad convention). We deliberately do NOT set eos_token / cls_token:
38
+ # Evo1 is a pure byte-level model with no special tokens added at
39
+ # encoding time, so downstream pooling logic (e.g. mRNABench) should
40
+ # treat every non-pad position as a real token.
41
+ kwargs.setdefault("pad_token", chr(1))
42
+ super().__init__(byte_level=byte_level, **kwargs)
43
+ # The model only consumes input_ids and attention_mask (no segment ids).
44
+ self.model_input_names = ["input_ids", "attention_mask"]
45
+
46
+ @property
47
+ def vocab_size(self) -> int:
48
+ return 512
49
+
50
+ @property
51
+ def byte_level(self) -> bool:
52
+ return self.init_kwargs.get("byte_level", True)
53
+
54
+ def get_vocab(self) -> dict:
55
+ return {chr(i): i for i in range(self.vocab_size)}
56
+
57
+ def __len__(self) -> int:
58
+ return self.vocab_size
59
+
60
+ def clamp(self, n: int) -> int:
61
+ return max(32, min(n, self.vocab_size))
62
+
63
+ def _tokenize(self, text: str, **kwargs) -> List[str]:
64
+ return list(text)
65
+
66
+ def byte_tokenize(self, text: str) -> np.ndarray:
67
+ return np.frombuffer(text.encode("utf-8"), dtype=np.uint8)
68
+
69
+ def _convert_token_to_id(self, token: str) -> int:
70
+ return self.clamp(ord(token))
71
+
72
+ def _convert_id_to_token(self, index: int) -> str:
73
+ return chr(self.clamp(index))
74
+
75
+ def convert_tokens_to_string(self, tokens: List[str]) -> str:
76
+ return EMPTY.join(tokens)
77
+
78
+ def _decode(self, token_ids: List[int], **kwargs) -> str:
79
+ # numpy >= 2 disallows clipping a uint8 array to a value outside [0, 255]
80
+ # (vocab_size=512). Convert to int16 first, clip, then back to uint8.
81
+ indices = np.asarray(token_ids, dtype=np.int16)
82
+ indices = indices.clip(min=32, max=255).astype(np.uint8)
83
+ return indices.tobytes().decode("utf-8", errors="replace")
84
+
85
+ def _encode_plus(self, text: str, **kwargs) -> BatchEncoding:
86
+ first_ids = self.byte_tokenize(text).tolist()
87
+ return self.prepare_for_model(
88
+ first_ids,
89
+ pair_ids=None,
90
+ add_special_tokens=kwargs.get("add_special_tokens", False),
91
+ padding=kwargs.get("padding_strategy", PaddingStrategy.DO_NOT_PAD).value,
92
+ truncation=kwargs.get("truncation_strategy", TruncationStrategy.DO_NOT_TRUNCATE).value,
93
+ max_length=kwargs.get("max_length"),
94
+ stride=kwargs.get("stride", 0),
95
+ pad_to_multiple_of=kwargs.get("pad_to_multiple_of"),
96
+ return_tensors=kwargs.get("return_tensors"),
97
+ prepend_batch_axis=True,
98
+ return_attention_mask=kwargs.get("return_attention_mask"),
99
+ return_token_type_ids=kwargs.get("return_token_type_ids"),
100
+ return_overflowing_tokens=kwargs.get("return_overflowing_tokens", False),
101
+ return_special_tokens_mask=kwargs.get("return_special_tokens_mask", False),
102
+ return_length=kwargs.get("return_length", False),
103
+ verbose=kwargs.get("verbose", True),
104
+ )
105
+
106
+ def _batch_encode_plus(self, batch_text_or_text_pairs, **kwargs) -> BatchEncoding:
107
+ input_ids = [(self.byte_tokenize(t).tolist(), None) for t in batch_text_or_text_pairs]
108
+ return self._batch_prepare_for_model(
109
+ input_ids,
110
+ add_special_tokens=kwargs.get("add_special_tokens", False),
111
+ padding_strategy=kwargs.get("padding_strategy", PaddingStrategy.DO_NOT_PAD),
112
+ truncation_strategy=kwargs.get("truncation_strategy", TruncationStrategy.DO_NOT_TRUNCATE),
113
+ max_length=kwargs.get("max_length"),
114
+ stride=kwargs.get("stride", 0),
115
+ pad_to_multiple_of=kwargs.get("pad_to_multiple_of"),
116
+ return_attention_mask=kwargs.get("return_attention_mask"),
117
+ return_token_type_ids=kwargs.get("return_token_type_ids"),
118
+ return_overflowing_tokens=kwargs.get("return_overflowing_tokens", False),
119
+ return_special_tokens_mask=kwargs.get("return_special_tokens_mask", False),
120
+ return_length=kwargs.get("return_length", False),
121
+ return_tensors=kwargs.get("return_tensors"),
122
+ verbose=kwargs.get("verbose", True),
123
+ )
124
+
125
+ def _save_pretrained(
126
+ self, save_directory: str | PathLike, file_names: Tuple[str], **kwargs
127
+ ) -> Tuple[str]:
128
+ return file_names
tokenizer_config.json ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "auto_map": {
3
+ "AutoTokenizer": [
4
+ "tokenization_evo1.ByteTokenizer",
5
+ null
6
+ ]
7
+ },
8
+ "tokenizer_class": "ByteTokenizer",
9
+ "model_max_length": 8192,
10
+ "pad_token": "\u0001",
11
+ "byte_level": true
12
+ }