ابنِ ملاحظاتك بنفسك على مخرجات النموذج

لا يقدّم Quran Lab مقيّمًا. ما رؤوس الإخراج، والعتبات التي تأتي في صورة بيانات، وما يبنيه تطبيقك بنفسه.

الـ SDK محرّك استدلال: يأخذ الصوت ويُعيد مخرجات النموذج. وهو لا يقارن أي تلاوة بآية متوقَّعة أبدًا، ولا يقول أبدًا إن شيئًا ما كان خطأً. لا يقدّم Quran Lab مقيّمًا. وما يراه المتعلّم من ملاحظات هو من عمل تطبيقك، يبنيه على ما سمعه النموذج. وتشرح هذه الصفحة ما تحصل عليه، وما عليك أنت أن تبنيه.

ما يقدّمه لك الـ SDK

لكل محاولة:

  • طبقة فك الترميز. ما سمعه النموذج، جاهزًا للعرض: text، و tokens (ولكل رمز منها id و name و firstMs و peakMs و lastMs و confidence)، و words، ولكل إطار مدّته 40 مللي ثانية الرمزُ الأعلى، ومعه الرمز التالي في الترتيب والفارق بينهما. و settled هو عدد الرموز الأولى التي استقرّت، فلن تتغيّر بعد الآن في هذه المحاولة؛ وتكون قيمة isFinal هي true في آخر مقطع منها.
  • رؤوس الإخراج (heads). المخرجات الخام للشبكة: لكل مقطع أثناء المحاولة، وللمحاولة كلها عند انتهائها.
  • مفردات النموذج. model.tokens، وعددها 38 رمزًا: الفراغ (blank)، وحدّ الكلمة، والصوامت (الحروف الصامتة) الـ 28، وصوت الإخفاء الأنفي، والحركات القصيرة a و i و u، والحركات الطويلة (حروف المدّ) aa و ii و uu، ورمز واحد للأصوات الأجنبية.

ويأتي مع النموذج ملفان من البيانات للقراءة فقط. ولا يطبّق الـ SDK أيًّا منهما ولا يقرؤه أبدًا:

  • المعايرة (model.calibration): العتبات التي قاسها Quran Lab لهذا النموذج.
  • البيانات المرجعية (model.reference): الوحدات المتوقَّعة في كل آية.

من أين تأتي الوحدات المتوقَّعة والأحكام: model.reference مصنوع من مرجع Quran Lab لصوتيات القرآن وأحكام تجويده، وهو يعطي كذلك لكل وحدة أصواتها وأحكامها وموضع النصّ على تلك الأحكام في الكتب الكلاسيكية. وتبيّن صفحة المرجع كيف تربطه بوحدات النموذج، مع مثال تطبيقي.

رؤوس الإخراج

اثنا عشر مُخرَجًا، بالأسماء نفسها على كل منصّة. وتحسب الجلسة log_probs و inter1_log_probs و timing_log_probs و gem و attr_qalqalah و conf، ما لم تطلب غيرها.

الرأس المعدّل ما هو
log_probs 40 ms CTC النهائي على الرموز الـ 38: ما قيل
inter1_log_probs 40 ms CTC من طبقة مبكرة، ويبقى أقرب إلى الصوت
inter4_log_probs 40 ms CTC من طبقة وسطى، للتشخيص
id_log_probs 20 ms CTC للهوية (identity) على الرموز نفسها، بدقّة زمنية أعلى
timing_log_probs 20 ms الوقت الذي يستمرّ فيه كل صوت: المُدد، ومقدار المدّ
gem 20 ms التشديد: مخفّف أو مشدّد (الشدّة)
attr_tafkheem 20 ms مرقّق، أو مفخّم، أو تفخيم أدنى
attr_ghunna 20 ms لا غنّة، غنّة عادية، غنّة المشدّد، غنّة الإخفاء، الإدغام بغنّة
attr_qalqalah 20 ms لا قلقلة، صغرى، كبرى
attr_face 20 ms لا شيء، الإمالة، التسهيل، السكت
boundary 20 ms قيمة logit لكل إطار تدلّ على موضع بداية الوحدة
conf 20 ms قيمة logit للثقة لكل إطار

