# 🧠 NeuroBrix Universal Architecture Analysis

**Date**: 2025-12-02 (Original) | **Updated**: 2026-02-08
**Scope**: Full HuggingFace Snapshots + Online Repository Analysis
**System Version**: Post-Package Restructure (pip-installable neurobrix)

---

## 📊 EXECUTIVE SUMMARY

### Models Analyzed: 23 local snapshots + HuggingFace patterns

| Category | Count | Architectures |
|----------|-------|---------------|
| **Image Generation** | 8 | Flux, FLUX.2, SDXL, PixArt(3), Sana |
| **Video Generation** | 2 | SVD, Zeroscope |
| **Audio Generation** | 3 | AudioLDM, Bark, MusicGen |
| **Speech** | 3 | Whisper(2), SpeechT5 |
| **Upscalers** | 7+ | Swin2SR(3), Real-ESRGAN(12+) |

---

## 🔍 KEY FINDINGS

### ✅ Architecture IS Universal - Now Production-Ready

The current NeuroBrix architecture handles ALL discovered model types through:

1. **All models are neural networks**: `output = forward(inputs)`
2. **All configs use similar patterns**: dimension keys like `hidden_size`, `num_layers`, `in_channels`
3. **Multi-component pipelines** share common patterns across families
4. **NBX v0.1 container format**: Universal `.nbx` package format with JSON manifests
5. **ZERO HARDCODE principle**: All dimensions derived from manifest/topology/runtime JSON files

### 📦 SYSTEM ARCHITECTURE (February 2026)

**Package Structure (pip-installable)**:
```
src/neurobrix/              ← pip install neurobrix
├── cli.py                  ← Entry: neurobrix run, import, list, remove
├── core/                   ← Runtime engine
│   ├── runtime/            ← RuntimeExecutor, GraphExecutor
│   ├── nbx/                ← NBX container format
│   ├── config/             ← hardware/, vendors/ YAML configs
│   ├── dtype/              ← DtypeEngine (AMP rules)
│   └── flow/               ← iterative_process, autoregressive_generation
├── kernels/                ← Triton kernels (opt-in via --triton)
└── config/
    ├── hardware/           ← v100-32g.yml, c4140-4xv100-custom-nvlink.yml
    └── vendors/            ← diffusers.yml

forge/                      ← PRIVATE (requires pip install -e .)
├── forge.py                ← Entry: snap, build, trace, publish
├── importer/               ← NBX builder (was: importer/)
├── tracer/                 ← Graph capture (was: trace/)
├── vendors/                ← Vendored diffusers
└── config/families/        ← image.yml, llm.yml templates
```

### ⚠️ GAPS IDENTIFIED [ARCHIVED - MOSTLY RESOLVED]

---

## 📦 NBX v0.1 CONTAINER FORMAT (Universal Package)

### Structure

The `.nbx` file is a ZIP archive containing:

```
model.nbx (ZIP archive)
├── manifest.json           ← Model metadata (family, generation_type, components)
├── topology.json           ← Execution flow + component bindings
├── runtime/
│   ├── defaults.json       ← User-tunable defaults (batch_size, steps, dtype)
│   ├── variables.json      ← Variable contracts with resolvers
│   └── execution.json      ← Flow definitions (iterative_process, autoregressive)
├── components/
│   ├── transformer/
│   │   ├── graph.json      ← TensorDAG (ops, edges, input_spec, output_spec)
│   │   ├── runtime.json    ← Component attributes (state_channels, sample_size)
│   │   ├── profile.json    ← Hardware metrics for Prism solver
│   │   └── weights/        ← Sharded tensors (*.safetensors)
│   ├── vae/
│   └── text_encoder/
└── modules/
    ├── scheduler/
    │   └── config.json     ← Scheduler params (num_train_timesteps, beta_schedule)
    └── tokenizer/
        └── config.json     ← Tokenizer params (vocab_size, max_length)
```

### Key Files Explained

**manifest.json**:
```json
{
  "model_name": "Sana_1600M_1024px_MultiLing",
  "family": "image",
  "generation_type": "iterative_diffusion",
  "components": ["transformer", "vae", "text_encoder"],
  "modules": ["scheduler", "tokenizer"]
}
```

