بلاگ پر واپس جائیں
19 اکتوبر، 2026Sergei Solod26 منٹ پڑھنے کا وقت

Whisper اور WebAssembly سے ویب سائٹ میں نجی آواز کو متن میں بدلنے کی سہولت کیسے شامل کریں

Whisper، Transformers.js، ONNX Runtime Web، AudioWorklet اور WebAssembly کی مدد سے مکمل طور پر براؤزر میں صوتی ٹائپنگ بنائیں۔ موبائل کی کارکردگی بہتر بنانے اور آواز کی شناخت روک دینے والی رن ٹائم، ورکر اور ٹوکنائزر کی خرابیوں کو درست کرنے کا طریقہ جانیں۔

آواز سے متنWhisperWebAssemblyAudioWorkletJavaScript

ویب سائٹ میں مائیکروفون کا بٹن شامل کرنا بظاہر آسان ہے: صارف کی آواز ریکارڈ کریں، بولے گئے الفاظ پہچانیں اور انہیں متن کے خانے میں ڈال دیں۔ لیکن ڈیسک ٹاپ اور موبائل براؤزرز میں یہ سہولت قابلِ اعتماد انداز میں چلانا کہیں زیادہ مشکل ہے، خاص طور پر جب آواز کی مکمل شناخت مقامی طور پر کرنی ہو اور مائیکروفون کی آڈیو سرور پر اپ لوڈ نہ کی جائے۔

اصل مسئلہ صرف آواز پہچاننے والا ماڈل منتخب کرنا نہیں۔ درست نفاذ کے لیے مائیکروفون کی اجازت، آڈیو کی ریکارڈنگ، دوبارہ سیمپلنگ، براؤزر ورکرز، WebAssembly، ONNX ماڈل کی ابتدا، ٹوکنائزیشن، کیشنگ اور ایپلی کیشن کے متن کے خانے سے انضمام، سبھی کو صحیح طریقے سے سنبھالنا ضروری ہے۔

اس مضمون میں OpenAI Whisper، Transformers.js، ONNX Runtime Web، AudioWorklet اور ایک مخصوص Web Worker کے ذریعے آواز کو متن میں بدلنے کی عملی، رازداری محفوظ رکھنے والی سہولت بنانے کا طریقہ بتایا گیا ہے۔ انضمام کی چند حقیقی خرابیوں پر بھی بات کی گئی ہے جن کی وجہ سے ماڈل کی فائلیں کامیابی سے ڈاؤن لوڈ ہونے کے باوجود مائیکروفون کا بٹن لوڈنگ کی حالت میں اٹکا رہ سکتا ہے۔

مقصد واضح ہے: آنے والا شخص مائیکروفون کا بٹن دبائے، فطری انداز میں بولے اور پہچانا گیا متن پہلے سے موجود ان پٹ خانے میں دیکھ سکے۔ وہ بھیجنے سے پہلے متن پڑھ یا درست کر سکے۔ خود مائیکروفون کی ریکارڈنگ کو براؤزر سے باہر بھیجنے کی ضرورت نہیں۔

مکمل طور پر کلائنٹ کی جانب آواز کی شناخت کا مطلب

ویب سائٹ میں آواز سے متن داخل کرنے کے دو بنیادی طور پر مختلف طریقے ہیں۔

پہلے طریقے میں آواز پہچاننے والی بیرونی سروس استعمال ہوتی ہے۔ براؤزر آڈیو ریکارڈ کرکے دور دراز سروس کو بھیجتا ہے اور وہاں سے پہچانا ہوا متن وصول کرتا ہے۔ اس سے نفاذ آسان ہوسکتا ہے، لیکن نیٹ ورک پر انحصار، رازداری کے خدشات، سروس فراہم کرنے والے کی دستیابی اور استعمال کے حساب سے ممکنہ اخراجات سامنے آتے ہیں۔

دوسرے طریقے میں ماڈل کا استدلال براہِ راست براؤزر کے اندر ہوتا ہے۔ ویب سائٹ آواز پہچاننے والا ماڈل اور اسے چلانے کے لیے درکار رن ٹائم ڈاؤن لوڈ کرتی ہے۔ براؤزر مائیکروفون کی آڈیو لے کر اسے عددی نمونوں میں بدلتا ہے، ماڈل مقامی طور پر چلاتا ہے اور آواز پہچاننے والے سرور کے بغیر متن تیار کرتا ہے۔

یہ مضمون مکمل طور پر دوسرے طریقے پر مرکوز ہے۔

براؤزر میں عام آواز کی شناخت اور یقینی طور پر مقامی شناخت کو ایک چیز نہ سمجھیں۔ Web Speech API سرور پر چلنے والا شناختی انجن استعمال کرسکتا ہے۔ بعض نئی صورتوں میں processLocally کا اختیار موجود ہے، مگر اس کی معاونت براؤزر اور آپریٹنگ سسٹم کے لحاظ سے مختلف ہوتی ہے۔ اگر مکمل مقامی پروسیسنگ لازمی ہو تو عمومی SpeechRecognition کو خودکار متبادل کے طور پر استعمال نہیں کرنا چاہیے۔

اس کے بجائے ایپلی کیشن پورے ماڈل کے استدلالی سلسلے کو خود کنٹرول کرتی ہے۔

Microphone
    |
    v
AudioWorklet
    |
    v
Float32 PCM audio
    |
    v
Dedicated Web Worker
    |
    v
16 kHz resampling
    |
    v
Whisper + ONNX Runtime Web
    |
    v
Tokenizer and text decoding
    |
    v
React input state

ویب سائٹ پھر بھی JavaScript، WebAssembly، ترتیب کی فائلیں اور ماڈل کے وزن فراہم کرتی ہے۔ یہ عام جامد فائلوں کے ڈاؤن لوڈ ہیں۔ فرق یہ ہے کہ شناخت کے لیے مائیکروفون کی آڈیو اپ لوڈ کرنے کے بجائے مقامی طور پر پراسیس کی جاتی ہے۔ بعد میں صارف کسی عام فارم سے حاصل شدہ متن بھیجتا ہے تو وہ ایپلی کیشن کی الگ کارروائی ہے۔

موزوں ماڈل کا انتخاب: Whisper Tiny یا Base

