andito HF Staff Claude Sonnet 4.5 commited on
Commit
2f7b75b
·
1 Parent(s): 7a0f76d

Fix progress bar display and correct model size to 2.5GB

Browse files

- Convert parakeet.js progress format to UI-expected format
- Send initiate/progress/done messages for progress bars
- Track seen files to avoid duplicate initiate messages
- Update model size from 2.1GB to 2.5GB (encoder is 2.3GB alone)
- Progress bars now show download status correctly

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

assets/index-D32DZD7n.js ADDED
The diff for this file is too large to render. See raw diff
 
assets/index-PHZx3Gsx.js ADDED
The diff for this file is too large to render. See raw diff
 
assets/index-sJbWHcwg.js ADDED
The diff for this file is too large to render. See raw diff
 
assets/worker-CY2tAIOW.js ADDED
@@ -0,0 +1 @@
 
 
1
+ async function f(t,a={}){const{getParakeetModel:e}=await import("./hub-BlMT648A.js"),{ParakeetModel:s}=await import("./parakeet-xcg-VHSn.js"),{MODELS:r}=await import("./models-Dq2DCePq.js"),o=r[t]?.repoId||t,n=await e(o,a);return s.fromUrls({...n.urls,filenames:n.filenames,preprocessorBackend:n.preprocessorBackend,...a})}let i=null,m=!1;async function w(t="parakeet-tdt-0.6b-v3",a={}){if(m)return{status:"loading",message:"Model is already loading..."};if(i)return{status:"ready",message:"Model already loaded"};try{m=!0;const e=a.device==="webgpu"?"webgpu-hybrid":"wasm";self.postMessage({status:"loading",message:`Downloading Parakeet ${t}... (~2.1GB, this may take 1-2 minutes)`}),console.log(`[Worker] Loading model with backend: ${e}`);const s=e==="wasm"?{encoderQuant:"int8",decoderQuant:"int8",preprocessor:"nemo128"}:{encoderQuant:"fp32",decoderQuant:"int8",preprocessor:"nemo128"},r=new Set;i=await f(t,{backend:e,...s,progress:u=>{const{loaded:g,total:c,file:l}=u,p=c>0?Math.round(g/c*100):0;r.has(l)||(r.add(l),self.postMessage({status:"initiate",file:l,progress:0,total:c})),self.postMessage({status:"progress",file:l,progress:p,total:c,loaded:g}),g>=c&&self.postMessage({status:"done",file:l})}});const n=i.session?.executionProviders?.[0]||e;console.log(`[Worker] Model loaded. Requested: ${e}, Actual provider: ${n}`),self.postMessage({status:"loading",message:"Model downloaded, warming up..."});const d=new Float32Array(16e3);return await i.transcribe(d,16e3),self.postMessage({status:"ready",message:`Parakeet ${t} loaded successfully!`,device:e,modelVersion:t}),{status:"ready",device:e}}catch(e){return console.error("Failed to load model:",e),self.postMessage({status:"error",message:`Failed to load model: ${e.message}`,error:e.toString()}),{status:"error",error:e.toString()}}finally{m=!1}}async function h(t,a=null){if(!i)throw new Error("Model not loaded. Call load() first.");try{const e=performance.now(),s=await i.transcribe(t,16e3,{returnTimestamps:!0,returnConfidences:!0,temperature:1}),o=(performance.now()-e)/1e3,n=t.length/16e3,d=n/o,u=k(s.words||[]);return{text:s.utterance_text||"",sentences:u,words:s.words||[],chunks:s.words||[],metadata:{latency:o,audioDuration:n,rtf:d,language:a,confidence:s.confidence_scores,metrics:s.metrics}}}catch(e){throw console.error("Transcription error:",e),e}}function k(t){if(!t||t.length===0)return[];const a=[];let e=[],s=t[0].start_time||0;for(let r=0;r<t.length;r++){const o=t[r];e.push(o.text),(/[.!?]$/.test(o.text)||r===t.length-1)&&(a.push({text:e.join(" ").trim(),start:s,end:o.end_time||o.start_time||0}),r<t.length-1&&(e=[],s=t[r+1].start_time||o.end_time||0))}return a}self.onmessage=async t=>{const{type:a,data:e}=t.data;try{switch(a){case"load":await w(e?.modelVersion,e?.options||{});break;case"transcribe":const s=await h(e.audio,e.language);self.postMessage({status:"transcription",result:s});break;case"ping":self.postMessage({status:"pong"});break;default:self.postMessage({status:"error",message:`Unknown message type: ${a}`})}}catch(s){self.postMessage({status:"error",message:s.message,error:s.toString()})}};
assets/worker-D2CeqmVH.js ADDED
@@ -0,0 +1 @@
 
 
1
+ async function f(t,a={}){const{getParakeetModel:e}=await import("./hub-BlMT648A.js"),{ParakeetModel:s}=await import("./parakeet-xcg-VHSn.js"),{MODELS:r}=await import("./models-Dq2DCePq.js"),o=r[t]?.repoId||t,n=await e(o,a);return s.fromUrls({...n.urls,filenames:n.filenames,preprocessorBackend:n.preprocessorBackend,...a})}let i=null,m=!1;async function w(t="parakeet-tdt-0.6b-v3",a={}){if(m)return{status:"loading",message:"Model is already loading..."};if(i)return{status:"ready",message:"Model already loaded"};try{m=!0;const e=a.device==="webgpu"?"webgpu-hybrid":"wasm";self.postMessage({status:"loading",message:`Downloading Parakeet ${t}... (~2.5GB, this may take 1-2 minutes)`}),console.log(`[Worker] Loading model with backend: ${e}`);const s=e==="wasm"?{encoderQuant:"int8",decoderQuant:"int8",preprocessor:"nemo128"}:{encoderQuant:"fp32",decoderQuant:"int8",preprocessor:"nemo128"},r=new Set;i=await f(t,{backend:e,...s,progress:u=>{const{loaded:g,total:c,file:l}=u,p=c>0?Math.round(g/c*100):0;r.has(l)||(r.add(l),self.postMessage({status:"initiate",file:l,progress:0,total:c})),self.postMessage({status:"progress",file:l,progress:p,total:c,loaded:g}),g>=c&&self.postMessage({status:"done",file:l})}});const n=i.session?.executionProviders?.[0]||e;console.log(`[Worker] Model loaded. Requested: ${e}, Actual provider: ${n}`),self.postMessage({status:"loading",message:"Model downloaded, warming up..."});const d=new Float32Array(16e3);return await i.transcribe(d,16e3),self.postMessage({status:"ready",message:`Parakeet ${t} loaded successfully!`,device:e,modelVersion:t}),{status:"ready",device:e}}catch(e){return console.error("Failed to load model:",e),self.postMessage({status:"error",message:`Failed to load model: ${e.message}`,error:e.toString()}),{status:"error",error:e.toString()}}finally{m=!1}}async function h(t,a=null){if(!i)throw new Error("Model not loaded. Call load() first.");try{const e=performance.now(),s=await i.transcribe(t,16e3,{returnTimestamps:!0,returnConfidences:!0,temperature:1}),o=(performance.now()-e)/1e3,n=t.length/16e3,d=n/o,u=k(s.words||[]);return{text:s.utterance_text||"",sentences:u,words:s.words||[],chunks:s.words||[],metadata:{latency:o,audioDuration:n,rtf:d,language:a,confidence:s.confidence_scores,metrics:s.metrics}}}catch(e){throw console.error("Transcription error:",e),e}}function k(t){if(!t||t.length===0)return[];const a=[];let e=[],s=t[0].start_time||0;for(let r=0;r<t.length;r++){const o=t[r];e.push(o.text),(/[.!?]$/.test(o.text)||r===t.length-1)&&(a.push({text:e.join(" ").trim(),start:s,end:o.end_time||o.start_time||0}),r<t.length-1&&(e=[],s=t[r+1].start_time||o.end_time||0))}return a}self.onmessage=async t=>{const{type:a,data:e}=t.data;try{switch(a){case"load":await w(e?.modelVersion,e?.options||{});break;case"transcribe":const s=await h(e.audio,e.language);self.postMessage({status:"transcription",result:s});break;case"ping":self.postMessage({status:"pong"});break;default:self.postMessage({status:"error",message:`Unknown message type: ${a}`})}}catch(s){self.postMessage({status:"error",message:s.message,error:s.toString()})}};
assets/worker-y2BU5_Lc.js ADDED
@@ -0,0 +1 @@
 
 
1
+ async function u(t,r={}){const{getParakeetModel:e}=await import("./hub-BlMT648A.js"),{ParakeetModel:s}=await import("./parakeet-xcg-VHSn.js"),{MODELS:o}=await import("./models-Dq2DCePq.js"),a=o[t]?.repoId||t,n=await e(a,r);return s.fromUrls({...n.urls,filenames:n.filenames,preprocessorBackend:n.preprocessorBackend,...r})}let c=null,l=!1;async function g(t="parakeet-tdt-0.6b-v3",r={}){if(l)return{status:"loading",message:"Model is already loading..."};if(c)return{status:"ready",message:"Model already loaded"};try{l=!0;const e=r.device==="webgpu"?"webgpu-hybrid":"wasm";self.postMessage({status:"loading",message:`Downloading Parakeet ${t}... (~2.1GB, this may take 1-2 minutes)`}),console.log(`[Worker] Loading model with backend: ${e}`),c=await u(t,{backend:e,...e==="wasm"?{encoderQuant:"int8",decoderQuant:"int8",preprocessor:"nemo128"}:{encoderQuant:"fp32",decoderQuant:"int8",preprocessor:"nemo128"},progress:i=>{console.log("[Worker] Progress callback received:",i),self.postMessage(i)}});const a=c.session?.executionProviders?.[0]||e;console.log(`[Worker] Model loaded. Requested: ${e}, Actual provider: ${a}`),self.postMessage({status:"loading",message:"Model downloaded, warming up..."});const n=new Float32Array(16e3);return await c.transcribe(n,16e3),self.postMessage({status:"ready",message:`Parakeet ${t} loaded successfully!`,device:e,modelVersion:t}),{status:"ready",device:e}}catch(e){return console.error("Failed to load model:",e),self.postMessage({status:"error",message:`Failed to load model: ${e.message}`,error:e.toString()}),{status:"error",error:e.toString()}}finally{l=!1}}async function m(t,r=null){if(!c)throw new Error("Model not loaded. Call load() first.");try{const e=performance.now(),s=await c.transcribe(t,16e3,{returnTimestamps:!0,returnConfidences:!0,temperature:1}),a=(performance.now()-e)/1e3,n=t.length/16e3,i=n/a,d=p(s.words||[]);return{text:s.utterance_text||"",sentences:d,words:s.words||[],chunks:s.words||[],metadata:{latency:a,audioDuration:n,rtf:i,language:r,confidence:s.confidence_scores,metrics:s.metrics}}}catch(e){throw console.error("Transcription error:",e),e}}function p(t){if(!t||t.length===0)return[];const r=[];let e=[],s=t[0].start_time||0;for(let o=0;o<t.length;o++){const a=t[o];e.push(a.text),(/[.!?]$/.test(a.text)||o===t.length-1)&&(r.push({text:e.join(" ").trim(),start:s,end:a.end_time||a.start_time||0}),o<t.length-1&&(e=[],s=t[o+1].start_time||a.end_time||0))}return r}self.onmessage=async t=>{const{type:r,data:e}=t.data;try{switch(r){case"load":await g(e?.modelVersion,e?.options||{});break;case"transcribe":const s=await m(e.audio,e.language);self.postMessage({status:"transcription",result:s});break;case"ping":self.postMessage({status:"pong"});break;default:self.postMessage({status:"error",message:`Unknown message type: ${r}`})}}catch(s){self.postMessage({status:"error",message:s.message,error:s.toString()})}};
index.html CHANGED
@@ -6,7 +6,7 @@
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
  <meta name="description" content="Real-time speech recognition with Parakeet STT and WebGPU acceleration. Progressive transcription demo." />
