rcode21212 commited on
Commit
7b42979
·
verified ·
1 Parent(s): f7d9e6d

Upload folder using huggingface_hub

Browse files
Files changed (2) hide show
  1. README.md +18 -5
  2. index.html +588 -19
README.md CHANGED
@@ -1,10 +1,23 @@
1
  ---
2
- title: Edge0 35b Showcase
3
- emoji: 🦀
4
- colorFrom: indigo
5
- colorTo: yellow
6
  sdk: static
 
 
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: Edge0 35B Preview — Showcase
3
+ emoji: 🧠
4
+ colorFrom: blue
5
+ colorTo: indigo
6
  sdk: static
7
+ sdk_version: 4.0.0
8
+ app_file: index.html
9
  pinned: false
10
+ license: apache-2.0
11
+ short_description: 35B MoE LLM that runs in ~3 GiB — animated demo
12
  ---
13
 
14
+ # Edge0-35B-A3B-preview — Showcase
15
+
16
+ A static showcase page for the [Edge0-35B-A3B-preview](https://huggingface.co/Edge0/Edge0-35B-A3B-preview) model:
17
+ 35B-class sparse MoE that streams experts from SSD in under 3 GiB of active memory.
18
+
19
+ Includes an interactive simulation of the streaming-inference pipeline (expert routing map, prerouter queue,
20
+ active-memory meter, token decode), animated benchmarks vs the fp16 teacher, architecture details and
21
+ run-it-on-your-Mac instructions.
22
+
23
+ Link: https://huggingface.co/spaces/rcode21212/edge0-35b-showcase
index.html CHANGED
@@ -1,19 +1,588 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ <title>Edge0-35B-A3B-preview — 35B MoE in phone-class memory</title>
7
+ <style>
8
+ :root {
9
+ --bg: #0b0e1a;
10
+ --bg-elev: #121736;
11
+ --bg-elev2: #1a2146;
12
+ --line: #2b3566;
13
+ --text: #e6e9ff;
14
+ --muted: #9aa3d8;
15
+ --accent: #4f7cff;
16
+ --accent2: #8b5cf6;
17
+ --green: #34d399;
18
+ --amber: #fbbf24;
19
+ --red: #f87171;
20
+ --mono: "SF Mono", "JetBrains Mono", Menlo, Consolas, monospace;
21
+ --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
22
+ }
23
+ * { box-sizing: border-box; margin: 0; padding: 0; }
24
+ html { scroll-behavior: smooth; }
25
+ body {
26
+ font-family: var(--sans);
27
+ background: radial-gradient(1200px 600px at 20% -10%, #141b3d 0%, transparent 60%),
28
+ radial-gradient(1000px 500px at 90% 0%, #1d1340 0%, transparent 55%),
29
+ var(--bg);
30
+ color: var(--text);
31
+ line-height: 1.6;
32
+ overflow-x: hidden;
33
+ }
34
+ a { color: var(--accent); text-decoration: none; }
35
+ a:hover { text-decoration: underline; }
36
+ .wrap { max-width: 1060px; margin: 0 auto; padding: 0 24px; }
37
+ nav {
38
+ position: sticky; top: 0; z-index: 50;
39
+ backdrop-filter: blur(12px);
40
+ background: rgba(11, 14, 26, 0.75);
41
+ border-bottom: 1px solid var(--line);
42
+ }
43
+ nav .wrap { display: flex; align-items: center; gap: 20px; height: 58px; }
44
+ nav .logo { font-weight: 700; letter-spacing: 0.02em; color: var(--text); }
45
+ nav .logo span { color: var(--accent); }
46
+ nav .spacer { flex: 1; }
47
+ nav a.link { color: var(--muted); font-size: 14px; }
48
+ nav a.link:hover { color: var(--text); text-decoration: none; }
49
+ nav .badge {
50
+ font-size: 12px; padding: 4px 10px; border-radius: 999px;
51
+ border: 1px solid var(--green); color: var(--green); white-space: nowrap;
52
+ }
53
+
54
+ header.hero { padding: 84px 0 56px; text-align: center; position: relative; }
55
+ .kicker {
56
+ display: inline-flex; align-items: center; gap: 8px;
57
+ font-size: 13px; color: var(--muted);
58
+ border: 1px solid var(--line); border-radius: 999px; padding: 6px 14px;
59
+ margin-bottom: 22px; background: rgba(255,255,255,0.02);
60
+ }
61
+ .kicker b { color: var(--amber); font-weight: 600; }
62
+ h1 {
63
+ font-size: clamp(34px, 5.5vw, 58px);
64
+ line-height: 1.08; letter-spacing: -0.02em; font-weight: 800;
65
+ background: linear-gradient(90deg, #ffffff, var(--accent) 55%, var(--accent2));
66
+ -webkit-background-clip: text; background-clip: text; color: transparent;
67
+ }
68
+ .sub { font-size: clamp(16px, 2.4vw, 20px); color: var(--muted); max-width: 720px; margin: 22px auto 8px; }
69
+ .sub b { color: var(--text); }
70
+ .badges { margin: 24px 0 8px; display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }
71
+ .badges a {
72
+ font-size: 13px; padding: 6px 12px; border-radius: 8px;
73
+ border: 1px solid var(--line); color: var(--text); background: rgba(255,255,255,0.03);
74
+ }
75
+ .badges a:hover { border-color: var(--accent); text-decoration: none; }
76
+ .cta {
77
+ margin-top: 26px; display: flex; gap: 12px; justify-content: center; flex-wrap: wrap;
78
+ }
79
+ .cta a.btn {
80
+ font-weight: 600; font-size: 15px; padding: 12px 22px; border-radius: 10px;
81
+ transition: transform 0.15s ease, box-shadow 0.15s ease;
82
+ }
83
+ .cta a.btn.primary {
84
+ background: linear-gradient(90deg, var(--accent), var(--accent2)); color: #fff;
85
+ box-shadow: 0 8px 32px rgba(79, 124, 255, 0.35);
86
+ }
87
+ .cta a.btn.ghost { border: 1px solid var(--line); color: var(--text); background: rgba(255,255,255,0.02); }
88
+ .cta a.btn:hover { transform: translateY(-2px); text-decoration: none; }
89
+ .cta a.btn.primary:hover { box-shadow: 0 12px 40px rgba(139, 92, 246, 0.4); }
90
+
91
+ .stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 14px; margin: 46px 0 0; }
92
+ .stat {
93
+ border: 1px solid var(--line); border-radius: 14px; padding: 18px 16px;
94
+ background: linear-gradient(180deg, rgba(255,255,255,0.03), rgba(255,255,255,0.01));
95
+ }
96
+ .stat .num { font-family: var(--mono); font-size: 26px; font-weight: 700; color: #fff; }
97
+ .stat .lbl { font-size: 12.5px; color: var(--muted); margin-top: 4px; letter-spacing: 0.04em; text-transform: uppercase; }
98
+
99
+ section { padding: 56px 0; }
100
+ section.alt { background: rgba(255,255,255,0.015); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
101
+ h2 {
102
+ font-size: clamp(24px, 3.4vw, 34px); letter-spacing: -0.02em; font-weight: 800;
103
+ margin-bottom: 8px;
104
+ }
105
+ h2 + p { color: var(--muted); max-width: 720px; margin-bottom: 32px; }
106
+ h3 { font-size: 19px; font-weight: 700; margin: 28px 0 8px; }
107
+
108
+ .demo {
109
+ border: 1px solid var(--line); border-radius: 18px; overflow: hidden;
110
+ background: var(--bg-elev); box-shadow: 0 20px 60px rgba(0,0,0,0.4);
111
+ }
112
+ .demo .bar {
113
+ display: flex; align-items: center; gap: 12px; padding: 10px 16px;
114
+ border-bottom: 1px solid var(--line); background: rgba(255,255,255,0.02);
115
+ font-family: var(--mono); font-size: 12.5px; color: var(--muted);
116
+ }
117
+ .demo .bar .dots { display: flex; gap: 6px; }
118
+ .demo .bar .dot { width: 10px; height: 10px; border-radius: 50%; }
119
+ .dot.r { background: #ff5f57; }.dot.y { background: #febc2e; }.dot.g { background: #28c840; }
120
+ .demo .bar .title { margin-left: 4px; font-weight: 600; color: var(--text); }
121
+ .demo .bar .spacer { flex: 1; }
122
+ .demo .bar .status { color: var(--green); }
123
+
124
+ .demo-body { display: grid; grid-template-columns: 1fr 320px; gap: 0; }
125
+ @media (max-width: 900px) { .demo-body { grid-template-columns: 1fr; } }
126
+
127
+ .stream {
128
+ padding: 20px 22px; border-right: 1px solid var(--line); min-height: 340px;
129
+ display: flex; flex-direction: column;
130
+ }
131
+ @media (max-width: 900px) { .stream { border-right: none; border-bottom: 1px solid var(--line); } }
132
+ .stream .out {
133
+ flex: 1; font-size: 17px; line-height: 1.7; color: var(--text);
134
+ }
135
+ .stream .out .tok { opacity: 0; animation: fadein 0.4s ease forwards; }
136
+ .stream .out .tok.hot { color: var(--accent2); }
137
+ .stream .meta { font-family: var(--mono); font-size: 12.5px; color: var(--muted); margin-top: 14px; display: flex; gap: 18px; flex-wrap: wrap; }
138
+ .stream .meta b { color: var(--text); font-weight: 600; }
139
+ @keyframes fadein { to { opacity: 1; } }
140
+
141
+ .side { padding: 20px 22px; }
142
+ .side h4 { font-size: 12.5px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); margin-bottom: 8px; }
143
+ .grid-wrap { display: grid; grid-template-columns: repeat(16, 1fr); gap: 3px; }
144
+ .exp {
145
+ aspect-ratio: 1; border-radius: 3px; background: #232c57;
146
+ transition: background 0.3s ease, box-shadow 0.3s ease;
147
+ }
148
+ .exp.on { background: linear-gradient(135deg, var(--accent), var(--accent2)); box-shadow: 0 0 10px rgba(139,92,246,0.8); }
149
+ .exp.loading { background: var(--amber); box-shadow: 0 0 8px rgba(251,191,36,0.6); }
150
+ .mem {
151
+ margin-top: 18px; border: 1px solid var(--line); border-radius: 10px; padding: 12px 14px;
152
+ background: rgba(255,255,255,0.02);
153
+ }
154
+ .mem .row { display: flex; justify-content: space-between; font-size: 13px; color: var(--muted); }
155
+ .mem .row b { color: var(--text); font-family: var(--mono); }
156
+ .mem .track { height: 10px; border-radius: 999px; background: #1a2146; margin-top: 10px; overflow: hidden; }
157
+ .mem .fill { height: 100%; width: 62%; border-radius: 999px; background: linear-gradient(90deg, var(--green), var(--accent)); transition: width 0.5s ease; }
158
+ .queue { margin-top: 16px; font-family: var(--mono); font-size: 12.5px; color: var(--muted); }
159
+ .queue .qrow { display: flex; align-items: center; gap: 8px; padding: 5px 0; }
160
+ .queue .qrow .tag { color: var(--green); }
161
+ .controls { margin-top: 16px; }
162
+ .controls button {
163
+ font-family: var(--sans); font-weight: 600; font-size: 14px; cursor: pointer;
164
+ padding: 10px 16px; border-radius: 9px; border: 1px solid var(--line); color: var(--text);
165
+ background: rgba(255,255,255,0.04);
166
+ }
167
+ .controls button:hover { border-color: var(--accent); }
168
+ .controls button:disabled { opacity: 0.45; cursor: default; }
169
+
170
+ .cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 18px; margin-top: 8px; }
171
+ .card {
172
+ border: 1px solid var(--line); border-radius: 14px; padding: 22px 20px;
173
+ background: linear-gradient(180deg, rgba(255,255,255,0.03), rgba(255,255,255,0.01));
174
+ }
175
+ .card .icon { font-size: 26px; }
176
+ .card h3 { margin: 12px 0 8px; font-size: 18px; }
177
+ .card p { color: var(--muted); font-size: 14.5px; }
178
+ .card .stat-line { font-family: var(--mono); color: var(--green); font-size: 13px; margin-top: 12px; }
179
+
180
+ .facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px; }
181
+ .fact { border: 1px solid var(--line); border-radius: 12px; padding: 14px 16px; background: rgba(255,255,255,0.02); }
182
+ .fact .k { font-size: 12px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); }
183
+ .fact .v { font-family: var(--mono); font-size: 15px; font-weight: 600; margin-top: 3px; }
184
+
185
+ table { width: 100%; border-collapse: collapse; font-size: 14.5px; margin-top: 6px; }
186
+ th, td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--line); }
187
+ th { color: var(--muted); font-size: 12.5px; text-transform: uppercase; letter-spacing: 0.05em; }
188
+ td.num, th.num { text-align: right; font-family: var(--mono); }
189
+ tr:hover td { background: rgba(255,255,255,0.02); }
190
+
191
+ .bars { margin-top: 8px; }
192
+ .brow { margin-bottom: 20px; }
193
+ .brow .name { font-size: 13.5px; color: var(--muted); margin-bottom: 6px; }
194
+ .brow .name b { color: var(--text); font-weight: 600; }
195
+ .btrack { display: flex; height: 24px; border-radius: 7px; overflow: hidden; background: #1a2146; gap: 3px; }
196
+ .bar { height: 100%; border-radius: 6px; display: flex; align-items: center; padding: 0 10px; font-size: 12.5px; font-family: var(--mono); color: #0b0e1a; font-weight: 700; white-space: nowrap; width: var(--w); overflow: hidden; }
197
+ .bar.b1 { background: linear-gradient(90deg, var(--amber), #f59e0b); }
198
+ .bar.b2 { background: linear-gradient(90deg, var(--accent), var(--accent2)); }
199
+ .bar.dim { opacity: 0.55; }
200
+ .legend { display: flex; gap: 20px; justify-content: flex-end; font-size: 13px; color: var(--muted); margin-bottom: 10px; }
201
+ .legend span { display: inline-flex; align-items: center; gap: 7px; }
202
+ .legend i { width: 14px; height: 14px; border-radius: 4px; display: inline-block; }
203
+ .legend .l1 { background: linear-gradient(90deg, var(--amber), #f59e0b); }
204
+ .legend .l2 { background: linear-gradient(90deg, var(--accent), var(--accent2)); }
205
+ .bar-anim { transform: scaleX(0); transform-origin: left; }
206
+ .inview .bar-anim { animation: grow 1.1s cubic-bezier(0.22, 1, 0.36, 1) forwards; }
207
+ @keyframes grow { to { transform: scaleX(1); } }
208
+
209
+ pre {
210
+ font-family: var(--mono); font-size: 13.5px; line-height: 1.7;
211
+ background: var(--bg-elev2); border: 1px solid var(--line); border-radius: 12px;
212
+ padding: 18px 20px; overflow-x: auto; margin: 10px 0 22px; color: #d8ddff;
213
+ }
214
+ pre .cm { color: #6b74a8; }
215
+ pre .c1 { color: var(--green); }
216
+ pre .c2 { color: var(--amber); }
217
+ code { font-family: var(--mono); }
218
+ p code, li code { background: var(--bg-elev2); padding: 2px 6px; border-radius: 5px; font-size: 0.92em; color: #c9d2ff; }
219
+
220
+ ul.tight { list-style: none; margin: 10px 0; }
221
+ ul.tight li { padding: 4px 0 4px 24px; position: relative; color: var(--muted); font-size: 14.5px; }
222
+ ul.tight li::before { content: "▸"; position: absolute; left: 4px; color: var(--accent); }
223
+
224
+ .limo {
225
+ border: 1px solid var(--line); border-left: 3px solid var(--amber); border-radius: 10px;
226
+ padding: 16px 18px; background: rgba(251,191,36,0.05); color: var(--muted); font-size: 14.5px; margin-top: 6px;
227
+ }
228
+ .limo b { color: var(--text); }
229
+
230
+ footer { border-top: 1px solid var(--line); padding: 34px 0 46px; color: var(--muted); font-size: 14px; }
231
+ footer .l { display: flex; gap: 6px; margin-top: 6px; font-family: var(--mono); font-size: 12.5px; color: #6b74a8; }
232
+ </style>
233
+ </head>
234
+ <body>
235
+
236
+ <nav>
237
+ <div class="wrap">
238
+ <a class="logo" href="#top">Edge0<span>·35B</span></a>
239
+ <div class="spacer"></div>
240
+ <a class="link" href="#demo">Live demo</a>
241
+ <a class="link" href="#how">How it works</a>
242
+ <a class="link" href="#bench">Benchmarks</a>
243
+ <a class="link" href="#run">Run it</a>
244
+ <span class="badge">● 15 tok/s decode</span>
245
+ </div>
246
+ </nav>
247
+
248
+ <header class="hero" id="top">
249
+ <div class="wrap">
250
+ <div class="kicker"><b>PREVIEW RELEASE</b>&nbsp;·&nbsp;sparse MoE · Apache-2.0 · arxiv 2609.18063</div>
251
+ <h1>Edge0-35B-A3B<br>A 35B model that runs in phone-class memory.</h1>
252
+ <p class="sub">A 35B-class sparse Mixture-of-Experts LLM that streams experts from SSD on demand — so it runs at interactive speed in just <b>~3&nbsp;GiB of active memory</b>, in 4-bit.</p>
253
+ <div class="badges">
254
+ <a href="https://huggingface.co/Edge0/Edge0-35B-A3B-preview">🤗 Model</a>
255
+ <a href="https://github.com/Edge0-AI/edge0">GitHub</a>
256
+ <a href="https://arxiv.org/abs/2609.18063">Paper</a>
257
+ <a href="https://huggingface.co/Edge0/Edge0-8b-a1b-preview">8B sibling</a>
258
+ <a href="https://huggingface.co/Qwen/Qwen3.6-35B-A3B">Base: Qwen3.6-35B-A3B</a>
259
+ </div>
260
+ <div class="cta">
261
+ <a class="btn primary" href="#demo">▶ Watch it stream</a>
262
+ <a class="btn ghost" href="#run">Run it on your Mac</a>
263
+ </div>
264
+
265
+ <div class="stats">
266
+ <div class="stat"><div class="num">35B</div><div class="lbl">params (MoE)</div></div>
267
+ <div class="stat"><div class="num">256 / 4</div><div class="lbl">experts · active per token</div></div>
268
+ <div class="stat"><div class="num">2.9&nbsp;GiB</div><div class="lbl">peak active memory</div></div>
269
+ <div class="stat"><div class="num">~15</div><div class="lbl">tok/s decode</div></div>
270
+ <div class="stat"><div class="num">140</div><div class="lbl">tok/s warm prefill</div></div>
271
+ <div class="stat"><div class="num">4-bit</div><div class="lbl">int4 + LoRA + prerouter</div></div>
272
+ </div>
273
+ </div>
274
+ </header>
275
+
276
+ <section class="alt" id="demo">
277
+ <div class="wrap">
278
+ <h2>Watch it stream in < 3 GiB</h2>
279
+ <p>Interactive simulation of a single forward pass under the edge0 framework: expert weights stream from storage only as routed, while a trained <em>prerouter</em> pre-loads next step's experts. Hit run and watch a token decode.</p>
280
+
281
+ <div class="demo">
282
+ <div class="bar">
283
+ <div class="dots"><span class="dot r"></span><span class="dot y"></span><span class="dot g"></span></div>
284
+ <div class="title">edge0 serve<br>— model edge0-35b —</div>
285
+ <div class="spacer"></div>
286
+ <div class="status" id="status">● idle — press run</div>
287
+ </div>
288
+ <div class="demo-body">
289
+ <div class="stream">
290
+ <div class="out" id="out">...</div>
291
+ <div class="meta">
292
+ <span>decoded: <b id="tokens">0</b></span>
293
+ <span>rate: <b id="rate">—</b></span>
294
+ <span>active: <b id="activePeak">—</b></span>
295
+ </div>
296
+ </div>
297
+ <div class="side">
298
+ <h4>Expert routing map — 256 experts</h4>
299
+ <div class="grid-wrap" id="grid"></div>
300
+
301
+ <div class="mem">
302
+ <div class="row"><span>Active memory</span><span><b id="memText">2.9 GiB</b></span></div>
303
+ <div class="track"><div class="fill" id="memFill"></div></div>
304
+ <div class="row" style="margin-top:8px"><span>Checkpoint on storage</span><span><b>19.6 GB</b></span></div>
305
+ </div>
306
+
307
+ <div class="queue" id="queue"></div>
308
+ <div class="controls">
309
+ <button id="btnRun">▶ Run next token</button>
310
+ <button id="btnAuto">Autoplay</button>
311
+ </div>
312
+ </div>
313
+ </div>
314
+ </div>
315
+ </div>
316
+ </section>
317
+
318
+ <section id="how">
319
+ <div class="wrap">
320
+ <h2>How it fits in phone-class memory</h2>
321
+ <p>Full 4-bit weights stay on storage. Only the experts the router touches — the <em>active set</em> — are streamed into RAM, so peak memory is bounded by activity, not parameter count.</p>
322
+
323
+ <div class="cards">
324
+ <div class="card">
325
+ <div class="icon">💾</div>
326
+ <h3>SSD expert offload</h3>
327
+ <p>All 256 expert blocks live on disk. The router fetches the 4 it needs per token just in time, from NVMe or internal flash, so RAM never holds the full model.</p>
328
+ <div class="stat-line">RAM bounded by active set, not 35B</div>
329
+ </div>
330
+ <div class="card">
331
+ <div class="icon">🔮</div>
332
+ <h3>Prerouter</h3>
333
+ <p>A trained head predicts next-step routing one token ahead, so expert loads overlap compute instead of stalling it — like instruction prefetch for an LLM.</p>
334
+ <div class="stat-line">up to +59% decode throughput</div>
335
+ </div>
336
+ <div class="card">
337
+ <div class="icon">🪢</div>
338
+ <h3>Recover-LoRA</h3>
339
+ <p>The int4 base is frozen; LoRA adapters are distilled from the FP16 teacher to claw back quantization loss. One read-only base serves many adapters, unmerged.</p>
340
+ <div class="stat-line">within 3.9 pts of fp16 teacher</div>
341
+ </div>
342
+ </div>
343
+
344
+ <h3>Specifications</h3>
345
+ <div class="facts">
346
+ <div class="fact"><div class="k">Base model</div><div class="v">Qwen3.6-35B-A3B</div></div>
347
+ <div class="fact"><div class="k">Quantization</div><div class="v">4-bit (int4)</div></div>
348
+ <div class="fact"><div class="k">Layers</div><div class="v">40</div></div>
349
+ <div class="fact"><div class="k">Experts / active</div><div class="v">256 / 4 (K=4)</div></div>
350
+ <div class="fact"><div class="k">Hidden size</div><div class="v">2048</div></div>
351
+ <div class="fact"><div class="k">Framework</div><div class="v">edge0 (MLX)</div></div>
352
+ <div class="fact"><div class="k">Contents</div><div class="v">base + LoRA + prerouter</div></div>
353
+ <div class="fact"><div class="k">License</div><div class="v">Apache-2.0</div></div>
354
+ </div>
355
+ </div>
356
+ </section>
357
+
358
+ <section class="alt" id="bench">
359
+ <div class="wrap">
360
+ <h2>Quality after quantization</h2>
361
+ <p>OpenCompass, identical settings, max score 100. The edge0 int4 + adapters pipeline loses <b style="color:var(--text)">3.9 points on average</b> versus the fp16 base.</p>
362
+
363
+ <div class="legend">
364
+ <span><i class="l1"></i>edge0-35b (int4 + adapters)</span>
365
+ <span><i class="l2"></i>Qwen3.6-35B (fp16)</span>
366
+ </div>
367
+ <div class="bars" id="bars"></div>
368
+
369
+ <h3>Measured performance — Mac mini M4 Pro, 24 GB</h3>
370
+ <table>
371
+ <tr><th></th><th class="num">Decode</th><th class="num">Prefill cold / warm</th><th class="num">Peak active memory*</th></tr>
372
+ <tr><td>edge0-35b</td><td class="num">14.9–17.7 tok/s</td><td class="num">113 / 140 tok/s</td><td class="num">2.9 GiB</td></tr>
373
+ </table>
374
+ <p style="font-size:12.5px;color:var(--muted);margin-top:8px">*Short contexts; long contexts add KV cache. Experts stream from SSD and are not resident.</p>
375
+
376
+ <h3>Model summary</h3>
377
+ <table>
378
+ <tr><th>Item</th><th>Value</th></tr>
379
+ <tr><td>Parameter count</td><td class="num">35B total, A3B active</td></tr>
380
+ <tr><td>Adapter contents</td><td><code>lora_edge0_35b.safetensors</code> · <code>prerouter_edge0_35b.safetensors</code></td></tr>
381
+ <tr><td>Chat template</td><td>thinking-mode enabled (multilingual reasoning)</td></tr>
382
+ <tr><td>Backend</td><td>edge0 streaming framework · MLX (Apple Silicon)</td></tr>
383
+ </table>
384
+ </div>
385
+ </section>
386
+
387
+ <section id="run">
388
+ <div class="wrap">
389
+ <h2>Run it on your Mac</h2>
390
+ <p>The repo is a complete, ready-to-run model directory — base, LoRA and prerouter co-located and loaded automatically.</p>
391
+
392
+ <p><b style="color:var(--text)">1 · Install edge0</b></p>
393
+ <pre><span class="cm"># MLX backend — requires Apple Silicon</span>
394
+ pip install -e <span class="c2">'git+https://github.com/Edge0-AI/edge0.git#egg=edge0[fetch]'</span></pre>
395
+
396
+ <p><b style="color:var(--text)">2 · Download the model</b></p>
397
+ <pre>huggingface-cli download <span class="c1">Edge0/Edge0-35b-a3b-preview</span> --local-dir ./Edge0-35b-a3b-preview</pre>
398
+
399
+ <p><b style="color:var(--text)">3 · Chat or serve</b></p>
400
+ <pre><span class="cm"># Interactive chat</span>
401
+ <span class="c2">export EDGE0_35B_MODEL=$PWD/Edge0-35b-a3b-preview</span>
402
+ edge0 chat --name edge0-35b --prompt <span class="c1">"Introduce yourself"</span>
403
+
404
+ <span class="cm"># OpenAI-compatible HTTP server</span>
405
+ edge0 serve --name edge0-35b --port 8085</pre>
406
+
407
+ <p><b style="color:var(--text)">Connect anything that speaks OpenAI</b></p>
408
+ <ul class="tight">
409
+ <li>Point <code>mlx_lm.server</code> / <code>Pi</code> / <code>Hermes</code> / <code>OpenClaw</code> at <code>http://127.0.0.1:8080/v1</code></li>
410
+ <li>One read-only base serves many LoRA adapter sets — batch multiple users from a single machine</li>
411
+ <li>NVMe or fast internal flash recommended; latency scales with storage speed</li>
412
+ </ul>
413
+
414
+ <h3>Notes & limitations</h3>
415
+ <div class="limo">
416
+ <b>Preview.</b> Coverage and agent/tool-use capability are being extended — multi-step planning and tool use are currently weak.<br>
417
+ <b>Backend.</b> The MLX backend targets Apple Silicon; other backends are on the roadmap.<br>
418
+ <b>Context.</b> Long contexts grow the KV cache; shorter contexts keep peak memory at ~3 GiB.
419
+ </div>
420
+ </div>
421
+ </section>
422
+
423
+ <footer>
424
+ <div class="wrap">
425
+ <b>Edge0-35B-A3B-preview</b> — Apache-2.0 · <a href="https://huggingface.co/Edge0/Edge0-35B-A3B-preview">huggingface.co/Edge0/Edge0-35B-A3B-preview</a>
426
+ <div class="l">Lin, Wang, Cai, Liu &amp; Zeng — "The Other Half of the Memory Wall: Serving 35B MoEs from SSD with Trained Routing Prediction" · arXiv 2609.18063</div>
427
+ </div>
428
+ </footer>
429
+
430
+ <script>
431
+ const SAMPLE = ["Edge0"," 35B"," streams"," experts"," from"," SSD"," on"," demand,"," keeping"," active"," memory"," under"," 3"," GiB"," at"," ~15"," tok/s.",]
432
+
433
+ const N_EXP = 256
434
+ const grid = document.getElementById("grid")
435
+ const out = document.getElementById("out")
436
+ const status = document.getElementById("status")
437
+ const memFill = document.getElementById("memFill")
438
+ const memText = document.getElementById("memText")
439
+ const queueEl = document.getElementById("queue")
440
+ const tokensEl = document.getElementById("tokens")
441
+ const rateEl = document.getElementById("rate")
442
+ const activePeak = document.getElementById("activePeak")
443
+ const btnRun = document.getElementById("btnRun")
444
+ const btnAuto = document.getElementById("btnAuto")
445
+
446
+ const cells = []
447
+ for (let i = 0; i < N_EXP; i++) {
448
+ const d = document.createElement("div")
449
+ d.className = "exp"
450
+ d.dataset.i = i
451
+ grid.appendChild(d)
452
+ cells.push(d)
453
+ }
454
+
455
+ let idx = 0
456
+ let auto = false
457
+ let autoTimer = null
458
+ let started = false
459
+ let lastTime = performance.now()
460
+
461
+ function pickExperts() {
462
+ const set = new Set()
463
+ while (set.size < 4) set.add(Math.floor(Math.random() * N_EXP))
464
+ return [...set]
465
+ }
466
+
467
+ function resetExperts() {
468
+ cells.forEach(c => { c.classList.remove("on", "loading") })
469
+ queueEl.innerHTML = ""
470
+ if (idx < SAMPLE.length) {
471
+ const next = pickExperts()
472
+ const q = document.createElement("div")
473
+ q.className = "qrow"
474
+ q.innerHTML = `<span class="tag">▸ prerouter</span> preloading K=4 experts for next step…`
475
+ queueEl.appendChild(q)
476
+ next.forEach((n, k) => {
477
+ setTimeout(() => cells[n].classList.add("loading"), k * 60)
478
+ })
479
+ }
480
+ }
481
+
482
+ function step() {
483
+ if (idx >= SAMPLE.length) {
484
+ if (auto) stopAuto()
485
+ status.textContent = "● done — re-run to loop"
486
+ return
487
+ }
488
+ const t0 = performance.now()
489
+ const combos = pickExperts()
490
+ resetExperts()
491
+ status.textContent = "● decoding token " + (idx + 1) + "…"
492
+ const tok = document.createElement("span")
493
+ tok.className = "tok"
494
+ tok.textContent = SAMPLE[idx]
495
+ out.appendChild(tok)
496
+ if (idx === SAMPLE.length - 1) { tok.classList.add("hot"); setTimeout(() => tok.classList.remove("hot"), 1200) }
497
+ idx++
498
+
499
+ combos.forEach((n, k) => {
500
+ setTimeout(() => cells[n].classList.add("on"), 120 + k * 70)
501
+ })
502
+
503
+ setTimeout(() => {
504
+ if (!started) { started = true; activePeak.textContent = "2.9 GiB" }
505
+ status.textContent = "○ waiting…"
506
+ }, 500)
507
+
508
+ tokensEl.textContent = idx
509
+ rateEl.textContent = ((idx / (performance.now() - lastTime) * 1000) || 0).toFixed(1) + " tok/s"
510
+ memFill.style.width = (58 + Math.sin(idx) * 3) + "%"
511
+ memText.textContent = (2.80 + 0.08 * Math.sin(idx)).toFixed(2) + " GiB"
512
+ }
513
+
514
+ function play() {
515
+ if (idx >= SAMPLE.length) { reset(); }
516
+ step()
517
+ }
518
+
519
+ function reset() {
520
+ idx = 0; started = false
521
+ out.textContent = "…"
522
+ tokensEl.textContent = 0; rateEl.textContent = "—"
523
+ memFill.style.width = "62%"; memText.textContent = "2.9 GiB"
524
+ activePeak.textContent = "—"
525
+ resetExperts()
526
+ status.textContent = "● idle — press run"
527
+ }
528
+
529
+ function autoToggle() {
530
+ auto = !auto
531
+ btnAuto.textContent = auto ? "⏸ Pause" : "Autoplay"
532
+ btnAuto.style.borderColor = auto ? "var(--green)" : ""
533
+ if (auto) {
534
+ if (!started && idx === 0) reset()
535
+ play()
536
+ autoTimer = setInterval(() => {
537
+ if (auto) play()
538
+ }, 430)
539
+ } else {
540
+ clearInterval(autoTimer)
541
+ }
542
+ }
543
+
544
+ btnRun.addEventListener("click", play)
545
+ btnAuto.addEventListener("click", autoToggle)
546
+
547
+ const bs = document.getElementById("bars")
548
+ const STARTED = new WeakMap()
549
+ const data = [
550
+ ["AIME 2026", 86.6, 92.7],
551
+ ["HumanEval", 90.9, 95.1],
552
+ ["GPQA-Diamond", 79.8, 81.8],
553
+ ["MMLU-Pro", 81.0, 84.6],
554
+ ["IFBench", 57.9, 61.7],
555
+ ["Average", 79.2, 83.2],
556
+ ]
557
+ data.forEach(([name, a, b]) => {
558
+ const row = document.createElement("div")
559
+ row.className = "brow"
560
+ const namediv = document.createElement("div")
561
+ namediv.className = "name"
562
+ namediv.innerHTML = `<b>${name}</b> · edge0 ${a} vs fp16 ${b} (Δ ${(b - a).toFixed(1)})`
563
+ const track = document.createElement("div")
564
+ track.className = "btrack"
565
+ for (const [v, cls] of [[a, "b1"), [b, "b2"]]) {
566
+ const bar = document.createElement("div")
567
+ bar.className = "bar " + cls + " bar-anim"
568
+ bar.style.setProperty("--w", v + "%")
569
+ bar.innerHTML = (a === v ? "edge0 " + v : "fp16 " + v)
570
+ track.appendChild(bar)
571
+ }
572
+ row.appendChild(namediv)
573
+ row.appendChild(track)
574
+ bs.appendChild(row)
575
+ row.style.visibility = "visible"
576
+ })
577
+
578
+ const io = new IntersectionObserver((entries) => {
579
+ entries.forEach(en => {
580
+ if (en.isIntersecting) { en.target.classList.add("inview"); io.unobserve(en.target) }
581
+ })
582
+ }, { threshold: 0.25 })
583
+ io.observe(bs)
584
+
585
+ resetExperts()
586
+ </script>
587
+ </body>
588
+ </html>