**topology.json**:
```json
{
  "execution": {
    "generation": {
      "flow": "iterative_process",
      "components": ["transformer"],
      "persistent": ["transformer"],
      "transient": []
    }
  },
  "bindings": {
    "transformer": {
      "hidden_states": "global.latents",
      "timestep": "scheduler.current_timestep",
      "encoder_hidden_states": "text_encoder.last_hidden_state"
    }
  }
}
```

**runtime/variables.json**:
```json
{
  "global.latents": {
    "type": "tensor",
    "resolver": {
      "method": "allocate_empty",
      "shape_source": {
        "axis_0": "runtime.batch_size",
        "axis_1": "component.transformer.attributes.state_channels",
        "axis_2": "component.transformer.attributes.state_extent_0",
        "axis_3": "component.transformer.attributes.state_extent_1"
      }
    }
  }
}
```

**runtime/defaults.json**:
```json
{
  "batch_size": 1,
  "num_inference_steps": 20,
  "guidance_scale": 4.5,
  "height": 1024,
  "width": 1024,
  "dtype": "float16",
  "output_range": [0, 1]
}
```

**components/transformer/graph.json**:
```json
{
  "ops": {
    "aten::linear::0": {
      "op_uid": "aten::linear::0",
      "op_type": "aten::linear",
      "inputs": ["hidden_states", "weight_adaln_linear"],
      "outputs": ["linear_output"],
      "attributes": {
        "bias": true
      }
    }
  },
  "input_spec": {
    "hidden_states": {"shape": ["B", 1024, 2304], "dtype": "float16"}
  },
  "output_spec": {
    "sample": {"shape": ["B", 1024, 32], "dtype": "float16"}
  }
}
```

### Implementation

**Files**:
- `src/neurobrix/nbx/container.py` — NBXContainer loader
- `src/neurobrix/nbx/cache.py` — Cache management (~/.neurobrix/cache/)
- `src/neurobrix/core/runtime/loader.py` — RuntimePackage loader
- `forge/importer/builder.py` — NBXBuilder (creates .nbx from snapshot)

**Usage**:
```python
from neurobrix.nbx.container import NBXContainer
from neurobrix.core.runtime.loader import NBXRuntimeLoader

# Load container
container = NBXContainer.load("model.nbx")
manifest = container.get_manifest()
components = container.get_neural_components()

# Load runtime package
loader = NBXRuntimeLoader()
pkg = loader.load("model.nbx")  # Auto-extracts to cache
executor = RuntimeExecutor(pkg, plan)
```

---

## 📋 PATTERN 1: Diffusers Pipelines (model_index.json)

### Discovered Variants
```
FluxPipeline          → transformer + vae + text_encoder(s)
Flux2Pipeline         → transformer + vae + text_encoder (Mistral-based)
StableDiffusionXLPipeline → unet + vae + text_encoder + text_encoder_2
PixArtAlphaPipeline   → transformer + vae + text_encoder
PixArtSigmaPipeline   → transformer + vae + text_encoder
SanaPipeline          → transformer + vae + text_encoder (Gemma-based)
StableVideoDiffusionPipeline → unet + vae + image_encoder
TextToVideoSDPipeline → unet + vae + text_encoder
AudioLDMPipeline      → unet + vae + text_encoder + vocoder
```

### Critical Dimensions per Component Type

#### TRANSFORMER (DiT-style)
| Key | Flux | FLUX.2 | Sana | PixArt |
|-----|------|--------|------|--------|
| in_channels | 64 | 128 | 32 | - |
| attention_head_dim | 128 | 128 | 32 | - |
| num_attention_heads | 24 | 48 | 70 | - |
| num_layers | 8 | 8 | 20 | - |
| num_single_layers | 38 | 48 | - | - |
| joint_attention_dim | 4096 | 15360 | 2240 | - |

