Supersede draft PR #26 with a merge-safe prerequisite: bake and preload the amy, irina, and claude Piper models, route only validated server-side language to fixed voices, and leave the live voice deployment manifest unchanged. Remove the pinned WebUI speaker selector and its persisted preference, omit client voice fields from every outbound TTS path, and keep hands-free Voice Mode and the conversation instrument intact. Hostile or legacy voice fields remain ignored by the Piper server. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
69 lines
5.4 KiB
Docker
69 lines
5.4 KiB
Docker
# syntax=docker/dockerfile:1
|
|
# dockerfiles/Dockerfile.hermes-jetson-tts
|
|
FROM python:3.11-slim-bookworm@sha256:d29f48a31a8b408ed19272ca1e7b10ebae13b240a27e862d3d4217c528e2e0c3
|
|
|
|
RUN python -m pip install --no-cache-dir piper-tts==1.5.0
|
|
|
|
# Pin the voice data in the image so synthesis has no runtime dependency on
|
|
# Hugging Face or mutable model metadata.
|
|
ADD --checksum=sha256:4cabf7c3a638017137f34a1516522032d4fe3f38228a843cc9b764ddcbcd9e09 --chmod=0444 \
|
|
https://huggingface.co/rhasspy/piper-voices/resolve/ea046e8458f6acd997706d6e6066a022b42f6fb1/en/en_US/lessac/high/en_US-lessac-high.onnx?download=true \
|
|
/opt/models/piper/en_US-lessac-high.onnx
|
|
ADD --checksum=sha256:db42b97d9859f257bc1561b8ed980e7fb2398402050a74ddd6cbec931a92412f --chmod=0444 \
|
|
https://huggingface.co/rhasspy/piper-voices/resolve/ea046e8458f6acd997706d6e6066a022b42f6fb1/en/en_US/lessac/high/en_US-lessac-high.onnx.json?download=true \
|
|
/opt/models/piper/en_US-lessac-high.onnx.json
|
|
ADD --checksum=sha256:5efe09e69902187827af646e1a6e9d269dee769f9877d17b16b1b46eeaaf019f --chmod=0444 \
|
|
https://huggingface.co/rhasspy/piper-voices/resolve/ea046e8458f6acd997706d6e6066a022b42f6fb1/en/en_US/lessac/medium/en_US-lessac-medium.onnx?download=true \
|
|
/opt/models/piper/en_US-lessac-medium.onnx
|
|
ADD --checksum=sha256:efe19c417bed055f2d69908248c6ba650fa135bc868b0e6abb3da181dab690a0 --chmod=0444 \
|
|
https://huggingface.co/rhasspy/piper-voices/resolve/ea046e8458f6acd997706d6e6066a022b42f6fb1/en/en_US/lessac/medium/en_US-lessac-medium.onnx.json?download=true \
|
|
/opt/models/piper/en_US-lessac-medium.onnx.json
|
|
ADD --checksum=sha256:f7d01dde371555732c4c314111ac79672b1a5ce2fc19266ab42178fd8df7f375 --chmod=0444 \
|
|
https://huggingface.co/rhasspy/piper-voices/resolve/ea046e8458f6acd997706d6e6066a022b42f6fb1/en/en_US/lessac/low/en_US-lessac-low.onnx?download=true \
|
|
/opt/models/piper/en_US-lessac-low.onnx
|
|
ADD --checksum=sha256:45754dfdebb3b8661c3fc564713772deec6e064feeb5b4e9594857dc7305193a --chmod=0444 \
|
|
https://huggingface.co/rhasspy/piper-voices/resolve/ea046e8458f6acd997706d6e6066a022b42f6fb1/en/en_US/lessac/low/en_US-lessac-low.onnx.json?download=true \
|
|
/opt/models/piper/en_US-lessac-low.onnx.json
|
|
|
|
# Multilingual chat voice policy: English -> amy, Russian -> irina, Spanish ->
|
|
# claude (Mexican Spanish, the only "claude" voice rhasspy/piper-voices
|
|
# publishes; there is no es_ES-claude).
|
|
ADD --checksum=sha256:b3a6e47b57b8c7fbe6a0ce2518161a50f59a9cdd8a50835c02cb02bdd6206c18 --chmod=0444 \
|
|
https://huggingface.co/rhasspy/piper-voices/resolve/ea046e8458f6acd997706d6e6066a022b42f6fb1/en/en_US/amy/medium/en_US-amy-medium.onnx?download=true \
|
|
/opt/models/piper/en_US-amy-medium.onnx
|
|
ADD --checksum=sha256:95a23eb4d42909d38df73bb9ac7f45f597dbfcde2d1bf9526fdeaf5466977d77 --chmod=0444 \
|
|
https://huggingface.co/rhasspy/piper-voices/resolve/ea046e8458f6acd997706d6e6066a022b42f6fb1/en/en_US/amy/medium/en_US-amy-medium.onnx.json?download=true \
|
|
/opt/models/piper/en_US-amy-medium.onnx.json
|
|
ADD --checksum=sha256:8ff38212d23da300bbe3705c645e6e5b9475f0bfde01558eb17813e22acaaaaa --chmod=0444 \
|
|
https://huggingface.co/rhasspy/piper-voices/resolve/ea046e8458f6acd997706d6e6066a022b42f6fb1/ru/ru_RU/irina/medium/ru_RU-irina-medium.onnx?download=true \
|
|
/opt/models/piper/ru_RU-irina-medium.onnx
|
|
ADD --checksum=sha256:c2ec28bb38e2b59e93b959b3e40348c1afebbd272f30fed5d41205d08e98a9d7 --chmod=0444 \
|
|
https://huggingface.co/rhasspy/piper-voices/resolve/ea046e8458f6acd997706d6e6066a022b42f6fb1/ru/ru_RU/irina/medium/ru_RU-irina-medium.onnx.json?download=true \
|
|
/opt/models/piper/ru_RU-irina-medium.onnx.json
|
|
ADD --checksum=sha256:3ef40a71ea63852cd8ab7e6fa7d2ecdcfa67a0b47c9c48e3f10e02ee02083ea0 --chmod=0444 \
|
|
https://huggingface.co/rhasspy/piper-voices/resolve/ea046e8458f6acd997706d6e6066a022b42f6fb1/es/es_MX/claude/high/es_MX-claude-high.onnx?download=true \
|
|
/opt/models/piper/es_MX-claude-high.onnx
|
|
ADD --checksum=sha256:1afc81f703c0e4cb3b4d7c0dca096b8b54a98806807f0170cf5eb5557723c12d --chmod=0444 \
|
|
https://huggingface.co/rhasspy/piper-voices/resolve/ea046e8458f6acd997706d6e6066a022b42f6fb1/es/es_MX/claude/high/es_MX-claude-high.onnx.json?download=true \
|
|
/opt/models/piper/es_MX-claude-high.onnx.json
|
|
RUN chmod 0555 /opt/models /opt/models/piper
|
|
|
|
COPY dockerfiles/hermes-jetson-tts-server.py /opt/atlas/hermes-jetson-tts-server.py
|
|
RUN chmod 0555 /opt/atlas/hermes-jetson-tts-server.py
|
|
|
|
# Load every pinned voice during the ARM64 build, including the three baked
|
|
# for the multilingual chat policy. This catches package or model-format
|
|
# drift before the image can reach Flux.
|
|
RUN python -c "import stat; from pathlib import Path; from piper import PiperVoice; p=Path('/opt/models/piper'); models=[p/'en_US-lessac-high.onnx',p/'en_US-lessac-medium.onnx',p/'en_US-lessac-low.onnx',p/'en_US-amy-medium.onnx',p/'ru_RU-irina-medium.onnx',p/'es_MX-claude-high.onnx']; assert stat.S_IMODE(p.stat().st_mode)==0o555; assert all(stat.S_IMODE(model.stat().st_mode)==0o444 for model in models); voices=[PiperVoice.load(model,Path(str(model)+'.json'),use_cuda=False,download_dir=p) for model in models]; assert all(voice.config.sample_rate>0 for voice in voices)"
|
|
|
|
ENV HERMES_TTS_HOST=0.0.0.0 \
|
|
HERMES_TTS_PORT=9001 \
|
|
HERMES_TTS_VOICE=en_US-amy-medium \
|
|
HERMES_TTS_CACHE=/opt/models/piper \
|
|
OMP_NUM_THREADS=2 \
|
|
PYTHONDONTWRITEBYTECODE=1 \
|
|
PYTHONUNBUFFERED=1
|
|
|
|
EXPOSE 9001
|
|
ENTRYPOINT ["python", "/opt/atlas/hermes-jetson-tts-server.py"]
|