تعطي رؤوس CTC لوغاريتمات الاحتمال على الرموز. ويعطي gem ورؤوس attr_ احتمالات لكل فئة. أما boundary و conf فقيم logit (طبّق عليها دالة sigmoid).

لا يستخدم النموذج أي نموذج لغوي في أي موضع: لا transducer، ولا إعادة تقييم (rescoring)، ولا معرفة نصية مسبقة. فالنموذج اللغوي يصحّح في صمت ما قاله القارئ، وهذا بالضبط ما لا تريده هنا.

العتبات تأتي في صورة بيانات

يأتي calibration.json مع النموذج، موقّعًا ومُتحقَّقًا منه كأي ملف آخر، ويسلّمه الـ SDK إليك كما وصل تمامًا. وهو خاص بنموذج واحد وبمجموعة واحدة من المفردات، ويذكر model_id و tokens_sha256 فيه أيّ نموذج وأيّ مفردات. ويحتوي على ما يلي:

  • فئات الاختلاف في وحدة واحدة (classes) التي يمكن اختبارها: vowel_sub و vowel_del و vowel_ins و short_to_long و long_to_short و cons_sub و cons_del و insertion؛
  • أربع مجموعات مسمّاة من العتبات (strict، balanced، sensitive، very_sensitive)، ضُبطت كلٌّ منها على معدّل مستهدف للتنبيهات الخاطئة في التلاوة الصحيحة؛
  • لكل سياق، الدمج (fusion): الرأسان اللذان تُطبَّق عليهما العتبات (log_probs و inter1_log_probs)، والوزن a لكل فئة، وطريقة تجهيز inter1_log_probs (دمج حدّ الكلمة في الفراغ)، وقصّ القيم (clip)؛
  • لكل سياق وفئة، عتبة بوحدة nats لكل مجموعة مسمّاة، وحالة (status): validated أو experimental أو unverified أو off؛
  • لكل سياق، أرقام المدّ (madd، وتُقرأ من timing_log_probs)، والقلقلة (qalqalah، من attr_qalqalah)، والتشديد (gemination، من gem)، وقراءة لكل كلمة (word) إن كانت في الحزمة.

تعني unverified أن العتبات ضُبطت على بيانات التطوير ولم تُقرأ بعدُ على بيانات محجوزة للاختبار (held-out)، فلا يُدّعى شيء عن معدّل التنبيهات الخاطئة فيها. وقد تحملها حزمة على قناة مبكرة على فئةٍ ما، أو على أرقام madd و qalqalah و gemination. تعامل معها كما تتعامل مع experimental: صالحة للاستخدام، لكنها غير مضمونة. ولا تعني أبدًا أن القراءة على البيانات المحجوزة قد نجحت.

وقد تأتي الحزمة أيضًا دون القراءة لكل كلمة، وعندها لا تكون في معايرتها كتلة word. تحقّق من وجود الكتلة قبل أن تقرأها.

قد تختلف العتبات من إصدار للنموذج إلى الإصدار التالي. اقرأها من النموذج المحمَّل، ولا تنسخها إلى شيفرتك أبدًا.