#### UNET (U-Net style)
| Key | SDXL | SVD | Zeroscope | AudioLDM |
|-----|------|-----|-----------|----------|
| in_channels | 4 | 8 | 4 | 8 |
| out_channels | 4 | 4 | 4 | 8 |
| block_out_channels | [320,640,1280] | [320,640,1280,1280] | [320,640,1280,1280] | [128,256,384,640] |
| cross_attention_dim | 2048 | 1024 | 1024 | [128,256,384,640] |
| sample_size | 128 | 96 | 32 | 128 |
| num_frames | - | 25 | - | - |

#### VAE
| Key | Standard | Flux | Temporal | DC-AE |
|-----|----------|------|----------|-------|
| latent_channels | 4 | 16 | 4 | 32 |
| block_out_channels | [128,256,512,512] | same | same | [128,256,512,512,1024,1024] |
| scaling_factor | 0.18215 | 0.3611 | 0.18215 | 0.41407 |
| shift_factor | - | 0.1159 | - | - |

---

## 📋 PATTERN 2: Transformers Standalone (config.json only)

### WHISPER (Speech-to-Text)
```json
{
  "model_type": "whisper",
  "d_model": 1280,
  "encoder_layers": 32,
  "decoder_layers": 32,
  "encoder_attention_heads": 20,
  "decoder_attention_heads": 20,
  "num_mel_bins": 128,
  "max_source_positions": 1500,
  "max_target_positions": 448,
  "vocab_size": 51866
}
```

### SWIN2SR (Image Super-Resolution)
```json
{
  "model_type": "swin2sr",
  "embed_dim": 180,
  "depths": [6,6,6,6,6,6],
  "num_heads": [6,6,6,6,6,6],
  "window_size": 8,
  "image_size": 64,
  "upscale": 2|4,
  "num_channels": 3
}
```

### SPEECHT5 (Text-to-Speech)
```json
{
  "model_type": "speecht5",
  "hidden_size": 768,
  "encoder_layers": 12,
  "decoder_layers": 6,
  "num_mel_bins": 80,
  "speaker_embedding_dim": 512,
  "max_speech_positions": 1876
}
```

---

## 📋 PATTERN 3: Composite Models (Nested Configs)

### BARK (Multi-stage TTS)
Components inside single config.json:
- `semantic_config` → Text to semantic tokens
- `coarse_acoustics_config` → Semantic to coarse audio
- `fine_acoustics_config` → Coarse to fine audio  
- `codec_config` → EnCodec for audio encoding

### MUSICGEN (Conditional Audio)
Components:
- `text_encoder` → T5 encoder config
- `decoder` → MusicGen decoder config
- `audio_encoder` → EnCodec config

---

## 📋 PATTERN 4: Pure Checkpoints (No Config)

### Real-ESRGAN / ESRGAN Variants
**Files**: `.pth` or `.pt` only
**Architecture**: RRDBNet (hardcoded in code)

**SOLUTION OPTIONS**:
1. Create standardized `config.json` during import from weight shapes
2. Maintain architecture registry for known checkpoint types
3. Use weight introspection to detect layer structure

---

## 🔧 PARAM_TO_CONFIG_KEYS Coverage Analysis [ARCHIVED - Now in forge/importer/]

**NOTE**: The original `PARAM_TO_CONFIG_KEYS` approach has been superseded by the NBX v0.1 container format. Variable resolution is now data-driven via `runtime/variables.json` and `runtime/defaults.json` in the `.nbx` package.

**Location**: `forge/importer/builder.py` (private forge module)

### ✅ PREVIOUSLY COVERED (65+ params) [ARCHIVED]

| Category | Parameters |
|----------|------------|
| Tokens | input_ids, decoder_input_ids, attention_mask, position_ids |
| Hidden States | hidden_states, encoder_hidden_states, inputs_embeds |
| Diffusion | sample, timestep, guidance, pooled_projections |
| Image | pixel_values, img_ids, txt_ids |
| Audio | input_features, input_values, speaker_embeddings |
| Masks | head_mask, cross_attn_mask, encoder_attention_mask |

### ❌ GAPS TO ADD [ARCHIVED - Variable resolver handles at runtime]

**Current System**: Variables resolved via `runtime/variables.json`:

