Files
ERP/bale stt report/bale_stt_opensource_thirdparty_assessment.md

44 KiB
Raw Permalink Blame History

گزارش جامع: ارزیابی پروژه‌های متن‌باز و سرویس‌های شخص ثالث، و ترکیب بهینه برای کرالر STT بله

تاریخ: ۱۶ مهر ۱۴۰۵ (8 Oct 2026)
ورودی‌ها: دو گزارش مدیر پروژه

  • گزارش A: «ارزیابی تحلیلی راهکارهای استخراج صوت‌به‌متن در بله: سرویس‌های شخص ثالث، کتابخانه‌ها، پروژه‌های متن‌باز و جایگزین‌ها»
  • گزارش B: bale_stt_executive_roadmap_report3.md (سند عملیاتی برای مدیر پروژه و ایجنت مجری)

دامنه (طبق درخواست): حریم خصوصی و امنیت در این گزارش بررسی نشده و بعداً تصمیم‌گیری می‌شود. فقط فهرست کامل راهکارها، ارزیابی، الگوبرداری از متن‌باز و بهترین ترکیب ارائه شده است.

روش کار: هر دو گزارش را خواندم و ادعاهای قابل راستی‌آزمایی را با منابع عمومی (PyPI، مستندات رسمی بله، arXiv، Hugging Face، GitHub) تطبیق دادم. هر ادعا یکی از سه وضعیت دارد:
✅ تأیید شد | 🟡 تأییدنشده / فقط استنباط | ❌ با شواهد در تناقض است

محدودیت مهم: شبکه sandbox من بسته است؛ پس نتوانستم پکیج‌ها را نصب کنم یا پروتوها را بخوانم. هر جا بگویم «تأییدنشده»، یعنی در منابع عمومی قابل مشاهده برای من نبود، نه لزوماً اینکه غلط باشد.


۱. خلاصه اجرایی

پاسخ کوتاه به چهار سؤال شما

سؤال پاسخ کوتاه
نظر درباره گزارش A (متن‌باز و شخص ثالث) تحلیل خوبی است و دسته‌بندی ۸ راهکار درست است. ولی چند ادعای مهم آن تأییدنشده یا غلط است: نام و وضعیت پکیج aiobale-py، وجود متد GetTranscript (فقط ادعا شده، من نتوانستم ببینم)، و برتری «مدل متن‌باز» بر سرویس‌های تجاری. داده‌های مستقل خلاف این برتری را نشان می‌دهد (بخش ۶).
آیا دیگران همین مشکل را داشته‌اند و چطور حل کرده‌اند؟ هیچ پروژه عمومی‌ای که دقیقاً خروجی STT خود بله را استخراج کند پیدا نکردم. همان الگوهای نزدیک وجود دارد: کلاینت‌های کاربری مهندسی‌معکوس‌شده (aiobale، bale-sdk، فورک‌ها)، سلف‌بات‌ها و اسکرپرهای مبتنی بر Selenium/Playwright، و کسب‌وکارهایی که سراغ ASR مستقل رفته‌اند (بخش ۳).
اگر الگوبرداری یا شخص ثالث بخواهیم، چه کنیم؟ از متن‌باز، لایه‌های انتقال و نشست و ابزار دیکود پروتوباف را بردارید، نه خود «ترنسکرایب» را. از شخص ثالث، چند ASR را به‌عنوان کاندید موازی کنار بله بگذارید (بخش ۵ و ۶).
بهترین ترکیب؟ «بله + یک ASR تجاری فارسی + یک مدل خودمیزبان با واژگان تخصصی + LLM اجماع‌گیر با کاتالوگ کالا»، با کرالر بله به‌صورت adapter قابل‌سوییچ. جزئیات در بخش ۷.

سه یافته‌ای که تصمیم شما را تغییر می‌دهد

  1. «نیازی به آپلود ویس نیست.» بات خودتان با sendVoice(file_id) می‌تواند همان ویس کاربر را برای حساب کرالر بفرستد. این‌طور فایل را کرالر دانلود و آپلود نمی‌کند. این طراحی از گزارش B ساده‌تر و کم‌ریسک‌تر است (بخش ۷.۲).
  2. داده بنچمارک مستقل نشان می‌دهد ASR تجاری فارسی حدود ۱۴ امتیاز WER از بهترین متن‌باز جلوتر است (مقاله PSRB، بخش ۶.۲). این با ادعای گزارش A که «متن‌باز پایدارترین راهکار» است، همخوان نیست. البته روی داده عمومی بوده، نه واژگان تدارکات شما.
  3. کد مرجع گزارش B شبه‌کد است، نه کد اجراشدنی. توابعی مثل client.send_voice و client.raw_call در مستندات عمومی bale-sdk وجود ندارند (بخش ۲.۲).

۲. ارزیابی دو گزارش مدیر پروژه

۲.۱ گزارش A: متن‌باز و شخص ثالث

نقاط قوت

  • پوشش گسترده: ۸ راهکار در یک ماتریس مقایسه (تأخیر، رم، خلوص متن، پایداری، هزینه).
  • تفکیک درست «چه چیزی را از بله بگیریم» و «چه چیزی را مستقل بسازیم».
  • پیشنهاد معماری دومسیره (بله + مسیر مستقل) درست و عملی است.
  • معرفی bale-sdk و توجه به مجوز اختصاصی آن (نکته‌ای که گزارش‌های قبلی کم‌رنگ داشتند).
  • اشاره درست به اینکه Playwright روی وب بله الگوی جاافتاده‌ای است.