Whisper مختلف زبانوں میں آواز پہچاننے والے ماڈلز کا ایک خاندان ہے۔ ایک ہی ماڈل سے متعدد زبانوں کی شناخت کی صلاحیت اسے کثیر لسانی ویب سائٹس کے لیے خاص طور پر مفید بناتی ہے۔

مختصر صوتی پیغامات کے لیے دو ماڈل شناخت کے معیار اور براؤزر کے وسائل کی کھپت میں مناسب توازن دیتے ہیں: Whisper Tiny اور Whisper Base۔

ماڈلمنتخب Q8 ONNX وزن کا تخمینی حجمتجویز کردہ استعمال
Whisper Tiny41 MBموبائل اور محدود وسائل کے لیے محتاط انتخاب
Whisper Base77 MBآزمودہ، زیادہ صلاحیت والے آلات پر بہتر معیار کا انتخاب

ان حجموں سے مراد جانچے گئے ماڈل ایکسپورٹس کی منتخب اینکوڈر اور ڈیکوڈر ONNX فائلیں ہیں۔ ان میں تمام معاون فائلیں شامل نہیں، اور انہیں براؤزر کی زیادہ سے زیادہ میموری کھپت بھی نہیں سمجھنا چاہیے۔

Whisper Tiny جلد ڈاؤن لوڈ ہوتا ہے، عموماً کم کمپیوٹنگ وسائل مانگتا ہے اور ایسے موبائل ماحول کے لیے بہتر ہے جس کی صلاحیت واضح نہ ہو۔ Whisper Base عموماً بہتر شناخت فراہم کرتا ہے، خاص طور پر بعض زبانوں میں جن پر چھوٹے ماڈل زیادہ غلطیاں کرتے ہیں۔

ماڈل کا انتخاب صرف آلے کی نصب شدہ RAM دیکھ کر نہیں کرنا چاہیے۔ براؤزر کو دستیاب میموری، آلے کی خصوصیات میں درج مقدار سے خاصی کم ہوسکتی ہے۔ پہلے سے کھلے صفحے کی میموری، WebAssembly کے لیے مختص میموری، عارضی ٹینسرز اور آپریٹنگ سسٹم کی میموری پر دباؤ سب اہم ہیں۔

محتاط طریقہ یہ ہے کہ نامعلوم صلاحیت والے موبائل آلات پر Tiny سے ابتدا کی جائے، Base صرف موزوں ثابت ہونے والے آلات کے لیے رکھا جائے، اور Base کی ابتدا ناکام ہو تو Tiny استعمال کیا جائے۔

Tiny لوڈ کرنے سے پہلے ناکام Base کی مثال کو مکمل طور پر میموری سے ہٹانا ضروری ہے۔ دونوں ماڈلز میموری میں رکھنا متبادل استعمال کرنے کا مقصد ہی ختم کردیتا ہے۔

پروڈکشن میں WebAssembly مناسب طے شدہ انتخاب کیوں ہے

ONNX Runtime Web براؤزرز کے اندر نیورل نیٹ ورک چلا سکتا ہے۔ اس کام میں WebAssembly بڑے ڈیسک ٹاپ اور موبائل براؤزرز پر CPU کے ذریعے ماڈل چلانے کا عملی راستہ فراہم کرتا ہے۔

موزوں ہارڈویئر پر WebGPU معاونت یافتہ ماڈلز کی رفتار بڑھا سکتا ہے، لیکن اس کی دستیابی کا مطلب آواز کی شناخت کا پورا سلسلہ درست چلنا نہیں۔ کسی براؤزر میں navigator.gpu موجود ہونا اس بات کی ضمانت نہیں کہ ONNX Runtime اس پلیٹ فارم کی معاونت کرتا ہے، مخصوص Whisper گراف صحیح شروع ہوتا ہے، یا بار بار ماڈل چلانے پر وسائل کی مشکلات نہیں آتیں۔

اس لیے محتاط نفاذ میں پروڈکشن کے بیک اینڈ کے طور پر WASM استعمال کیا جاسکتا ہے، جبکہ WebGPU کو مطابقت، درستگی، میموری اور بار بار چلنے والے سیشنز کی جانچ کے بعد الگ سے پرکھا جائے۔

ابتدائی نفاذ میں ایک تھریڈ والا WASM استعمال کرنے سے پوری ویب سائٹ کو cross-origin isolation اور SharedArrayBuffer پر منحصر بھی نہیں بنانا پڑتا۔

env.backends.onnx.wasm.numThreads = 1;
env.backends.onnx.wasm.proxy = false;

ماڈل کا استدلال ایک مخصوص ورکر میں چلانے سے بھاری حسابی کام مرکزی JavaScript تھریڈ سے باہر رہتا ہے۔ ماڈل آڈیو پراسیس کررہا ہو تو بھی متن کا خانہ، ورچوئل کی بورڈ، اسکرولنگ اور ایپلی کیشن کا انٹرفیس جواب دیتے رہتے ہیں۔

صفحے کی ابتدائی لوڈنگ سے آواز کی شناخت کو مکمل طور پر الگ رکھیں

جو زائرین کبھی مائیکروفون استعمال ہی نہیں کرتے، ان پر اس سہولت کی وجہ سے نیٹ ورک یا میموری کا بڑا بوجھ نہیں پڑنا چاہیے۔

ابتدائی ایپلی کیشن بنڈل میں Transformers.js کو پیشگی درآمد نہ کریں۔ صفحہ کھلتے ہی ONNX Runtime شروع نہ کریں، اور غیر فعال وقت میں ماڈل کے وزن خودکار طور پر ڈاؤن لوڈ نہ کریں۔

اس کے بجائے شناخت کا پورا نظام صرف اس وقت لوڈ کریں جب صارف خود مائیکروفون کے بٹن پر کلک کرے۔

پہلی مرتبہ استعمال کا ایک موزوں سلسلہ یہ ہے:

  1. مائیکروفون بٹن پر کلک وصول کریں۔
  2. getUserMedia() کے ذریعے مائیکروفون کی اجازت مانگیں۔
  3. اجازت نہ ملے تو ماڈل ڈاؤن لوڈ کیے بغیر خرابی دکھائیں۔
  4. اجازت مل جائے تو ماڈل کی تیاری کے دوران عارضی مائیکروفون اسٹریم بند کردیں۔
  5. مخصوص ورکر کو ضرورت کے وقت شروع کریں اور منتخب مقامی ماڈل لوڈ کریں۔
  6. انتظار کریں کہ ورکر شناخت کا پورا سلسلہ تیار ہونے کی تصدیق کرے۔
  7. صارف نے کارروائی منسوخ نہ کی ہو تو ریکارڈنگ خودکار طور پر شروع کریں۔
  8. واضح انداز میں دکھائیں کہ اب آواز سنی جارہی ہے۔

