返回 build

build-pack-lang.mjs

build/build-pack-lang.mjs · 2.1 KB · 55 行
build/build-pack-lang.mjs 2.1 KB · 55 行 GitHub
// Build per-language game data packs (GWD-format) from vocab + extracted vectors.// Filters to words that actually have Numberbatch vectors, quantizes int8 per-dim,// writes /d/gw-dl/lang/pack-<lang>.json  {lang, N, words, level, vec, min, max, answers}import fs from "node:fs";const LANG = "D:/gw-dl/lang";const D = 300;const LANGS = ["ja", "ko", "fr", "de", "es"];for (const lang of LANGS) {  const vocab = JSON.parse(fs.readFileSync(`${LANG}/vocab-${lang}.json`, "utf8"));  const raw = fs.readFileSync(`${LANG}/vec-${lang}.f32`);  const all = new Float32Array(raw.buffer, raw.byteOffset, raw.length / 4);  if (all.length !== vocab.length * D) throw new Error(`${lang}: vec count mismatch`);  const keep = [];  for (let i = 0; i < vocab.length; i++) {    const off = i * D;    let nz = false;    for (let d = 0; d < D; d++) if (all[off + d] !== 0) { nz = true; break; }    if (nz) keep.push(i);  }  const N = keep.length;  const words = keep.map(i => vocab[i].w);  const level = keep.map(i => vocab[i].lv).join("");  const f32 = new Float32Array(N * D);  for (let k = 0; k < N; k++) f32.set(all.subarray(keep[k] * D, keep[k] * D + D), k * D);  const min = new Float64Array(D).fill(Infinity);  const max = new Float64Array(D).fill(-Infinity);  for (let i = 0; i < N; i++) for (let d = 0; d < D; d++) {    const v = f32[i * D + d];    if (v < min[d]) min[d] = v;    if (v > max[d]) max[d] = v;  }  const bytes = new Uint8Array(N * D);  for (let i = 0; i < N; i++) for (let d = 0; d < D; d++) {    const span = max[d] - min[d] || 1;    bytes[i * D + d] = Math.round((f32[i * D + d] - min[d]) / span * 255);  }  const answers = level.split("").filter(c => c !== "9").length;  const pack = {    lang, N, D,    words: words.join("|"),    level,    vec: Buffer.from(bytes).toString("base64"),    min: Array.from(min, v => +v.toFixed(8)),    max: Array.from(max, v => +v.toFixed(8)),    answers,  };  fs.writeFileSync(`${LANG}/pack-${lang}.json`, JSON.stringify(pack));  console.log(`${lang}: vocab ${N} (answers ${answers}, guess-only ${N - answers}) | pack ${(fs.statSync(`${LANG}/pack-${lang}.json`).size / 1048576).toFixed(2)} MB`);}