نقاط ضعف

  • چند ادعای کلیدی بدون منبع است و در بررسی من تأیید نشد (جدول زیر).
  • مقایسه دقت متن‌باز با تجاری فقط بر اساس WER خودگزارشی مدل‌ها روی Common Voice است. این عدد روی ویس‌های واقعی و محاوره‌ای معنی ندارد.
  • ارائه‌دهندگان تجاری مهم فارسی (Avanegar/Partai، Aipa) و Google Chirp 2 اصلاً در گزارش نیستند.
  • تحلیل خطای شخص ثالث ناقص است (مثلاً قیمت‌ها بدون تاریخ و منبع).

جدول راستی‌آزمایی ادعاهای گزارش A

ادعا وضعیت یافته من
Bot API رسمی STT ندارد ✅ مستندات رسمی docs.bale.ai: شیء Voice فقط file_id و file_unique_id دارد و هیچ متدی برای ترنسکریپت نیست. اصلاح: گزارش می‌گوید «حجم و مدت‌زمان» هم هست؛ در مستندات رسمی نیست (SDKهای شخص ثالث فیلد duration را اضافه کرده‌اند).
bale-sdk از mtp1376، نسخه 0.1.1، ۶۰۷ RPC در ۵۲ سرویس، پوشه proto/ ✅ صفحه PyPI (27 Jun 2026) دقیقاً همین را می‌گوید.
bale-sdk مجوز اختصاصی «All Rights Reserved» دارد ✅ تأیید شد. خود README هم می‌گوید استفاده فقط با حساب‌ها و داده‌هایی که مجاز هستید و مطابق ToS بله باشد.
سرویس bale.turing.v1.AI و متد GetTranscript با فیلدهای ۱ تا ۳ 🟡 نتوانستم از منبع عمومی تأیید کنم. فایل‌های docs/API_COVERAGE.md و docs/API_FA.md در صفحه PyPI لینک شده‌اند ولی برای من باز نشد. این مهم‌ترین ادعای هر دو گزارش است و باید در ۳۰ دقیقه اول خودتان تأیید شود (بخش ۹).
aiobale-py توسط امین مدنی، نسخه 0.3.x، متکی بر blackboxprotobuf 🟡 aiobale-py را پیدا نکردم. آنچه پیدا کردم: aiobale (Enalite، MIT، آخرین نسخه 0.1.5 در Aug 2025). توضیح خودش می‌گوید «از صفر و بدون فایل proto ساخته شده».
aiobale اولیه رها شده ✅ آخرین انتشار Aug 2025؛ فورک‌ها (autobale، BaleClient) می‌گویند نگهداری نمی‌شود و باگ دارد.
autobale توسط علی عمادی، نسخه 1.0.0، MIT ✅ تأیید شد (مخزن AliEmadii/autobale).
BaleClient — در گزارش نیست، ولی وجود دارد: فورک دیگری از aiobale (Foad-KhAb/baleclient، Python 3.11+).
bale-mcp-server روی aiobale-py 🟡/❌ پروژه‌ای به نام bale-mcp پیدا کردم که با توکن بات رسمی و tapi.bale.ai کار می‌کند، نه کلاینت کاربری. شاید پروژه دیگری باشد.
bale-chat-exporter با نشست کلاینت 🟡 اسکرپر Playwright + BeautifulSoup برای Bale Web پیدا کردم (خروجی اکسل). هم‌پروژه‌بودن با آنچه گزارش می‌گوید تأییدنشده است، ولی الگوی Playwright روی وب بله اثبات‌شده است.
Bale-Self-Bot در GitLab چابکان 🟡 آن را پیدا نکردم. ولی baleself (PyPI، zellias/bale-self-bot) یک سلف‌بات مبتنی بر Selenium است و الگو را تأیید می‌کند.
MajidAPI یک پراکسی روی موتورهای عمومی است 🟡 endpoint را در منابع قابل جست‌وجو پیدا نکردم. «پراکسی روی موتور عمومی» استنباط گزارش است، نه چیزی که ثابت شده باشد. هرچه باشد، SLA ندارد.
فارس‌آوا (عامراندیش): ۱۰ هزار ساعت داده، نصب On-Premise، ساعتی ۴۵–۶۰ هزار تومان 🟡 قیمت و جزئیات را مستقل تأیید نکردم؛ قیمت‌ها زمان‌دارند. قبل از تصمیم، استعلام رسمی بگیرید.
آی‌او تایپ دقت «بالای ۹۸٪» 🟡 ادعای بازاریابی است. روی ویس تدارکات خودتان اندازه بگیرید.
hezarai/whisper-small-fa روی CPU زیر ۲ ثانیه 🟡 محتمل برای ویس کوتاه، ولی مدل small روی فارسی محاوره‌ای ضعیف است (بخش ۶).
nezamisafa/whisper-v3-turbo-persian-v1.0 با WER ‏۲۹.۹٪ 🟡 این مدل را نتوانستم باز کنم. مدل مشابه vhdm/whisper-v3-turbo-persian-v1.1 ‏WER ‏14.07٪ می‌دهد ولی روی دادگان خودش؛ اعداد WER بین دادگان‌های مختلف قابل مقایسه نیستند.
Faster-Whisper تا ۴ برابر سریع‌تر ✅ (تا حد دانسته‌های من) ادعای رسمی خود پروژه است. در مقاله PSRB هم Faster-Whisper هالوسینیشن کمتری از Whisper خام داشت.
«مدل‌های متن‌باز پایدارترین راهکار فنی‌اند» ❌ با داده PSRB سازگار نیست: ASR تجاری فارسی و Chirp 2 به‌طور محسوس دقیق‌ترند (بخش ۶.۲). متن‌باز «مستقل‌ترین» است، نه لزوماً «دقیق‌ترین».