ما يبنيه تطبيقك بنفسه

  1. الوحدات المتوقَّعة في الآية. model.reference جدول بحث: تُدخل فيه السورة والآية، فيُخرج معرّفات الوحدات وحدود الكلمات. وهو ليس جزءًا من التنزيل الأول، فاجلبه مرة واحدة. ومعرّفاته هي معرّفات model.tokens نفسها.
  2. القرينة في كل موضع. لكل موضع في التسلسل المتوقَّع، ولكل بديل من فئة ما يختلف عنه في وحدة واحدة، احسب، للتسلسل المتوقَّع وللبديل، لوغاريتم احتمال CTC الأمامي (forward) على التسلسل كاملًا، وذلك على log_probs، ثم مرة أخرى على inter1_log_probs بعد تجهيزه كما تنصّ المعايرة. ونسبة الأرجحية اللوغاريتمية لرأس ما هي log P لأفضل بديل ناقص log P للتسلسل المتوقَّع. ادمج الرأسين بوزن الفئة: a * llr(log_probs) + (1 - a) * llr(inter1_log_probs)، ثم اقصص الناتج، وقارنه بعتبة المعايرة لذلك السياق وتلك الفئة.
  3. المدّ والقلقلة والتشديد. يُحسب المدّ من timing_log_probs: المدة التي تستمرّ فيها الحركة الطويلة مقارنةً بوسيط مدد الحركات القصيرة في المحاولة، بنقاط القطع الواردة في المعايرة. وتُقرأ القلقلة من attr_qalqalah على الإطارات التي تلي الحرف، والتشديد من gem على امتداد الحرف، وكلٌّ منهما مقارنةً بقيمته في المعايرة.
  4. أيّ مجموعة من العتبات يحصل عليها المتعلّم، وأي تغيير لكل فئة. فهذا من إعدادات تطبيقك.
  5. النص الذي يقرؤه المتعلّم في تطبيقك. كيف يُعرض الاختلاف، ومتى يُعرض، أمر يعود إليك.

ولكل حزمة SDK ملف docs/migrating-to-3.md يشرح المحاذاة (alignment) ونسب الأرجحية خطوة بخطوة.

حدود ينبغي أن تراعيها في التصميم

بحسب بطاقة النموذج الخاصة بـ TajweedFormer V4:

  • تَسِم معايرة هذا الإصدار التشديد بالحالة off، والقلقلة بالحالة experimental؛ وقد تَسِمهما حزمة أخرى بغير ذلك، فاقرأ كل حالة من النموذج المحمَّل. وليس لرأسَي attr_ghunna و attr_tafkheem عتبات مُتحقَّق منها في هذا الإصدار: تعامل معهما على أنهما إشارتان خام.
  • مواضع المعايرة في المدّ اللازم قليلة جدًا، فلا يمكن الاعتماد عليه، والمدّ المتّصل هو أضعف فئات المدّ.
  • الصوت الملتقط بالهاتف وأصوات الأطفال هي أضعف الحالات بالنسبة إلى كل عتبة.
  • ضُبطت العتبات على القيمة المدموجة لرأسين. ورأسٌ واحد وحده، أو نص فك الترميز الجشع (greedy)، ليس قرينة على أن المتعلّم تلا شيئًا على نحو خاطئ.

ما يطلبه الترخيص على شاشتك

حيثما يعرض تطبيقك ملاحظات مبنية على النموذج، فاذكر في سطر واحد: «الملاحظات الآلية على التجويد قد تخطئ. وهي لا تغني عن معلم مؤهل.» لا تقدّم مخرجات النموذج أبدًا حكمًا شرعيًا على تلاوة أحد، ولا تتقاضَ أجرًا أبدًا على النموذج ولا على الوصول إليه ولا على أي ميزة يشغّلها. وما تكسبه من تعليمك وعملك يبقى لك.

إحصاءات ما تبنيه

يحصي الـ SDK ما يقيسه بنفسه: المحاولات، وثواني الصوت والكلام والصمت، وزمن الاستجابة، والرموز. أما ما لا يستطيع معرفته من دون ملاحظاتك، فيمكن لتطبيقك أن يُبلغ عنه؛ وإن لم يفعل، فلا يُرسَل شيء:

session.reportRecited(1, 1, 7);                       // surah, first ayah, last ayah of this take
client.analytics.reportChecks('vowel_sub', 31, 1);    // your rule, times checked, times flagged

ويدخل كلاهما في مجاميع ذلك اليوم المجهولة الهوية، ويُوسَمان في صفحة تطبيقك بأن التطبيق هو الذي أبلغ عنهما.