اجازت کی درخواست صارف کی اپنی کارروائی سے منسلک ہونی چاہیے۔ ایپلی کیشن کو منسوخ شدہ کارروائیوں اور مختلف براؤزرز کی ریکارڈنگ پابندیوں کو بھی سنبھالنا چاہیے، نہ کہ یہ فرض کرلینا چاہیے کہ ریکارڈنگ ہمیشہ خاموشی سے دوبارہ شروع ہوسکتی ہے۔

ماڈل تیار ہونے کے دوران صوتی ان پٹ تیار کیا جا رہا ہے جیسی واضح حالت دکھانی چاہیے۔ معنی خیز تبدیلی کے بغیر محض گھومتا ہوا نشان ماڈل کے کامیابی سے ڈاؤن لوڈ ہونے کو بھی خراب مائیکروفون جیسا ظاہر کرسکتا ہے۔

ایک مرتبہ تیار ہونے کے بعد ورکر کو اگلی آواز لکھوانے کے لیے مختصر عرصے تک دستیاب رکھا جاسکتا ہے۔ تقریباً ایک منٹ غیر فعال رہنے پر بند کرنا ایک مناسب ابتدائی انتخاب ہے۔ اس کے بعد ورکر ختم کرکے میموری میں موجود ماڈل آزاد کردیں۔ براؤزر میں کیش شدہ ماڈل فائلیں آئندہ دوروں کے لیے باقی رہ سکتی ہیں۔

AudioWorklet سے خام آڈیو حاصل کریں

Whisper کو عددی آڈیو نمونے درکار ہوتے ہیں۔ MediaRecorder آڈیو فائلیں ریکارڈ کرنے میں بہت اچھا ہے، لیکن مقامی آواز کی شناخت میں اس کے استعمال سے انکوڈنگ اور ڈیکوڈنگ کا غیر ضروری اضافی چکر شامل ہوسکتا ہے۔

پروسیسنگ کا سادہ راستہ یہ ہے:

getUserMedia()
    |
    v
AudioContext
    |
    v
AudioWorklet
    |
    v
Float32 PCM buffers
    |
    v
Dedicated Worker

AudioWorklet ایپلی کیشن کے مرکزی JavaScript تھریڈ سے باہر آڈیو پروسیسنگ کا کوڈ چلاتا ہے۔ یہ PCM نمونے حاصل کرسکتا ہے، متعدد چینلز کو ایک مونو چینل میں لاسکتا ہے، آواز کی سطح کے سادہ پیمانے حساب کرسکتا ہے اور جمع شدہ بفرز ورکر کو منتقل کرسکتا ہے۔

مائیکروفون شروع کرنے کی آسان مثال یہ ہے:

const stream = await navigator.mediaDevices.getUserMedia({
  audio: {
    channelCount: { ideal: 1 },
    echoCancellation: true,
    noiseSuppression: true,
    autoGainControl: true,
  },
});

const context = new AudioContext();

await context.audioWorklet.addModule(
  '/assets/speech/pcm-worklet.js'
);

const source = context.createMediaStreamSource(stream);
const processor = new AudioWorkletNode(
  context,
  'pcm-capture'
);

source.connect(processor);

// Connect the worklet through an inaudible output path
// if required to keep the audio processing graph active.

مائیکروفون کی دی گئی شرائط ترجیحات ہیں، ضمانتیں نہیں۔ براؤزرز echo cancellation، noise suppression اور automatic gain control کے الگ الگ الگورتھم استعمال کرسکتے ہیں۔

ایک اہم بات یہ ہے کہ مائیکروفون کا سیمپل ریٹ لازماً 16 kHz نہیں ہوتا۔ بہت سے آڈیو کانٹیکسٹس 44.1 kHz یا 48 kHz استعمال کرتے ہیں۔ Whisper کو 16 kHz ان پٹ درکار ہے، اس لیے ریکارڈ شدہ نمونوں کی درست دوبارہ سیمپلنگ ضروری ہے۔

ہر دوسرا یا تیسرا نمونہ نکال دینا عمومی طور پر درست حل نہیں۔ windowed-sinc جیسے مناسب low-pass resampler سے سیمپل ریٹ کم کرتے ہوئے غیر مطلوبہ تکراری اثرات گھٹتے ہیں اور بول چال کی مفید فریکوئنسی محفوظ رہتی ہے۔

دوبارہ سیمپلنگ کا کام حقیقی وقت کے AudioWorklet کال بیک کے بجائے مخصوص ورکر کے اندر رکھیں۔

براؤزر تھریڈز کے درمیان آڈیو مؤثر انداز میں منتقل کریں

AudioWorklet آڈیو کے بہت سے چھوٹے حصے بنا سکتا ہے۔ ہر آڈیو رینڈرنگ کوانٹم کو الگ پیغام بنا کر آگے بھیجنے سے غیر ضروری اضافی بوجھ پیدا ہوسکتا ہے۔

ایک عملی طریقہ یہ ہے کہ PCM کے مختصر بیچ جمع کرکے ہر بیچ ArrayBuffer کی صورت میں منتقل کریں۔

worker.postMessage(
  {
    type: 'audio-chunk',
    buffer,
  },
  [buffer]
);

منتقلی کی فہرست اہم ہے: اس سے ArrayBuffer کی ملکیت منتقل ہوتی ہے اور پورے بفر کی غیر ضروری نقل نہیں بنانی پڑتی۔

ورکر ان حصوں کو آڈیو جمع کرنے والے بفر میں شامل کرکے ریکارڈنگ ختم ہونے پر اکٹھا کرسکتا ہے۔

ریکارڈنگ کے اصل سیمپل ریٹ، جمع کردہ نمونوں کی تعداد اور ریکارڈنگ کی مدت پر نظر رکھنا بھی مفید ہے۔ یہ معلومات حساس آڈیو ڈیٹا لاگ کیے بغیر خاموش ریکارڈنگ کی خرابی سمجھنے میں مدد دیتی ہیں۔

