Spaces:
Running
Running
Add pinned Nanbeige and Qwen architecture comparison
#5
by alphabell-research - opened
- NOTICE +4 -1
- architecture/comparison.css +122 -0
- architecture/comparison.js +123 -0
- architecture/index.html +57 -0
- index.html +1 -1
- models/nanbeige.json +37 -0
- sources.json +6 -0
- style.css +2 -0
- tests/architecture.test.cjs +66 -0
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 & 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 & 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 & 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 & 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|—|—|—/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 |
+
});
|