Files
church-translate/app/_sweep-batch.mjs
T

47 lines
2.5 KiB
JavaScript
Raw Normal View History

/* Does the batched path have a cliff at N=4..6? Sweep every N through the REAL
service, interleaved A/B so machine load hits both arms equally. */
import { fork } from 'child_process';
import os from 'os'; import path from 'path';
import { fileURLToPath } from 'url';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const MODELS_DIR = path.join(os.homedir(), 'Library/Application Support/Church Translate Models');
const LANGS = ['spa_Latn','por_Latn','fra_Latn','zho_Hans','hat_Latn','hin_Deva','kor_Hang','vie_Latn','arb_Arab'];
const TEXT = 'And I want you to understand that God has a plan for your life';
const child = fork(path.join(__dirname, 'mt-service.js'), [], { stdio: ['ignore','pipe','pipe','ipc'] });
child.stderr.on('data', () => {});
let seq = 0; const pending = new Map();
child.on('message', (m) => {
if (m.type === 'ready') { pending.get('ready')(); return; }
if (m.type === 'progress' || m.type === 'note') return;
const w = pending.get(m.id); if (!w) return; pending.delete(m.id);
if (m.type === 'error') w.reject(new Error(m.message));
else w.resolve(m.type === 'multi' ? m.texts : m.text);
});
const send = (p) => new Promise((resolve, reject) => { const id = ++seq; pending.set(id, {resolve,reject}); child.send({...p, id}); });
const ready = new Promise(r => pending.set('ready', r));
child.send({ type:'load', model:'Xenova/nllb-200-distilled-600M', dtype:'fp32', cacheDir: MODELS_DIR });
await ready;
const one = (t) => send({ type:'translate', text:TEXT, src:'eng_Latn', tgt:t });
const many = (ts) => send({ type:'translateMulti', text:TEXT, src:'eng_Latn', tgts:ts });
await one('spa_Latn'); await many(['spa_Latn','fra_Latn']);
const REPS = 3;
console.log(' N | serial(med) | batched(med) | speedup | identical');
console.log('---+-------------+--------------+---------+----------');
for (let n = 1; n <= 9; n++) {
const langs = LANGS.slice(0, n);
const S = [], B = []; let same = 0, tot = 0;
for (let r = 0; r < REPS; r++) {
let t = Date.now(); const so = {}; for (const l of langs) so[l] = await one(l); S.push(Date.now()-t);
t = Date.now(); const bo = await many(langs); B.push(Date.now()-t);
for (const l of langs) { tot++; if (so[l] === bo[l]) same++; }
}
const med = (a) => a.sort((x,y)=>x-y)[Math.floor(a.length/2)];
const s = med(S), b = med(B);
console.log(String(n).padStart(2) + ' | ' + (s+'ms').padStart(11) + ' | ' + (b+'ms').padStart(12) +
' | ' + ((s/b).toFixed(2)+'x').padStart(7) + ' | ' + same + '/' + tot);
}
child.kill();