Upload web/public/transformer.js with huggingface_hub
Browse files- web/public/transformer.js +20 -1
web/public/transformer.js
CHANGED
|
@@ -182,6 +182,7 @@
|
|
| 182 |
cfg: { ...cfg, layers, heads, hidden, vocab: vocabSize() },
|
| 183 |
ctx: { L, bgemm: (engine && engine.bgemm) || null,
|
| 184 |
att: (engine && engine.att) || null, fgemm: (engine && engine.fgemm) || null,
|
|
|
|
| 185 |
mlp: (engine && engine.mlp) || null,
|
| 186 |
audit: audit || null, unitBackward: !!cfg.unitBackward },
|
| 187 |
emb: add("emb", mk(vocabSize() * c, 0.08)),
|
|
@@ -271,6 +272,11 @@
|
|
| 271 |
const qq = V.quantizeRows(q, BT * heads, hd), kq = V.quantizeRows(k, BT * heads, hd);
|
| 272 |
const sAll = ctx.att ? await ctx.att.scores(qq.q, kq.q, qq.s, kq.s, dAtt)
|
| 273 |
: V.attScoresJS(qq.q, kq.q, qq.s, kq.s, dAtt, ctx.L);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 274 |
const aAll = new Float32Array(BH * T * T); // causal softmax
|
| 275 |
for (let bz = 0; bz < BH; bz++) {
|
| 276 |
const so = bz * T * T;
|
|
@@ -286,6 +292,10 @@
|
|
| 286 |
const vq = V.quantizeHeadCols(v, B, T, heads, hd);
|
| 287 |
const ctxOut = ctx.att ? await ctx.att.ctx(aq.q, vq.q, aq.s, vq.s, dAtt)
|
| 288 |
: V.attCtxJS(aq.q, vq.q, aq.s, vq.s, dAtt, ctx.L);
|
|
|
|
|
|
|
|
|
|
|
|
|
| 289 |
cb.aAll = aAll; // backward slices heads from q/k/v/aAll
|
| 290 |
cb.ctxOut = ctxOut;
|
| 291 |
const attnOut = await vmm(ctxOut, bl.Wo, BT, C, C, ctx);
|
|
@@ -360,7 +370,16 @@
|
|
| 360 |
// tied unembed: logits = lnf @ embᵀ, so the unembedding gradient flows
|
| 361 |
// straight into emb — dlogitsᵀ @ lnf is V×C, emb's own shape
|
| 362 |
let dlnfIn;
|
| 363 |
-
if (m.ctx.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 364 |
[g[gi.emb], dlnfIn] = await Promise.all([
|
| 365 |
m.ctx.fgemm(cache.dlogits, cache.lnf.y, { m: vocab, k: BT, n: C, transA: true }),
|
| 366 |
m.ctx.fgemm(cache.dlogits, m.emb, { m: BT, k: vocab, n: C }), // split-K shape
|
|
|
|
| 182 |
cfg: { ...cfg, layers, heads, hidden, vocab: vocabSize() },
|
| 183 |
ctx: { L, bgemm: (engine && engine.bgemm) || null,
|
| 184 |
att: (engine && engine.att) || null, fgemm: (engine && engine.fgemm) || null,
|
| 185 |
+
fgemm2: (engine && engine.fgemm2) || null,
|
| 186 |
mlp: (engine && engine.mlp) || null,
|
| 187 |
audit: audit || null, unitBackward: !!cfg.unitBackward },
|
| 188 |
emb: add("emb", mk(vocabSize() * c, 0.08)),
|
|
|
|
| 272 |
const qq = V.quantizeRows(q, BT * heads, hd), kq = V.quantizeRows(k, BT * heads, hd);
|
| 273 |
const sAll = ctx.att ? await ctx.att.scores(qq.q, kq.q, qq.s, kq.s, dAtt)
|
| 274 |
: V.attScoresJS(qq.q, kq.q, qq.s, kq.s, dAtt, ctx.L);
|
| 275 |
+
// live-shape audit: the init gate only ever saw four test shapes
|
| 276 |
+
if (ctx.att && ctx.audit && ctx.audit.due()) {
|
| 277 |
+
const bad = V.auditAttScores(qq.q, kq.q, qq.s, kq.s, dAtt, sAll, ctx.L, ctx.audit.cells);
|
| 278 |
+
if (bad) ctx.audit.fail(bad);
|
| 279 |
+
}
|
| 280 |
const aAll = new Float32Array(BH * T * T); // causal softmax
|
| 281 |
for (let bz = 0; bz < BH; bz++) {
|
| 282 |
const so = bz * T * T;
|
|
|
|
| 292 |
const vq = V.quantizeHeadCols(v, B, T, heads, hd);
|
| 293 |
const ctxOut = ctx.att ? await ctx.att.ctx(aq.q, vq.q, aq.s, vq.s, dAtt)
|
| 294 |
: V.attCtxJS(aq.q, vq.q, aq.s, vq.s, dAtt, ctx.L);
|
| 295 |
+
if (ctx.att && ctx.audit && ctx.audit.due()) {
|
| 296 |
+
const bad = V.auditAttCtx(aq.q, vq.q, aq.s, vq.s, dAtt, ctxOut, ctx.L, ctx.audit.cells);
|
| 297 |
+
if (bad) ctx.audit.fail(bad);
|
| 298 |
+
}
|
| 299 |
cb.aAll = aAll; // backward slices heads from q/k/v/aAll
|
| 300 |
cb.ctxOut = ctxOut;
|
| 301 |
const attnOut = await vmm(ctxOut, bl.Wo, BT, C, C, ctx);
|
|
|
|
| 370 |
// tied unembed: logits = lnf @ embᵀ, so the unembedding gradient flows
|
| 371 |
// straight into emb — dlogitsᵀ @ lnf is V×C, emb's own shape
|
| 372 |
let dlnfIn;
|
| 373 |
+
if (m.ctx.fgemm2 && !units) {
|
| 374 |
+
// Both GEMMs consume dlogits (BT x vocab, ~17 MB at the 16512 vocab).
|
| 375 |
+
// fgemm2 uploads it ONCE and runs both on one submit — profiling had
|
| 376 |
+
// this pair at 55% of the step, over half of it re-uploading the same
|
| 377 |
+
// operand. Bit-identical to the two separate calls (gated at init).
|
| 378 |
+
[g[gi.emb], dlnfIn] = await m.ctx.fgemm2(
|
| 379 |
+
cache.dlogits,
|
| 380 |
+
cache.lnf.y, { m: vocab, k: BT, n: C, transA: true },
|
| 381 |
+
m.emb, { m: BT, k: vocab, n: C }); // split-K shape
|
| 382 |
+
} else if (m.ctx.fgemm && !units) {
|
| 383 |
[g[gi.emb], dlnfIn] = await Promise.all([
|
| 384 |
m.ctx.fgemm(cache.dlogits, cache.lnf.y, { m: vocab, k: BT, n: C, transA: true }),
|
| 385 |
m.ctx.fgemm(cache.dlogits, m.emb, { m: BT, k: vocab, n: C }), // split-K shape
|