Humuhumu33 commited on
Commit
813e8d8
·
verified ·
1 Parent(s): dfdc138

Upload qvac-gpu.js with huggingface_hub

Browse files
Files changed (1) hide show
  1. qvac-gpu.js +20 -5
qvac-gpu.js CHANGED
@@ -1065,6 +1065,12 @@ export async function createQvacGPU(manifest, fetchTensor, cap = 64, eos = 2, st
1065
  };
1066
  if (!frameGran) await upW("lm_head"); // resident in resident/layer modes; TILED (played) in frame mode
1067
  let RQ = null, RS = null, packLayout = null, packStride = 0, packQbytes = 0;
 
 
 
 
 
 
1068
  let opfsStore = null;
1069
  const frameMan = {}; // name → {off, qlen, slen, N, K} (frame layout)
1070
  if (frameGran) {
@@ -1104,20 +1110,27 @@ export async function createQvacGPU(manifest, fetchTensor, cap = 64, eos = 2, st
1104
  // The packed bytes live in JS ("layer") or on DISK in OPFS ("opfs" — the
1105
  // RAM-wall break); EITHER way the per-layer body is the SAME proven layerBody().
1106
  const al = (n) => Math.ceil(n / 256) * 256;
1107
- const qbl = (t) => Math.ceil(qlenOf(t) / 4) * 4; // padded q length from manifest, no fetch
 
 
 
1108
  packLayout = {}; let qo = 0, so = 0;
1109
- for (const role of ROLES) { const t = tmap[`l0.${role}`]; qo = al(qo); so = al(so); packLayout[role] = { qoff: qo, qsize: qbl(t), soff: so, ssize: slenOf(t), N: t.N, K: t.K }; qo += qbl(t); so += slenOf(t); }
1110
  const packQ = al(qo), packS = al(so);
1111
  RQ = dev.createBuffer({ size: packQ, usage: U.STORAGE | U.COPY_DST });
1112
  RS = dev.createBuffer({ size: Math.max(16, packS), usage: U.STORAGE | U.COPY_DST });
1113
  streamBuf = packQ + Math.max(16, packS);
 
 
1114
  for (const role of ROLES) {
1115
  const L = packLayout[role];
1116
- R[role] = { qbuf: { buffer: RQ, offset: L.qoff, size: L.qsize }, sbuf: { buffer: RS, offset: L.soff, size: L.ssize }, uni: ubuf(new Uint32Array([L.K, L.N, L.K / 32, 0])), N: L.N };
 
 
1117
  }
1118
- const packLayer = async (l) => { // build one layer's packed (q,s) from the GGUF
1119
  const q = new Uint8Array(packQ), s = new Uint8Array(packS);
1120
- for (const role of ROLES) { const p = await parts(`l${l}.${role}`); q.set(p.q, packLayout[role].qoff); s.set(new Uint8Array(p.s.buffer, p.s.byteOffset, p.s.byteLength), packLayout[role].soff); }
1121
  return { q, s };
1122
  };
1123
  if (opfs) { // DISK-backed: page each layer's packed blob in per token
@@ -1651,6 +1664,8 @@ export async function createQvacGPU(manifest, fetchTensor, cap = 64, eos = 2, st
1651
  dev.queue.writeBuffer(RQ, 0, Wb[l].q); // one fat DMA for the whole layer's matrices
1652
  dev.queue.writeBuffer(RS, 0, Wb[l].s); // + one for all its scales
1653
  }
 
 
1654
  const enc = dev.createCommandEncoder();
1655
  cur = layerBody(enc, l, cur, (role) => R[role]);
1656
  dev.queue.submit([enc.finish()]);
 
1065
  };
1066
  if (!frameGran) await upW("lm_head"); // resident in resident/layer modes; TILED (played) in frame mode
1067
  let RQ = null, RS = null, packLayout = null, packStride = 0, packQbytes = 0;
1068
+ // DRAFT (t2 layer-streaming — needs WebGPU verification): BitNet/Falcon t2 has a SCALAR scale per matrix
1069
+ // (baked into the matmul uniform via fbits), not a per-block scale buffer. So a t2 streamed layer packs
1070
+ // q ONLY (no scale blob), and each layer's per-role scalar is written into the reusable R[role].uni before
1071
+ // that layer's matmul. t2scales[l][role] = fbits(scale) is precomputed from the manifest (no fetch).
1072
+ const t2stream = !!stream && !moe && !frameGran && ROLES.every((r) => (tmap[`l0.${r}`] || {}).fmt === "t2");
1073
+ let t2scales = null;
1074
  let opfsStore = null;
1075
  const frameMan = {}; // name → {off, qlen, slen, N, K} (frame layout)
1076
  if (frameGran) {
 
1110
  // The packed bytes live in JS ("layer") or on DISK in OPFS ("opfs" — the
1111
  // RAM-wall break); EITHER way the per-layer body is the SAME proven layerBody().
1112
  const al = (n) => Math.ceil(n / 256) * 256;
1113
+ // t2 (BitNet/Falcon): q is codes only (N·K/4 B, 4 trits/byte) + a SCALAR scale (→ uniform); no scale blob.
1114
+ // Every other stream fmt (q3f/q4/e8/t2r): q (padded) + a per-block scale blob at soff. Same packLayer shape.
1115
+ const qbl = (t) => t2stream ? Math.ceil((t.N * t.K / 4) / 4) * 4 : Math.ceil(qlenOf(t) / 4) * 4;
1116
+ const sbl = (t) => t2stream ? 0 : slenOf(t);
1117
  packLayout = {}; let qo = 0, so = 0;
1118
+ for (const role of ROLES) { const t = tmap[`l0.${role}`]; qo = al(qo); so = al(so); packLayout[role] = { qoff: qo, qsize: qbl(t), soff: so, ssize: sbl(t), N: t.N, K: t.K }; qo += qbl(t); so += sbl(t); }
1119
  const packQ = al(qo), packS = al(so);
1120
  RQ = dev.createBuffer({ size: packQ, usage: U.STORAGE | U.COPY_DST });
1121
  RS = dev.createBuffer({ size: Math.max(16, packS), usage: U.STORAGE | U.COPY_DST });
1122
  streamBuf = packQ + Math.max(16, packS);
1123
+ // t2: per-layer-per-role scalar (fbits), refreshed into R[role].uni each layer in the forward. Manifest-only.
1124
+ if (t2stream) { t2scales = []; for (let l = 0; l < n_layers; l++) { const row = {}; for (const role of ROLES) row[role] = fbits((tmap[`l${l}.${role}`] || {}).s ?? 1); t2scales.push(row); } }
1125
  for (const role of ROLES) {
1126
  const L = packLayout[role];
1127
+ R[role] = t2stream
1128
+ ? { qbuf: { buffer: RQ, offset: L.qoff, size: L.qsize }, uni: ubuf(new Uint32Array([L.K, L.N, L.K / 16, 0])), N: L.N, K: L.K, t2: true } // scale.w set per layer
1129
+ : { qbuf: { buffer: RQ, offset: L.qoff, size: L.qsize }, sbuf: { buffer: RS, offset: L.soff, size: L.ssize }, uni: ubuf(new Uint32Array([L.K, L.N, L.K / 32, 0])), N: L.N };
1130
  }
1131
+ const packLayer = async (l) => { // build one layer's packed (q[,s]) from the κ-object
1132
  const q = new Uint8Array(packQ), s = new Uint8Array(packS);
1133
+ for (const role of ROLES) { const p = await parts(`l${l}.${role}`); q.set(p.q, packLayout[role].qoff); if (!t2stream) s.set(new Uint8Array(p.s.buffer, p.s.byteOffset, p.s.byteLength), packLayout[role].soff); }
1134
  return { q, s };
1135
  };
1136
  if (opfs) { // DISK-backed: page each layer's packed blob in per token
 
1664
  dev.queue.writeBuffer(RQ, 0, Wb[l].q); // one fat DMA for the whole layer's matrices
1665
  dev.queue.writeBuffer(RS, 0, Wb[l].s); // + one for all its scales
1666
  }
1667
+ // t2: this layer's per-role scalar scales into the reused uniforms (matmul reads scale from uni.w).
1668
+ if (t2stream) for (const role of ROLES) { const L = packLayout[role]; dev.queue.writeBuffer(R[role].uni, 0, new Uint32Array([L.K, L.N, L.K / 16, t2scales[l][role]])); }
1669
  const enc = dev.createCommandEncoder();
1670
  cur = layerBody(enc, l, cur, (role) => R[role]);
1671
  dev.queue.submit([enc.finish()]);