۲.۲ گزارش B: نقشه راه اجرایی

نقاط قوت

  • دیاگرام‌های توالی و جریان تاب‌آوری خوب و قابل‌تحویل به مدیر پروژه‌اند.
  • اصلاحات قبلی اعمال شده است: compare_digest، سقف روزانه، قفل ترتیبی، ۵۰۳ در خطا و متن خالی.
  • ورودی‌های انسانی روشن‌اند و «تأیید دکمه روی وب» به‌عنوان ورودی گذاشته شده است.
  • Rollback با خالی‌کردن env درست است.

ایرادها و ریسک‌های اجرایی

مورد توضیح
کد مرجع شبه‌کد است client.send_voice(...)، client.raw_call(service=..., method=...) و sent_msg.voice.to_media() در README عمومی bale-sdk نیست. جدول متدهای سطح‌بالای آن ارسال رسانه ندارد. مدل دسترسی RPC خام آن این‌طور است: «namespace برابر snake_case بخش آخر نام سرویس». یعنی bale.messaging.v2.Messaging → client.messaging. پس فراخوانی احتمالی bale.turing.v1.AI باید چیزی شبیه client.ai.GetTranscript(...) باشد (استنباط من).
آپلود ویس کارِ آپلود فایل و ساخت پیام صوتی (Media) را سند فرض گرفته ولی طراحی نکرده. این بخش از خود RPC ترنسکریپت سخت‌تر است. راه ساده‌تر در بخش ۷.۲ آمده.
پاسخ GetTranscript طبق خود سند، پاسخ bool mustWait و یک DownloadSource دارد، نه رشته متن. یعنی احتمالاً متن باید از یک لینک/منبع دانلود خوانده شود. مثال کد این را مدیریت نمی‌کند.
کلید پیش‌فرض os.environ.get("BALE_STT_INTERNAL_KEY", "bale_internal_secret") هنوز مقدار پیش‌فرض دارد؛ بدون env هم بالا می‌آید. با os.environ[...] خطا بدهد.
شمارنده روزانه متغیر درون‌حافظه است: با ریست کانتینر صفر می‌شود و ریست روزانه هم ندارد (پس بعد از رسیدن به سقف تا ری‌استارت بعدی می‌ماند).
.env نمونه API_KEY=bale_internal_secret یعنی همان مقدار پیش‌فرض ضعیف.
مسیرهای محلی لینک‌ها به file:///c:/Users/Reza/Desktop/... اشاره دارند. در اشتراک سند باید پاک شوند.
«بدون وقفه» ادعای «بدون حتی ۱ ثانیه قطعی» فقط وقتی درست است که stt.py در مواجهه با ۵۰۳ همان پرووایدر را بی‌خطا رد کند. این را باید در کد بات بررسی کرد، نه از روی سند.

۳. آیا دیگران هم همین مشکل را داشته‌اند؟ و چطور حل کرده‌اند؟

۳.۱ نتیجه کلی

پروژه عمومیِ مشخصی که خروجی STT خود بله را برای یک بات استخراج کند پیدا نکردم (گزارش A هم همین را می‌گوید). آنچه وجود دارد الگوهای مجاور است:

الگو نمونه‌های تأییدشده درسی که برای ما دارد
A. بات رسمی + ASR مستقل بات‌های بله روی Webhook (مثلاً hamedcode/bale-ai-bot روی Cloudflare Workers)، بات‌های مشتری‌مداری با LLM رایج‌ترین راه. بله فقط کانال پیام است؛ صوت دانلود و به موتور دیگر داده می‌شود.
B. کلاینت کاربری مهندسی‌معکوس‌شده aiobale (MIT)، فورک‌های autobale و BaleClient، bale-sdk (اختصاصی، ۶۰۷ RPC) نشان می‌دهد نگهداری نشست کاربری و تماس با RPCهای داخلی شدنی است، ولی پروژه‌ها تازه‌اند و بعضی رها می‌شوند.
C. اتوماسیون مرورگر baleself (Selenium)، اسکرپر چت Bale Web با Playwright روی وب بله جاافتاده است، ولی معمولاً برای کارهای ساده مثل پاسخ خودکار و بک‌آپ.
D. سوءاستفاده خلاقانه از زیرساخت BaleVPN (تونل روی تماس صوتی بله) نشان می‌دهد جامعه تا کجا از لایه‌های داخلی استفاده می‌کند؛ برای STT به کار ما نمی‌آید.
E. ابزارهای مدیریتی روی Bot API bale-mcp، SDKهای PHP/Node/Python/Swift/C# فقط Bot API؛ بدون هیچ راهی برای رسیدن به ترنسکریپت.

۳.۲ برداشت از همین شواهد

  1. راه مشترک جامعه این است که STT را بیرون از بله انجام می‌دهند. هیچ‌کس STT بله را «کرال» نکرده یا اگر کرده منتشر نشده است. پس در هر حال ریسک بالاتر و شواهد کمتری برای مسیر شماست.
  2. زیرساخت لازم برای کرالر وجود دارد (انتقال WebSocket، OTP، نشست، ارسال و دانلود فایل)؛ پس این پروژه «ساخت از صفر» نیست.
  3. پایداری کتابخانه‌ها ضعیف است (aiobale رها شد، bale-sdk نسخه 0.1.1 است). هر معماری باید فرض کند اجزای متن‌باز ممکن است از کار بیفتند.
  4. تنها چیزی که کل شرط‌بندی را توجیه می‌کند، دقت بله روی ویس‌های شماست. بدون آزمون دستی (بخش ۸، گام ۰) نباید ساخت شروع شود.

