import React, { useState, useRef, useEffect } from 'react'; import { ParakeetModel, getParakeetModel } from 'parakeet.js'; import './App.css'; export default function App() { const repoId = 'istupakov/parakeet-tdt-0.6b-v2-onnx'; const [backend, setBackend] = useState('webgpu-hybrid'); const [encoderQuant, setEncoderQuant] = useState('fp32'); const [decoderQuant, setDecoderQuant] = useState('int8'); const [preprocessor, setPreprocessor] = useState('nemo128'); const [status, setStatus] = useState('Idle'); const [progress, setProgress] = useState(''); const [progressText, setProgressText] = useState(''); const [progressPct, setProgressPct] = useState(null); const [text, setText] = useState(''); const [latestMetrics, setLatestMetrics] = useState(null); const [transcriptions, setTranscriptions] = useState([]); const [isTranscribing, setIsTranscribing] = useState(false); const [verboseLog, setVerboseLog] = useState(false); const [frameStride, setFrameStride] = useState(1); const [dumpDetail, setDumpDetail] = useState(false); const maxCores = navigator.hardwareConcurrency || 8; const [cpuThreads, setCpuThreads] = useState(Math.max(1, maxCores - 2)); const modelRef = useRef(null); const fileInputRef = useRef(null); // Auto-adjust quant presets when backend changes useEffect(() => { if (backend.startsWith('webgpu')) { setEncoderQuant('fp32'); setDecoderQuant('int8'); } else { setEncoderQuant('int8'); setDecoderQuant('int8'); } }, [backend]); async function loadModel() { setStatus('Loading model…'); setProgress(''); setProgressText(''); setProgressPct(0); console.time('LoadModel'); try { const progressCallback = (p) => setProgress(`${p.file}: ${Math.round(p.loaded/p.total*100)}%`); // 1. Download all model files from HuggingFace Hub const modelUrls = await getParakeetModel(repoId, { encoderQuant, decoderQuant, preprocessor, progress: progressCallback }); // Show compiling sessions stage setStatus('Creating sessions…'); setProgressText('Compiling model (this may take ~10 s)…'); setProgressPct(null); // 2. Create the model instance with all file URLs modelRef.current = await ParakeetModel.fromUrls({ ...modelUrls.urls, filenames: modelUrls.filenames, // Pass the filenames object backend, }); // 3. Warm-up and verify setStatus('Warming up & verifying…'); setProgressText('Model ready! Upload an audio file to transcribe.'); setProgressPct(null); console.timeEnd('LoadModel'); setStatus('Model ready ✔'); setProgressText(''); } catch (e) { console.error(e); setStatus(`Failed: ${e.message}`); setProgress(''); } } async function transcribeFile(e) { if (!modelRef.current) return alert('Load model first'); const file = e.target.files?.[0]; if (!file) return; setIsTranscribing(true); setStatus(`Transcribing "${file.name}"…`); try { const buf = await file.arrayBuffer(); const audioCtx = new AudioContext({ sampleRate: 16000 }); const decoded = await audioCtx.decodeAudioData(buf); const pcm = decoded.getChannelData(0); console.time(`Transcribe-${file.name}`); const res = await modelRef.current.transcribe(pcm, 16_000, { returnTimestamps: true, returnConfidences: true, frameStride }); console.timeEnd(`Transcribe-${file.name}`); if (dumpDetail) { console.log('[Parakeet] Detailed transcription output', res); } setLatestMetrics(res.metrics); // Add to transcriptions list const newTranscription = { id: Date.now(), filename: file.name, text: res.utterance_text, timestamp: new Date().toLocaleTimeString(), duration: pcm.length / 16000, // duration in seconds wordCount: res.words?.length || 0, confidence: res.confidence_scores?.token_avg ?? res.confidence_scores?.word_avg ?? null, metrics: res.metrics }; setTranscriptions(prev => [newTranscription, ...prev]); setText(res.utterance_text); // Show latest transcription setStatus('Model ready ✔'); // Ready for next file } catch (error) { console.error('Transcription failed:', error); setStatus('Transcription failed'); alert(`Failed to transcribe "${file.name}": ${error.message}`); } finally { setIsTranscribing(false); // Clear the file input so the same file can be selected again if (fileInputRef.current) { fileInputRef.current.value = ''; } } } function clearTranscriptions() { setTranscriptions([]); setText(''); } return (

🦜 Parakeet.js - HF Spaces Demo

NVIDIA Parakeet speech recognition for the browser using WebGPU/WASM

Model: {repoId}

{' '} {' '} {' '} {' '} {' '} {' '} {(backend === 'wasm') && ( )}
{typeof SharedArrayBuffer === 'undefined' && backend === 'wasm' && (
⚠️ Performance Note: SharedArrayBuffer is not available. WASM will run single-threaded. For better performance, use WebGPU.
)}
{transcriptions.length > 0 && ( )}

Status: {status}

{progressPct!==null && (

{progressText}

)} {/* Latest transcription */}

Latest Transcription: