אירוח עצמי של Whisper ו-Piper על שרת VPS
הקימו שירות תמלול וטקסט לדיבור על שרת VPS ללא GPU. המדריך מפרט עלויות משאבים, שימוש ב-faster-whisper ו-Piper, והגדרת שרת HTTP תואם OpenAI לחיבור קל לכל אפליקציה קיימת.
אירוח עצמי של המרת דיבור לטקסט וטקסט לדיבור, בקצרה
אירוח עצמי של המרת דיבור לטקסט (Speech to Text) וטקסט לדיבור (TTS) הוא סוג הבינה המלאכותית הזול ביותר שניתן להריץ על שרת בבעלותכם. תמלול מתבצע באמצעות Whisper דרך סביבת הריצה faster-whisper. סינתזה מתבצעת באמצעות Piper. שניהם עובדים על שרת VPS עם מעבד (CPU) רגיל, ללא צורך ב־GPU כלל. המודל הקטן של Whisper דורש כ-484 MB שטח דיסק, וקול של Piper הוא קובץ בודד שגודלו קטן מ-150 MB.
זו הסיבה שאודיו הוא נקודת ההתחלה המומלצת. מחולל תמונות באירוח עצמי ויצירת וידאו באירוח עצמי דורשים שניהם GPU כדי להיות שמישים. אודיו אינו דורש זאת.
מדריך זה מכסה את שני הכיוונים ואת השכבה המקשרת ביניהם. Whisper הופך אודיו לטקסט. Piper הופך טקסט לאודיו. שרת HTTP תואם OpenAI הממוקם לפני שניהם מאפשר ללקוח קיים להצביע על השרת שלכם ללא כל שינוי מלבד כתובת ה-base URL.
כל גרסה המוזכרת כאן הייתה עדכנית נכון לאוגוסט 2026.
מדוע להשתמש ב-faster-whisper ולא בחבילת ה-Whisper הרשמית
חבילת ה-whisper של OpenAI מריצה את המודל על גבי PyTorch. לעומת זאת, faster-whisper מריצה את אותם משקלי מודל על CTranslate2, מנוע הסקה (inference engine) שנכתב במיוחד עבור מודלי transformer. המשקלים זהים, ולכן התמלול שמתקבל זהה לחלוטין. ההבדל טמון אך ורק בסביבת ה-runtime.
CTranslate2 מבצע קוונטיזציה (quantization) למשקלים בזמן הטעינה, וזו הסיבה ש-compute_type="int8" הוא ארגומנט בודד ולא שלב המרה נפרד. בנוסף, אין לו תלות ב-PyTorch. ה-pip install faster-whisper מושך את CTranslate2, טוקנייזר ו-PyAV לפענוח אודיו, כך שהסביבה הווירטואלית תופסת מאות מגה-בייטים במקום מספר גיגה-בייטים. בשרת VPS עם דיסק של 40 GB, פער זה הוא ההבדל בין עבודה בנוחות לבין מחסור במקום.
להלן הנתונים הרשמיים של הפרויקט עבור מודל ה-small על גבי CPU. המבחן מתמלל 13 דקות של אודיו תוך שימוש ב-8 תהליכונים (threads) על מעבד Intel Core i7-12700K. עמודת ה-x_realtime מייצגת את 13 הדקות הללו חלקי הזמן שנמדד: 7.6 פירושו הקלטה של 13 דקות שהסתיימה תוך קצת יותר מדקה ו-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 על מעבד זה, 6.2x לעומת 5.0x, והוא עושה זאת בפחות מחצי מכמות הזיכרון. זוהי אותה משפחת ggml שנמצאת בבסיס צד ה-llama.cpp של מחסנית ה-LLM המקומית. faster-whisper עוקף אותו ברגע ש-int8 ו-batching מופעלים, ומגיע ל-15.3x, תוך צריכת 3,608 MB של RAM. לסיכום: בחרו ב-faster-whisper עבור ה-API של Python וה-batching, ובחרו ב-whisper.cpp כאשר ה-RAM הוא המגבלה שאינכם יכולים לחרוג ממנה.
השורה הראשונה היא לב העניין בסעיף זה. החבילה הרשמית מגיעה ל-1.9x מהזמן האמיתי על אותה מכונה, מה שאומר ששעת אודיו דורשת חצי שעה של זמן מעבד.
כמה שטח דיסק דורשים משקלי המודל 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 מבצע להם קוונטיזציה בזיכרון בזמן הטעינה. לכן, large-v3 תופס 3,090 MB על הדיסק, ללא קשר לשאלה אם אתם מריצים אותו ב-float16 או ב-int8. שימוש ב-int8 חוסך RAM ומשפר מהירות, אך לא חוסך מקום בדיסק.
המודלים יורדים בשימוש הראשון לתוך ~/.cache/huggingface/hub. בשרת VPS עם מחיצת root קטנה, הפנו את הנתיב למקום עם מספיק שטח פנוי באמצעות הארגומנט download_root או משתנה הסביבה HF_HOME. אחרת, ההרצה הראשונה תמלא את הדיסק והתהליך יקרוס במהלך ההורדה.
התקנת faster-whisper מבלי לפגוע ב־Python של המערכת
הפצות Ubuntu 24.04 ו־Debian 13 מגדירות את ה־Python של המערכת כ"מנוהל חיצונית" (externally managed). הרצת 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 היא הגרסה הנוכחית, שפורסמה באוקטובר 2025. הספרייה faster-whisper מפענחת אודיו באמצעות PyAV, אשר כוללת בתוכה ספריות ffmpeg משלה, לכן היא קוראת קובצי mp3 או m4a ללא צורך בבינארי ffmpeg נפרד. חבילת ה־ffmpeg לעיל מיועדת לעיבוד וידאו בהמשך מדריך זה.
בדקו את ההתקנה לפני הורדת משקולות (weights) בנפח שלושה גיגה-בייט:
~/stt/bin/python -c "from faster_whisper import WhisperModel; print('ok')"שורה המציגה ok מעידה על כך שהחבילות הותקנו בהצלחה. שגיאת ImportError המציינת את ctranslate2 מעידה על כך שהחבילה (wheel) עבור הארכיטקטורה שלכם לא הותקנה, דבר שקורה בתמונות מערכת של 32-bit ARM.
תמלול הקלטת פגישה או הערה קולית
שמרו זאת כ-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. ההרצה הראשונה מורידה את המשקולות (weights), לכן לא יודפס דבר במשך זמן מה. לאחר מכן, המודל ייטען מה-cache תוך שניות ספורות.
segments הוא מחולל (generator), לכן התמלול לא יתחיל עד שתבצעו איטרציה עליו. אנשים מודדים את זמן הקריאה ל-transcribe(), רואים שהיא חוזרת באופן מיידי, וחושבים שמשהו תקול. שום דבר אינו תקול. העבודה מתבצעת בתוך הלולאה.
vad_filter=True מריץ תחילה את Silero VAD (זיהוי פעילות קולית) ומסיר קטעים שקטים לפני ש-Whisper רואה אותם. בהקלטת פגישה עם הפסקות ארוכות, זהו השיפור המשמעותי ביותר במהירות שניתן להשיג, כיוון ש-Whisper לא מבזבז זמן כלל על אודיו שאינו מכיל דיבור. זה גם מונע לולאות של משפטים חוזרים ש-Whisper מייצר כאשר מוזנת אליו דממה והוא מנסה למצוא בה מילים.
הגדירו את cpu_threads למספר הליבות שיש לכם בפועל. הגדרה גבוהה ממספר ה-vCPU שלכם תאט את התמלול, כיוון שהת'רדים הנוספים יתחרו על אותה ליבה וה-scheduler ישלם מחיר על כל החלפת הקשר (context switch).
כתוביות עבור ספריית Jellyfin
Jellyfin קורא קובצי כתוביות חיצוניים הנמצאים לצד קובץ הווידאו ונושאים את אותו השם, לכן Movie (2019).en.srt לצד Movie (2019).mkv יופיע כערוץ אנגלית ללא צורך בקידוד מחדש (transcoding) או בבנייה מחדש של הספרייה.
תחילה יש לחלץ את האודיו. Whisper מבצע דגימה מחדש (resampling) פנימית לכל קובץ ל-16 kHz בפורמט mono, לכן הזנת קובץ בפורמט זה חוסכת עבודה משני הצדדים:
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 דקות זמן מעבד, כך שספרייה של חמישים סרטים היא משימה ללילה שלם. בתוכנית vCPU משותפת הביצועים יהיו איטיים יותר, וזהו התפקיד של nice: הרצת הכתוביות תפנה משאבים לכל פעולה אחרת שהשרת מבצע באותו זמן.
טקסט לדיבור באמצעות Piper
Piper הוא מנוע טקסט לדיבור (TTS) עצבי המריץ מודל קול בפורמט ONNX על גבי ה-CPU. המנוע כולל בתוכו את espeak-ng לצורך המרת טקסט לפונמות, כך שאין צורך בהתקנה נפרדת של רכיב פונמיזציה. הגרסה הנוכחית היא 1.6.0, שפורסמה ביולי 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 לשתי הפקודות, שכן אחרת הנגן יחפש בתיקיית העבודה ולא ימצא את הקול אם הוא אינו שם.
ה--- לפני הטקסט חשוב גם הוא. בלעדיו, כל משפט שמתחיל במקף יפורש כדגל (option) של שורת הפקודה.
הקולות מופצים ברמות איכות שונות. קול אנגלי ברמה בינונית שוקל כ-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 במקום בטרמינל שייסגר:
[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.targetsudo systemctl enable --now piper מפעיל את השירות ומבטיח את עלייתו מחדש לאחר reboot. אם פקודת ה-curl לעיל לא מחזירה דבר, journalctl -u piper -n 50 יכיל את הסיבה, כאשר קובץ קול חסר הוא הסיבה הנפוצה ביותר.
המבנה של שרת תואם OpenAI
רוב התוכנות המטפלות באודיו כבר תומכות ב-API האודיו של OpenAI: בקשת multipart POST אל /v1/audio/transcriptions עבור קובץ, ובקשת JSON POST אל /v1/audio/speech עבור משפט. אם תגישו את שני הנתיבים הללו בעצמכם, הלקוח יזדקק לשינוי אחד בלבד: כתובת ה-base URL.
Speaches הוא שרת המטפל בשני הכיוונים. הוא מריץ את faster-whisper עבור תמלול ואת Piper או Kokoro עבור דיבור, מאחורי נתיבי ה-OpenAI. הגרסה הנוכחית היא v0.9.0-rc.3 מדצמבר 2025, שטרם הגיעה ל-1.0, לכן קבעו את ה-tag של ה-image וקראו את הערות השחרור לפני שדרוג.
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ה-named volume הוא החלק שאנשים נוטים לשכוח. בלעדיו, ה-cache של המודל נשאר בתוך המכולה, כך שכל אתחול מחדש גורם להורדה חוזרת של גיגה-בייטים של משקולות לפני שהבקשה הראשונה מקבלת מענה.
שירות הדיבור זקוק לקול שהורד לפני ש-/v1/audio/speech ישיב:
uvx speaches-cli model download speaches-ai/Kokoro-82M-v1.0-ONNXלאחר מכן, כל לקוח OpenAI יעבוד עם שינוי ה-base 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 היא העדכנית, מדצמבר 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 מקבל מודל אחד, לכן כיסוי של שני הכיוונים דורש מופע שני בפורט שני עם מזהה repo של דיבור.
שאלו את השרת מה הוא טען, ולאחר מכן השתמשו במזהה זה בשדה 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 וחלופותיה מקבלים בהגדרות שלהם כתובת בסיס (base URL) תואמת OpenAI עבור אודיו, כך ששרת אחד יכול להריץ LLM מקומי עם Ollama ולסגור את המעגל הקולי בשני הקצוות.
יש לתכנן את השיהוי (latency) בכנות, כיוון ששלושת השלבים הללו רצים בזה אחר זה על אותם ליבות מעבד. שאלה באורך 10 שניות דורשת כ-1.3 שניות לתמלול לפי נתון ה-7.6x לעיל, וזה עוד לפני שהמודל קרא טוקן אחד. הוסיפו לכך יצירת טוקנים ב-CPU, וזמן הלוך-חזור הופך לאיטי מספיק כדי שבודקים יניחו שהמערכת קרסה. תמלול באצווה (batch) עובד היטב על 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, ושימוש ב-batching מעלה את המהירות ל-48.8x. שימו לב היטב למה ששני התרשימים אינם מציינים. הם מריצים מודלים שונים: שורות ה-GPU מתייחסות ל-large-v2, בעוד שורות ה-CPU מתייחסות למודל ה-small. ה-GPU לא הופך את המודל הקטן למהיר פי שישה; הוא הופך את המודל המדויק לשימושי.
מהיכן מגיעים הנתונים הללו
שני התרשימים משחזרים את ה-benchmark שפורסם ב-README של faster-whisper. האודיו הוא קובץ בודד באורך 13 דקות. שורות ה-CPU השתמשו ב-8 תהליכונים (threads) על מעבד Intel Core i7-12700K, ושורות ה-GPU השתמשו ב-CUDA 12.4 על כרטיס NVIDIA RTX 3070 Ti עם 8 GB של VRAM. עמודות השניות והזיכרון הן הנתונים שפורסמו. עמודת ה-x_realtime היא חישוב אריתמטי המבוסס עליהם: 780 שניות של אודיו חלקי הזמן שנמדד, מעוגל לספרה עשרונית אחת. עמודת הזיכרון מתייחסת ל-RAM של המערכת עבור תרשים ה-CPU ול-VRAM עבור תרשים ה-GPU.
תוכנית vCPU משותפת לא תגיע לביצועי ה-CPU הללו. ה-benchmark ההוא השתמש ב-8 תהליכונים של רכיב שולחני מהיר שהוקצו לו בלבד. התייחסו ל-7.6x כאל תקרה, ומדדו את השרת שלכם עם time על הקלטה אמיתית לפני שתתכננו סביבו משהו.
ארבעה כללי אצבע שתקפים בפועל:
- תמלול מזדמן של הקלטות אישיות: CPU, מודל small, פורמט int8. שני vCPU ייעודיים מספיקים.
- עבודת batch לילית, כגון יצירת כתוביות: 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 או קבעו גרסה (pin) לסביבת הריצה הישנה באמצעות pip install --force-reinstall ctranslate2==4.4.0. בצעו רק אחת מהפעולות הללו. ביצוע של שתיהן יחזיר אתכם לנקודת ההתחלה.
This CTranslate2 package was not compiled with CUDA support היא תקלה שונה בעלת מאפיינים דומים. ה-wheel שהותקן הוא גרסת ה-CPU בלבד. בנו מחדש את הסביבה הירטואלית על מארח ה-GPU ואפשרו ל-pip לבחור את ה-wheel המתאים שוב.
חזרה על משפטים בתמלול. משפט שחוזר על עצמו עשר פעמים הוא כמעט תמיד שקט או מוזיקה שמפוענחים בטעות כדיבור. הפעילו תחילה את vad_filter=True. אם הבעיה נמשכת, האזינו לקטע: אודיו שקט כמעט לחלוטין לא מספק ל-Whisper נקודת אחיזה, והוא חוזר על הניחוש הבטוח האחרון שלו.
זיהוי שפה שגוי. Whisper מבצע ניחוש על סמך 30 השניות הראשונות בלבד. ערך info.language_probability נמוך משמעותית מ-1.0 מעיד על חוסר ודאות, דבר שקורה כאשר הקלטה נפתחת במוזיקה או בדיבור חופף. העבירו את language="en" כאשר השפה ידועה לכם מראש.
התהליך מדפיס Killed ונעצר. זהו מנגנון ה-OOM killer של ה-kernel, ופקודת dmesg תציג את שורת ה-oom-kill המתאימה. המודל large-v3 דורש מעל 3 GB עבור המשקולות בלבד, עוד לפני הקצאת זיכרון עבודה. בשרת VPS עם 2 GB, המודל הגדול ביותר שניתן להריץ הוא small בפורמט int8.
Piper לא מוצא את הקול. הנגן מחפש בספריית העבודה אלא אם תעבירו את --data-dir. הריצו את ls בספרייה הרצויה וודאו שגם ה-.onnx וגם ה-.onnx.json קיימים, שכן חוסר באחד מהם יגרום לכשל בדיוק כמו חוסר בשניהם.
FAQ
האם ניתן להריץ המרת דיבור לטקסט על שרת VPS ללא GPU?
כן, ועבור עבודה באצוות (batch) זו הבחירה ההגיונית. בשימוש ב-faster-whisper עם המודל small בפורמט int8, מדד הביצועים שפורסם עבור הפרויקט מתמלל 13 דקות של אודיו ב-102 שניות על 8 תהליכונים של מעבד i7 שולחני, במהירות של פי 7.6 מזמן אמת, תוך צריכת 1,477 MB של זיכרון RAM. תוכנית vCPU משותפת תרוץ לאט יותר, לכן מומלץ לבצע מדידה על השרת הספציפי שלכם. המרת טקסט לדיבור באמצעות Piper קלה עוד יותר ואינה דורשת GPU בשום מקרה.
באיזה גודל מודל Whisper כדאי להשתמש?
התחילו עם small בפורמט int8. גודלו 484 MB על הדיסק והוא מטפל היטב בדיבור מוקלט וברור. עברו למודל medium כאשר מבטאים או רעשי רקע גורמים לשגיאות שאינכם יכולים להשלים איתן, ועברו למודל large-v3 רק כאשר הדיוק חשוב יותר מכל דבר אחר, שכן הוא דורש 3,090 MB של שטח דיסק ומעל 3 GB של זיכרון. בכיוון ההפוך, המודל tiny שגודלו 75.5 MB שימושי לזיהוי שפה ולבדיקת תקינות ה-pipeline, אך לא עבור תמלולים המיועדים לקריאה על ידי בני אדם.
מדוע faster-whisper מהיר יותר מחבילת Whisper המקורית?
המודל זהה, אך סביבת ההרצה שונה. החבילה המקורית מריצה את Whisper בתוך PyTorch, בעוד ש-faster-whisper מריצה את אותם משקלים על CTranslate2, מנוע שנבנה עבור הסקה (inference) של מודלי transformer, המבצע קוונטיזציה למשקלים בזמן הטעינה ואינו דורש התקנה של PyTorch. במדד הביצועים שפורסם עבור מעבדים, החבילה המקורית מגיעה למהירות של פי 1.9 מזמן אמת, לעומת פי 7.6 עבור faster-whisper בפורמט int8, תוך שימוש בפחות זיכרון.
מדוע התמלול שלי חוזר על אותו משפט שוב ושוב?
Whisper מפענח שקט או מוזיקה כדיבור ונסמך על הניחוש הבטוח האחרון שלו. הגדירו את vad_filter=True בקריאה ל-transcribe(), שמריצה תחילה את מנגנון זיהוי הפעילות הקולית Silero ומסירה קטעי שקט לפני שהמודל מעבד אותם. אם החזרתיות נמשכת, בדקו את עוצמת האודיו, שכן הקלטה שכמעט שקטה לחלוטין לא מספקת למודל נתונים לעבודה.
כיצד אוכל להקים נקודת קצה (endpoint) לאודיו התואמת ל-OpenAI על השרת שלי?
הריצו שרת המממש את POST /v1/audio/transcriptions ו-POST /v1/audio/speech, ולאחר מכן כוונו את הלקוח אליו באמצעות כתובת בסיס (base URL) חדשה. Speaches היא אפשרות אחת, המופצת כ-container image עם build עבור מעבד, המשתמשת ב-faster-whisper לתמלול וב-Piper או Kokoro לדיבור. vox-box היא אפשרות נוספת, המותקנת באמצעות pip install vox-box ומופעלת באמצעות vox-box start --huggingface-repo-id, המגישה מודל אחד לכל תהליך. אף אחת מהן אינה מפעילה אימות כברירת מחדל, לכן הגדירו האזנה ל-localhost והציבו proxy או VPN לפני השרת.