Drama-3 / Dockerfile.engine
zhaochenyang20's picture andito's picture
andito HF Staff
Replace ZeroGPU demo with Gradio studio and H200 endpoint (#6)
e9cf2ae
Raw History Blame Contribute Delete
3.93 kB
# Fish Audio Drama 3 on SGLang Omni, as a Hugging Face Docker Space on one GPU
# (RTX Pro 6000 or H200).
#
# The base image is the one SGLang Omni's CI runs main on: CUDA, SGLang, and most
# Python dependencies, but not sglang-omni itself, which is installed at a pinned commit.
FROM hongccc/sglang-omni@sha256:ebe4239e29a764ee3a2806385c061c5fd438a26f01458e503d3822dcba5790df
ARG SGLANG_OMNI_COMMIT=22d4ace88f9547777b819a69d7691204bb9ce847
# The image moves slower than SGLang Omni (its SGLang predates the pinned commit's
# sglang==0.5.21). Install the commit's pins the image does not satisfy, as SGLang
# Omni's CI does before testing on this image (.github/scripts/prepare_omni_venv.sh).
COPY scripts/omni_missing_deps.py /tmp/omni_missing_deps.py
RUN python3 -c "import sys, urllib.request; urllib.request.urlretrieve(sys.argv[1], '/tmp/omni-pyproject.toml')" \
"https://raw.githubusercontent.com/sgl-project/sglang-omni/${SGLANG_OMNI_COMMIT}/pyproject.toml" \
&& python3 /tmp/omni_missing_deps.py /tmp/omni-pyproject.toml > /tmp/omni-missing.txt \
&& echo "Pins the image does not satisfy:" && cat /tmp/omni-missing.txt \
&& if [ -s /tmp/omni-missing.txt ]; then xargs -d '\n' -n 1 python3 -m pip install --no-cache-dir < /tmp/omni-missing.txt; fi \
&& python3 /tmp/omni_missing_deps.py --overrides /tmp/omni-pyproject.toml \
| xargs -r -d '\n' python3 -m pip install --no-cache-dir --no-deps \
&& python3 /tmp/omni_missing_deps.py --report /tmp/omni-pyproject.toml
RUN python3 -m pip install --no-cache-dir --no-deps \
"sglang-omni @ https://github.com/sgl-project/sglang-omni/archive/${SGLANG_OMNI_COMMIT}.tar.gz" \
python-multipart \
&& python3 -m pip install --no-cache-dir authlib itsdangerous "gradio[oauth]==6.28.0" \
&& python3 -c "import sglang_omni, whisper, av, librosa, httpx, fastapi, huggingface_hub; from huggingface_hub import attach_huggingface_oauth, parse_huggingface_oauth; print('sglang-omni', sglang_omni.__version__, 'huggingface_hub', huggingface_hub.__version__)"
# SGLang Omni declares each stage's factory in the model's config class and refuses
# to override it from the command line. Rebind the class name the Drama 3
# preprocessing factory builds to the Space's subclass, which adds described
# characters and directing history (drama3_space_ext.py, on PYTHONPATH at runtime).
RUN stages=$(python3 -c "import os, sglang_omni; print(os.path.join(os.path.dirname(sglang_omni.__file__), 'models', 'fishaudio_drama3', 'stages.py'))") \
&& grep -q "^def create_preprocessing_executor" "$stages" \
&& grep -q "preprocessor = Drama3SpeechPreprocessor(" "$stages" \
&& printf '\n\n# Drama 3 Space: described characters and directing history.\nfrom drama3_space_ext import Drama3SpacePreprocessor as Drama3SpeechPreprocessor # noqa: E402\n' >> "$stages" \
&& tail -3 "$stages"
# Spaces run the container as uid 1000. Give it a writable home that holds the
# FlashInfer JIT cache the image built for Hopper, and stop the base entrypoint from
# cloning SGLang Omni's main branch at start.
RUN (id -u 1000 >/dev/null 2>&1 || useradd -m -u 1000 -s /bin/bash user) \
&& mkdir -p /home/user/app /home/user/.cache \
&& if [ -d /root/.cache/flashinfer ]; then cp -a /root/.cache/flashinfer /home/user/.cache/; fi \
&& chown -R 1000:1000 /home/user
ENV HOME=/home/user \
USER=user \
FLASHINFER_WORKSPACE_BASE=/home/user \
SGLANG_OMNI_AUTO_CLONE=0 \
PYTHONUNBUFFERED=1 \
PYTHONPATH=/home/user/app \
WHISPER_DIR=/home/user/.cache/whisper \
DEMO_UNLIMITED_ORGS=fishaudio \
USAGE_BUCKET_MOUNT_PATH=/data
USER 1000
WORKDIR /home/user/app
# Whisper large-v3-turbo transcribes reference clips (about 1.5 GB).
RUN python3 -c "import whisper; whisper._download(whisper._MODELS['turbo'], '/home/user/.cache/whisper', False)"
COPY --chown=1000:1000 . .
EXPOSE 7860
CMD ["python3", "server.py"]