Add pinned Nanbeige and Qwen architecture comparison

#5
NOTICE CHANGED
@@ -6,11 +6,14 @@ RecursiveSI/flint, Recursive Superintelligence, Inc.
6
  https://huggingface.co/RecursiveSI/flint
7
  Qwen/Qwen3.8-27B, Qwen Team
8
  https://huggingface.co/Qwen/Qwen3.8-27B
 
 
9
  The publishers distribute these models under Apache License 2.0:
10
  https://www.apache.org/licenses/LICENSE-2.0
11
 
12
  Configurations record architectural facts. The Qwen configuration describes
13
- its text decoder; the source model also includes other components.
 
14
  Bundled measured activation captures are published by alphaBell for reuse
15
  with this viewer. No model weights are included.
16
 
 
6
  https://huggingface.co/RecursiveSI/flint
7
  Qwen/Qwen3.8-27B, Qwen Team
8
  https://huggingface.co/Qwen/Qwen3.8-27B
9
+ Nanbeige/Nanbeige4.3-33B, Nanbeige
10
+ https://huggingface.co/Nanbeige/Nanbeige4.3-33B
11
  The publishers distribute these models under Apache License 2.0:
12
  https://www.apache.org/licenses/LICENSE-2.0
13
 
14
  Configurations record architectural facts. The Qwen configuration describes
15
+ its text decoder; the source model also includes other components. The
16
+ Nanbeige configuration is bundled for architecture comparison.
17
  Bundled measured activation captures are published by alphaBell for reuse
18
  with this viewer. No model weights are included.
19
 