```json
{
  "global.latents": {
    "type": "tensor",
    "resolver": {
      "method": "allocate_empty",
      "shape_source": {
        "axis_0": "runtime.batch_size",
        "axis_1": "component.transformer.attributes.state_channels",
        "axis_2": "component.transformer.attributes.state_extent_0",
        "axis_3": "component.transformer.attributes.state_extent_1"
      }
    }
  }
}
```

**Implementation**: `src/neurobrix/core/runtime/variables.py`

---

## 🚀 UNIVERSALITY VALIDATION (February 2026 Status)

### Test Matrix

| Model | Type | Components | Status |
|-------|------|------------|--------|
| PixArt-Alpha | Image | transformer, vae, text_encoder | ✅ Production |
| PixArt-Sigma | Image | transformer, vae, text_encoder | ✅ Production |
| Sana 1600M 1024px | Image | transformer, vae, text_encoder (Gemma) | ✅ Production |
| Janus-Pro-7B | Image | gen_vision_model, aligner, language_model, gen_embed, gen_aligner, gen_head | ✅ Production |
| DeepSeek-MoE-16B | LLM | language_model | ✅ Production |
| Flux.1-dev | Image | transformer, vae, text_encoder | ✅ Traced (not yet in registry) |
| FLUX.2-dev | Image | transformer, vae, text_encoder | 🔄 To Test |
| SDXL | Image | unet, vae, text_encoder, text_encoder_2 | 🔄 To Test |
| SVD | Video | unet, vae, image_encoder | 🔄 To Test |
| Zeroscope | Video | unet, vae, text_encoder | 🔄 To Test |
| AudioLDM | Audio | unet, vae, text_encoder, vocoder | ❌ Needs Pattern 3 |
| Whisper | Speech | encoder-decoder (single) | 🔄 To Test |
| SpeechT5 | TTS | encoder-decoder + vocoder | ❌ Needs Pattern 3 |
| Bark | TTS | semantic + coarse + fine + codec | ❌ Needs Pattern 3 |
| MusicGen | Audio | text_encoder + decoder + audio_encoder | ❌ Needs Pattern 3 |
| Swin2SR | Upscale | single model | ❌ Needs Pattern 2 |
| Real-ESRGAN | Upscale | RRDBNet | ❌ Needs Pattern 4 |

### Registry Models (neurobrix.es)

**Available via `neurobrix import <org>/<name>`**:
- `sana/1600m-1024` (Sana_1600M_1024px_MultiLing)
- `pixart/alpha-1024-ms` (PixArt-Alpha 1024px)
- `pixart/sigma-1024-ms` (PixArt-Sigma 1024px)
- `deepseek/janus-pro-7b` (Janus-Pro-7B VQ autoregressive)
- `deepseek/moe-16b-chat` (DeepSeek-MoE-16B-Chat LLM)

---

## 📝 RECOMMENDED ACTIONS [UPDATED - February 2026]

### Priority 1: Additional Model Families (Weeks 1-2)
1. **Video Models**: SVD, Zeroscope
   - Add `num_frames`, `fps_id`, `motion_bucket_id` to defaults.json generation
   - Temporal VAE support in tracer
   - 3D conv support in kernels

2. **Audio Models**: AudioLDM, Whisper
   - Add `spectrogram`, `audio_codes`, `codebook_indices` variable resolvers
   - Vocoder component support
   - Mel-spectrogram preprocessing

### Priority 2: Complex Architectures (Weeks 3-4)
3. **Pattern 3 (Composite)**: Bark, MusicGen, SpeechT5
   - Multi-stage pipeline support in `runtime/execution.json`
   - Nested component hierarchy in manifest
   - Intermediate state passing

4. **Pattern 4 (Pure Checkpoint)**: Real-ESRGAN, Swin2SR
   - Weight introspection to generate synthetic config.json
   - Architecture registry for known checkpoint types
   - Fallback to weight shape analysis

### Priority 3: Extended Testing (Weeks 5-6)
5. Run `forge/forge.py build` on ALL 23 snapshots
6. Validate all execution modes:
   - Default (compiled): `neurobrix run --model ...`
   - Native ATen (--seq_aten): `neurobrix run --model ... --seq_aten`
   - Triton kernels (--triton): `neurobrix run --model ... --triton`