۴. کاتالوگ کامل راهکارها

برای هر راهکار: چه کار می‌کند، مزیت، عیب، تلاش (تخمین من)، وضعیت تأیید.

گروه ۱: استفاده از STT خود بله

# راهکار توضیح مزایا معایب تلاش وضعیت
S1 مسیر رسمی/تجاری با بله ایمیل یا تماس با تیم توسعه‌دهندگان/بیزینس بله برای API رسمی STT یا قرارداد پایدار، بدون ریسک بن احتمال موافقت کم؛ زمان‌بر ۱ ایمیل هیچ مستند عمومی‌ای برای وجود چنین API نیست
S2 RPC مستقیم با bale-sdk استفاده از پروتوها و کلاینت آماده، فراخوانی GetTranscript سریع‌ترین مسیر فنی؛ پروتو آماده مجوز اختصاصی؛ نسخه 0.1.1؛ ادعای RPC تأییدنشده ۱–۲ روز 🟡
S3 RPC مستقیم با aiobale / autobale / BaleClient (MIT) + پروتوی خودساخته انتقال و نشست و آپلود از کتابخانه MIT؛ تعریف GetTranscript را از کپچر ترافیک خودتان در web.bale.ai بسازید بدون مشکل مجوز؛ قابل‌نگهداری کشف RPC و تعریف پروتو کار می‌برد؛ کتابخانه‌ها کم‌نگهداری‌اند ۳–۵ روز ✅ ابزارها؛ 🟡 RPC
S4 Playwright روی web.bale.ai کرومیوم headless با پروفایل پایدار؛ ارسال ویس، کلیک دکمه، خواندن DOM مقاوم در برابر تغییر پروتکل؛ الگوی اثبات‌شده ۳۵۰–۵۰۰MB رم؛ شکننده در برابر تغییر UI؛ وابسته به وجود دکمه در وب ۱–۲ روز ✅ الگو؛ 🟡 دکمه وب
S5 ترکیب «مرورگر برای ورود، پروتکل برای کار» Playwright فقط ورود/تمدید توکن (JWT) را انجام می‌دهد؛ کار اصلی را کلاینت WebSocket سبک می‌کند از سبک‌بودن S3 و پایداری ورود S4 بهره می‌برد پیچیدگی دو لایه ۴–۶ روز پیشنهاد من
S6 شبیه‌ساز اندروید + uiautomator اپ بله در شبیه‌ساز، خواندن متن از رابط مستقل از وب رم >2GB؛ شکننده؛ سخت‌ترین نگهداری ۵+ روز آخرین چاره
S7 چت هوش مصنوعی بله (Oracle) ارسال ویس به بات هوش مصنوعی بله و گرفتن پاسخ بدون کشف RPC خروجی «متن + تفسیر»؛ تأخیر ۵–۱۵ ثانیه؛ اینکه ویس را پیاده می‌کند هم تأییدنشده ۱ روز 🟡

گروه ۲: سرویس‌های شخص ثالث

# راهکار توضیح مزایا معایب تلاش وضعیت
T1 پراکسی‌های غیررسمی (MajidAPI و مشابه) فراخوانی REST با لینک ویس چند ساعت بدون SLA؛ موتور نامشخص؛ ورودی URL (ویس باید لینک عمومی شود) ساعتی 🟡
T2 ASR تجاری فارسی Avanegar/Partai (API: api.ivira.ai/partai/speechRecognition)، Aipa، عامراندیش (فارس‌آوا)، IOType دقت بالا روی فارسی؛ پشتیبانی؛ گاهی On-Premise هزینه ریالی؛ قرارداد ۱ روز (adapter) ✅ Avanegar/Aipa در بنچمارک؛ 🟡 قیمت‌ها
T3 ASR ابری بین‌المللی Google Chirp 2، Azure Speech، OpenAI Whisper API، Groq Whisper Chirp 2 تقریباً هم‌سطح بهترین تجاری فارسی هزینه ارزی؛ محدودیت دسترسی؛ بسته‌به شرایط شبکه ۱ روز ✅ Chirp/Azure در بنچمارک

گروه ۳: مدل‌های متن‌باز خودمیزبان

# راهکار توضیح مزایا معایب تلاش وضعیت
O1 Faster-Whisper large-v3 (+ initial_prompt/hotwords واژگان تدارکات) سرور OpenAI-compatible داخلی مستقل؛ قابل‌شخصی‌سازی با واژگان؛ بهترین متن‌باز در بنچمارک WER ≈ 34٪ روی فارسی واقعی؛ نیاز به GPU برای سرعت ۱ روز ✅
O2 Whisper large-v3-turbo فاین‌تیون فارسی (مثل vhdm/whisper-v3-turbo-persian-v1.1) مدل فاین‌تیون‌شده روی دادگان فارسی سریع‌تر؛ احتمالاً دقیق‌تر روی گفتار تمیز ارقام خودگزارشی و روی دادگان متفاوت؛ باید روی داده شما سنجید ۱ روز 🟡
O3 NeMo FastConformer فارسی (NVIDIA) stt_fa_fastconformer_hybrid_large مدل مستقل از Whisper؛ دیکودر CTC در بنچمارک WER ≈ 45٪ (ضعیف‌تر از Whisper) ۲ روز ✅
O4 Vosk فارسی (vosk-model-fa-0.5) Kaldi/DNN-HMM سبک، CPU بسیار سبک؛ آفلاین WER ≈ 45٪ ساعتی ✅
O5 SLPL wav2vec2 فارسی (دانشگاه شریف) XLS-R فاین‌تیون‌شده مناسب برای تحقیق و ensemble WER ≈ 47٪ ۲ روز ✅
O6 Seamless M4T v2 مدل چندزبانه — احتمال بازنویسی/هالوسینیشن (Interpretation Error در مقاله PSRB) ۲ روز ✅ مشکل

