همهٔ مقاله‌ها

· Casimiro Ferreira· 5 دقیقه مطالعه

مدل‌های TTS که روی یک سیب‌زمینی اجرا می‌شوند

  • phoonnx
  • TTS
  • ONNX
  • VITS
  • self-hosted
  • OVOS

تبدیل متن به گفتار خوب نیازی به GPU یا اشتراک ابری ندارد. یک صدای طبیعی و چندزبانه می‌تواند در چیزی جا بگیرد که خجالت می‌کشید آن را سرور بنامید — همان نوع بردی که “فقط محض احتیاط” در کشوی میز نگه می‌دارید. یک سیب‌زمینی.

phoonnx چارچوب پژوهشی ما دقیقاً برای همین هدف است: صداهای کوچک مبتنی بر VITS که کاملاً آفلاین، روی CPU و روی سخت‌افزار ارزان اجرا می‌شوند، و ما همچنین می‌توانیم آن‌ها را خودمان از صفر آموزش دهیم.

کوچک چقدر کوچک است؟

بیایید به جای کلی‌گویی، یک عدد واقعی روی آن بگذاریم. ما یک صدای تولیدی phoonnx — صدای باسکی “Miro” (OpenVoiceOS/phoonnx_eu-ES_miro_espeak) — را مستقیماً از Hugging Face برداشتیم و وزن‌های موجود در گراف ONNX را شمردیم:

import onnx, numpy as np
m = onnx.load("miro_eu-ES.onnx")
print(sum(int(np.prod(i.dims)) for i in m.graph.initializer))
# 15650459

حدود ۱۵٫۶۵ میلیون پارامتر. این کل صداست — encoder، decoder، همه‌چیز — در یک فایل ۶۳ مگابایتی. صدای زنانه “Dii” از همان نسخه به دقیقاً همان عدد می‌رسد، چون آن‌ها معماری استاندارد VITS در phoonnx را به اشتراک می‌گذارند؛ شخصیت در وزن‌ها زندگی می‌کند، نه در ظرفیت اضافی.

برای درک بهتر: یک لایه‌ی واحد از یک مدل زبانی مدرن “کوچک” می‌تواند پارامترهای بیشتری از کل این سنتی‌کننده‌ی گفتار حمل کند، و با این حال روان صحبت می‌کند.

چرا VITS و چرا ONNX

VITS ستون فقرات هر صدای phoonnx است. این یک معماری سرتاسری (end-to-end) است — متن (خب، فونم‌ها) به ورودی، شکل موج به خروجی — بدون vocoder جداگانه‌ای که باید مراقبش بود و بدون حلقه‌ی خودبازگشتی (autoregressive) که نمونه‌به‌نمونه پیش می‌خزد. همین طراحی سرتاسری دقیقاً چیزی است که آن را روی یک سیب‌زمینی قابل اجرا می‌کند: یک عبور رو به جلو، سنتز موازی، تمام.

ما PyTorch را به لبه (edge) نمی‌فرستیم. صداهای آموزش‌دیده به ONNX صادر می‌شوند و از طریق onnxruntime روی CPU اجرا می‌شوند — بدون CUDA، بدون GPU، بدون رولت درایورها. onnxruntime یک موتور C++ فشرده و قابل حمل است، و یک گراف ۱۵ میلیون پارامتری کاملاً در محدوده‌ای است که یک هسته‌ی هم‌تراز Raspberry Pi آن را سریع‌تر از زمان واقعی می‌جود. نتیجه یک دستیار صوتی است که وقتی اینترنت‌تان قطع می‌شود، وقتی ارائه‌دهنده‌ی ابری دچار اختلال می‌شود، یا وقتی که صرفاً هرگز نخواستید صدای خانه‌تان از خانه بیرون برود، به صحبت کردن ادامه می‌دهد.

هوشمندی در فونم‌ها پنهان است

یک مدل صوتی کوچک می‌تواند به این تجمل دست یابد که کوچک باشد، چون phoonnx کار سنگین زبان‌شناختی را پیشاپیش، در phonemizer انجام می‌دهد. یک phonemizer (گرافم به فونم، یا G2P) متن نوشته‌شده را به دنباله‌ای از واحدهای صوتی که مدل واقعاً بیان می‌کند تبدیل می‌کند — به‌طوری‌که شبکه‌ی VITS هرگز مجبور نیست املا را یاد بگیرد، فقط صدا را.

کار ما با فونم‌ها بر پایه‌ی گرافم به IPA برای بیش از ۳۵۰ زبان و آواشناسی کلاسیک پرتغالی استوار است، که آموزش صدا برای زبان‌های کم‌منبع را بدون هفته‌ها حاشیه‌نویسی تخصصی ممکن می‌سازند.