---

## 🧮 PRISM SOLVER — Hardware-Aware Placement (February 2026)

### Overview

Prism is the hardware abstraction layer that solves component placement given:
- Hardware profile (VRAM, topology, dtype support)
- Component memory requirements (weights, activations, KV cache)
- Multi-GPU strategies (single_gpu, zero3, pipeline, tensor_parallel, fgp)

**Files**:
- `src/neurobrix/core/prism/solver.py` — PrismSolver (main entry point)
- `src/neurobrix/core/strategies/` — Strategy implementations
- `src/neurobrix/config/hardware/` — Hardware YAML profiles

### Strategy Evaluation

Prism ranks strategies by score, then validates memory fit (including KV cache):

| Strategy | Score | VRAM Allocated | Capacity |
|----------|-------|----------------|----------|
| `single_gpu` (lazy) | 1000 | max(one component) | Largest GPU |
| `single_gpu` (eager) | 995 | sum(all components) | Largest GPU |
| `single_gpu_lifecycle` | 990 | sum(persistent) + max(transient) | Largest GPU |
| `pp_nvlink` / `fgp_nvlink` | 795 | sum(all components) | All GPUs (NVLink) |
| `pipeline` | 790 | sum(all components) | All GPUs (PCIe) |
| `zero3` | 1 | sum(activations only) | Largest GPU |

**Fallback loop**: If best strategy can't fit KV cache, try next candidate.

### KV Cache Sizing (Data-Driven)

**Formula** (from `defaults.json`):
```
cache_len = max_tokens + prompt_margin (128)
per_token = num_layers × 2 × num_kv_heads × head_dim × dtype_bytes
total_kv = cache_len × per_token
```

**NEVER use `max_position_embeddings`** (28× too large for Janus).

| Model | max_tokens | cache_len | KV (fp32) | KV (fp16) |
|-------|-----------|-----------|-----------|-----------|
| Janus-Pro-7B | 576 | 704 | 660 MB | 330 MB |
| DeepSeek-MoE-16B | 256 | 384 | 220 MB | 110 MB |

### Lifecycle Classification (Autoregressive)

Components classified from `topology.json → execution.generation`:

| Type | Components | Behavior |
|------|-----------|----------|
| **Persistent** | language_model, gen_head, gen_embed, gen_aligner | Loaded simultaneously during decode loop |
| **Transient** | vision_model, gen_vision_model, aligner | Loaded/unloaded on demand |

### Dtype Safety

**UPDATED (2026-02)**: bf16 → fp16 conversion is **ALLOWED with range verification**. `PrismSolver._scan_bf16_fp16_safety()` scans all bf16 safetensors to verify abs values <= 65504 (fp16 max). If all values fit → convert to fp16 (saves memory, enables V100). If any value exceeds range → keep bf16 or upcast to fp32.

**Conversion safety**:
- bf16 → fp16 (ALLOWED after `_scan_bf16_fp16_safety()` verification)
- bf16 → fp32 (always safe without verification, same exponent range, wider mantissa)
- fp32 → fp16 (narrow range, may overflow)
- fp16 → fp32 (always safe)

### Hardware Profiles

**Location**: `src/neurobrix/config/hardware/`

**Available**:
- `v100-32g.yml` — Single V100 32GB (supports: float32, float16)
- `v100-16g.yml` — Single V100 16GB (supports: float32, float16)
- `c4140-4xv100-custom-nvlink.yml` — 2×V100 32GB + 2×V100 64GB NVLink
- `a100-80g.yml` — Single A100 80GB (supports: float32, float16, bfloat16)

**Example** (`v100-32g.yml`):
```yaml
device_id: 0
total_vram: 34089730048  # 31.75 GiB
supports_dtypes:
  - float32
  - float16
compute_capability: "7.0"
tensor_cores: true
```

## 🔧 EXECUTION MODES (February 2026)

### Runtime Execution Strategies

