چیتشیت
تشخیص گفتار و Whisper
Speech Recognition and Whisper
رمزگشایی CTC، اجرا و تیونینگ Whisper، گیتگذاری با VAD، و تحویل پایپلاین تبدیل WAV به زیرنویس.
فهرست مطالب
وظایف در قالب کد
کار و کد| وظیفه | کد |
|---|---|
| رمزگشایی حریصانه CTC | ctc_greedy(frame_probs) |
| رمزگشایی پرتوی CTC | ctc_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
معماریرونویسی با 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|>.
پیشفرضها
پیشفرضها| تنظیم | پیشفرض | نکته |
|---|---|---|
temperature | 0.0 | بازنویسی زنجیره جایگزین |
condition_on_previous_text | False | توقف توهم زنجیرهای |
no_speech_threshold | 0.6 | تشخیص سکوت |
Silero `threshold` | 0.5 | 0.3 حساس است |
min_speech_duration_ms | 250 | رد کردن صدای سرفه و حرکت صندلی |
Silence hangover | 500-800 ms | کوتاهتر یعنی وقفه زودهنگام، بلندتر یعنی حس کندی و تاخیر |
Pre-roll buffer | 300-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
پایپلاین پروژه
گامبهگام- decode_wav: فقط مونو، 16 بیتی، غیرفشرده. تقسیم نمونهها بر 32768.
- activity: فقط همراه با
--segment. محاسبه RMS برای هر فریمframe_ms=20، باthreshold=0.02، merge کردن فاصلههایgap_ms=40، حذف اسپنهای زیرmin_ms=40. - transcribe: اعمال
encode_wavروی هر اسپن. تلاش مجدد خطایTimeoutErrorتا سقفretries=1. نگهداریaudio_sha256وattemptsبرای هر سطر. - http_recognizer: فیلدهای multipart برای
modelوfile. محدودیت پاسخ 1 مگابایت. مهلت زمانی 30 ثانیه. - captions: هدر
WEBVTT. زمانهای cue بهصورتstamp()با فرمت hh:mm:ss.mmm. همپوشانیها با خطا مواجه میشوند. - 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 فعال میشود.