گروه ۴: لایه‌های بالاتر (نه جایگزین، بلکه تقویت‌کننده)

# راهکار توضیح
L1 LLM اجماع‌گیر با کاتالوگ کاندیدها + فهرست کالا/برند/واحد دیتابیس تدارکات را به LLM بدهید تا خروجی ساختاریافته و تصحیح‌شده بسازد. (مقاله PSRB هم می‌گوید LLMها خطاهای جزئی ASR را خوب اصلاح می‌کنند.)
L2 نرمال‌سازی فارسی یکسان‌سازی «ی/ک»، ارقام، نیم‌فاصله (ZWNJ) و اعداد حرفی. PSRB نشان می‌دهد مرزبندی کلمه و نیم‌فاصله WER را بالا می‌برد.
L3 فاین‌تیون روی داده خودتان ویس‌های واقعی + متن نهایی تأییدشده توسط کاربر → LoRA روی Whisper. بلندمدت‌ترین سرمایه‌گذاری برای استقلال از بله.
L4 مسیریابی بر اساس اعتماد اگر کاندیدها در اعداد/واحدها اختلاف دارند، از کاربر تأیید بگیرید (UX)، نه حدس بزنید.

۵. اگر از پروژه‌های متن‌باز الگوبرداری کنیم: چه چیزی را می‌توان برداشت؟

مؤلفه منبع مجوز چه چیزی بردارید ملاحظات
انتقال WebSocket، ورود با OTP، ذخیره نشست، Dispatcher aiobale / autobale / BaleClient MIT ✅ همه چیز؛ حتی می‌توانید فورک کنید aiobale رها شده؛ autobale فعال‌تر ادعا می‌شود. نسخه را قفل کنید
ارسال/دانلود فایل و رسانه همان کتابخانه‌ها (گزارش A: حدود ۸۰ متد) MIT آپلود و ساخت پیام صوتی اگر ایده بخش ۷.۲ را بپذیرید (بات sendVoice بفرستد) اصلاً لازم نیست
تعریف RPC و پروتوها bale-sdk (proto/) اختصاصی ❌ فقط به‌عنوان مرجع و با اجازه نویسنده؛ کپی مستقیم ممنوع راه تمیز: از کپی خود کپچر web.bale.ai پروتو بسازید. ابزارها: bbpb/blackboxprotobuf، protoscope، protoc --decode_raw
دیکود بدون .proto blackboxprotobuf (NCC Group؛ پکیج رسمی PyPI با نام bbpb) MIT تحلیل payloadهای ناشناخته wire format خودتوصیف نیست؛ نام فیلد را باید خودتان حدس بزنید
الگوی DOM و صفحه‌خوانی بله اسکرپر Playwright چت (GitHub) و baleself (Selenium) بررسی مجوز هر مخزن سلکتورها، انتظار برای بارگذاری، اسکرول سلکتورها با هر آپدیت UI می‌شکنند
سرور OpenAI-compatible برای Whisper Faster-Whisper، پروژه‌های سرور مبتنی بر آن معمولاً MIT/Apache سرور داخلی با همان /v1/audio/transcriptions همان قرارداد adapter بات؛ تغییر کد لازم نیست
نرمال‌سازی و ارزیابی فارسی مقاله و دادگان PSRB (PartAI/PSRB در Hugging Face)، hazm بررسی معیار SW-WER، فهرست خطاهای رایج فارسی دادگان عمومی فقط زیرمجموعه است

قواعد پیشنهادی الگوبرداری

  1. تمیز‌کاری حقوقی: منطق را از متن‌باز MIT بردارید و تعریف RPC را از کپچر خودتان تولید کنید (clean-room).
  2. لایه‌بندی: adapter فقط قرارداد OpenAI را بشناسد؛ هیچ import از bale* بیرون از ماژول driver/ نباشد.
  3. قفل نسخه و آینه: نسخه دقیق کتابخانه‌ها را pin و کپی داخلی نگه دارید (رهاشدن مخزن، مثل aiobale، اتفاق افتاده است).
  4. تست قرارداد: با یک «ویس طلایی» شبانه بررسی کنید پاسخ هنوز ساختار قبلی را دارد.

۶. اگر شخص ثالث بخواهیم: چه کار کنیم؟

۶.۱ ساده‌ترین کار: هر سرویس یک «پرووایدر» در stt.py

بات شما اکنون پرووایدرهای شماره‌دار با قرارداد OpenAI دارد. پس هر شخص ثالث را یا مستقیم (اگر OpenAI-compatible است) یا با یک adapter کوچک اضافه کنید. مزیت: چند ASR موازی، اجماع LLM، و حذف خودکار پرووایدر خراب (۵۰۳).

۶.۲ داده مستقل برای انتخاب: بنچمارک PSRB (مقاله arXiv:2505.21230)

