كيف تشغّل Whisper وPiper على VPS خاص بك؟
شغّل Whisper للتفريغ وPiper للنطق على VPS عادي بلا GPU. تعرّف إلى استهلاك CPU ومساحة القرص، وكيف تنشئ واجهة متوافقة مع OpenAI.
تحويل الكلام إلى نص وتحويل النص إلى كلام ذاتياً، باختصار
يُعد تحويل الكلام إلى نص وتحويل النص إلى كلام (TTS) المستضافين ذاتياً أرخص نوع من الذكاء الاصطناعي الذي يمكنك تشغيله على خادم تملكه. تُجري خدمة Whisper عملية التفريغ باستخدام بيئة التشغيل faster-whisper. وتُجري Piper عملية التوليد الصوتي. يعمل كلاهما على VPS عادي مزوّد بوحدة CPU فقط، من دون أي GPU. يحتاج نموذج Whisper الصغير إلى نحو 484 MB من مساحة القرص، بينما يكون صوت Piper ملفاً واحداً يقل حجمه كثيراً عن 150 MB.
لذلك يُعد الصوت نقطة البداية المناسبة. يتطلب كل من مولّد الصور المستضاف ذاتياً وتوليد الفيديو المستضاف ذاتياً وحدة GPU قبل أن يصبح قابلاً للاستخدام أصلاً. أما الصوت فلا يتطلب ذلك.
يغطي هذا الدليل الاتجاهين والطبقة التي تربط بينهما. يحوّل Whisper الصوت إلى نص. وتحول Piper النص إلى صوت. ويتيح خادم HTTP متوافق مع OpenAI أمام كليهما توجيه عميل موجود إلى خادمك، من دون تغيير أي شيء سوى عنوان URL الأساسي.
كانت كل الإصدارات المذكورة هنا هي الأحدث حتى August 2026.
لماذا نستخدم faster-whisper بدلاً من حزمة Whisper المرجعية
تشغّل حزمة OpenAI whisper النموذج باستخدام PyTorch. أما faster-whisper فتشغّل الأوزان نفسها باستخدام CTranslate2، وهو محرك استدلال مصمم خصيصاً لنماذج transformer. الأوزان متطابقة، لذلك يكون التفريغ النصي متطابقاً. يكمن الاختلاف بالكامل في بيئة التشغيل.
تُجري CTranslate2 عملية تكميم للأوزان أثناء تحميلها، ولذلك يكون compute_type="int8" وسيطاً واحداً وليس خطوة تحويل منفصلة. كما أنها لا تعتمد على PyTorch. تسحب pip install faster-whisper كلاً من CTranslate2 وtokenizer وPyAV لفك ترميز الصوت، لذلك يصل حجم البيئة الافتراضية إلى مئات الميغابايت بدلاً من عدة غيغابايت. على VPS بسعة قرص تبلغ 40 GB، يمثّل هذا الفرق الفارق بين مساحة مريحة ومساحة ضيقة.
فيما يلي الأرقام المنشورة من المشروع نفسه لنموذج small على CPU. يفرّغ الاختبار تسجيلاً صوتياً مدته 13 دقيقة باستخدام 8 خيوط على Intel Core i7-12700K. يمثل العمود x_realtime ناتج قسمة مدة التسجيل البالغة 13 دقيقة على الزمن المقاس: تعني القيمة 7.6 أن تسجيل مدته 13 دقيقة اكتمل خلال ما يزيد قليلاً على 1 دقيقة و40 ثانية.
The data behind this chart
[
{
"label": "openai/whisper, fp32",
"x_realtime": 1.9,
"seconds": 418,
"memory_mb": "2,335"
},
{
"label": "whisper.cpp, fp32",
"x_realtime": 6.2,
"seconds": 125,
"memory_mb": "1,049"
},
{
"label": "faster-whisper, fp32",
"x_realtime": 5.0,
"seconds": 157,
"memory_mb": "2,257"
},
{
"label": "faster-whisper, int8",
"x_realtime": 7.6,
"seconds": 102,
"memory_mb": "1,477"
},
{
"label": "faster-whisper, int8, batch 8",
"x_realtime": 15.3,
"seconds": 51,
"memory_mb": "3,608"
}
]اقرأ الصف الثاني بدقة. عند استخدام fp32، يكون whisper.cpp أسرع من faster-whisper على وحدة CPU هذه، إذ تبلغ السرعة 6.2x مقابل 5.0x، كما أنه يستهلك أقل من نصف الذاكرة. وهو ينتمي إلى عائلة ggml نفسها التي يعتمد عليها جانب llama.cpp من حزمة LLM المحلية. يتفوق faster-whisper عند تفعيل int8 والمعالجة الدفعية، إذ يصل إلى 15.3x، مقابل استهلاك 3,608 MB من RAM. لذلك، اختر faster-whisper عند الحاجة إلى Python API والمعالجة الدفعية، واختر whisper.cpp عندما تكون RAM مورداً لا يمكنك زيادته.
يوضح الصف الأول سبب أهمية هذا القسم. تصل الحزمة المرجعية إلى 1.9x من الزمن الفعلي على الجهاز نفسه، ما يعني أن ساعة من الصوت تستغرق نصف ساعة من وقت CPU.
ما مقدار مساحة القرص التي تحتاجها أوزان نموذج Whisper؟
The data behind this chart
[
{
"label": "tiny",
"weights_mb": 75.5
},
{
"label": "base",
"weights_mb": 145
},
{
"label": "small",
"weights_mb": 484
},
{
"label": "medium",
"weights_mb": "1,530"
},
{
"label": "large-v3",
"weights_mb": "3,090"
}
]هذه هي تحويلات CTranslate2 المنشورة بتنسيق float16. لاحظ ما لا يفعله compute_type="int8": لا يقلل حجم التنزيل. تصل الأوزان بتنسيق float16، ثم يجري CTranslate2 عملية quantization لها في الذاكرة عند التحميل. لذلك يستهلك large-v3 مقدار 3,090 MB على القرص، سواء شغّلته بتنسيق float16 أو int8. يوفّر لك int8 ذاكرة RAM وسرعة أكبر، لكنه لا يقلل مساحة القرص.
تُنزَّل النماذج عند أول استخدام إلى ~/.cache/huggingface/hub. إذا كان الخادم الافتراضي VPS يملك وحدة تخزين جذرية صغيرة، فحدّد مساراً آخر تتوفر فيه مساحة كافية باستخدام الوسيطة download_root أو متغير البيئة HF_HOME. وإلا سيمتلئ القرص عند التشغيل الأول، وتتوقف العملية أثناء التنزيل.
تثبيت faster-whisper دون الإخلال ببيئة Python النظام
تتعامل Ubuntu 24.04 وDebian 13 مع Python النظام باعتباره مُداراً خارجياً. يؤدي تشغيل pip install faster-whisper خارج بيئة افتراضية إلى التوقف فوراً مع ظهور:
error: externally-managed-environmentيحمي نظام الحزم بذلك الملفات التي يملكها apt. استخدم بيئة افتراضية.
sudo apt update
sudo apt install -y python3-venv ffmpeg
python3 -m venv ~/stt
~/stt/bin/pip install --upgrade pip
~/stt/bin/pip install faster-whisper==1.2.1الإصدار 1.2.1 هو الإصدار الحالي، وقد نُشر في October 2025. يفكك faster-whisper الصوت عبر PyAV، الذي يضم مكتبات ffmpeg الخاصة به. لذلك يمكنه قراءة ملف mp3 أو m4a من دون ملف ffmpeg ثنائي منفصل. حزمة ffmpeg أعلاه مخصصة لمعالجة الفيديو لاحقاً في هذا الدليل.
تحقق من التثبيت قبل تنزيل ثلاثة غيغابايت من الأوزان:
~/stt/bin/python -c "from faster_whisper import WhisperModel; print('ok')"يعني ظهور سطر يحتوي على ok أن ملفات wheel ثُبّتت بنجاح. يعني ظهور ImportError الذي يسمّي ctranslate2 أن ملف wheel الخاص ببنيتك لم يُثبّت. يحدث ذلك مع صور ARM ذات 32-bit.
نسخ تسجيل اجتماع أو مذكرة صوتية
احفظ هذا باسم transcribe.py:
from faster_whisper import WhisperModel
model = WhisperModel("small", device="cpu", compute_type="int8", cpu_threads=4)
segments, info = model.transcribe("meeting.m4a", beam_size=5, vad_filter=True)
print("language: %s (%.2f)" % (info.language, info.language_probability))
for segment in segments:
print("[%.2fs -> %.2fs] %s" % (segment.start, segment.end, segment.text))شغّله باستخدام ~/stt/bin/python transcribe.py. ينزّل التشغيل الأول الأوزان، لذلك لا يظهر أي ناتج لبعض الوقت. بعد ذلك، يُحمّل النموذج من ذاكرة التخزين المؤقت خلال بضع ثوانٍ.
segments مولّد، لذلك لا تبدأ عملية النسخ حتى تكرّر عليه. يقيس بعض الأشخاص زمن استدعاء transcribe()، ويرونه يعود فوراً، فيظنون أن هناك عطلاً. لا يوجد عطل. يحدث العمل داخل الحلقة.
يشغّل vad_filter=True أداة Silero VAD، أي اكتشاف النشاط الصوتي، أولاً، ويحذف المقاطع الصامتة قبل أن تصل إلى Whisper. في تسجيل اجتماع يحتوي على فترات صمت طويلة، يمثّل ذلك أكبر تحسن منفرد متاح في السرعة، لأن Whisper لا يقضي أي وقت على الصوت الذي لا يحتوي على كلام. كما يمنع حلقات تكرار الجمل التي ينتجها Whisper عندما يُمرَّر إليه الصمت ويحاول العثور على كلمات فيه.
اضبط cpu_threads على عدد الأنوية المتاحة فعلياً لديك. يؤدي ضبطه على قيمة أعلى من عدد vCPU لديك إلى إبطاء النسخ، لأن الخيوط الإضافية تتنافس على النواة نفسها، ويتحمل المجدول تكلفة كل عملية تبديل.
ترجمات مكتبة Jellyfin
يقرأ Jellyfin ملفات الترجمة الخارجية الموجودة بجوار ملف الفيديو والتي تحمل الاسم نفسه، لذلك يظهر Movie (2019).en.srt بجوار Movie (2019).mkv كمسار باللغة الإنجليزية من دون تحويل للترميز ومن دون إعادة بناء المكتبة.
استخرج الصوت أولاً. يعيد Whisper أخذ عينات كل شيء داخلياً إلى صوت أحادي بقيمة 16 kHz، لذلك فإن تمرير صوت أحادي بقيمة 16 kHz يقلل العمل في الطرفين:
ffmpeg -i "Movie (2019).mkv" -vn -ac 1 -ar 16000 -c:a pcm_s16le "Movie (2019).wav"لا يحتوي faster-whisper على كاتب لملفات SRT، لذلك نسّق المقاطع بنفسك. احفظ هذا الملف باسم srt.py:
import sys
from faster_whisper import WhisperModel
def ts(seconds):
ms = int(round(seconds * 1000))
hours, ms = divmod(ms, 3600000)
minutes, ms = divmod(ms, 60000)
secs, ms = divmod(ms, 1000)
return "%02d:%02d:%02d,%03d" % (hours, minutes, secs, ms)
model = WhisperModel("small", device="cpu", compute_type="int8")
segments, info = model.transcribe(sys.argv[1], vad_filter=True)
with open(sys.argv[2], "w", encoding="utf-8") as out:
for index, segment in enumerate(segments, start=1):
out.write("%d\n" % index)
out.write("%s --> %s\n" % (ts(segment.start), ts(segment.end)))
out.write("%s\n\n" % segment.text.strip())ثم مرّر عناصر المكتبة واحداً تلو الآخر:
for f in /srv/media/films/*.mkv; do
ffmpeg -nostdin -y -i "$f" -vn -ac 1 -ar 16000 -c:a pcm_s16le "${f%.mkv}.wav"
nice -n 15 ~/stt/bin/python srt.py "${f%.mkv}.wav" "${f%.mkv}.en.srt"
rm -f "${f%.mkv}.wav"
doneإن -nostdin ليس للزينة. من دونه يقرأ ffmpeg من الإدخال القياسي للحلقة، فيستهلك بقية قائمة الملفات، وتتوقف الحلقة بعد فيلم واحد من دون عرض رسالة خطأ.
قدّر الوقت قبل أن تبدأ. وفق سرعة 7.6x المذكورة أعلاه، يحتاج فيلم مدته 100 دقيقة إلى نحو 13 دقيقة من وقت المعالجة على CPU، لذلك تستغرق مكتبة تضم خمسين فيلماً ليلة كاملة. وعلى خطة vCPU مشتركة ستكون العملية أبطأ من ذلك، ولهذا يُستخدم nice: عندها تفسح عملية إنشاء الترجمات المجال لما ينفذه الخادم فعلياً من مهام أخرى.
تحويل النص إلى كلام باستخدام Piper
Piper هو محرّك عصبي لتحويل النص إلى كلام، ويشغّل نموذج صوت ONNX على CPU. يضم espeak-ng لتحويل النص إلى وحدات صوتية، لذلك لا تحتاج إلى تثبيت أداة منفصلة للتحويل الصوتي. الإصدار الحالي هو 1.6.0، وقد نُشر في July 2026.
python3 -m venv ~/tts
~/tts/bin/pip install piper-tts==1.6.0
~/tts/bin/python -m piper.download_voices en_US-lessac-medium
~/tts/bin/python -m piper -m en_US-lessac-medium -f test.wav -- 'This is a test.'يكتب download_voices ملفين في دليل العمل: أوزان .onnx وملف إعداد .onnx.json يحتوي على معدل أخذ العينات وقائمة المتحدثين. يجب أن يبقيا معاً. إذا احتفظت بالأصوات في مسار ثابت، مرّر --data-dir إلى كلا الأمرين، لأن المشغّل يبحث في دليل العمل افتراضياً، ولن يعثر على صوت ليس موجوداً فيه.
تؤثر -- التي تسبق النص أيضاً. من دونها، تُفسَّر أي جملة تبدأ بواصلة على أنها خيار لسطر الأوامر.
تتوفر الأصوات بمستويات جودة متعددة. يبلغ حجم الصوت الإنجليزي المتوسط نحو 60 MB، بينما يبلغ حجم الصوت العالي ضعف ذلك تقريباً. تعني الجودة الأعلى نموذجاً أكبر واستهلاكاً أكبر لـCPU في كل ثانية من الكلام، ولا تعني متحدثاً مختلفاً.
لا تستدعِ CLI داخل حلقة. يحمّل النموذج عند كل استدعاء، ويشكّل تحميل النموذج معظم تكلفة الجملة القصيرة. شغّل خادم HTTP بدلاً من ذلك:
~/tts/bin/pip install 'piper-tts[http]==1.6.0'
~/tts/bin/python -m piper.http_server -m en_US-lessac-medium --host 127.0.0.1 --port 5000curl -X POST -H 'Content-Type: application/json' \
-d '{ "text": "This is a test." }' \
-o test.wav localhost:5000/synthesizeإذا أمكنك تشغيل test.wav، فهذا يعني أنه يعمل. يتبع ذلك المسار بنية Piper الخاصة، وليس بنية OpenAI، لذلك لن يتصل به عميل يتوقع /v1/audio/speech. يعالج القسم التالي هذه المشكلة.
أبقِه قيد التشغيل باستخدام ملف وحدة بدلاً من جلسة طرفية ستغلقها:
[Unit]
Description=Piper text to speech HTTP server
After=network-online.target
[Service]
User=piper
ExecStart=/home/piper/tts/bin/python -m piper.http_server -m en_US-lessac-medium --data-dir /home/piper/voices --host 127.0.0.1 --port 5000
Restart=on-failure
[Install]
WantedBy=multi-user.targetيبدأ sudo systemctl enable --now piper تشغيله ويعيد تشغيله بعد إعادة الإقلاع. إذا لم يُرجع أمر curl أعلاه أي نتيجة، فإن journalctl -u piper -n 50 يحتوي على السبب، ويكون ملف الصوت المفقود هو السبب المعتاد.
بنية الخادم المتوافق مع OpenAI
تتحدث معظم البرامج التي تتعامل مع الصوت مسبقاً مع واجهة OpenAI الصوتية: طلب POST متعدد الأجزاء إلى /v1/audio/transcriptions لإرسال ملف، وطلب POST بصيغة JSON إلى /v1/audio/speech لإرسال جملة. قدّم هذين المسارين بنفسك، ولن يحتاج العميل إلا إلى تغيير واحد، وهو عنوان URL الأساسي.
Speaches خادم واحد يدعم الاتجاهين. فهو يشغّل faster-whisper لتحويل الكلام إلى نص، وPiper أو Kokoro لتحويل النص إلى كلام، خلف مسارات OpenAI. الإصدار الحالي هو v0.9.0-rc.3 من December 2025، وما زال قبل الإصدار 1.0. لذلك ثبّت وسم الصورة، واقرأ ملاحظات الإصدار قبل الترقية.
curl --silent --remote-name https://raw.githubusercontent.com/speaches-ai/speaches/master/compose.yaml
curl --silent --remote-name https://raw.githubusercontent.com/speaches-ai/speaches/master/compose.cpu.yaml
export COMPOSE_FILE=compose.cpu.yaml
docker compose up --detachصيغة الحاوية المفردة، إذا كنت تفضّل عدم الاحتفاظ بملفات compose:
docker run --rm --detach --publish 8000:8000 --name speaches \
--volume hf-hub-cache:/home/ubuntu/.cache/huggingface/hub \
ghcr.io/speaches-ai/speaches:latest-cpuالحجم المسمّى هو الجزء الذي يغفل عنه المستخدمون. بدونه، تبقى ذاكرة التخزين المؤقت للنماذج داخل الحاوية، لذلك تعيد كل إعادة تشغيل تنزيل gigabytes من الأوزان قبل أن يستجيب الخادم للطلب الأول.
تحتاج خدمة الكلام إلى تنزيل صوت قبل أن يستجيب /v1/audio/speech:
uvx speaches-cli model download speaches-ai/Kokoro-82M-v1.0-ONNXبعد ذلك، يعمل أي عميل من عملاء OpenAI بعد تغيير عنوان URL الأساسي:
from pathlib import Path
from openai import OpenAI
openai = OpenAI(base_url="http://localhost:8000/v1", api_key="cant-be-empty")
res = openai.audio.speech.create(
model="speaches-ai/Kokoro-82M-v1.0-ONNX",
voice="af_heart",
input="Hello, world!",
response_format="mp3",
speed=1,
)
with Path("output.mp3").open("wb") as f:
f.write(res.response.read())العنصر النائب api_key مطلوب لأن مكتبة عميل OpenAI ترفض إرسال طلب من دونه. يتجاهل الخادم قيمته إلى أن تضبط مفتاحاً فعلياً.
vox-box هو المشروع الآخر الذي يستحق الذكر هنا. وهو حزمة Python لا حاوية، ويقدّم المسارات نفسها باستخدام Whisper أو FunASR أو Bark أو Dia أو CosyVoice خلفها. الإصدار 0.0.21 هو الحالي، وقد صدر في December 2025، ويحتاج إلى Python 3.10 أو أحدث.
python3 -m venv ~/voice
~/voice/bin/pip install vox-box==0.0.21
~/voice/bin/vox-box start --huggingface-repo-id Systran/faster-whisper-small \
--data-dir ~/voice/data --host 127.0.0.1 --port 8010يربط المثال الخاص بالمشروع المنفذ 80، وهذا يتطلب حساب root. استخدام منفذ مرتفع خلف reverse proxy هو التصميم الأفضل على خادم ينفّذ مهام أخرى. يقبل vox-box start نموذجاً واحداً، لذلك يتطلب دعم الاتجاهين تشغيل نسخة ثانية على منفذ ثانٍ مع معرّف مستودع خاص بخدمة الكلام.
اطلب من الخادم عرض ما حمّله، ثم استخدم ذلك المعرّف في الحقل model:
curl http://127.0.0.1:8010/v1/modelscurl http://127.0.0.1:8010/v1/audio/transcriptions \
-H "Content-Type: multipart/form-data" \
-F file="@voice-note.m4a" \
-F model="faster-whisper-small"تعني هيئة JSON بالشكل {"text": "..."} أن المسار بأكمله يعمل. يشير ظهور 404 عند استخدام اسم النموذج إلى أنك خمّنت الاسم بدلاً من قراءة ناتج /v1/models.
لا يفعّل أي من هذه الخوادم المصادقة افتراضياً. اربطها بالعنوان 127.0.0.1، ثم صِل إليها عبر VPN أو reverse proxy يطلب بيانات الاعتماد. إنّ ترك /v1/audio/transcriptions مفتوحاً على عنوان IP عاماً يوفّر CPU مجانياً لأي شخص يعثر عليه، وسيعثر عليه.
واجهة صوتية أمامية لمساعد مستضاف ذاتياً
بعد أن تستجيب المساران على نقاط نهاية OpenAI، يمكن لواجهة محادثة تشغيلهما. تقبل Open WebUI وبدائله عنوان URL أساسياً متوافقاً مع OpenAI للصوت ضمن إعداداتها، لذلك يمكن لصندوق واحد أن يشغّل نموذج LLM محلياً باستخدام Ollama ويغلق حلقة الصوت من الطرفين.
قدّر زمن الاستجابة بواقعية، لأن هذه الخطوات الثلاث تُنفَّذ بالتتابع على الأنوية نفسها. يستغرق سؤال مدته 10 ثوانٍ نحو 1.3 ثانية لتفريغه نصياً وفق قيمة 7.6x المذكورة أعلاه، وذلك قبل أن يقرأ النموذج رمزاً واحداً. أضف توليد الرموز باستخدام CPU، وستصبح دورة الطلب والاستجابة بطيئة بما يكفي ليظن المختبرون أن النظام قد تعطل. تفريغ التسجيلات دفعة واحدة مريح على CPU. أما المحادثة فليست كذلك، وعند هذه النقطة يبدأ VPS مزوداً بوحدة GPU في تبرير تكلفته.
متى تستحق GPU الاستخدام فعلياً؟
The data behind this chart
[
{
"label": "openai/whisper, fp16",
"x_realtime": 5.5,
"seconds": 143,
"memory_mb": "4,708"
},
{
"label": "faster-whisper, fp16",
"x_realtime": 12.4,
"seconds": 63,
"memory_mb": "4,525"
},
{
"label": "faster-whisper, int8",
"x_realtime": 13.2,
"seconds": 59,
"memory_mb": "2,926"
},
{
"label": "faster-whisper, int8, batch 8",
"x_realtime": 48.8,
"seconds": 16,
"memory_mb": "4,500"
}
]على GPU، يعمل النموذج الكبير بوضع int8 بسرعة تعادل 13.2x من الزمن الفعلي، ويستخدم 2,926 MB من VRAM، بينما يرفع تنفيذ الدُفعات السرعة إلى 48.8x. انتبه جيداً إلى ما لا يوضحه المخططان. فهما يستخدمان نموذجين مختلفين: صفوف GPU تستخدم large-v2، وصفوف CPU تستخدم small. لا تجعل GPU النموذج الصغير أسرع بست مرات. بل يجعل النموذج الدقيق قابلاً للاستخدام.
مصدر هذه الأرقام
يعيد كلا المخططين إنتاج الاختبار المنشور في README الخاص بـ faster-whisper. الملف الصوتي عبارة عن ملف واحد مدته 13 دقيقة. استخدمت صفوف CPU 8 خيوط على Intel Core i7-12700K، بينما استخدمت صفوف GPU CUDA 12.4 على NVIDIA RTX 3070 Ti مع 8 GB من VRAM. أعمدة الثواني والذاكرة هي الأرقام المنشورة. أما عمود x_realtime فهو ناتج حسابي مبني عليها: 780 ثانية من الصوت مقسومة على الزمن المقاس، مع التقريب إلى منزلة عشرية واحدة. يمثل عمود الذاكرة ذاكرة النظام في مخطط CPU وVRAM في مخطط GPU.
لن تحقق خطة vCPU مشتركة أرقام CPU. فقد استخدم ذلك الاختبار 8 خيوط من معالج مكتبي سريع مخصصة له بالكامل. اعتبر 7.6x حداً أقصى، ثم اختبر جهازك بنفسك باستخدام time على تسجيل حقيقي قبل أن تبني أي خطة عليه.
أربع قواعد تقريبية تصمد عملياً:
- التفريغ الصوتي العرضي لتسجيلاتك: CPU، وsmall، وint8. يكفي 2 vCPU مخصصان.
- المعالجة الدفعية الليلية، مثل إنشاء ملف ترجمة: CPU، وsmall أو medium، وint8، ضمن
nice. - أي استخدام تفاعلي، أو معالجة مكتبة كاملة خلال مساء واحد: GPU.
- Piper: CPU دائماً. لا يستفيد نموذج صوت بهذا الحجم تقريباً من GPU.
إذا كنت تحاول تحديد المهام الأخرى التي يمكن للمعدات نفسها تشغيلها، فـالسؤال الأوسع حول نماذج AI التي يمكنك استضافتها ذاتياً يوضح الأحجام التي تناسب هذه المعدات وتلك التي لا تناسبها.
أنماط الفشل، مع النصوص التي ستظهر لك
error: externally-managed-environment عند التثبيت. تحمي التوزيعة Python النظام. أنشئ بيئة افتراضية كما هو موضح أعلاه.
عدم تطابق cuDNN على جهاز GPU. يظهر الفشل بهذا الشكل:
Unable to load any of {libcudnn_ops.so.9.1.0, libcudnn_ops.so.9.1, libcudnn_ops.so.9, libcudnn_ops.so}
Invalid handle. Cannot load symbol cudnnCreateTensorDescriptorيتطلب CTranslate2 4.5.0 والإصدارات الأحدث منه cuDNN 9 مع CUDA 12، بينما يحتوي المضيف على cuDNN 8. ثبّت cuDNN 9، أو ثبّت إصدار runtime الأقدم باستخدام pip install --force-reinstall ctranslate2==4.4.0. نفّذ أحد الخيارين فقط. تنفيذ الخيارين معاً يعيدك إلى المشكلة نفسها.
This CTranslate2 package was not compiled with CUDA support خطأ مختلف له مظهر مشابه. حزمة wheel المثبّتة هي إصدار CPU فقط. أعد إنشاء البيئة الافتراضية على مضيف GPU، ودَع pip يختار حزمة wheel من جديد.
تكرار العبارات في النص المفرغ. تكرار جملة 10 مرات يعني غالباً أنه جرى فك ترميز الصمت أو الموسيقى على أنها كلام. فعّل vad_filter=True أولاً. إذا استمر التكرار، استمع إلى المقطع: لا يوفّر الصوت شبه الصامت نقطة ارتكاز لـWhisper، لذلك يكرر آخر تخمين واثق له.
اكتشاف اللغة الخطأ. يخمّن Whisper اللغة من أول 30 ثانية فقط. تعني قيمة info.language_probability أقل بكثير من 1.0 أنه غير متأكد، ويحدث ذلك عندما يبدأ التسجيل بالموسيقى أو بتداخل أصوات متعددة. مرّر language="en" عندما تكون الإجابة معروفة لديك مسبقاً.
تطبع العملية Killed ثم تتوقف. هذا هو قاتل نفاد الذاكرة في النواة، وسيعرض dmesg السطر المطابق لعملية oom-kill. يحتاج large-v3 إلى أكثر من 3 GB للأوزان وحدها، قبل احتساب أي ذاكرة عمل. في VPS بسعة 2 GB، يكون small مع int8 أكبر نموذج يمكن تشغيله.
لا يستطيع Piper العثور على الصوت. يبحث المشغّل في دليل العمل ما لم تمرّر --data-dir. شغّل ls على الدليل المتوقع، وتأكد من وجود .onnx و.onnx.json معاً، لأن وجود أحدهما دون الآخر يفشل تماماً كغيابهما معاً.
FAQ
هل يمكنني تشغيل تحويل الكلام إلى نص على VPS يعمل بالمعالج فقط؟
نعم، وهذا خيار مناسب لأعمال المعالجة الدفعية. عند استخدام faster-whisper مع النموذج small بدقة int8، يوضح المعيار المنشور للمشروع أنه يحوّل 13 دقيقة من الصوت إلى نص خلال 102 ثانية باستخدام 8 خيوط على معالج i7 مكتبي، أي نحو 7.6x من الزمن الحقيقي، وباستخدام 1,477 MB من الذاكرة العشوائية. تعمل خطة vCPU مشتركة بسرعة أقل من ذلك، لذا قِس الأداء على خادمك. أما تحويل النص إلى كلام باستخدام Piper فهو أسهل، ولا يحتاج إلى GPU تحت أي ظرف.
ما حجم نموذج Whisper الذي ينبغي أن أستخدمه؟
ابدأ بالنموذج small مع int8. يشغل 484 MB على القرص، ويتعامل جيداً مع الكلام المسجّل والواضح. انتقل إلى medium عندما تسبب اللهجات أو ضوضاء الخلفية أخطاء لا يمكنك قبولها، واستخدم large-v3 فقط عندما تكون الدقة أهم من كل شيء آخر، لأنه يحتاج إلى 3,090 MB من مساحة القرص وأكثر من 3 GB من الذاكرة. أما tiny، بحجم 75.5 MB، فهو مفيد لاكتشاف اللغة واختبار مسار المعالجة، وليس لإنتاج نصوص سيقرأها شخص.
لماذا يُعد faster-whisper أسرع من حزمة Whisper الأصلية؟
النموذج نفسه. أما بيئة التشغيل فمختلفة. تشغّل الحزمة المرجعية Whisper ضمن PyTorch، بينما يشغّل faster-whisper الأوزان نفسها على CTranslate2، وهو محرك مصمم للاستدلال على نماذج transformer، ويكمّم الأوزان عند تحميلها ولا يحتاج إلى تثبيت PyTorch. في معيار الأداء المنشور على CPU، يحقق ذلك 1.9x من الزمن الحقيقي للحزمة المرجعية مقابل 7.6x لـfaster-whisper عند استخدام int8، مع استهلاك ذاكرة أقل.
لماذا يكرر النص المفرّغ الجملة نفسها مراراً؟
يحوّل Whisper الصمت أو الموسيقى إلى كلام، ثم يعود إلى آخر تخمين واثق لديه. اضبط vad_filter=True في استدعاء transcribe()، إذ يشغّل ذلك أولاً اكتشاف النشاط الصوتي باستخدام Silero، ويزيل المقاطع الصامتة قبل أن يراها النموذج. إذا استمر التكرار، فتحقق من مستوى الصوت، لأن التسجيل الذي يكاد يكون صامتاً بالكامل لا يوفّر للنموذج ما يعالجه.
كيف أحصل على نقطة نهاية صوت متوافقة مع OpenAI على خادمي؟
شغّل خادماً يطبّق POST /v1/audio/transcriptions وPOST /v1/audio/speech، ثم وجّه العميل إليه باستخدام عنوان أساسي جديد. يُعد Speaches أحد الخيارات، وهو منشور كصورة حاوية تتضمن إصداراً يعمل على CPU، ويستخدم faster-whisper لتحويل الكلام إلى نص وPiper أو Kokoro لتحويل النص إلى كلام. ويُعد vox-box خياراً آخر، ويُثبّت باستخدام pip install vox-box ويُشغّل باستخدام vox-box start --huggingface-repo-id، ويخدم نموذجاً واحداً لكل عملية. لا يفعّل أي منهما المصادقة افتراضياً، لذا اربطه بـlocalhost وضع proxy أو VPN أمامه.