Spaces:
Running
Running
| // IQ-quant dequantization, transcribed line-for-line from ggml-quants.c | |
| // (llama.cpp b7248): dequantize_row_iq2_xxs:3077 iq2_xs:3105 iq2_s:3132 | |
| // iq3_xxs:3164 iq3_s:3196 iq1_s:3239 iq1_m:3264 iq4_nl:3314 iq4_xs:3332. | |
| // Block layouts: ggml-common.h:485-563. | |
| // | |
| // ONE source of truth, two behaviours: makeIQ(fr, f16ToF32) binds the rounding | |
| // function. The Tier-A oracle passes Math.fround (binary32-exact, witnessed | |
| // bit-for-bit vs ggml to_float in gguf-forge-iq.test.mjs); the runtime passes | |
| // identity (float64, fine for the GPU engine which re-quantizes anyway). | |
| // | |
| // Codebook grids are flattened little-endian byte runs (gguf-forge-iq-grids.mjs): | |
| // an entry `idx` of stride S occupies bytes [idx*S .. idx*S+S). iq2*/iq3* read | |
| // uint8, iq1s_grid / kvalues_iq4nl read int8. | |
| import { | |
| iq2xxs_grid, iq2xs_grid, iq2s_grid, iq3xxs_grid, iq3s_grid, iq1s_grid, | |
| ksigns_iq2xs, kmask_iq2xs, kvalues_iq4nl, | |
| } from "./gguf-forge-iq-grids.mjs"; | |
| const QK_K = 256; | |
| const IQ1S_DELTA = 0.125, IQ1M_DELTA = 0.125; | |
| const s8 = (b) => (b << 24) >> 24; // uint8 -> int8 | |
| export function makeIQ(fr, f16ToF32) { | |
| const sign1 = (signs, j) => (signs & kmask_iq2xs[j] ? -1 : 1); | |
| // dequantize_row_iq2_xxs (:3077). Block 66 B: d:f16 qs:uint16[32]. | |
| function dequantIQ2XXS(raw, elements) { | |
| const out = new Float32Array(elements); | |
| const dv = new DataView(raw.buffer, raw.byteOffset, raw.byteLength); | |
| const nb = elements / QK_K; let o = 0; | |
| for (let i = 0; i < nb; i++) { | |
| const bp = i * 66, qs = bp + 2; | |
| const d = f16ToF32(dv.getUint16(bp, true)); | |
| for (let ib32 = 0; ib32 < QK_K / 32; ++ib32) { | |
| const a0 = dv.getUint32(qs + 8 * ib32, true), a1 = dv.getUint32(qs + 8 * ib32 + 4, true); | |
| const db = fr(fr(d * fr(0.5 + (a1 >>> 28))) * 0.25); | |
| for (let l = 0; l < 4; ++l) { | |
| const idx = (a0 >>> (8 * l)) & 0xff; | |
| const signs = ksigns_iq2xs[(a1 >>> (7 * l)) & 127]; | |
| for (let j = 0; j < 8; ++j) out[o++] = sign1(signs, j) * fr(db * iq2xxs_grid[idx * 8 + j]); | |
| } | |
| } | |
| } | |
| return out; | |
| } | |
| // dequantize_row_iq2_xs (:3105). Block 74 B: d:f16 qs:uint16[32] scales:uint8[8]. | |
| function dequantIQ2XS(raw, elements) { | |
| const out = new Float32Array(elements); | |
| const dv = new DataView(raw.buffer, raw.byteOffset, raw.byteLength); | |
| const nb = elements / QK_K; let o = 0; | |
| for (let i = 0; i < nb; i++) { | |
| const bp = i * 74, qs = bp + 2, scB = bp + 66; | |
| const d = f16ToF32(dv.getUint16(bp, true)); | |
| for (let ib32 = 0; ib32 < QK_K / 32; ++ib32) { | |
| const db = [fr(fr(d * fr(0.5 + (raw[scB + ib32] & 0xf))) * 0.25), | |
| fr(fr(d * fr(0.5 + (raw[scB + ib32] >> 4))) * 0.25)]; | |
| for (let l = 0; l < 4; ++l) { | |
| const q = dv.getUint16(qs + (4 * ib32 + l) * 2, true); | |
| const idx = q & 511, signs = ksigns_iq2xs[q >> 9], dl = db[l >> 1]; | |
| for (let j = 0; j < 8; ++j) out[o++] = sign1(signs, j) * fr(dl * iq2xs_grid[idx * 8 + j]); | |
| } | |
| } | |
| } | |
| return out; | |
| } | |
| // dequantize_row_iq2_s (:3132). Block 82 B: d:f16 qs:uint8[64] qh:uint8[8] scales:uint8[8]. | |
| // signs = qs + 32 (second half of qs); idx = qs[l] | ((qh[ib32]<<(8-2l)) & 0x300). | |
| function dequantIQ2S(raw, elements) { | |
| const out = new Float32Array(elements); | |
| const dv = new DataView(raw.buffer, raw.byteOffset, raw.byteLength); | |
| const nb = elements / QK_K; let o = 0; | |
| for (let i = 0; i < nb; i++) { | |
| const bp = i * 82, qhB = bp + 66, scB = bp + 74; | |
| const d = f16ToF32(dv.getUint16(bp, true)); | |
| let qs = bp + 2, signs = bp + 2 + 32; | |
| for (let ib32 = 0; ib32 < QK_K / 32; ++ib32) { | |
| const db = [fr(fr(d * fr(0.5 + (raw[scB + ib32] & 0xf))) * 0.25), | |
| fr(fr(d * fr(0.5 + (raw[scB + ib32] >> 4))) * 0.25)]; | |
| for (let l = 0; l < 4; ++l) { | |
| const dl = db[l >> 1]; | |
| const idx = raw[qs + l] | (((raw[qhB + ib32] << (8 - 2 * l)) & 0x300)); | |
| for (let j = 0; j < 8; ++j) out[o++] = sign1(raw[signs + l], j) * fr(dl * iq2s_grid[idx * 8 + j]); | |
| } | |
| qs += 4; signs += 4; | |
| } | |
| } | |
| return out; | |
| } | |
| // dequantize_row_iq3_xxs (:3164). Block 98 B: d:f16 qs:uint8[96]. | |
| // qs[0..63]=grid idx; scales_and_signs = qs+64 (8 uint32). db scale uses *0.5. | |
| function dequantIQ3XXS(raw, elements) { | |
| const out = new Float32Array(elements); | |
| const dv = new DataView(raw.buffer, raw.byteOffset, raw.byteLength); | |
| const nb = elements / QK_K; let o = 0; | |
| for (let i = 0; i < nb; i++) { | |
| const bp = i * 98, ss = bp + 2 + 64; | |
| const d = f16ToF32(dv.getUint16(bp, true)); | |
| let qs = bp + 2; | |
| for (let ib32 = 0; ib32 < QK_K / 32; ++ib32) { | |
| const a32 = dv.getUint32(ss + 4 * ib32, true); | |
| const db = fr(fr(d * fr(0.5 + (a32 >>> 28))) * 0.5); | |
| for (let l = 0; l < 4; ++l) { | |
| const signs = ksigns_iq2xs[(a32 >>> (7 * l)) & 127]; | |
| const g1 = raw[qs + 2 * l] * 4, g2 = raw[qs + 2 * l + 1] * 4; | |
| for (let j = 0; j < 4; ++j) { | |
| out[o + j + 0] = sign1(signs, j + 0) * fr(db * iq3xxs_grid[g1 + j]); | |
| out[o + j + 4] = sign1(signs, j + 4) * fr(db * iq3xxs_grid[g2 + j]); | |
| } | |
| o += 8; | |
| } | |
| qs += 8; | |
| } | |
| } | |
| return out; | |
| } | |
| // dequantize_row_iq3_s (:3196). Block 110 B: d:f16 qs:uint8[64] qh:uint8[8] signs:uint8[32] scales:uint8[4]. | |
| function dequantIQ3S(raw, elements) { | |
| const out = new Float32Array(elements); | |
| const dv = new DataView(raw.buffer, raw.byteOffset, raw.byteLength); | |
| const nb = elements / QK_K; let o = 0; | |
| for (let i = 0; i < nb; i++) { | |
| const bp = i * 110, scB = bp + 106; | |
| const d = f16ToF32(dv.getUint16(bp, true)); | |
| let qs = bp + 2, qh = bp + 66, signs = bp + 74; | |
| for (let ib32 = 0; ib32 < QK_K / 32; ib32 += 2) { | |
| const db1 = fr(d * (1 + 2 * (raw[scB + (ib32 >> 1)] & 0xf))); | |
| const db2 = fr(d * (1 + 2 * (raw[scB + (ib32 >> 1)] >> 4))); | |
| for (let l = 0; l < 4; ++l) { | |
| const g1 = (raw[qs + 2 * l] | ((raw[qh] << (8 - 2 * l)) & 256)) * 4; | |
| const g2 = (raw[qs + 2 * l + 1] | ((raw[qh] << (7 - 2 * l)) & 256)) * 4; | |
| for (let j = 0; j < 4; ++j) { | |
| out[o + j + 0] = sign1(raw[signs + l], j + 0) * fr(db1 * iq3s_grid[g1 + j]); | |
| out[o + j + 4] = sign1(raw[signs + l], j + 4) * fr(db1 * iq3s_grid[g2 + j]); | |
| } | |
| o += 8; | |
| } | |
| qs += 8; signs += 4; | |
| for (let l = 0; l < 4; ++l) { | |
| const g1 = (raw[qs + 2 * l] | ((raw[qh + 1] << (8 - 2 * l)) & 256)) * 4; | |
| const g2 = (raw[qs + 2 * l + 1] | ((raw[qh + 1] << (7 - 2 * l)) & 256)) * 4; | |
| for (let j = 0; j < 4; ++j) { | |
| out[o + j + 0] = sign1(raw[signs + l], j + 0) * fr(db2 * iq3s_grid[g1 + j]); | |
| out[o + j + 4] = sign1(raw[signs + l], j + 4) * fr(db2 * iq3s_grid[g2 + j]); | |
| } | |
| o += 8; | |
| } | |
| qh += 2; qs += 8; signs += 4; | |
| } | |
| } | |
| return out; | |
| } | |
| // dequantize_row_iq1_s (:3239). Block 50 B: d:f16 qs:uint8[32] qh:uint16[8]. grid int8. | |
| function dequantIQ1S(raw, elements) { | |
| const out = new Float32Array(elements); | |
| const dv = new DataView(raw.buffer, raw.byteOffset, raw.byteLength); | |
| const nb = elements / QK_K; let o = 0; | |
| for (let i = 0; i < nb; i++) { | |
| const bp = i * 50, qhB = bp + 34; | |
| const d = f16ToF32(dv.getUint16(bp, true)); | |
| let qs = bp + 2; | |
| for (let ib = 0; ib < QK_K / 32; ++ib) { | |
| const qh = dv.getUint16(qhB + 2 * ib, true); | |
| const dl = fr(d * (2 * ((qh >> 12) & 7) + 1)); | |
| const delta = (qh & 0x8000) ? -IQ1S_DELTA : IQ1S_DELTA; | |
| for (let l = 0; l < 4; ++l) { | |
| const g = (raw[qs + l] | (((qh >> (3 * l)) & 7) << 8)) * 8; | |
| for (let j = 0; j < 8; ++j) out[o++] = fr(dl * fr(s8(iq1s_grid[g + j]) + delta)); | |
| } | |
| qs += 4; | |
| } | |
| } | |
| return out; | |
| } | |
| // dequantize_row_iq1_m (:3264). Block 56 B: qs:uint8[32] qh:uint8[16] scales:uint8[8]. | |
| // No d field — f16 scale is woven from the four scale uint16s. grid int8. | |
| function dequantIQ1M(raw, elements) { | |
| const out = new Float32Array(elements); | |
| const dv = new DataView(raw.buffer, raw.byteOffset, raw.byteLength); | |
| const nb = elements / QK_K; let o = 0; | |
| const delta = new Float32Array(4), idx = new Uint16Array(4); | |
| for (let i = 0; i < nb; i++) { | |
| const bp = i * 56, scB = bp + 48; | |
| const sc = [dv.getUint16(scB, true), dv.getUint16(scB + 2, true), dv.getUint16(scB + 4, true), dv.getUint16(scB + 6, true)]; | |
| const u16 = (sc[0] >> 12) | ((sc[1] >> 8) & 0x00f0) | ((sc[2] >> 4) & 0x0f00) | (sc[3] & 0xf000); | |
| const d = f16ToF32(u16); | |
| let qs = bp, qh = bp + 32; | |
| for (let ib = 0; ib < QK_K / 32; ++ib) { | |
| const dl1 = fr(d * (2 * ((sc[ib >> 1] >> (6 * (ib % 2) + 0)) & 0x7) + 1)); | |
| const dl2 = fr(d * (2 * ((sc[ib >> 1] >> (6 * (ib % 2) + 3)) & 0x7) + 1)); | |
| idx[0] = raw[qs + 0] | ((raw[qh + 0] << 8) & 0x700); | |
| idx[1] = raw[qs + 1] | ((raw[qh + 0] << 4) & 0x700); | |
| idx[2] = raw[qs + 2] | ((raw[qh + 1] << 8) & 0x700); | |
| idx[3] = raw[qs + 3] | ((raw[qh + 1] << 4) & 0x700); | |
| delta[0] = raw[qh + 0] & 0x08 ? -IQ1M_DELTA : IQ1M_DELTA; | |
| delta[1] = raw[qh + 0] & 0x80 ? -IQ1M_DELTA : IQ1M_DELTA; | |
| delta[2] = raw[qh + 1] & 0x08 ? -IQ1M_DELTA : IQ1M_DELTA; | |
| delta[3] = raw[qh + 1] & 0x80 ? -IQ1M_DELTA : IQ1M_DELTA; | |
| for (let l = 0; l < 2; ++l) { | |
| const g = idx[l] * 8; | |
| for (let j = 0; j < 8; ++j) out[o++] = fr(dl1 * fr(s8(iq1s_grid[g + j]) + delta[l])); | |
| } | |
| for (let l = 2; l < 4; ++l) { | |
| const g = idx[l] * 8; | |
| for (let j = 0; j < 8; ++j) out[o++] = fr(dl2 * fr(s8(iq1s_grid[g + j]) + delta[l])); | |
| } | |
| qs += 4; qh += 2; | |
| } | |
| } | |
| return out; | |
| } | |
| // dequantize_row_iq4_nl (:3314). Block 18 B / 32 elems: d:f16 qs:uint8[16]. kvalues int8. | |
| function dequantIQ4NL(raw, elements) { | |
| const out = new Float32Array(elements); | |
| const dv = new DataView(raw.buffer, raw.byteOffset, raw.byteLength); | |
| const nb = elements / 32; let o = 0; | |
| for (let i = 0; i < nb; i++) { | |
| const bp = i * 18, qs = bp + 2; | |
| const d = f16ToF32(dv.getUint16(bp, true)); | |
| for (let j = 0; j < 16; ++j) { | |
| out[o + j] = fr(d * s8(kvalues_iq4nl[raw[qs + j] & 0xf])); | |
| out[o + 16 + j] = fr(d * s8(kvalues_iq4nl[raw[qs + j] >> 4])); | |
| } | |
| o += 32; | |
| } | |
| return out; | |
| } | |
| // dequantize_row_iq4_xs (:3332). Block 136 B: d:f16 scales_h:uint16 scales_l:uint8[4] qs:uint8[128]. | |
| function dequantIQ4XS(raw, elements) { | |
| const out = new Float32Array(elements); | |
| const dv = new DataView(raw.buffer, raw.byteOffset, raw.byteLength); | |
| const nb = elements / QK_K; let o = 0; | |
| for (let i = 0; i < nb; i++) { | |
| const bp = i * 136, slB = bp + 4; | |
| const d = f16ToF32(dv.getUint16(bp, true)); | |
| const sh = dv.getUint16(bp + 2, true); | |
| let qs = bp + 8; | |
| for (let ib = 0; ib < QK_K / 32; ++ib) { | |
| const ls = ((raw[slB + (ib >> 1)] >> (4 * (ib % 2))) & 0xf) | (((sh >> (2 * ib)) & 3) << 4); | |
| const dl = fr(d * (ls - 32)); | |
| for (let j = 0; j < 16; ++j) { | |
| out[o + j] = fr(dl * s8(kvalues_iq4nl[raw[qs + j] & 0xf])); | |
| out[o + 16 + j] = fr(dl * s8(kvalues_iq4nl[raw[qs + j] >> 4])); | |
| } | |
| o += 32; qs += 16; | |
| } | |
| } | |
| return out; | |
| } | |
| return { dequantIQ2XXS, dequantIQ2XS, dequantIQ2S, dequantIQ3XXS, dequantIQ3S, dequantIQ1S, dequantIQ1M, dequantIQ4NL, dequantIQ4XS }; | |
| } | |