8
  <title>Parakeet STT Progressive Transcription | WebGPU Demo</title>
9
- <script type="module" crossorigin src="/assets/index-B8OCqX1p.js"></script>
10
  <link rel="stylesheet" crossorigin href="/assets/index-4ud1a0so.css">
11
  </head>
12
  <body>
 
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
  <meta name="description" content="Real-time speech recognition with Parakeet STT and WebGPU acceleration. Progressive transcription demo." />
8
  <title>Parakeet STT Progressive Transcription | WebGPU Demo</title>
9
+ <script type="module" crossorigin src="/assets/index-D32DZD7n.js"></script>
10
  <link rel="stylesheet" crossorigin href="/assets/index-4ud1a0so.css">
11
  </head>
12
  <body>
source/src/App.jsx CHANGED
@@ -140,7 +140,7 @@ function App() {
140
  };
141
 
142
  const clearCache = async () => {
143
- if (!confirm('Clear cached model files (~2.1GB)? You will need to re-download the model.')) {
144
  return;
145
  }
146
 
@@ -386,7 +386,7 @@ function App() {
386
  Real-time speech recognition with smart progressive streaming • WebGPU accelerated
387
  </p>
388
  <p className="text-gray-500 text-xs mt-2">
389
- 💾 Model files (~2.1GB) are cached locally for faster loading on future visits
390
  </p>
391
  </div>
392
  </header>
@@ -441,7 +441,7 @@ function App() {
441
  onClick={loadModel}
442
  className="px-6 py-3 bg-gradient-to-r from-cyan-500 to-blue-500 hover:from-cyan-600 hover:to-blue-600 rounded-lg font-semibold transition-all duration-200 shadow-lg hover:shadow-xl"
443
  >
444
- Load Model (~2.1GB)
445
  </button>
446
  <button
447
  onClick={clearCache}
@@ -560,7 +560,7 @@ function App() {
560
  browser using WebGPU acceleration. No data is sent to servers.
561
  </p>
562
  <p className="text-xs">
563
- Model: Parakeet TDT 0.6B v3 (ONNX via parakeet.js) • 25 languages supported • ~2.1GB download (cached locally)
564
  </p>
565
  </div>
566
  </div>
 
140
  };
141
 
142
  const clearCache = async () => {
143
+ if (!confirm('Clear cached model files (~2.5GB)? You will need to re-download the model.')) {
144
  return;
145
  }
146
 
 
386
  Real-time speech recognition with smart progressive streaming • WebGPU accelerated
387
  </p>
388
  <p className="text-gray-500 text-xs mt-2">
389
+ 💾 Model files (~2.5GB) are cached locally for faster loading on future visits
390
  </p>
391
  </div>
392
  </header>
 
441
  onClick={loadModel}
442
  className="px-6 py-3 bg-gradient-to-r from-cyan-500 to-blue-500 hover:from-cyan-600 hover:to-blue-600 rounded-lg font-semibold transition-all duration-200 shadow-lg hover:shadow-xl"
443
  >
444
+ Load Model (~2.5GB)
445
  </button>
446
  <button
447
  onClick={clearCache}
 
560
  browser using WebGPU acceleration. No data is sent to servers.
561
  </p>
562
  <p className="text-xs">
563
+ Model: Parakeet TDT 0.6B v3 (ONNX via parakeet.js) • 25 languages supported • ~2.5GB download (cached locally)
564
  </p>
565
  </div>
566
  </div>
source/src/worker.js CHANGED
@@ -31,7 +31,7 @@ async function loadModel(modelVersion = 'parakeet-tdt-0.6b-v3', options = {}) {
31
 
32
  self.postMessage({
33
  status: 'loading',
34
- message: `Downloading Parakeet ${modelVersion}... (~2.1GB, this may take 1-2 minutes)`,
35
  });
36
 
37
  // Load model using parakeet.js fromHub helper
@@ -44,8 +44,40 @@ async function loadModel(modelVersion = 'parakeet-tdt-0.6b-v3', options = {}) {
44
  : { encoderQuant: 'fp32', decoderQuant: 'int8', preprocessor: 'nemo128' }; // WebGPU-hybrid: FP32 encoder + INT8 decoder
45
 
46
  // Progress callback to forward download progress
 
 
 
47
  const progressCallback = (progressData) => {
48
- self.postMessage(progressData);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  };
50
 
51
  model = await fromHub(modelVersion, {
 
31
 
32
  self.postMessage({
33
  status: 'loading',
34
+ message: `Downloading Parakeet ${modelVersion}... (~2.5GB, this may take 1-2 minutes)`,
35
  });
36
 
37
  // Load model using parakeet.js fromHub helper
 
44
  : { encoderQuant: 'fp32', decoderQuant: 'int8', preprocessor: 'nemo128' }; // WebGPU-hybrid: FP32 encoder + INT8 decoder
45
 
46
  // Progress callback to forward download progress
47
+ // parakeet.js sends: {loaded, total, file}
48
+ // Convert to format expected by UI: {status, file, progress, total}
49
+ const seenFiles = new Set();
50
  const progressCallback = (progressData) => {
51
+ const { loaded, total, file } = progressData;
52
+ const progress = total > 0 ? Math.round((loaded / total) * 100) : 0;
53
+
54
+ // Send initiate message for new files
55
+ if (!seenFiles.has(file)) {
56
+ seenFiles.add(file);
57
+ self.postMessage({
58
+ status: 'initiate',
59
+ file,
60
+ progress: 0,
61
+ total
62
+ });
63
+ }
64
+
65
+ // Send progress update
66
+ self.postMessage({
67
+ status: 'progress',
68
+ file,
69
+ progress,
70
+ total,
71
+ loaded
72
+ });
73
+
74
+ // Send done message when complete
75
+ if (loaded >= total) {
76
+ self.postMessage({
77
+ status: 'done',
78
+ file
79
+ });
80
+ }
81
  };
82
 
83
  model = await fromHub(modelVersion, {