مقاله «PSRB: A Comprehensive Benchmark for Evaluating Persian ASR Systems» (مرکز تحقیقات Part AI، May 2025) ده سیستم را روی گفتار واقعی (۵۸٪ خودانگیخته، ۷۱٪ غیررسمی، ۵۳٪ نویزی/تلفنی) سنجیده است.

مدل نوع CER WER SW-WER
Avanegar تجاری فارسی 8.75 19.30 15.68
Google Chirp v2 ابری چندزبانه 9.05 19.92 15.99
Aipa تجاری فارسی 10.43 24.64 19.83
Faster-Whisper large-v3 متن‌باز 13.72 33.93 26.77
Azure ابری چندزبانه 15.78 33.94 28.06
Seamless M4T v2 متن‌باز 22.30 38.85 34.76
Whisper large-v3 متن‌باز 18.92 41.49 36.97
Vosk fa 0.5 متن‌باز 23.96 44.62 39.41
NeMo FastConformer fa متن‌باز 19.42 44.85 37.58
SLPL wav2vec2 متن‌باز 19.06 46.74 39.16

نکات خواندن این جدول:

  • ASR تجاری فارسی (و Chirp 2) تقریباً ۱۴ امتیاز WER از بهترین متن‌باز جلوتر است. این یعنی ادعای «متن‌باز پایدارترین راهکار» در گزارش A دقیق نیست. متن‌باز مستقل‌تر است، نه دقیق‌تر.
  • سوگیری احتمالی: نویسندگان از Part AI هستند و از آدرس API در پاورقی مقاله، Avanegar ظاهراً محصول همان شرکت است. پس عدد Avanegar را «بالاترین حد خوش‌بینانه» بدانید.
  • داده‌ها عمومی‌اند، نه واژگان تدارکات. نام کالا، برند، واحد و اعداد در محاوره سخت‌ترین بخش‌اند و فقط آزمون روی ویس‌های خودتان تصمیم‌گیر است.
  • مقاله می‌گوید خطا در گفتار غیررسمی و لهجه‌های محلی (مثلاً مشهدی، یزدی) بیشتر است و Whisper/Seamless هالوسینیشن و بازنویسی دارند. هر دو برای متن تدارکات خطرناک‌اند، چون عدد یا واحد اشتباه معنی سفارش را عوض می‌کند.
  • ترکیب «مرتبه اول: دو سیستم متفاوت» معمولاً از «یک سیستم قوی» پایدارتر است. اجماع LLM هم برای همین است.

۶.۳ ارزیابی شخص ثالث: روش پیشنهادی (بدون وابستگی به ادعاهای فروشنده)

  1. مجموعه طلایی: ۱۰۰ ویس واقعی (حداقل ۳۰) با رونوشت انسانی و جدول کالا/تعداد/واحد.
  2. اجرای همه کاندیدها روی همان ویس‌ها: بله (دستی در گام ۰)، Avanegar، Aipa، Chirp 2، Faster-Whisper، مدل فاین‌تیون فارسی.
  3. سه معیار: CER (برای فارسی مناسب‌تر از WER)، WER و مهم‌تر F1 استخراج اقلام (نام کالا، تعداد، واحد).
  4. انتخاب بر اساس «بهبود اجماع»، نه دقت تکی: هر کاندید را به مجموعه فعلی اضافه کنید و ببینید خطای نهایی استخراج اقلام چقدر کم می‌شود.
  5. هزینه: هزینه به ازای هر ویس ۱۰–۳۰ثانیه‌ای در ماه برای حجم واقعی شما.

۶.۴ چه سرویسی را کجا بگذاریم؟ (پیشنهاد مقدماتی)

نقش کاندید چرا
پرووایدر ۱ (تجاری فارسی) Avanegar یا Aipa بهترین در بنچمارک فارسی و لهجه‌ها
پرووایدر ۲ (ابری) Chirp 2 (اگر دسترسی ممکن است) تقریباً هم‌سطح؛ مکمل متفاوت
پرووایدر ۳ (خودمیزبان) Faster-Whisper large-v3 + واژگان تدارکات مستقل؛ قابل بهبود با داده خودتان
پرووایدر ۴ (بله) کرالر بله (S3/S4/S5) تنها کاندیدی که تفاوت واقعی (آموزش‌دیده روی داده‌های متفاوت) دارد؛ ارزش آن را گام ۰ تعیین می‌کند
پشتیبان سبک Vosk فقط برای اینکه همیشه یک خروجی داشته باشیم

۷. بهترین ترکیب برای کرالر شما

۷.۱ اصول طراحی

  1. کرالر بله «یک کاندید» است، نه ستون فقرات. اگر خراب شد، سیستم باید بدون آن ادامه دهد.
  2. حداقل دو کاندید غیر بله همیشه فعال باشند تا اجماع بدون بله هم معنی داشته باشد.
  3. تصمیم بر اساس داده خودتان، نه ادعای مقاله و فروشنده.
  4. هر چیز بله پشت یک قرارداد ثابت (OpenAI-compatible) باشد تا موتور داخلی عوض شود و بات دست نخورد.
  5. داده را جمع کنید تا در بلندمدت از بله مستقل شوید (L3).

۷.۲ معماری پیشنهادی

