Any-to-Any
Transformers
Safetensors
multilingual
spev
feature-extraction
multimodal
text
audio
image
video
decision-model
choice
qwen3-omni
lora
custom-code
custom_code
Instructions to use SpragAI/SPEV with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use SpragAI/SPEV with Transformers:
# pip install -U transformers accelerate # Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("SpragAI/SPEV", trust_remote_code=True, device_map="auto") - Notebooks
- Google Colab
- Kaggle
Download token_operations.py from SpragAI/SPEV: direct link, hf CLI and curl.
- Browser
- Download file 4.13 kB
-
https://huggingface.co/SpragAI/SPEV/resolve/main/token_operations.py
- Command line
-
hf download hf://SpragAI/SPEV/token_operations.py
-
curl -L -o token_operations.py https://huggingface.co/SpragAI/SPEV/resolve/main/token_operations.py
4.13 kB
| """Reuse request-local gather indices for fixed-shape token-local operations.""" | |
| from collections import defaultdict | |
| from .branch_attention import REQUEST | |
| from contextvars import ContextVar | |
| import types | |
| import torch | |
| DEPTH=ContextVar('spev_vectorized_token_ops_depth',default=0) | |
| class PackingCache: | |
| def __init__(self): | |
| self.tree=None;self.device=None;self.plan=None | |
| def __call__(self,tree,device): | |
| if tree is self.tree and device==self.device:return self.plan | |
| buckets=defaultdict(list);start=tree.prefix_length | |
| for index,length in enumerate(tree.branch_lengths): | |
| buckets[((length+31)//32)*32].append((index,start,length));start+=length | |
| assert start==tree.length | |
| blocks=[];restore=[None]*len(tree.branch_lengths);offset=0 | |
| for width,branches in sorted(buckets.items()): | |
| for begin in range(0,len(branches),8): | |
| block=branches[begin:begin+8];indices=[0]*(8*width);valid=[False]*(8*width) | |
| for slot,(index,start,length) in enumerate(block): | |
| a=slot*width;indices[a:a+length]=range(start,start+length);valid[a:a+length]=[True]*length | |
| restore[index]=torch.arange(length,device=device)+offset+a | |
| blocks.append((width,torch.tensor(indices,device=device,dtype=torch.long),torch.tensor(valid,device=device,dtype=torch.bool))) | |
| offset+=8*width | |
| order=torch.cat(restore) if restore else torch.empty(0,device=device,dtype=torch.long) | |
| self.tree=tree;self.device=device;self.plan=(blocks,order) | |
| return self.plan | |
| def grouped_forward(original,tree_getter,plan_getter=None): | |
| cache=PackingCache() if plan_getter is None else plan_getter | |
| def forward(module,value,*args,**kwargs): | |
| if DEPTH.get():return original(value,*args,**kwargs) | |
| tree=tree_getter() | |
| if tree is None:raise ValueError('Grouped token operations require a tree layout') | |
| if value.ndim not in (2,3) or value.shape[-2]!=tree.length:raise ValueError('Grouped token operations require the packed token sequence') | |
| if value.ndim==3 and value.shape[0]!=1:raise ValueError('Grouped token operations support one packed request') | |
| x=value[0] if value.ndim==3 else value | |
| blocks,order=cache(tree,x.device);token=DEPTH.set(DEPTH.get()+1) | |
| try: | |
| prefix=original(x[:tree.prefix_length].contiguous(),*args,**kwargs);outputs=[] | |
| for width,indices,valid in blocks: | |
| packed=x.index_select(0,indices).masked_fill(~valid[:,None],0).reshape(8,width,x.shape[-1]) | |
| output=original(packed,*args,**kwargs) | |
| assert isinstance(output,torch.Tensor) and output.shape[:2]==packed.shape[:2] | |
| outputs.append(output.reshape(8*width,output.shape[-1])) | |
| branch=(outputs[0] if len(outputs)==1 else torch.cat(outputs,dim=0)).index_select(0,order) if outputs else prefix[:0] | |
| output=torch.cat([prefix,branch],dim=0) | |
| return output[None] if value.ndim==3 else output | |
| finally:DEPTH.reset(token) | |
| return forward | |
| def install(model,*,linears,moe): | |
| if moe:raise ValueError('MoE dispatch is not a token-local linear operation') | |
| originals=[] | |
| def cache(tree, device): | |
| request=REQUEST.get() | |
| attention_cache=request[1] | |
| if not hasattr(attention_cache, "packing"): | |
| attention_cache.packing=PackingCache() | |
| return attention_cache.packing(tree,device) | |
| getter=lambda:REQUEST.get()[0] if REQUEST.get() else None | |
| if linears: | |
| for layer in model.backbone.model.layers: | |
| for module in list(layer.modules()): | |
| is_lora=all(hasattr(module,name) for name in ['a','b','base','scale']) | |
| if isinstance(module,torch.nn.Linear) or is_lora: | |
| original=module.forward;originals.append((module,original)) | |
| module.forward=types.MethodType(grouped_forward(original,getter,cache),module) | |
| def restore(): | |
| for module,forward in reversed(originals):module.forward=forward | |
| return restore | |