SSD Nodes Learn 🎉 VPS $5.50/월부터
가이드 Matt Connor작성자 Matt Connor · 업데이트됨 2026-08-13

VPS에서 Whisper와 Piper로 STT 및 TTS 자체 호스팅하기

GPU 없이 CPU 기반 VPS에서 faster-whisper와 Piper를 실행하는 방법을 안내합니다. 디스크 점유율을 최소화하는 모델 최적화 기법과 기존 클라이언트에서 바로 사용할 수 있는 OpenAI 호환 API 서버 구축 과정을 상세히 설명합니다.

자체 호스팅 음성 인식 및 음성 합성 요약

자체 호스팅 음성 인식(STT)과 음성 합성(TTS)은 직접 운영하는 서버에서 실행할 수 있는 가장 저렴한 AI 서비스입니다. 음성 인식은 faster-whisper 런타임을 통해 Whisper를 실행하며, 음성 합성은 Piper를 사용합니다. 두 서비스 모두 GPU가 없는 일반적인 CPU 기반 VPS에서 원활하게 작동합니다. 소형 Whisper 모델은 약 484 MB의 디스크 공간을 차지하며, Piper 음성 데이터는 150 MB 미만의 파일 하나로 구성됩니다.

이러한 이유로 오디오 관련 서비스가 시작하기에 가장 적합합니다. 자체 호스팅 이미지 생성이나 자체 호스팅 비디오 생성은 실사용을 위해 GPU가 필수적이지만, 오디오 서비스는 그렇지 않습니다.

이 가이드에서는 두 가지 방향의 서비스와 이를 연결하는 계층을 다룹니다. Whisper는 오디오를 텍스트로 변환하고, Piper는 텍스트를 오디오로 변환합니다. 두 서비스 앞에 OpenAI 호환 HTTP 서버를 배치하면, 기존 클라이언트의 base URL만 변경하여 사용자의 서버를 바로 이용할 수 있습니다.

여기에 명시된 모든 버전은 2026년 8월 기준으로 최신 상태입니다.

왜 reference Whisper 패키지가 아닌 faster-whisper인가

OpenAI의 whisper 패키지는 PyTorch에서 모델을 실행합니다. faster-whisper는 트랜스포머 모델 전용 추론 엔진인 CTranslate2에서 동일한 모델 가중치를 실행합니다. 가중치가 동일하므로 결과물인 전사(transcript) 내용도 같습니다. 차이점은 전적으로 런타임에 있습니다.

CTranslate2는 가중치를 로드할 때 양자화(quantize)를 수행하므로 compute_type="int8"은 별도의 변환 단계가 아닌 하나의 인자로 처리됩니다. 또한 PyTorch 의존성이 없습니다. pip install faster-whisper는 CTranslate2, 토크나이저, 오디오 디코딩을 위한 PyAV를 가져오므로 가상 환경의 크기가 수 기가바이트가 아닌 수백 메가바이트 수준으로 유지됩니다. 40 GB 디스크를 사용하는 VPS 환경에서 이 차이는 여유로운 공간과 부족한 공간을 가르는 기준이 됩니다.

다음은 CPU 환경에서 small 모델에 대해 프로젝트 측이 공개한 수치입니다. 이 벤치마크는 Intel Core i7-12700K에서 8개의 스레드를 사용하여 13분 분량의 오디오를 전사합니다. x_realtime 열은 13분을 측정된 시간으로 나눈 값입니다. 예를 들어 7.6은 13분짜리 녹음 파일을 1분 40초 조금 넘는 시간에 완료했음을 의미합니다.

ChartWhisper small on CPU, 13 minutes of audio (published project figures)
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는 이 CPU에서 6.2x의 속도로 faster-whisper의 5.0x보다 빠르며, 메모리 사용량도 절반 미만입니다. 이는 로컬 LLM 스택의 llama.cpp 측을 지탱하는 것과 동일한 ggml 계열입니다. faster-whisper는 int8과 배치 처리를 활성화하면 15.3x에 도달하며, 이때 3,608 MB의 RAM을 사용합니다. 따라서 Python API와 배치 처리가 필요하다면 faster-whisper를 선택하고, RAM 제약이 절대적이라면 whisper.cpp를 선택하십시오.