flowchart TD
    U[کاربر: ویس] --> BOT[بات تدارکات - Bot API رسمی]
    BOT --> PRE[پیش‌پردازش: 16kHz mono، VAD، مدت]

    PRE --> P1[پرووایدر 1: ASR تجاری فارسی]
    PRE --> P2[پرووایدر 2: Chirp 2 / ابری]
    PRE --> P3[پرووایدر 3: Faster-Whisper + واژگان]
    PRE --> RELAY[رله ویس به حساب کرالر: sendVoice با file_id]

    RELAY --> CR[کرالر بله: adapter]
    CR -->|انتخاب موتور با env| E1[موتور RPC: GetTranscript]
    CR -->|فالبک| E2[موتور Playwright]
    CR --> DEL[حذف پیام رله]

    P1 --> NORM[نرمال‌سازی فارسی: ZWNJ، ارقام، یی/کاف]
    P2 --> NORM
    P3 --> NORM
    E1 --> NORM
    E2 --> NORM

    NORM --> LLM[LLM اجماع‌گیر + کاتالوگ کالا/برند/واحد]
    LLM --> CONF{اختلاف در عدد/واحد؟}
    CONF -- خیر --> OUT[ثبت استعلام]
    CONF -- بله --> ASK[از کاربر تأیید بگیر]
    ASK --> OUT
    OUT --> DATA[(ذخیره ویس + متن تأییدشده برای فاین‌تیون)]

۷.۳ ایده کلیدی: «رله» به‌جای آپلود

گزارش B فرض می‌کند کرالر ویس را به Saved Messages خودش آپلود می‌کند. راه ساده‌تر و سالم‌تر:

  1. حساب کرالر یک‌بار به بات شما /start می‌زند (گفتگوی خصوصی بات↔کرالر).
  2. بات با Bot API رسمی sendVoice(chat_id=<id حساب کرالر>, voice=<file_id همان ویس کاربر>) می‌فرستد. طبق مستندات رسمی، ارسال با file_id بدون آپلود مجدد و بدون محدودیت است. (file_id مخصوص همان بات است؛ اینجا همان بات می‌فرستد، پس مشکلی نیست.)
  3. حساب کرالر (کلاینت کاربری) آپدیت پیام جدید را می‌گیرد؛ شیء Media ویس، OutPeer و message_id همه همان‌جاست. دقیقاً سه ورودی GetTranscript (Media voice، OutPeer، MessageId).
  4. کرالر GetTranscript را صدا می‌زند، متن را می‌گیرد.
  5. پیام با deleteMessage رسمی بات (برای پیام خروجی در گفتگوی خصوصی مجاز است، تا ۴۸ ساعت) یا از سمت کرالر حذف می‌شود.

مزایا: بدون RPC آپلود؛ بدون ساخت Media از صفر؛ بدون الگوی شبه‌انسانی «آپلود فایل» روی حساب؛ ID پیام و peer واقعی‌اند.
ریسک: اینکه RPC روی ویس دریافتی هم کار کند (در اپ، دکمه روی ویس دریافتی هم هست؛ ولی تأییدش با آزمون واقعی لازم است).

۷.۴ لایه‌بندی موتور کرالر (به ترتیب اولویت)

اولویت موتور شرط یادداشت
۱ E1: RPC مستقیم (transport از aiobale/autobale، پروتوی خودساخته) RPC تأیید شد سبک (<۲۰MB)، متن خالص
۲ E1+: ورود با مرورگر، کار با پروتکل (S5) ورود/تمدید JWT ناپایدار باشد Playwright فقط برای توکن
۳ E2: Playwright کامل RPC تأیید نشد ولی دکمه وب هست رم ۳۵۰–۵۰۰MB
۴ شبیه‌ساز اندروید هیچ‌کدام ممکن نشد فقط در صورت ارزش بالای بله

اگر RPC در باندل وب بله وجود دارد، به احتمال زیاد دکمه هم در وب هست (استنباط من: گزارش‌ها می‌گویند پروتوها از کلاینت وب بازیابی شده‌اند). ولی تا خودتان نبینید فرض نکنید.

۷.۵ تقویت اجماع (جایی که بیشترین دقت را می‌گیرید)

اقدام اثر مورد انتظار هزینه
تزریق کاتالوگ کالا/برند/واحد به LLM اجماع‌گیر بیشترین کاهش خطای استخراج اقلام کم
initial_prompt/hotwords واژگان تدارکات در Faster-Whisper بهبود نام برندها و اصطلاح‌ها کم
نرمال‌سازی فارسی (ZWNJ، ارقام) پیش از اجماع کاهش اختلاف‌های ساختگی بین کاندیدها کم
قاعده «اختلاف عدد/واحد ⇒ تأیید از کاربر» حذف سفارش اشتباه متوسط (UX)
ثبت ویس + متن تأییدشده → LoRA روی Whisper استقلال بلندمدت؛ بهبود روی لهجه و واژگان شما بالا (ولی ارزشمندترین)
VAD پیش از ASR کاهش هالوسینیشن Whisper روی سکوت/نویز (پیشنهاد مقاله PSRB) کم

۷.۶ سناریوهای تصمیم

اگر… آنگاه…
گام ۰: بله بهتر از مجموعه فعلی نیست کرالر را نسازید. سرمایه را روی ASR تجاری + فاین‌تیون بگذارید.
بله کمی بهتر است (< ۱۰٪) فقط مسیر سبک E1 را بسازید؛ Playwright و شبیه‌ساز را رها کنید.
بله به‌طور چشمگیر بهتر است (> ۱۵٪) E1 + فالبک E2 + مسیر رسمی S1 را موازی دنبال کنید.
RPC پیدا نشد و دکمه وب نیست S6 فقط اگر ارزش بله زیاد باشد؛ در غیر این صورت منصرف شوید.
بله خوب است ولی ناپایدار از خروجی بله به‌عنوان برچسب‌گذار برای ساخت دادگان فاین‌تیون استفاده کنید (L3) تا وابستگی کم شود.

