Church Translate, as it runs at the campuses
Live sermon translation into 100+ languages, running entirely on one Mac per campus: audio in, voice detection, Whisper on the GPU, NLLB-200 in its own process, and a built-in web server the congregation reads from on their phones. No audio leaves the building. This is the source only. What used to sit beside it — 14 GB of speech and translation models, 8 GB of voice bundles, 6 GB of natural voices, the Electron caches, and the app data holding the operator PIN and every service transcript — is machine state and downloaded assets, and stays in the NAS backup where it belongs. The vendored node, cloudflared and Windows ffmpeg binaries are out too (533 MB, re-fetched for packaging); the browser-side runtime beside them is kept, so a checkout still serves the congregation page. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
/* Everything below is already on disk. Whatever this prints is what the app
|
||||
calls "Downloading". */
|
||||
import { pipeline, env } from '@huggingface/transformers';
|
||||
import os from 'os'; import path from 'path';
|
||||
env.allowLocalModels = false;
|
||||
env.cacheDir = path.join(os.homedir(), 'Library/Application Support/Church Translate Models');
|
||||
|
||||
const seen = [];
|
||||
const t0 = Date.now();
|
||||
await pipeline('translation', 'Xenova/nllb-200-distilled-600M', {
|
||||
dtype: 'fp32',
|
||||
progress_callback: (p) => seen.push({ ms: Date.now() - t0, ...p })
|
||||
});
|
||||
|
||||
const byStatus = {};
|
||||
for (const e of seen) byStatus[e.status] = (byStatus[e.status] || 0) + 1;
|
||||
console.log('event counts by status:', byStatus);
|
||||
console.log('total events:', seen.length, 'over', ((Date.now()-t0)/1000).toFixed(1) + 's\n');
|
||||
|
||||
console.log('per file — did any bytes actually move?');
|
||||
const files = {};
|
||||
for (const e of seen) {
|
||||
if (!e.file) continue;
|
||||
const f = files[e.file] || (files[e.file] = { statuses: new Set(), maxTotal: 0, progressEvents: 0 });
|
||||
f.statuses.add(e.status);
|
||||
if (e.total) f.maxTotal = Math.max(f.maxTotal, e.total);
|
||||
if (e.status === 'progress') f.progressEvents++;
|
||||
}
|
||||
for (const [name, f] of Object.entries(files)) {
|
||||
console.log(' ' + name.padEnd(38) +
|
||||
(f.maxTotal ? (f.maxTotal / 1048576).toFixed(1) + ' MB' : ' — ').padStart(10) +
|
||||
' progress-events=' + String(f.progressEvents).padEnd(5) +
|
||||
' [' + Array.from(f.statuses).join(', ') + ']');
|
||||
}
|
||||
Reference in New Issue
Block a user