چیت‌شیت

تشخیص گفتار و Whisper

Speech Recognition and Whisper

رمزگشایی CTC، اجرا و تیونینگ Whisper، گیت‌گذاری با VAD، و تحویل پایپ‌لاین تبدیل WAV به زیرنویس.

  • ۱۱ بخش
  • ۴ درس مرتبط
  • کد و دستورها عیناً از دوره‌ی اصلی
فهرست مطالب
  1. وظایف در قالب کد
  2. ساختار درونی Whisper
  3. رونویسی با Whisper
  4. محیط‌های اجرای سریع‌تر و VAD
  5. فرمول‌بندی‌های مختلف ASR
  6. پیش‌فرض‌ها
  7. اجرای پروژه
  8. پایپ‌لاین پروژه
  9. فلگ‌های پروژه
  10. عیب‌یابی
  11. پرسش‌ها

وظایف در قالب کد

کار و کد
وظیفهکد
رمزگشایی حریصانه CTCctc_greedy(frame_probs)
رمزگشایی پرتوی CTCctc_beam(frame_probs, beam_width=8)
نرخ خطای کلمات (WER)wer(ref, hyp)
برنامه‌ریزی چانک‌ها برای کلیپ 10 دقیقه‌ایchunk_schedule(600.0, chunk_s=30.0, stride_s=5.0)
ماشین وضعیت پایان نوبت گفت‌وگوTurnDetector(silence_hangover_ms=500, min_speech_ms=250)
پیاده‌سازی LoRA روی اتنشنLoraConfig(r=16, lora_alpha=32, target_modules=["q_proj", "v_proj"])

ساختار درونی Whisper

معماری
1500کراس‌اتنشنپیشوندصدا16 کیلوهرتز، پدینگ یا برش به 30 ثانیهاسپکتروگرام لگاریتمی مِل80 مِل × 3000 فریمساقه‌ی کانولوشنی (Conv stem)کرنل 3، استراید 2انکودر1500 گام زمانیتوکن‌های وظیفهزبان، وظیفه، برچسب‌های زمانیدیکودراتنشن علی به خود + کراس‌اتنشنتوکن‌های BPEدایره لغات 51,865 توکنی

رونویسی با Whisper

کد
python
import whisper
model = whisper.load_model("large-v3-turbo")
result = model.transcribe("clip.wav",
    language="en",                     # توقف دریفت تشخیص خودکار زبان (LID)
    task="transcribe",                 # یا <|translate|> به انگلیسی
    temperature=0.0,                   # بدون زنجیره جایگزین نمونه‌برداری
    condition_on_previous_text=False)  # جلوگیری از تکرار مهارگسیخته
print(result["text"])
for seg in result["segments"]:         # شروع، پایان، متن به ازای هر بخش
    print(seg["start"], seg["end"], seg["text"])

محیط‌های اجرای سریع‌تر و VAD

کد
python
from faster_whisper import WhisperModel
model = WhisperModel("large-v3-turbo", compute_type="int8_float16")  # 4 برابر سریع‌تر
segments, info = model.transcribe("meeting.wav", vad_filter=True)    # گیت VAD
from silero_vad import load_silero_vad, get_speech_timestamps
vad = load_silero_vad()
segments = get_speech_timestamps(audio, vad, sampling_rate=16000, threshold=0.5,
    min_speech_duration_ms=250, min_silence_duration_ms=500, speech_pad_ms=300)

فرمول‌بندی‌های مختلف ASR

مفهوم‌ها
CTC
توکن‌های هر فریم به‌همراه توکن blank. بدون مدل زبان (LM) درونی. سریع.
CTC حریصانه
ادغام تکرارها، حذف blankها. a a _ _ a b b _ c خروجی می‌دهد: a a b c.
RNN-T
ترکیب پیش‌بین و اتصال‌دهنده. استریم‌شدنی، دارای مدل زبان داخلی.
انکودر-دیکودر با اتنشن
بهترین کیفیت آفلاین. نیازمند کارهای مهندسی برای استریم.
WER
فرمول $(S + D + I) / N$. بالای 20% غیرقابل‌استفاده است. زیر 5% معادل دقت انسان است.
Turbo
دیکودر 4 لایه‌ای (به‌جای 32). 8 برابر سریع‌تر، با افت WER کمتر از 1%.
پرامپت
<|startoftranscript|>، <|en|>، <|transcribe|> یا <|translate|>، سپس <|notimestamps|>.

پیش‌فرض‌ها

پیش‌فرض‌ها
تنظیمپیش‌فرضنکته
temperature0.0بازنویسی زنجیره جایگزین
condition_on_previous_textFalseتوقف توهم زنجیره‌ای
no_speech_threshold0.6تشخیص سکوت
Silero `threshold`0.50.3 حساس است
min_speech_duration_ms250رد کردن صدای سرفه و حرکت صندلی
Silence hangover500-800 msکوتاه‌تر یعنی وقفه زودهنگام، بلندتر یعنی حس کندی و تاخیر
Pre-roll buffer300-500 msحفظ کلمه‌ی اول

