Spaces:
Running
Running
update
Browse files- .gitignore +3 -3
- Dockerfile +19 -15
- Dockerfile_GPU +22 -18
- bert_vits2/bert_vits2.py +2 -0
- bert_vits2/models.py +1 -1
- docker-compose-gpu.yaml +7 -2
- docker-compose.yaml +3 -1
- gunicorn_config.py +16 -1
- utils/nlp.py +16 -12
- vits-simple-api-installer-latest.sh +266 -34
- vits/text/cantonese.py +1 -1
- vits/text/shanghainese.py +1 -1
.gitignore
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
**/__pycache__
|
| 2 |
/Model/
|
| 3 |
-
/
|
| 4 |
-
/
|
| 5 |
-
/
|
|
|
|
| 1 |
**/__pycache__
|
| 2 |
/Model/
|
| 3 |
+
/logs/
|
| 4 |
+
/cache/
|
| 5 |
+
/upload/
|
Dockerfile
CHANGED
|
@@ -5,31 +5,35 @@ WORKDIR /app
|
|
| 5 |
|
| 6 |
ENV DEBIAN_FRONTEND=noninteractive
|
| 7 |
|
| 8 |
-
COPY . /app
|
| 9 |
-
|
| 10 |
RUN apt-get update && \
|
| 11 |
apt-get install -yq build-essential espeak-ng cmake wget && \
|
| 12 |
apt-get clean && \
|
| 13 |
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false && \
|
| 14 |
-
rm -rf /var/lib/apt/lists/*
|
| 15 |
|
| 16 |
-
|
| 17 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
|
| 19 |
-
|
| 20 |
-
tar -zxvf openjtalk-0.3.0.dev2.tar.gz && \
|
| 21 |
-
cd openjtalk-0.3.0.dev2 && \
|
| 22 |
-
rm -rf ./pyopenjtalk/open_jtalk_dic_utf_8-1.11 && \
|
| 23 |
-
python setup.py install && \
|
| 24 |
-
cd ../ && \
|
| 25 |
-
rm -f openjtalk-0.3.0.dev2.tar.gz && \
|
| 26 |
-
rm -rf openjtalk-0.3.0.dev2
|
| 27 |
|
| 28 |
RUN pip install torch --index-url https://download.pytorch.org/whl/cpu --no-cache-dir
|
| 29 |
|
| 30 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 31 |
|
| 32 |
-
|
| 33 |
|
| 34 |
EXPOSE 23456
|
| 35 |
|
|
|
|
| 5 |
|
| 6 |
ENV DEBIAN_FRONTEND=noninteractive
|
| 7 |
|
|
|
|
|
|
|
| 8 |
RUN apt-get update && \
|
| 9 |
apt-get install -yq build-essential espeak-ng cmake wget && \
|
| 10 |
apt-get clean && \
|
| 11 |
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false && \
|
| 12 |
+
rm -rf /var/lib/apt/lists/*
|
| 13 |
|
| 14 |
+
# Install jemalloc
|
| 15 |
+
RUN wget https://github.com/jemalloc/jemalloc/releases/download/5.3.0/jemalloc-5.3.0.tar.bz2 && \
|
| 16 |
+
tar -xvf jemalloc-5.3.0.tar.bz2 && \
|
| 17 |
+
cd jemalloc-5.3.0 && \
|
| 18 |
+
./configure && \
|
| 19 |
+
make && \
|
| 20 |
+
make install && \
|
| 21 |
+
cd .. && \
|
| 22 |
+
rm -rf jemalloc-5.3.0* && \
|
| 23 |
+
ldconfig
|
| 24 |
|
| 25 |
+
ENV LD_PRELOAD=/usr/local/lib/libjemalloc.so
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 26 |
|
| 27 |
RUN pip install torch --index-url https://download.pytorch.org/whl/cpu --no-cache-dir
|
| 28 |
|
| 29 |
+
COPY requirements.txt /app/
|
| 30 |
+
RUN pip install --upgrade pip && \
|
| 31 |
+
pip install pyopenjtalk==0.3.2 -i https://pypi.artrajz.cn/simple --no-cache-dir && \
|
| 32 |
+
pip install gunicorn --no-cache-dir && \
|
| 33 |
+
pip install -r requirements.txt --no-cache-dir&& \
|
| 34 |
+
rm -rf /root/.cache/pip/*
|
| 35 |
|
| 36 |
+
COPY . /app
|
| 37 |
|
| 38 |
EXPOSE 23456
|
| 39 |
|
Dockerfile_GPU
CHANGED
|
@@ -1,35 +1,39 @@
|
|
| 1 |
-
FROM
|
| 2 |
|
| 3 |
RUN mkdir -p /app
|
| 4 |
WORKDIR /app
|
| 5 |
|
| 6 |
ENV DEBIAN_FRONTEND=noninteractive
|
| 7 |
|
| 8 |
-
COPY . /app
|
| 9 |
-
|
| 10 |
RUN apt-get update && \
|
| 11 |
-
apt-get install -yq build-essential espeak-ng cmake wget && \
|
|
|
|
| 12 |
apt-get clean && \
|
| 13 |
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false && \
|
| 14 |
-
rm -rf /var/lib/apt/lists/*
|
| 15 |
|
| 16 |
-
RUN pip install --upgrade pip --no-cache-dir && \
|
| 17 |
-
pip install MarkupSafe==2.1.2 numpy==1.23.3 cython six==1.16.0 safetensors==0.3.2 --no-cache-dir
|
| 18 |
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
|
|
|
|
|
|
| 27 |
|
| 28 |
-
|
| 29 |
|
| 30 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 31 |
|
| 32 |
-
|
| 33 |
|
| 34 |
EXPOSE 23456
|
| 35 |
|
|
|
|
| 1 |
+
FROM cnstark/pytorch:2.0.1-py3.10.11-cuda11.8.0-ubuntu22.04
|
| 2 |
|
| 3 |
RUN mkdir -p /app
|
| 4 |
WORKDIR /app
|
| 5 |
|
| 6 |
ENV DEBIAN_FRONTEND=noninteractive
|
| 7 |
|
|
|
|
|
|
|
| 8 |
RUN apt-get update && \
|
| 9 |
+
apt-get install -yq build-essential espeak-ng cmake wget ca-certificates && \
|
| 10 |
+
update-ca-certificates && \
|
| 11 |
apt-get clean && \
|
| 12 |
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false && \
|
| 13 |
+
rm -rf /var/lib/apt/lists/*
|
| 14 |
|
|
|
|
|
|
|
| 15 |
|
| 16 |
+
# Install jemalloc
|
| 17 |
+
RUN wget https://github.com/jemalloc/jemalloc/releases/download/5.3.0/jemalloc-5.3.0.tar.bz2 && \
|
| 18 |
+
tar -xvf jemalloc-5.3.0.tar.bz2 && \
|
| 19 |
+
cd jemalloc-5.3.0 && \
|
| 20 |
+
./configure && \
|
| 21 |
+
make && \
|
| 22 |
+
make install && \
|
| 23 |
+
cd .. && \
|
| 24 |
+
rm -rf jemalloc-5.3.0* && \
|
| 25 |
+
ldconfig
|
| 26 |
|
| 27 |
+
ENV LD_PRELOAD=/usr/local/lib/libjemalloc.so
|
| 28 |
|
| 29 |
+
COPY requirements.txt /app/
|
| 30 |
+
RUN pip install --upgrade pip && \
|
| 31 |
+
pip install pyopenjtalk==0.3.2 fasttext -i https://pypi.artrajz.cn/simple --no-cache-dir && \
|
| 32 |
+
pip install gunicorn --no-cache-dir && \
|
| 33 |
+
pip install -r requirements.txt --no-cache-dir&& \
|
| 34 |
+
rm -rf /root/.cache/pip/*
|
| 35 |
|
| 36 |
+
COPY . /app
|
| 37 |
|
| 38 |
EXPOSE 23456
|
| 39 |
|
bert_vits2/bert_vits2.py
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
|
|
|
|
|
| 1 |
import numpy as np
|
| 2 |
import torch
|
| 3 |
|
|
|
|
| 1 |
+
import re
|
| 2 |
+
|
| 3 |
import numpy as np
|
| 4 |
import torch
|
| 5 |
|
bert_vits2/models.py
CHANGED
|
@@ -643,7 +643,7 @@ class SynthesizerTrn(nn.Module):
|
|
| 643 |
self.sdp = StochasticDurationPredictor(hidden_channels, 192, 3, 0.5, 4, gin_channels=gin_channels)
|
| 644 |
self.dp = DurationPredictor(hidden_channels, 256, 3, 0.5, gin_channels=gin_channels)
|
| 645 |
|
| 646 |
-
if n_speakers
|
| 647 |
self.emb_g = nn.Embedding(n_speakers, gin_channels)
|
| 648 |
else:
|
| 649 |
self.ref_enc = ReferenceEncoder(spec_channels, gin_channels)
|
|
|
|
| 643 |
self.sdp = StochasticDurationPredictor(hidden_channels, 192, 3, 0.5, 4, gin_channels=gin_channels)
|
| 644 |
self.dp = DurationPredictor(hidden_channels, 256, 3, 0.5, gin_channels=gin_channels)
|
| 645 |
|
| 646 |
+
if n_speakers >= 1:
|
| 647 |
self.emb_g = nn.Embedding(n_speakers, gin_channels)
|
| 648 |
else:
|
| 649 |
self.ref_enc = ReferenceEncoder(spec_channels, gin_channels)
|
docker-compose-gpu.yaml
CHANGED
|
@@ -1,4 +1,5 @@
|
|
| 1 |
-
version: '3.
|
|
|
|
| 2 |
services:
|
| 3 |
vits:
|
| 4 |
image: artrajz/vits-simple-api:latest-gpu
|
|
@@ -13,4 +14,8 @@ services:
|
|
| 13 |
- ./config.py:/app/config.py # 挂载配置文件
|
| 14 |
- ./logs:/app/logs # logging logs
|
| 15 |
- ./gunicorn_config.py:/app/gunicorn_config.py # gunicorn configuration
|
| 16 |
-
- ./
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version: '3.8'
|
| 2 |
+
|
| 3 |
services:
|
| 4 |
vits:
|
| 5 |
image: artrajz/vits-simple-api:latest-gpu
|
|
|
|
| 14 |
- ./config.py:/app/config.py # 挂载配置文件
|
| 15 |
- ./logs:/app/logs # logging logs
|
| 16 |
- ./gunicorn_config.py:/app/gunicorn_config.py # gunicorn configuration
|
| 17 |
+
- ./vits/bert:/app/vits/bert # vits_chinese
|
| 18 |
+
- ./bert_vits2/bert/chinese-roberta-wwm-ext-large:/app/bert_vits2/bert/chinese-roberta-wwm-ext-large # Bert-vits2
|
| 19 |
+
- ./pyopenjtalk/open_jtalk_dic_utf_8-1.11:/usr/local/lib/python3.10/site-packages/pyopenjtalk/open_jtalk_dic_utf_8-1.11 #pyopentjalk
|
| 20 |
+
devices:
|
| 21 |
+
- "/dev/nvidia0:/dev/nvidia0"
|
docker-compose.yaml
CHANGED
|
@@ -13,4 +13,6 @@ services:
|
|
| 13 |
- ./config.py:/app/config.py # 挂载配置文件
|
| 14 |
- ./logs:/app/logs # logging logs
|
| 15 |
- ./gunicorn_config.py:/app/gunicorn_config.py # gunicorn configuration
|
| 16 |
-
- ./
|
|
|
|
|
|
|
|
|
| 13 |
- ./config.py:/app/config.py # 挂载配置文件
|
| 14 |
- ./logs:/app/logs # logging logs
|
| 15 |
- ./gunicorn_config.py:/app/gunicorn_config.py # gunicorn configuration
|
| 16 |
+
- ./vits/bert:/app/vits/bert # vits_chinese
|
| 17 |
+
- ./bert_vits2/bert/chinese-roberta-wwm-ext-large:/app/bert_vits2/bert/chinese-roberta-wwm-ext-large # Bert-vits2
|
| 18 |
+
- ./pyopenjtalk/open_jtalk_dic_utf_8-1.11:/usr/local/lib/python3.10/site-packages/pyopenjtalk/open_jtalk_dic_utf_8-1.11 #pyopentjalk
|
gunicorn_config.py
CHANGED
|
@@ -1,4 +1,19 @@
|
|
|
|
|
| 1 |
import multiprocessing
|
| 2 |
|
| 3 |
bind = "0.0.0.0:23456"
|
| 4 |
-
workers = multiprocessing.cpu_count()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gc
|
| 2 |
import multiprocessing
|
| 3 |
|
| 4 |
bind = "0.0.0.0:23456"
|
| 5 |
+
# workers = multiprocessing.cpu_count()
|
| 6 |
+
workers = 1
|
| 7 |
+
preload_app = True
|
| 8 |
+
|
| 9 |
+
# disable GC in master as early as possible
|
| 10 |
+
gc.disable()
|
| 11 |
+
|
| 12 |
+
def when_ready(server):
|
| 13 |
+
# freeze objects after preloading app
|
| 14 |
+
gc.freeze()
|
| 15 |
+
print("Objects frozen in perm gen: ", gc.get_freeze_count())
|
| 16 |
+
|
| 17 |
+
def post_fork(server, worker):
|
| 18 |
+
# reenable GC on worker
|
| 19 |
+
gc.enable()
|
utils/nlp.py
CHANGED
|
@@ -3,6 +3,9 @@ import config
|
|
| 3 |
from .utils import check_is_none
|
| 4 |
from logger import logger
|
| 5 |
|
|
|
|
|
|
|
|
|
|
| 6 |
|
| 7 |
def clasify_lang(text, speaker_lang):
|
| 8 |
pattern = r'[\!\"\#\$\%\&\'\(\)\*\+\,\-\.\/\:\;\<\>\=\?\@\[\]\{\}\\\\\^\_\`' \
|
|
@@ -12,22 +15,23 @@ def clasify_lang(text, speaker_lang):
|
|
| 12 |
|
| 13 |
pre = ""
|
| 14 |
p = 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
for word in words:
|
| 16 |
|
| 17 |
if check_is_none(word): continue
|
| 18 |
|
| 19 |
-
|
| 20 |
-
clf = getattr(config, "LANGUAGE_IDENTIFICATION_LIBRARY", "fastlid")
|
| 21 |
-
if clf.upper() == "FASTLID" or clf.upper() == "FASTTEXT":
|
| 22 |
-
from fastlid import fastlid
|
| 23 |
-
lang = fastlid(word)[0]
|
| 24 |
-
if speaker_lang != None: fastlid.set_languages = speaker_lang
|
| 25 |
-
elif clf.upper() == "LANGID":
|
| 26 |
-
import langid
|
| 27 |
-
lang = langid.classify(word)[0]
|
| 28 |
-
if speaker_lang != None: langid.set_languages(speaker_lang)
|
| 29 |
-
else:
|
| 30 |
-
raise ValueError(f"Wrong LANGUAGE_IDENTIFICATION_LIBRARY in config.py")
|
| 31 |
|
| 32 |
if pre == "":
|
| 33 |
text = text[:p] + text[p:].replace(word, f'[{lang.upper()}]' + word, 1)
|
|
|
|
| 3 |
from .utils import check_is_none
|
| 4 |
from logger import logger
|
| 5 |
|
| 6 |
+
# 读取配置选择语种识别库
|
| 7 |
+
clf = getattr(config, "LANGUAGE_IDENTIFICATION_LIBRARY", "fastlid")
|
| 8 |
+
|
| 9 |
|
| 10 |
def clasify_lang(text, speaker_lang):
|
| 11 |
pattern = r'[\!\"\#\$\%\&\'\(\)\*\+\,\-\.\/\:\;\<\>\=\?\@\[\]\{\}\\\\\^\_\`' \
|
|
|
|
| 15 |
|
| 16 |
pre = ""
|
| 17 |
p = 0
|
| 18 |
+
|
| 19 |
+
if clf.upper() == "FASTLID" or clf.upper() == "FASTTEXT":
|
| 20 |
+
from fastlid import fastlid
|
| 21 |
+
detect = fastlid
|
| 22 |
+
if speaker_lang != None: fastlid.set_languages = speaker_lang
|
| 23 |
+
elif clf.upper() == "LANGID":
|
| 24 |
+
import langid
|
| 25 |
+
detect = langid.classify
|
| 26 |
+
if speaker_lang != None: langid.set_languages(speaker_lang)
|
| 27 |
+
else:
|
| 28 |
+
raise ValueError(f"Wrong LANGUAGE_IDENTIFICATION_LIBRARY in config.py")
|
| 29 |
+
|
| 30 |
for word in words:
|
| 31 |
|
| 32 |
if check_is_none(word): continue
|
| 33 |
|
| 34 |
+
lang = detect(word)[0]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 35 |
|
| 36 |
if pre == "":
|
| 37 |
text = text[:p] + text[p:].replace(word, f'[{lang.upper()}]' + word, 1)
|
vits-simple-api-installer-latest.sh
CHANGED
|
@@ -5,48 +5,280 @@ GREEN='\033[0;32m'
|
|
| 5 |
YELLOW='\033[0;33m'
|
| 6 |
PLAIN='\033[0m'
|
| 7 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
mkdir -p $INSTALL_DIR
|
| 9 |
cd $INSTALL_DIR
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
if [ ! -f config.py ]; then
|
| 11 |
-
|
| 12 |
-
|
|
|
|
| 13 |
fi
|
| 14 |
|
| 15 |
if [ ! -f gunicorn_config.py ]; then
|
| 16 |
-
|
| 17 |
-
|
|
|
|
| 18 |
fi
|
| 19 |
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 41 |
|
| 42 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 43 |
|
| 44 |
-
|
| 45 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 46 |
|
| 47 |
-
echo -e "\
|
| 48 |
-
echo -e "
|
| 49 |
-
echo -e "${YELLOW}
|
| 50 |
-
echo -e "
|
| 51 |
-
echo -e "${
|
| 52 |
-
echo -e "
|
|
|
|
| 5 |
YELLOW='\033[0;33m'
|
| 6 |
PLAIN='\033[0m'
|
| 7 |
|
| 8 |
+
declare -A EN_MESSAGES
|
| 9 |
+
declare -A ZH_MESSAGES
|
| 10 |
+
|
| 11 |
+
EN_MESSAGES=(
|
| 12 |
+
["ATTEMPT_DOWNLOAD"]="Attempting to download"
|
| 13 |
+
["FROM"]="from"
|
| 14 |
+
["DOWNLOAD_FAIL"]="Failed to download"
|
| 15 |
+
["FROM_ALL_URLS"]="from all provided URLs."
|
| 16 |
+
["DOWNLOADING"]="Downloading..."
|
| 17 |
+
["VERIFYING"]="Verifying..."
|
| 18 |
+
["UNZIPPING"]="Unzipping..."
|
| 19 |
+
["CHOOSE_VERSION"]="Which version of docker-compose.yaml do you want to download?"
|
| 20 |
+
["DOCKER_CPU"]="docker-compose.yaml (CPU version)"
|
| 21 |
+
["DOCKER_GPU"]="docker-compose-gpu.yaml (GPU version)"
|
| 22 |
+
["ENTER_CHOICE"]="Enter your choice (1 or 2): "
|
| 23 |
+
["INVALID_CHOICE"]="Invalid choice. Please enter 1 or 2."
|
| 24 |
+
["DOWNLOAD_CONFIG"]="Downloading configuration file shortly..."
|
| 25 |
+
["PULL_IMAGE"]="Do you want to start pulling the image? Enter 1 for yes or 2 for no"
|
| 26 |
+
["DOWNLOAD_DICT"]="Do you want to download the pyopenjtalk dictionary file? Enter 1 for yes or 2 for no"
|
| 27 |
+
["MUST_DOWNLOAD_JP"]="Japanese model must be downloaded."
|
| 28 |
+
["DOWNLOAD_VITS_CHINESE"]="Do you want to download the bert model for vits_chinese? Enter 1 for yes, 2 for no."
|
| 29 |
+
["MUST_DOWNLOAD_VITS_CHINESE"]="Using vits_chinese requires downloading these models, which will take up about 410MB."
|
| 30 |
+
["DOWNLOAD_BERT_VITS2"]="Do you want to download chinese-roberta-wwm-ext-large? Enter 1 for yes or 2 for no"
|
| 31 |
+
["MUST_DOWNLOAD_BERT_VITS2"]="To use Bert-VITS2, you must download these models, which will take up about 3.64GB."
|
| 32 |
+
["DOWNLOADED"]="File is downloaded correctly."
|
| 33 |
+
["CORRUPTED"]="File is corrupted or incomplete."
|
| 34 |
+
["INSTALL_COMPLETE"]="The upgrade or installation has been completed."
|
| 35 |
+
["CONFIG_DIR"]="The configuration file directory is"
|
| 36 |
+
["IMPORT_NOTICE"]="If the vits model is not imported, it cannot be used. Import the model in the configuration file directory."
|
| 37 |
+
["RESTART_NOTICE"]="After modifying the configuration file, restart the docker container for the modification to take effect."
|
| 38 |
+
["ISSUE_NOTICE"]="If you have any questions, please put them in the issues."
|
| 39 |
+
["GITHUB_LINK"]="https://github.com/Artrajz/vits-simple-api"
|
| 40 |
+
)
|
| 41 |
+
|
| 42 |
+
ZH_MESSAGES=(
|
| 43 |
+
["ATTEMPT_DOWNLOAD"]="正在尝试下载"
|
| 44 |
+
["FROM"]="从"
|
| 45 |
+
["DOWNLOAD_FAIL"]="都下载失败"
|
| 46 |
+
["FROM_ALL_URLS"]="从所有提供的URLs"
|
| 47 |
+
["DOWNLOADING"]="正在下载..."
|
| 48 |
+
["VERIFYING"]="正在校验"
|
| 49 |
+
["UNZIPPING"]="正在解压..."
|
| 50 |
+
["CHOOSE_VERSION"]="你想下载哪个版本的docker-compose.yaml?"
|
| 51 |
+
["DOCKER_CPU"]="docker-compose.yaml (CPU版本)"
|
| 52 |
+
["DOCKER_GPU"]="docker-compose-gpu.yaml (GPU版本)"
|
| 53 |
+
["ENTER_CHOICE"]="请输入您的选择 (1 或 2): "
|
| 54 |
+
["INVALID_CHOICE"]="无效选择。 请重新输入 1 或 2。"
|
| 55 |
+
["DOWNLOAD_CONFIG"]="即将下载配置文件..."
|
| 56 |
+
["PULL_IMAGE"]="是否要开始拉取镜像?输入1表示是,2表示否。"
|
| 57 |
+
["DOWNLOAD_DICT"]="是否要下载pyopenjtalk的词典文件?输入1表示是,2表示否。"
|
| 58 |
+
["MUST_DOWNLOAD_JP"]="使用日语模型必须下载该词典文件,将占用大约102MB。"
|
| 59 |
+
["DOWNLOAD_VITS_CHINESE"]="是否要下载vits_chinese的bert模型?输入1表示是,2表示否。"
|
| 60 |
+
["MUST_DOWNLOAD_VITS_CHINESE"]="使用vits_chinese必须下载这些模型,将占用大约410MB。"
|
| 61 |
+
["DOWNLOAD_BERT_VITS2"]="是否要下载chinese-roberta-wwm-ext-large?输入1表示是,2表示否。"
|
| 62 |
+
["MUST_DOWNLOAD_BERT_VITS2"]="使用Bert-VITS2必须下载这些模型,将占用大约3.64GB。"
|
| 63 |
+
["DOWNLOADED"]="文件已正确下载。"
|
| 64 |
+
["CORRUPTED"]="文件已损坏或不完整。"
|
| 65 |
+
["INSTALL_COMPLETE"]="更新或安装已完成。"
|
| 66 |
+
["CONFIG_DIR"]="配置文件目录是"
|
| 67 |
+
["IMPORT_NOTICE"]="如果vits模型没有被导入,它是无法使用的。请在配置文件目录中导入模型。"
|
| 68 |
+
["RESTART_NOTICE"]="修改配置文件后,请重启docker容器以使修改生效。"
|
| 69 |
+
["ISSUE_NOTICE"]="如果你有任何问题,请在issues中提出,或者加入q群提问。"
|
| 70 |
+
["GITHUB_LINK"]="https://github.com/Artrajz/vits-simple-api"
|
| 71 |
+
)
|
| 72 |
+
|
| 73 |
+
echo -e "${PLAIN}${GREEN}Choose a language/选择语言: ${PLAIN}"
|
| 74 |
+
echo "1. English"
|
| 75 |
+
echo "2. 中文"
|
| 76 |
+
read -p "Enter your choice (1 or 2): " choice_language
|
| 77 |
+
|
| 78 |
+
declare -A MESSAGES
|
| 79 |
+
if [ "$choice_language" -eq 1 ]; then
|
| 80 |
+
for key in "${!EN_MESSAGES[@]}"; do
|
| 81 |
+
MESSAGES["$key"]="${EN_MESSAGES[$key]}"
|
| 82 |
+
done
|
| 83 |
+
else
|
| 84 |
+
for key in "${!ZH_MESSAGES[@]}"; do
|
| 85 |
+
MESSAGES["$key"]="${ZH_MESSAGES[$key]}"
|
| 86 |
+
done
|
| 87 |
+
fi
|
| 88 |
+
|
| 89 |
mkdir -p $INSTALL_DIR
|
| 90 |
cd $INSTALL_DIR
|
| 91 |
+
|
| 92 |
+
download_with_fallback() {
|
| 93 |
+
local filename=$1
|
| 94 |
+
shift # Shift arguments to the left to handle URLs
|
| 95 |
+
|
| 96 |
+
local success=0
|
| 97 |
+
local url
|
| 98 |
+
for url in "$@"; do
|
| 99 |
+
echo -e "${YELLOW}${MESSAGES["ATTEMPT_DOWNLOAD"]} $filename ${MESSAGES["FROM"]} $url\n${PLAIN}"
|
| 100 |
+
if wget -O "$INSTALL_DIR/$filename" "$url"; then
|
| 101 |
+
success=1
|
| 102 |
+
break
|
| 103 |
+
fi
|
| 104 |
+
done
|
| 105 |
+
|
| 106 |
+
if [ "$success" -ne 1 ]; then
|
| 107 |
+
echo -e "${RED} $filename ${MESSAGES["FROM_ALL_URLS"]} ${MESSAGES["DOWNLOAD_FAIL"]}${PLAIN}"
|
| 108 |
+
exit 1
|
| 109 |
+
fi
|
| 110 |
+
}
|
| 111 |
+
|
| 112 |
+
version_gt() {
|
| 113 |
+
test "$(echo "$@" | tr " " "\n" | sort -V | head -n 1)" != "$1"
|
| 114 |
+
}
|
| 115 |
+
|
| 116 |
+
while true; do
|
| 117 |
+
echo -e "${GREEN}${MESSAGES["CHOOSE_VERSION"]}${PLAIN}"
|
| 118 |
+
echo -e "1. ${MESSAGES["DOCKER_CPU"]}"
|
| 119 |
+
echo -e "2. ${MESSAGES["DOCKER_GPU"]}"
|
| 120 |
+
read -p "${MESSAGES["ENTER_CHOICE"]}" choice_gpu
|
| 121 |
+
case $choice_gpu in
|
| 122 |
+
1)
|
| 123 |
+
echo -e "${MESSAGES["DOWNLOADING"]}"
|
| 124 |
+
download_with_fallback docker-compose.yaml \
|
| 125 |
+
"https://raw.githubusercontent.com/Artrajz/vits-simple-api/main/docker-compose.yaml" \
|
| 126 |
+
"https://ghproxy.com/https://raw.githubusercontent.com/Artrajz/vits-simple-api/main/docker-compose.yaml"
|
| 127 |
+
break
|
| 128 |
+
;;
|
| 129 |
+
2)
|
| 130 |
+
echo -e "${MESSAGES["DOWNLOADING"]}"
|
| 131 |
+
download_with_fallback docker-compose.yaml \
|
| 132 |
+
"https://raw.githubusercontent.com/Artrajz/vits-simple-api/main/docker-compose-gpu.yaml" \
|
| 133 |
+
"https://ghproxy.com/https://raw.githubusercontent.com/Artrajz/vits-simple-api/main/docker-compose-gpu.yaml"
|
| 134 |
+
break
|
| 135 |
+
;;
|
| 136 |
+
*)
|
| 137 |
+
echo -e "${RED}${MESSAGES["INVALID_CHOICE"]}${PLAIN}"
|
| 138 |
+
;;
|
| 139 |
+
esac
|
| 140 |
+
done
|
| 141 |
+
|
| 142 |
+
if [ "$choice_gpu" -eq 2 ]; then
|
| 143 |
+
DOCKER_VERSION=$(docker version --format '{{.Server.Version}}')
|
| 144 |
+
MIN_DOCKER_VERSION="19.03"
|
| 145 |
+
|
| 146 |
+
if version_gt $MIN_DOCKER_VERSION $DOCKER_VERSION; then
|
| 147 |
+
echo -e "${RED}Your Docker version ($DOCKER_VERSION) does not support GPU. You need at least version $MIN_DOCKER_VERSION.${PLAIN}"
|
| 148 |
+
exit 1
|
| 149 |
+
fi
|
| 150 |
+
fi
|
| 151 |
+
|
| 152 |
+
if ! command -v docker-compose &>/dev/null; then
|
| 153 |
+
echo -e "${RED}docker-compose could not be found.${PLAIN}"
|
| 154 |
+
exit 1
|
| 155 |
+
fi
|
| 156 |
+
|
| 157 |
+
echo -e "${GREEN}${MESSAGES["PULL_IMAGE"]}${PLAIN}"
|
| 158 |
+
read -p "${MESSAGES["ENTER_CHOICE"]}" choice_pull
|
| 159 |
+
|
| 160 |
+
if [ "$choice_pull" -eq 1 ]; then
|
| 161 |
+
docker compose pull
|
| 162 |
+
docker compose up -d
|
| 163 |
+
fi
|
| 164 |
+
|
| 165 |
+
echo -e "${YELLOW}${MESSAGES["DOWNLOAD_CONFIG"]}${PLAIN}"
|
| 166 |
+
|
| 167 |
if [ ! -f config.py ]; then
|
| 168 |
+
download_with_fallback config.py \
|
| 169 |
+
"https://raw.githubusercontent.com/Artrajz/vits-simple-api/main/config.py" \
|
| 170 |
+
"https://ghproxy.com/https://raw.githubusercontent.com/Artrajz/vits-simple-api/main/config.py"
|
| 171 |
fi
|
| 172 |
|
| 173 |
if [ ! -f gunicorn_config.py ]; then
|
| 174 |
+
download_with_fallback gunicorn_config.py \
|
| 175 |
+
"https://raw.githubusercontent.com/Artrajz/vits-simple-api/main/gunicorn_config.py" \
|
| 176 |
+
"https://ghproxy.com/https://raw.githubusercontent.com/Artrajz/vits-simple-api/main/gunicorn_config.py"
|
| 177 |
fi
|
| 178 |
|
| 179 |
+
download_with_fallback config.example.py \
|
| 180 |
+
"https://raw.githubusercontent.com/Artrajz/vits-simple-api/main/config.py" \
|
| 181 |
+
"https://ghproxy.com/https://raw.githubusercontent.com/Artrajz/vits-simple-api/main/config.py"
|
| 182 |
+
|
| 183 |
+
download_with_fallback gunicorn_config.example.py \
|
| 184 |
+
"https://raw.githubusercontent.com/Artrajz/vits-simple-api/main/gunicorn_config.py" \
|
| 185 |
+
"https://ghproxy.com/https://raw.githubusercontent.com/Artrajz/vits-simple-api/main/gunicorn_config.py"
|
| 186 |
+
|
| 187 |
+
echo -e "${GREEN}${MESSAGES["DOWNLOAD_DICT"]}${PLAIN}"
|
| 188 |
+
echo -e "${GREEN}${MESSAGES["MUST_DOWNLOAD_JP"]}${PLAIN}"
|
| 189 |
+
read -p "${MESSAGES["ENTER_CHOICE"]}" choice_download_pyopenjtalk
|
| 190 |
+
|
| 191 |
+
if [ "$choice_download_pyopenjtalk" -eq 1 ]; then
|
| 192 |
+
mkdir -p pyopenjtalk
|
| 193 |
+
echo -e "${MESSAGES["DOWNLOADING"]}"
|
| 194 |
+
download_with_fallback open_jtalk_dic_utf_8-1.11.tar.gz \
|
| 195 |
+
"https://github.com/r9y9/open_jtalk/releases/download/v1.11.1/open_jtalk_dic_utf_8-1.11.tar.gz" \
|
| 196 |
+
"https://ghproxy.com/https://github.com/r9y9/open_jtalk/releases/download/v1.11.1/open_jtalk_dic_utf_8-1.11.tar.gz"
|
| 197 |
+
echo -e "${MESSAGES["UNZIPPING"]}"
|
| 198 |
+
tar -xzvf open_jtalk_dic_utf_8-1.11.tar.gz -C pyopenjtalk/
|
| 199 |
+
rm open_jtalk_dic_utf_8-1.11.tar.gz
|
| 200 |
+
fi
|
| 201 |
+
|
| 202 |
+
echo -e "${GREEN}${MESSAGES["DOWNLOAD_VITS_CHINESE"]}${PLAIN}"
|
| 203 |
+
echo -e "${GREEN}${MESSAGES["MUST_DOWNLOAD_VITS_CHINESE"]}${PLAIN}"
|
| 204 |
+
read -p "${MESSAGES["ENTER_CHOICE"]}" choice_download_vits_chinese
|
| 205 |
+
|
| 206 |
+
if [ "$choice_download_vits_chinese" -eq 1 ]; then
|
| 207 |
+
mkdir -p vits/bert
|
| 208 |
+
|
| 209 |
+
EXPECTED_MD5="dea78034433141adc8002404aa1b3184"
|
| 210 |
+
FILE_PATH="vits/bert/prosody_model.pt"
|
| 211 |
+
echo -e "${MESSAGES["VERIFYING"]}$FILE_PATH"
|
| 212 |
+
ACTUAL_MD5=$(md5sum $FILE_PATH | awk '{print $1}')
|
| 213 |
+
|
| 214 |
+
if [ "$EXPECTED_MD5" == "$ACTUAL_MD5" ]; then
|
| 215 |
+
echo "${MESSAGES["DOWNLOADED"]}"
|
| 216 |
+
else
|
| 217 |
+
echo "${MESSAGES["CORRUPTED"]}"
|
| 218 |
+
download_with_fallback vits/bert/prosody_model.pt \
|
| 219 |
+
"https://huggingface.co/spaces/maxmax20160403/vits_chinese/resolve/main/bert/prosody_model.pt"
|
| 220 |
+
fi
|
| 221 |
+
|
| 222 |
+
fi
|
| 223 |
+
|
| 224 |
+
echo -e "${GREEN}${MESSAGES["DOWNLOAD_BERT_VITS2"]}${PLAIN}"
|
| 225 |
+
echo -e "${GREEN}${MESSAGES["MUST_DOWNLOAD_BERT_VITS2"]}${PLAIN}"
|
| 226 |
+
read -p "${MESSAGES["ENTER_CHOICE"]}" choice_download_bert_vits2
|
| 227 |
+
|
| 228 |
+
if [ "$choice_download_bert_vits2" -eq 1 ]; then
|
| 229 |
+
mkdir -p bert_vits2/bert/chinese-roberta-wwm-ext-large
|
| 230 |
+
|
| 231 |
+
EXPECTED_MD5="78ef42421495cb23372bef9d069a75f3"
|
| 232 |
+
FILE_PATH="bert_vits2/bert/chinese-roberta-wwm-ext-large/flax_model.msgpack"
|
| 233 |
+
echo -e "${MESSAGES["VERIFYING"]}$FILE_PATH"
|
| 234 |
+
ACTUAL_MD5=$(md5sum $FILE_PATH | awk '{print $1}')
|
| 235 |
+
|
| 236 |
+
if [ "$EXPECTED_MD5" == "$ACTUAL_MD5" ]; then
|
| 237 |
+
echo "${MESSAGES["DOWNLOADED"]}"
|
| 238 |
+
else
|
| 239 |
+
echo "${MESSAGES["CORRUPTED"]}"
|
| 240 |
+
download_with_fallback bert_vits2/bert/chinese-roberta-wwm-ext-large/flax_model.msgpack \
|
| 241 |
+
"https://huggingface.co/hfl/chinese-roberta-wwm-ext-large/resolve/main/flax_model.msgpack"
|
| 242 |
+
fi
|
| 243 |
+
|
| 244 |
+
EXPECTED_MD5="15d7435868fef1bd4222ff7820149a2a"
|
| 245 |
+
FILE_PATH="bert_vits2/bert/chinese-roberta-wwm-ext-large/pytorch_model.bin"
|
| 246 |
+
echo -e "${MESSAGES["VERIFYING"]}$FILE_PATH"
|
| 247 |
+
ACTUAL_MD5=$(md5sum $FILE_PATH | awk '{print $1}')
|
| 248 |
|
| 249 |
+
if [ "$EXPECTED_MD5" == "$ACTUAL_MD5" ]; then
|
| 250 |
+
echo "${MESSAGES["DOWNLOADED"]}"
|
| 251 |
+
else
|
| 252 |
+
echo ${MESSAGES["CORRUPTED"]}
|
| 253 |
+
download_with_fallback bert_vits2/bert/chinese-roberta-wwm-ext-large/pytorch_model.bin \
|
| 254 |
+
"https://huggingface.co/hfl/chinese-roberta-wwm-ext-large/resolve/main/pytorch_model.bin"
|
| 255 |
+
fi
|
| 256 |
|
| 257 |
+
EXPECTED_MD5="d15991416bd4a86fa127c70d3c0f4779"
|
| 258 |
+
FILE_PATH="bert_vits2/bert/chinese-roberta-wwm-ext-large/tf_model.h5"
|
| 259 |
+
echo -e "${MESSAGES["VERIFYING"]}$FILE_PATH"
|
| 260 |
+
ACTUAL_MD5=$(md5sum $FILE_PATH | awk '{print $1}')
|
| 261 |
+
|
| 262 |
+
if [ "$EXPECTED_MD5" == "$ACTUAL_MD5" ]; then
|
| 263 |
+
echo "${MESSAGES["DOWNLOADED"]}"
|
| 264 |
+
else
|
| 265 |
+
echo "${MESSAGES["CORRUPTED"]}"
|
| 266 |
+
download_with_fallback bert_vits2/bert/chinese-roberta-wwm-ext-large/tf_model.h5 \
|
| 267 |
+
"https://huggingface.co/hfl/chinese-roberta-wwm-ext-large/resolve/main/tf_model.h5"
|
| 268 |
+
fi
|
| 269 |
+
|
| 270 |
+
fi
|
| 271 |
+
|
| 272 |
+
if [ "$choice_gpu" -eq 2 ]; then
|
| 273 |
+
if ! docker run --gpus all artrajz/vits-simple-api:latest-gpu nvidia-smi &>/dev/null; then
|
| 274 |
+
echo -e "${RED}Your Docker does not seem to support GPU or NVIDIA Docker is not installed properly.${PLAIN}"
|
| 275 |
+
exit 1
|
| 276 |
+
fi
|
| 277 |
+
fi
|
| 278 |
|
| 279 |
+
echo -e "\n${MESSAGES["INSTALL_COMPLETE"]}"
|
| 280 |
+
echo -e "${MESSAGES["CONFIG_DIR"]} $(realpath $INSTALL_DIR)"
|
| 281 |
+
echo -e "${YELLOW}${MESSAGES["IMPORT_NOTICE"]}${PLAIN}"
|
| 282 |
+
echo -e "${YELLOW}${MESSAGES["RESTART_NOTICE"]}${PLAIN}"
|
| 283 |
+
echo -e "${MESSAGES["ISSUE_NOTICE"]}"
|
| 284 |
+
echo -e "${MESSAGES["GITHUB_LINK"]}"
|
vits/text/cantonese.py
CHANGED
|
@@ -3,7 +3,7 @@ import cn2an
|
|
| 3 |
import opencc
|
| 4 |
import config
|
| 5 |
|
| 6 |
-
converter = opencc.OpenCC(config.ABS_PATH + '/chinese_dialect_lexicons/jyutjyu_2')
|
| 7 |
|
| 8 |
# List of (Latin alphabet, ipa) pairs:
|
| 9 |
_latin_to_ipa = [(re.compile('%s' % x[0]), x[1]) for x in [
|
|
|
|
| 3 |
import opencc
|
| 4 |
import config
|
| 5 |
|
| 6 |
+
converter = opencc.OpenCC(config.ABS_PATH + '/vits/text/chinese_dialect_lexicons/jyutjyu_2')
|
| 7 |
|
| 8 |
# List of (Latin alphabet, ipa) pairs:
|
| 9 |
_latin_to_ipa = [(re.compile('%s' % x[0]), x[1]) for x in [
|
vits/text/shanghainese.py
CHANGED
|
@@ -3,7 +3,7 @@ import cn2an
|
|
| 3 |
import opencc
|
| 4 |
import config
|
| 5 |
|
| 6 |
-
converter = opencc.OpenCC(config.ABS_PATH + '/chinese_dialect_lexicons/zaonhe')
|
| 7 |
|
| 8 |
# List of (Latin alphabet, ipa) pairs:
|
| 9 |
_latin_to_ipa = [(re.compile('%s' % x[0]), x[1]) for x in [
|
|
|
|
| 3 |
import opencc
|
| 4 |
import config
|
| 5 |
|
| 6 |
+
converter = opencc.OpenCC(config.ABS_PATH + '/vits/text/chinese_dialect_lexicons/zaonhe')
|
| 7 |
|
| 8 |
# List of (Latin alphabet, ipa) pairs:
|
| 9 |
_latin_to_ipa = [(re.compile('%s' % x[0]), x[1]) for x in [
|