Text Generation
Transformers
Safetensors
Upper Grand Valley Dani
evo1
DNA
language-model
StripedHyena
Evo
long-context
custom_code
Instructions to use Taykhoom/Evo1-1-7B-131K with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use Taykhoom/Evo1-1-7B-131K with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="Taykhoom/Evo1-1-7B-131K", trust_remote_code=True)# Load model directly from transformers import AutoModelForCausalLM model = AutoModelForCausalLM.from_pretrained("Taykhoom/Evo1-1-7B-131K", trust_remote_code=True, dtype="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use Taykhoom/Evo1-1-7B-131K with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "Taykhoom/Evo1-1-7B-131K" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Taykhoom/Evo1-1-7B-131K", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker
docker model run hf.co/Taykhoom/Evo1-1-7B-131K
- SGLang
How to use Taykhoom/Evo1-1-7B-131K with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "Taykhoom/Evo1-1-7B-131K" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Taykhoom/Evo1-1-7B-131K", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "Taykhoom/Evo1-1-7B-131K" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Taykhoom/Evo1-1-7B-131K", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }' - Docker Model Runner
How to use Taykhoom/Evo1-1-7B-131K with Docker Model Runner:
docker model run hf.co/Taykhoom/Evo1-1-7B-131K
Commit ·
9e26fe9
0
Parent(s):
Initial release
Browse files- .gitattributes +35 -0
- README.md +220 -0
- attention.py +294 -0
- cache.py +132 -0
- config.json +86 -0
- configuration_evo1.py +153 -0
- engine.py +388 -0
- generation_config.json +5 -0
- layers.py +82 -0
- model-00001-of-00003.safetensors +3 -0
- model-00002-of-00003.safetensors +3 -0
- model-00003-of-00003.safetensors +3 -0
- model.safetensors.index.json +446 -0
- modeling_evo1.py +764 -0
- rotary.py +245 -0
- special_tokens_map.json +1 -0
- tokenization_evo1.py +128 -0
- tokenizer_config.json +12 -0
.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,220 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
language:
|
| 3 |
+
- dna
|
| 4 |
+
library_name: transformers
|
| 5 |
+
tags:
|
| 6 |
+
- DNA
|
| 7 |
+
- language-model
|
| 8 |
+
- StripedHyena
|
| 9 |
+
- Evo
|
| 10 |
+
- long-context
|
| 11 |
+
license: apache-2.0
|
| 12 |
+
---
|
| 13 |
+
|
| 14 |
+
# Evo1-1-7B-131K
|
| 15 |
+
|
| 16 |
+
A clean, minimal HuggingFace port of [Evo 1 (131k)](https://huggingface.co/togethercomputer/evo-1-131k-base), the long-context variant of Evo 1 supporting sequences up to 131 072 tokens via linearly-interpolated rotary positional embeddings. ~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 |
+
[togethercomputer/evo-1-131k-base](https://huggingface.co/togethercomputer/evo-1-131k-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 togethercomputer 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, **linearly scaled by 1/16**) |
|
| 43 |
+
| Architecture | StripedHyena (alternating Hyena / MHA blocks) |
|
| 44 |
+
| Max sequence length | 131 072 |
|
| 45 |
+
| Training dtype | bfloat16 (Hyena modal-form `poles` / `residues` kept in fp32) |
|
| 46 |
+
|
| 47 |
+
## Pretraining
|
| 48 |
+
|
| 49 |
+
- **Objective:** causal byte-level next-token prediction.
|
| 50 |
+
- **Data:** [OpenGenome](https://huggingface.co/datasets/LongSafari/open-genome), ~300B tokens of prokaryotic whole-genome DNA. The 131k context window was added on top of the 8k base model via continued training with linearly-scaled RoPE.
|
| 51 |
+
- **Source checkpoint:** `togethercomputer/evo-1-131k-base@1.1_fix`.
|
| 52 |
+
|
| 53 |
+
## Parity Verification
|
| 54 |
+
|
| 55 |
+
Hidden-state representations verified **bit-exact** (`max_abs_diff = 0.000e+00`) to the togethercomputer 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.
|
| 56 |
+
|
| 57 |
+
### Numerical equivalence across attention backends
|
| 58 |
+
|
| 59 |
+
`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`).
|
| 60 |
+
|
| 61 |
+
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.
|
| 62 |
+
|
| 63 |
+
## Related Models
|
| 64 |
+
|
| 65 |
+
See the full [Evo1 collection](https://huggingface.co/collections/Taykhoom/evo1-6a24ae4a98f04906482db8c2) on the Hub.
|
| 66 |
+
|
| 67 |
+
| Model | Context | Notes |
|
| 68 |
+
|---|---|---|
|
| 69 |
+
| [Taykhoom/Evo1-1-7B-8K](https://huggingface.co/Taykhoom/Evo1-1-7B-8K) | 8 192 | Original Evo 1 base model (8k context). |
|
| 70 |
+
| **[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). |
|
| 71 |
+
| [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. |
|
| 72 |
+
|
| 73 |
+
## Usage
|
| 74 |
+
|
| 75 |
+
> **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.
|
| 76 |
+
|
| 77 |
+
> **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.
|
| 78 |
+
|
| 79 |
+
### Embedding generation (no LM head)
|
| 80 |
+
|
| 81 |
+
```python
|
| 82 |
+
import torch
|
| 83 |
+
from transformers import AutoTokenizer, AutoModel
|
| 84 |
+
|
| 85 |
+
tokenizer = AutoTokenizer.from_pretrained("Taykhoom/Evo1-1-7B-131K", trust_remote_code=True)
|
| 86 |
+
model = AutoModel.from_pretrained(
|
| 87 |
+
"Taykhoom/Evo1-1-7B-131K",
|
| 88 |
+
trust_remote_code=True,
|
| 89 |
+
attn_implementation="flash_attention_2", # strongly recommended for long context
|
| 90 |
+
).cuda().eval()
|
| 91 |
+
|
| 92 |
+
seqs = ["ACGTACGTACGT", "GGGTTTAAACCC"]
|
| 93 |
+
inputs = tokenizer(seqs, return_tensors="pt", padding=True).to(model.device)
|
| 94 |
+
|
| 95 |
+
with torch.no_grad():
|
| 96 |
+
out = model(**inputs, output_hidden_states=True)
|
| 97 |
+
|
| 98 |
+
last_hidden = out.last_hidden_state # (B, T, 4096)
|
| 99 |
+
all_layers = out.hidden_states # tuple of (B, T, 4096), len = 34 (embed + 32 blocks + post-norm)
|
| 100 |
+
layer_12_emb = all_layers[12] # often used as a "middle" representation
|
| 101 |
+
```
|
| 102 |
+
|
| 103 |
+
### LM logits
|
| 104 |
+
|
| 105 |
+
```python
|
| 106 |
+
import torch
|
| 107 |
+
from transformers import AutoTokenizer, AutoModelForCausalLM
|
| 108 |
+
|
| 109 |
+
tokenizer = AutoTokenizer.from_pretrained("Taykhoom/Evo1-1-7B-131K", trust_remote_code=True)
|
| 110 |
+
model = AutoModelForCausalLM.from_pretrained(
|
| 111 |
+
"Taykhoom/Evo1-1-7B-131K",
|
| 112 |
+
trust_remote_code=True,
|
| 113 |
+
attn_implementation="flash_attention_2",
|
| 114 |
+
).cuda().eval()
|
| 115 |
+
|
| 116 |
+
inputs = tokenizer(["ACGT"], return_tensors="pt").to(model.device)
|
| 117 |
+
with torch.no_grad():
|
| 118 |
+
logits = model(**inputs).logits # (1, T, 512)
|
| 119 |
+
```
|
| 120 |
+
|
| 121 |
+
### Generation
|
| 122 |
+
|
| 123 |
+
```python
|
| 124 |
+
import torch
|
| 125 |
+
from transformers import AutoTokenizer, AutoModelForCausalLM
|
| 126 |
+
|
| 127 |
+
tokenizer = AutoTokenizer.from_pretrained("Taykhoom/Evo1-1-7B-131K", trust_remote_code=True)
|
| 128 |
+
model = AutoModelForCausalLM.from_pretrained(
|
| 129 |
+
"Taykhoom/Evo1-1-7B-131K",
|
| 130 |
+
trust_remote_code=True,
|
| 131 |
+
attn_implementation="flash_attention_2",
|
| 132 |
+
).cuda().eval()
|
| 133 |
+
|
| 134 |
+
inputs = tokenizer(["ACGT"], return_tensors="pt").to(model.device)
|
| 135 |
+
out = model.generate(**inputs, max_new_tokens=128, do_sample=True, top_k=4, temperature=1.0)
|
| 136 |
+
print(tokenizer.decode(out[0]))
|
| 137 |
+
```
|
| 138 |
+
|
| 139 |
+
`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).
|
| 140 |
+
|
| 141 |
+
### Attention weights
|
| 142 |
+
|
| 143 |
+
```python
|
| 144 |
+
import torch
|
| 145 |
+
from transformers import AutoTokenizer, AutoModel
|
| 146 |
+
|
| 147 |
+
tokenizer = AutoTokenizer.from_pretrained("Taykhoom/Evo1-1-7B-131K", trust_remote_code=True)
|
| 148 |
+
model = AutoModel.from_pretrained(
|
| 149 |
+
"Taykhoom/Evo1-1-7B-131K",
|
| 150 |
+
trust_remote_code=True,
|
| 151 |
+
attn_implementation="eager", # required for output_attentions to populate
|
| 152 |
+
).cuda().eval()
|
| 153 |
+
|
| 154 |
+
inputs = tokenizer(["ACGTACGT"], return_tensors="pt").to(model.device)
|
| 155 |
+
with torch.no_grad():
|
| 156 |
+
out = model(**inputs, output_attentions=True)
|
| 157 |
+
|
| 158 |
+
# out.attentions is a tuple of length 32. Entries at indices not in [8, 16, 24]
|
| 159 |
+
# are None (Hyena blocks have no attention matrix). Entries at [8, 16, 24] are
|
| 160 |
+
# (B, num_heads, T, T) tensors.
|
| 161 |
+
attn_block_8 = out.attentions[8]
|
| 162 |
+
```
|
| 163 |
+
|
| 164 |
+
### Multi-GPU loading (optional)
|
| 165 |
+
|
| 166 |
+
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):
|
| 167 |
+
|
| 168 |
+
```python
|
| 169 |
+
import torch
|
| 170 |
+
from transformers import AutoTokenizer, AutoModel
|
| 171 |
+
|
| 172 |
+
tokenizer = AutoTokenizer.from_pretrained("Taykhoom/Evo1-1-7B-131K", trust_remote_code=True)
|
| 173 |
+
model = AutoModel.from_pretrained(
|
| 174 |
+
"Taykhoom/Evo1-1-7B-131K",
|
| 175 |
+
trust_remote_code=True,
|
| 176 |
+
attn_implementation="flash_attention_2",
|
| 177 |
+
device_map="auto", # auto-shard across all visible GPUs; falls back to single GPU if only one is present
|
| 178 |
+
).eval()
|
| 179 |
+
```
|
| 180 |
+
|
| 181 |
+
Requires `pip install accelerate`.
|
| 182 |
+
|
| 183 |
+
### Fine-tuning
|
| 184 |
+
|
| 185 |
+
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.
|
| 186 |
+
|
| 187 |
+
## Implementation Notes
|
| 188 |
+
|
| 189 |
+
- **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.
|
| 190 |
+
- **Long-context RoPE (`rotary.py`).** The 131k context window is achieved by linearly scaling RoPE position indices by 1/16 (equivalent to extending the 8k base model's effective context by 16x). Implemented in `LinearlyScaledRotaryEmbedding`, which subclasses either `flash_attn.layers.rotary.RotaryEmbedding` (when available) or our pure-PyTorch fallback.
|
| 191 |
+
- **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.
|
| 192 |
+
- **Hyena engine (`engine.py`).** Copied verbatim from the togethercomputer reference (FFT-based long convolution, modal-form prefill).
|
| 193 |
+
- **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.
|
| 194 |
+
- **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).
|
| 195 |
+
- **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"`.
|
| 196 |
+
|
| 197 |
+
## Citation
|
| 198 |
+
|
| 199 |
+
```bibtex
|
| 200 |
+
@article{nguyen2024_evo,
|
| 201 |
+
title = {Sequence modeling and design from molecular to genome scale with {Evo}},
|
| 202 |
+
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.},
|
| 203 |
+
journal = {Science},
|
| 204 |
+
volume = {386},
|
| 205 |
+
number = {6723},
|
| 206 |
+
pages = {eado9336},
|
| 207 |
+
year = {2024},
|
| 208 |
+
doi = {10.1126/science.ado9336}
|
| 209 |
+
}
|
| 210 |
+
```
|
| 211 |
+
|
| 212 |
+
## Credits
|
| 213 |
+
|
| 214 |
+
Original Evo1 model and code by Nguyen et al. Source repo: [evo-design/evo](https://github.com/evo-design/evo). Source checkpoint: [togethercomputer/evo-1-131k-base](https://huggingface.co/togethercomputer/evo-1-131k-base).
|
| 215 |
+
|
| 216 |
+
The HuggingFace conversion code in this repo was authored primarily by [Claude](https://claude.ai/code) and reviewed manually by Taykhoom Dalal.
|
| 217 |
+
|
| 218 |
+
## License
|
| 219 |
+
|
| 220 |
+
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": 131072,
|
| 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": 16.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": true,
|
| 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:8c14f4e255ba241895f8b81c2220794c575082a814bc0a5fe77beb8c371ef0b9
|
| 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:f79d8d96432cf933fd731e3da53cbb2efb75fb43b2fa082d661b2c89468dc331
|
| 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:4a5ba8e23ea9978157a95664a765cddace2c8a4cac23456927f9ce04dfcc1416
|
| 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": 131072,
|
| 10 |
+
"pad_token": "\u0001",
|
| 11 |
+
"byte_level": true
|
| 12 |
+
}
|