۸. نقشه راه پیشنهادی

روز کار خروجی دروازه
۰ آزمون دستی دقت: ۳۰ ویس واقعی را در اپ بله به متن تبدیل کنید و با کاندیدهای فعلی مقایسه کنید جدول CER/WER و F1 اقلام G0: بهبود معنی‌دار یا توقف
۰ جست‌وجوی GetTranscript در bale-sdk؛ تأیید دکمه روی web.bale.ai؛ ایمیل به بله (S1) یک صفحه یافته G1: RPC یا دکمه وجود دارد
۱ کپچر ترافیک وب و ساخت پروتوی خودتان req.bin/resp.bin، findings.md G2
۲–۳ پروتوتایپ E1 با رله بات→کرالر یک ویس → یک متن G3
۳–۴ adapter سخت‌شده (۵۰۳، سقف روزانه پایدار، قفل، لاگ) اتصال به stt.py —
۴–۵ موازی: پرووایدرهای شخص ثالث (Avanegar/Aipa/Chirp، Faster-Whisper) سنجش روی مجموعه طلایی G4: بهبود اجماع
۶–۱۰ سواک ۵۰–۱۰۰ ویس + مانیتورینگ + مجموعه طلایی شبانه گزارش پایداری G5: استقرار
ماه ۲+ جمع‌آوری داده و LoRA مدل داخلی کاهش وابستگی

KPIها: F1 استخراج اقلام، CER، نرخ اختلاف عدد/واحد، نرخ موفقیت کرالر، p95 تأخیر، هزینه به ازای ویس.


۹. ضمیمه: دستورها و نمونه‌ها

۹.۱ کشف سریع (۳۰ دقیقه)

python -m venv .v && . .v/bin/activate
pip index versions aiobale-py       # آیا واقعاً وجود دارد؟
pip index versions aiobale autobale baleclient bale-sdk

pip download bale-sdk --no-deps --no-binary :all:
tar xzf bale_sdk-*.tar.gz
grep -rniE "transcri|turing|speech|asr|stt" bale_sdk-*/proto bale_sdk-*/docs | head -50

در پایتون:

from bale import ALL_RPCS
for r in ALL_RPCS:
    s = str(r).lower()
    if any(k in s for k in ("transcri", "turing", "speech")):
        print(r)

۹.۲ ساخت پروتو از کپچر خودتان

  1. web.bale.ai را با حساب اختصاصی باز کنید، DevTools → Network (فیلتر WS و Fetch).
  2. روی ویس «تبدیل به متن» را بزنید؛ درخواست/پاسخ را ذخیره کنید.
  3. پیشوند ۵ بایتی gRPC-Web را بردارید (برای POST gRPC-Web؛ در WebSocket بله قالب را باید ببینید).
  4. protoc --decode_raw < req.bin یا protoscope.

۹.۳ اسکلت رله بات→کرالر (شبه‌کد؛ نام متدها را با کتابخانه واقعی تطبیق دهید)

# سمت بات (Bot API رسمی)
async def relay_voice_to_crawler(voice_file_id: str, crawler_user_id: int) -> int:
    msg = await bot_api("sendVoice", chat_id=crawler_user_id, voice=voice_file_id)
    return msg["message_id"]

# سمت کرالر (کلاینت کاربری) - شبه‌کد
@client.on(NewMessage)           # فقط از بات خودمان
async def on_voice(event):
    media, peer, mid = event.media, event.peer, event.id
    resp = await client.ai.GetTranscript(voice=media, outPeer=peer, messageId=mid)  # نام‌ها = استنباط
    while resp.mustWait:
        await asyncio.sleep(1.5)
        resp = await client.ai.GetTranscript(voice=media, outPeer=peer, messageId=mid)
    text = await read_download_source(resp.downloadSource)
    await client.delete_messages(peer, [mid])
    return text

۹.۴ قرارداد adapter (بدون تغییر در بات)

  • ورودی: POST /v1/audio/transcriptions (multipart: file, model, language).
  • خروجی موفق: {"text": "..."}.
  • هر خطا یا متن خالی: HTTP 503 (نه ۲۰۰ با متن خالی).
  • کلید داخلی: از env الزامی، بدون مقدار پیش‌فرض؛ مقایسه با secrets.compare_digest.
  • سقف روزانه و صف ترتیبی؛ شمارنده را پایدار (Redis/فایل) و روزانه ریست‌شونده بگیرید.

۱۰. پرسش‌های باز (قبل از شروع ساخت پاسخ دهید)

  1. GetTranscript واقعاً در bale-sdk وجود دارد؟ (۳۰ دقیقه، بخش ۹.۱)
  2. دکمه «تبدیل به متن» روی web.bale.ai برای ویس دریافتی هست؟
  3. خروجی پاسخ: متن مستقیم است یا DownloadSource که باید دانلود شود؟
  4. stt.py با ۵۰۳ و متن خالی چه می‌کند؟
  5. حجم واقعی ویس‌های شما در روز و طول متوسط آن‌ها چقدر است؟ (برای هزینه و سقف)
  6. آیا می‌توانید ۳۰–۱۰۰ ویس واقعی با رونوشت انسانی تهیه کنید؟ (بدون آن هیچ مقایسه‌ای معتبر نیست.)
  7. آیا دسترسی شبکه به Chirp 2 / ارائه‌دهندگان خارجی از سرورهای شما ممکن است؟
  8. نگهداری: چه کسی مالک کرالر است اگر بله پروتکل را عوض کرد؟

۱۱. منابع