06eb487a26
- app.py: thin FastAPI wrapper exposing OpenAI /v1/audio/speech (+ /v1/audio/voices, /healthz) around OmniVoice's Python API; precomputes a voice-clone prompt per voice at startup (loaded Whisper auto-transcribes each reference). Replaces the Gradio demo. - Dockerfile/compose: run the uvicorn wrapper, /healthz healthcheck, project name pinned to "omnivoice" so the asset-engine liveness probe matches. - deploy-omnivoice.yaml: stage chatterbox /refs/*.wav as clone voices (skip _* artifacts) + verify the API surface. - services.yaml: catalog entry (id omnivoice, :8199/v1/audio/speech, voice list sourced live from /v1/audio/voices) + reproducibility_audit row. Verified live on irv-ml1: /healthz ok, 33 voices loaded, test synth -> 24kHz PCM_16 WAV.
56 lines
2.3 KiB
Docker
56 lines
2.3 KiB
Docker
# syntax=docker/dockerfile:1.6
|
|
#
|
|
# OmniVoice (k2-fsa/OmniVoice) — zero-shot, massively-multilingual (600+
|
|
# languages) voice-cloning + voice-design TTS, diffusion-LM architecture,
|
|
# Apache-2.0. Upstream ships a pip package + its own Gradio demo
|
|
# (`omnivoice-demo`); there's no official image, so we build a thin CUDA
|
|
# container around the pip package and run its Gradio server directly.
|
|
# Unlike index-tts we DON'T need a FastAPI wrapper — OmniVoice serves itself.
|
|
|
|
ARG CUDA_BASE=nvidia/cuda:12.8.0-cudnn-runtime-ubuntu22.04
|
|
FROM ${CUDA_BASE}
|
|
|
|
ENV DEBIAN_FRONTEND=noninteractive \
|
|
PIP_ROOT_USER_ACTION=ignore \
|
|
PYTHONUNBUFFERED=1 \
|
|
PATH="/opt/venv/bin:${PATH}"
|
|
|
|
RUN apt-get update \
|
|
&& apt-get install -y --no-install-recommends \
|
|
python3.10 python3.10-venv python3-pip \
|
|
git ffmpeg libsndfile1 \
|
|
ca-certificates wget \
|
|
&& rm -rf /var/lib/apt/lists/* \
|
|
&& python3.10 -m venv /opt/venv
|
|
|
|
# CUDA 12.8 torch wheels (per OmniVoice's documented install line).
|
|
RUN pip install --no-cache-dir \
|
|
torch==2.8.0 torchaudio==2.8.0 \
|
|
--index-url https://download.pytorch.org/whl/cu128
|
|
|
|
# OmniVoice from PyPI (+ huggingface_hub for the entrypoint weight pre-warm).
|
|
# Optional reproducible pin via the OMNIVOICE_VERSION build arg (empty=latest).
|
|
ARG OMNIVOICE_VERSION=
|
|
RUN pip install --no-cache-dir "omnivoice${OMNIVOICE_VERSION:+==${OMNIVOICE_VERSION}}" huggingface_hub
|
|
|
|
# Our asset-engine wrapper deps (FastAPI stack + soundfile for WAV encoding).
|
|
RUN pip install --no-cache-dir fastapi 'uvicorn[standard]' soundfile python-multipart
|
|
|
|
# Fail the build loudly if the runtime imports aren't satisfiable.
|
|
RUN python -c "import omnivoice, fastapi, soundfile, uvicorn; print('omnivoice wrapper deps OK')"
|
|
|
|
WORKDIR /app
|
|
COPY app.py /app/app.py
|
|
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
|
|
RUN chmod +x /usr/local/bin/entrypoint.sh
|
|
|
|
EXPOSE 8001
|
|
|
|
# Our wrapper exposes /healthz (200 once model + >=1 voice are loaded). Generous
|
|
# start period: first boot pre-warms OmniVoice + Whisper ASR + clones every voice.
|
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=1200s --retries=3 \
|
|
CMD wget -q -O /dev/null http://127.0.0.1:8001/healthz || exit 1
|
|
|
|
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
|
|
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8001"]
|