phoonnx به‌عمد نسبت به phonemizer بی‌طرف است و ارتش کوچکی از آن‌ها را همراه خود دارد: espeak-ng، gruut، epitran، misaki، transphone (که به هزاران زبان فهرست‌شده در Glottolog دست می‌یابد)، به‌علاوه‌ی متخصص‌هایی مانند mantoq برای عربی، cotovia برای گالیسیایی، OpenJTalk برای ژاپنی، و KoG2P برای کره‌ای. آن‌ها IPA، ARPA، Pinyin، Hangul، Buckwalter تولید می‌کنند — هر چه زبان نیاز داشته باشد. حتی یک G2P چندزبانه‌ی مبتنی بر مدل هم وجود دارد که روی ByT5 ساخته شده و مانند بقیه‌ی چیزها به ONNX صادر شده است.

واگذار کردن املا به phonemizer همان ترفندی است که به یک مدل ۱۵ میلیون پارامتری اجازه می‌دهد در یک زبان کم‌منبع که هرگز آن را به‌صورت نوشته ندیده است، خوب به گوش برسد.

چارچوبی برای ساختن صداها، نه فقط اجرای آن‌ها

‏phoonnx فقط یک جعبه‌ابزار استنتاج نیست. چارچوب همراه آن phoonnx_train روشی است که با آن در وهله‌ی نخست صداها را می‌سازیم.

phoonnx_train کل خط لوله (pipeline) را پوشش می‌دهد:

  • پیش‌پردازش یک دیتاست به سبک LJSpeech به داده‌های آموزشی فونمی‌شده.
  • آموزش مولد VITS (همان حدود ۱۵٫۶۵ میلیون پارامتر) روی یک GPU مصرفی واحد یا میان‌رده — مدلی به این کوچکی نیازی به یک خوشه‌ی آموزشی ندارد.
  • صادر کردن checkpoint نهایی به ONNX با یک اسکریپت واحد، آماده برای قرار گرفتن مستقیم در onnxruntime روی یک دستگاه.

از آنجا که دستورالعمل باز است و مدل‌ها کوچک‌اند، ساختن یک صدای کاملاً جدید برای زبانی که هیچ گزینه‌ی آفلاین بازی ندارد، پروژه‌ای در مقیاس یک آخر هفته است، نه در مقیاس یک بورس پژوهشی. این‌گونه است که ما شکاف‌ها را برای زبان‌های کم‌خدمت پر می‌کنیم — باسکی، میراندی، پرتغالی اروپایی و بیشتر — به‌جای آنکه منتظر بمانیم تا یک فروشنده تصمیم بگیرد که یک زبان از نظر تجاری جالب است.

پیشاپیش به دستیار شما متصل است

لازم نیست هیچ‌کدام از این‌ها را با دست به هم بچسبانید. phoonnx یک افزونه‌ی بومی OpenVoiceOS به نام ovos-tts-plugin-phoonnx ارائه می‌دهد که صداها را برایتان دریافت و بارگذاری می‌کند:

"tts": {
  "module": "ovos-tts-plugin-phoonnx",
  "ovos-tts-plugin-phoonnx": {
    "voice": "OpenVoiceOS/phoonnx_pt-PT_miro_tugaphone"
  }
}

voice را حذف کنید و آن اولین مدلی را که با زبان شما مطابقت دارد انتخاب می‌کند. برای مدیریت صداها خارج از یک دستیار، یک CLI به نام phoonnx-voices وجود دارد که زبان‌ها را فهرست می‌کند، صداها را مرور می‌کند و مدل‌ها را از پیش دانلود می‌کند:

phoonnx-voices list-voices --lang pt-PT
phoonnx-voices download OpenVoiceOS/phoonnx_pt-PT_miro_tugaphone

و چون phoonnx به زبان ساده‌ی VITS-over-ONNX صحبت می‌کند، موتور استنتاج آن صداهای آموزش‌دیده توسط Piper، Mimic3، Coqui و MMS را نیز اجرا می‌کند — بیش از هزار زبان و صدا در مجموع. یک runtime کوچک، یک کاتالوگ عظیم، و هیچ‌کدام از آن‌ها به خانه تماس نمی‌گیرد.

نکته‌ی اصلی

فناوری صوتی که به شما احترام می‌گذارد باید همان‌جا که شما هستید اجرا شود — روی سخت‌افزار شما، تحت کنترل شما، و اگر بخواهید با کابل شبکه‌ی جدا‌شده. phoonnx شرط‌بندی ما بر این است که راه رسیدن به آنجا مدل‌های بزرگ‌تر نیست، بلکه معماری درست است که کوچک ساخته شده باشد: VITS برای ستون فقرات، phonemizer های هوشمند برای حمل بار زبان‌شناختی، ONNX برای قابلیت حمل، و یک چارچوب آموزش باز تا هر کسی بتواند کاتالوگ را رشد دهد.

پانزده و نیم میلیون پارامتر، در حال اجرا روی CPU، آموزش‌دیده روی سخت‌افزاری که هرکسی می‌تواند داشته باشد: این است خط لوله‌ی آموزشیِ پشتِ هر صدای phoonnx.