اجرای پروژه

کد
bash
python3 scripts/project_test.py voice-note-transcriber-pipeline --init my-voice-pipeline
python3 scripts/project_test.py voice-note-transcriber-pipeline --all --solution --strict
cd projects/voice-note-transcriber-pipeline/solution
python3 pipeline.py --input fixtures/repair-note.wav --transcript-file fixtures/reference.json --out voice-output
ffmpeg -i YOUR_NOTE.m4a -ac 1 -ar 16000 -c:a pcm_s16le YOUR_NOTE.wav  # مونو، PCM شانزده بیتی
python3 pipeline.py --input YOUR_NOTE.wav --endpoint <url> --model YOUR_MODEL --out voice-output

پایپ‌لاین پروژه

گام‌به‌گام
  1. ‏decode_wav: فقط مونو، 16 بیتی، غیرفشرده. تقسیم نمونه‌ها بر 32768.
  2. ‏activity: فقط همراه با --segment. محاسبه RMS برای هر فریم frame_ms=20، با threshold=0.02، merge کردن فاصله‌های gap_ms=40، حذف اسپن‌های زیر min_ms=40.
  3. ‏transcribe: اعمال encode_wav روی هر اسپن. تلاش مجدد خطای TimeoutError تا سقف retries=1. نگه‌داری audio_sha256 و attempts برای هر سطر.
  4. ‏http_recognizer: فیلدهای multipart برای model و file. محدودیت پاسخ 1 مگابایت. مهلت زمانی 30 ثانیه.
  5. ‏captions: هدر WEBVTT. زمان‌های cue به‌صورت stamp() با فرمت hh:mm:ss.mmm. همپوشانی‌ها با خطا مواجه می‌شوند.
  6. ‏export_transcript: فایل‌های transcript.json، captions.vtt، audio.wav و index.html را می‌نویسد.

فلگ‌های پروژه

دستورها
دستورکاربرد
--input <wav>فایل WAV مونو با 16 بیت PCM، حداکثر 20 مگابایت
--out <dir>پوشه خروجی، پیش‌فرض voice-output
--transcript-file <json>متن مرجع آفلاین متصل به SHA256 صوت
--endpoint <url>آپلود فایل WAV به اندپوینت audio/transcriptions
--segmentتفکیک فعالیت‌ها بر پایه RMS پیش از پردازش و شناسایی
--review-file <json>رندر مجدد transcript.json ویرایش‌شده

عیب‌یابی

عیب‌یابی
  • تولید «Thanks for watching!» روی سکوت

    علت
    نبود VAD
    راه‌حل
    گیت‌گذاری با VAD پیش از فراخوانی Whisper
  • خروجی ژاپنی برای کلیپ نویزی

    علت
    دریفت در تشخیص خودکار زبان (LID)
    راه‌حل
    اجبار مقدار language="en"
  • تکرار یک خطا در پنجره‌های بعدی

    علت
    توالی متن‌های قبلی (Previous text cascade)
    راه‌حل
    تنظیم condition_on_previous_text=False
  • تولید متن در بخش پدینگ یک کلیپ 2 ثانیه‌ای

    علت
    پدینگ تا 30 ثانیه
    راه‌حل
    تنظیم pad=False یا اعمال گیت VAD
  • خروجی تقریباً تصادفی و نامفهوم

    علت
    استفاده از مِل‌های librosa با آماره‌های نادرست
    راه‌حل
    استفاده از whisper.audio.log_mel_spectrogram
  • ایجنت حرف کاربر را قطع می‌کند

    علت
    زمان hangover بیش از حد کوتاه است
    راه‌حل
    تنظیم hangover بین 500 تا 800 میلی‌ثانیه، اندپوینت معنایی
  • خطای «16-bit mono PCM required»

    علت
    ورودی استریو یا فشرده‌شده است
    راه‌حل
    تبدیل با دستور ffmpeg -ac 1 -ar 16000
  • خطای «Remote endpoints require HTTPS»

    علت
    ارسال HTTP به یک هاست از راه دور
    راه‌حل
    استفاده از HTTPS. پروتکل HTTP فقط برای loopback مجاز است

پرسش‌ها

پرسش و پاسخ
چه زمانی انکودر فریز شود؟
وقتی داده‌ها کمتر از 10 ساعت است. فقط دیکودر را تیون کنید.
چقدر داده برای فاین‌تیون نیاز است؟
10 تا 100 ساعت صوت حوزه هدف همراه با متن رونویسی‌شده.
چرا جستجوی پرتو CTC بر حریصانه ارجح است؟
جستجوی پرتو ادغام با LM را ممکن می‌کند؛ CTC مدل زبان درونی ندارد.
ترفند تخلیه (flush trick) چیست؟
در پایان گفتار، STT را تخلیه کنید. بافر 500 میلی‌ثانیه‌ای در حدود 125 میلی‌ثانیه تمام می‌شود.
آیا استفاده از Energy VAD در محیط عملیاتی مناسب است؟
خیر. روی هر نویزی بالای 40- dBFS فعال می‌شود.