| Mode | Flag | Dispatcher | Performance | Use Case |
|------|------|-----------|-------------|----------|
| **Compiled** (default) | None | `CompiledSequenceV2` | 🟢 Best (zero Python overhead) | Production |
| **Native ATen** | `--seq_aten` | `NativeATenDispatcher` | 🟡 Good (dict-based) | Debugging |
| **Triton Kernels** | `--triton` | `KernelAdapter` | 🟢 Best (custom kernels) | GPU optimization |

**Implementation**:
- `src/neurobrix/core/runtime/graph/compiled_sequence.py` — CompiledSequenceV2 (closure-based, int slot addressing)
- `src/neurobrix/core/runtime/native_dispatcher.py` — NativeATenDispatcher (dict-based, ATen ops)
- `src/neurobrix/kernels/adapter.py` — KernelAdapter (Triton kernel routing)

### Flow Handlers (runtime/execution.json)

**Location**: `src/neurobrix/core/flow/`

| flow_type | Handler | Models | Description |
|-----------|---------|--------|-------------|
| `iterative_process` | `IterativeProcessFlow` | PixArt, Sana, Flux | Diffusion loop with scheduler |
| `autoregressive_generation` | `AutoregressiveFlow` | Janus, DeepSeek | Token-by-token generation |
| `forward_pass` | `ForwardPassFlow` | Whisper | Single encoder-decoder pass |
| `static_graph` | `StaticGraphFlow` | Super-resolution | Single forward pass |

**Example** (`runtime/execution.json`):
```json
{
  "flow_type": "iterative_process",
  "loops": {
    "primary_loop": {
      "driver_module": "scheduler",
      "state_variable": "global.latents",
      "steps_variable": "global.num_inference_steps",
      "iterates_over": ["transformer"]
    }
  }
}
```

### DtypeEngine — AMP Rules

**Location**: `src/neurobrix/core/dtype/engine.py`

**Source**: PyTorch `aten/src/ATen/autocast_mode.h`

| Category | Ops | Behavior |
|----------|-----|----------|
| **FP32 ops** | pow, rsqrt, softmax, sum, mean | Upcast to fp32 |
| **FP16 ops** | mm, bmm, conv2d, linear | Downcast to compute_dtype |
| **Promote ops** | add, mul | Match higher precision |
| **Complex** | polar, view_as_complex | NEVER cast complex → real |

**Critical**: Without AMP, RMSNorm's `pow → mean → rsqrt` chain overflows in fp16 → ALL ZEROS.

## 📊 DETAILED COMPONENT MATRIX

### All Discovered Text Encoders

| Class | d_model/hidden | Used By |
|-------|----------------|---------|
| `CLIPTextModel` | 768 | SD, Flux |
| `CLIPTextModelWithProjection` | 1280 | SDXL |
| `T5EncoderModel` | 4096 | Flux, PixArt |
| `Gemma2Model` | 2304 | Sana |
| `Mistral3ForConditionalGeneration` | 15360 | FLUX.2 |
| `ClapTextModelWithProjection` | 512 | AudioLDM |

### All Discovered Schedulers

| Class | Key Params |
|-------|------------|
| `FlowMatchEulerDiscreteScheduler` | shift, use_dynamic_shifting |
| `EulerDiscreteScheduler` | num_train_timesteps, beta_schedule |
| `DDIMScheduler` | num_train_timesteps, clip_sample |
| `DPMSolverMultistepScheduler` | solver_order, algorithm_type |

---

## 🎯 CONCLUSION [UPDATED - February 2026]

**NeuroBrix architecture IS fundamentally universal** - The NBX v0.1 container format with JSON manifests correctly maps parameters to config values without hardcoding model types.

**Production Status (February 2026)**:
- ✅ Image generation (diffusion): PixArt-Alpha, PixArt-Sigma, Sana, Flux.1
- ✅ Image generation (autoregressive VQ): Janus-Pro-7B
- ✅ LLM text generation: DeepSeek-MoE-16B-Chat
- ✅ pip-installable package: `pip install neurobrix`
- ✅ Registry system: neurobrix.es (Next.js + PostgreSQL + MinIO)
- ✅ Execution modes: compiled (default), native (--seq_aten), triton (--triton)
- ✅ Multi-GPU strategies: single_gpu, zero3, pipeline, tensor_parallel, fgp (Fine-Grained Pipeline)
- ✅ Hardware abstraction: Prism solver with KV cache awareness
- ✅ DtypeEngine: PyTorch AMP autocast rules (eliminates fp16 overflow)

