Views
No views yet
NVIDIA Transformer Engine required. This variant uses FP8 input projections (use_fp8_input_projections=True) which require TransformerEngine and a Hopper-class GPU (H100 / H200). Install with:pip install transformer-engine[pytorch]>=2.3.0
.pt checkpoint that requires the evo2 and vortex Python packages just to instantiate the model. Even with both installed, common pain points remain:from_pretrained, no AutoModel, no AutoModelForCausalLM - the original ships a thin Python wrapper around a custom nn.Module.(B, H, T, T) attention matrix.evo2 + vortex packages mandatory even for inference.max_abs_diff = 0.000e+00 at every layer; see Parity Verification). Loads with from_pretrained and trust_remote_code=True - no evo2 / vortex install needed.| Parameter | Value |
|---|---|
| Total parameters | ~18.5B |
| Architecture | StripedHyena 2 (interleaved Hyena cascade + MHA blocks) |
| Layers | 24 |
| Attention heads | 64 |
| Embedding dimension | 8192 |
| Inner MLP size | 22 528 |
| Vocabulary size | 512 (UTF-8 byte-level) |
| Attention block indices | 3, 10, 17 (3 blocks total) |
| Hyena block indices | all others (21 blocks: hcs / hcm / hcl pattern) |
| Positional encoding | RoPE (base = 1 000 000), linearly scaled by 128x |
| Max sequence length | 1 048 576 |
| Training dtype | bfloat16 (Hyena modal-form log_poles / residues and rotary inv_freq kept in fp32) |
| FP8 input projections | yes (TransformerEngine required) |
| Weight format | model.safetensors (18.5B params, 8 files) |
arcinstitute/evo2_20b (evo2_20b.pt).max_abs_diff = 0.000e+00) to the vortex reference at every block output after reconstructing the published checkpoint's bf16-rounded inv_freq from base and dim in fp32 on both sides. Parity uses attn_implementation="sdpa" in bf16, with FP8 input projections disabled on both sides where applicable. Logits from Evo2ForCausalLM were also bit-exact (top-1 agreement: 128/128 positions on a 128-byte ACGT input). This verifies conversion fidelity under that controlled configuration; it does not claim bit-exact output against the upstream default Flash Attention / FP8 execution path. Verified on H100 with PyTorch 2.7 / CUDA 12.inv_freq recomputation. A checkpoint-loaded rotary inv_freq can contain bf16-rounded values even when its destination buffer is fp32. The remote model code treats inv_freq as non-persistent runtime state and reconstructs it in fp32 from base and dim during construction, after checkpoint loading, and whenever the RoPE cache is rebuilt.SelfAttention (use_flash_attn=False) calls F.scaled_dot_product_attention, not a textbook softmax loop. Parity is measured with attn_implementation="sdpa" on our side. Using "eager" (textbook einsum + softmax) is mathematically equivalent but not bit-exact in bf16; using "flash_attention_2" (the recommended runtime backend) is also not bit-exact but agrees within bf16 noise.Taykhoom/Evo2-* collection for our minimal HF ports.| Model | Size | Context | Notes |
|---|---|---|---|
| Taykhoom/Evo2-1B-8K | 1B | 8 192 | |
| Taykhoom/Evo2-7B-8K | 7B | 8 192 | |
| Taykhoom/Evo2-7B-262K | 7B | 262 144 | |
| Taykhoom/Evo2-7B-1M | 7B | 1 048 576 | |
| Taykhoom/Evo2-20B-1M | 20B | 1 048 576 | <- this model |
| Taykhoom/Evo2-40B-8K | 40B | 8 192 | |
| Taykhoom/Evo2-40B-1M | 40B | 1 048 576 |
Note on dtype. Bfloat16 is recommended. Float32 is also supported, while float16 is rejected because the modal filters are numerically unstable in FP16. Hyenalog_poles/residuesand rotaryinv_freqremain fp32 for numerical stability.
Note on padding. Attention masks accept boolean, integer, or floating-point 1/0 values. Padded keys are excluded from attention.
Note on attention backend. By HuggingFace convention this model defaults toattn_implementation="sdpa"(F.scaled_dot_product_attention) since SDPA needs onlytorchand runs on any GPU. The original Arc Institute Evo 2 inference path uses flash_attention_2, which is faster on long sequences but requires a separateflash-attninstall. All usage examples below opt in toflash_attention_2explicitly because most real users will want it. Drop the kwarg (or pass"sdpa"/"eager") if you don't haveflash-attninstalled.
1import torch
2from transformers import AutoTokenizer, AutoModel
3
4tokenizer = AutoTokenizer.from_pretrained("Taykhoom/Evo2-20B-1M", trust_remote_code=True)
5model = AutoModel.from_pretrained(
6 "Taykhoom/Evo2-20B-1M",
7 trust_remote_code=True,
8 attn_implementation="flash_attention_2", # or "sdpa" (default) or "eager"
9).cuda().eval()
10
11seqs = ["ACGTACGTACGT", "GGGTTTAAACCC"]
12inputs = tokenizer(seqs, return_tensors="pt", padding=True).to(model.get_input_embeddings().weight.device)
13
14with torch.no_grad():
15 out = model(**inputs, output_hidden_states=True)
16
17last_hidden = out.last_hidden_state # (B, T, 8192)
18all_layers = out.hidden_states # tuple of (B, T, 8192), len = 26
19middle_layer = all_layers[12] # input to block 12 (= output of block 11)blocks.28.mlp.l3 for the 7B model. For this variant, the middle-block value is blocks[12].pre_norm(hidden_states[12]):1import torch
2from transformers import AutoTokenizer, AutoModel
3
4tokenizer = AutoTokenizer.from_pretrained("Taykhoom/Evo2-20B-1M", trust_remote_code=True)
5model = AutoModel.from_pretrained(
6 "Taykhoom/Evo2-20B-1M",
7 trust_remote_code=True,
8 attn_implementation="flash_attention_2",
9).cuda().eval()
10
11inputs = tokenizer(["ACGTACGTACGT"], return_tensors="pt").to(model.get_input_embeddings().weight.device)
12with torch.no_grad():
13 out = model(**inputs, output_hidden_states=True)
14 pre_norm_middle = model.backbone.blocks[12].pre_norm(
15 out.hidden_states[12]
16 ) # (B, T, 8192)output_hidden_states). The pattern above applies the block's pre_norm submodule directly to the corresponding hidden_states entry; this gives a bit-identical result to registering a forward hook on backbone.blocks[i].pre_norm and is simpler than using PyTorch hooks. Note that it does require running the full forward pass and then re-applying pre_norm, so a forward hook is more efficient if you only need this single intermediate.1import torch
2from transformers import AutoTokenizer, AutoModelForCausalLM
3
4tokenizer = AutoTokenizer.from_pretrained("Taykhoom/Evo2-20B-1M", trust_remote_code=True)
5model = AutoModelForCausalLM.from_pretrained(
6 "Taykhoom/Evo2-20B-1M", trust_remote_code=True,
7 attn_implementation="flash_attention_2",
8).cuda().eval()
9
10inputs = tokenizer(["ACGT"], return_tensors="pt").to(model.get_input_embeddings().weight.device)
11with torch.no_grad():
12 logits = model(**inputs).logits # (1, T, 512)1import torch
2from transformers import AutoTokenizer, AutoModelForCausalLM
3
4tokenizer = AutoTokenizer.from_pretrained("Taykhoom/Evo2-20B-1M", trust_remote_code=True)
5model = AutoModelForCausalLM.from_pretrained(
6 "Taykhoom/Evo2-20B-1M", trust_remote_code=True,
7 attn_implementation="flash_attention_2",
8).cuda().eval()
9
10
11inputs = tokenizer(["ACGT"], return_tensors="pt").to(model.get_input_embeddings().weight.device)
12out = model.generate(**inputs, max_new_tokens=128, do_sample=True, top_k=4, temperature=1.0)
13print(tokenizer.decode(out[0]))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.1import torch
2from transformers import AutoTokenizer, AutoModel
3
4tokenizer = AutoTokenizer.from_pretrained("Taykhoom/Evo2-20B-1M", trust_remote_code=True)
5model = AutoModel.from_pretrained(
6 "Taykhoom/Evo2-20B-1M",
7 trust_remote_code=True,
8 attn_implementation="eager", # required for output_attentions to populate
9).cuda().eval()
10
11inputs = tokenizer(["ACGTACGT"], return_tensors="pt").to(model.get_input_embeddings().weight.device)
12with torch.no_grad():
13 out = model(**inputs, output_attentions=True)
14
15# out.attentions is a tuple of length 24. Entries at indices not in
16# [3, 10, 17] are None (Hyena blocks have no attention matrix).
17# The 3 attention block(s) at those indices return a (B, num_heads, T, T) tensor.
18attn_block_3 = out.attentions[3]device_map="auto":1from transformers import AutoModelForCausalLM
2# pip install accelerate
3model = AutoModelForCausalLM.from_pretrained(
4 "Taykhoom/Evo2-20B-1M", trust_remote_code=True,
5 device_map="auto", # accelerate will shard across all visible GPUs
6)base_model_prefix = "backbone" exposes the raw StripedHyena2 module through .base_model. Its public forward accepts standard HF arguments (input_ids, attention_mask, past_key_values, use_cache, output_hidden_states, output_attentions, return_dict) and returns BaseModelOutputWithPast; AutoModel delegates to this same path.inv_freq kept exact in fp32 (critical for parity). The geometric series inv_freq[i] = 1 / base^(2i/dim) loses ~7 bits of mantissa when rounded to bf16, which shifts the cos/sin tables and adds Q/K error at every attention layer. inv_freq is non-persistent runtime state: the remote code reconstructs it from base and dim in fp32 after loading and before rebuilding the RoPE cache. Rotary multiplication is also performed in fp32 before casting back to the activation dtype, matching Flash Attention 2.log_poles / residues kept in fp32 (critical for stability). The Hyena cascade long (hcl) blocks parameterize an IIR filter via log_poles and residues; bf16 quantisation makes the recurrence numerically unstable. Both are stored as fp32 in the safetensors, covered by _keep_in_fp32_modules, and explicitly restored to fp32 after from_pretrained completes.attn_implementation switching (attention.py). Three backends, selected via the standard HF attn_implementation kwarg to from_pretrained (default chosen by HF auto-detection - typically "sdpa"):
"sdpa": calls F.scaled_dot_product_attention. Bit-exact with vortex's reference path (when vortex uses use_flash_attn=False)."flash_attention_2": calls flash_attn.flash_attn_qkvpacked_func, the same attention backend used by the default Arc Institute inference path; faster on long sequences; requires flash-attn installed."eager": textbook einsum + softmax(QK^T) + einsum. Slowest, used internally when output_attentions=True so the attention matrix is materialized.hyena.py). StripedHyena 2 has 4 block types, dispatched by layer_idx membership in four config lists: attn_layer_idxs (MHA + RoPE), hcl_layer_idxs (modal-form IIR via FFT), hcm_layer_idxs (medium FIR cascade, inner length 128), hcs_layer_idxs (short FIR cascade, inner length 7). The disjoint union must equal range(num_layers).TELinear with pure-PyTorch fallback (layers.py). Hyena cascade blocks use a TransformerEngine-backed input projection (3x hidden_size output) that supports FP8 quantisation. When TE is not installed, a TELinear fallback class with the same state_dict layout (weight, bias) is used - checkpoints are cross-loadable.max_seqlen up front.tokenization_evo2.py). Byte-level UTF-8, vocab_size = 512. Pad token = byte \x01. EOS = byte \x00 (set as eos_token_id in generation_config.json). Tokenizer does not add EOS at encoding time - matches the original Evo 2 inference pipeline.torch, transformers, numpy, safetensors, huggingface_hub. transformer-engine[pytorch] is required for this variant's FP8 input projections. accelerate is optional but recommended if you want to load with device_map="auto" for multi-GPU sharding. flash_attn is optional (only needed if you pass attn_implementation="flash_attention_2").1@article{brixi2026_evo2,
2 title = {Genome modelling and design across all domains of life with {Evo} 2},
3 author = {Brixi, Garyk and Durrant, Matthew G. and Ku, Jerome and Naghipourfar, Mohsen and Poli, Michael and Sun, Gwanggyu and Brockman, Greg and Chang, Daniel and Fanton, Alison and Gonzalez, Gabriel A. and King, Samuel H. and Li, David B. and Merchant, Aditi T. and Nguyen, Eric and Ricci-Tam, Chiara and Romero, David W. and Schmok, Jonathan C. and Taghibakhshi, Ali and Vorontsov, Anton and Yang, Brandon and Deng, Myra and Gorton, Liv and Nguyen, Nam and Wang, Nicholas K. and Pearce, Michael T. and Simon, Elana and Adams, Etowah and Amador, Zachary J. and Ashley, Euan A. and Baccus, Stephen A. and Dai, Haoyu and Dillmann, Steven and Ermon, Stefano and Guo, Daniel and Herschl, Michael H. and Ilango, Rajesh and Janik, Ken and Lu, Amy X. and Mehta, Reshma and Mofrad, Mohammad R. K. and Ng, Madelena Y. and Pannu, Jaspreet and {R{\'e}}, Christopher and St. John, John and Sullivan, Jeremy and Tey, Joseph and Viggiano, Ben and Zhu, Kevin and Zynda, Greg and Balsam, Daniel and Collison, Patrick and Costa, Anthony B. and Hernandez-Boussard, Tina and Ho, Eric and Liu, Ming-Yu and McGrath, Thomas and Powell, Kimberly and Pinglay, Sudarshan and Burke, Dave P. and Goodarzi, Hani and Hsu, Patrick D. and Hie, Brian L.},
4 journal = {Nature},
5 volume = {652},
6 number = {8112},
7 pages = {1349--1361},
8 year = {2026},
9 doi = {10.1038/s41586-026-10176-5}
10}