첫 번째 행이 이 섹션의 핵심입니다. reference 패키지는 동일한 머신에서 1.9x의 실시간 성능을 보이며, 이는 1시간 분량의 오디오를 처리하는 데 30분의 CPU 시간이 소요됨을 의미합니다.

Whisper 모델 가중치는 디스크 공간을 얼마나 차지합니까?

Chartfaster-whisper model weights on disk (Systran CTranslate2 conversions, float16)
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"
  }
]

위 수치는 float16 형식으로 변환된 CTranslate2 모델 기준입니다. compute_type="int8"이 수행하지 않는 작업에 유의하십시오. 다운로드 크기를 줄여주지는 않습니다. 가중치는 float16 상태로 다운로드되며 CTranslate2가 로드 시점에 메모리 내에서 양자화를 수행하므로, large-v3 모델은 float16으로 실행하든 int8로 실행하든 디스크에서 3,090 MB를 차지합니다. int8은 RAM 사용량과 속도를 개선할 뿐 디스크 공간을 절약하지는 않습니다.

모델은 처음 사용할 때 ~/.cache/huggingface/hub 경로로 다운로드됩니다. 루트 볼륨이 작은 VPS를 사용하는 경우, download_root 인수나 HF_HOME 환경 변수를 사용하여 공간이 충분한 위치로 경로를 지정하십시오. 그렇지 않으면 첫 실행 시 디스크가 가득 차서 다운로드 도중 프로세스가 종료될 수 있습니다.

시스템 Python을 손상시키지 않고 faster-whisper 설치하기

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은 2025년 10월에 릴리스된 최신 버전입니다. faster-whisper는 자체 ffmpeg 라이브러리를 포함하는 PyAV를 통해 오디오를 디코딩하므로, 별도의 ffmpeg 바이너리 없이도 mp3나 m4a 파일을 읽을 수 있습니다. 위에서 언급한 ffmpeg 패키지는 이 가이드의 후반부에서 다룰 비디오 작업을 위한 것입니다.

3GB에 달하는 가중치 파일을 다운로드하기 전에 설치 상태를 확인하십시오.

~/stt/bin/python -c "from faster_whisper import WhisperModel; print('ok')"

ok라는 줄이 출력되면 휠(wheel)이 정상적으로 설치된 것입니다. ctranslate2을 명시하는 ImportError 오류가 발생한다면 해당 아키텍처용 휠이 설치되지 않은 것이며, 이는 32비트 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로 실행하십시오. 첫 실행 시에는 가중치를 다운로드하므로 한동안 아무것도 출력되지 않습니다. 그 이후부터는 캐시에서 모델을 불러오므로 몇 초 안에 완료됩니다.

segments는 제너레이터이므로 반복문을 돌리기 전까지는 전사가 시작되지 않습니다. transcribe() 호출이 즉시 반환되는 것을 보고 무언가 고장 났다고 생각하는 경우가 많지만, 고장 난 것이 아닙니다. 실제 작업은 루프 안에서 수행됩니다.

vad_filter=True은 Silero VAD(음성 활동 감지)를 먼저 실행하여 Whisper가 처리하기 전에 무음 구간을 제거합니다. 긴 공백이 포함된 회의 녹음의 경우, Whisper가 음성이 없는 오디오를 처리하는 데 시간을 낭비하지 않으므로 가장 큰 속도 향상을 얻을 수 있습니다. 또한 Whisper가 무음 구간을 입력받았을 때 단어를 찾으려다 발생하는 문장 반복 루프 현상도 억제합니다.

cpu_threads는 실제 보유한 코어 수로 설정하십시오. vCPU 개수보다 높게 설정하면 추가 스레드가 동일한 코어를 두고 경쟁하게 되고 스케줄러가 컨텍스트 스위칭 비용을 지불하게 되어 전사 속도가 오히려 느려집니다.

Jellyfin 라이브러리용 자막 생성