architecture/comparison.css ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ :root{--ink:#17352d;--muted:#62786f;--line:#dce5dc;--paper:#f7f8f3;--card:#fff;--green:#236a55;--green-soft:#e6f0e9;--blue:#347d97;--blue-soft:#e4f0f2;font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;color:var(--ink);background:var(--paper)}
2
+
3
+ *{box-sizing:border-box}
4
+ html{scroll-behavior:smooth}
5
+ body{margin:0}
6
+ a{color:inherit}
7
+ button{font:inherit}
8
+ button:focus-visible,a:focus-visible{outline:3px solid #e69741;outline-offset:3px}
9
+ .topbar{min-height:72px;padding:12px clamp(20px,4vw,60px);display:flex;align-items:center;justify-content:space-between;gap:20px;border-bottom:1px solid var(--line);background:#fff}
10
+ .brand{display:flex;align-items:center;gap:11px;text-decoration:none;font-size:16px;font-weight:650;letter-spacing:-.03em}
11
+ .mark{display:grid;place-items:center;width:34px;height:34px;border-radius:10px;background:var(--green);color:#fff;font-size:28px;font-family:Georgia,serif}
12
+ .slash{color:#a7b8ac;padding:0 3px}
13
+ .back{font-size:13px;font-weight:650;text-decoration:none}
14
+ .back:hover,footer a:hover{text-decoration:underline}
15
+ main{max-width:1320px;margin:auto;padding:0 clamp(20px,4vw,60px) 64px}
16
+ .intro{padding:clamp(52px,7vw,96px) 0 48px;max-width:920px}
17
+ .eyebrow{font-size:11px;font-weight:750;letter-spacing:.17em;text-transform:uppercase;color:var(--green);margin:0 0 19px}
18
+ .intro .eyebrow{display:flex;gap:18px}
19
+ .intro .eyebrow span{color:#9caea2}
20
+ h1,h2,h3,p{margin-top:0}
21
+ h1{font-size:clamp(43px,6.2vw,80px);line-height:1.04;letter-spacing:-.06em;margin-bottom:26px;font-weight:700}
22
+ h1 em{font-style:normal;color:var(--green)}
23
+ .lead{font-size:clamp(17px,2vw,22px);line-height:1.55;max-width:750px;color:#435e53;margin-bottom:28px}
24
+ .scope{display:flex;align-items:flex-start;gap:10px;max-width:830px;padding:14px 17px;background:#edf3ec;border:1px solid #d8e6d9;border-radius:9px;color:#4b6658;font-size:12px;line-height:1.5}
25
+ .scope strong{white-space:nowrap;color:var(--green)}
26
+ .scope-dot{flex:none;margin-top:5px;width:7px;height:7px;border-radius:50%;background:var(--green)}
27
+ section.overview,section.layers,section.source{border-top:1px solid var(--line);padding-top:38px;margin-top:18px}
28
+ .section-heading{margin-bottom:24px}
29
+ .section-heading .eyebrow{margin-bottom:8px}
30
+ .section-heading h2{font-size:clamp(27px,3.2vw,37px);letter-spacing:-.045em;margin-bottom:10px}
31
+ .section-heading>p:last-child:not(.eyebrow){color:var(--muted);max-width:650px;line-height:1.6;margin:0;font-size:14px}
32
+ .overview-grid{display:grid;grid-template-columns:1fr 1fr;gap:16px}
33
+ .model-card{background:var(--card);border:1px solid var(--line);border-radius:14px;padding:24px;min-height:255px;display:flex;flex-direction:column}
34
+ .nanbeige-card{border-top:4px solid var(--green)}
35
+ .qwen-card{border-top:4px solid var(--blue)}
36
+ .model-head{display:flex;align-items:center;gap:14px}
37
+ .model-letter{display:grid;place-items:center;width:47px;height:47px;flex:none;border-radius:10px;background:var(--green-soft);color:var(--green);font-weight:750;font-size:25px}
38
+ .qwen-card .model-letter{background:var(--blue-soft);color:var(--blue)}
39
+ .model-family{font-size:10px;text-transform:uppercase;letter-spacing:.13em;color:var(--muted);font-weight:750;margin-bottom:3px}
40
+ .model-head h3{font-size:22px;letter-spacing:-.04em;margin:0}
41
+ .model-summary{font-size:14px;line-height:1.6;color:#526a5f;margin:19px 0 14px;max-width:48ch}
42
+ .hero-number{display:flex;align-items:baseline;gap:10px;margin-top:auto}
43
+ .hero-number strong{font-size:38px;letter-spacing:-.06em}
44
+ .hero-number span{font-size:12px;color:var(--muted);font-weight:650}
45
+ .spec-wrap{margin-top:16px;overflow-x:auto;border:1px solid var(--line);background:#fff;border-radius:12px}
46
+ .spec-table{width:100%;border-collapse:collapse;min-width:570px}
47
+ .spec-table caption{text-align:left;padding:18px 22px 11px;font-size:14px;font-weight:750}
48
+ .spec-table th,.spec-table td{padding:12px 22px;border-top:1px solid #e9eee8;text-align:left;font-size:13px}
49
+ .spec-table thead th{color:var(--muted);font-size:10px;letter-spacing:.1em;text-transform:uppercase}
50
+ .spec-table tbody th{font-weight:550;width:42%}
51
+ .spec-table tbody td{font-variant-numeric:tabular-nums;font-weight:650}
52
+ .legend{display:flex;gap:24px;flex-wrap:wrap;font-size:12px;font-weight:650;margin-bottom:16px}
53
+ .legend span{display:inline-flex;align-items:center;gap:8px}
54
+ .swatch{width:12px;height:12px;border-radius:3px;display:inline-block}
55
+ .swatch.full{background:var(--green)}
56
+ .swatch.linear{background:var(--blue)}
57
+ .map-pair{display:grid;grid-template-columns:1fr 1fr;gap:16px}
58
+ .map-card{background:#fff;border:1px solid var(--line);border-radius:12px;padding:20px;min-width:0}
59
+ .map-title{display:flex;justify-content:space-between;align-items:baseline;gap:10px;margin-bottom:17px}
60
+ .map-title h3{font-size:17px;letter-spacing:-.02em;margin:0}
61
+ .map-title span{font-size:11px;color:var(--muted);white-space:nowrap}
62
+ .layer-grid{display:grid;grid-template-columns:repeat(8,minmax(0,1fr));gap:5px}
63
+ .layer{min-width:0;aspect-ratio:1.4;border:1px solid transparent;border-radius:4px;cursor:pointer;font-size:10px;font-weight:750;font-variant-numeric:tabular-nums;transition:transform .12s,box-shadow .12s}
64
+ .layer.full{color:#fff;background:var(--green)}
65
+ .layer.linear{color:#fff;background:var(--blue)}
66
+ .layer:hover{transform:translateY(-2px)}
67
+ .layer[aria-pressed="true"]{box-shadow:0 0 0 3px #f3ad54;transform:translateY(-2px)}
68
+ .inspect{margin-top:16px;background:#e9f0e9;border:1px solid #d1e1d2;border-radius:12px;padding:24px}
69
+ .inspect .eyebrow{margin-bottom:8px}
70
+ .inspect h3{font-size:21px;letter-spacing:-.03em;margin-bottom:7px}
71
+ .inspect>p:not(.eyebrow){font-size:13px;color:#526b5c;line-height:1.5;max-width:760px}
72
+ .inspect dl{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;margin:20px 0 0}
73
+ .inspect dl>div{background:#fff;border-radius:7px;padding:12px 14px;min-width:0}
74
+ .inspect dt{font-size:10px;color:var(--muted);font-weight:650;margin-bottom:6px}
75
+ .inspect dd{font-size:15px;line-height:1.3;font-weight:720;margin:0;overflow-wrap:anywhere}
76
+ .source{padding-bottom:24px}
77
+ .source>p{max-width:800px;line-height:1.65;color:#526a5f;font-size:14px}
78
+ .source code{font-size:.9em;background:#e9efe7;padding:2px 4px;border-radius:3px}
79
+ .source-links{display:flex;flex-wrap:wrap;gap:12px}
80
+ .source-links a{display:flex;justify-content:space-between;gap:24px;min-width:min(100%,290px);background:#fff;border:1px solid var(--line);padding:15px 17px;border-radius:8px;text-decoration:none;font-weight:700;font-size:13px}
81
+ .source-links a:hover{border-color:var(--green)}
82
+ .source-links span{color:var(--muted);font-size:11px}
83
+ footer{border-top:1px solid var(--line);padding:25px clamp(20px,4vw,60px);display:flex;justify-content:space-between;gap:16px;color:var(--muted);font-size:12px}
84
+ footer a{color:var(--green);font-weight:650;text-decoration:none}
85
+
86
+ @media(max-width:760px){.topbar{min-height:60px}
87
+ .brand{font-size:13px}
88
+ .back{font-size:11px}
89
+ .intro{padding-top:53px}
90
+ .scope{display:grid;grid-template-columns:8px 1fr;gap:3px 10px}
91
+ .scope span:last-child{grid-column:2}
92
+ .scope-dot{margin-top:5px}
93
+ .overview-grid,.map-pair{grid-template-columns:1fr}
94
+ .model-card{min-height:220px}
95
+ .inspect dl{grid-template-columns:repeat(2,minmax(0,1fr))}
96
+ }
97
+
98
+ @media(max-width:500px){.spec-table{min-width:0;table-layout:fixed}
99
+ .spec-table tbody th{width:38%}
100
+ .spec-table th,.spec-table td{padding:10px 7px;font-size:12px;line-height:1.35;overflow-wrap:anywhere}
101
+ .spec-table thead th{font-size:10px;letter-spacing:.03em}
102
+ .spec-table caption{padding:15px 7px 9px}
103
+ }
104
+
105
+ @media(max-width:430px){main{padding-left:16px;padding-right:16px}
106
+ .topbar{padding-left:16px;padding-right:16px}
107
+ .brand{gap:7px;font-size:12px}
108
+ .mark{width:29px;height:29px;font-size:23px}
109
+ .back{max-width:106px;text-align:right}
110
+ .layer-grid{gap:4px}
111
+ .layer{font-size:9px}
112
+ .inspect{padding:17px}
113
+ .inspect dl{gap:7px}
114
+ .inspect dl>div{padding:10px}
115
+ .inspect dd{font-size:13px}
116
+ footer{display:block;padding-left:16px;padding-right:16px}
117
+ footer a{display:block;margin-top:8px}
118
+ }
119
+
120
+ @media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}
121
+ .layer{transition:none}
122
+ }
architecture/comparison.js ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 'use strict';
2
+
3
+ const paths = {
4
+ nanbeige: '../models/nanbeige.json',
5
+ qwen: '../models/qwen.json'
6
+ };
7
+ const names = { nanbeige: 'Nanbeige4.3-33B', qwen: 'Qwen3.8-27B text decoder' };
8
+ const fmt = value => new Intl.NumberFormat('en-US').format(value);
9
+ const byId = id => document.getElementById(id);
10
+ const configs = {};
11
+ let selected = { model: 'qwen', layer: 3 };
12
+
13
+ function attentionType(model, layer) {
14
+ if (model === 'nanbeige') return 'full';
15
+ return configs.qwen.layer_types[layer] === 'linear_attention' ? 'linear' : 'full';
16
+ }
17
+
18
+ function specRow(label, left, right) {
19
+ const tr = document.createElement('tr');
20
+ for (const [tag, value] of [['th', label], ['td', left], ['td', right]]) {
21
+ const cell = document.createElement(tag);
22
+ if (tag === 'th') cell.scope = 'row';
23
+ cell.textContent = value;
24
+ tr.append(cell);
25
+ }
26
+ return tr;
27
+ }
28
+
29
+ function renderSpecs() {
30
+ const n = configs.nanbeige;
31
+ const q = configs.qwen;
32
+ const linear = q.layer_types.filter(type => type === 'linear_attention').length;
33
+ const full = q.layer_types.length - linear;
34
+ byId('nanbeige-layer-count').textContent = fmt(n.num_hidden_layers);
35
+ byId('qwen-layer-count').textContent = `${linear} + ${full}`;
36
+ const rows = [
37
+ ['Decoder layers', fmt(n.num_hidden_layers), fmt(q.num_hidden_layers)],
38
+ ['Attention pattern', '52 full', `${linear} recurrent linear / ${full} full`],
39
+ ['Hidden width', fmt(n.hidden_size), fmt(q.hidden_size)],
40
+ ['Dense feed-forward width', fmt(n.intermediate_size), fmt(q.intermediate_size)],
41
+ ['Full-attention query heads', fmt(n.num_attention_heads), fmt(q.num_attention_heads)],
42
+ ['Full-attention key/value heads', fmt(n.num_key_value_heads), fmt(q.num_key_value_heads)],
43
+ ['Full-attention head dimension', fmt(n.head_dim), fmt(q.head_dim)],
44
+ ['Configured maximum positions', fmt(n.max_position_embeddings), fmt(q.max_position_embeddings)]
45
+ ];
46
+ byId('spec-body').replaceChildren(...rows.map(row => specRow(...row)));
47
+ }
48
+
49
+ function fact(label, value) {
50
+ const group = document.createElement('div');
51
+ const dt = document.createElement('dt');
52
+ const dd = document.createElement('dd');
53
+ dt.textContent = label;
54
+ dd.textContent = value;
55
+ group.append(dt, dd);
56
+ return group;
57
+ }
58
+
59
+ function renderSelection() {
60
+ const { model, layer } = selected;
61
+ const config = configs[model];
62
+ const type = attentionType(model, layer);
63
+ const label = type === 'linear' ? 'Recurrent linear attention' : 'Full attention';
64
+ document.querySelectorAll('.layer-grid button').forEach(button => {
65
+ button.setAttribute('aria-pressed', String(button.dataset.model === model && Number(button.dataset.layer) === layer));
66
+ });
67
+ byId('inspect-title').textContent = `${names[model]} · layer ${layer + 1}`;
68
+ byId('inspect-description').textContent = type === 'linear'
69
+ ? 'This configured layer uses gated recurrent linear attention. Its head counts describe the linear key and value branches.'
70
+ : 'This configured layer uses grouped-query full attention. The feed-forward path is dense.';
71
+ const rows = [
72
+ fact('Attention', label),
73
+ fact('Hidden width', fmt(config.hidden_size)),
74
+ fact('Feed-forward width', fmt(config.intermediate_size)),
75
+ fact(type === 'linear' ? 'Linear key heads' : 'Query heads', fmt(type === 'linear' ? config.linear_num_key_heads : config.num_attention_heads)),
76
+ fact(type === 'linear' ? 'Linear value heads' : 'Key/value heads', fmt(type === 'linear' ? config.linear_num_value_heads : config.num_key_value_heads)),
77
+ fact(type === 'linear' ? 'Linear value dimension' : 'Head dimension', fmt(type === 'linear' ? config.linear_value_head_dim : config.head_dim))
78
+ ];
79
+ byId('inspect-facts').replaceChildren(...rows);
80
+ }
81
+
82
+ function renderMap(model) {
83
+ const config = configs[model];
84
+ const grid = byId(`${model}-grid`);
85
+ const buttons = Array.from({ length: config.num_hidden_layers }, (_, layer) => {
86
+ const type = attentionType(model, layer);
87
+ const button = document.createElement('button');
88
+ button.type = 'button';
89
+ button.className = `layer ${type}`;
90
+ button.dataset.model = model;
91
+ button.dataset.layer = layer;
92
+ button.textContent = String(layer + 1).padStart(2, '0');
93
+ button.setAttribute('aria-label', `${names[model]}, layer ${layer + 1}, ${type === 'linear' ? 'recurrent linear' : 'full'} attention`);
94
+ button.addEventListener('click', () => {
95
+ selected = { model, layer };
96
+ renderSelection();
97
+ });
98
+ return button;
99
+ });
100
+ grid.replaceChildren(...buttons);
101
+ }
102
+
103
+ async function init() {
104
+ try {
105
+ const entries = await Promise.all(Object.entries(paths).map(async ([model, path]) => {
106
+ const response = await fetch(path);
107
+ if (!response.ok) throw new Error(`${model}: HTTP ${response.status}`);
108
+ return [model, await response.json()];
109
+ }));
110
+ for (const [model, config] of entries) configs[model] = config;
111
+ if (configs.nanbeige.num_hidden_layers !== 52 || configs.qwen.layer_types.length !== configs.qwen.num_hidden_layers) throw new Error('Unexpected decoder configuration');
112
+ renderSpecs();
113
+ renderMap('nanbeige');
114
+ renderMap('qwen');
115
+ renderSelection();
116
+ } catch (error) {
117
+ byId('inspect-title').textContent = 'The comparison could not open';
118
+ byId('inspect-description').textContent = 'Reload this page to try the model configurations again.';
119
+ console.error('Architecture comparison failed', error);
120
+ }
121
+ }
122
+
123
+ init();
architecture/index.html ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <meta name="theme-color" content="#f7f8f3">
7
+ <meta name="description" content="Compare the published decoder configurations of Nanbeige4.3-33B and Qwen3.8-27B, layer by layer.">
8
+ <title>Nanbeige and Qwen architecture | alphaBell</title>
9
+ <link rel="icon" href="../favicon.svg">
10
+ <link rel="stylesheet" href="comparison.css">
11
+ <script src="comparison.js" defer></script>
12
+ </head>
13
+ <body>
14
+ <header class="topbar">
15
+ <a class="brand" href="../index.html" aria-label="Model Observatory home"><span class="mark">α</span><span>alphaBell <span class="slash">/</span> observatory</span></a>
16
+ <a class="back" href="../index.html">Measured captures <span aria-hidden="true">↗</span></a>
17
+ </header>
18
+ <main>
19
+ <section class="intro" aria-labelledby="page-title">
20
+ <p class="eyebrow">Architecture comparison <span>01 / 02</span></p>
21
+ <h1 id="page-title">Two dense decoders.<br><em>Different paths through a token.</em></h1>
22
+ <p class="lead">Nanbeige repeats full attention in 52 layers. Qwen alternates recurrent linear attention with full attention across 64 text-decoder layers. Explore the published configuration, one layer at a time.</p>
23
+ <div class="scope"><span class="scope-dot" aria-hidden="true"></span><strong>Configuration view</strong><span>Layer types and dimensions come from pinned model configs. Nanbeige weights, activations and routing were not measured here.</span></div>
24
+ </section>
25
+
26
+ <section class="overview" aria-labelledby="overview-title">
27
+ <div class="section-heading"><p class="eyebrow">01 / At a glance</p><h2 id="overview-title">The decoder shapes</h2></div>
28
+ <div class="overview-grid">
29
+ <article class="model-card nanbeige-card">
30
+ <div class="model-head"><span class="model-letter">N</span><div><p class="model-family">Llama-style decoder</p><h3>Nanbeige4.3-33B</h3></div></div>
31
+ <p class="model-summary">A uniform stack: every configured layer uses full attention and a dense feed-forward network.</p>
32
+ <div class="hero-number"><strong id="nanbeige-layer-count">52</strong><span>full-attention layers</span></div>
33
+ </article>
34
+ <article class="model-card qwen-card">
35
+ <div class="model-head"><span class="model-letter">Q</span><div><p class="model-family">Hybrid text decoder</p><h3>Qwen3.8-27B</h3></div></div>
36
+ <p class="model-summary">A repeating pattern: three recurrent linear-attention layers, then one full-attention layer.</p>
37
+ <div class="hero-number"><strong id="qwen-layer-count">48 + 16</strong><span>linear + full layers</span></div>
38
+ </article>
39
+ </div>
40
+ <div class="spec-wrap"><table class="spec-table"><caption>Published decoder configuration</caption><thead><tr><th scope="col">Configuration</th><th scope="col">Nanbeige</th><th scope="col">Qwen text decoder</th></tr></thead><tbody id="spec-body"></tbody></table></div>
41
+ </section>
42
+
43
+ <section class="layers" aria-labelledby="layers-title">
44
+ <div class="section-heading"><p class="eyebrow">02 / Layer map</p><h2 id="layers-title">Follow the stack</h2><p>Each square is one configured decoder layer. Select a layer to inspect its attention and feed-forward dimensions.</p></div>
45
+ <div class="legend" aria-label="Layer colors"><span><i class="swatch full"></i>Full attention</span><span><i class="swatch linear"></i>Recurrent linear attention</span></div>
46
+ <div class="map-pair">
47
+ <div class="map-card"><div class="map-title"><h3>Nanbeige</h3><span>52 layers</span></div><div class="layer-grid" id="nanbeige-grid" role="group" aria-label="Nanbeige layers"></div></div>
48
+ <div class="map-card"><div class="map-title"><h3>Qwen text decoder</h3><span>64 layers</span></div><div class="layer-grid" id="qwen-grid" role="group" aria-label="Qwen text decoder layers"></div></div>
49
+ </div>
50
+ <div class="inspect" id="inspect" aria-live="polite"><p class="eyebrow">Selected layer</p><h3 id="inspect-title">Loading configuration</h3><p id="inspect-description"></p><dl id="inspect-facts"></dl></div>
51
+ </section>
52
+
53
+ <section class="source" aria-labelledby="source-title"><div class="section-heading"><p class="eyebrow">Pinned sources</p><h2 id="source-title">Inspect the configs</h2></div><p>Qwen values refer to the <code>text_config</code> decoder inside its released model configuration. Context values are configured maximum positions, not measured usable context.</p><div class="source-links"><a href="https://huggingface.co/Nanbeige/Nanbeige4.3-33B/blob/c1093c501cc6460427c0ac634db7223d0450c0ee/config.json" target="_blank" rel="noopener noreferrer">Nanbeige config <span>c1093c5 ↗</span></a><a href="https://huggingface.co/Qwen/Qwen3.8-27B/blob/1d4bf0f2ff6012fd82039f2fa52739d0dd7c60c0/config.json" target="_blank" rel="noopener noreferrer">Qwen config <span>1d4bf0f ↗</span></a></div></section>
54
+ </main>
55
+ <footer><span>alphaBell / Model Observatory</span><a href="../index.html">Explore measured Flint and Qwen captures ↗</a></footer>
56
+ </body>
57
+ </html>
index.html CHANGED
@@ -3,7 +3,7 @@
3
  <head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Flint &amp; Qwen Model Observatory | alphaBell</title><meta name="description" content="Explore Flint expert routing and Qwen recurrent memory with real Q8 tensor captures. Replay every token, inspect every block and import your own trace."><meta property="og:title" content="Model Observatory by alphaBell"><meta property="og:description" content="Two architectures. Real tensor captures. Every token."><meta property="og:image" content="https://huggingface.co/spaces/alphabell/Model-Observatory/resolve/main/cover.png"><meta name="theme-color" content="#176b59"><link rel="icon" href="favicon.svg"><link rel="stylesheet" href="style.css"></head>
4
  <body>
5
  <header class="models-header"><div class="header-start"><a class="brand" href="./"><span class="brand-icon">α</span><span>alphaBell<span class="brand-divider">/</span><b>observatory</b></span></a><label class="model-control"><span>MODEL</span><select id="modelSelect" aria-label="Model" disabled><option>Recursive Flint</option></select></label></div><div class="header-end"><span class="engine-status" id="engineStatus"><i></i>Loading capture</span><button class="icon-button" id="aboutButton" title="How to read the model" aria-label="How to read the model">?</button></div></header>
6
- <section class="overview"><div><div class="eyebrow" id="modelEyebrow">MODEL OBSERVATORY</div><h1>Inside Flint &amp; Qwen.</h1><a class="experiment-entry" href="experiments/index.html">Try the five experiments ↗</a></div><div class="stats" id="modelStats"></div></section>
7
  <main>
8
  <aside class="input-panel">
9
  <section class="prompt-section"><div class="section-heading"><h2>01 <span>Measured capture</span></h2><span class="small-tag" id="quantization">Q8_0</span></div><p id="traceOrigin" class="trace-origin">Opening example capture…</p><label class="sr-only" for="prompt" id="promptLabel">Captured prompt</label><textarea id="prompt" readonly spellcheck="false">Explain why the sky is blue in two sentences.</textarea><p class="capture-settings" id="captureSettings"></p><button id="runButton" class="primary" disabled>Loading capture…</button><p id="runNote" class="run-note" role="status">Structure is ready while the capture loads.</p><details class="capture-help"><summary>Use your own capture</summary><p>Import a compatible Flint or Qwen trace JSON. It stays in your browser. This public viewer replays measured captures; new prompts need a separate capture engine.</p><a href="https://huggingface.co/spaces/alphabell/Model-Observatory/blob/main/TRACE-FORMAT.md" target="_blank" rel="noreferrer">Trace format ↗</a></details></section>
 
3
  <head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Flint &amp; Qwen Model Observatory | alphaBell</title><meta name="description" content="Explore Flint expert routing and Qwen recurrent memory with real Q8 tensor captures. Replay every token, inspect every block and import your own trace."><meta property="og:title" content="Model Observatory by alphaBell"><meta property="og:description" content="Two architectures. Real tensor captures. Every token."><meta property="og:image" content="https://huggingface.co/spaces/alphabell/Model-Observatory/resolve/main/cover.png"><meta name="theme-color" content="#176b59"><link rel="icon" href="favicon.svg"><link rel="stylesheet" href="style.css"></head>
4
  <body>
5
  <header class="models-header"><div class="header-start"><a class="brand" href="./"><span class="brand-icon">α</span><span>alphaBell<span class="brand-divider">/</span><b>observatory</b></span></a><label class="model-control"><span>MODEL</span><select id="modelSelect" aria-label="Model" disabled><option>Recursive Flint</option></select></label></div><div class="header-end"><span class="engine-status" id="engineStatus"><i></i>Loading capture</span><button class="icon-button" id="aboutButton" title="How to read the model" aria-label="How to read the model">?</button></div></header>
6
+ <section class="overview"><div><div class="eyebrow" id="modelEyebrow">MODEL OBSERVATORY</div><h1>Inside Flint &amp; Qwen.</h1><a class="experiment-entry" href="experiments/index.html">Try the five experiments ↗</a><a class="experiment-entry architecture-entry" href="architecture/index.html">Compare Nanbeige and Qwen architecture ↗</a></div><div class="stats" id="modelStats"></div></section>
7
  <main>
8
  <aside class="input-panel">
9
  <section class="prompt-section"><div class="section-heading"><h2>01 <span>Measured capture</span></h2><span class="small-tag" id="quantization">Q8_0</span></div><p id="traceOrigin" class="trace-origin">Opening example capture…</p><label class="sr-only" for="prompt" id="promptLabel">Captured prompt</label><textarea id="prompt" readonly spellcheck="false">Explain why the sky is blue in two sentences.</textarea><p class="capture-settings" id="captureSettings"></p><button id="runButton" class="primary" disabled>Loading capture…</button><p id="runNote" class="run-note" role="status">Structure is ready while the capture loads.</p><details class="capture-help"><summary>Use your own capture</summary><p>Import a compatible Flint or Qwen trace JSON. It stays in your browser. This public viewer replays measured captures; new prompts need a separate capture engine.</p><a href="https://huggingface.co/spaces/alphabell/Model-Observatory/blob/main/TRACE-FORMAT.md" target="_blank" rel="noreferrer">Trace format ↗</a></details></section>
models/nanbeige.json ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "LlamaForCausalLM"
4
+ ],
5
+ "attention_bias": false,
6
+ "attention_dropout": 0.0,
7
+ "bos_token_id": 166100,
8
+ "embd_pdrop": 0.0,
9
+ "eos_token_id": 166101,
10
+ "ffn_hidden_size": 22016,
11
+ "head_dim": 128,
12
+ "hidden_act": "silu",
13
+ "hidden_size": 7168,
14
+ "initializer_range": 0.02,
15
+ "intermediate_size": 22016,
16
+ "kv_channels": 128,
17
+ "max_position_embeddings": 524288,
18
+ "mlp_bias": false,
19
+ "model_type": "llama",
20
+ "num_attention_heads": 56,
21
+ "num_hidden_layers": 52,
22
+ "num_key_value_heads": 8,
23
+ "num_query_groups": 8,
24
+ "pad_token_id": 0,
25
+ "pretraining_tp": 1,
26
+ "resid_pdrop": 0.0,
27
+ "rms_norm_eps": 1e-05,
28
+ "rope_scaling": null,
29
+ "rope_theta": 120000000,
30
+ "rotary_base": 120000000,
31
+ "seq_length": 524288,
32
+ "tie_word_embeddings": false,
33
+ "torch_dtype": "bfloat16",
34
+ "transformers_version": "4.51.1",
35
+ "use_cache": false,
36
+ "vocab_size": 166912
37
+ }
sources.json CHANGED
@@ -7,6 +7,11 @@
7
  "Qwen/Qwen3.8-27B": {
8
  "sha": "1d4bf0f2ff6012fd82039f2fa52739d0dd7c60c0",
9
  "config": "https://huggingface.co/Qwen/Qwen3.8-27B/resolve/1d4bf0f2ff6012fd82039f2fa52739d0dd7c60c0/config.json"
 
 
 
 
 
10
  }
11
  },
12
  "capture_engine": {
@@ -16,6 +21,7 @@
16
  "checks": {
17
  "flint_matched_configuration_fields": 38,
18
  "qwen_matched_configuration_fields": 23,
 
19
  "differences": 0
20
  }
21
  }
 
7
  "Qwen/Qwen3.8-27B": {
8
  "sha": "1d4bf0f2ff6012fd82039f2fa52739d0dd7c60c0",
9
  "config": "https://huggingface.co/Qwen/Qwen3.8-27B/resolve/1d4bf0f2ff6012fd82039f2fa52739d0dd7c60c0/config.json"
10
+ },
11
+ "Nanbeige/Nanbeige4.3-33B": {
12
+ "sha": "c1093c501cc6460427c0ac634db7223d0450c0ee",
13
+ "config": "https://huggingface.co/Nanbeige/Nanbeige4.3-33B/resolve/c1093c501cc6460427c0ac634db7223d0450c0ee/config.json",
14
+ "bundled_config_sha256": "ee6db71f6de1bc2d78c0adc543e339c44e9340c1e3f474285f3144d2d3cd3df9"
15
  }
16
  },
17
  "capture_engine": {
 
21
  "checks": {
22
  "flint_matched_configuration_fields": 38,
23
  "qwen_matched_configuration_fields": 23,
24
+ "nanbeige_matched_configuration_fields": 33,
25
  "differences": 0
26
  }
27
  }
style.css CHANGED
@@ -145,3 +145,5 @@ button.expert-chip{border:0}
145
  @media(min-width:981px){main{height:max(760px,calc(100vh - 325px));grid-template-rows:minmax(0,1fr)}.input-panel,.model-panel{min-height:0}.model-map{min-height:0}}
146
 
147
  .experiment-entry{display:inline-block;margin-top:9px;font:11px system-ui,sans-serif;color:#176b59;text-underline-offset:4px}
 
 
 
145
  @media(min-width:981px){main{height:max(760px,calc(100vh - 325px));grid-template-rows:minmax(0,1fr)}.input-panel,.model-panel{min-height:0}.model-map{min-height:0}}
146
 
147
  .experiment-entry{display:inline-block;margin-top:9px;font:11px system-ui,sans-serif;color:#176b59;text-underline-offset:4px}
148
+ .architecture-entry{margin-left:15px}
149
+ @media(max-width:650px){.architecture-entry{margin-left:0;display:block}}
tests/architecture.test.cjs ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 'use strict';
2
+ const test = require('node:test');
3
+ const assert = require('node:assert/strict');
4
+ const fs = require('node:fs');
5
+ const path = require('node:path');
6
+ const crypto = require('node:crypto');
7
+ const root = path.resolve(__dirname, '..');
8
+ const read = file => fs.readFileSync(path.join(root, file), 'utf8');
9
+ const n = JSON.parse(read('models/nanbeige.json'));
10
+ const q = JSON.parse(read('models/qwen.json'));
11
+ const sources = JSON.parse(read('sources.json'));
12
+
13
+ test('the pinned Nanbeige configuration supports the displayed comparison', () => {
14
+ assert.deepEqual(n.architectures, ['LlamaForCausalLM']);
15
+ assert.equal(n.num_hidden_layers, 52);
16
+ assert.equal(n.hidden_size, 7168);
17
+ assert.equal(n.intermediate_size, 22016);
18
+ assert.equal(n.num_attention_heads, 56);
19
+ assert.equal(n.num_key_value_heads, 8);
20
+ assert.equal(n.head_dim, 128);
21
+ assert.equal(n.max_position_embeddings, 524288);
22
+ assert.equal(n.num_experts, undefined);
23
+ });
24
+
25
+ test('the pinned Qwen text decoder has three linear layers for each full layer', () => {
26
+ assert.equal(q.model_type, 'qwen3_5_text');
27
+ assert.equal(q.layer_types.length, q.num_hidden_layers);
28
+ assert.equal(q.num_hidden_layers, 64);
29
+ for (let i = 0; i < q.layer_types.length; i++) {
30
+ assert.equal(q.layer_types[i], i % 4 === 3 ? 'full_attention' : 'linear_attention');
31
+ }
32
+ assert.equal(q.linear_num_key_heads, 16);
33
+ assert.equal(q.linear_num_value_heads, 48);
34
+ assert.equal(q.num_experts, 0);
35
+ });
36
+
37
+ test('the architecture route is linked and ships its local assets', () => {
38
+ const home = read('index.html');
39
+ const html = read('architecture/index.html');
40
+ assert.match(home, /href="architecture\/index\.html"/);
41
+ for (const file of ['architecture/comparison.css', 'architecture/comparison.js', 'models/nanbeige.json', 'models/qwen.json']) {
42
+ assert.ok(fs.statSync(path.join(root, file)).size > 0, file);
43
+ }
44
+ assert.match(html, /Nanbeige.*?config/s);
45
+ assert.match(html, /c1093c501cc6460427c0ac634db7223d0450c0ee/);
46
+ assert.match(html, /1d4bf0f2ff6012fd82039f2fa52739d0dd7c60c0/);
47
+ assert.match(html, /Nanbeige weights, activations and routing were not measured here/);
48
+ for (const text of [html, read('architecture/comparison.js'), read('architecture/comparison.css')]) {
49
+ assert.doesNotMatch(text, /\u2014|&mdash;|&#8212;|&#x2014;/i);
50
+ }
51
+ });
52
+
53
+ test('Nanbeige attribution and source pin match the bundled configuration', () => {
54
+ const source = sources.configurations['Nanbeige/Nanbeige4.3-33B'];
55
+ const notice = read('NOTICE');
56
+ const html = read('architecture/index.html');
57
+ assert.equal(source.sha, 'c1093c501cc6460427c0ac634db7223d0450c0ee');
58
+ assert.equal(source.config, `https://huggingface.co/Nanbeige/Nanbeige4.3-33B/resolve/${source.sha}/config.json`);
59
+ assert.equal(crypto.createHash('sha256').update(read('models/nanbeige.json')).digest('hex'), source.bundled_config_sha256);
60
+ assert.equal(Object.keys(n).length, 33);
61
+ assert.equal(sources.checks.nanbeige_matched_configuration_fields, Object.keys(n).length);
62
+ assert.match(html, new RegExp(source.sha));
63
+ assert.match(notice, /Nanbeige\/Nanbeige4\.3-33B, Nanbeige/);
64
+ assert.match(notice, /Apache License 2\.0/);
65
+ assert.match(notice, /https:\/\/www\.apache\.org\/licenses\/LICENSE-2\.0/);
66
+ });