مزید نیورل نیٹ ورک کے بغیر وقفے پہچانیں

مختصر پیغامات بول کر لکھوانے کے لیے نیورل آواز کی سرگرمی جانچنے والا الگ ماڈل لازمی نہیں۔

موافقت اختیار کرنے والا RMS ڈیٹیکٹر آواز کی موجودگی کا کم خرچ تخمینہ دے سکتا ہے۔ RMS سگنل کی شدت ناپتا ہے، جس سے ایپلی کیشن اندازہ لگاسکتی ہے کہ پہلے بولنے والا شخص کب خاموش ہوگیا۔

انٹرفیس میں مائیکروفون پر دوسری بار کلک کرکے ریکارڈنگ خود بند کرنے کا اختیار ہمیشہ ہونا چاہیے۔ خاموشی کی خودکار شناخت محض سہولت ہے، کامیاب شناخت کے لیے ضروری شرط نہیں۔

مختصر آواز لکھوانے کے لیے مناسب ابتدائی قدریں یہ ہیں:

پیرامیٹرابتدائی قدر
تجزیے کا وقفہ20 ms
پس منظر کے شور کی پیمائش300 ms
بولنے کی تصدیق140 ms
خودکار بندش سے پہلے خاموشی1.4 سیکنڈ
آواز نہ آنے کی مہلت8 سیکنڈ
ریکارڈنگ کی زیادہ سے زیادہ مدت30 سیکنڈ

یہ ترتیب شروع کرنے کی قدریں ہیں، ہر حالت کے لیے بہترین حدیں نہیں۔ دھیمی گفتگو، پس منظر کی موسیقی اور مائیکروفون میں شور کم کرنے کی پروسیسنگ RMS کی پیمائش متاثر کرسکتی ہے۔

جملے کے آخری دھیمے الفاظ خودکار طور پر کاٹنے کے بجائے صارف کو ریکارڈنگ دستی طور پر بند کرنے دیں۔

عام مختصر متن داخل کرنے کے لیے درمیان کے نتائج حاصل کرنے کی خاطر Whisper بار بار چلانے کے بجائے ایک ہی بار متن تیار کرنا عموماً آسان ہوتا ہے۔ آواز ریکارڈ کریں، روکیں، ماڈل ایک بار چلائیں اور حتمی متن درج کردیں۔

Whisper کے مکمل سلسلے کے لیے صرف ONNX ماڈل کافی نہیں

یہ نفاذ کی نہایت اہم تفصیلات میں سے ایک ہے۔

Whisper کا استدلال محض ONNX اینکوڈر کے بعد ONNX ڈیکوڈر چلانا نہیں۔ آواز کی مکمل خودکار شناخت میں آڈیو کی خصوصیات اخذ کرنا، ٹوکنائزیشن، متن پیدا کرنے کی ترتیب اور پیش گوئی شدہ ٹوکنز کو پڑھنے کے قابل متن میں بدلنا بھی ضروری ہے۔

پروسیسنگ کا مکمل سلسلہ یہ ہے:

Raw microphone PCM
        |
        v
Resampling to 16 kHz
        |
        v
Whisper feature extractor
        |
        v
ONNX encoder
        |
        v
ONNX decoder and token generation
        |
        v
Whisper tokenizer
        |
        v
Recognized text

ONNX سیشن کی کامیاب ابتدا صرف یہ ثابت کرتی ہے کہ ماڈل کا گراف لوڈ ہوسکتا ہے۔ اس سے پورا شناختی سلسلہ درست کام کرنے کی تصدیق نہیں ہوتی۔

Transformers.js کے ایک آزمودہ انضمام میں ماڈل سیشن شروع ہوجاتے تھے، مگر متن بنانا پھر بھی ناکام تھا، کیونکہ مقامی طور پر بنائے گئے سلسلے میں ضروری پروسیسر اور ٹوکنائزر درست طور پر ترتیب نہیں دیے گئے تھے۔

درست کام کرنے والے نفاذ میں مقامی ماڈل کی معلومات سے ان اجزا کی واضح طور پر ابتدا کی گئی تھی۔

ذیل میں اس مخصوص ورژن سے متعلق طریقے کی مختصر مثال ہے؛ یہ مکمل، خود مختار ورکر نہیں:

import {
  WhisperTokenizer,
  WhisperFeatureExtractor,
  WhisperProcessor,
} from '@huggingface/transformers';

// These values come from local model configuration files.
const tokenizer = new WhisperTokenizer(
  tokenizerJson,
  tokenizerConfig
);

const featureExtractor = new WhisperFeatureExtractor(
  preprocessorConfig
);

const processor = new WhisperProcessor(
  {},
  {
    tokenizer,
    feature_extractor: featureExtractor,
  },
  ''
);

// In the affected version-specific integration:
recognizer.tokenizer = tokenizer;
recognizer.processor = processor;

کنسٹرکٹر کی درست ساخت اور انضمام کا طریقہ نصب شدہ Transformers.js ورژن کے مطابق جانچنا ضروری ہے۔ کچھ ورژنز اور ماڈل ایکسپورٹس یہ اجزا خود بناسکتے ہیں؛ انہیں ہاتھ سے بنانا ہر صورت میں لازمی نہیں سمجھنا چاہیے۔

جب مکمل سلسلہ دستیاب ہو تو مختصر گفتگو کا متن زبان اور کام واضح کرکے تیار کیا جاسکتا ہے:

const result = await recognizer(audio16k, {
  language: 'en',
  task: 'transcribe',
  return_timestamps: false,
});

اگر ایپلی کیشن کو صارف کی زبان پہلے سے معلوم ہو تو اسے واضح طور پر دینے سے زبان کا غیر ضروری پتا لگانے کی ضرورت نہیں رہتی اور مختصر ریکارڈنگ کے نتائج زیادہ قابلِ پیش گوئی ہوسکتے ہیں۔

مطابقت رکھنے والے Transformers.js اور ONNX Runtime ورژنز مقرر رکھیں

خرابی کی ایک اور اہم وجہ Transformers.js اور ONNX Runtime Web کے باہمی تعلق میں ہوسکتی ہے۔

