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,41 @@
|
||||
import { pipeline, env } from '@huggingface/transformers';
|
||||
import { createRequire } from 'module';
|
||||
import os from 'os'; import path from 'path'; import fs from 'fs';
|
||||
const require = createRequire(import.meta.url);
|
||||
env.allowLocalModels=false;
|
||||
env.cacheDir=path.join(os.homedir(),'Library/Application Support/Church Translate Models');
|
||||
const pipe=await pipeline('translation','Xenova/nllb-200-distilled-600M',{dtype:'fp32'});
|
||||
|
||||
/* The names a preacher actually says, frequency-ranked from the owner's own
|
||||
Strong's export, plus the Gospel/epistle authors that are rare INSIDE
|
||||
scripture but constant as book references. */
|
||||
const ranked=require('/private/tmp/claude-502/-Users-Studio-Documents-BandLineupDisplay/cee248f6-d861-4845-bd13-03867cf46596/scratchpad/proper-nouns.json')
|
||||
.map(r=>r.english).filter(n=>/^[A-Z][a-z]+$/.test(n));
|
||||
const NAMES=[...new Set(['Matthew','Mark','Luke','John','Paul','Peter','James','Jude','Timothy','Titus',
|
||||
'Jesus','Moses','David','Abraham','Isaac','Jacob','Joseph','Mary','Elijah','Isaiah','Jeremiah',
|
||||
'Daniel','Solomon','Samuel','Saul','Noah','Adam','Eve','Joshua','Thomas','Philip','Andrew',
|
||||
'Stephen','Barnabas','Silas','Apollos','Lazarus','Nicodemus','Pilate','Herod','Jerusalem',
|
||||
'Bethlehem','Nazareth','Galilee','Egypt','Babylon','Corinth','Ephesus','Rome','Zion',
|
||||
...ranked.slice(0,20)])].slice(0,60);
|
||||
|
||||
const LANGS=['por_Latn','fra_Latn','zho_Hans','zho_Hant','kor_Hang','vie_Latn','hat_Latn','arb_Arab','hin_Deva'];
|
||||
const LATIN=/[A-Za-z]/;
|
||||
const NONLATIN=new Set(['zho_Hans','zho_Hant','kor_Hang','arb_Arab','hin_Deva']);
|
||||
|
||||
const out={};
|
||||
for (const lang of LANGS) {
|
||||
out[lang]={};
|
||||
for (const n of NAMES) {
|
||||
const o=await pipe('We read about '+n+' in the Bible.',{src_lang:'eng_Latn',tgt_lang:lang});
|
||||
out[lang][n]=(Array.isArray(o)?o[0]:o).translation_text.trim();
|
||||
}
|
||||
/* For a non-Latin script, surviving Latin letters mean the name was never
|
||||
translated at all — an unambiguous, mechanically detectable failure. */
|
||||
const survived=NONLATIN.has(lang)
|
||||
? NAMES.filter(n=>LATIN.test(out[lang][n]))
|
||||
: NAMES.filter(n=>new RegExp('\\b'+n+'\\b').test(out[lang][n]));
|
||||
console.log(lang+' '+String(survived.length).padStart(2)+'/'+NAMES.length+' names left in ENGLISH: '+survived.slice(0,18).join(', ')+(survived.length>18?' …':''));
|
||||
out[lang]._survived=survived;
|
||||
}
|
||||
fs.writeFileSync('/tmp/name-probe.json',JSON.stringify(out,null,1));
|
||||
console.log('\nsaved /tmp/name-probe.json');
|
||||
Reference in New Issue
Block a user