// CPU latency benchmark: model-only time per form (extraction excluded), onnxruntime-node via transformers.js import fs from "fs"; import path from "path"; import { createRequire } from "module"; const require = createRequire(import.meta.url); const tf = require("@huggingface/transformers"); const { JSDOM, VirtualConsole } = require("jsdom"); const { zapExtract } = require("./zap-extract.js"); const { ZapModel } = require("./zap-infer.js"); const [modelDir, dir, dtype] = process.argv.slice(2); tf.env.allowRemoteModels = false; tf.env.localModelPath = path.dirname(path.resolve(modelDir)) + "/"; const zap = await ZapModel.load(tf, path.basename(modelDir), { dtype: dtype || "fp32" }); const pages = JSON.parse(fs.readFileSync(path.join(dir, "py.json"), "utf8")).slice(0, 200); const vc = new VirtualConsole(); const forms = []; let tx = 0; for (const p of pages) { const d = new JSDOM(fs.readFileSync(path.join(dir, p.file), "utf8"), { url: p.url, virtualConsole: vc }); const t = performance.now(); forms.push(...zapExtract(d.window.document, p.url)); tx += performance.now() - t; } await zap.classify(forms.slice(0, 20)); // warmup const t0 = performance.now(); const res = await zap.classify(forms); const dt = performance.now() - t0; const nf = forms.reduce((a, f) => a + f.fields.length, 0); console.log(JSON.stringify({ dtype: dtype || "fp32", forms: forms.length, fields: nf, ms_per_form: +(dt / forms.length).toFixed(2), extract_ms_per_form: +(tx / forms.length).toFixed(2) }));