Transformers.js شناخت کا اعلیٰ سطحی سلسلہ فراہم کرتا ہے، جبکہ ONNX Runtime Web نیورل نیٹ ورک کے گراف چلاتا ہے۔ دونوں پیکجز کا ایک دوسرے سے اور استعمال ہونے والے مخصوص ONNX ماڈل ایکسپورٹس سے مطابقت رکھنا ضروری ہے۔

جانچے گئے نفاذ میں ONNX Runtime Web کی ایک ترقیاتی بلڈ نے Whisper اینکوڈر شروع کردیا، مگر کوانٹائزڈ ڈیکوڈر کا سیشن بناتے وقت ناکام ہوگئی۔ خرابی کا تعلق DequantizeLinear آپریشن میں کوانٹائزیشن کی مطلوبہ اسکیل قدر نہ ہونے سے تھا۔

یہ مائیکروفون کی اجازت، ڈاؤن لوڈ یا آڈیو فارمیٹ کا مسئلہ نہیں تھا۔ براؤزر کو ماڈل کی فائلیں مل رہی تھیں، لیکن رن ٹائم ضروری ماڈل گراف میں سے ایک کو شروع نہیں کرسکا۔

ایک مستحکم، مقرر کردہ ONNX Runtime Web ریلیز سے اینکوڈر اور ڈیکوڈر دونوں کو براہِ راست آزمانے سے یہ مخصوص عدم مطابقت دور ہوگئی۔

مطابقت کی یہ جانچ خاص طور پر اہم تھی، کیونکہ اس نے دو الگ دعووں میں فرق واضح کیا:

  • ماڈل کی فائل کامیابی سے ڈاؤن لوڈ ہوگئی۔
  • رن ٹائم نے اس فائل سے قابلِ استعمال استدلالی سیشن کامیابی سے بنا لیا۔

یہ دونوں باتیں ایک جیسی نہیں۔

جن ماڈل ایکسپورٹس کو آزمایا گیا، ان کے ساتھ Transformers.js 4.2.0 اور ONNX Runtime Web 1.24.3 کی جوڑی مطابقت رکھتی تھی۔ نسبتاً نئے ترقیاتی رن ٹائم میں کوانٹائزڈ ڈیکوڈر گراف ناکام ہوا۔ یہ مخصوص ورژنز کا مشاہدہ ہے، اس بات کا ثبوت نہیں کہ پرانے رن ٹائم ہمیشہ بہتر ہوتے ہیں۔

بالواسطہ آنے والے رن ٹائم انحصار کا ورژن بدلتے وقت پیکج کی لاک فائل میں عین ورژن مقرر کریں اور تبدیلی کی وجہ درج کریں۔ رن ٹائم کی اپ گریڈ کے لیے صرف پیکج کا کامیاب انسٹال کافی نہیں؛ براؤزر میں پورے استدلالی سلسلے کی دوبارہ جانچ درکار ہونی چاہیے۔

Whisper کی خرابی ڈھونڈنے سے پہلے ورکر بنڈل کا فارمیٹ جانچیں

JavaScript Web Worker مختلف ماڈیول فارمیٹس میں بنایا جاسکتا ہے۔

ایک انضمامی خرابی اس لیے ہوئی کہ ایپلی کیشن ورکر کو ES module کے طور پر چلا رہی تھی، جبکہ تیار شدہ ورکر بنڈل classic-worker کا طریقہ importScripts() استعمال کررہا تھا۔

یہ دونوں طریقۂ اجرا ایک دوسرے کے متبادل نہیں۔ ماڈیول ورکر صرف classic-worker کے لیے لکھا ہوا کوڈ یوں ہی نہیں چلاسکتا۔

عملی سبق یہ ہے کہ کسی عام رہنما سے کنسٹرکٹر کا اختیار نقل کرنے کے بجائے Worker کنسٹرکٹر کو تیار شدہ بنڈل کی حقیقی ساخت کے مطابق رکھیں۔

مثلاً درج ذیل دونوں اختیارات لازماً برابر نہیں:

// Module worker: requires a compatible module bundle.
new Worker(workerUrl, { type: 'module' });

// Classic worker: requires a compatible classic bundle.
new Worker(workerUrl);

درست انتخاب کا انحصار بنڈلر اور بنائی گئی JavaScript پر ہے۔

ورکر کی ابتدا کی خرابی جانچتے وقت براؤزر کا Console، تیار کردہ ورکر فائل اور Network پینل دیکھیں۔ معلوم کریں کہ خرابی ONNX Runtime شروع ہونے سے بھی پہلے تو نہیں آرہی۔

بعض بنڈل شدہ براؤزر لائبریریاں اپنی ماڈیول فائل کی جگہ کے لحاظ سے URL بناتی ہیں۔ انہیں ورکرز کے اندر پیک کرتے وقت یہ فرض نہ کریں کہ اصل پیکج سے متعلق راستے اب بھی ٹھیک ملیں گے؛ نتیجے میں بننے والے رن ٹائم اثاثوں کے راستے آزمائیں۔

WASM اور JavaScript ماڈیولز درست MIME اقسام کے ساتھ فراہم کریں

اگر ویب سرور غلط جوابی ہیڈرز بھیجے تو مکمل طور پر مطابقت رکھنے والی JavaScript اور ONNX ماڈل فائلیں بھی ناکام ہوسکتی ہیں۔

ایک حقیقی خرابی میں .mjs ایکسٹینشن والا JavaScript ماڈیول application/octet-stream کے طور پر فراہم ہورہا تھا۔ براؤزر نے اسے مسترد کردیا، کیونکہ جواب کی قسم JavaScript ماڈیول چلانے کے لیے مناسب نہیں تھی۔

عام طور پر متوقع جوابی اقسام یہ ہیں:

فائل کی ایکسٹینشنContent-Type
.mjsapplication/javascript
.wasmapplication/wasm

صرف سرور کی ترتیب والی فائل نہیں بلکہ پروڈکشن کا حقیقی جواب جانچیں۔

curl -I https://example.com/runtime/speech/v2/runtime.mjs
curl -I https://example.com/runtime/speech/v2/runtime.wasm

اوپر دیے گئے URLs محض مثالیں ہیں۔ منتخب رن ٹائم بلڈ سے اصل ورژن شدہ فائل نام استعمال کریں۔

صرف درست HTTP اسٹیٹس کافی نہیں۔ براؤزر MIME قسم، Content Security Policy، ماڈیول کے طریقۂ اجرا یا غلط اثاثہ URL کی وجہ سے بھی فائل مسترد کرسکتا ہے۔

