mlx-bun 0.0.5 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -2
- package/docs/dag/training-inference-map.html +575 -0
- package/docs/design/memory-system.md +193 -295
- package/docs/design/orpo-dynamic-lambda.md +179 -0
- package/docs/design/orpo-future-enhancements.md +42 -0
- package/docs/design/orpo-training.md +13 -0
- package/docs/design/parity-tier-dag.md +143 -0
- package/docs/design/w4a16-compute-precision-spike.md +232 -0
- package/docs/investigations/orpo-base-uf-experiment-and-directions.md +120 -0
- package/docs/investigations/orpo-flash-cce-pin-leak.md +167 -0
- package/docs/investigations/orpo-uf-testing-handoff.md +126 -0
- package/docs/investigations/steel-flash-cce-handoff.md +58 -0
- package/docs/investigations/trainer-validation-experiment.md +173 -0
- package/docs/reference/memory.md +77 -0
- package/docs/reference/orpo-quickstart.md +44 -5
- package/docs/reference/training.md +9 -5
- package/package.json +3 -3
- package/src/cli.ts +651 -18
- package/src/eval/runner.ts +76 -6
- package/src/eval/tasks/bfcl.ts +49 -15
- package/src/eval/tasks/gsm8k.ts +21 -9
- package/src/eval/tasks/hashhop.ts +33 -4
- package/src/eval/tasks/humaneval.ts +30 -8
- package/src/eval/tasks/ifeval.ts +52 -18
- package/src/eval/tasks/mmlu.ts +85 -74
- package/src/jobs/runner.ts +6 -0
- package/src/memory/chunk.ts +25 -0
- package/src/memory/cluster.ts +24 -0
- package/src/memory/db.ts +114 -0
- package/src/memory/ingest.ts +22 -0
- package/src/memory/pipeline.ts +63 -0
- package/src/memory/prompts.ts +23 -0
- package/src/memory/schedule.ts +163 -0
- package/src/memory/synthesize.ts +29 -0
- package/src/memory/tools.ts +399 -0
- package/src/memory/vault.ts +694 -0
- package/src/memory/wikify.ts +23 -0
- package/src/mlx/metal-kernel.ts +13 -0
- package/src/model/flash-attention.ts +5 -3
- package/src/pi-provider.ts +29 -13
- package/src/pi-session.ts +81 -0
- package/src/pi-terminal.ts +13 -24
- package/src/pi-web.ts +246 -166
- package/src/quantize/job.ts +17 -2
- package/src/quantize/quantizer.ts +26 -2
- package/src/server.ts +213 -44
- package/src/tokenizer.ts +6 -2
- package/src/train/dataset.ts +11 -3
- package/src/train/flash-cce.ts +18 -5
- package/src/train/job.ts +41 -4
- package/src/train/loss.ts +10 -4
- package/src/train/trainer.ts +62 -3
- package/src/train/watch.ts +542 -0
- package/src/web/app.html +264 -14
- package/src/web/skills/memory/SKILL.md +97 -0
- package/src/web/skills/web-research/SKILL.md +3 -1
- package/src/web/skills.ts +46 -8
package/README.md
CHANGED
|
@@ -134,6 +134,14 @@ back in responses).
|
|
|
134
134
|
- **The background agent runtime** — leave a local OpenAI-compatible endpoint
|
|
135
135
|
available for scripts, recurring jobs, app integrations, and per-request
|
|
136
136
|
adapter routing.
|
|
137
|
+
- **The local memory layer** — `mlx-bun memory init` creates a git-tracked
|
|
138
|
+
Markdown wiki at `~/.mlx-bun/wiki`; `Reference/` is seeded with read-only
|
|
139
|
+
symlinks to mlx-bun's own docs, and the built-in pi agents read both those
|
|
140
|
+
docs and your articles quietly (`memory_search`, `memory_section`, etc.) and can open it in Obsidian for you
|
|
141
|
+
(`mlx-bun memory open [article]`). Chat-time memory is read-only; synthesis is
|
|
142
|
+
the separate writer path. The planned synthesis pipeline uses the same local
|
|
143
|
+
models with stage-specific LoRA adapters (chunk, bucket, synthesize, edit)
|
|
144
|
+
trained by the project creator and distributed from Hugging Face.
|
|
137
145
|
|
|
138
146
|
The default experience is intentionally opinionated. Power users can override
|
|
139
147
|
models, budgets, KV modes, adapters, and flags; the average user should not
|
|
@@ -407,8 +415,9 @@ prompt cache); registry / fit / KV persistence; quantized +
|
|
|
407
415
|
mixed-precision KV serving (rotating-cache KV-quant, Phase 9) with fused
|
|
408
416
|
quantized prefill (Phase 10); LoRA hot-swap with per-request selection;
|
|
409
417
|
segmented-backward LoRA training (SFT / DPO / ORPO, with an `[M,vocab]`-free
|
|
410
|
-
flash-CCE head + prefix-sharing for long-context preference data —
|
|
411
|
-
[training guide](docs/reference/training.md));
|
|
418
|
+
flash-CCE head + prefix-sharing for long-context preference data — `mlx-bun
|
|
419
|
+
train <model> --data <dir>`, see [training guide](docs/reference/training.md));
|
|
420
|
+
resumable
|
|
412
421
|
verified downloads (`mlx-bun get`); memory admission control; the
|
|
413
422
|
head-to-head benchmark harness; the decode-gap root-cause fix
|
|
414
423
|
(2026-06-11); Anthropic Messages + Responses API (`/v1/messages` and
|
|
@@ -0,0 +1,575 @@
|
|
|
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>mlx-bun · control-flow DAG (MiniCPM5-1B)</title>
|
|
7
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.28.1/cytoscape.min.js"></script>
|
|
8
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/dagre/0.8.5/dagre.min.js"></script>
|
|
9
|
+
<script src="https://cdn.jsdelivr.net/npm/cytoscape-dagre@2.5.0/cytoscape-dagre.min.js"></script>
|
|
10
|
+
<style>
|
|
11
|
+
:root{--bg:#0b0f14;--panel:#11161d;--line:#243040;--txt:#cdd9e5;--dim:#7d8aa0;--cond:#39c5cf;}
|
|
12
|
+
*{box-sizing:border-box;}
|
|
13
|
+
html,body{margin:0;height:100%;background:var(--bg);color:var(--txt);font:13px/1.5 ui-monospace,SFMono-Regular,Menlo,monospace;}
|
|
14
|
+
#top{display:flex;align-items:center;gap:12px;padding:8px 14px;flex-wrap:wrap;border-bottom:1px solid var(--line);background:var(--panel);}
|
|
15
|
+
#top b{color:#fff;font-size:14px;}
|
|
16
|
+
.seg{display:flex;gap:2px;background:#0b0f14;border:1px solid var(--line);border-radius:6px;}
|
|
17
|
+
.seg button,.btn{background:transparent;color:var(--dim);border:0;padding:5px 11px;cursor:pointer;font:inherit;border-radius:5px;}
|
|
18
|
+
.seg button.on{background:#388bfd;color:#fff;}
|
|
19
|
+
.btn{border:1px solid var(--line);}
|
|
20
|
+
.legend{margin-left:auto;display:flex;gap:11px;color:var(--dim);align-items:center;flex-wrap:wrap;font-size:11px;}
|
|
21
|
+
.legend span{display:flex;align-items:center;gap:5px;}
|
|
22
|
+
.dot{width:9px;height:9px;border-radius:50%;display:inline-block;}
|
|
23
|
+
.dash{width:15px;border-top:2px dashed var(--cond);display:inline-block;}
|
|
24
|
+
#wrap{display:flex;height:calc(100% - 46px);}
|
|
25
|
+
#cy{flex:1;height:100%;}
|
|
26
|
+
#side{width:340px;border-left:1px solid var(--line);background:var(--panel);padding:14px;overflow:auto;}
|
|
27
|
+
#side h2{margin:0 0 4px;font-size:14px;color:#fff;}
|
|
28
|
+
#side .file{color:#388bfd;font-size:12px;word-break:break-all;margin-bottom:8px;}
|
|
29
|
+
#side .k{color:var(--dim);text-transform:uppercase;font-size:10.5px;letter-spacing:.06em;margin-top:10px;}
|
|
30
|
+
#side .v{white-space:pre-wrap;}
|
|
31
|
+
.hint{color:var(--dim);font-size:12px;margin-top:6px;}
|
|
32
|
+
code{color:#e3b341;}
|
|
33
|
+
</style>
|
|
34
|
+
</head>
|
|
35
|
+
<body>
|
|
36
|
+
<div id="top">
|
|
37
|
+
<b>mlx-bun control-flow DAG</b><span style="color:var(--dim);font-size:11px">MiniCPM5-1B</span>
|
|
38
|
+
<div class="seg" id="graph">
|
|
39
|
+
<button data-g="infer" class="on">inference</button>
|
|
40
|
+
<button data-g="train">training</button>
|
|
41
|
+
</div>
|
|
42
|
+
<button class="btn" id="fit">⤢ fit</button>
|
|
43
|
+
<div class="legend" id="legend"></div>
|
|
44
|
+
</div>
|
|
45
|
+
<div id="wrap">
|
|
46
|
+
<div id="cy"></div>
|
|
47
|
+
<div id="side">
|
|
48
|
+
<h2 id="s-title">Click a step</h2>
|
|
49
|
+
<div class="file" id="s-file"></div>
|
|
50
|
+
<div class="hint" id="hint">Every node = one actual step the code runs. Solid arrows = the next step in execution order. <b style="color:var(--cond)">Dashed labelled arrows</b> = a branch: the code can go several ways, and the label is the exact condition (flag / variable / check) that takes that edge. Loops are back-edges. Scroll to zoom, drag to pan. Colour = subsystem (legend). Traced from the actual source — file:line on each node.</div>
|
|
51
|
+
<div id="s-body" style="display:none">
|
|
52
|
+
<div class="k">file</div><div class="v" id="s-fileb"></div>
|
|
53
|
+
<div class="k">subsystem</div><div class="v" id="s-grp"></div>
|
|
54
|
+
<div class="k">outgoing</div><div class="v" id="s-out"></div>
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
<script>
|
|
59
|
+
// node = [id, label, group, file]. edge = [from, to, condition('' = unconditional)].
|
|
60
|
+
// A node with several edges of different conditions IS a branch point.
|
|
61
|
+
const GRP={ // subsystem → colour
|
|
62
|
+
drive:'#388bfd', fwd:'#2ea043', layer:'#3fb950', attn:'#d29922', sdpa:'#a371f7',
|
|
63
|
+
unfused:'#6e7b91', tiled:'#39c5cf', mlp:'#56d364', kv:'#f0883e', samp:'#db61a2',
|
|
64
|
+
setup:'#6e7b91', loss:'#d29922', seg:'#a371f7', accum:'#388bfd', bwd:'#f85149',
|
|
65
|
+
norm:'#39c5cf', opt:'#f0883e', metrics:'#db61a2' };
|
|
66
|
+
|
|
67
|
+
const INFER={ n:[
|
|
68
|
+
['n1','generate() entry','drive','generate.ts:168'],
|
|
69
|
+
['n2','generateInner() entry','drive','generate.ts:208'],
|
|
70
|
+
['n3','? wired-scope: FORCE_WIRE ∨ weights>thresh','drive','generate.ts:175'],
|
|
71
|
+
['n4','enter wired scope','drive','generate.ts:200'],
|
|
72
|
+
['n5','? adapters?.length','drive','generate.ts:174'],
|
|
73
|
+
['n6','set loraState.active','drive','generate.ts:187'],
|
|
74
|
+
['n7','makeCache/Sampler/LogitsProcessors','drive','generate.ts:218'],
|
|
75
|
+
['n8','maybeQuantizeKv (prefill)','drive','generate.ts:281'],
|
|
76
|
+
['n9','? prompt-pos > prefillChunkSize','drive','generate.ts:298'],
|
|
77
|
+
['n10','chunked prefill: loop chunk','drive','generate.ts:299'],
|
|
78
|
+
['n11','forwardHidden(chunk, cache)','drive','generate.ts:301'],
|
|
79
|
+
['n12','evalAll(cache) after chunk','drive','generate.ts:304'],
|
|
80
|
+
['n13','clearCache() after chunk','drive','generate.ts:312'],
|
|
81
|
+
['n14','? options.promptEmbeddings','drive','generate.ts:284'],
|
|
82
|
+
['n15','forwardEmbeddings(...)','drive','generate.ts:292'],
|
|
83
|
+
['n16','forwardHidden(lastChunk, cache)','drive','generate.ts:320'],
|
|
84
|
+
['n17','? needsTokenHistory init','drive','generate.ts:315'],
|
|
85
|
+
['n18','slice last position h0[:,L-1]','drive','generate.ts:324'],
|
|
86
|
+
['n19','logitsFromHidden(hLast)','drive','generate.ts:326'],
|
|
87
|
+
['n20','sampleStep(logits0, 0)','drive','generate.ts:328'],
|
|
88
|
+
['n21','asyncEvalAll([pending])','drive','generate.ts:338'],
|
|
89
|
+
['n22','? CompiledDecode.for (env·adapters·gemma4)','drive','generate.ts:352'],
|
|
90
|
+
['n23','decode loop: while !stop','drive','generate.ts:360'],
|
|
91
|
+
['n24','? generated+1 < maxTokens','drive','generate.ts:364'],
|
|
92
|
+
['n25','maybeQuantizeKv (decode)','drive','generate.ts:365'],
|
|
93
|
+
['n26','pushHistory(cur)','drive','generate.ts:366'],
|
|
94
|
+
['n27','? compiled && supports(cache)','drive','generate.ts:369'],
|
|
95
|
+
['n28','compiled.step(cur, cache)','drive','generate.ts:371'],
|
|
96
|
+
['n29','catch → compiled=null (fallback)','drive','generate.ts:374'],
|
|
97
|
+
['n30','forwardHidden(ids, cache)','drive','generate.ts:383'],
|
|
98
|
+
['n31','logitsFromHidden(h)','drive','generate.ts:385'],
|
|
99
|
+
['n32','sampleStep(logits, n+1)','drive','generate.ts:388'],
|
|
100
|
+
['n33','asyncEvalAll([nextPending,…])','drive','generate.ts:390'],
|
|
101
|
+
['n34','itemUint32(cur) sync-read token','drive','generate.ts:394'],
|
|
102
|
+
['n35','? first token: prefillMs/tDecode','drive','generate.ts:399'],
|
|
103
|
+
['n36','cur.dispose; generated++','drive','generate.ts:402'],
|
|
104
|
+
['n37','? nextPending !== null','drive','generate.ts:406'],
|
|
105
|
+
['n38','? eosTokenIds.includes(token)','drive','generate.ts:408'],
|
|
106
|
+
['n39','yield {token, index}','drive','generate.ts:413'],
|
|
107
|
+
['n40','? clearCache every 256','drive','generate.ts:416'],
|
|
108
|
+
['n42','stop = true (no next)','drive','generate.ts:418'],
|
|
109
|
+
['n43','pending = nextPending','drive','generate.ts:420'],
|
|
110
|
+
['n44','stop = true (EOS / done)','drive','generate.ts:411'],
|
|
111
|
+
['n45','decodeMs','drive','generate.ts:425'],
|
|
112
|
+
['n46','return makeStats()','drive','generate.ts:427'],
|
|
113
|
+
['n47','finally: dispose pending/cache/history','drive','generate.ts:432'],
|
|
114
|
+
['n49','loraState.active=[] (scope exit)','drive','generate.ts:191'],
|
|
115
|
+
['n50','exitWiredScope()','drive','generate.ts:204'],
|
|
116
|
+
// model forward
|
|
117
|
+
['n51','embed.encode(ids)','fwd','minicpm5.ts:250'],
|
|
118
|
+
['n52','forwardLayers(h, cache)','fwd','minicpm5.ts:258'],
|
|
119
|
+
['n53','runLayerRange(h,0,N,cache)','fwd','minicpm5.ts:259'],
|
|
120
|
+
['n54','? makeMask(L) (N==1? offset==0?)','fwd','minicpm5.ts:275'],
|
|
121
|
+
['n55','for i in [0,N): layers','fwd','minicpm5.ts:277'],
|
|
122
|
+
['n56','layers[i].forward(cur,mask,cache[i])','fwd','minicpm5.ts:278'],
|
|
123
|
+
['n57','? dispose(cur) if i>0','fwd','minicpm5.ts:279'],
|
|
124
|
+
['n58','mask.arr?.dispose()','fwd','minicpm5.ts:282'],
|
|
125
|
+
['n59','finalNorm.forward(h)','fwd','minicpm5.ts:261'],
|
|
126
|
+
['n60','lmHead.forward(h) → logits','fwd','minicpm5.ts:287'],
|
|
127
|
+
// layer
|
|
128
|
+
['n61','inputNorm RMSNorm','layer','minicpm5.ts:189'],
|
|
129
|
+
['n62','attn.forward(xn,mask,cache)','layer','minicpm5.ts:190'],
|
|
130
|
+
['n63','add(x, attnOut) residual','layer','minicpm5.ts:192'],
|
|
131
|
+
['n64','postAttnNorm RMSNorm','layer','minicpm5.ts:194'],
|
|
132
|
+
['n65','mlp.forward(hn)','layer','minicpm5.ts:195'],
|
|
133
|
+
['n66','add(h, mlpOut) residual','layer','minicpm5.ts:197'],
|
|
134
|
+
// attention
|
|
135
|
+
['n67','q_proj quantized_matmul','attn','minicpm5.ts:89'],
|
|
136
|
+
['n68','k_proj quantized_matmul','attn','minicpm5.ts:90'],
|
|
137
|
+
['n69','v_proj quantized_matmul','attn','minicpm5.ts:91'],
|
|
138
|
+
['n70','reshape q [B,L,H,D]','attn','minicpm5.ts:93'],
|
|
139
|
+
['n71','reshape k [B,L,Kv,D]','attn','minicpm5.ts:94'],
|
|
140
|
+
['n72','reshape v [B,L,Kv,D]','attn','minicpm5.ts:95'],
|
|
141
|
+
['n73','transpose q →[B,H,L,D]','attn','minicpm5.ts:97'],
|
|
142
|
+
['n74','transpose k','attn','minicpm5.ts:98'],
|
|
143
|
+
['n75','transpose v','attn','minicpm5.ts:99'],
|
|
144
|
+
['n76','? rope: prefixPlan / offsetArr / static','attn','minicpm5.ts:106'],
|
|
145
|
+
['n77','ropeBlocks(q) (prefix)','attn','minicpm5.ts:108'],
|
|
146
|
+
['n78','ropeDynamic(q) (offsetArr)','attn','minicpm5.ts:110'],
|
|
147
|
+
['n79','rope(q, cache.offset)','attn','minicpm5.ts:111'],
|
|
148
|
+
['n80','rope k (same offset)','attn','minicpm5.ts:113'],
|
|
149
|
+
['n81','? cache instanceof QuantizedKVCache','attn','minicpm5.ts:115'],
|
|
150
|
+
['n82','updateAndFetchQuantized(k,v)','attn','minicpm5.ts:116'],
|
|
151
|
+
['n83','quantizedSdpa(q,kq,vq,…)','attn','minicpm5.ts:119'],
|
|
152
|
+
['n84','updateAndFetch(k,v) bf16','attn','minicpm5.ts:123'],
|
|
153
|
+
['n85','? getTrainingAttn()=="flash"','attn','minicpm5.ts:128'],
|
|
154
|
+
['n86','flashAttention(...)','attn','minicpm5.ts:130'],
|
|
155
|
+
['n87','ops.sdpa(q,keys,values,…)','attn','minicpm5.ts:132'],
|
|
156
|
+
['n88','transpose attn →[B,L,H,D]','attn','minicpm5.ts:138'],
|
|
157
|
+
['n89','reshape merged [B,L,H*D]','attn','minicpm5.ts:140'],
|
|
158
|
+
['n90','o_proj quantized_matmul','attn','minicpm5.ts:142'],
|
|
159
|
+
// sdpa dispatch
|
|
160
|
+
['n91','? mask=="" && scale==1.0','sdpa','gemma4-base.ts:1514'],
|
|
161
|
+
['n92','? perfKernelEnabled()','sdpa','fused-decode-kernel.ts:36'],
|
|
162
|
+
['n93','? !isCompiledTrace()','sdpa','gemma4-base.ts:1515'],
|
|
163
|
+
['n94','? fusedDecodeKernelSupported','sdpa','gemma4-base.ts:1515'],
|
|
164
|
+
['n95','⚙ fusedDecodeSdpa (L=1)','sdpa','gemma4-base.ts:1517'],
|
|
165
|
+
['n96','? tile: L>1 ∨ FUSED_DECODE','sdpa','gemma4-base.ts:1518'],
|
|
166
|
+
['n97','? fusedSdpaSupported','sdpa','gemma4-base.ts:1519'],
|
|
167
|
+
['n98','⚙ quantizedSdpaTiled','sdpa','gemma4-base.ts:1520'],
|
|
168
|
+
['n99','quantizedSdpaUnfused','sdpa','gemma4-base.ts:1521'],
|
|
169
|
+
// unfused internals
|
|
170
|
+
['n100','dims [B,H,L,D,KV,nRep,N]','unfused','gemma4-base.ts:1221'],
|
|
171
|
+
['n101','? scale !== 1.0','unfused','gemma4-base.ts:1229'],
|
|
172
|
+
['n102','mulScalar(q, scale)','unfused','gemma4-base.ts:1229'],
|
|
173
|
+
['n103','? nRep > 1 (GQA)','unfused','gemma4-base.ts:1233'],
|
|
174
|
+
['n104','reshape q [B,KV,nRep,L,D]','unfused','gemma4-base.ts:1234'],
|
|
175
|
+
['n105','expandDims(k.packed,-3)','unfused','gemma4-base.ts:1245'],
|
|
176
|
+
['n106','quantizedMatmulQT(q,kᵀ) → scores','unfused','gemma4-base.ts:1251'],
|
|
177
|
+
['n107','? mask.mode=="causal"','unfused','gemma4-base.ts:1256'],
|
|
178
|
+
['n108','greaterEqual → causal mask','unfused','gemma4-base.ts:1261'],
|
|
179
|
+
['n109','? mask.mode=="array"','unfused','gemma4-base.ts:1264'],
|
|
180
|
+
['n110','where(mask, scores, -inf)','unfused','gemma4-base.ts:1269'],
|
|
181
|
+
['n111','softmaxAxis(scores,-1)','unfused','gemma4-base.ts:1276'],
|
|
182
|
+
['n112','quantizedMatmulQT(probs,vᵀ) → out','unfused','gemma4-base.ts:1278'],
|
|
183
|
+
['n113','? nRep > 1','unfused','gemma4-base.ts:1279'],
|
|
184
|
+
['n114','reshape out [B,H,L,D]','unfused','gemma4-base.ts:1280'],
|
|
185
|
+
// tiled internals
|
|
186
|
+
['n115','dims [B,H,L,D,KV,nRep,N]','tiled','gemma4-base.ts:1304'],
|
|
187
|
+
['n116','? scale !== 1.0','tiled','gemma4-base.ts:1312'],
|
|
188
|
+
['n117','mulScalar(q, scale)','tiled','gemma4-base.ts:1312'],
|
|
189
|
+
['n118','? nRep > 1 (GQA)','tiled','gemma4-base.ts:1317'],
|
|
190
|
+
['n119','reshape q [B,KV,nRep,L,D]','tiled','gemma4-base.ts:1318'],
|
|
191
|
+
['n120','expandDims(k.packed,-3)','tiled','gemma4-base.ts:1324'],
|
|
192
|
+
['n121','? mask.mode=="causal"','tiled','gemma4-base.ts:1340'],
|
|
193
|
+
['n122','greaterEqual → causal mask','tiled','gemma4-base.ts:1345'],
|
|
194
|
+
['n123','? mask.mode=="array"','tiled','gemma4-base.ts:1348'],
|
|
195
|
+
['n124','for n0=0..N step 512 (KV chunks)','tiled','gemma4-base.ts:1378'],
|
|
196
|
+
['n125','slice kᵀ.packed chunk','tiled','gemma4-base.ts:1381'],
|
|
197
|
+
['n126','slice kᵀ.scales chunk','tiled','gemma4-base.ts:1382'],
|
|
198
|
+
['n127','slice kᵀ.biases chunk','tiled','gemma4-base.ts:1383'],
|
|
199
|
+
['n128','slice vᵀ.packed chunk','tiled','gemma4-base.ts:1386'],
|
|
200
|
+
['n129','quantizedMatmulQT(q,kChunk) → scores','tiled','gemma4-base.ts:1391'],
|
|
201
|
+
['n130','? maskChunk dtype bool','tiled','gemma4-base.ts:1397'],
|
|
202
|
+
['n131','where(mask, scores, -inf)','tiled','gemma4-base.ts:1399'],
|
|
203
|
+
['n132','add(scores, maskChunk) float','tiled','gemma4-base.ts:1402'],
|
|
204
|
+
['n133','maxAxis(scores) → chunkMax','tiled','gemma4-base.ts:1409'],
|
|
205
|
+
['n134','? oAcc===null (first tile)','tiled','gemma4-base.ts:1410'],
|
|
206
|
+
['n135','init rowMax/rowSum/oAcc','tiled','gemma4-base.ts:1411'],
|
|
207
|
+
['n136','maximum(rowMax,chunkMax)=newMax','tiled','gemma4-base.ts:1419'],
|
|
208
|
+
['n137','exp(rowMax-newMax)=factor','tiled','gemma4-base.ts:1422'],
|
|
209
|
+
['n138','exp(scores-newMax)=exps','tiled','gemma4-base.ts:1425'],
|
|
210
|
+
['n139','newSum = factor·rowSum + Σexps','tiled','gemma4-base.ts:1428'],
|
|
211
|
+
['n140','nextAcc = oAcc·factor + exps·vChunk','tiled','gemma4-base.ts:1436'],
|
|
212
|
+
['n141','rowMax/rowSum = new','tiled','gemma4-base.ts:1443'],
|
|
213
|
+
['n142','div(oAcc, rowSum) → out','tiled','gemma4-base.ts:1452'],
|
|
214
|
+
['n143','? nRep > 1','tiled','gemma4-base.ts:1459'],
|
|
215
|
+
['n144','reshape out [B,H,L,D]','tiled','gemma4-base.ts:1460'],
|
|
216
|
+
// mlp
|
|
217
|
+
['n145','gate_proj quantized_matmul','mlp','minicpm5.ts:160'],
|
|
218
|
+
['n146','up_proj quantized_matmul','mlp','minicpm5.ts:161'],
|
|
219
|
+
['n147','sigmoid(gate)','mlp','minicpm5.ts:162'],
|
|
220
|
+
['n148','mul → SiLU (gate·σ(gate))','mlp','minicpm5.ts:163'],
|
|
221
|
+
['n149','mul(silu, up)','mlp','minicpm5.ts:166'],
|
|
222
|
+
['n150','down_proj quantized_matmul','mlp','minicpm5.ts:169'],
|
|
223
|
+
// KV bf16
|
|
224
|
+
['n151','offset=prev, L=k.shape[2]','kv','gemma4-base.ts:252'],
|
|
225
|
+
['n152','? capacity: !keys ∨ prev+L>cap','kv','gemma4-base.ts:254'],
|
|
226
|
+
['n153','alloc newK/newV zeros','kv','gemma4-base.ts:257'],
|
|
227
|
+
['n154','? cache exists','kv','gemma4-base.ts:260'],
|
|
228
|
+
['n155','? prev%STEP!=0 (trim)','kv','gemma4-base.ts:263'],
|
|
229
|
+
['n156','slice old, dispose','kv','gemma4-base.ts:264'],
|
|
230
|
+
['n157','concat([old,new]) grow','kv','gemma4-base.ts:271'],
|
|
231
|
+
['n158','sliceUpdate keys←k','kv','gemma4-base.ts:283'],
|
|
232
|
+
['n159','sliceUpdate values←v','kv','gemma4-base.ts:284'],
|
|
233
|
+
['n160','slice fetch keys','kv','gemma4-base.ts:290'],
|
|
234
|
+
['n161','slice fetch values','kv','gemma4-base.ts:291'],
|
|
235
|
+
// KV quantized
|
|
236
|
+
['n162','prev/L/elPerInt','kv','gemma4-base.ts:443'],
|
|
237
|
+
['n163','? capacity (packed)','kv','gemma4-base.ts:446'],
|
|
238
|
+
['n164','grow cache (6 comps)','kv','gemma4-base.ts:447'],
|
|
239
|
+
['n165','? prev%STEP!=0 (trim)','kv','gemma4-base.ts:448'],
|
|
240
|
+
['n166','trimTo (slice 6)','kv','gemma4-base.ts:449'],
|
|
241
|
+
['n167','quantize(k) → kq','kv','gemma4-base.ts:467'],
|
|
242
|
+
['n168','quantize(v) → vq','kv','gemma4-base.ts:468'],
|
|
243
|
+
['n169','write k packed/scales/biases','kv','gemma4-base.ts:479'],
|
|
244
|
+
['n175','fetch keys (3 comps)','kv','gemma4-base.ts:488'],
|
|
245
|
+
['n176','fetch values (3 comps)','kv','gemma4-base.ts:488'],
|
|
246
|
+
// sampler
|
|
247
|
+
['n177','? curve sampler active','samp','sampler.ts:418'],
|
|
248
|
+
['n178','applyCurve(lp, curve)','samp','sampler.ts:420'],
|
|
249
|
+
['n179','randomCategorical (curve)','samp','sampler.ts:421'],
|
|
250
|
+
['n180','? temperature === 0','samp','sampler.ts:429'],
|
|
251
|
+
['n181','argmaxAxis(lp) greedy','samp','sampler.ts:430'],
|
|
252
|
+
['n182','? hlg?.enabled','samp','sampler.ts:437'],
|
|
253
|
+
['n183','applyHlgShaper','samp','sampler.ts:453'],
|
|
254
|
+
['n184','applyHlgPipeline','samp','sampler.ts:454'],
|
|
255
|
+
['n185','applyHlgEotf','samp','sampler.ts:454'],
|
|
256
|
+
['n186','applyHlgOetf','samp','sampler.ts:455'],
|
|
257
|
+
['n187','applyHlg (parametric)','samp','sampler.ts:455'],
|
|
258
|
+
['n188','randomCategorical (HLG)','samp','sampler.ts:457'],
|
|
259
|
+
['n189','? topP in (0,1)','samp','sampler.ts:467'],
|
|
260
|
+
['n190','applyTopP(lp, topP)','samp','sampler.ts:467'],
|
|
261
|
+
['n191','? topK > 0','samp','sampler.ts:468'],
|
|
262
|
+
['n192','applyTopK(lp, topK)','samp','sampler.ts:468'],
|
|
263
|
+
['n193','mulScalar(lp, 1/temp)','samp','sampler.ts:469'],
|
|
264
|
+
['n194','randomCategorical (temp)','samp','sampler.ts:471'],
|
|
265
|
+
],e:[
|
|
266
|
+
['n1','n2',''],['n2','n3',''],
|
|
267
|
+
['n3','n4','FORCE_WIRE ∨ weights>thresh'],['n3','n5','else'],
|
|
268
|
+
['n4','n5',''],
|
|
269
|
+
['n5','n6','adapters?.length'],['n5','n7','else'],
|
|
270
|
+
['n6','n7',''],['n7','n8',''],['n8','n9',''],
|
|
271
|
+
['n9','n10','pos > prefillChunkSize'],['n9','n14','else (one-shot)'],
|
|
272
|
+
['n10','n11',''],['n11','n51','call forward'],['n11','n12',''],['n12','n13',''],
|
|
273
|
+
['n13','n10','more chunks'],['n13','n14','done'],
|
|
274
|
+
['n14','n15','promptEmbeddings'],['n14','n16','else'],
|
|
275
|
+
['n15','n17',''],['n16','n51','call forward'],['n16','n17',''],
|
|
276
|
+
['n17','n18',''],['n18','n19',''],['n19','n60','call lmHead'],['n19','n20',''],['n20','n21',''],['n21','n22',''],['n22','n23',''],
|
|
277
|
+
['n23','n24',''],
|
|
278
|
+
['n24','n25','generated+1<maxTokens'],['n24','n34','else'],
|
|
279
|
+
['n25','n26',''],['n26','n27',''],
|
|
280
|
+
['n27','n28','compiled && supports'],['n27','n30','else (uncompiled)'],
|
|
281
|
+
['n28','n29','throws'],['n28','n31','ok'],['n29','n30',''],
|
|
282
|
+
['n30','n51','call forward'],['n30','n31',''],['n31','n60','call lmHead'],['n31','n32',''],['n32','n33',''],['n33','n34',''],
|
|
283
|
+
['n34','n35','first token'],['n34','n36','else'],['n35','n36',''],['n36','n37',''],
|
|
284
|
+
['n37','n38','nextPending!=null'],['n37','n42','else'],
|
|
285
|
+
['n38','n39','!EOS'],['n38','n44','EOS'],
|
|
286
|
+
['n39','n40',''],['n40','n43','nextPending'],['n40','n42','none'],
|
|
287
|
+
['n42','n44',''],['n43','n23','loop'],
|
|
288
|
+
['n44','n45',''],['n45','n46',''],['n46','n47',''],['n47','n49',''],['n49','n50',''],
|
|
289
|
+
// forward
|
|
290
|
+
['n51','n52',''],['n52','n53',''],['n53','n54',''],['n54','n55',''],
|
|
291
|
+
['n55','n56','i<N'],['n56','n57',''],['n57','n55','i++'],['n57','n58','done'],
|
|
292
|
+
['n58','n59',''],['n59','n12','return (prefill)'],['n59','n17','return (prefill)'],['n59','n31','return (decode)'],
|
|
293
|
+
// layer (called by n56)
|
|
294
|
+
['n56','n61','call layer'],
|
|
295
|
+
['n61','n62',''],['n62','n63',''],['n63','n64',''],['n64','n65',''],['n65','n66',''],
|
|
296
|
+
// attention (called by n62)
|
|
297
|
+
['n62','n67','call attn'],
|
|
298
|
+
['n67','n68',''],['n68','n69',''],['n69','n70',''],['n70','n71',''],['n71','n72',''],['n72','n73',''],['n73','n74',''],['n74','n75',''],['n75','n76',''],
|
|
299
|
+
['n76','n77','_prefixPlan'],['n76','n78','offsetArr'],['n76','n79','else (static)'],
|
|
300
|
+
['n77','n80',''],['n78','n80',''],['n79','n80',''],['n80','n81',''],
|
|
301
|
+
['n81','n82','QuantizedKVCache'],['n81','n84','else (bf16)'],
|
|
302
|
+
['n82','n83',''],['n83','n88',''],
|
|
303
|
+
['n84','n85',''],
|
|
304
|
+
['n85','n86','flash & supported'],['n85','n87','else'],
|
|
305
|
+
['n86','n88',''],['n87','n88',''],['n88','n89',''],['n89','n90',''],
|
|
306
|
+
// sdpa dispatch (called by n83)
|
|
307
|
+
['n83','n91','call quantizedSdpa'],
|
|
308
|
+
['n91','n92','mask=="" & scale==1'],['n91','n96','else'],
|
|
309
|
+
['n92','n93','perfKernel'],['n92','n96','else'],
|
|
310
|
+
['n93','n94','!compiledTrace'],['n93','n96','else'],
|
|
311
|
+
['n94','n95','supported'],['n94','n96','else'],
|
|
312
|
+
['n96','n97','tile (L>1 ∨ FUSED_DECODE)'],['n96','n99','else'],
|
|
313
|
+
['n97','n98','fusedSdpaSupported'],['n97','n99','else'],
|
|
314
|
+
// unfused (n99)
|
|
315
|
+
['n99','n100','call'],['n100','n101',''],
|
|
316
|
+
['n101','n102','scale!=1'],['n101','n103','else'],['n102','n103',''],
|
|
317
|
+
['n103','n104','nRep>1'],['n103','n106','else'],['n104','n105',''],['n105','n106',''],
|
|
318
|
+
['n106','n107',''],['n107','n108','causal'],['n107','n109','else'],
|
|
319
|
+
['n108','n110',''],['n109','n110','array'],['n109','n111','none'],['n110','n111',''],
|
|
320
|
+
['n111','n112',''],['n112','n113',''],['n113','n114','nRep>1'],
|
|
321
|
+
// tiled (n98)
|
|
322
|
+
['n98','n115','call'],['n115','n116',''],
|
|
323
|
+
['n116','n117','scale!=1'],['n116','n118','else'],['n117','n118',''],
|
|
324
|
+
['n118','n119','nRep>1'],['n118','n121','else'],['n119','n120',''],['n120','n121',''],
|
|
325
|
+
['n121','n122','causal'],['n121','n123','else'],['n122','n124',''],['n123','n124',''],
|
|
326
|
+
['n124','n125','n0<N'],['n125','n126',''],['n126','n127',''],['n127','n128',''],['n128','n129',''],
|
|
327
|
+
['n129','n130',''],['n130','n131','bool'],['n130','n132','float'],['n131','n133',''],['n132','n133',''],
|
|
328
|
+
['n133','n134',''],['n134','n135','first'],['n134','n136','else'],
|
|
329
|
+
['n135','n124','next chunk'],
|
|
330
|
+
['n136','n137',''],['n137','n138',''],['n138','n139',''],['n139','n140',''],['n140','n141',''],['n141','n124','next chunk'],
|
|
331
|
+
['n124','n142','n0>=N'],['n142','n143',''],['n143','n144','nRep>1'],
|
|
332
|
+
// mlp (called by n65)
|
|
333
|
+
['n65','n145','call mlp'],
|
|
334
|
+
['n145','n146',''],['n146','n147',''],['n147','n148',''],['n148','n149',''],['n149','n150',''],
|
|
335
|
+
// KV bf16 (called by n84)
|
|
336
|
+
['n84','n151','call updateAndFetch'],
|
|
337
|
+
['n151','n152',''],['n152','n153','grow'],['n152','n158','fits'],
|
|
338
|
+
['n153','n154',''],['n154','n155','exists'],['n154','n157','first'],
|
|
339
|
+
['n155','n156','prev%STEP!=0'],['n155','n157','aligned'],['n156','n157',''],['n157','n158',''],
|
|
340
|
+
['n158','n159',''],['n159','n160',''],['n160','n161',''],
|
|
341
|
+
// KV quant (called by n82)
|
|
342
|
+
['n82','n162','call updateAndFetchQuantized'],
|
|
343
|
+
['n162','n163',''],['n163','n164','grow'],['n163','n167','fits'],
|
|
344
|
+
['n164','n165',''],['n165','n166','prev%STEP!=0'],['n165','n167','aligned'],['n166','n167',''],
|
|
345
|
+
['n167','n168',''],['n168','n169',''],['n169','n175',''],['n175','n176',''],
|
|
346
|
+
// sampler (called by n20, n32)
|
|
347
|
+
['n20','n177','call sampleStep'],['n32','n177','call sampleStep'],
|
|
348
|
+
['n177','n178','curve'],['n177','n180','else'],['n178','n179',''],
|
|
349
|
+
['n180','n181','temp==0'],['n180','n182','else'],
|
|
350
|
+
['n182','n183','shaper'],['n182','n184','pipeline'],['n182','n185','eotf'],['n182','n186','oetf'],['n182','n187','parametric'],['n182','n189','hlg off'],
|
|
351
|
+
['n183','n188',''],['n184','n188',''],['n185','n188',''],['n186','n188',''],['n187','n188',''],
|
|
352
|
+
['n189','n190','topP'],['n189','n191','else'],['n190','n191',''],
|
|
353
|
+
['n191','n192','topK'],['n191','n193','else'],['n192','n193',''],['n193','n194',''],
|
|
354
|
+
]};
|
|
355
|
+
|
|
356
|
+
const TRAIN={ n:[
|
|
357
|
+
['t1','step loop begins','setup','trainer.ts:479'],
|
|
358
|
+
['t2','per-step dropout seed','setup','trainer.ts:876'],
|
|
359
|
+
['t3','enter accumulation loop','accum','trainer.ts:487'],
|
|
360
|
+
['t4','fetch micro-batch','accum','trainer.ts:490'],
|
|
361
|
+
['t5','? segmentSize > 0','setup','trainer.ts:409'],
|
|
362
|
+
['t6','segmented forward start','seg','segmented.ts:196'],
|
|
363
|
+
['t7','embed.encode(ids)','seg','segmented.ts:196'],
|
|
364
|
+
['t8','detach embedding boundary','seg','segmented.ts:196'],
|
|
365
|
+
['t9','for segment k=0..nSeg','seg','segmented.ts:197'],
|
|
366
|
+
['t10','runLayerRange[lo:hi] (swap LoRA)','seg','segmented.ts:199'],
|
|
367
|
+
['t11','detach output boundary k','seg','segmented.ts:199'],
|
|
368
|
+
['t12','? ORPO prefix-shared & segmented','seg','trainer.ts:880'],
|
|
369
|
+
['t13','splitPrefixBatch','seg','trainer.ts:881'],
|
|
370
|
+
['t14','single forward [P;C;R] block-mask','seg','prefix-shared.ts:159'],
|
|
371
|
+
['t15','prefix fallback (two-forward)','seg','trainer.ts:884'],
|
|
372
|
+
['t16','non-segmented forward start','accum','trainer.ts:492'],
|
|
373
|
+
['t17','value_and_grad: swap primals','accum','trainer.ts:432'],
|
|
374
|
+
['t18','? B==1 response-only vs full','loss','loss.ts:123'],
|
|
375
|
+
['t19','forwardHidden → [B,T,hid]','fwd','forward.ts:72'],
|
|
376
|
+
['t20','embedding forward','fwd','forward.ts:92'],
|
|
377
|
+
['t21','layer-stack forward','fwd','forward.ts:92'],
|
|
378
|
+
['t22','? MLX_BUN_TRAIN_ATTN=="flash"','fwd','trainer.ts:469'],
|
|
379
|
+
['t23','sdpa attention (O(L²) bwd)','fwd','loss.ts:131'],
|
|
380
|
+
['t24','flash attention (O(L) bwd)','fwd','trainer.ts:469'],
|
|
381
|
+
['t25','final norm','fwd','forward.ts:113'],
|
|
382
|
+
['t26','lm-head → logits','fwd','loss.ts:131'],
|
|
383
|
+
['t27','? B==1 responseCe vs B>1 maskedCe','loss','loss.ts:123'],
|
|
384
|
+
['t28','slice hidden to response span','loss','loss.ts:160'],
|
|
385
|
+
['t29','head at response positions','loss','loss.ts:161'],
|
|
386
|
+
['t30','gather target logits','loss','loss.ts:170'],
|
|
387
|
+
['t31','logsumexp vocab','loss','loss.ts:169'],
|
|
388
|
+
['t32','CE = lse - target','loss','loss.ts:172'],
|
|
389
|
+
['t33','sum/normalize response CE','loss','loss.ts:174'],
|
|
390
|
+
['t34','build response mask [B,T]','loss','loss.ts:233'],
|
|
391
|
+
['t35','reshape logits [B*T,V]','loss','loss.ts:251'],
|
|
392
|
+
['t36','gather targets','loss','loss.ts:252'],
|
|
393
|
+
['t37','logsumexp','loss','loss.ts:256'],
|
|
394
|
+
['t38','CE * mask','loss','loss.ts:262'],
|
|
395
|
+
['t39','sum masked CE / norm','loss','loss.ts:264'],
|
|
396
|
+
['t40','DPO ref logps (scale=0, detach)','loss','loss.ts:361'],
|
|
397
|
+
['t41','DPO policy logps','loss','loss.ts:389'],
|
|
398
|
+
['t42','logr_c = piC - refC','loss','loss.ts:392'],
|
|
399
|
+
['t43','logr_r = piR - refR','loss','loss.ts:393'],
|
|
400
|
+
['t44','adv = β(logr_c - logr_r)','loss','loss.ts:394'],
|
|
401
|
+
['t45','-logσ(adv) = softplus; mean','loss','loss.ts:399'],
|
|
402
|
+
['t46','ORPO chosen logp','loss','loss.ts:1242'],
|
|
403
|
+
['t47','? orpoChunkSize > 0','loss','loss.ts:481'],
|
|
404
|
+
['t48','? orpoFusedCe ∨ orpoFlashCe','loss','loss.ts:482'],
|
|
405
|
+
['t49','chunked head (Checkpoint)','loss','loss.ts:567'],
|
|
406
|
+
['t50','fused linear-CE head (CustomVjp)','loss','loss.ts:726'],
|
|
407
|
+
['t51','vocab-blocked head','loss','loss.ts:822'],
|
|
408
|
+
['t52','flash-CCE Metal head','loss','loss.ts:1009'],
|
|
409
|
+
['t53','whole-vocab head (oracle)','loss','loss.ts:1087'],
|
|
410
|
+
['t54','ORPO rejected logp','loss','loss.ts:1243'],
|
|
411
|
+
['t55','NLL = mean(-ℓw)','loss','loss.ts:1225'],
|
|
412
|
+
['t56','log_odds calc','loss','loss.ts:1207'],
|
|
413
|
+
['t57','OR = mean softplus(-log_odds)','loss','loss.ts:1228'],
|
|
414
|
+
['t58','L = NLL + λ·OR','loss','loss.ts:1231'],
|
|
415
|
+
['t59','seg loss-head VJP (cot=1)','seg','segmented.ts:141'],
|
|
416
|
+
['t60','seg loss scalar (detached)','seg','segmented.ts:204'],
|
|
417
|
+
['t61','seg dh_out = dLoss/dhidden','seg','segmented.ts:205'],
|
|
418
|
+
['t62','evalAll([loss, …grads])','accum','trainer.ts:1027'],
|
|
419
|
+
['t63','loss scalar toFloat32','accum','trainer.ts:1028'],
|
|
420
|
+
['t64','scale grad by 1/accum','accum','trainer.ts:1042'],
|
|
421
|
+
['t65','accumulate grad','accum','trainer.ts:1048'],
|
|
422
|
+
['t66','dispose checkpoint closures','accum','trainer.ts:496'],
|
|
423
|
+
['t67','sum micro losses','accum','trainer.ts:1061'],
|
|
424
|
+
['t69','value_and_grad backward','bwd','trainer.ts:492'],
|
|
425
|
+
['t70','MLX reverse-mode AD','bwd','trainer.ts:492'],
|
|
426
|
+
['t71','restore LoRA leaves','bwd','trainer.ts:436'],
|
|
427
|
+
['t72','seg backward: k=nSeg-1..0','bwd','segmented.ts:210'],
|
|
428
|
+
['t73','vjp segment k (cot=dh_out)','bwd','segmented.ts:215'],
|
|
429
|
+
['t74','scatter per-seg LoRA grads','bwd','segmented.ts:220'],
|
|
430
|
+
['t75','dh_in → cotangent for k-1','bwd','segmented.ts:225'],
|
|
431
|
+
['t76','dispose boundary k','bwd','segmented.ts:226'],
|
|
432
|
+
['t80','globalNorm(grads)','norm','trainer.ts:1076'],
|
|
433
|
+
['t81','square each grad','norm','trainer.ts:1078'],
|
|
434
|
+
['t82','sum squares, sqrt','norm','trainer.ts:1086'],
|
|
435
|
+
['t83','? ‖g‖ > maxNorm','norm','trainer.ts:1099'],
|
|
436
|
+
['t84','scale g *= max/‖g‖','norm','trainer.ts:1103'],
|
|
437
|
+
['t85','AdamW.step(grads)','opt','trainer.ts:504'],
|
|
438
|
+
['t86','t++ step counter','opt','optimizer.ts:84'],
|
|
439
|
+
['t87','bias-correct β1^t','opt','optimizer.ts:85'],
|
|
440
|
+
['t88','bias-correct β2^t','opt','optimizer.ts:86'],
|
|
441
|
+
['t89','for each param i (A,B)','opt','optimizer.ts:88'],
|
|
442
|
+
['t90','grad → float32','opt','optimizer.ts:92'],
|
|
443
|
+
['t91','m ← β1·m + (1-β1)g','opt','optimizer.ts:95'],
|
|
444
|
+
['t92','v ← β2·v + (1-β2)g²','opt','optimizer.ts:105'],
|
|
445
|
+
['t93','? weight decay','opt','optimizer.ts:119'],
|
|
446
|
+
['t94','m̂ = m/(1-β1^t)','opt','optimizer.ts:125'],
|
|
447
|
+
['t95','v̂ = v/(1-β2^t)','opt','optimizer.ts:126'],
|
|
448
|
+
['t96','√v̂ + ε','opt','optimizer.ts:127'],
|
|
449
|
+
['t97','m̂/(√v̂+ε)','opt','optimizer.ts:130'],
|
|
450
|
+
['t98','scale by lr (LoRA+ per-param)','opt','optimizer.ts:131'],
|
|
451
|
+
['t99','p = p - lr·update','opt','optimizer.ts:132'],
|
|
452
|
+
['t100','writeParam → swap into LoRA','opt','trainer.ts:402'],
|
|
453
|
+
['t101','opt.evalState()','opt','trainer.ts:505'],
|
|
454
|
+
['t102','clearCache()','metrics','trainer.ts:511'],
|
|
455
|
+
['t103','emit step metrics','metrics','trainer.ts:516'],
|
|
456
|
+
['t104','? step%report==0 ∨ step==1','metrics','trainer.ts:514'],
|
|
457
|
+
['t105','recompute dpo/orpo metrics','metrics','trainer.ts:900'],
|
|
458
|
+
['t106','? step%eval==0 & valid>0','metrics','trainer.ts:529'],
|
|
459
|
+
['t107','disable grad-ckpt for eval','metrics','trainer.ts:532'],
|
|
460
|
+
['t108','loop validation examples','metrics','trainer.ts:554'],
|
|
461
|
+
['t109','eval loss per example','metrics','trainer.ts:564'],
|
|
462
|
+
['t110','reduce eval (mean/acc/margin)','metrics','trainer.ts:684'],
|
|
463
|
+
['t111','re-enable grad-ckpt','metrics','trainer.ts:534'],
|
|
464
|
+
['t112','step iteration completes','setup','trainer.ts:538'],
|
|
465
|
+
],e:[
|
|
466
|
+
['t1','t2',''],['t2','t3',''],['t3','t4',''],['t4','t5',''],
|
|
467
|
+
['t5','t6','segmentSize>0'],['t5','t16','else'],
|
|
468
|
+
['t6','t7',''],['t7','t8',''],['t8','t9',''],
|
|
469
|
+
['t9','t10','k<nSeg'],['t10','t11',''],['t11','t9','k++'],
|
|
470
|
+
['t11','t12','done (ORPO)'],['t11','t59','done (SFT seg)'],
|
|
471
|
+
['t12','t13','prefixShared & segmented'],['t12','t59','else'],
|
|
472
|
+
['t13','t14','split non-null'],['t13','t15','null (mismatch)'],
|
|
473
|
+
['t14','t59',''],['t15','t72',''],
|
|
474
|
+
['t16','t17',''],['t17','t18',''],
|
|
475
|
+
['t18','t19','B==1'],['t18','t20','full-logits'],
|
|
476
|
+
['t19','t20',''],['t20','t21',''],['t21','t22',''],
|
|
477
|
+
['t22','t24','flash'],['t22','t23','else'],
|
|
478
|
+
['t23','t25',''],['t24','t25',''],['t25','t26',''],
|
|
479
|
+
['t19','t27','SFT B==1'],['t26','t27','SFT B>1'],
|
|
480
|
+
['t27','t28','B==1'],['t27','t34','B>1'],
|
|
481
|
+
['t28','t29',''],['t29','t30',''],['t30','t31',''],['t31','t32',''],['t32','t33',''],
|
|
482
|
+
['t34','t35',''],['t35','t36',''],['t36','t37',''],['t37','t38',''],['t38','t39',''],
|
|
483
|
+
// DPO
|
|
484
|
+
['t4','t40','method==dpo'],['t40','t41',''],['t41','t42',''],['t42','t43',''],['t43','t44',''],['t44','t45',''],
|
|
485
|
+
// ORPO
|
|
486
|
+
['t4','t12','method==orpo & prefixShared'],['t12','t46','else'],['t13','t46','null → two-forward'],
|
|
487
|
+
['t46','t47',''],
|
|
488
|
+
['t47','t48','chunkSize>0'],['t47','t54','batched'],
|
|
489
|
+
['t48','t49','neither'],['t48','t50','fused'],['t48','t52','flash'],
|
|
490
|
+
['t50','t51','vocabBlock>0'],['t50','t53','else'],
|
|
491
|
+
['t49','t54',''],['t51','t54',''],['t52','t54',''],['t53','t54',''],
|
|
492
|
+
['t14','t55','prefix-shared done'],['t54','t55',''],
|
|
493
|
+
['t55','t56',''],['t56','t57',''],['t57','t58',''],
|
|
494
|
+
// seg head
|
|
495
|
+
['t59','t60',''],['t60','t61',''],
|
|
496
|
+
// accumulation
|
|
497
|
+
['t33','t62','SFT B==1'],['t39','t62','SFT B>1'],['t45','t62','DPO'],['t58','t62','ORPO'],['t60','t62','seg'],
|
|
498
|
+
['t62','t63',''],
|
|
499
|
+
['t63','t64','accum>1'],['t63','t66','else'],
|
|
500
|
+
['t64','t65',''],['t65','t66',''],
|
|
501
|
+
['t66','t64','next micro'],['t66','t67','last micro'],
|
|
502
|
+
// backward
|
|
503
|
+
['t62','t69','non-seg'],['t69','t70',''],['t70','t71',''],
|
|
504
|
+
['t61','t72','seg'],['t72','t73','k>=0'],['t73','t74',''],['t74','t75',''],['t75','t76',''],['t76','t72','k--'],
|
|
505
|
+
// norm/clip
|
|
506
|
+
['t71','t80',''],['t72','t80','seg done'],['t67','t80','accum done'],
|
|
507
|
+
['t80','t81',''],['t81','t82',''],['t82','t83',''],
|
|
508
|
+
['t83','t84','‖g‖>max'],['t83','t85','else'],['t84','t85',''],
|
|
509
|
+
// optimizer
|
|
510
|
+
['t85','t86',''],['t86','t87',''],['t87','t88',''],['t88','t89',''],
|
|
511
|
+
['t89','t90','i<len'],['t90','t91',''],['t91','t92',''],['t92','t93',''],
|
|
512
|
+
['t93','t94','wd>0 / else'],['t94','t95',''],['t95','t96',''],['t96','t97',''],['t97','t98',''],['t98','t99',''],['t99','t100',''],['t100','t89','i++'],
|
|
513
|
+
['t89','t101','done'],
|
|
514
|
+
// metrics
|
|
515
|
+
['t101','t102',''],['t102','t103',''],['t103','t104',''],
|
|
516
|
+
['t104','t105','report'],['t104','t106','skip'],['t105','t106',''],
|
|
517
|
+
['t106','t107','eval'],['t106','t112','skip'],
|
|
518
|
+
['t107','t108',''],['t108','t109','ex'],['t109','t108','next'],['t108','t110','done'],['t110','t111',''],['t111','t112',''],
|
|
519
|
+
['t112','t1','step++'],
|
|
520
|
+
]};
|
|
521
|
+
|
|
522
|
+
let MODE_G='infer';
|
|
523
|
+
const cy=cytoscape({container:document.getElementById('cy'),minZoom:0.06,maxZoom:3,wheelSensitivity:0.25,
|
|
524
|
+
autoungrabify:true, boxSelectionEnabled:false, selectionType:'single',
|
|
525
|
+
style:[
|
|
526
|
+
{selector:'node',style:{'background-color':d=>GRP[d.data('grp')]||'#6e7b91','label':'data(label)',
|
|
527
|
+
'color':'#0b0f14','font-family':'ui-monospace, Menlo, monospace','font-size':'11px','font-weight':'600',
|
|
528
|
+
'text-valign':'center','text-halign':'center','shape':'round-rectangle','width':'label','height':22,
|
|
529
|
+
'padding':'7px','text-wrap':'wrap','text-max-width':'210px','border-width':1,'border-color':'#0b0f14'}},
|
|
530
|
+
{selector:'node[branch]',style:{'border-width':2.5,'border-color':'#39c5cf'}},
|
|
531
|
+
{selector:'node:selected',style:{'border-width':3,'border-color':'#fff'}},
|
|
532
|
+
{selector:'edge',style:{'width':1.6,'line-color':'#3a4760','target-arrow-color':'#3a4760',
|
|
533
|
+
'target-arrow-shape':'triangle','curve-style':'bezier','arrow-scale':0.8}},
|
|
534
|
+
{selector:'edge[cond]',style:{'line-color':'#39c5cf','target-arrow-color':'#39c5cf','line-style':'dashed',
|
|
535
|
+
'label':'data(cond)','font-size':'8px','font-family':'ui-monospace, Menlo, monospace','color':'#39c5cf',
|
|
536
|
+
'text-background-color':'#0b0f14','text-background-opacity':0.85,'text-background-padding':'1px','text-rotation':'autorotate'}},
|
|
537
|
+
]});
|
|
538
|
+
|
|
539
|
+
function build(g){
|
|
540
|
+
// count outgoing per node to mark branch points (>1 distinct outgoing edge)
|
|
541
|
+
const out={}; g.e.forEach(([a])=>out[a]=(out[a]||0)+1);
|
|
542
|
+
const nodes=g.n.map(([id,label,grp,file])=>({data:{id,label,grp,file,branch:out[id]>1?1:undefined}}));
|
|
543
|
+
const edges=g.e.map(([a,b,c])=>({data:{id:a+'>'+b+(c||''),source:a,target:b,...(c?{cond:c}:{})}}));
|
|
544
|
+
return {nodes,edges};
|
|
545
|
+
}
|
|
546
|
+
function load(g){const el=build(g);cy.elements().remove();cy.add(el.nodes);cy.add(el.edges);
|
|
547
|
+
cy.layout({name:'dagre',rankDir:'TB',nodeSep:18,rankSep:30,padding:30}).run();}
|
|
548
|
+
|
|
549
|
+
function show(d){
|
|
550
|
+
document.getElementById('s-title').textContent=d.label;
|
|
551
|
+
document.getElementById('s-file').textContent=d.file||'';
|
|
552
|
+
document.getElementById('hint').style.display='none';
|
|
553
|
+
document.getElementById('s-body').style.display='block';
|
|
554
|
+
document.getElementById('s-fileb').textContent=d.file||'';
|
|
555
|
+
document.getElementById('s-grp').textContent=d.grp||'';
|
|
556
|
+
const outs=cy.getElementById(d.id).outgoers('edge').map(e=>{
|
|
557
|
+
const t=e.target().data('label'); const c=e.data('cond'); return c?`• [${c}] → ${t}`:`• → ${t}`;}).join('\n');
|
|
558
|
+
document.getElementById('s-out').textContent=outs||'(terminal)';
|
|
559
|
+
}
|
|
560
|
+
cy.on('tap','node',e=>show(e.target.data()));
|
|
561
|
+
document.getElementById('fit').onclick=()=>cy.fit(undefined,40);
|
|
562
|
+
const LABELS={drive:'generate',fwd:'forward',layer:'layer',attn:'attention',sdpa:'sdpa dispatch',unfused:'unfused sdpa',tiled:'tiled sdpa',mlp:'mlp',kv:'kv cache',samp:'sampler',
|
|
563
|
+
setup:'setup/loop',loss:'loss head',seg:'segmented',accum:'accum',bwd:'backward',norm:'grad norm/clip',opt:'optimizer',metrics:'metrics/eval'};
|
|
564
|
+
function legend(){
|
|
565
|
+
const groups = MODE_G==='infer' ? ['drive','fwd','attn','sdpa','tiled','unfused','mlp','kv','samp'] : ['setup','fwd','loss','seg','accum','bwd','norm','opt','metrics'];
|
|
566
|
+
document.getElementById('legend').innerHTML='<span><i class="dash"></i>branch (condition)</span>'+
|
|
567
|
+
groups.map(g=>`<span><i class="dot" style="background:${GRP[g]}"></i>${LABELS[g]}</span>`).join('');
|
|
568
|
+
}
|
|
569
|
+
document.querySelectorAll('#graph button').forEach(b=>b.onclick=()=>{
|
|
570
|
+
document.querySelectorAll('#graph button').forEach(x=>x.classList.remove('on'));b.classList.add('on');
|
|
571
|
+
MODE_G=b.dataset.g;load(MODE_G==='infer'?INFER:TRAIN);legend();});
|
|
572
|
+
legend();load(INFER);
|
|
573
|
+
</script>
|
|
574
|
+
</body>
|
|
575
|
+
</html>
|