| """ |
| FlowNet Model — Full Architecture Integration. |
| |
| This is the complete model that integrates all novel components: |
| - Particle encoding (not embeddings) |
| - Flow field dynamics (not attention) |
| - Wave interference (not softmax) |
| - Bond system (not fixed weights) |
| - Phase transitions (not fixed depth) |
| - Consistency field (not just cross-entropy) |
| - Topological memory (not vector DB) |
| """ |
|
|
| import torch |
| import torch.nn as nn |
| import torch.nn.functional as F |
| import numpy as np |
| from typing import Dict, Optional, Tuple |
|
|
| from ..core.particle import ParticleEncoder, ParticleState, ParticleCombiner, ParticleUpdater |
| from ..core.flow_field import FlowField, FlowFieldEfficient |
| from ..core.wave_processor import WaveProcessor, WaveAttention |
| from ..core.bond_system import BondSystem, BondState |
| from ..core.phase_engine import PhaseEngine |
| from ..core.consistency_field import ConsistencyField |
| from ..core.topological_memory import TopologicalMemory |
|
|
|
|
| class FlowNetBlock(nn.Module): |
| """A single FlowNet processing block. |
| |
| Equivalent to a Transformer block, but with completely different |
| internal computation: |
| |
| Transformer block: |
| x → LayerNorm → MultiHeadAttention → Residual → LayerNorm → FFN → Residual |
| |
| FlowNet block: |
| x → ParticleUpdate → WaveProcess → BondUpdate → PhaseTransition → Residual |
| """ |
| |
| def __init__( |
| self, |
| d_semantic: int = 256, |
| d_charge: int = 32, |
| d_spin: int = 32, |
| d_memory: int = 128, |
| n_wave_heads: int = 8, |
| d_wave: int = 32, |
| use_efficient_flow: bool = False, |
| local_radius: int = 64, |
| ): |
| super().__init__() |
| self.d_semantic = d_semantic |
| |
| |
| self.particle_updater = ParticleUpdater(d_semantic, d_charge, d_spin, d_memory) |
| |
| |
| self.wave_processor = WaveProcessor(d_semantic, n_wave_heads, d_wave) |
| |
| |
| self.bond_system = BondSystem(d_semantic, d_charge, d_spin) |
| |
| |
| if use_efficient_flow: |
| self.flow_field = FlowFieldEfficient(d_semantic, local_radius=local_radius) |
| else: |
| self.flow_field = FlowField(d_semantic) |
| |
| |
| self.norm1 = nn.LayerNorm(d_semantic) |
| self.norm2 = nn.LayerNorm(d_semantic) |
| |
| |
| self.gate = nn.Sequential( |
| nn.Linear(d_semantic * 2, d_semantic), |
| nn.Sigmoid(), |
| ) |
| |
| def forward( |
| self, |
| particles: ParticleState, |
| bonds: Optional[BondState] = None, |
| ) -> Tuple[ParticleState, BondState, Dict]: |
| """Process one FlowNet block. |
| |
| Args: |
| particles: Input particle state |
| bonds: Previous bond state |
| |
| Returns: |
| Updated particles, bonds, and diagnostics |
| """ |
| residual = particles.semantic |
| |
| |
| particles = self.particle_updater(particles) |
| |
| |
| wave_output, wave_diag = self.wave_processor(particles) |
| |
| |
| gate = self.gate(torch.cat([particles.semantic, wave_output], dim=-1)) |
| particles_semantic = particles.semantic + wave_output * gate |
| |
| |
| particles_semantic = self.norm1(particles_semantic + residual) |
| |
| |
| particles_for_bonds = ParticleState( |
| semantic=particles_semantic, |
| position=particles.position, |
| charge=particles.charge, |
| mass=particles.mass, |
| spin=particles.spin, |
| amplitude=particles.amplitude, |
| phase=particles.phase, |
| memory_trace=particles.memory_trace, |
| ) |
| |
| bonds, bond_output, bond_diag = self.bond_system(particles_for_bonds, bonds) |
| particles_semantic = particles_semantic + bond_output * 0.1 |
| |
| |
| residual2 = particles_semantic |
| |
| particles_for_flow = ParticleState( |
| semantic=particles_semantic, |
| position=particles.position, |
| charge=particles.charge, |
| mass=particles.mass, |
| spin=particles.spin, |
| amplitude=particles.amplitude, |
| phase=particles.phase, |
| memory_trace=particles.memory_trace, |
| ) |
| |
| particles_for_flow, flow_diag = self.flow_field(particles_for_flow) |
| particles_semantic = self.norm2(particles_for_flow.semantic + residual2) |
| |
| |
| final_particles = ParticleState( |
| semantic=particles_semantic, |
| position=particles.position, |
| charge=particles.charge, |
| mass=particles.mass, |
| spin=particles.spin, |
| amplitude=particles_for_flow.amplitude, |
| phase=particles_for_flow.phase, |
| memory_trace=particles_for_flow.memory_trace, |
| ) |
| |
| diagnostics = { |
| 'wave': wave_diag, |
| 'bond': bond_diag, |
| 'flow': flow_diag, |
| } |
| |
| return final_particles, bonds, diagnostics |
|
|
|
|
| class FlowNetModel(nn.Module): |
| """Complete FlowNet model for language modeling. |
| |
| Architecture: |
| |
| 1. Token → Particle encoding |
| 2. N × FlowNet blocks (wave + bond + flow) |
| 3. Phase transition engine (adaptive depth) |
| 4. Consistency field (truth verification) |
| 5. Topological memory (persistent storage) |
| 6. Particle → output decoding |
| |
| This is NOT a Transformer. It processes language through |
| physical dynamics rather than matrix multiplication. |
| """ |
| |
| def __init__( |
| self, |
| vocab_size: int = 32000, |
| d_semantic: int = 256, |
| d_position: int = 64, |
| d_charge: int = 32, |
| d_spin: int = 32, |
| d_memory: int = 128, |
| n_blocks: int = 6, |
| n_wave_heads: int = 8, |
| d_wave: int = 32, |
| use_phase_engine: bool = True, |
| use_consistency: bool = True, |
| use_topological_memory: bool = True, |
| max_seq_len: int = 8192, |
| use_efficient_flow: bool = False, |
| local_radius: int = 64, |
| ): |
| super().__init__() |
| self.vocab_size = vocab_size |
| self.d_semantic = d_semantic |
| self.n_blocks = n_blocks |
| self.use_phase_engine = use_phase_engine |
| self.use_consistency = use_consistency |
| self.use_topological_memory = use_topological_memory |
| |
| |
| self.encoder = ParticleEncoder( |
| vocab_size=vocab_size, |
| d_semantic=d_semantic, |
| d_position=d_position, |
| d_charge=d_charge, |
| d_spin=d_spin, |
| d_memory=d_memory, |
| max_seq_len=max_seq_len, |
| ) |
| |
| |
| self.blocks = nn.ModuleList([ |
| FlowNetBlock( |
| d_semantic=d_semantic, |
| d_charge=d_charge, |
| d_spin=d_spin, |
| d_memory=d_memory, |
| n_wave_heads=n_wave_heads, |
| d_wave=d_wave, |
| use_efficient_flow=use_efficient_flow, |
| local_radius=local_radius, |
| ) |
| for _ in range(n_blocks) |
| ]) |
| |
| |
| if use_phase_engine: |
| self.phase_engine = PhaseEngine( |
| d_semantic=d_semantic, |
| min_steps=2, |
| max_steps=16, |
| ) |
| |
| |
| if use_consistency: |
| self.consistency_field = ConsistencyField( |
| d_semantic=d_semantic, |
| ) |
| |
| |
| if use_topological_memory: |
| self.topological_memory = TopologicalMemory( |
| d_semantic=d_semantic, |
| ) |
| |
| |
| |
| self.output_head = nn.Sequential( |
| nn.Linear(d_semantic + d_memory, d_semantic), |
| nn.GELU(), |
| nn.LayerNorm(d_semantic), |
| nn.Linear(d_semantic, vocab_size), |
| ) |
| |
| |
| self.combiner = ParticleCombiner(d_semantic, d_memory, vocab_size) |
| |
| def forward( |
| self, |
| token_ids: torch.Tensor, |
| labels: Optional[torch.Tensor] = None, |
| store_memory: bool = False, |
| use_stored_memory: bool = True, |
| ) -> Dict: |
| """Forward pass through the complete FlowNet architecture. |
| |
| Args: |
| token_ids: Input token indices [batch, seq_len] |
| labels: Target tokens for loss computation [batch, seq_len] |
| store_memory: Whether to store processed patterns in memory |
| use_stored_memory: Whether to retrieve from topological memory |
| |
| Returns: |
| Dictionary with logits, loss, diagnostics |
| """ |
| batch, seq_len = token_ids.shape |
| device = token_ids.device |
| |
| |
| particles = self.encoder(token_ids) |
| |
| |
| memory_diag = {} |
| if self.use_topological_memory and use_stored_memory and self.training is False: |
| |
| particles.semantic, memory_diag = self.topological_memory( |
| particles.semantic, particles.semantic |
| ) |
| |
| |
| bonds = None |
| block_diagnostics = [] |
| |
| for block in self.blocks: |
| particles, bonds, block_diag = block(particles, bonds) |
| block_diagnostics.append(block_diag) |
| |
| |
| phase_diag = {} |
| if self.use_phase_engine: |
| |
| def flow_fn(p): |
| updated, _, diag = self.blocks[0](p, bonds) |
| return updated, diag |
| |
| particles, phase_diag = self.phase_engine( |
| particles, flow_fn=flow_fn |
| ) |
| |
| |
| consistency_diag = {} |
| if self.use_consistency: |
| particles.semantic, consistency_diag = self.consistency_field( |
| particles.semantic |
| ) |
| |
| |
| if self.use_topological_memory and store_memory: |
| |
| for b in range(batch): |
| self.topological_memory.store(particles.semantic[b]) |
| |
| |
| |
| combined = torch.cat([particles.semantic, particles.memory_trace], dim=-1) |
| logits = self.output_head(combined) |
| |
| |
| loss = None |
| if labels is not None: |
| |
| shift_logits = logits[..., :-1, :].contiguous() |
| shift_labels = labels[..., 1:].contiguous() |
| loss = F.cross_entropy( |
| shift_logits.reshape(-1, self.vocab_size), |
| shift_labels.reshape(-1), |
| ignore_index=-100, |
| ) |
| |
| |
| if self.use_consistency: |
| energy_penalty = consistency_diag.get('final_energy', 0) |
| if isinstance(energy_penalty, torch.Tensor): |
| loss = loss + energy_penalty * 0.01 |
| |
| |
| if self.use_phase_engine: |
| |
| pass |
| |
| |
| diagnostics = { |
| 'blocks': block_diagnostics, |
| 'phase': phase_diag, |
| 'consistency': consistency_diag, |
| 'memory': memory_diag, |
| 'particles': { |
| 'mean_amplitude': particles.amplitude.mean().item(), |
| 'mean_phase': particles.phase.mean().item(), |
| 'phase_coherence': torch.abs( |
| torch.exp(1j * particles.phase).mean() |
| ).item(), |
| }, |
| } |
| |
| return { |
| 'logits': logits, |
| 'loss': loss, |
| 'diagnostics': diagnostics, |
| 'particles': particles, |
| } |
| |
| def generate( |
| self, |
| token_ids: torch.Tensor, |
| max_new_tokens: int = 100, |
| temperature: float = 1.0, |
| top_k: int = 50, |
| top_p: float = 0.9, |
| consistency_check: bool = True, |
| ) -> torch.Tensor: |
| """Generate tokens autoregressively. |
| |
| Unlike standard generation, FlowNet can: |
| 1. Use topological memory to recall relevant patterns |
| 2. Check consistency of generated tokens |
| 3. Adapt computation depth based on difficulty |
| """ |
| self.eval() |
| generated = token_ids.clone() |
| |
| with torch.no_grad(): |
| for _ in range(max_new_tokens): |
| |
| output = self.forward( |
| generated, |
| store_memory=False, |
| use_stored_memory=True, |
| ) |
| |
| logits = output['logits'][:, -1, :] |
| |
| |
| if consistency_check and self.use_consistency: |
| |
| top_logits, top_indices = logits.topk(top_k) |
| |
| |
| |
| pass |
| |
| |
| logits = logits / temperature |
| |
| |
| if top_k > 0: |
| indices_to_remove = logits < torch.topk(logits, top_k)[0][..., -1, None] |
| logits[indices_to_remove] = float('-inf') |
| |
| |
| if top_p < 1.0: |
| sorted_logits, sorted_indices = torch.sort(logits, descending=True) |
| cumulative_probs = torch.cumsum(F.softmax(sorted_logits, dim=-1), dim=-1) |
| sorted_indices_to_remove = cumulative_probs > top_p |
| sorted_indices_to_remove[..., 1:] = sorted_indices_to_remove[..., :-1].clone() |
| sorted_indices_to_remove[..., 0] = 0 |
| indices_to_remove = sorted_indices_to_remove.scatter( |
| 1, sorted_indices, sorted_indices_to_remove |
| ) |
| logits[indices_to_remove] = float('-inf') |
| |
| |
| probs = F.softmax(logits, dim=-1) |
| next_token = torch.multinomial(probs, num_samples=1) |
| |
| generated = torch.cat([generated, next_token], dim=1) |
| |
| return generated |
|
|
|
|
| class FlowNetForClassification(nn.Module): |
| """FlowNet variant for sequence classification tasks.""" |
| |
| def __init__( |
| self, |
| vocab_size: int = 32000, |
| d_semantic: int = 256, |
| n_classes: int = 2, |
| **kwargs |
| ): |
| super().__init__() |
| self.model = FlowNetModel(vocab_size=vocab_size, d_semantic=d_semantic, **kwargs) |
| self.classifier = nn.Sequential( |
| nn.Linear(d_semantic + 128, 256), |
| nn.GELU(), |
| nn.Dropout(0.1), |
| nn.Linear(256, n_classes), |
| ) |
| |
| def forward(self, token_ids: torch.Tensor, labels: Optional[torch.Tensor] = None): |
| output = self.model(token_ids, store_memory=False) |
| particles = output['particles'] |
| |
| |
| combined = torch.cat([particles.semantic, particles.memory_trace], dim=-1) |
| phase_weights = F.softmax(torch.cos(particles.phase), dim=-1) |
| pooled = (combined * phase_weights.unsqueeze(-1)).sum(dim=1) |
| |
| logits = self.classifier(pooled) |
| |
| loss = None |
| if labels is not None: |
| loss = F.cross_entropy(logits, labels) |
| |
| return {'logits': logits, 'loss': loss} |
|
|