یاد رکھیں کہ ایک ہی درخواست براؤزر کے ٹیب میں براہِ راست کھولنے پر کامیاب ہوسکتی ہے، مگر قابلِ اجرا ماڈیول یا WebAssembly کے انحصار کے طور پر لوڈ ہونے پر ناکام ہوسکتی ہے۔

ناقابلِ تبدیلی اثاثہ URLs استعمال کریں، مگر صارف کو خراب رن ٹائم میں نہ پھنسائیں

Whisper ماڈل کی فائلیں اتنی بڑی ہیں کہ براؤزر کی کیشنگ اہم ہوجاتی ہے۔

ورژن کے ساتھ ناقابلِ تبدیلی اثاثوں کے راستے براؤزر کو ہر بار بولنے پر دوبارہ ڈاؤن لوڈ کیے بغیر وہی ماڈل اور رن ٹائم فائلیں استعمال کرنے دیتے ہیں۔

کیش کی ایک عام پالیسی یہ ہے:

Cache-Control: public, max-age=31536000, immutable

تاہم اس سے تعیناتی کی ایک شرط پیدا ہوتی ہے: کسی URL کو ناقابلِ تبدیلی قرار دینے کے بعد اس کا مواد خاموشی سے تبدیل نہیں کرنا چاہیے۔

اگر رن ٹائم بائنری بدلنی ہو تو اسے نئے ورژن والے URL پر جاری کریں۔

/models/speech/v1/
/runtime/speech/v1/
/runtime/speech/v2/

رن ٹائم کا راستہ بدلنے کا مقصد محض ظاہری ترتیب نہیں۔ اگر ناقابلِ تبدیلی URL کے اندر موجود مواد بدل کر وہی URL دوبارہ استعمال کیا جائے تو براؤزر پہلے کیش شدہ، غیر مطابقت رکھنے والی WebAssembly بائنری استعمال کرتا رہ سکتا ہے۔

JavaScript کا معاون کوڈ اور WebAssembly فائلیں ایک ہی رن ٹائم تقسیم سے رکھنا بھی مفید ہے۔ مختلف ورژنز کی رن ٹائم فائلیں ملانے سے ایسی ابتدائی خرابیاں پیدا ہوسکتی ہیں جن کی تشخیص مشکل ہو۔

بلڈ کے وقت تیار کردہ فہرست میں متوقع فائلوں، ان کے حجم اور کرپٹوگرافک چیک سمز کا اندراج، تعیناتی سے پہلے گمشدہ یا غیر مطابقت رکھنے والے اثاثوں کا پتا دے سکتا ہے۔

شناخت کی لائبریری کو اپنی ویب سائٹ سے فراہم کردہ اثاثے استعمال کرنے کے لیے ترتیب دیں اور دور دراز سے ماڈل لوڈ کرنا بند کریں۔ یوں مقامی ماڈل نہ ملے تو بیرونی ماڈل میزبان سے غیر ارادی ڈاؤن لوڈ شروع ہونے کے بجائے واضح خرابی ملے گی۔

مائیکروفون کچھ کام نہ کرنے کے باوجود کیوں گھومتا رہ سکتا ہے

ترقی کے دوران ایک عام علامت یہ ہوتی ہے کہ مائیکروفون بٹن اجازت مانگتا ہے، لوڈنگ کی حرکت دکھاتا ہے اور آخرکار کوئی متن درج کیے بغیر خرابی کی حالت میں واپس آجاتا ہے۔

براؤزر یہ بھی دکھا سکتا ہے کہ مائیکروفون استعمال ہورہا ہے۔

اس سے آواز پہچاننے والا نظام صحیح کام کرنے کی تصدیق نہیں ہوتی۔ صرف اتنا پتا چلتا ہے کہ کسی وقت مائیکروفون سے ریکارڈنگ کی اجازت تھی یا ریکارڈنگ فعال تھی۔

کئی الگ خرابیاں تقریباً ایک جیسی علامات پیدا کرسکتی ہیں:

  1. JavaScript ماڈیول کی غلط MIME قسم۔ براؤزر رن ٹائم ماڈیول ڈاؤن لوڈ کرتا ہے مگر اسے چلاتا نہیں۔
  2. ورکر کے طریقۂ اجرا میں عدم مطابقت۔ تیار شدہ ورکر classic-worker کے APIs استعمال کرتا ہے لیکن ماڈیول ورکر کے طور پر شروع ہوتا ہے، یا اس کے برعکس۔
  3. ONNX ڈیکوڈر کی عدم مطابقت۔ رن ٹائم اینکوڈر سیشن بنالیتا ہے لیکن کوانٹائزڈ ڈیکوڈر گراف پر ناکام ہوتا ہے۔
  4. نامکمل شناختی سلسلہ۔ ONNX سیشن موجود ہوتے ہیں مگر ٹوکنائزر یا آڈیو پروسیسر درست طور پر شروع نہیں ہوتا۔

ان مسائل کی الگ الگ تشخیص ضروری ہے۔ ایک خرابی درست کرنے کے بعد دوسری سامنے آسکتی ہے۔

خرابی کی تشخیص کا سب سے اہم اصول یہ ہے کہ HTTP 200 ملنے سے ماڈل کی کامیاب ابتدا ثابت نہیں ہوتی، اور ماڈل کی کامیاب ابتدا سے متن بننے کی کامیابی ثابت نہیں ہوتی۔

یہاں تک کہ کامیابی سے متن بن جانا بھی اس بات کی ضمانت نہیں کہ وہ ایپلی کیشن کے اصل متن کے خانے میں پہنچ گیا۔

ہر مرحلے کی حد پر تشخیص کے لیے واضح اشارہ درکار ہے۔

نجی گفتگو جمع کیے بغیر مشاہدہ کرنے کی صلاحیت شامل کریں

مفید تشخیصی لاگز کے لیے صارف کی گفتگو محفوظ کرنا ضروری نہیں۔

ایپلی کیشن درج ذیل تکنیکی حالتوں پر نظر رکھ سکتی ہے:

permission-granted
worker-created
runtime-loading
runtime-ready
encoder-ready
decoder-ready
recording-started
pcm-received
recording-stopped
inference-started
inference-completed
result-inserted

