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 decision_head.py from SpragAI/SPEV: direct link, hf CLI and curl.
- Browser
- Download file 6.37 kB
-
https://huggingface.co/SpragAI/SPEV/resolve/main/decision_head.py
- Command line
-
hf download hf://SpragAI/SPEV/decision_head.py
-
curl -L -o decision_head.py https://huggingface.co/SpragAI/SPEV/resolve/main/decision_head.py
6.37 kB
| # SPDX-License-Identifier: Apache-2.0 | |
| # SPDX-FileCopyrightText: Copyright contributors to the vLLM-Omni project | |
| """Question-local evidence routing for SPEV decision checkpoints.""" | |
| from dataclasses import dataclass | |
| import torch | |
| from torch import nn | |
| from torch.nn import functional as F | |
| class EvidenceBlock(nn.Module): | |
| def __init__(self, width: int, heads: int, ff: int): | |
| super().__init__() | |
| self.qnorm = nn.LayerNorm(width) | |
| self.mnorm = nn.LayerNorm(width) | |
| self.attn = nn.MultiheadAttention(width, heads, batch_first=True, dropout=0.0) | |
| self.fnorm = nn.LayerNorm(width) | |
| self.ff = nn.Sequential(nn.Linear(width, ff), nn.GELU(), nn.Linear(ff, width)) | |
| def forward(self, query, memory, memory_pad): | |
| memory = self.mnorm(memory) | |
| value, _ = self.attn(self.qnorm(query), memory, memory, key_padding_mask=memory_pad, need_weights=False) | |
| query = query + value | |
| return query + self.ff(self.fnorm(query)) | |
| class IsolatedDecisionHead(nn.Module): | |
| def __init__(self, hidden: int, width: int, heads: int, ff: int, depth: int): | |
| super().__init__() | |
| self.norm = nn.LayerNorm(hidden) | |
| self.memory = nn.Linear(hidden, width, bias=False) | |
| self.qproj = nn.Linear(hidden, width, bias=False) | |
| self.oqproj = nn.Linear(hidden, width, bias=False) | |
| self.globalproj = nn.Linear(hidden, width, bias=False) | |
| self.context = nn.Linear(hidden, width, bias=False) | |
| self.lexical = nn.Linear(hidden, width, bias=False) | |
| self.types = nn.Embedding(3, width) | |
| self.evidence = nn.ModuleList([EvidenceBlock(width, heads, ff) for _ in range(depth)]) | |
| self.summarynorm = nn.LayerNorm(width) | |
| self.joint = nn.ModuleList( | |
| [ | |
| nn.TransformerDecoderLayer( | |
| width, heads, ff, dropout=0.0, activation="gelu", batch_first=True, norm_first=True | |
| ) | |
| for _ in range(depth) | |
| ] | |
| ) | |
| self.fnorm = nn.LayerNorm(width) | |
| self.onorm = nn.LayerNorm(width) | |
| self.scorer = nn.Sequential(nn.Linear(width * 4, width), nn.GELU(), nn.Linear(width, 1)) | |
| self.prior_scale = nn.Parameter(torch.zeros(())) | |
| self.joint_scale = nn.Parameter(torch.zeros(())) | |
| self.gate = nn.Parameter(torch.zeros(())) | |
| def forward(self, batch: dict[str, torch.Tensor]) -> torch.Tensor: | |
| memory = self.memory(self.norm(batch["memory"])) | |
| question = self.norm(batch["questions"]) | |
| context = self.norm(batch["options"]) | |
| global_feature = self.norm(batch["global"]) | |
| options = self.context(context) + self.lexical(batch["lexical"]) + self.oqproj(question) | |
| for block in self.evidence: | |
| options = block(options, memory, batch["memory_pad"]) | |
| fields = self.qproj(question) | |
| membership = ~batch["option_pad"][:, None, :] | |
| weights = torch.einsum("bqd,bcd->bqc", fields, options) / memory.shape[-1] ** 0.5 | |
| weights = weights.masked_fill(~membership, -1e9).softmax(-1) * membership | |
| summary = torch.einsum("bqc,bcd->bqd", weights, options) | |
| fields = fields + self.summarynorm(summary) + self.globalproj(global_feature)[:, None, :] | |
| fields = fields + self.types(batch["types"]) | |
| for block in self.joint: | |
| fields = block(fields, memory, memory_key_padding_mask=batch["memory_pad"]) | |
| fields = self.fnorm(fields).expand(-1, options.shape[1], -1) | |
| options = self.onorm(options) | |
| prior = ( | |
| F.normalize(question + global_feature[:, None, :], dim=-1) * F.normalize(batch["lexical"], dim=-1) | |
| ).sum(-1) * self.prior_scale.clamp(max=4.605170186).exp() | |
| joint = F.cosine_similarity(fields, options, dim=-1) * self.joint_scale.clamp(max=4.605170186).exp() | |
| residual = self.scorer(torch.cat([fields, options, fields * options, (fields - options).abs()], -1)).squeeze(-1) | |
| return prior + self.gate.sigmoid() * (joint + residual) | |
| class QuestionFeatures: | |
| memory: torch.Tensor | |
| question: torch.Tensor | |
| options: torch.Tensor | |
| lexical: torch.Tensor | |
| global_feature: torch.Tensor | |
| question_type: int | |
| def score_questions(head: IsolatedDecisionHead, records: list[QuestionFeatures]) -> list[torch.Tensor]: | |
| """Score all questions in a request batch with one head invocation.""" | |
| if not records: | |
| raise ValueError("At least one question is required") | |
| device = head.norm.weight.device | |
| hidden = head.norm.normalized_shape[0] | |
| memories = max(len(record.memory) for record in records) | |
| candidates = max(len(record.options) for record in records) | |
| batch = { | |
| name: torch.zeros(shape, device=device, dtype=torch.float32) | |
| for name, shape in { | |
| "memory": (len(records), memories, hidden), | |
| "questions": (len(records), 1, hidden), | |
| "options": (len(records), candidates, hidden), | |
| "lexical": (len(records), candidates, hidden), | |
| "global": (len(records), hidden), | |
| }.items() | |
| } | |
| batch["memory_pad"] = torch.ones(len(records), memories, device=device, dtype=torch.bool) | |
| batch["option_pad"] = torch.ones(len(records), candidates, device=device, dtype=torch.bool) | |
| batch["types"] = torch.tensor([[record.question_type] for record in records], device=device) | |
| for index, record in enumerate(records): | |
| if not len(record.memory) or not len(record.options) or record.question_type not in (0, 1, 2): | |
| raise ValueError("Invalid question features") | |
| if record.lexical.shape != record.options.shape: | |
| raise ValueError("Criterion embeddings must match candidate features") | |
| for name, value in (("memory", record.memory), ("options", record.options), ("lexical", record.lexical)): | |
| batch[name][index, : len(value)] = value.to(device=device, dtype=torch.float32) | |
| batch["questions"][index, 0] = record.question.to(device=device, dtype=torch.float32) | |
| batch["global"][index] = record.global_feature.to(device=device, dtype=torch.float32) | |
| batch["memory_pad"][index, : len(record.memory)] = False | |
| batch["option_pad"][index, : len(record.options)] = False | |
| values = head(batch) | |
| return [values[index, : len(record.options)] for index, record in enumerate(records)] | |