mirror of
https://github.com/slackr31337/wyoming-piper-gpu.git
synced 2026-10-21 21:04:40 +02:00
Fixes for Docker container (#11)
* Update Dockerfile * Update run.sh * Update Dockerfile * Update __main__.py * Update process.py * Update Dockerfile * Update Dockerfile * Update settings.json * Delete wyoming-piper_cuda_path.diff * Create wyoming-piper_cuda.patch * Delete __main__.py * Delete process.py * Update wyoming-piper_cuda.patch * Update run.sh * Update run.sh * Update Dockerfile * Update settings.json * Update run.sh * Update Dockerfile * Update Dockerfile * Update Dockerfile * Update wyoming-piper_cuda.patch * Update Dockerfile --------- Co-authored-by: Robert Dunmire III <rdunmire@i-evolve.com>
This commit is contained in:
co-authored by
Robert Dunmire III
parent
de7e69b7e2
commit
4a422e7369
Vendored
+7
@@ -1,10 +1,17 @@
|
||||
{
|
||||
"cSpell.words": [
|
||||
"cublas",
|
||||
"CUDA",
|
||||
"cudnn",
|
||||
"cufft",
|
||||
"curand",
|
||||
"manylinux",
|
||||
"nvrtc",
|
||||
"onnxruntime",
|
||||
"phonemize",
|
||||
"setuptools",
|
||||
"slackr",
|
||||
"venv",
|
||||
"zxvf"
|
||||
]
|
||||
}
|
||||
+46
-34
@@ -1,59 +1,71 @@
|
||||
FROM nvidia/cuda:11.7.1-base-ubuntu22.04
|
||||
FROM nvidia/cuda:12.2.2-base-ubuntu22.04
|
||||
|
||||
# Install Piper
|
||||
WORKDIR /usr/src
|
||||
|
||||
ARG TARGETARCH=amd64
|
||||
ARG TARGETVARIANT=
|
||||
ARG PIPER_LIB_VERSION=1.4.0
|
||||
ARG WYOMING_PIPER_VERSION='1.5.0'
|
||||
ARG WYOMING_PIPER_VERSION='1.4.0'
|
||||
ARG PIPER_RELEASE='1.2.0'
|
||||
|
||||
RUN \
|
||||
apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
apt-get update &&\
|
||||
apt-get install -y --no-install-recommends \
|
||||
wget \
|
||||
curl \
|
||||
patch \
|
||||
python3 \
|
||||
python3-dev \
|
||||
python3-venv \
|
||||
python3-pip
|
||||
|
||||
RUN \
|
||||
pip3 install --no-cache-dir -U \
|
||||
setuptools \
|
||||
wheel \
|
||||
\
|
||||
&& pip3 install --no-cache-dir torch \
|
||||
\
|
||||
&& wget https://github.com/rhasspy/piper-phonemize/releases/download/v1.1.0/piper_phonemize-1.1.0-cp310-cp310-manylinux_2_28_x86_64.whl \
|
||||
\
|
||||
&& mv piper_phonemize-1.1.0-cp310-cp310-manylinux_2_28_x86_64.whl piper_phonemize-1.1.0-py3-none-any.whl \
|
||||
\
|
||||
&& pip3 install --no-cache-dir --force-reinstall --no-deps \
|
||||
mkdir -p /app /data &&\
|
||||
python3 -m venv /app &&\
|
||||
. /app/bin/activate &&\
|
||||
pip3 install --no-cache-dir --upgrade pip setuptools wheel &&\
|
||||
pip3 install --no-cache-dir \
|
||||
torch
|
||||
|
||||
RUN \
|
||||
. /app/bin/activate && \
|
||||
pip3 install --no-cache-dir --force-reinstall --no-deps\
|
||||
"piper-tts==${PIPER_RELEASE}" \
|
||||
piper_phonemize==1.1.0 \
|
||||
&&\
|
||||
\
|
||||
&& pip3 install --no-cache-dir --force-reinstall --no-deps \
|
||||
piper_phonemize-1.1.0-py3-none-any.whl \
|
||||
\
|
||||
&& pip3 install --no-cache-dir \
|
||||
pip3 install --no-cache-dir\
|
||||
onnxruntime-gpu \
|
||||
"wyoming-piper @ https://github.com/rhasspy/wyoming-piper/archive/refs/tags/v${WYOMING_PIPER_VERSION}.tar.gz" \
|
||||
&&\
|
||||
\
|
||||
&& rm -r piper_phonemize-1.1.0-py3-none-any.whl
|
||||
pip3 install --no-cache-dir\
|
||||
"wyoming-piper==${WYOMING_PIPER_VERSION}"\
|
||||
&&\
|
||||
\
|
||||
wget \
|
||||
"https://github.com/rhasspy/piper/releases/download/v${PIPER_RELEASE}/piper_${TARGETARCH}${TARGETVARIANT}.tar.gz" -O -|tar -zxvf - -C /usr/share
|
||||
|
||||
# pip3 install --no-cache-dir --force-reinstall --no-deps\
|
||||
# piper_phonemize-1.1.0-py3-none-any.whl &&\
|
||||
# \
|
||||
# "wyoming-piper @ https://github.com/rhasspy/wyoming-piper/archive/refs/tags/v${WYOMING_PIPER_VERSION}.tar.gz"
|
||||
# wget https://github.com/rhasspy/piper-phonemize/releases/download/v1.1.0/piper_phonemize-1.1.0-cp310-cp310-manylinux_2_28_x86_64.whl &&\
|
||||
# mv piper_phonemize-1.1.0-cp310-cp310-manylinux_2_28_x86_64.whl piper_phonemize-1.1.0-py3-none-any.whl &&\
|
||||
# rm -r piper_phonemize-1.1.0-py3-none-any.whl &&\
|
||||
|
||||
# Patch to enable CUDA arguments for piper
|
||||
COPY patch/wyoming-piper_cuda.patch /tmp/
|
||||
RUN \
|
||||
cd /app/lib/python3.10/site-packages/wyoming_piper/ &&\
|
||||
patch -p0 < /tmp/wyoming-piper_cuda.patch
|
||||
|
||||
# Clean up
|
||||
RUN \
|
||||
rm -rf /var/lib/apt/lists/* \
|
||||
&& rm /*.deb \
|
||||
&& mkdir -p /share/piper
|
||||
rm -rf /var/lib/apt/lists/* /*.deb /tmp/*
|
||||
|
||||
# Patch to enable CUDA arguments for piper
|
||||
COPY patch/process.py /usr/local/lib/python3.10/dist-packages/wyoming_piper/
|
||||
COPY patch/__main__.py /usr/local/lib/python3.10/dist-packages/wyoming_piper/
|
||||
|
||||
WORKDIR /
|
||||
COPY run.sh ./
|
||||
RUN chmod +x /run.sh
|
||||
WORKDIR /app
|
||||
COPY run.sh /app/
|
||||
RUN chmod +x /app/run.sh
|
||||
|
||||
EXPOSE 10200
|
||||
|
||||
ENTRYPOINT ["bash", "/run.sh \"${@}\""]
|
||||
ENTRYPOINT ["bash", "/app/run.sh"]
|
||||
@@ -1,230 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
import argparse
|
||||
import asyncio
|
||||
import json
|
||||
import logging
|
||||
from functools import partial
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, Set
|
||||
|
||||
from wyoming.info import Attribution, Info, TtsProgram, TtsVoice, TtsVoiceSpeaker
|
||||
from wyoming.server import AsyncServer
|
||||
|
||||
from . import __version__
|
||||
from .download import find_voice, get_voices
|
||||
from .handler import PiperEventHandler
|
||||
from .process import PiperProcessManager
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
"""Main entry point."""
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"--piper",
|
||||
required=True,
|
||||
help="Path to piper executable",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--voice",
|
||||
required=True,
|
||||
help="Default Piper voice to use (e.g., en_US-lessac-medium)",
|
||||
)
|
||||
parser.add_argument("--uri", default="stdio://", help="unix:// or tcp://")
|
||||
parser.add_argument(
|
||||
"--data-dir",
|
||||
required=True,
|
||||
action="append",
|
||||
help="Data directory to check for downloaded models",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--download-dir",
|
||||
help="Directory to download voices into (default: first data dir)",
|
||||
)
|
||||
#
|
||||
parser.add_argument(
|
||||
"--speaker", type=str, help="Name or id of speaker for default voice"
|
||||
)
|
||||
parser.add_argument("--noise-scale", type=float, help="Generator noise")
|
||||
parser.add_argument("--length-scale", type=float, help="Phoneme length")
|
||||
parser.add_argument("--noise-w", type=float, help="Phoneme width noise")
|
||||
#
|
||||
parser.add_argument(
|
||||
"--auto-punctuation", default=".?!", help="Automatically add punctuation"
|
||||
)
|
||||
parser.add_argument("--samples-per-chunk", type=int, default=1024)
|
||||
parser.add_argument(
|
||||
"--max-piper-procs",
|
||||
type=int,
|
||||
default=1,
|
||||
help="Maximum number of piper process to run simultaneously (default: 1)",
|
||||
)
|
||||
#
|
||||
parser.add_argument(
|
||||
"--update-voices",
|
||||
action="store_true",
|
||||
help="Download latest voices.json during startup",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--cuda",
|
||||
action="store_true",
|
||||
help="Use GPU"
|
||||
)
|
||||
#
|
||||
parser.add_argument("--debug", action="store_true", help="Log DEBUG messages")
|
||||
parser.add_argument(
|
||||
"--version",
|
||||
action="version",
|
||||
version=__version__,
|
||||
help="Print version and exit",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
if not args.download_dir:
|
||||
# Default to first data directory
|
||||
args.download_dir = args.data_dir[0]
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG if args.debug else logging.INFO)
|
||||
_LOGGER.debug(args)
|
||||
|
||||
# Load voice info
|
||||
voices_info = get_voices(args.download_dir, update_voices=args.update_voices)
|
||||
|
||||
# Resolve aliases for backwards compatibility with old voice names
|
||||
aliases_info: Dict[str, Any] = {}
|
||||
for voice_info in voices_info.values():
|
||||
for voice_alias in voice_info.get("aliases", []):
|
||||
aliases_info[voice_alias] = {"_is_alias": True, **voice_info}
|
||||
|
||||
voices_info.update(aliases_info)
|
||||
voices = [
|
||||
TtsVoice(
|
||||
name=voice_name,
|
||||
description=get_description(voice_info),
|
||||
attribution=Attribution(
|
||||
name="rhasspy", url="https://github.com/rhasspy/piper"
|
||||
),
|
||||
installed=True,
|
||||
version=None,
|
||||
languages=[
|
||||
voice_info.get("language", {}).get(
|
||||
"code",
|
||||
voice_info.get("espeak", {}).get("voice", voice_name.split("_")[0]),
|
||||
)
|
||||
],
|
||||
speakers=[
|
||||
TtsVoiceSpeaker(name=speaker_name)
|
||||
for speaker_name in voice_info["speaker_id_map"]
|
||||
]
|
||||
if voice_info.get("speaker_id_map")
|
||||
else None,
|
||||
)
|
||||
for voice_name, voice_info in voices_info.items()
|
||||
if not voice_info.get("_is_alias", False)
|
||||
]
|
||||
|
||||
custom_voice_names: Set[str] = set()
|
||||
if args.voice not in voices_info:
|
||||
custom_voice_names.add(args.voice)
|
||||
|
||||
for data_dir in args.data_dir:
|
||||
data_dir = Path(data_dir)
|
||||
if not data_dir.is_dir():
|
||||
continue
|
||||
|
||||
for onnx_path in data_dir.glob("*.onnx"):
|
||||
custom_voice_name = onnx_path.stem
|
||||
if custom_voice_name not in voices_info:
|
||||
custom_voice_names.add(custom_voice_name)
|
||||
|
||||
for custom_voice_name in custom_voice_names:
|
||||
# Add custom voice info
|
||||
custom_voice_path, custom_config_path = find_voice(
|
||||
custom_voice_name, args.data_dir
|
||||
)
|
||||
with open(custom_config_path, "r", encoding="utf-8") as custom_config_file:
|
||||
custom_config = json.load(custom_config_file)
|
||||
custom_name = custom_config.get("dataset", custom_voice_path.stem)
|
||||
custom_quality = custom_config.get("audio", {}).get("quality")
|
||||
if custom_quality:
|
||||
description = f"{custom_name} ({custom_quality})"
|
||||
else:
|
||||
description = custom_name
|
||||
|
||||
lang_code = custom_config.get("language", {}).get("code")
|
||||
if not lang_code:
|
||||
lang_code = custom_config.get("espeak", {}).get("voice")
|
||||
if not lang_code:
|
||||
lang_code = custom_voice_path.stem.split("_")[0]
|
||||
|
||||
voices.append(
|
||||
TtsVoice(
|
||||
name=custom_name,
|
||||
description=description,
|
||||
version=None,
|
||||
attribution=Attribution(name="", url=""),
|
||||
installed=True,
|
||||
languages=[lang_code],
|
||||
)
|
||||
)
|
||||
|
||||
wyoming_info = Info(
|
||||
tts=[
|
||||
TtsProgram(
|
||||
name="piper",
|
||||
description="A fast, local, neural text to speech engine",
|
||||
attribution=Attribution(
|
||||
name="rhasspy", url="https://github.com/rhasspy/piper"
|
||||
),
|
||||
installed=True,
|
||||
voices=sorted(voices, key=lambda v: v.name),
|
||||
version=__version__,
|
||||
)
|
||||
],
|
||||
)
|
||||
|
||||
process_manager = PiperProcessManager(args, voices_info)
|
||||
|
||||
# Make sure default voice is loaded.
|
||||
# Other voices will be loaded on-demand.
|
||||
await process_manager.get_process()
|
||||
|
||||
# Start server
|
||||
server = AsyncServer.from_uri(args.uri)
|
||||
|
||||
_LOGGER.info("Ready")
|
||||
await server.run(
|
||||
partial(
|
||||
PiperEventHandler,
|
||||
wyoming_info,
|
||||
args,
|
||||
process_manager,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
def get_description(voice_info: Dict[str, Any]):
|
||||
"""Get a human readable description for a voice."""
|
||||
name = voice_info["name"]
|
||||
name = " ".join(name.split("_"))
|
||||
quality = voice_info["quality"]
|
||||
|
||||
return f"{name} ({quality})"
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
def run():
|
||||
asyncio.run(main())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
run()
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
@@ -1,174 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
import argparse
|
||||
import asyncio
|
||||
import json
|
||||
import logging
|
||||
import tempfile
|
||||
import time
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, Dict, Optional
|
||||
|
||||
from .download import ensure_voice_exists, find_voice
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@dataclass
|
||||
class PiperProcess:
|
||||
"""Info for a running Piper process (one voice)."""
|
||||
|
||||
name: str
|
||||
proc: "asyncio.subprocess.Process"
|
||||
config: Dict[str, Any]
|
||||
wav_dir: tempfile.TemporaryDirectory
|
||||
last_used: int = 0
|
||||
|
||||
def get_speaker_id(self, speaker: str) -> Optional[int]:
|
||||
"""Get speaker by name or id."""
|
||||
return _get_speaker_id(self.config, speaker)
|
||||
|
||||
@property
|
||||
def is_multispeaker(self) -> bool:
|
||||
"""True if model has more than one speaker."""
|
||||
return _is_multispeaker(self.config)
|
||||
|
||||
|
||||
def _get_speaker_id(config: Dict[str, Any], speaker: str) -> Optional[int]:
|
||||
"""Get speaker by name or id."""
|
||||
speaker_id_map = config.get("speaker_id_map", {})
|
||||
speaker_id = speaker_id_map.get(speaker)
|
||||
if speaker_id is None:
|
||||
try:
|
||||
# Try to interpret as an id
|
||||
speaker_id = int(speaker)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
return speaker_id
|
||||
|
||||
|
||||
def _is_multispeaker(config: Dict[str, Any]) -> bool:
|
||||
"""True if model has more than one speaker."""
|
||||
return config.get("num_speakers", 1) > 1
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
class PiperProcessManager:
|
||||
"""Manager of running Piper processes."""
|
||||
|
||||
def __init__(self, args: argparse.Namespace, voices_info: Dict[str, Any]):
|
||||
self.voices_info = voices_info
|
||||
self.args = args
|
||||
self.processes: Dict[str, PiperProcess] = {}
|
||||
self.processes_lock = asyncio.Lock()
|
||||
|
||||
async def get_process(self, voice_name: Optional[str] = None) -> PiperProcess:
|
||||
"""Get a running Piper process or start a new one if necessary."""
|
||||
voice_speaker: Optional[str] = None
|
||||
if voice_name is None:
|
||||
# Default voice
|
||||
voice_name = self.args.voice
|
||||
|
||||
if voice_name == self.args.voice:
|
||||
# Default speaker
|
||||
voice_speaker = self.args.speaker
|
||||
|
||||
assert voice_name is not None
|
||||
|
||||
# Resolve alias
|
||||
voice_info = self.voices_info.get(voice_name, {})
|
||||
voice_name = voice_info.get("key", voice_name)
|
||||
assert voice_name is not None
|
||||
|
||||
piper_proc = self.processes.get(voice_name)
|
||||
if (piper_proc is None) or (piper_proc.proc.returncode is not None):
|
||||
# Remove if stopped
|
||||
self.processes.pop(voice_name, None)
|
||||
|
||||
# Start new Piper process
|
||||
if self.args.max_piper_procs > 0:
|
||||
# Restrict number of running processes
|
||||
while len(self.processes) >= self.args.max_piper_procs:
|
||||
# Stop least recently used process
|
||||
lru_proc_name, lru_proc = sorted(
|
||||
self.processes.items(), key=lambda kv: kv[1].last_used
|
||||
)[0]
|
||||
_LOGGER.debug("Stopping process for: %s", lru_proc_name)
|
||||
self.processes.pop(lru_proc_name, None)
|
||||
if lru_proc.proc.returncode is None:
|
||||
try:
|
||||
lru_proc.proc.terminate()
|
||||
await lru_proc.proc.wait()
|
||||
except Exception:
|
||||
_LOGGER.exception("Unexpected error stopping piper process")
|
||||
|
||||
_LOGGER.debug(
|
||||
"Starting process for: %s (%s/%s)",
|
||||
voice_name,
|
||||
len(self.processes) + 1,
|
||||
self.args.max_piper_procs,
|
||||
)
|
||||
|
||||
ensure_voice_exists(
|
||||
voice_name,
|
||||
self.args.data_dir,
|
||||
self.args.download_dir,
|
||||
self.voices_info,
|
||||
)
|
||||
|
||||
onnx_path, config_path = find_voice(voice_name, self.args.data_dir)
|
||||
with open(config_path, "r", encoding="utf-8") as config_file:
|
||||
config = json.load(config_file)
|
||||
|
||||
wav_dir = tempfile.TemporaryDirectory()
|
||||
piper_args = [
|
||||
"--model",
|
||||
str(onnx_path),
|
||||
"--config",
|
||||
str(config_path),
|
||||
"--output_dir",
|
||||
str(wav_dir.name),
|
||||
"--json-input", # piper 1.1+
|
||||
]
|
||||
|
||||
if voice_speaker is not None:
|
||||
if _is_multispeaker(config):
|
||||
speaker_id = _get_speaker_id(config, voice_speaker)
|
||||
if speaker_id is not None:
|
||||
piper_args.extend(["--speaker", str(speaker_id)])
|
||||
|
||||
if self.args.noise_scale:
|
||||
piper_args.extend(["--noise-scale", str(self.args.noise_scale)])
|
||||
|
||||
if self.args.length_scale:
|
||||
piper_args.extend(["--length-scale", str(self.args.length_scale)])
|
||||
|
||||
if self.args.noise_w:
|
||||
piper_args.extend(["--noise-w", str(self.args.noise_w)])
|
||||
|
||||
if self.args.cuda:
|
||||
piper_args.extend(["--cuda"])
|
||||
|
||||
_LOGGER.debug(
|
||||
"Starting piper process: %s args=%s", self.args.piper, piper_args
|
||||
)
|
||||
piper_proc = PiperProcess(
|
||||
name=voice_name,
|
||||
proc=await asyncio.create_subprocess_exec(
|
||||
self.args.piper,
|
||||
*piper_args,
|
||||
stdin=asyncio.subprocess.PIPE,
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.DEVNULL,
|
||||
),
|
||||
config=config,
|
||||
wav_dir=wav_dir,
|
||||
)
|
||||
self.processes[voice_name] = piper_proc
|
||||
|
||||
# Update used
|
||||
piper_proc.last_used = time.monotonic_ns()
|
||||
|
||||
return piper_proc
|
||||
@@ -1,11 +1,9 @@
|
||||
diff --git a/wyoming_piper/__main__.py b/wyoming_piper/__main__.py
|
||||
index 08b20f1..f88312b 100755
|
||||
--- a/wyoming_piper/__main__.py
|
||||
+++ b/wyoming_piper/__main__.py
|
||||
@@ -77,6 +77,15 @@ async def main() -> None:
|
||||
version=__version__,
|
||||
help="Print version and exit",
|
||||
--- __main__.py 2025-01-04 17:48:27.645862671 +0000
|
||||
+++ __main__.py.patched 2025-01-04 17:51:50.193357609 +0000
|
||||
@@ -66,6 +66,15 @@
|
||||
help="Download latest voices.json during startup",
|
||||
)
|
||||
#
|
||||
+ parser.add_argument(
|
||||
+ "--cuda",
|
||||
+ action="store_true",
|
||||
@@ -15,14 +13,13 @@ index 08b20f1..f88312b 100755
|
||||
+ "--espeak-data-dir",
|
||||
+ help="Path to espeak-ng data directory"
|
||||
+ )
|
||||
parser.add_argument("--debug", action="store_true", help="Log DEBUG messages")
|
||||
args = parser.parse_args()
|
||||
|
||||
if not args.download_dir:
|
||||
diff --git a/wyoming_piper/process.py b/wyoming_piper/process.py
|
||||
index a7e90a7..98b0712 100644
|
||||
--- a/wyoming_piper/process.py
|
||||
+++ b/wyoming_piper/process.py
|
||||
@@ -148,6 +148,14 @@ class PiperProcessManager:
|
||||
|
||||
--- process.py 2025-01-04 17:48:27.653862810 +0000
|
||||
+++ process.py.patched 2025-01-04 17:52:48.494362993 +0000
|
||||
@@ -148,6 +148,14 @@
|
||||
if self.args.noise_w:
|
||||
piper_args.extend(["--noise-w", str(self.args.noise_w)])
|
||||
|
||||
@@ -36,4 +33,4 @@ index a7e90a7..98b0712 100644
|
||||
+
|
||||
_LOGGER.debug(
|
||||
"Starting piper process: %s args=%s", self.args.piper, piper_args
|
||||
)
|
||||
)
|
||||
@@ -1,10 +1,14 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib/python3.10/dist-packages/nvidia/cudnn/lib/:/usr/local/lib/python3.10/dist-packages/nvidia/cublas/lib:/usr/local/lib/python3.10/dist-packages/nvidia/curand/lib/:/usr/local/lib/python3.10/dist-packages/nvidia/cufft/lib/:/usr/local/lib/python3.10/dist-packages/nvidia/cuda_runtime/lib/:/usr/local/lib/python3.10/dist-packages/nvidia/cuda_nvrtc/lib/
|
||||
python3 -m wyoming_piper \
|
||||
|
||||
PIPER_CPU="/usr/share/piper/piper"
|
||||
PIPER_GPU="/usr/local/bin/piper"
|
||||
|
||||
source /app/bin/activate
|
||||
/app/bin/python3 -m wyoming_piper \
|
||||
--piper '/usr/local/bin/piper' \
|
||||
--cuda \
|
||||
--uri 'tcp://0.0.0.0:10200' \
|
||||
--data-dir /data \
|
||||
--data-dir /share/piper \
|
||||
--download-dir /data "$@"
|
||||
--download-dir /data --debug "$@"
|
||||
|
||||
Reference in New Issue
Block a user