ناکامی پر متعلقہ مرحلہ، مستقل تکنیکی خرابی کوڈ اور حساس معلومات سے پاک خرابی کا مختصر ریکارڈ شامل کریں۔

ماڈل کی ابتدا میں ناکامی کو مائیکروفون کی اجازت نہ ملنے یا خالی ریکارڈنگ سے الگ پہچانا جاسکے۔ ورکر کی خرابی ترقیاتی ماحول میں نظر آنی چاہیے، نہ کہ کسی عمومی خرابی سنبھالنے والے نظام میں چھپ جائے۔

مائیکروفون کے نمونے، پہچانے گئے جملے، ٹوکن کی ترتیب یا گفتگو کا کوئی اور مواد لاگ نہ کریں۔ کارکردگی کی پیمائش میں دورانیے کی حدیں، منتخب ماڈل کی سطح، ابتدا میں لگا وقت، ماڈل چلنے کا وقت اور خرابیوں کی اقسام رکھی جاسکتی ہیں۔

اس سے رازداری کے تقاضے کمزور کیے بغیر خراب مائیکروفون کی تشخیص بہت آسان ہوجاتی ہے۔

React کی اسٹیٹ کے ذریعے حاصل شدہ متن درج کریں

آواز کی شناخت تبھی مفید ہے جب حتمی متن پہلے سے موجود فارم کے خانے تک پہنچے۔

React ایپلی کیشن میں اس خانے کو اکثر کمپوننٹ کی اسٹیٹ کنٹرول کرتی ہے۔ براہِ راست input.value کو قدر دینا فریم ورک کے رینڈر کرنے کے طریقے سے متصادم ہوسکتا ہے۔

اس کے بجائے پہچانا گیا متن اسی اسٹیٹ اپ ڈیٹ کے راستے سے گزرنا چاہیے جو عام ٹائپنگ میں استعمال ہوتا ہے۔

انضمام میں غیر ہم وقت رویے کا خیال بھی رکھنا ہوگا۔ ممکن ہے صارف مزید حروف لکھ چکا ہو یا کرسر ہٹا چکا ہو اور اس کے بعد شناخت مکمل ہو۔

ریکارڈنگ شروع ہونے پر محفوظ کی گئی پرانی ان پٹ قدر استعمال کرنے سے بعد کی ترامیم غلطی سے مٹ سکتی ہیں۔

انضمام کا ایک سادہ نمونہ یہ ہے:

const insertion = insertTranscript({
  currentValue: latestValue,
  transcript: recognizedText,
  selection: currentSelection,
  maxLength: inputLimit,
});

setMessage(insertion.value);
restoreCaret(insertion.caret);

متن داخل کرنے والے معاون فنکشن کو موجودہ متن محفوظ رکھنا چاہیے، ضرورت پڑنے پر منتخب حصہ بدلنا چاہیے، مناسب وقفے شامل کرنے چاہییں اور خانے کی زیادہ سے زیادہ طوالت کا لحاظ رکھنا چاہیے۔

Unicode پر بھی توجہ ضروری ہے، کیونکہ JavaScript اسٹرنگ کی لمبائی UTF-16 کوڈ یونٹس میں گنتی ہے۔ کسی بھی من مانے مقام پر اسٹرنگ کاٹنے سے ایک surrogate pair ٹوٹ سکتا ہے۔

سب سے اہم بات یہ ہے کہ آواز پہچان لینے پر فارم خودکار طور پر جمع نہیں ہونا چاہیے۔ صارف کو بھیجنے سے پہلے متن پڑھنے اور درست کرنے کا موقع ملنا لازم ہے۔

عام متن کے ان پٹ کو خراب کیے بغیر ناکامیاں سنبھالیں

آواز کا نظام اختیاری ہونا چاہیے۔

اگر مائیکروفون کی اجازت نہ ملے، براؤزر ماڈل کے لیے میموری مختص نہ کرسکے، ورکر بند ہوجائے یا ریکارڈنگ میں آواز نہ ہو، تب بھی عام متن کا خانہ کام کرتا رہنا چاہیے۔

مائیکروفون کے پورے عملی دور کو درج ذیل واضح حالتوں سے ظاہر کریں:

idle
preparing
listening
recognizing
error

آسانی سے سمجھ آنے والے لیبل اور واضح حالت کی معلومات دیں۔ لوڈنگ کے بعد مائیکروفون کا محض سرخ یا گلابی ہوجانا صارف کو تقریباً کچھ نہیں بتاتا۔

منسوخی پر آڈیو ٹریکس، آڈیو کانٹیکسٹ، زیرِ انتظار بفرز اور فعال ریکارڈنگ سیشن صاف ہونے چاہییں۔ انٹرفیس کو یہ بھی روکنا چاہیے کہ پہلے منسوخ کی گئی ریکارڈنگ کا دیر سے آنے والا نتیجہ نئے متن کی حالت پر لکھ دیا جائے۔

اگر بڑا ماڈل میموری یا ابتدا کی پابندیوں کی وجہ سے ناکام ہو تو چھوٹا ماڈل آزمانے سے پہلے اسے مکمل طور پر آزاد کریں۔ دوبارہ کوششوں کی تعداد محدود رکھیں تاکہ براؤزر بار بار ایسے ماڈل ڈاؤن لوڈ یا شروع نہ کرے جو چل نہیں سکتے۔

مقامی شناخت ناکام ہو تو خاموشی سے کسی کلاؤڈ آواز پہچاننے والی سروس پر منتقل نہ ہوں۔ اگر مقامی پروسیسنگ سخت شرط ہے تو مقامی نظام کی ناکامی بھی مقامی ناکامی ہی رہنی چاہیے۔

براؤزر کے مکمل سلسلے کی جانچ کریں

TypeScript کی کامیاب جانچ یا پروڈکشن بلڈ اس بات کا کافی ثبوت نہیں کہ صوتی ان پٹ کام کرتا ہے۔

اسی طرح براؤزر کے ONNX فائلیں ڈاؤن لوڈ کرلینے سے یہ ثابت نہیں ہوتا کہ ماڈل کے دونوں سیشن کامیابی سے شروع ہوتے ہیں۔

سب سے مفید دوبارہ جانچ کے لیے وہی ورکر، رن ٹائم فائلیں، ماڈل، پروسیسر اور ٹوکنائزر استعمال ہونے چاہییں جو پروڈکشن میں چلتے ہیں۔