**Remaining Work** (Estimated: 4-6 weeks):
- Video models (SVD, Zeroscope): Temporal conv + 3D attention
- Audio models (AudioLDM, Whisper): Vocoder + spectrogram handling
- Complex pipelines (Bark, MusicGen): Multi-stage execution
- Pure checkpoints (Real-ESRGAN): Weight introspection

**CLI Commands** (February 2026):

```bash
# PUBLIC — pip-installed package
neurobrix run --model sana/1600m-1024 --hardware v100-32g --prompt "A sunset"
neurobrix import deepseek/janus-pro-7b
neurobrix list
neurobrix remove 1600m-1024
neurobrix info --model sana/1600m-1024

# PRIVATE — forge/ (requires pip install -e .)
python forge/forge.py snap --name PixArt-alpha/PixArt-Sigma-XL-2-1024-MS
python forge/forge.py build --snapshot-path /path/to/snapshot --family image
python forge/forge.py trace --family llm --model deepseek-moe-16b-chat
NEUROBRIX_API_TOKEN=nbx_... python forge/forge.py publish models/image/.../model.nbx --org sana --name 1600m-1024
```

**Cache Layout**:
```
~/.neurobrix/
├── store/          ← Downloaded .nbx files (9+ GB each)
└── cache/          ← Extracted runtime models (READ by neurobrix run)
    └── 1600m-1024/
        ├── manifest.json       ← Model metadata
        ├── topology.json       ← Component graph
        ├── runtime/
        │   ├── defaults.json   ← User-tunable defaults
        │   ├── variables.json  ← Variable contracts
        │   └── execution.json  ← Flow definitions
        ├── components/
        │   └── transformer/
        │       ├── graph.json  ← TensorDAG
        │       ├── runtime.json
        │       └── weights/    ← Sharded tensors
        └── modules/
            └── scheduler/
                └── config.json
```

**Architecture Philosophy**:
- **ZERO HARDCODE**: All dimensions from NBX container
- **ZERO FALLBACK**: Crash explicitly if data missing
- **ZERO SEMANTIC**: Runtime has NO domain knowledge ("image", "latent", "vae")
- **ZERO COUPLING**: `forge/` has zero imports from `src/neurobrix/core/`

**Files Updated** (this document):
- Paths: `core/` → `src/neurobrix/core/`, `importer/` → `forge/importer/`, `trace/` → `forge/tracer/`
- Imports: `from core.` → `from neurobrix.core.`
- CLI: `python neurobrix.py` → `neurobrix` (pip command)
- Execution modes: No --cpp, --native, --family flags (removed)
- No ONNX export (not implemented)
- Flow handlers: `iterative_process`, `autoregressive_generation`, `forward_pass`, `static_graph`

---

## 🌐 REGISTRY SYSTEM (neurobrix.es)

### Architecture

```
                    ┌──────────────┐
                    │ neurobrix.es │  (Next.js + PostgreSQL)
                    │ 10.0.0.39    │  (API: /api/admin/*, /api/registry/*)
                    └──────┬───────┘
                           │
           ┌───────────────┼───────────────┐
           │ (publish)     │               │ (import)
           │ internal PUT  │               │ signed GET
           ▼               │               ▼
    ┌──────────────┐       │     ┌──────────────────┐
    │ MinIO        │       │     │ hub.neurobrix.es │
    │ 10.0.0.36    │◄──────┘     │ (Cloudflare →    │
    │ :9000        │             │  OPNsense HAProxy│
    │ Bucket:      │             │  → MinIO:9000)   │
    │ neurobrix/   │             └──────────────────┘
    └──────────────┘
```

### Components

