"""PyTorch implementation of the heterogeneous hierarchical omni architecture.""" import itertools import math from dataclasses import dataclass import torch from torch import nn from torch.nn import functional as F from transformers import PreTrainedModel from transformers.utils import ModelOutput from .configuration_omni import OmniConfig class Attention(nn.Module): def __init__(self, width, head_dim): super().__init__() self.head_dim = head_dim self.q_proj = nn.Linear(width, width, bias=False) self.k_proj = nn.Linear(width, width, bias=False) self.v_proj = nn.Linear(width, width, bias=False) self.o_proj = nn.Linear(width, width, bias=False) def forward(self, x, causal=False): b, s, d = x.shape def heads(value): return value.reshape(b, s, d // self.head_dim, self.head_dim).transpose(1, 2) q, k, v = (heads(layer(x)) for layer in (self.q_proj, self.k_proj, self.v_proj)) y = F.scaled_dot_product_attention(q, k, v, is_causal=causal) return self.o_proj(y.transpose(1, 2).reshape_as(x)) class Expert(nn.Module): def __init__(self, width, intermediate): super().__init__() self.gate_proj = nn.Linear(width, intermediate, bias=False) self.up_proj = nn.Linear(width, intermediate, bias=False) self.down_proj = nn.Linear(intermediate, width, bias=False) def forward(self, x): return self.down_proj(F.silu(self.gate_proj(x)) * self.up_proj(x)) class SparseMLP(nn.Module): def __init__(self, width, experts, expansion, selected): super().__init__() self.selected = selected self.router = nn.Linear(width, experts, bias=False) if experts > 1 else None self.experts = nn.ModuleList([Expert(width, width * expansion) for _ in range(experts)]) def forward(self, x): if self.router is None: return self.experts[0](x) flat = x.reshape(-1, x.shape[-1]) scores, ids = self.router(flat).topk(self.selected, dim=-1) scores = scores.softmax(-1) result = torch.zeros_like(flat) for expert_id, expert in enumerate(self.experts): tokens, slots = torch.where(ids == expert_id) if tokens.numel(): result = result.index_add( 0, tokens, expert(flat[tokens]) * scores[tokens, slots, None] ) return result.reshape_as(x) class Block(nn.Module): def __init__(self, width, experts, expansion, selected, head_dim): super().__init__() self.attention_norm = nn.RMSNorm(width) self.attention = Attention(width, head_dim) self.ffn_norm = nn.RMSNorm(width) self.mlp = SparseMLP(width, experts, expansion, selected) def forward(self, x, causal=False): x = x + self.attention(self.attention_norm(x), causal) return x + self.mlp(self.ffn_norm(x)) class Chunker(nn.Module): """Learned boundaries, weighted pooling, and explicit source-to-chunk mapping. Single-example sequences avoid treating padding as real observations. Processing a complete observed prefix is bidirectional; next-token targets are not inputs. """ def __init__(self, width, context_dim): super().__init__() self.boundary = nn.Linear(width, 1) self.condition = nn.Linear(context_dim, width, bias=False) def forward(self, x, context): gate = torch.sigmoid(self.boundary(x + self.condition(context)[:, None])) starts = gate[0, :, 0] > 0.5 starts = starts.clone() starts[0] = True assignment = starts.long().cumsum(0) - 1 groups = int(assignment[-1]) + 1 weights = gate[0] sums = x.new_zeros(groups, x.shape[-1]).index_add(0, assignment, x[0] * weights) counts = x.new_zeros(groups, 1).index_add(0, assignment, weights) pooled = (sums / counts.clamp_min(torch.finfo(x.dtype).eps))[None] return pooled, assignment class Stage(nn.Module): def __init__(self, row, config, adaptive): super().__init__() width, depth, experts, expansion, selected = row self.blocks = nn.ModuleList( [Block(width, experts, expansion, selected, config.head_dim) for _ in range(depth)] ) self.chunker = Chunker(width, config.context_dim) if adaptive else None def forward(self, x, context, causal=False): for block in self.blocks: x = block(x, causal) detail = x if self.chunker is None: return x, None, detail pooled, assignment = self.chunker(x, context) return pooled, assignment, detail class Hierarchy(nn.Module): def __init__(self, name, config, adaptive=False): super().__init__() rows = config.stages[name] self.stages = nn.ModuleList([Stage(row, config, adaptive) for row in rows]) self.transitions = nn.ModuleList( [nn.Linear(a[0], b[0], bias=False) for a, b in itertools.pairwise(rows)] ) self.dechunk_projections = ( nn.ModuleList([nn.Linear(b[0], a[0], bias=False) for a, b in itertools.pairwise(rows)]) if adaptive else nn.ModuleList() ) def forward(self, x, context, causal=False): details, assignments = [], [] for i, stage in enumerate(self.stages): x, assignment, detail = stage(x, context, causal) details.append(detail) assignments.append(assignment) if i < len(self.transitions): x = self.transitions[i](x) return x, (details, assignments) def dechunk(self, x, trace): details, assignments = trace for i in reversed(range(len(self.stages))): if assignments[i] is not None: x = x[:, assignments[i]] + details[i] if i: x = self.dechunk_projections[i - 1](x) return x class Encoder(nn.Module): def __init__(self, name, config): super().__init__() width = config.stages[name][0][0] self.name = name self.config = config if name == "text_encoder": self.embedding = nn.Embedding(config.vocab_size, width) elif name == "image_encoder": self.patch_embedding = nn.Conv2d( 3, width, config.patch_size, stride=config.patch_size, bias=False ) elif name == "video_encoder": self.tubelet_embedding = nn.Conv3d( 3, width, (2, config.patch_size, config.patch_size), stride=(2, config.patch_size, config.patch_size), bias=False, ) elif name == "audio_encoder": self.waveform_projection = nn.Linear(config.audio_frame_size, width, bias=False) self.spectrum_projection = nn.Linear( config.audio_frame_size // 2 + 1, width, bias=False ) elif name == "eeg_encoder": self.electrode_projection = nn.Linear(config.eeg_channels, width, bias=False) self.graph_mix = nn.Linear(config.eeg_channels, config.eeg_channels, bias=False) self.hierarchy = Hierarchy(name, config, adaptive=True) def forward(self, value, context, adjacency=None): rank = { "text_encoder": 2, "audio_encoder": 2, "image_encoder": 4, "video_encoder": 5, "eeg_encoder": 3, }[self.name] if value.ndim != rank or value.shape[0] != 1 or 0 in value.shape: raise ValueError( f"{self.name} requires a nonempty rank-{rank} input with batch size one" ) if self.name in ("image_encoder", "video_encoder") and ( value.shape[1] != 3 or any(n % self.config.patch_size for n in value.shape[-2:]) ): raise ValueError("RGB spatial dimensions must be divisible by patch_size") if self.name == "video_encoder" and value.shape[2] % 2: raise ValueError("Video frame count must be divisible by two") if self.name == "eeg_encoder" and value.shape[1] != self.config.eeg_channels: raise ValueError("EEG channel count must match config") if self.name == "text_encoder": x = self.embedding(value) elif self.name == "image_encoder": x = self.patch_embedding(value).flatten(2).transpose(1, 2) elif self.name == "video_encoder": x = self.tubelet_embedding(value).flatten(2).transpose(1, 2) elif self.name == "audio_encoder": frame = self.config.audio_frame_size if value.shape[-1] % frame: raise ValueError("Audio must contain complete frames") frames = value.unfold(-1, frame, frame) spectrum = torch.fft.rfft(frames.float()).abs().to(value.dtype) x = self.waveform_projection(frames) + self.spectrum_projection(spectrum) else: channels = self.config.eeg_channels if adjacency is None or adjacency.shape != (channels, channels): raise ValueError("EEG requires an explicit electrode adjacency matrix") if ( (adjacency < 0).any() or not torch.isfinite(adjacency).all() or (adjacency.sum(-1) <= 0).any() ): raise ValueError("Invalid EEG adjacency") graph = adjacency / adjacency.sum(-1, keepdim=True) mixed = (graph @ value).transpose(1, 2) x = self.electrode_projection(mixed + self.graph_mix(mixed)) position = torch.arange(x.shape[1], device=x.device)[:, None] rate = torch.exp(-math.log(10000) * torch.arange(x.shape[2], device=x.device) / x.shape[2]) x = x + torch.sin(position * rate).to(x.dtype)[None] high, trace = self.hierarchy(x, context) # Fuse reconstructed detail features with the high-level representation. details = self.hierarchy.dechunk(high, trace) return high, details, trace class Fusion(nn.Module): def __init__(self, config): super().__init__() width = config.stages["fusion"][0][0] encoders = sorted(k for k in config.stages if k.endswith("_encoder")) self.high_projections = nn.ModuleDict( {k: nn.Linear(config.stages[k][-1][0], width, bias=False) for k in encoders} ) self.detail_projections = nn.ModuleDict( {k: nn.Linear(config.stages[k][0][0], width, bias=False) for k in encoders} ) self.modality_embedding = nn.Embedding(5, width) self.hierarchy = Hierarchy("fusion", config) def forward(self, features, context): tokens = [] for name, (high, detail, _) in features.items(): i = list(self.high_projections).index(name) token = self.high_projections[name](high) + self.detail_projections[name]( detail.mean(1, keepdim=True) ) tokens.append(token + self.modality_embedding.weight[i]) return self.hierarchy(torch.cat(tokens, dim=1), context)[0] class Decoder(nn.Module): def __init__(self, name, config, output_width): super().__init__() self.input_projection = nn.Linear( config.stages["world_model"][-1][0], config.stages[name][0][0], bias=False ) self.hierarchy = Hierarchy(name, config) self.output_projection = nn.Linear(config.stages[name][-1][0], output_width, bias=False) def forward(self, x, context): x = self.input_projection(x) return self.output_projection(self.hierarchy(x, context, causal=True)[0]) @dataclass class OmniOutput(ModelOutput): next_token_logits: torch.Tensor | None = None audio_codes: torch.Tensor | None = None image_latents: torch.Tensor | None = None video_latents: torch.Tensor | None = None memory_state: torch.Tensor | None = None class OmniModel(PreTrainedModel): config_class = OmniConfig def __init__(self, config): super().__init__(config) for name in (k for k in config.stages if k.endswith("_encoder")): setattr(self, name, Encoder(name, config)) self.fusion = Fusion(config) self.world_input = nn.Linear( config.stages["fusion"][-1][0], config.stages["world_model"][0][0], bias=False ) self.world_model = Hierarchy("world_model", config, adaptive=True) self.world_detail_projection = nn.Linear( config.stages["world_model"][0][0], config.stages["world_model"][-1][0], bias=False ) self.text_head = nn.Linear( config.stages["world_model"][-1][0], config.vocab_size, bias=False ) self.audio_decoder = Decoder( "audio_decoder", config, config.audio_codebooks * config.audio_codebook_size ) self.image_decoder = Decoder("image_decoder", config, 64) self.video_decoder = Decoder("video_decoder", config, 128) self.memory_input = nn.Linear( config.stages["world_model"][-1][0], config.stages["memory_control"][0][0], bias=False ) self.memory_control = Hierarchy("memory_control", config) self.memory_output = nn.Linear( config.stages["memory_control"][-1][0], config.stages["fusion"][0][0], bias=False ) self.post_init() def _init_weights(self, module): if isinstance(module, (nn.Linear, nn.Embedding, nn.Conv2d, nn.Conv3d)): nn.init.normal_(module.weight, std=0.02) if getattr(module, "bias", None) is not None: nn.init.zeros_(module.bias) def forward( self, input_ids, pixel_values=None, audio_values=None, video_values=None, eeg_values=None, eeg_adjacency=None, task_vector=None, memory_state=None, output_modalities=(), ): if input_ids.ndim != 2 or input_ids.shape[0] != 1 or input_ids.shape[1] == 0: raise ValueError("Reference execution requires one nonempty observed prefix per call") context = ( self.text_head.weight.new_zeros(1, self.config.context_dim) if task_vector is None else task_vector ) if context.shape != (1, self.config.context_dim): raise ValueError("Invalid task_vector shape") values = { "text_encoder": input_ids, "image_encoder": pixel_values, "audio_encoder": audio_values, "video_encoder": video_values, "eeg_encoder": eeg_values, } features = { name: getattr(self, name)(value, context, eeg_adjacency) for name, value in values.items() if value is not None } fused = self.fusion(features, context) if memory_state is not None: fused = fused + self.memory_output(memory_state)[:, None] world, trace = self.world_model(self.world_input(fused), context) detail = self.world_model.dechunk(world, trace) world = world + self.world_detail_projection(detail.mean(1, keepdim=True)) summary = world.mean(1) memory = self.memory_control(self.memory_input(summary[:, None]), context)[0][:, 0] outputs = {} if set(output_modalities) - {"audio", "image", "video"}: raise ValueError("Unknown output modality") for name in output_modalities: output = getattr(self, name + "_decoder")(world, context) key = "audio_codes" if name == "audio" else name + "_latents" outputs[key] = output return OmniOutput(next_token_logits=self.text_head(summary), memory_state=memory, **outputs) @torch.no_grad() def generate(self, input_ids, max_new_tokens=8, **kwargs): for _ in range(max_new_tokens): token = self(input_ids, **kwargs).next_token_logits.argmax(-1, keepdim=True) input_ids = torch.cat((input_ids, token), dim=-1) return input_ids OmniModel.register_for_auto_class("AutoModel")