Quazim0t0 commited on
Commit
4ee151b
·
verified ·
1 Parent(s): 114d5d4

Upload web/public/webgpu.js with huggingface_hub

Browse files
Files changed (1) hide show
  1. web/public/webgpu.js +29 -2
web/public/webgpu.js CHANGED
@@ -491,8 +491,35 @@
491
  let mlpDp4 = (xq, w1q, w2q, xs, w1s, w2s, d) => gpuMlpChain(device, dp4MlpEnv, xq, w1q, w2q, xs, w1s, w2s, d);
492
  const mlpDp4Bad = await gateMlp(mlpDp4);
493
  if (mlpDp4Bad) { console.warn("B2B MLP chain (DP4A) failed verification — using the LUT chain:", mlpDp4Bad); mlpDp4 = mlpLut; }
494
- return { backend: "webgpu", label: `${gpuName} (DP4A int8 dot · exact-gated vs units)`,
495
- bgemm: bg, att, fgemm, mlp: mlpDp4 };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
496
  } catch (e) { console.warn("WebGPU init failed, CPU fallback:", e); return cpu; }
497
  }
498
 
 
491
  let mlpDp4 = (xq, w1q, w2q, xs, w1s, w2s, d) => gpuMlpChain(device, dp4MlpEnv, xq, w1q, w2q, xs, w1s, w2s, d);
492
  const mlpDp4Bad = await gateMlp(mlpDp4);
493
  if (mlpDp4Bad) { console.warn("B2B MLP chain (DP4A) failed verification — using the LUT chain:", mlpDp4Bad); mlpDp4 = mlpLut; }
494
+
495
+ // Both backends are exact-gated bit-identical, so WHICH one runs is a
496
+ // free choice. On our NVIDIA part they TIE on the shipped float path
497
+ // (packing overhead cancels the dot-throughput win at these sizes) and
498
+ // DP4A is ~12% faster in int8-backward mode — but the ordering is
499
+ // device-dependent in principle (a driver with slow dot4I8Packed or a
500
+ // fast cache path for the LUT flips it). The race below costs ~40ms at
501
+ // init and self-calibrates per device instead of trusting one machine's
502
+ // benchmark. First run of a fresh build is warm-up-skewed; the race
503
+ // warms both before timing.
504
+ const dp4 = { backend: "webgpu", label: `${gpuName} (DP4A int8 dot · exact-gated vs units)`,
505
+ bgemm: bg, att, fgemm, mlp: mlpDp4 };
506
+ try {
507
+ const d0 = { m: 256, k: 32, n: 32, batch: 3, relu: false };
508
+ const rnd8 = (len) => { const a = new Int8Array(len); for (let i = 0; i < len; i++) a[i] = (Math.random() * 256 - 128) | 0; return a; };
509
+ const Xq = rnd8(d0.batch * d0.m * d0.k), Wq = rnd8(d0.batch * d0.k * d0.n);
510
+ const rs = Float32Array.from({ length: d0.batch * d0.m }, () => Math.random() + 0.5);
511
+ const cs = Float32Array.from({ length: d0.batch * d0.n }, () => Math.random() + 0.5);
512
+ const time = async (fn) => {
513
+ await fn(Xq, Wq, rs, cs, d0); await fn(Xq, Wq, rs, cs, d0); // warm
514
+ const t0 = performance.now();
515
+ for (let r = 0; r < 6; r++) await fn(Xq, Wq, rs, cs, d0); // serialized, like training
516
+ return performance.now() - t0;
517
+ };
518
+ const tLut = await time(bgLut), tDp4 = await time(bg);
519
+ const winner = tDp4 <= tLut ? dp4 : viaLUT;
520
+ winner.label += ` · won init race ${Math.min(tLut, tDp4).toFixed(0)}ms vs ${Math.max(tLut, tDp4).toFixed(0)}ms`;
521
+ return winner;
522
+ } catch (e) { return dp4; }
523
  } catch (e) { console.warn("WebGPU init failed, CPU fallback:", e); return cpu; }
524
  }
525