Jellyfin은 비디오 파일 옆에 위치하며 이름이 동일한 외부 자막 파일을 읽어 들입니다. 따라서 Movie (2019).en.srtMovie (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 시간이 필요하므로, 영화 50편 규모의 라이브러리는 하룻밤 정도 걸리는 작업입니다. 공유 vCPU 플랜에서는 이보다 더 느리게 작동하며, 이때 nice을 사용하면 자막 생성 작업이 서버의 다른 작업에 우선순위를 양보하게 됩니다.

Piper를 이용한 텍스트 음성 변환(TTS)

Piper는 CPU에서 ONNX 음성 모델을 실행하는 신경망 기반 텍스트 음성 변환 엔진입니다. espeak-ng를 내장하여 텍스트를 음소로 변환하므로 별도의 음소 변환기를 설치할 필요가 없습니다. 현재 릴리스는 2026년 7월에 발표된 1.6.0 버전입니다.

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 5000
curl -X POST -H 'Content-Type: application/json' \
  -d '{ "text": "This is a test." }' \
  -o test.wav localhost:5000/synthesize

test.wav을 재생할 수 있다면 정상적으로 작동하는 것입니다. 해당 엔드포인트는 OpenAI 형식이 아닌 Piper 고유의 형식이므로, /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 오디오 API를 지원합니다. 파일 처리를 위해 /v1/audio/transcriptions로 multipart POST를 보내고, 문장 처리를 위해 /v1/audio/speech로 JSON POST를 보냅니다. 이 두 경로를 직접 서비스하면 클라이언트는 기본 URL만 변경하면 됩니다.

Speaches는 양방향을 모두 지원하는 서버입니다. 이 서버는 OpenAI 경로 뒤에서 전사(transcription)를 위해 faster-whisper를, 음성 합성을 위해 Piper나 Kokoro를 실행합니다. 현재 릴리스는 2025년 12월에 배포된 v0.9.0-rc.3이며, 아직 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

명명된 볼륨(named volume)은 사람들이 자주 누락하는 부분입니다. 볼륨이 없으면 모델 캐시가 컨테이너 내부에 저장되므로, 재시작할 때마다 첫 요청에 응답하기 전에 수 기가바이트의 가중치 파일을 다시 다운로드하게 됩니다.

Speech는 /v1/audio/speech가 응답하기 전에 음성 데이터가 먼저 다운로드되어야 합니다:

uvx speaches-cli model download speaches-ai/Kokoro-82M-v1.0-ONNX

그 후에는 기본 URL만 변경하면 모든 OpenAI 클라이언트가 작동합니다:

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를 사용하여 동일한 경로를 서비스합니다. 2025년 12월 기준 최신 버전은 0.0.21이며, 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 권한이 필요합니다. 다른 작업을 수행하는 서버라면 리버스 프록시 뒤에서 높은 포트를 사용하는 것이 더 나은 구성입니다. vox-box start은 하나의 모델만 처리하므로, 양방향을 모두 지원하려면 음성 저장소 ID를 사용하여 두 번째 포트에서 두 번째 인스턴스를 실행해야 합니다.

서버에 로드된 모델을 확인한 다음, 해당 ID를 model 필드에 사용하십시오:

curl http://127.0.0.1:8010/v1/models
curl 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"

{"text": "..."} 형태의 JSON 본문이 반환되면 전체 경로가 정상 작동하는 것입니다. 모델 이름에서 404 오류가 발생한다면 /v1/models 출력을 확인하지 않고 추측했기 때문입니다.

이 서버들 중 기본적으로 인증이 활성화된 것은 없습니다. 127.0.0.1에 바인딩하고 VPN이나 자격 증명을 요구하는 리버스 프록시를 통해 접근하십시오. 공용 IP에서 /v1/audio/transcriptions을 열어두면 발견하는 누구에게나 무료 CPU 자원을 제공하는 꼴이 되며, 그들은 반드시 찾아낼 것입니다.

자체 호스팅 어시스턴트를 위한 음성 프론트엔드

양방향 모두 OpenAI 경로로 응답이 설정되면, 채팅 프론트엔드를 통해 이를 구동할 수 있습니다. Open WebUI 및 대안들은 설정에서 오디오를 위한 OpenAI 호환 베이스 URL을 허용하므로, 하나의 박스에서 Ollama로 로컬 LLM을 실행하고 양쪽 끝에서 음성 루프를 완성할 수 있습니다.

이 세 단계가 동일한 코어에서 순차적으로 실행되므로 지연 시간을 현실적으로 계산해야 합니다. 10초짜리 질문은 위에서 언급한 7.6x 수치에 따라 전사하는 데 약 1.3초가 소요되며, 이는 모델이 단 하나의 토큰도 읽기 전의 시간입니다. 여기에 CPU 토큰 생성 시간을 더하면 왕복 시간이 너무 길어져 테스트 사용자는 시스템이 멈췄다고 가정하게 됩니다. 배치 전사는 CPU에서도 무리가 없지만, 대화형 작업은 그렇지 않습니다. 바로 이 지점에서 GPU가 탑재된 VPS가 비용 값을 하기 시작합니다.

GPU가 실제로 가치 있는 경우는 언제인가?

ChartWhisper large-v2 on an RTX 3070 Ti, 13 minutes of audio (published project figures)
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로 양자화된 대형 모델은 2,926 MB의 VRAM을 사용하여 13.2배 실시간 속도로 동작하며, 배치 처리를 적용하면 48.8배까지 빨라집니다. 두 차트가 명시하지 않는 부분을 주의 깊게 살펴보십시오. 두 차트는 서로 다른 모델을 사용합니다. GPU 행은 large-v2 모델을, CPU 행은 small 모델을 사용한 결과입니다. GPU가 small 모델을 6배 더 빠르게 만드는 것이 아닙니다. GPU는 정확도가 높은 모델을 실사용 가능한 수준으로 만들어 줍니다.

이 수치의 출처

두 차트 모두 faster-whisper README에 게시된 벤치마크를 재현한 것입니다. 오디오는 13분짜리 단일 파일입니다. CPU 행은 Intel Core i7-12700K에서 8개의 스레드를 사용했고, GPU 행은 8 GB VRAM을 탑재한 NVIDIA RTX 3070 Ti에서 CUDA 12.4를 사용했습니다. 초(seconds)와 메모리 열은 게시된 수치 그대로입니다. x_realtime 열은 780초의 오디오를 측정된 시간으로 나눈 뒤 소수점 첫째 자리까지 반올림하여 계산한 값입니다. 메모리 열은 CPU 차트의 경우 시스템 RAM을, GPU 차트의 경우 VRAM을 의미합니다.

공유 vCPU 플랜으로는 위 CPU 벤치마크 수치에 도달할 수 없습니다. 해당 벤치마크는 고성능 데스크톱 프로세서의 8개 스레드를 온전히 사용한 결과입니다. 7.6배를 최대 성능으로 간주하고, 계획을 세우기 전에 실제 녹음 파일을 사용하여 time로 직접 본인의 서버에서 측정해 보십시오.

실무에서 통용되는 4가지 경험칙은 다음과 같습니다.

  • 본인 녹음 파일을 가끔 변환하는 경우: CPU, small, int8 모델을 사용하십시오. 전용 vCPU 2개면 충분합니다.
  • 자막 생성과 같은 야간 배치 작업: CPU, small 또는 medium, int8 모델을 사용하고 nice로 감싸서 실행하십시오.
  • 대화형 작업이 필요하거나 하룻밤 사이에 전체 라이브러리를 처리해야 하는 경우: GPU를 사용하십시오.
  • Piper: 항상 CPU를 사용하십시오. 이 정도 크기의 음성 모델은 GPU를 사용해도 거의 이득이 없습니다.

동일한 하드웨어에서 다른 어떤 작업을 수행할 수 있을지 고민 중이라면, 직접 호스팅 가능한 AI 모델의 범위에 관한 더 넓은 질문 문서를 통해 수용 가능한 모델 크기를 확인해 보십시오.

실패 유형 및 확인되는 메시지

error: externally-managed-environment 설치 시 발생합니다. 시스템 Python은 배포판에 의해 보호됩니다. 위에서 설명한 대로 가상 환경을 생성하십시오.

GPU 서버에서의 cuDNN 불일치. 실패 메시지는 다음과 같습니다.

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 이상 버전은 CUDA 12 환경에서 cuDNN 9를 요구하지만, 호스트에는 cuDNN 8이 설치되어 있습니다. cuDNN 9를 설치하거나 pip install --force-reinstall ctranslate2==4.4.0을 사용하여 이전 런타임을 고정하십시오. 둘 중 하나만 수행해야 합니다. 두 가지를 모두 수행하면 원래 상태로 돌아갑니다.

This CTranslate2 package was not compiled with CUDA support은 유사하게 느껴지지만 다른 오류입니다. 설치된 휠(wheel) 파일이 CPU 전용 빌드입니다. GPU 호스트에서 가상 환경을 다시 빌드하여 pip가 올바른 휠을 다시 선택하도록 하십시오.

전사 내용의 문구 반복. 문장이 10번 반복되는 현상은 거의 항상 침묵이나 음악이 음성으로 잘못 인식되어 발생합니다. 먼저 vad_filter=True를 활성화하십시오. 그래도 문제가 지속되면 해당 구간을 들어보십시오. 오디오가 거의 침묵 상태이면 Whisper가 참조할 정보가 없어 마지막으로 확신했던 추측을 반복하게 됩니다.

잘못된 언어 감지. Whisper는 처음 30초 분량만으로 언어를 추측합니다. info.language_probability 값이 1.0보다 훨씬 낮다면 확신이 없다는 의미이며, 이는 녹음 시작 부분에 음악이나 잡담이 섞여 있을 때 발생합니다. 언어를 이미 알고 있다면 language="en"를 전달하십시오.

프로세스가 Killed를 출력하고 중단됨. 이는 커널의 OOM(Out-of-Memory) 킬러에 의한 종료이며, dmesg 명령을 실행하면 일치하는 oom-kill 라인을 확인할 수 있습니다. large-v3 모델은 작업 메모리 외에도 가중치 로드에만 3 GB 이상의 메모리가 필요합니다. 2 GB VPS 환경에서는 int8로 설정된 small 모델이 탑재 가능한 최대 크기입니다.

Piper가 음성 파일을 찾을 수 없음. 플레이어는 --data-dir을 전달하지 않으면 작업 디렉터리에서 파일을 찾습니다. 예상되는 디렉터리에서 ls을 실행하여 .onnx.onnx.json이 모두 존재하는지 확인하십시오. 하나라도 없으면 둘 다 없는 것과 마찬가지로 실패합니다.

FAQ

Can I run speech to text on a CPU-only VPS?

Yes, and for batch work it is the sensible choice. Using faster-whisper with the small model at int8, the project's published benchmark transcribes 13 minutes of audio in 102 seconds on 8 threads of a desktop i7, about 7.6x real time, in 1,477 MB of RAM. A shared vCPU plan runs slower than that, so measure your own box. Text to speech with Piper is easier still and needs no GPU under any circumstances.

Which Whisper model size should I use?

Start with small at int8. It is 484 MB on disk and it handles clear recorded speech well. Move up to medium when accents or background noise cause errors you cannot live with, and to large-v3 only when accuracy matters more than everything else, since it wants 3,090 MB of disk and over 3 GB of memory. Going the other way, tiny at 75.5 MB is useful for language detection and for testing a pipeline, not for transcripts a person will read.

Why is faster-whisper faster than the original Whisper package?

The model is the same. The runtime is not. The reference package runs Whisper in PyTorch, while faster-whisper runs the same weights on CTranslate2, an engine built for transformer inference that quantizes weights at load time and needs no PyTorch install. On the published CPU benchmark that is 1.9x real time for the reference package against 7.6x for faster-whisper at int8, with less memory used.

Why does my transcript repeat the same sentence over and over?

Whisper is decoding silence or music as speech and falling back on its last confident guess. Set vad_filter=True in the transcribe() call, which runs Silero voice activity detection first and removes the silent stretches before the model sees them. If it still repeats, check the audio level, because a recording that is nearly silent throughout gives the model nothing to work from.

How do I get an OpenAI-compatible audio endpoint on my own server?

Run a server that implements POST /v1/audio/transcriptions and POST /v1/audio/speech, then point the client at it with a new base URL. Speaches is one option, published as a container image with a CPU build, using faster-whisper for transcription and Piper or Kokoro for speech. vox-box is another, installed with pip install vox-box and started with vox-box start --huggingface-repo-id, which serves one model per process. Neither enables authentication by default, so bind to localhost and put a proxy or a VPN in front.

#whisper#tts#piper#speech-to-text#self-hosted-ai