WIP: fix(hermes-voice): switch Atlas Piper TTS to hfc_female, bake amy as alternate #24
@ -24,6 +24,18 @@ ADD --checksum=sha256:f7d01dde371555732c4c314111ac79672b1a5ce2fc19266ab42178fd8d
|
|||||||
ADD --checksum=sha256:45754dfdebb3b8661c3fc564713772deec6e064feeb5b4e9594857dc7305193a --chmod=0444 \
|
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 \
|
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
|
/opt/models/piper/en_US-lessac-low.onnx.json
|
||||||
|
ADD --checksum=sha256:914c473788fc1fa8b63ace1cdcdb44588f4ae523d3ab37df1536616835a140b7 --chmod=0444 \
|
||||||
|
https://huggingface.co/rhasspy/piper-voices/resolve/ea046e8458f6acd997706d6e6066a022b42f6fb1/en/en_US/hfc_female/medium/en_US-hfc_female-medium.onnx?download=true \
|
||||||
|
/opt/models/piper/en_US-hfc_female-medium.onnx
|
||||||
|
ADD --checksum=sha256:03f1fa0622b80463283592d97aca9f6e89aec345a5c56b7257723e0093c58b6c --chmod=0444 \
|
||||||
|
https://huggingface.co/rhasspy/piper-voices/resolve/ea046e8458f6acd997706d6e6066a022b42f6fb1/en/en_US/hfc_female/medium/en_US-hfc_female-medium.onnx.json?download=true \
|
||||||
|
/opt/models/piper/en_US-hfc_female-medium.onnx.json
|
||||||
|
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
|
||||||
RUN chmod 0555 /opt/models /opt/models/piper
|
RUN chmod 0555 /opt/models /opt/models/piper
|
||||||
|
|
||||||
COPY dockerfiles/hermes-jetson-tts-server.py /opt/atlas/hermes-jetson-tts-server.py
|
COPY dockerfiles/hermes-jetson-tts-server.py /opt/atlas/hermes-jetson-tts-server.py
|
||||||
@ -31,11 +43,11 @@ RUN chmod 0555 /opt/atlas/hermes-jetson-tts-server.py
|
|||||||
|
|
||||||
# Load the actual pinned voice during the ARM64 build. This catches package or
|
# Load the actual pinned voice during the ARM64 build. This catches package or
|
||||||
# model-format drift before the image can reach Flux.
|
# 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']; 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)"
|
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-hfc_female-medium.onnx',p/'en_US-amy-medium.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 \
|
ENV HERMES_TTS_HOST=0.0.0.0 \
|
||||||
HERMES_TTS_PORT=9001 \
|
HERMES_TTS_PORT=9001 \
|
||||||
HERMES_TTS_VOICE=en_US-lessac-medium \
|
HERMES_TTS_VOICE=en_US-hfc_female-medium \
|
||||||
HERMES_TTS_CACHE=/opt/models/piper \
|
HERMES_TTS_CACHE=/opt/models/piper \
|
||||||
OMP_NUM_THREADS=2 \
|
OMP_NUM_THREADS=2 \
|
||||||
PYTHONDONTWRITEBYTECODE=1 \
|
PYTHONDONTWRITEBYTECODE=1 \
|
||||||
|
|||||||
@ -17,7 +17,7 @@ from piper import PiperConfig, PiperVoice, SynthesisConfig
|
|||||||
|
|
||||||
HOST = os.getenv("HERMES_TTS_HOST", "0.0.0.0")
|
HOST = os.getenv("HERMES_TTS_HOST", "0.0.0.0")
|
||||||
PORT = int(os.getenv("HERMES_TTS_PORT", "9001"))
|
PORT = int(os.getenv("HERMES_TTS_PORT", "9001"))
|
||||||
VOICE_NAME = os.getenv("HERMES_TTS_VOICE", "en_US-lessac-high")
|
VOICE_NAME = os.getenv("HERMES_TTS_VOICE", "en_US-hfc_female-medium")
|
||||||
CACHE_DIR = Path(os.getenv("HERMES_TTS_CACHE", "/cache/piper"))
|
CACHE_DIR = Path(os.getenv("HERMES_TTS_CACHE", "/cache/piper"))
|
||||||
MAX_TEXT_CHARS = 5000
|
MAX_TEXT_CHARS = 5000
|
||||||
ONNX_THREADS = max(1, int(os.getenv("HERMES_TTS_ONNX_THREADS", "4")))
|
ONNX_THREADS = max(1, int(os.getenv("HERMES_TTS_ONNX_THREADS", "4")))
|
||||||
|
|||||||
@ -63,7 +63,7 @@ atlas = ''' # ── Atlas private Jetson TTS ──────────
|
|||||||
request_body = json.dumps({
|
request_body = json.dumps({
|
||||||
"model": "piper",
|
"model": "piper",
|
||||||
"input": text,
|
"input": text,
|
||||||
"voice": "en_US-lessac-high",
|
"voice": "en_US-hfc_female-medium",
|
||||||
"speed": speed,
|
"speed": speed,
|
||||||
}).encode("utf-8")
|
}).encode("utf-8")
|
||||||
request = Request(atlas_url, data=request_body, headers={
|
request = Request(atlas_url, data=request_body, headers={
|
||||||
|
|||||||
@ -114,7 +114,7 @@ spec:
|
|||||||
app: hermes-tts
|
app: hermes-tts
|
||||||
annotations:
|
annotations:
|
||||||
ai.bstein.dev/role: private-chat-text-to-speech
|
ai.bstein.dev/role: private-chat-text-to-speech
|
||||||
ai.bstein.dev/model: piper-en-us-lessac-medium
|
ai.bstein.dev/model: piper-en-us-hfc-female-medium
|
||||||
ai.bstein.dev/gpu: CPU-only beside Whisper on the voice node
|
ai.bstein.dev/gpu: CPU-only beside Whisper on the voice node
|
||||||
spec:
|
spec:
|
||||||
automountServiceAccountToken: false
|
automountServiceAccountToken: false
|
||||||
@ -131,7 +131,7 @@ spec:
|
|||||||
- {name: HOME, value: /tmp}
|
- {name: HOME, value: /tmp}
|
||||||
- {name: XDG_CACHE_HOME, value: /tmp/cache}
|
- {name: XDG_CACHE_HOME, value: /tmp/cache}
|
||||||
- {name: HERMES_TTS_PORT, value: "9001"}
|
- {name: HERMES_TTS_PORT, value: "9001"}
|
||||||
- {name: HERMES_TTS_VOICE, value: en_US-lessac-medium}
|
- {name: HERMES_TTS_VOICE, value: en_US-hfc_female-medium}
|
||||||
- {name: HERMES_TTS_CACHE, value: /opt/models/piper}
|
- {name: HERMES_TTS_CACHE, value: /opt/models/piper}
|
||||||
- {name: HERMES_TTS_ONNX_THREADS, value: "2"}
|
- {name: HERMES_TTS_ONNX_THREADS, value: "2"}
|
||||||
startupProbe:
|
startupProbe:
|
||||||
|
|||||||
@ -398,7 +398,11 @@ def test_voice_models_are_baked_and_runtime_has_no_public_egress():
|
|||||||
assert "HERMES_STT_CACHE=/opt/models/whisper" in stt_dockerfile
|
assert "HERMES_STT_CACHE=/opt/models/whisper" in stt_dockerfile
|
||||||
assert "ADD --checksum=sha256:4cabf7c3" in tts_dockerfile
|
assert "ADD --checksum=sha256:4cabf7c3" in tts_dockerfile
|
||||||
assert "ADD --checksum=sha256:db42b97d" in tts_dockerfile
|
assert "ADD --checksum=sha256:db42b97d" in tts_dockerfile
|
||||||
assert tts_dockerfile.count("--chmod=0444") == 6
|
assert "ADD --checksum=sha256:914c473788fc1fa8b63ace1cdcdb44588f4ae523d3ab37df1536616835a140b7" in tts_dockerfile
|
||||||
|
assert "ADD --checksum=sha256:03f1fa0622b80463283592d97aca9f6e89aec345a5c56b7257723e0093c58b6c" in tts_dockerfile
|
||||||
|
assert "ADD --checksum=sha256:b3a6e47b57b8c7fbe6a0ce2518161a50f59a9cdd8a50835c02cb02bdd6206c18" in tts_dockerfile
|
||||||
|
assert "ADD --checksum=sha256:95a23eb4d42909d38df73bb9ac7f45f597dbfcde2d1bf9526fdeaf5466977d77" in tts_dockerfile
|
||||||
|
assert tts_dockerfile.count("--chmod=0444") == 10
|
||||||
assert "chmod 0555 /opt/models /opt/models/piper" in tts_dockerfile
|
assert "chmod 0555 /opt/models /opt/models/piper" in tts_dockerfile
|
||||||
assert "HERMES_TTS_CACHE=/opt/models/piper" in tts_dockerfile
|
assert "HERMES_TTS_CACHE=/opt/models/piper" in tts_dockerfile
|
||||||
tts_server = (ROOT / "dockerfiles" / "hermes-jetson-tts-server.py").read_text()
|
tts_server = (ROOT / "dockerfiles" / "hermes-jetson-tts-server.py").read_text()
|
||||||
@ -449,7 +453,7 @@ def test_voice_workloads_have_deliberate_xavier_placement():
|
|||||||
tts_env = {
|
tts_env = {
|
||||||
item["name"]: item["value"] for item in tts["containers"][0]["env"]
|
item["name"]: item["value"] for item in tts["containers"][0]["env"]
|
||||||
}
|
}
|
||||||
assert tts_env["HERMES_TTS_VOICE"] == "en_US-lessac-medium"
|
assert tts_env["HERMES_TTS_VOICE"] == "en_US-hfc_female-medium"
|
||||||
assert tts_env["HERMES_TTS_ONNX_THREADS"] == "2"
|
assert tts_env["HERMES_TTS_ONNX_THREADS"] == "2"
|
||||||
assert tts["containers"][0]["resources"]["limits"]["cpu"] == "4"
|
assert tts["containers"][0]["resources"]["limits"]["cpu"] == "4"
|
||||||
assert all("hostPath" not in volume for volume in stt["volumes"])
|
assert all("hostPath" not in volume for volume in stt["volumes"])
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user