Ines-1 / assets /architecture.svg
Endikavi's picture
Add architecture diagram (assets/architecture.png + SVG source) and README Architecture section
2e965de verified
|
Raw History Blame Contribute Delete
20.6 kB
<svg xmlns="http://www.w3.org/2000/svg" width="1900" height="2010" viewBox="0 0 1900 2010" font-family="Inter, Helvetica, Arial, sans-serif">
<defs>
<marker id="a" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
<path d="M0,0 L10,5 L0,10 z" fill="#3a3f4b"/>
</marker>
<style>
.ln{stroke:#3a3f4b;stroke-width:2.2;fill:none}
.box{stroke:#4a5160;stroke-width:2.5;rx:7}
.enc{fill:#edf2e7}.dec{fill:#e7ecf5}.emb{fill:#e6d9ea;stroke:#8e6a9e}
.moe{fill:#f3dcdf;stroke:#b5525c}.head{fill:#f6e8c8}.kv{fill:#f8cfa0;stroke:#a8743a}
.t{font-size:22px;fill:#1d2129;text-anchor:middle;dominant-baseline:middle}
.s{font-size:17px;fill:#2b303a;text-anchor:middle;dominant-baseline:middle}
.xs{font-size:15px;fill:#3a3f4b;text-anchor:middle;dominant-baseline:middle}
.b{font-weight:700}
.l{text-anchor:start}.r{text-anchor:end}
</style>
</defs>
<rect width="1900" height="2010" fill="#ffffff"/>
<!-- ===== Header ===== -->
<text x="40" y="70" font-size="46" font-weight="700" fill="#1d2129">Ines-1 <tspan font-weight="400" fill="#5a6070" font-size="34">(mini-v41)</tspan></text>
<text x="40" y="118" font-size="21" fill="#3a3f4b">Causal Encoder-Decoder (CED) MoE + Engram · 1.59B total / 405M active per token · vocab 65,536 · context 2,048</text>
<text x="40" y="150" font-size="18" fill="#5a6070">enc8 + dec8 · d_model 1024 · 16 q / 4 kv heads · 16 routed + 1 shared expert, top-2 · engram [1, 5] · untied embeddings</text>
<g font-size="16" fill="#3a3f4b">
<rect x="40" y="195" width="22" height="22" rx="4" fill="#edf2e7" stroke="#4a5160" stroke-width="2"/><text x="70" y="212">encoder (full causal attention)</text>
<rect x="320" y="195" width="22" height="22" rx="4" fill="#e7ecf5" stroke="#4a5160" stroke-width="2"/><text x="350" y="212">decoder (window 128 + global K/V)</text>
<rect x="630" y="195" width="22" height="22" rx="4" fill="#f8cfa0" stroke="#a8743a" stroke-width="2"/><text x="660" y="212">global K/V (from encoder output)</text>
<rect x="930" y="195" width="22" height="22" rx="4" fill="#f3dcdf" stroke="#b5525c" stroke-width="2"/><text x="960" y="212">MoE</text>
<rect x="1030" y="195" width="22" height="22" rx="4" fill="#e6d9ea" stroke="#8e6a9e" stroke-width="2"/><text x="1060" y="212">embeddings / Engram</text>
<rect x="1255" y="195" width="22" height="22" rx="4" fill="#f6e8c8" stroke="#4a5160" stroke-width="2"/><text x="1285" y="212">output head</text>
</g>
<!-- ===== Left column: full stack ===== -->
<!-- Decision reader / head -->
<rect x="40" y="330" width="260" height="70" class="box head" stroke-dasharray="7 5"/>
<text x="170" y="355" class="s b">Ines-1 Decision Reader</text>
<text x="170" y="380" class="xs">letters A–Z @ 1st assistant pos.</text>
<path d="M170,440 V403" class="ln" stroke-dasharray="6 5" marker-end="url(#a)"/>
<rect x="40" y="440" width="260" height="72" class="box head"/>
<text x="170" y="465" class="t">LM Head (untied)</text>
<text x="170" y="492" class="xs">1024 → 65,536</text>
<path d="M170,534 V515" class="ln" marker-end="url(#a)"/>
<rect x="40" y="534" width="260" height="50" class="box" fill="#fff"/>
<text x="170" y="559" class="t">Final RMSNorm</text>
<path d="M170,606 V587" class="ln" marker-end="url(#a)"/>
<!-- Decoder layers 7..0 (top y = 1110 - 72 j) -->
<g>
<rect x="40" y="606" width="260" height="50" class="box dec"/><text x="170" y="631" class="t">Decoder Layer 7</text>
<rect x="40" y="678" width="260" height="50" class="box dec"/><text x="170" y="703" class="t">Decoder Layer 6</text>
<rect x="40" y="750" width="260" height="50" class="box dec"/><text x="170" y="775" class="t">Decoder Layer 5</text>
<rect x="40" y="822" width="260" height="50" class="box dec"/><text x="170" y="847" class="t">Decoder Layer 4</text>
<rect x="40" y="894" width="260" height="50" class="box dec"/><text x="170" y="919" class="t">Decoder Layer 3</text>
<rect x="40" y="966" width="260" height="50" class="box dec"/><text x="170" y="991" class="t">Decoder Layer 2</text>
<rect x="40" y="1038" width="260" height="50" class="box dec"/><text x="170" y="1063" class="t">Decoder Layer 1</text>
<rect x="40" y="1110" width="260" height="50" class="box dec"/><text x="170" y="1135" class="t">Decoder Layer 0</text>
<path d="M170,678 V659" class="ln" marker-end="url(#a)"/><path d="M170,750 V731" class="ln" marker-end="url(#a)"/><path d="M170,822 V803" class="ln" marker-end="url(#a)"/><path d="M170,894 V875" class="ln" marker-end="url(#a)"/><path d="M170,966 V947" class="ln" marker-end="url(#a)"/><path d="M170,1038 V1019" class="ln" marker-end="url(#a)"/><path d="M170,1110 V1091" class="ln" marker-end="url(#a)"/>
</g>
<!-- Encoder layers 7..0 (top y = 1740 - 72 i) -->
<g>
<rect x="40" y="1236" width="260" height="50" class="box enc"/><text x="170" y="1261" class="t">Encoder Layer 7</text>
<rect x="40" y="1308" width="260" height="50" class="box enc"/><text x="170" y="1333" class="t">Encoder Layer 6</text>
<rect x="40" y="1380" width="260" height="50" class="box enc"/><text x="170" y="1405" class="t">Encoder Layer 5</text>
<rect x="40" y="1452" width="260" height="50" class="box enc"/><text x="170" y="1477" class="t">Encoder Layer 4</text>
<rect x="40" y="1524" width="260" height="50" class="box enc"/><text x="170" y="1549" class="t">Encoder Layer 3</text>
<rect x="40" y="1596" width="260" height="50" class="box enc"/><text x="170" y="1621" class="t">Encoder Layer 2</text>
<rect x="40" y="1668" width="260" height="50" class="box enc"/><text x="170" y="1693" class="t">Encoder Layer 1</text>
<rect x="40" y="1740" width="260" height="50" class="box enc"/><text x="170" y="1765" class="t">Encoder Layer 0</text>
<path d="M170,1308 V1289" class="ln" marker-end="url(#a)"/><path d="M170,1380 V1361" class="ln" marker-end="url(#a)"/><path d="M170,1452 V1433" class="ln" marker-end="url(#a)"/><path d="M170,1524 V1505" class="ln" marker-end="url(#a)"/><path d="M170,1596 V1577" class="ln" marker-end="url(#a)"/><path d="M170,1668 V1649" class="ln" marker-end="url(#a)"/><path d="M170,1740 V1721" class="ln" marker-end="url(#a)"/>
</g>
<!-- h_enc continues into the decoder; branch to global K/V -->
<path d="M170,1236 V1163" class="ln" marker-end="url(#a)"/>
<text x="182" y="1182" font-size="16" fill="#3a3f4b" font-style="italic">h_enc</text>
<path d="M170,1198 H317" class="ln" marker-end="url(#a)"/>
<rect x="320" y="1170" width="180" height="54" class="box kv"/>
<text x="410" y="1189" class="xs b">Global K/V proj</text>
<text x="410" y="1209" class="xs">enc_out_norm · RoPE</text>
<!-- bus to every decoder layer -->
<path d="M415,1170 V631" class="ln" stroke="#a8743a" stroke-width="3"/>
<g class="ln" stroke="#a8743a">
<path d="M415,631 H303" marker-end="url(#a)"/><path d="M415,703 H303" marker-end="url(#a)"/>
<path d="M415,775 H303" marker-end="url(#a)"/><path d="M415,847 H303" marker-end="url(#a)"/>
<path d="M415,919 H303" marker-end="url(#a)"/><path d="M415,991 H303" marker-end="url(#a)"/>
<path d="M415,1063 H303" marker-end="url(#a)"/><path d="M415,1135 H303" marker-end="url(#a)"/>
</g>
<text transform="translate(448,885) rotate(-90)" class="xs" fill="#8a5a24">shared global K/V → all 8 decoder layers</text>
<!-- Embedding + inputs -->
<path d="M170,1830 V1793" class="ln" marker-end="url(#a)"/>
<rect x="40" y="1830" width="260" height="72" class="box emb"/>
<text x="170" y="1855" class="t">Vocabulary Embedding</text>
<text x="170" y="1881" class="xs">65,536 × 1024</text>
<path d="M170,1945 V1905" class="ln" marker-end="url(#a)"/>
<path d="M170,1925 H1100 V1905" class="ln" marker-end="url(#a)"/>
<text x="170" y="1970" class="t">Input Tokens</text>
<!-- Engram -->
<rect x="340" y="1830" width="1520" height="72" class="box emb"/>
<text x="1100" y="1855" class="t">Engram — hashed n-gram memory (2-, 3-, 4-grams)</text>
<text x="1100" y="1881" class="xs b">added to the residual before Encoder Layers 1 and 5 only</text>
<path d="M360,1830 V1693 H303" class="ln" marker-end="url(#a)"/>
<path d="M392,1830 V1405 H303" class="ln" marker-end="url(#a)"/>
<!-- ===== Zoom panel ===== -->
<rect x="520" y="300" width="1350" height="1495" fill="none" stroke="#7a8494" stroke-width="2.5" stroke-dasharray="14 9"/>
<text x="1868" y="288" font-size="19" font-weight="700" fill="#1d2129" text-anchor="end">Layer internals (pre-norm, single residual stream)</text>
<!-- Decoder layer panel -->
<rect x="545" y="320" width="1300" height="480" rx="30" class="dec" stroke="#4a5160" stroke-width="2.5"/>
<text x="1820" y="358" font-size="30" font-weight="700" fill="#1d2129" text-anchor="end">Decoder Layer</text>
<text x="600" y="560" font-size="36" fill="#1d2129" text-anchor="middle">8×</text>
<!-- residual -->
<path d="M680,830 V614" class="ln"/><path d="M680,586 V474" class="ln"/><path d="M680,446 V303" class="ln" marker-end="url(#a)"/>
<circle cx="680" cy="600" r="14" fill="#fff" stroke="#3a3f4b" stroke-width="2.2"/><text x="680" y="601" class="t">+</text>
<circle cx="680" cy="460" r="14" fill="#fff" stroke="#3a3f4b" stroke-width="2.2"/><text x="680" y="461" class="t">+</text>
<!-- attention row -->
<path d="M680,700 H757" class="ln" marker-end="url(#a)"/>
<rect x="760" y="680" width="120" height="40" class="box" fill="#fff"/><text x="820" y="700" class="xs">RMSNorm</text>
<path d="M880,700 H937" class="ln" marker-end="url(#a)"/>
<rect x="940" y="630" width="860" height="95" class="box" fill="#dfe8d6"/>
<text x="1370" y="655" class="t b">CED Attention — one softmax over two K/V sets</text>
<text x="1370" y="683" class="s">[ local K/V of this layer · sliding window 128 | global K/V from encoder · full causal ]</text>
<text x="1370" y="707" class="xs">16 q heads / 4 kv heads (GQA) · head_dim 64 · RoPE θ = 10⁴ on full head</text>
<path d="M1370,630 V600 H697" class="ln" marker-end="url(#a)"/>
<rect x="1450" y="748" width="350" height="40" class="box kv"/>
<text x="1625" y="768" class="xs b">Global K/V ← encoder (shared ×8)</text>
<path d="M1625,748 V728" class="ln" marker-end="url(#a)"/>
<!-- MoE row -->
<path d="M680,545 H757" class="ln" marker-end="url(#a)"/>
<rect x="760" y="525" width="120" height="40" class="box" fill="#fff"/><text x="820" y="545" class="xs">RMSNorm</text>
<path d="M880,545 H937" class="ln" marker-end="url(#a)"/>
<rect x="940" y="495" width="860" height="80" class="box moe"/>
<text x="1370" y="522" class="t b">MoE FFN</text>
<text x="1370" y="552" class="s">16 routed experts (top-2) + 1 shared · SwiGLU 1536</text>
<path d="M1370,495 V460 H697" class="ln" marker-end="url(#a)"/>
<!-- Encoder layer panel -->
<rect x="545" y="830" width="1300" height="420" rx="30" class="enc" stroke="#4a5160" stroke-width="2.5"/>
<text x="1820" y="868" font-size="30" font-weight="700" fill="#1d2129" text-anchor="end">Encoder Layer</text>
<text x="600" y="1080" font-size="36" fill="#1d2129" text-anchor="middle">8×</text>
<path d="M680,1268 V1214" class="ln"/><path d="M680,1186 V1086" class="ln"/><path d="M680,1058 V949" class="ln"/><path d="M680,921 V830" class="ln"/>
<circle cx="680" cy="1200" r="14" fill="#fff" stroke="#3a3f4b" stroke-width="2.2" stroke-dasharray="4 3"/><text x="680" y="1201" class="t">+</text>
<circle cx="680" cy="1072" r="14" fill="#fff" stroke="#3a3f4b" stroke-width="2.2"/><text x="680" y="1073" class="t">+</text>
<circle cx="680" cy="935" r="14" fill="#fff" stroke="#3a3f4b" stroke-width="2.2"/><text x="680" y="936" class="t">+</text>
<!-- engram injection -->
<rect x="960" y="1182" width="380" height="40" class="box emb" stroke-dasharray="7 5"/>
<text x="1150" y="1202" class="xs b">Engram (only before layers 1 and 5)</text>
<path d="M960,1200 H697" class="ln" stroke-dasharray="7 5" marker-end="url(#a)"/>
<!-- attention row -->
<path d="M680,1150 H757" class="ln" marker-end="url(#a)"/>
<rect x="760" y="1130" width="120" height="40" class="box" fill="#fff"/><text x="820" y="1150" class="xs">RMSNorm</text>
<path d="M880,1150 H937" class="ln" marker-end="url(#a)"/>
<rect x="940" y="1095" width="860" height="75" class="box" fill="#dfe8d6"/>
<text x="1370" y="1120" class="t b">Causal Self-Attention (full, no window, ≤ 2,048)</text>
<text x="1370" y="1149" class="s">16 q heads / 4 kv heads (GQA) · head_dim 64 · RoPE θ = 10⁴</text>
<path d="M1370,1095 V1072 H697" class="ln" marker-end="url(#a)"/>
<!-- MoE row -->
<path d="M680,1020 H757" class="ln" marker-end="url(#a)"/>
<rect x="760" y="1000" width="120" height="40" class="box" fill="#fff"/><text x="820" y="1020" class="xs">RMSNorm</text>
<path d="M880,1020 H937" class="ln" marker-end="url(#a)"/>
<rect x="940" y="965" width="860" height="80" class="box moe"/>
<text x="1370" y="992" class="t b">MoE FFN</text>
<text x="1370" y="1022" class="s">16 routed experts (top-2) + 1 shared · SwiGLU 1536</text>
<path d="M1370,965 V935 H697" class="ln" marker-end="url(#a)"/>
<text x="700" y="1240" font-size="15" fill="#5a6070" font-style="italic" text-anchor="start">residual h</text>
<!-- MoE detail -->
<rect x="545" y="1275" width="640" height="500" rx="24" fill="#fbf1f2" stroke="#b5525c" stroke-width="2.5"/>
<text x="565" y="1310" font-size="24" font-weight="700" fill="#1d2129">MoE FFN (all 16 layers, no dense FFN)</text>
<text x="565" y="1340" font-size="16" fill="#3a3f4b">16 routed + 1 shared expert · each SwiGLU 1024 → 1536 → 1024</text>
<text x="565" y="1364" font-size="16" fill="#3a3f4b">aux loss 0.01 · z-loss 0.001 · no capacity / token drop · no bias balancing</text>
<!-- sigma -->
<path d="M865,1424 V1390" class="ln" marker-end="url(#a)"/>
<text x="878" y="1398" font-size="15" fill="#3a3f4b" font-style="italic">→ residual +</text>
<circle cx="865" cy="1440" r="16" fill="#fff" stroke="#3a3f4b" stroke-width="2.2"/><text x="865" y="1441" class="t">Σ</text>
<!-- shared expert -->
<rect x="1000" y="1460" width="170" height="50" class="box" fill="#f3dcdf" stroke="#b5525c"/>
<text x="1085" y="1485" class="xs b">Shared expert</text>
<path d="M1000,1478 L882,1446" class="ln" marker-end="url(#a)"/>
<!-- routed experts -->
<g font-size="12" text-anchor="middle" dominant-baseline="middle" fill="#3a3f4b">
<rect x="575" y="1560" width="28" height="40" fill="#fff" stroke="#b5525c" stroke-width="1.6"/><text x="589" y="1580">1</text>
<rect x="607" y="1560" width="28" height="40" fill="#fff" stroke="#b5525c" stroke-width="1.6"/><text x="621" y="1580">2</text>
<rect x="639" y="1560" width="28" height="40" fill="#e9a3ab" stroke="#b5525c" stroke-width="2.4"/><text x="653" y="1580" font-weight="700">3</text>
<rect x="671" y="1560" width="28" height="40" fill="#fff" stroke="#b5525c" stroke-width="1.6"/><text x="685" y="1580">4</text>
<rect x="703" y="1560" width="28" height="40" fill="#fff" stroke="#b5525c" stroke-width="1.6"/><text x="717" y="1580">5</text>
<rect x="735" y="1560" width="28" height="40" fill="#fff" stroke="#b5525c" stroke-width="1.6"/><text x="749" y="1580">6</text>
<rect x="767" y="1560" width="28" height="40" fill="#fff" stroke="#b5525c" stroke-width="1.6"/><text x="781" y="1580">7</text>
<rect x="799" y="1560" width="28" height="40" fill="#fff" stroke="#b5525c" stroke-width="1.6"/><text x="813" y="1580">8</text>
<rect x="831" y="1560" width="28" height="40" fill="#fff" stroke="#b5525c" stroke-width="1.6"/><text x="845" y="1580">9</text>
<rect x="863" y="1560" width="28" height="40" fill="#fff" stroke="#b5525c" stroke-width="1.6"/><text x="877" y="1580">10</text>
<rect x="895" y="1560" width="28" height="40" fill="#e9a3ab" stroke="#b5525c" stroke-width="2.4"/><text x="909" y="1580" font-weight="700">11</text>
<rect x="927" y="1560" width="28" height="40" fill="#fff" stroke="#b5525c" stroke-width="1.6"/><text x="941" y="1580">12</text>
<rect x="959" y="1560" width="28" height="40" fill="#fff" stroke="#b5525c" stroke-width="1.6"/><text x="973" y="1580">13</text>
<rect x="991" y="1560" width="28" height="40" fill="#fff" stroke="#b5525c" stroke-width="1.6"/><text x="1005" y="1580">14</text>
<rect x="1023" y="1560" width="28" height="40" fill="#fff" stroke="#b5525c" stroke-width="1.6"/><text x="1037" y="1580">15</text>
<rect x="1055" y="1560" width="28" height="40" fill="#fff" stroke="#b5525c" stroke-width="1.6"/><text x="1069" y="1580">16</text>
</g>
<path d="M653,1560 L852,1451" class="ln" marker-end="url(#a)"/>
<path d="M909,1560 L874,1455" class="ln" marker-end="url(#a)"/>
<text x="730" y="1500" font-size="15" fill="#3a3f4b" font-style="italic">g₁</text>
<text x="905" y="1505" font-size="15" fill="#3a3f4b" font-style="italic">g₂</text>
<!-- router -->
<rect x="575" y="1680" width="510" height="45" class="box" fill="#fff" stroke="#b5525c"/>
<text x="830" y="1703" class="xs"><tspan font-weight="700">Router</tspan> · s = √softplus(Wx) · fp32 · top-2 of 16, renormalised</text>
<path d="M653,1680 V1603" class="ln" marker-end="url(#a)"/>
<path d="M909,1680 V1603" class="ln" marker-end="url(#a)"/>
<path d="M830,1768 V1728" class="ln" marker-end="url(#a)"/>
<path d="M830,1748 H1120 V1513" class="ln" marker-end="url(#a)"/>
<text x="815" y="1762" font-size="15" fill="#3a3f4b" font-style="italic" text-anchor="end">x</text>
<!-- Engram detail -->
<rect x="1205" y="1275" width="640" height="500" rx="24" fill="#f6f0f8" stroke="#8e6a9e" stroke-width="2.5"/>
<text x="1225" y="1310" font-size="24" font-weight="700" fill="#1d2129">Engram (n-gram memory)</text>
<text x="1225" y="1340" font-size="16" fill="#3a3f4b">2 tables (layers 1, 5) · ~1M rows × 64 · 128M params · LR ×8</text>
<text x="1225" y="1364" font-size="16" fill="#3a3f4b">position-independent: looks only at the last 3 tokens</text>
<path d="M1450,1405 V1390" class="ln" marker-end="url(#a)"/>
<text x="1465" y="1396" font-size="15" fill="#3a3f4b" font-style="italic" text-anchor="start">→ residual +</text>
<rect x="1240" y="1405" width="420" height="50" class="box" fill="#f8cfa0" stroke="#a8743a"/>
<text x="1450" y="1423" class="xs b">gate = σ(⟨RMSNorm(h)·w, key⟩)</text>
<text x="1450" y="1443" class="xs">out = gate ⊙ value</text>
<path d="M1760,1430 H1663" class="ln" marker-end="url(#a)"/>
<text x="1768" y="1430" font-size="15" fill="#3a3f4b" font-style="italic" text-anchor="start" dominant-baseline="middle">h</text>
<path d="M1450,1480 V1458" class="ln" marker-end="url(#a)"/>
<rect x="1240" y="1480" width="420" height="45" class="box" fill="#fff"/>
<text x="1450" y="1503" class="xs">W_kv : 384 → key, value (1024)</text>
<path d="M1450,1555 V1528" class="ln" marker-end="url(#a)"/>
<rect x="1240" y="1555" width="420" height="45" class="box emb"/>
<text x="1450" y="1578" class="xs">table lookup → 6 × 64 = 384-d</text>
<text x="1672" y="1578" font-size="14" fill="#5a6070" dominant-baseline="middle">collisions ≈ 1.1 %</text>
<path d="M1450,1630 V1603" class="ln" marker-end="url(#a)"/>
<rect x="1240" y="1630" width="420" height="45" class="box" fill="#fff"/>
<text x="1450" y="1653" class="xs">hash 2/3/4-grams × 2 heads = 6 ids</text>
<text x="1672" y="1653" font-size="14" fill="#5a6070" dominant-baseline="middle">XOR-hash mod prime</text>
<path d="M1450,1712 V1678" class="ln" marker-end="url(#a)"/>
<g>
<rect x="1290" y="1712" width="70" height="40" class="box" fill="#fff"/><text x="1325" y="1732" class="xs">t−3</text>
<rect x="1370" y="1712" width="70" height="40" class="box" fill="#fff"/><text x="1405" y="1732" class="xs">t−2</text>
<rect x="1450" y="1712" width="70" height="40" class="box" fill="#fff"/><text x="1485" y="1732" class="xs">t−1</text>
<rect x="1530" y="1712" width="70" height="40" class="box" fill="#fff"/><text x="1565" y="1732" class="xs">t</text>
</g>
<text x="1620" y="1732" font-size="15" fill="#3a3f4b" font-style="italic" dominant-baseline="middle">token ids</text>
<!-- footnote -->
<text x="1860" y="1972" font-size="16" fill="#5a6070" text-anchor="end">Receptive field: raw tokens reach every decoder token through the encoder → global K/V path (full 2,048);</text>
<text x="1860" y="1995" font-size="16" fill="#5a6070" text-anchor="end">features computed inside the decoder travel only 128 + 7·127 = 1,017 positions.</text>
</svg>