پہلے سے معلوم ایک مختصر PCM ریکارڈنگ کو براؤزر کے حقیقی استدلالی راستے سے گزاریں اور تصدیق کریں کہ خالی نہ ہونے والا متن واپس ملتا ہے۔

اس کے بعد اصل براؤزر میں مائیکروفون کی مکمل کارروائی آزمائیں۔

  • صفحے کی ابتدائی لوڈنگ: تصدیق کریں کہ مائیکروفون استعمال ہونے سے پہلے آواز کے ماڈلز یا رن ٹائم اثاثے ڈاؤن لوڈ نہیں ہوتے۔
  • پہلی مرتبہ ابتدا: مائیکروفون کی اجازت، ماڈل کی درخواستیں، JavaScript اور WASM کی MIME اقسام اور ورکر کے واقعی تیار ہونے کا جواب جانچیں۔
  • ONNX کی ابتدا: تصدیق کریں کہ اینکوڈر اور ڈیکوڈر دونوں کے سیشن بن سکتے ہیں۔
  • آڈیو ریکارڈنگ: تصدیق کریں کہ AudioWorklet غیر خالی PCM بفرز بناتا ہے۔
  • دوبارہ سیمپلنگ: تصدیق کریں کہ ورکر اصل سیمپل ریٹ وصول کرکے درست 16 kHz آڈیو بناتا ہے۔
  • دستی طور پر روکنا: جانچیں کہ مائیکروفون پر دوسری بار کلک کرنے سے ریکارڈنگ قابلِ اعتماد انداز میں بند ہوتی ہے۔
  • خودکار روکنا: جانچیں کہ فطری وقفوں پر دھیمی گفتگو کے الفاظ کاٹے بغیر ریکارڈنگ ختم ہوتی ہے۔
  • متن بنانا: تصدیق کریں کہ مکمل پروسیسر، ماڈل اور ٹوکنائزر قابلِ فہم متن واپس کرتے ہیں۔
  • ان پٹ سے انضمام: تصدیق کریں کہ پہچانا ہوا متن صارف کی تبدیلیاں مٹائے بغیر اصل کنٹرول شدہ خانے میں آتا ہے۔
  • خرابی سے بحالی: اجازت نہ ملنا، فائلوں کا غائب ہونا، ورکر کی خرابی، ماڈل کی ناکام ابتدا، منسوخی اور چھوٹے ماڈل پر منتقلی آزمائیں۔
  • رازداری: نیٹ ورک کی درخواستیں دیکھ کر تصدیق کریں کہ مائیکروفون کی آڈیو کسی سرور یا تجزیاتی سروس پر اپ لوڈ نہیں ہوتی۔
  • موبائل مطابقت: اصلی فونز پر پہلی مرتبہ، دوبارہ اور مسلسل آواز لکھوانے کے سیشنز کی جانچ دہرائیں۔

ریکارڈ شدہ PCM کے ٹیسٹ ماڈل چلانے کے پورے نظام کی تصدیق کے لیے بہت اچھے ہیں، لیکن یہ ثابت نہیں کرتے کہ مائیکروفون سے آڈیو ریکارڈ ہو رہی ہے۔ آخری قبولیت کی جانچ میں اصلی مائیکروفون اور حقیقی یوزر انٹرفیس لازماً شامل ہوں۔

براؤزر میں قابلِ اعتماد صوتی ٹائپنگ کا عملی ڈھانچا

ایسی ویب سائٹ جسے مختصر، کثیر لسانی اور رازداری محفوظ رکھنے والا صوتی ان پٹ چاہیے، اس کے لیے سب سے عملی ڈھانچا جان بوجھ کر سادہ رکھا گیا ہے:

React microphone button
        |
        v
Permission request
        |
        v
Lazy model initialization
        |
        v
AudioWorklet PCM capture
        |
        v
Adaptive RMS / manual stop
        |
        v
Dedicated Worker
        |
        v
16 kHz audio resampling
        |
        v
Whisper Tiny or Base Q8
        |
        v
Compatible ONNX Runtime WASM
        |
        v
Whisper processor + tokenizer
        |
        v
Final transcript
        |
        v
Controlled React input

ایپلی کیشن کو ماڈل اور رن ٹائم کی ورژن شدہ فائلیں اپنے سرور پر رکھنی چاہییں، مرکزی تھریڈ سے باہر ماڈل چلانا چاہیے، غیر ضروری ڈاؤن لوڈ سے بچنا چاہیے، استعمال کے بعد وسائل آزاد کرنے چاہییں اور آواز کی شناخت کے لیے مائیکروفون کی آڈیو کبھی اپ لوڈ نہیں کرنی چاہیے۔

WebGPU سے رفتار بڑھانے، نیورل آواز کی سرگرمی جانچنے، دورانِ گفتگو جزوی متن بنانے یا اضافی ماڈل سطحوں جیسے پیچیدہ اختیارات پر بعد میں غور کیا جاسکتا ہے، جب پیمائش ان کی اضافی پیچیدگی کا جواز فراہم کرے۔

سب سے اہم سبق کسی خاص لائبریری کے ورژن یا ماڈل کے حجم میں نہیں، بلکہ براؤزر میں آواز پہچاننے کے سلسلے کے ہر مرحلے کی حد کو جانچنے کی اہمیت میں ہے۔

مائیکروفون کی اجازت مانگنے کا پیغام کام کرجائے تو اس کا مطلب آڈیو کا متن بننا نہیں۔ ماڈل ڈاؤن لوڈ ہوجانے سے اس کے ڈیکوڈر کی ابتدا ثابت نہیں ہوتی۔ ONNX سیشن بننے سے ٹوکنائزر کی دستیابی ثابت نہیں ہوتی۔ اور متن کامیابی سے بننے سے یہ ثابت نہیں ہوتا کہ ایپلی کیشن نے اسے صحیح جگہ درج کیا۔

یہ سہولت تب مکمل ہوتی ہے جب آنے والا شخص مائیکروفون دبا سکے، فطری انداز میں بول سکے، ریکارڈنگ روک سکے اور پہچانے گئے الفاظ قابلِ تدوین خانے میں دیکھ سکے—اور ریکارڈنگ آواز پہچاننے والے کسی سرور کو نہ بھیجی جائے۔