| Component | Location | Purpose |
|-----------|----------|---------|
| **neurobrix.es** | 10.0.0.39:3000 | Next.js API + admin UI |
| **PostgreSQL** | 10.0.0.35:5432 | Metadata storage (Prisma) |
| **MinIO** | 10.0.0.36:9000 | .nbx file storage (S3-compatible) |
| **hub.neurobrix.es** | Cloudflare + HAProxy | Public download endpoint |

### Prisma Schema

**Tables**:
- `User` — NextAuth users
- `Model` — Registry entries (org, name, category, tags)
- `Download` — Download tracking
- `ApiToken` — CLI auth tokens (`nbx_...` format)

**Security**:
- Admin routes: NextAuth session (browser) OR Bearer token (CLI)
- OPNsense ACL: `hub.neurobrix.es` restricted to `/neurobrix/` path only
- S3 signed URLs: 1h expiry, HOST-bound (hub.neurobrix.es)

### Dual S3 Client (storage.ts)

```typescript
// Internal (10.0.0.36:9000) — for uploads (forge publish)
const s3 = new S3Client({
  endpoint: "http://10.0.0.36:9000",
  forcePathStyle: true
});

// Public (hub.neurobrix.es) — for downloads (neurobrix import)
const s3Public = new S3Client({
  endpoint: "https://hub.neurobrix.es",
  forcePathStyle: true
});
```

**Why Dual Client?** S3 signed URLs are HOST-bound. Users access via `hub.neurobrix.es`, so signed URLs must be generated with that endpoint.

### CLI Commands

**forge publish** (upload .nbx to MinIO, register in DB):
```bash
NEUROBRIX_API_TOKEN=nbx_... python forge/forge.py publish \
  models/image/Sana_1600M_1024px_MultiLing_diffusers/model.nbx \
  --org sana --name 1600m-1024 --category IMAGE \
  --tags "diffusion,text-to-image,sana,1024px" \
  --description "Sana 1600M 1024px MultiLingual"
```

**neurobrix import** (download .nbx via signed URL, extract to cache):
```bash
neurobrix import sana/1600m-1024
# Downloads: hub.neurobrix.es → ~/.neurobrix/store/1600m-1024.nbx
# Extracts: ~/.neurobrix/cache/1600m-1024/
```

**neurobrix list** (show installed models):
```bash
neurobrix list
# Registry cache: ~/.neurobrix/cache/
# Dev workspace: ./models/ (if exists)
```

**neurobrix remove** (delete from cache):
```bash
neurobrix remove 1600m-1024          # Delete from ~/.neurobrix/cache/
neurobrix remove 1600m-1024 --store  # Also delete from ~/.neurobrix/store/
```

### User Cache Layout

```
~/.neurobrix/
├── store/              ← Downloaded .nbx files (9+ GB each)
│   ├── 1600m-1024.nbx
│   └── janus-pro-7b.nbx
└── cache/              ← Extracted models (runtime reads from here)
    ├── 1600m-1024/
    │   ├── manifest.json
    │   ├── topology.json
    │   ├── runtime/
    │   ├── components/
    │   └── modules/
    └── janus-pro-7b/
        └── ...
```

### Performance

| Operation | Bandwidth | Notes |
|-----------|-----------|-------|
| **forge publish** | ~580 MB/s | Internal 10GbE (10.0.0.36) |
| **neurobrix import** | ~70 MB/s | Public (Cloudflare → HAProxy → MinIO) |

### API Endpoints

| Endpoint | Method | Auth | Purpose |
|----------|--------|------|---------|
| `/api/registry/list` | GET | Public | List all models |
| `/api/registry/download/:org/:name` | GET | Public | Get signed download URL |
| `/api/admin/models` | POST | Bearer | Upload model metadata |
| `/api/admin/models/:id/upload-url` | POST | Bearer | Get presigned PUT URL |

**Example** (neurobrix import flow):
```
1. GET /api/registry/download/sana/1600m-1024
   → Returns: { url: "https://hub.neurobrix.es/neurobrix/sana-1600m-1024.nbx?X-Amz-..." }

2. GET https://hub.neurobrix.es/neurobrix/sana-1600m-1024.nbx?X-Amz-...
   → Downloads .nbx file (1h expiry)

3. Extract to ~/.neurobrix/cache/1600m-1024/
```
