From ece55ffe06c76eaccf16c5771f72c280f3d6ee23 Mon Sep 17 00:00:00 2001 From: Josh XT <102809327+Josh-XT@users.noreply.github.com> Date: Mon, 22 Jan 2024 10:46:10 -0500 Subject: [PATCH 01/25] Create Dockerfile --- Dockerfile | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..1624570 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,8 @@ +FROM python:3.11-slim +WORKDIR /app +COPY . . +# Argument for specifying the GPU type, defaulting to "other" +ARG gpu_type=other +RUN pip install --no-cache-dir -r requirements_${gpu_type}.txt +EXPOSE 7851 +CMD ["python", "script.py"] From 55799b2de8f3d225b12205480b152a933a8426ed Mon Sep 17 00:00:00 2001 From: Josh XT Date: Mon, 22 Jan 2024 10:54:14 -0500 Subject: [PATCH 02/25] Add workflow --- .github/workflows/publish-docker.yml | 51 ++++++++++++++++++++++++++++ Dockerfile | 3 +- 2 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/publish-docker.yml diff --git a/.github/workflows/publish-docker.yml b/.github/workflows/publish-docker.yml new file mode 100644 index 0000000..6f5a605 --- /dev/null +++ b/.github/workflows/publish-docker.yml @@ -0,0 +1,51 @@ +name: Publish Docker image + +on: + push: + branches: [main] + release: + types: [published] + workflow_dispatch: + +jobs: + build_and_push: + runs-on: ubuntu-latest + strategy: + matrix: + include: + - image_name: "python:3.11-slim" + gpu_type: "other" + platforms: "linux/amd64,linux/arm64/v8" + tag_name: "other" + - image_name: "nvidia/cuda:12.1.1-devel-ubuntu22.04" + gpu_type: "nvidia" + platforms: "linux/amd64" + tag_name: "cuda" + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: . + file: ./Dockerfile + platforms: ${{ matrix.platforms }} + push: true + tags: | + ghcr.io/josh-xt/alltalk_tts:${{ matrix.tag_name }} + ghcr.io/josh-xt/alltalk_tts:${{ matrix.tag_name }}-${{ github.sha }} + build-args: | + image_name=${{ matrix.image_name }} + gpu_type=${{ matrix.gpu_type }} diff --git a/Dockerfile b/Dockerfile index 1624570..5a3a349 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,5 @@ -FROM python:3.11-slim +ARG image_name=python:3.11-slim +FROM ${image_name} WORKDIR /app COPY . . # Argument for specifying the GPU type, defaulting to "other" From 61998b4d39385fdc703a17b397fb77c4960ec2bd Mon Sep 17 00:00:00 2001 From: Josh XT Date: Mon, 22 Jan 2024 11:21:15 -0500 Subject: [PATCH 03/25] Set to nvidia --- .github/workflows/publish-docker.yml | 21 +++------------------ Dockerfile | 9 ++++----- 2 files changed, 7 insertions(+), 23 deletions(-) diff --git a/.github/workflows/publish-docker.yml b/.github/workflows/publish-docker.yml index 6f5a605..bdb66b0 100644 --- a/.github/workflows/publish-docker.yml +++ b/.github/workflows/publish-docker.yml @@ -10,18 +10,6 @@ on: jobs: build_and_push: runs-on: ubuntu-latest - strategy: - matrix: - include: - - image_name: "python:3.11-slim" - gpu_type: "other" - platforms: "linux/amd64,linux/arm64/v8" - tag_name: "other" - - image_name: "nvidia/cuda:12.1.1-devel-ubuntu22.04" - gpu_type: "nvidia" - platforms: "linux/amd64" - tag_name: "cuda" - steps: - name: Checkout code uses: actions/checkout@v4 @@ -41,11 +29,8 @@ jobs: with: context: . file: ./Dockerfile - platforms: ${{ matrix.platforms }} + platforms: "linux/amd64" push: true tags: | - ghcr.io/josh-xt/alltalk_tts:${{ matrix.tag_name }} - ghcr.io/josh-xt/alltalk_tts:${{ matrix.tag_name }}-${{ github.sha }} - build-args: | - image_name=${{ matrix.image_name }} - gpu_type=${{ matrix.gpu_type }} + ghcr.io/josh-xt/alltalk_tts:latest + ghcr.io/josh-xt/alltalk_tts:main-${{ github.sha }} diff --git a/Dockerfile b/Dockerfile index 5a3a349..702953c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,8 @@ -ARG image_name=python:3.11-slim -FROM ${image_name} +FROM nvidia/cuda:12.1.1-devel-ubuntu22.04 WORKDIR /app COPY . . -# Argument for specifying the GPU type, defaulting to "other" -ARG gpu_type=other -RUN pip install --no-cache-dir -r requirements_${gpu_type}.txt +RUN pip install --no-cache-dir -r requirements_nvidia.txt && \ + pip install --no-cache-dir -r requirements_finetune.txt && \ + pip install --no-cache-dir -r requirements_other.txt EXPOSE 7851 CMD ["python", "script.py"] From a199adfbd60fc1cac20806aa26d3b3cd95839c8e Mon Sep 17 00:00:00 2001 From: Josh XT Date: Mon, 22 Jan 2024 11:24:54 -0500 Subject: [PATCH 04/25] Add deps --- Dockerfile | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Dockerfile b/Dockerfile index 702953c..b157498 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,15 @@ FROM nvidia/cuda:12.1.1-devel-ubuntu22.04 +ENV HOST 0.0.0.0 +RUN apt-get update && apt-get upgrade -y \ + && apt-get install -y git build-essential \ + python3 python3-pip gcc wget \ + ocl-icd-opencl-dev opencl-headers clinfo \ + libclblast-dev libopenblas-dev \ + && mkdir -p /etc/OpenCL/vendors && echo "libnvidia-opencl.so.1" > /etc/OpenCL/vendors/nvidia.icd WORKDIR /app COPY . . +ENV CUDA_DOCKER_ARCH=all +RUN pip install deepspeed RUN pip install --no-cache-dir -r requirements_nvidia.txt && \ pip install --no-cache-dir -r requirements_finetune.txt && \ pip install --no-cache-dir -r requirements_other.txt From d008c7ab0a07c99b4a806a70ed32a1af8c0e5257 Mon Sep 17 00:00:00 2001 From: Josh XT Date: Mon, 22 Jan 2024 11:27:35 -0500 Subject: [PATCH 05/25] Move install --- Dockerfile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index b157498..5a79e77 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,9 +9,10 @@ RUN apt-get update && apt-get upgrade -y \ WORKDIR /app COPY . . ENV CUDA_DOCKER_ARCH=all -RUN pip install deepspeed + RUN pip install --no-cache-dir -r requirements_nvidia.txt && \ pip install --no-cache-dir -r requirements_finetune.txt && \ - pip install --no-cache-dir -r requirements_other.txt + pip install --no-cache-dir -r requirements_other.txt && \ + pip install --no-cache-dir deepspeed EXPOSE 7851 CMD ["python", "script.py"] From f089e3e85b8f7c437a09fcda6688f273011f3d50 Mon Sep 17 00:00:00 2001 From: Josh XT Date: Mon, 22 Jan 2024 11:45:55 -0500 Subject: [PATCH 06/25] Add multi build --- .github/workflows/publish-docker.yml | 32 ++++++++++++++++++++++++---- Dockerfile | 14 +++--------- nvidia.Dockerfile | 18 ++++++++++++++++ 3 files changed, 49 insertions(+), 15 deletions(-) create mode 100644 nvidia.Dockerfile diff --git a/.github/workflows/publish-docker.yml b/.github/workflows/publish-docker.yml index bdb66b0..570e75e 100644 --- a/.github/workflows/publish-docker.yml +++ b/.github/workflows/publish-docker.yml @@ -10,6 +10,15 @@ on: jobs: build_and_push: runs-on: ubuntu-latest + strategy: + matrix: + include: + - dockerfile: "./Dockerfile" + platforms: "linux/amd64,linux/arm64/v8" + tag_name: "cpu" + - dockerfile: "./nvidia.Dockerfile" + platforms: "linux/amd64" + tag_name: "cuda" steps: - name: Checkout code uses: actions/checkout@v4 @@ -24,13 +33,28 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Login to DockerHub + if: vars.DOCKERHUB_USERNAME != '' + uses: docker/login-action@v3 + with: + username: ${{ vars.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Build and push Docker image uses: docker/build-push-action@v5 with: context: . - file: ./Dockerfile - platforms: "linux/amd64" + file: ${{ matrix.dockerfile }} + platforms: ${{ matrix.platforms }} push: true tags: | - ghcr.io/josh-xt/alltalk_tts:latest - ghcr.io/josh-xt/alltalk_tts:main-${{ github.sha }} + ghcr.io/${{ github.actor }}/alltalk_tts:${{ matrix.tag_name }}-${{ github.sha }} + ghcr.io/${{ github.actor }}/alltalk_tts:${{ matrix.tag_name }} + + - name: Docker Hub Description + if: vars.DOCKERHUB_USERNAME != '' + uses: peter-evans/dockerhub-description@v3.4.2 + with: + username: ${{ vars.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + repository: ${{ vars.DOCKERHUB_USERNAME }}/alltalk_tts diff --git a/Dockerfile b/Dockerfile index 5a79e77..3c329a5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,18 +1,10 @@ -FROM nvidia/cuda:12.1.1-devel-ubuntu22.04 +FROM python:3-slim-bullseye ENV HOST 0.0.0.0 RUN apt-get update && apt-get upgrade -y \ && apt-get install -y git build-essential \ - python3 python3-pip gcc wget \ - ocl-icd-opencl-dev opencl-headers clinfo \ - libclblast-dev libopenblas-dev \ - && mkdir -p /etc/OpenCL/vendors && echo "libnvidia-opencl.so.1" > /etc/OpenCL/vendors/nvidia.icd + python3 python3-pip gcc wget WORKDIR /app COPY . . -ENV CUDA_DOCKER_ARCH=all - -RUN pip install --no-cache-dir -r requirements_nvidia.txt && \ - pip install --no-cache-dir -r requirements_finetune.txt && \ - pip install --no-cache-dir -r requirements_other.txt && \ - pip install --no-cache-dir deepspeed +RUN pip install --no-cache-dir -r requirements_other.txt EXPOSE 7851 CMD ["python", "script.py"] diff --git a/nvidia.Dockerfile b/nvidia.Dockerfile new file mode 100644 index 0000000..5a79e77 --- /dev/null +++ b/nvidia.Dockerfile @@ -0,0 +1,18 @@ +FROM nvidia/cuda:12.1.1-devel-ubuntu22.04 +ENV HOST 0.0.0.0 +RUN apt-get update && apt-get upgrade -y \ + && apt-get install -y git build-essential \ + python3 python3-pip gcc wget \ + ocl-icd-opencl-dev opencl-headers clinfo \ + libclblast-dev libopenblas-dev \ + && mkdir -p /etc/OpenCL/vendors && echo "libnvidia-opencl.so.1" > /etc/OpenCL/vendors/nvidia.icd +WORKDIR /app +COPY . . +ENV CUDA_DOCKER_ARCH=all + +RUN pip install --no-cache-dir -r requirements_nvidia.txt && \ + pip install --no-cache-dir -r requirements_finetune.txt && \ + pip install --no-cache-dir -r requirements_other.txt && \ + pip install --no-cache-dir deepspeed +EXPOSE 7851 +CMD ["python", "script.py"] From cd164ae2581d6ead1d66e4534dae34c0baa524f8 Mon Sep 17 00:00:00 2001 From: Josh XT Date: Mon, 22 Jan 2024 11:49:10 -0500 Subject: [PATCH 07/25] Updates --- .github/workflows/publish-docker.yml | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/.github/workflows/publish-docker.yml b/.github/workflows/publish-docker.yml index 570e75e..1f7dc52 100644 --- a/.github/workflows/publish-docker.yml +++ b/.github/workflows/publish-docker.yml @@ -13,10 +13,10 @@ jobs: strategy: matrix: include: - - dockerfile: "./Dockerfile" + - dockerfile: "Dockerfile" platforms: "linux/amd64,linux/arm64/v8" tag_name: "cpu" - - dockerfile: "./nvidia.Dockerfile" + - dockerfile: "nvidia.Dockerfile" platforms: "linux/amd64" tag_name: "cuda" steps: @@ -26,11 +26,16 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 + - name: Lowercase Actor and Extract Repo Name + run: | + echo "ACTOR_LOWER=$(echo ${{ github.actor }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV + echo "REPO_NAME=$(echo ${{ github.repository }} | cut -d'/' -f 2)" >> $GITHUB_ENV + - name: Login to GitHub Container Registry uses: docker/login-action@v3 with: registry: ghcr.io - username: ${{ github.actor }} + username: ${{ env.ACTOR_LOWER }} password: ${{ secrets.GITHUB_TOKEN }} - name: Login to DockerHub @@ -44,12 +49,12 @@ jobs: uses: docker/build-push-action@v5 with: context: . - file: ${{ matrix.dockerfile }} + file: ./${{ matrix.dockerfile }} platforms: ${{ matrix.platforms }} push: true tags: | - ghcr.io/${{ github.actor }}/alltalk_tts:${{ matrix.tag_name }}-${{ github.sha }} - ghcr.io/${{ github.actor }}/alltalk_tts:${{ matrix.tag_name }} + ghcr.io/${{ env.ACTOR_LOWER }}/${{ env.REPO_NAME }}:${{ matrix.tag_name }}-${{ github.sha }} + ghcr.io/${{ env.ACTOR_LOWER }}/${{ env.REPO_NAME }}:${{ matrix.tag_name }} - name: Docker Hub Description if: vars.DOCKERHUB_USERNAME != '' @@ -57,4 +62,4 @@ jobs: with: username: ${{ vars.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - repository: ${{ vars.DOCKERHUB_USERNAME }}/alltalk_tts + repository: ${{ vars.DOCKERHUB_USERNAME }}/${{ env.REPO_NAME }} From 6166d4f75122f20572ae1b3ede2f3f0a654ec505 Mon Sep 17 00:00:00 2001 From: Josh XT Date: Mon, 22 Jan 2024 11:52:41 -0500 Subject: [PATCH 08/25] No arm support --- .github/workflows/publish-docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-docker.yml b/.github/workflows/publish-docker.yml index 1f7dc52..60cb6e9 100644 --- a/.github/workflows/publish-docker.yml +++ b/.github/workflows/publish-docker.yml @@ -14,7 +14,7 @@ jobs: matrix: include: - dockerfile: "Dockerfile" - platforms: "linux/amd64,linux/arm64/v8" + platforms: "linux/amd64" tag_name: "cpu" - dockerfile: "nvidia.Dockerfile" platforms: "linux/amd64" From def2d51c5ffd66add1d1d432c60484430521e088 Mon Sep 17 00:00:00 2001 From: Josh XT Date: Mon, 22 Jan 2024 11:54:29 -0500 Subject: [PATCH 09/25] Use ubuntu --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 3c329a5..d7f3543 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3-slim-bullseye +FROM ubuntu:22.04 ENV HOST 0.0.0.0 RUN apt-get update && apt-get upgrade -y \ && apt-get install -y git build-essential \ From c17959f142046d58e1341c518c146bea497e5f17 Mon Sep 17 00:00:00 2001 From: Josh XT Date: Mon, 22 Jan 2024 12:12:22 -0500 Subject: [PATCH 10/25] Add dockerhub publish --- .github/workflows/publish-docker.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-docker.yml b/.github/workflows/publish-docker.yml index 60cb6e9..95de743 100644 --- a/.github/workflows/publish-docker.yml +++ b/.github/workflows/publish-docker.yml @@ -39,7 +39,6 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Login to DockerHub - if: vars.DOCKERHUB_USERNAME != '' uses: docker/login-action@v3 with: username: ${{ vars.DOCKERHUB_USERNAME }} @@ -55,9 +54,12 @@ jobs: tags: | ghcr.io/${{ env.ACTOR_LOWER }}/${{ env.REPO_NAME }}:${{ matrix.tag_name }}-${{ github.sha }} ghcr.io/${{ env.ACTOR_LOWER }}/${{ env.REPO_NAME }}:${{ matrix.tag_name }} + ghcr.io/${{ env.ACTOR_LOWER }}/${{ env.REPO_NAME }}:latest + ${{ steps.vars.outputs.DOCKERHUB_USERNAME }}/${{ env.REPO_NAME }}:${{ matrix.tag_name }}-${{ github.sha }} + ${{ steps.vars.outputs.DOCKERHUB_USERNAME }}/${{ env.REPO_NAME }}:${{ matrix.tag_name }} + ${{ steps.vars.outputs.DOCKERHUB_USERNAME }}/${{ env.REPO_NAME }}:latest - name: Docker Hub Description - if: vars.DOCKERHUB_USERNAME != '' uses: peter-evans/dockerhub-description@v3.4.2 with: username: ${{ vars.DOCKERHUB_USERNAME }} From c3bb58d2af0fbd72da806d71480361c25ac7bdb3 Mon Sep 17 00:00:00 2001 From: Josh XT Date: Mon, 22 Jan 2024 12:15:10 -0500 Subject: [PATCH 11/25] Update dockerhub --- .github/workflows/publish-docker.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish-docker.yml b/.github/workflows/publish-docker.yml index 95de743..302b78c 100644 --- a/.github/workflows/publish-docker.yml +++ b/.github/workflows/publish-docker.yml @@ -55,9 +55,9 @@ jobs: ghcr.io/${{ env.ACTOR_LOWER }}/${{ env.REPO_NAME }}:${{ matrix.tag_name }}-${{ github.sha }} ghcr.io/${{ env.ACTOR_LOWER }}/${{ env.REPO_NAME }}:${{ matrix.tag_name }} ghcr.io/${{ env.ACTOR_LOWER }}/${{ env.REPO_NAME }}:latest - ${{ steps.vars.outputs.DOCKERHUB_USERNAME }}/${{ env.REPO_NAME }}:${{ matrix.tag_name }}-${{ github.sha }} - ${{ steps.vars.outputs.DOCKERHUB_USERNAME }}/${{ env.REPO_NAME }}:${{ matrix.tag_name }} - ${{ steps.vars.outputs.DOCKERHUB_USERNAME }}/${{ env.REPO_NAME }}:latest + ${{ vars.DOCKERHUB_USERNAME }}/${{ env.REPO_NAME }}:${{ matrix.tag_name }}-${{ github.sha }} + ${{ vars.DOCKERHUB_USERNAME }}/${{ env.REPO_NAME }}:${{ matrix.tag_name }} + ${{ vars.DOCKERHUB_USERNAME }}/${{ env.REPO_NAME }}:latest - name: Docker Hub Description uses: peter-evans/dockerhub-description@v3.4.2 From d15931bdda41c803c73da9eebb43b344c5c0a082 Mon Sep 17 00:00:00 2001 From: Josh XT Date: Mon, 22 Jan 2024 15:54:46 -0500 Subject: [PATCH 12/25] 3 --- Dockerfile | 2 +- nvidia.Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index d7f3543..a8ef875 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,4 +7,4 @@ WORKDIR /app COPY . . RUN pip install --no-cache-dir -r requirements_other.txt EXPOSE 7851 -CMD ["python", "script.py"] +CMD ["python3", "script.py"] diff --git a/nvidia.Dockerfile b/nvidia.Dockerfile index 5a79e77..cd9c594 100644 --- a/nvidia.Dockerfile +++ b/nvidia.Dockerfile @@ -15,4 +15,4 @@ RUN pip install --no-cache-dir -r requirements_nvidia.txt && \ pip install --no-cache-dir -r requirements_other.txt && \ pip install --no-cache-dir deepspeed EXPOSE 7851 -CMD ["python", "script.py"] +CMD ["python3", "script.py"] From fcec9d8f5ba1f8f1fdbd9572ef2a66d9387de041 Mon Sep 17 00:00:00 2001 From: Josh XT Date: Mon, 22 Jan 2024 16:32:30 -0500 Subject: [PATCH 13/25] Fix python alias --- Dockerfile | 5 +++-- nvidia.Dockerfile | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index a8ef875..1ddd804 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,9 +2,10 @@ FROM ubuntu:22.04 ENV HOST 0.0.0.0 RUN apt-get update && apt-get upgrade -y \ && apt-get install -y git build-essential \ - python3 python3-pip gcc wget + python3 python3-pip gcc wget \ + && ln -s /usr/bin/python3 /usr/bin/python WORKDIR /app COPY . . RUN pip install --no-cache-dir -r requirements_other.txt EXPOSE 7851 -CMD ["python3", "script.py"] +CMD ["python", "script.py"] diff --git a/nvidia.Dockerfile b/nvidia.Dockerfile index cd9c594..617f070 100644 --- a/nvidia.Dockerfile +++ b/nvidia.Dockerfile @@ -5,7 +5,8 @@ RUN apt-get update && apt-get upgrade -y \ python3 python3-pip gcc wget \ ocl-icd-opencl-dev opencl-headers clinfo \ libclblast-dev libopenblas-dev \ - && mkdir -p /etc/OpenCL/vendors && echo "libnvidia-opencl.so.1" > /etc/OpenCL/vendors/nvidia.icd + && mkdir -p /etc/OpenCL/vendors && echo "libnvidia-opencl.so.1" > /etc/OpenCL/vendors/nvidia.icd \ + && ln -s /usr/bin/python3 /usr/bin/python WORKDIR /app COPY . . ENV CUDA_DOCKER_ARCH=all @@ -15,4 +16,4 @@ RUN pip install --no-cache-dir -r requirements_nvidia.txt && \ pip install --no-cache-dir -r requirements_other.txt && \ pip install --no-cache-dir deepspeed EXPOSE 7851 -CMD ["python3", "script.py"] +CMD ["python", "script.py"] From bd74de53dac979efb27624fb26bc03a8745e0afa Mon Sep 17 00:00:00 2001 From: Josh XT Date: Mon, 22 Jan 2024 16:53:08 -0500 Subject: [PATCH 14/25] Add portaudio19-dev --- Dockerfile | 2 +- nvidia.Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 1ddd804..8e5a376 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ FROM ubuntu:22.04 ENV HOST 0.0.0.0 RUN apt-get update && apt-get upgrade -y \ - && apt-get install -y git build-essential \ + && apt-get install -y git build-essential portaudio19-dev \ python3 python3-pip gcc wget \ && ln -s /usr/bin/python3 /usr/bin/python WORKDIR /app diff --git a/nvidia.Dockerfile b/nvidia.Dockerfile index 617f070..686bb09 100644 --- a/nvidia.Dockerfile +++ b/nvidia.Dockerfile @@ -1,7 +1,7 @@ FROM nvidia/cuda:12.1.1-devel-ubuntu22.04 ENV HOST 0.0.0.0 RUN apt-get update && apt-get upgrade -y \ - && apt-get install -y git build-essential \ + && apt-get install -y git build-essential portaudio19-dev \ python3 python3-pip gcc wget \ ocl-icd-opencl-dev opencl-headers clinfo \ libclblast-dev libopenblas-dev \ From d750959f52db7c4cd08e580921d14f4598a277a5 Mon Sep 17 00:00:00 2001 From: Josh XT Date: Mon, 22 Jan 2024 17:04:28 -0500 Subject: [PATCH 15/25] Add docker-compose --- docker-compose-cuda.yml | 17 +++++++++++++++++ docker-compose.yml | 10 ++++++++++ 2 files changed, 27 insertions(+) create mode 100644 docker-compose-cuda.yml create mode 100644 docker-compose.yml diff --git a/docker-compose-cuda.yml b/docker-compose-cuda.yml new file mode 100644 index 0000000..3b99827 --- /dev/null +++ b/docker-compose-cuda.yml @@ -0,0 +1,17 @@ +version: '3.8' +services: + alltalk-tts: + image: joshxt/alltalk_tts:cuda + restart: unless-stopped + ports: + - "7851:7851" + volumes: + - ./outputs:/app/outputs/ + - ./finetune/put-voice-samples-in-here:/app/finetune/put-voice-samples-in-here + deploy: + resources: + reservations: + devices: + - driver: nvidia + count: all + capabilities: [ gpu ] \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..d54c3ee --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,10 @@ +version: '3.8' +services: + alltalk-tts: + image: joshxt/alltalk_tts:cpu + restart: unless-stopped + ports: + - "7851:7851" + volumes: + - ./outputs:/app/outputs/ + - ./finetune/put-voice-samples-in-here:/app/finetune/put-voice-samples-in-here From cdce7511dc01e1111470bec756a9b6c09f2b106e Mon Sep 17 00:00:00 2001 From: Josh XT Date: Mon, 22 Jan 2024 17:31:41 -0500 Subject: [PATCH 16/25] Use deepspeed --- confignew.json | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/confignew.json b/confignew.json index 8d9d0c5..039a973 100644 --- a/confignew.json +++ b/confignew.json @@ -1 +1,25 @@ -{"activate": true, "autoplay": true, "branding": "AllTalk ", "narrator_enabled": false, "deepspeed_activate": false, "delete_output_wavs": "Disabled", "ip_address": "127.0.0.1", "language": "English", "low_vram": false, "local_temperature": "0.7", "local_repetition_penalty": "10.0", "tts_model_loaded": true, "tts_model_name": "tts_models/multilingual/multi-dataset/xtts_v2", "narrator_voice": "female_01.wav", "output_folder_wav": "extensions/alltalk_tts/outputs/", "output_folder_wav_standalone": "outputs/", "port_number": "7851", "remove_trailing_dots": false, "show_text": true, "tts_method_api_local": false, "tts_method_api_tts": false, "tts_method_xtts_local": true, "voice": "female_01.wav"} \ No newline at end of file +{ + "activate": true, + "autoplay": true, + "branding": "AllTalk ", + "narrator_enabled": false, + "deepspeed_activate": true, + "delete_output_wavs": "Disabled", + "ip_address": "127.0.0.1", + "language": "English", + "low_vram": false, + "local_temperature": "0.7", + "local_repetition_penalty": "10.0", + "tts_model_loaded": true, + "tts_model_name": "tts_models/multilingual/multi-dataset/xtts_v2", + "narrator_voice": "female_01.wav", + "output_folder_wav": "extensions/alltalk_tts/outputs/", + "output_folder_wav_standalone": "outputs/", + "port_number": "7851", + "remove_trailing_dots": false, + "show_text": true, + "tts_method_api_local": false, + "tts_method_api_tts": false, + "tts_method_xtts_local": true, + "voice": "female_01.wav" +} \ No newline at end of file From 81a9f4c847686de64073b8e82fd0b41042219199 Mon Sep 17 00:00:00 2001 From: Josh XT Date: Mon, 22 Jan 2024 17:33:02 -0500 Subject: [PATCH 17/25] Persist config --- docker-compose-cuda.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker-compose-cuda.yml b/docker-compose-cuda.yml index 3b99827..49edd03 100644 --- a/docker-compose-cuda.yml +++ b/docker-compose-cuda.yml @@ -8,6 +8,7 @@ services: volumes: - ./outputs:/app/outputs/ - ./finetune/put-voice-samples-in-here:/app/finetune/put-voice-samples-in-here + - ./confignew.json:/app/confignew.json deploy: resources: reservations: From 51c91c3d708b4ba31cad762ef43352d0a3982154 Mon Sep 17 00:00:00 2001 From: Josh XT Date: Mon, 22 Jan 2024 17:35:21 -0500 Subject: [PATCH 18/25] Fix config --- confignew.json | 2 +- docker-compose-cuda.yml | 2 +- docker-compose.yml | 1 + dockerconfig.json | 25 +++++++++++++++++++++++++ 4 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 dockerconfig.json diff --git a/confignew.json b/confignew.json index 039a973..2b8f584 100644 --- a/confignew.json +++ b/confignew.json @@ -3,7 +3,7 @@ "autoplay": true, "branding": "AllTalk ", "narrator_enabled": false, - "deepspeed_activate": true, + "deepspeed_activate": false, "delete_output_wavs": "Disabled", "ip_address": "127.0.0.1", "language": "English", diff --git a/docker-compose-cuda.yml b/docker-compose-cuda.yml index 49edd03..2ee2b53 100644 --- a/docker-compose-cuda.yml +++ b/docker-compose-cuda.yml @@ -8,7 +8,7 @@ services: volumes: - ./outputs:/app/outputs/ - ./finetune/put-voice-samples-in-here:/app/finetune/put-voice-samples-in-here - - ./confignew.json:/app/confignew.json + - ./dockerconfig.json:/app/confignew.json deploy: resources: reservations: diff --git a/docker-compose.yml b/docker-compose.yml index d54c3ee..39d3609 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,3 +8,4 @@ services: volumes: - ./outputs:/app/outputs/ - ./finetune/put-voice-samples-in-here:/app/finetune/put-voice-samples-in-here + - ./dockerconfig.json:/app/confignew.json \ No newline at end of file diff --git a/dockerconfig.json b/dockerconfig.json new file mode 100644 index 0000000..039a973 --- /dev/null +++ b/dockerconfig.json @@ -0,0 +1,25 @@ +{ + "activate": true, + "autoplay": true, + "branding": "AllTalk ", + "narrator_enabled": false, + "deepspeed_activate": true, + "delete_output_wavs": "Disabled", + "ip_address": "127.0.0.1", + "language": "English", + "low_vram": false, + "local_temperature": "0.7", + "local_repetition_penalty": "10.0", + "tts_model_loaded": true, + "tts_model_name": "tts_models/multilingual/multi-dataset/xtts_v2", + "narrator_voice": "female_01.wav", + "output_folder_wav": "extensions/alltalk_tts/outputs/", + "output_folder_wav_standalone": "outputs/", + "port_number": "7851", + "remove_trailing_dots": false, + "show_text": true, + "tts_method_api_local": false, + "tts_method_api_tts": false, + "tts_method_xtts_local": true, + "voice": "female_01.wav" +} \ No newline at end of file From 360f70cb0acd16ebeb754d8afe66aa369957b16f Mon Sep 17 00:00:00 2001 From: Josh XT Date: Mon, 22 Jan 2024 18:10:20 -0500 Subject: [PATCH 19/25] Disable deepspeed --- dockerconfig.json | 2 +- nvidia.Dockerfile | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/dockerconfig.json b/dockerconfig.json index 039a973..2b8f584 100644 --- a/dockerconfig.json +++ b/dockerconfig.json @@ -3,7 +3,7 @@ "autoplay": true, "branding": "AllTalk ", "narrator_enabled": false, - "deepspeed_activate": true, + "deepspeed_activate": false, "delete_output_wavs": "Disabled", "ip_address": "127.0.0.1", "language": "English", diff --git a/nvidia.Dockerfile b/nvidia.Dockerfile index 686bb09..fdc2f39 100644 --- a/nvidia.Dockerfile +++ b/nvidia.Dockerfile @@ -13,7 +13,6 @@ ENV CUDA_DOCKER_ARCH=all RUN pip install --no-cache-dir -r requirements_nvidia.txt && \ pip install --no-cache-dir -r requirements_finetune.txt && \ - pip install --no-cache-dir -r requirements_other.txt && \ - pip install --no-cache-dir deepspeed + pip install --no-cache-dir -r requirements_other.txt EXPOSE 7851 CMD ["python", "script.py"] From 12bf008b3fb7d2ba0e7af15c41fb4412eac81a08 Mon Sep 17 00:00:00 2001 From: Josh XT Date: Mon, 22 Jan 2024 19:15:54 -0500 Subject: [PATCH 20/25] Run back end without subprocess --- Dockerfile | 2 +- docker-compose-cuda.yml | 1 + docker-compose.yml | 1 + dockerconfig.json | 2 +- launch.sh | 4 + nvidia.Dockerfile | 2 +- script.py | 385 ++++++++++++++++++++++++++++------------ 7 files changed, 277 insertions(+), 120 deletions(-) create mode 100644 launch.sh diff --git a/Dockerfile b/Dockerfile index 8e5a376..0e0cef9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,4 +8,4 @@ WORKDIR /app COPY . . RUN pip install --no-cache-dir -r requirements_other.txt EXPOSE 7851 -CMD ["python", "script.py"] +ENTRYPOINT ["sh", "-c", "./launch.sh"] \ No newline at end of file diff --git a/docker-compose-cuda.yml b/docker-compose-cuda.yml index 2ee2b53..309609e 100644 --- a/docker-compose-cuda.yml +++ b/docker-compose-cuda.yml @@ -7,6 +7,7 @@ services: - "7851:7851" volumes: - ./outputs:/app/outputs/ + - ./models:/app/models/ - ./finetune/put-voice-samples-in-here:/app/finetune/put-voice-samples-in-here - ./dockerconfig.json:/app/confignew.json deploy: diff --git a/docker-compose.yml b/docker-compose.yml index 39d3609..2ab938b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,5 +7,6 @@ services: - "7851:7851" volumes: - ./outputs:/app/outputs/ + - ./models:/app/models/ - ./finetune/put-voice-samples-in-here:/app/finetune/put-voice-samples-in-here - ./dockerconfig.json:/app/confignew.json \ No newline at end of file diff --git a/dockerconfig.json b/dockerconfig.json index 2b8f584..039a973 100644 --- a/dockerconfig.json +++ b/dockerconfig.json @@ -3,7 +3,7 @@ "autoplay": true, "branding": "AllTalk ", "narrator_enabled": false, - "deepspeed_activate": false, + "deepspeed_activate": true, "delete_output_wavs": "Disabled", "ip_address": "127.0.0.1", "language": "English", diff --git a/launch.sh b/launch.sh new file mode 100644 index 0000000..23dc4d6 --- /dev/null +++ b/launch.sh @@ -0,0 +1,4 @@ +#!/bin/sh +uvicorn tts_server:app --host 0.0.0.0 --port 7581 --workers 1 --proxy-headers & +sleep 5 +python script.py \ No newline at end of file diff --git a/nvidia.Dockerfile b/nvidia.Dockerfile index fdc2f39..d7ac052 100644 --- a/nvidia.Dockerfile +++ b/nvidia.Dockerfile @@ -15,4 +15,4 @@ RUN pip install --no-cache-dir -r requirements_nvidia.txt && \ pip install --no-cache-dir -r requirements_finetune.txt && \ pip install --no-cache-dir -r requirements_other.txt EXPOSE 7851 -CMD ["python", "script.py"] +ENTRYPOINT ["sh", "-c", "./launch.sh"] \ No newline at end of file diff --git a/script.py b/script.py index 74f23f5..a02d79c 100644 --- a/script.py +++ b/script.py @@ -30,12 +30,14 @@ startup_wait_time = 120 # STARTUP VARIABLE - Create "this_dir" variable as the current script directory this_dir = Path(__file__).parent.resolve() + # load config file in and get settings def load_config(file_path): with open(file_path, "r") as config_file: config = json.load(config_file) return config + config_file_path = this_dir / "confignew.json" # Load the params dictionary from the confignew.json file params = load_config(config_file_path) @@ -56,6 +58,7 @@ except ModuleNotFoundError: # IMPORT - Attempt Importing DeepSpeed (required for displaying Deepspeed checkbox in gradio) try: import deepspeed + deepspeed_installed = True except ImportError: deepspeed_installed = False @@ -68,6 +71,7 @@ try: from modules.logging_colors import logger from modules.ui import create_refresh_button from modules.utils import gradio + # This is set to check if the script is being run within text generation webui or as a standalone script. False is running as part of text gen web ui or a gradio interface running_in_standalone = False output_folder_wav = params["output_folder_wav"] @@ -88,10 +92,12 @@ process_lock = threading.Lock() # Base setting for a possible FineTuned model existing and the loader being available tts_method_xtts_ft = False + # Gather the voice files def get_available_voices(): return sorted([voice.name for voice in Path(f"{this_dir}/voices").glob("*.wav")]) + ######################### #### LICENSE DISPLAY #### ######################### @@ -149,6 +155,7 @@ def check_required_files(): subprocess.run(["python", str(download_script_path)]) print(f"[{params['branding']}Startup] All required files are present.") + # STARTUP Call Check routine check_required_files() @@ -163,7 +170,9 @@ finetuned_model = trained_model_directory.exists() # If true, this will add a extra option in the Gradio interface for loading Xttsv2 FT if finetuned_model: required_files = ["model.pth", "config.json", "vocab.json"] - finetuned_model = all((trained_model_directory / file).exists() for file in required_files) + finetuned_model = all( + (trained_model_directory / file).exists() for file in required_files + ) if finetuned_model: print(f"[{params['branding']}Startup] Finetuned model \033[93mDetected\033[0m") @@ -181,6 +190,7 @@ elif params["tts_method_xtts_local"] == True: # Set the default for Narrated text without asterisk or quotes to be Narrator non_quoted_text_is = True + ###################### #### GRADIO STUFF #### ###################### @@ -239,65 +249,79 @@ def signal_handler(sig, frame): # Attach the signal handler to the SIGINT signal (Ctrl+C) signal.signal(signal.SIGINT, signal_handler) -# Start the subprocess -process = subprocess.Popen(["python", script_path]) - -# Check if the subprocess has started successfully -if process.poll() is None: - print(f"[{params['branding']}Startup] TTS Subprocess starting") - print(f"[{params['branding']}Startup]") - print( - f"[{params['branding']}Startup] \033[94m {params['branding']}Settings & Documentation:\033[00m", - f"\033[92mhttp://{params['ip_address']}:{params['port_number']}\033[00m", - ) - print(f"[{params['branding']}Startup]") -else: - print( - f"[{params['branding']}Startup] \033[91mWarning\033[0m TTS Subprocess Webserver failing to start process" - ) - print( - f"[{params['branding']}Startup] \033[91mWarning\033[0m It could be that you have something on port:", - params["port_number"], - ) - print( - f"[{params['branding']}Startup] \033[91mWarning\033[0m Or you have not started in a Python environement with all the necesssary bits installed" - ) - print( - f"[{params['branding']}Startup] \033[91mWarning\033[0m Check you are starting Text-generation-webui with either the start_xxxxx file or the Python environment with cmd_xxxxx file." - ) - print( - f"[{params['branding']}Startup] \033[91mWarning\033[0m xxxxx is the type of OS you are on e.g. windows, linux or mac." - ) - print( - f"[{params['branding']}Startup] \033[91mWarning\033[0m Alternatively, you could check no other Python processes are running that shouldnt be e.g. Restart your computer is the simple way." - ) - # Cleanly kill off this script, but allow text-generation-webui to keep running, albeit without this alltalk_tts - sys.exit(1) - -timeout = startup_wait_time # Gather timeout setting from startup_wait_time - -# Introduce a delay before starting the check loop -time.sleep(26) # Wait 26 secs before checking if the tts_server.py has started up. -start_time = time.time() -while time.time() - start_time < timeout: - try: - response = requests.get(f"{base_url}/ready") - if response.status_code == 200: - break - except requests.RequestException as e: - # Print the exception for debugging purposes +try: + response = requests.get(f"{base_url}/ready") + if response.status_code == 200: + pass +except: + # Start the subprocess + process = subprocess.Popen(["python", script_path]) + # Check if the subprocess has started successfully + if process.poll() is None: + print(f"[{params['branding']}Startup] TTS Subprocess starting") + print(f"[{params['branding']}Startup]") print( - f"[{params['branding']}Startup] \033[91mWarning\033[0m TTS Subprocess has NOT started up yet, Will keep trying for {timeout} seconds maximum. Please wait." + f"[{params['branding']}Startup] \033[94m {params['branding']}Settings & Documentation:\033[00m", + f"\033[92mhttp://{params['ip_address']}:{params['port_number']}\033[00m", ) - time.sleep(5) -else: - print(f"\n[{params['branding']}Startup] Startup timed out. Full help available here \033[92mhttps://github.com/erew123/alltalk_tts#-help-with-problems\033[0m") - print(f"[{params['branding']}Startup] On older system you may wish to open and edit \033[94mscript.py\033[0m with a text editor and changing the") - print(f"[{params['branding']}Startup] \033[94mstartup_wait_time = 120\033[0m setting to something like \033[94mstartup_wait_time = 240\033[0m as this will allow") - print(f"[{params['branding']}Startup] AllTalk more time to try load the model into your VRAM. Otherise please visit the Github for") - print(f"[{params['branding']}Startup] a list of other possible troubleshooting options.") - # Cleanly kill off this script, but allow text-generation-webui to keep running, albeit without this alltalk_tts - sys.exit(1) + print(f"[{params['branding']}Startup]") + else: + print( + f"[{params['branding']}Startup] \033[91mWarning\033[0m TTS Subprocess Webserver failing to start process" + ) + print( + f"[{params['branding']}Startup] \033[91mWarning\033[0m It could be that you have something on port:", + params["port_number"], + ) + print( + f"[{params['branding']}Startup] \033[91mWarning\033[0m Or you have not started in a Python environement with all the necesssary bits installed" + ) + print( + f"[{params['branding']}Startup] \033[91mWarning\033[0m Check you are starting Text-generation-webui with either the start_xxxxx file or the Python environment with cmd_xxxxx file." + ) + print( + f"[{params['branding']}Startup] \033[91mWarning\033[0m xxxxx is the type of OS you are on e.g. windows, linux or mac." + ) + print( + f"[{params['branding']}Startup] \033[91mWarning\033[0m Alternatively, you could check no other Python processes are running that shouldnt be e.g. Restart your computer is the simple way." + ) + # Cleanly kill off this script, but allow text-generation-webui to keep running, albeit without this alltalk_tts + sys.exit(1) + + timeout = startup_wait_time # Gather timeout setting from startup_wait_time + + # Introduce a delay before starting the check loop + time.sleep(26) # Wait 26 secs before checking if the tts_server.py has started up. + start_time = time.time() + while time.time() - start_time < timeout: + try: + response = requests.get(f"{base_url}/ready") + if response.status_code == 200: + break + except requests.RequestException as e: + # Print the exception for debugging purposes + print( + f"[{params['branding']}Startup] \033[91mWarning\033[0m TTS Subprocess has NOT started up yet, Will keep trying for {timeout} seconds maximum. Please wait." + ) + time.sleep(5) + else: + print( + f"\n[{params['branding']}Startup] Startup timed out. Full help available here \033[92mhttps://github.com/erew123/alltalk_tts#-help-with-problems\033[0m" + ) + print( + f"[{params['branding']}Startup] On older system you may wish to open and edit \033[94mscript.py\033[0m with a text editor and changing the" + ) + print( + f"[{params['branding']}Startup] \033[94mstartup_wait_time = 120\033[0m setting to something like \033[94mstartup_wait_time = 240\033[0m as this will allow" + ) + print( + f"[{params['branding']}Startup] AllTalk more time to try load the model into your VRAM. Otherise please visit the Github for" + ) + print( + f"[{params['branding']}Startup] a list of other possible troubleshooting options." + ) + # Cleanly kill off this script, but allow text-generation-webui to keep running, albeit without this alltalk_tts + sys.exit(1) ##################################### @@ -352,6 +376,7 @@ def send_reload_request(tts_method): ) return {"status": "error", "message": str(e)} + ################## #### LOW VRAM #### ################## @@ -392,7 +417,7 @@ def send_deepspeed_request(deepspeed_param): audio_path = this_dir / "templates" / "deepspeedenabled.wav" else: audio_path = this_dir / "templates" / "deepspeeddisabled.wav" - + url = f"{base_url}/api/deepspeed?new_deepspeed_value={deepspeed_param}" headers = {"Content-Type": "application/json"} response = requests.post(url, headers=headers) @@ -466,9 +491,13 @@ def combine(audio_files, output_folder, state): # Save the combined audio to a file with a specified sample rate if "character_menu" in state: - output_file_path = os.path.join(output_folder, f'{state["character_menu"]}_{int(time.time())}_combined.wav') + output_file_path = os.path.join( + output_folder, f'{state["character_menu"]}_{int(time.time())}_combined.wav' + ) else: - output_file_path = os.path.join(output_folder, f'TTSOUT_{int(time.time())}_combined.wav') + output_file_path = os.path.join( + output_folder, f"TTSOUT_{int(time.time())}_combined.wav" + ) sf.write(output_file_path, audio, samplerate=sample_rate) # Clean up unnecessary files for audio_file in audio_files: @@ -506,7 +535,12 @@ def voice_preview(string): # Lock before making the generate request with process_lock: generate_response = send_generate_request( - string, params["voice"], language_code, temperature, repetition_penalty, output_file_str + string, + params["voice"], + language_code, + temperature, + repetition_penalty, + output_file_str, ) # Check if lock is already acquired if process_lock.locked(): @@ -528,7 +562,7 @@ def process_text(text): text = html.unescape(text) # Replace ellipsis with a single dot - text = re.sub(r'\.{3,}', '.', text) + text = re.sub(r"\.{3,}", ".", text) # Pattern to identify combined narrator and character speech combined_pattern = r'(\*[^*"]+\*|"[^"*]+")' @@ -543,22 +577,22 @@ def process_text(text): for match in re.finditer(combined_pattern, text): # Add the text before the match, if any, as ambiguous if start < match.start(): - ambiguous_text = text[start:match.start()].strip() + ambiguous_text = text[start : match.start()].strip() if ambiguous_text: - ordered_parts.append(('ambiguous', ambiguous_text)) + ordered_parts.append(("ambiguous", ambiguous_text)) # Add the matched part as either narrator or character matched_text = match.group(0) - if matched_text.startswith('*') and matched_text.endswith('*'): - ordered_parts.append(('narrator', matched_text.strip('*').strip())) + if matched_text.startswith("*") and matched_text.endswith("*"): + ordered_parts.append(("narrator", matched_text.strip("*").strip())) elif matched_text.startswith('"') and matched_text.endswith('"'): - ordered_parts.append(('character', matched_text.strip('"').strip())) + ordered_parts.append(("character", matched_text.strip('"').strip())) else: # In case of mixed or improperly formatted parts - if '*' in matched_text: - ordered_parts.append(('narrator', matched_text.strip('*').strip('"'))) + if "*" in matched_text: + ordered_parts.append(("narrator", matched_text.strip("*").strip('"'))) else: - ordered_parts.append(('character', matched_text.strip('"').strip('*'))) + ordered_parts.append(("character", matched_text.strip('"').strip("*"))) # Update the start of the next segment start = match.end() @@ -567,10 +601,11 @@ def process_text(text): if start < len(text): ambiguous_text = text[start:].strip() if ambiguous_text: - ordered_parts.append(('ambiguous', ambiguous_text)) + ordered_parts.append(("ambiguous", ambiguous_text)) return ordered_parts + ################################# #### TTS STANDARD GENERATION #### ################################# @@ -579,7 +614,7 @@ def output_modifier(string, state): if not params["activate"]: return string original_string = string - #print("ORIGINAL STRING IS:", original_string) + # print("ORIGINAL STRING IS:", original_string) cleaned_string = before_audio_generation(string, params) if cleaned_string is None: return @@ -601,29 +636,50 @@ def output_modifier(string, state): continue # Determine the voice to use based on the part type - if part_type == 'narrator': + if part_type == "narrator": voice_to_use = params["narrator_voice"] - print(f"[{params['branding']}TTSGen] \033[92mNarrator\033[0m") # Green - elif part_type == 'character': + print( + f"[{params['branding']}TTSGen] \033[92mNarrator\033[0m" + ) # Green + elif part_type == "character": voice_to_use = params["voice"] - print(f"[{params['branding']}TTSGen] \033[36mCharacter\033[0m") # Yellow + print( + f"[{params['branding']}TTSGen] \033[36mCharacter\033[0m" + ) # Yellow else: # Handle ambiguous parts based on user preference - voice_to_use = params["voice"] if non_quoted_text_is else params["narrator_voice"] - voice_description = "\033[36mCharacter (Text-not-inside)\033[0m" if non_quoted_text_is else "\033[92mNarrator (Text-not-inside)\033[0m" + voice_to_use = ( + params["voice"] + if non_quoted_text_is + else params["narrator_voice"] + ) + voice_description = ( + "\033[36mCharacter (Text-not-inside)\033[0m" + if non_quoted_text_is + else "\033[92mNarrator (Text-not-inside)\033[0m" + ) print(f"[{params['branding']}TTSGen] {voice_description}") # Replace multiple exclamation marks, question marks, or other punctuation with a single instance - cleaned_part = re.sub(r'([!?.])\1+', r'\1', part) + cleaned_part = re.sub(r"([!?.])\1+", r"\1", part) # Further clean to remove any other unwanted characters - cleaned_part = re.sub(r'[^a-zA-Z0-9\s\.,;:!?\-\'"\u0400-\u04FFÀ-ÿ\u0150\u0151\u0170\u0171\$]', '', cleaned_part) + cleaned_part = re.sub( + r'[^a-zA-Z0-9\s\.,;:!?\-\'"\u0400-\u04FFÀ-ÿ\u0150\u0151\u0170\u0171\$]', + "", + cleaned_part, + ) # Remove all newline characters (single or multiple) - cleaned_part = re.sub(r'\n+', ' ', cleaned_part) + cleaned_part = re.sub(r"\n+", " ", cleaned_part) # Generate TTS and output to a file output_filename = get_output_filename(state) generate_response = send_generate_request( - cleaned_part, voice_to_use, language_code, temperature, repetition_penalty, output_filename + cleaned_part, + voice_to_use, + language_code, + temperature, + repetition_penalty, + output_filename, ) audio_path = generate_response.get("data", {}).get("audio_path") audio_files_all_paragraphs.append(audio_path) @@ -636,20 +692,33 @@ def output_modifier(string, state): # Decode HTML entities first cleaned_part = html.unescape(original_string) # Replace multiple instances of certain punctuation marks with a single instance - cleaned_part = re.sub(r'([!?.])\1+', r'\1', cleaned_part) + cleaned_part = re.sub(r"([!?.])\1+", r"\1", cleaned_part) # Further clean to remove any other unwanted characters - cleaned_part = re.sub(r'[^a-zA-Z0-9\s\.,;:!?\-\'"\u0400-\u04FFÀ-ÿ\u0150\u0151\u0170\u0171\$]', '', cleaned_part) + cleaned_part = re.sub( + r'[^a-zA-Z0-9\s\.,;:!?\-\'"\u0400-\u04FFÀ-ÿ\u0150\u0151\u0170\u0171\$]', + "", + cleaned_part, + ) # Remove all newline characters (single or multiple) - cleaned_part = re.sub(r'\n+', ' ', cleaned_part) + cleaned_part = re.sub(r"\n+", " ", cleaned_part) # Process the part and give it a non-character name if being used vai API or standalone. if "character_menu" in state: - output_file = Path(f'{params["output_folder_wav"]}/{state["character_menu"]}_{int(time.time())}.wav') + output_file = Path( + f'{params["output_folder_wav"]}/{state["character_menu"]}_{int(time.time())}.wav' + ) else: - output_file = Path(f'{params["output_folder_wav"]}/TTSOUT_{int(time.time())}.wav') + output_file = Path( + f'{params["output_folder_wav"]}/TTSOUT_{int(time.time())}.wav' + ) output_file_str = output_file.as_posix() output_file = get_output_filename(state) generate_response = send_generate_request( - cleaned_part, params["voice"], language_code, temperature, repetition_penalty, output_file_str + cleaned_part, + params["voice"], + language_code, + temperature, + repetition_penalty, + output_file_str, ) audio_path = generate_response.get("data", {}).get("audio_path") final_output_file = audio_path @@ -690,15 +759,21 @@ def output_modifier(string, state): def get_output_filename(state): if "character_menu" in state: - return Path(f'{params["output_folder_wav"]}/{state["character_menu"]}_{str(uuid.uuid4())[:8]}.wav').as_posix() + return Path( + f'{params["output_folder_wav"]}/{state["character_menu"]}_{str(uuid.uuid4())[:8]}.wav' + ).as_posix() else: - return Path(f'{params["output_folder_wav"]}/TTSOUT_{str(uuid.uuid4())[:8]}.wav').as_posix() + return Path( + f'{params["output_folder_wav"]}/TTSOUT_{str(uuid.uuid4())[:8]}.wav' + ).as_posix() ############################################### #### SEND GENERATION REQUEST TO TTS ENGINE #### ############################################### -def send_generate_request(text, voice, language, temperature, repetition_penalty, output_file): +def send_generate_request( + text, voice, language, temperature, repetition_penalty, output_file +): url = f"{base_url}/api/generate" payload = { "text": text, @@ -730,12 +805,14 @@ def state_modifier(state): state["stream"] = False return state + def update_narrator_enabled(value): if value == "Enabled": params["narrator_enabled"] = True elif value == "Disabled": params["narrator_enabled"] = False + def update_non_quoted_text_is(value): global non_quoted_text_is if value == "Narrator": @@ -743,6 +820,7 @@ def update_non_quoted_text_is(value): elif value == "Char": non_quoted_text_is = True + def input_modifier(string, state): if not params["activate"]: return string @@ -755,21 +833,29 @@ def ui(): with gr.Accordion(params["branding"] + " TTS (XTTSv2)"): # Activate alltalk_tts, Enable autoplay, Show text with gr.Row(): - activate = gr.Checkbox(value=params['activate'], label='Enable TTS') - autoplay = gr.Checkbox(value=params['autoplay'], label='Autoplay TTS') - show_text = gr.Checkbox(value=params['show_text'], label='Show Text') + activate = gr.Checkbox(value=params["activate"], label="Enable TTS") + autoplay = gr.Checkbox(value=params["autoplay"], label="Autoplay TTS") + show_text = gr.Checkbox(value=params["show_text"], label="Show Text") # Low vram enable, Deepspeed enable, Remove trailing dots with gr.Row(): - low_vram = gr.Checkbox(value=params['low_vram'], label='Enable Low VRAM Mode') + low_vram = gr.Checkbox( + value=params["low_vram"], label="Enable Low VRAM Mode" + ) low_vram_play = gr.HTML(visible=False) - deepspeed_checkbox = gr.Checkbox(value=params['deepspeed_activate'], label='Enable DeepSpeed', visible=deepspeed_installed) + deepspeed_checkbox = gr.Checkbox( + value=params["deepspeed_activate"], + label="Enable DeepSpeed", + visible=deepspeed_installed, + ) deepspeed_checkbox_play = gr.HTML(visible=False) - remove_trailing_dots = gr.Checkbox(value=params['remove_trailing_dots'], label='Remove trailing "."') + remove_trailing_dots = gr.Checkbox( + value=params["remove_trailing_dots"], label='Remove trailing "."' + ) # TTS method, Character voice selection with gr.Row(): - model_loader_choices=["API TTS", "API Local", "XTTSv2 Local"] + model_loader_choices = ["API TTS", "API Local", "XTTSv2 Local"] if finetuned_model: model_loader_choices.append("XTTSv2 FT") tts_radio_buttons = gr.Radio( @@ -780,33 +866,86 @@ def ui(): tts_radio_buttons_play = gr.HTML(visible=False) with gr.Row(): available_voices = get_available_voices() - default_voice = params["voice"] # Check if the default voice is in the list of available voices + default_voice = params[ + "voice" + ] # Check if the default voice is in the list of available voices if default_voice not in available_voices: - default_voice = available_voices[ 0 ] # Choose the first available voice as the default + default_voice = available_voices[ + 0 + ] # Choose the first available voice as the default # Add allow_custom_value=True to the Dropdown - voice = gr.Dropdown(available_voices, label="Character Voice", value=default_voice, allow_custom_value=True, ) - create_refresh_button(voice, lambda: None, lambda: {"choices": get_available_voices(), "value": params["voice"],}, "refresh-button",) + voice = gr.Dropdown( + available_voices, + label="Character Voice", + value=default_voice, + allow_custom_value=True, + ) + create_refresh_button( + voice, + lambda: None, + lambda: { + "choices": get_available_voices(), + "value": params["voice"], + }, + "refresh-button", + ) # Language, Narrator voice with gr.Row(): - language = gr.Dropdown(languages.keys(), label="Language", value=params["language"]) + language = gr.Dropdown( + languages.keys(), label="Language", value=params["language"] + ) with gr.Row(): - narrator_voice_gr = gr.Dropdown(get_available_voices(), label="Narrator Voice", allow_custom_value=True, value=params["narrator_voice"]) - create_refresh_button(narrator_voice_gr, lambda: None, lambda: {"choices": get_available_voices(), "value": params["narrator_voice"],}, "refresh-button") + narrator_voice_gr = gr.Dropdown( + get_available_voices(), + label="Narrator Voice", + allow_custom_value=True, + value=params["narrator_voice"], + ) + create_refresh_button( + narrator_voice_gr, + lambda: None, + lambda: { + "choices": get_available_voices(), + "value": params["narrator_voice"], + }, + "refresh-button", + ) # Temperature, Repetition Penalty with gr.Row(): - local_temperature_gr = gr.Slider(minimum=0.05, maximum=1, step=0.05, label="Temperature", value=params["local_temperature"]) - local_repetition_penalty_gr = gr.Slider(minimum=0.5, maximum=20, step=0.5, label="Repetition Penalty", value=params["local_repetition_penalty"]) + local_temperature_gr = gr.Slider( + minimum=0.05, + maximum=1, + step=0.05, + label="Temperature", + value=params["local_temperature"], + ) + local_repetition_penalty_gr = gr.Slider( + minimum=0.5, + maximum=20, + step=0.5, + label="Repetition Penalty", + value=params["local_repetition_penalty"], + ) # Narrator enable, Non quoted text, Explanation text with gr.Row(): with gr.Row(): - narrator_enabled_gr = gr.Radio(choices={"Enabled": "true", "Disabled": "false"}, label="Narrator", value="Enabled" if params.get("narrator_enabled") else "Disabled") - non_quoted_text_is_gr = gr.Radio(choices={"Character": "true", "Narrator": "false"}, label='Unmarked text NOT inside of * or " is', value="Character" if non_quoted_text_is else "Narrator") + narrator_enabled_gr = gr.Radio( + choices={"Enabled": "true", "Disabled": "false"}, + label="Narrator", + value="Enabled" if params.get("narrator_enabled") else "Disabled", + ) + non_quoted_text_is_gr = gr.Radio( + choices={"Character": "true", "Narrator": "false"}, + label='Unmarked text NOT inside of * or " is', + value="Character" if non_quoted_text_is else "Narrator", + ) explanation_text = gr.HTML( - f"

⚙️ Settings and Documentation Page⚙️
- Low VRAM Mode and Deepspeed take 15 seconds to be enabled or disabled.
- The DeepSpeed checkbox is only visible if DeepSpeed is present.

") + f"

⚙️ Settings and Documentation Page⚙️
- Low VRAM Mode and Deepspeed take 15 seconds to be enabled or disabled.
- The DeepSpeed checkbox is only visible if DeepSpeed is present.

" + ) # Preview speech with gr.Row(): @@ -817,7 +956,7 @@ def ui(): ) preview_play = gr.Button("Preview") preview_audio = gr.HTML(visible=False) - + with gr.Row(): convert = gr.Button("Permanently replace audios with the message texts") convert_cancel = gr.Button("Cancel", visible=False) @@ -878,8 +1017,12 @@ def ui(): autoplay.change(lambda x: params.update({"autoplay": x}), autoplay, None) low_vram.change(lambda x: params.update({"low_vram": x}), low_vram, None) low_vram.change(lambda x: send_lowvram_request(x), low_vram, low_vram_play, None) - tts_radio_buttons.change(send_reload_request, tts_radio_buttons, tts_radio_buttons_play, None) - deepspeed_checkbox.change(send_deepspeed_request, deepspeed_checkbox, deepspeed_checkbox_play, None) + tts_radio_buttons.change( + send_reload_request, tts_radio_buttons, tts_radio_buttons_play, None + ) + deepspeed_checkbox.change( + send_deepspeed_request, deepspeed_checkbox, deepspeed_checkbox_play, None + ) remove_trailing_dots.change( lambda x: params.update({"remove_trailing_dots": x}), remove_trailing_dots, None ) @@ -887,13 +1030,21 @@ def ui(): language.change(lambda x: params.update({"language": x}), language, None) # TSS Settings - local_temperature_gr.change(lambda x: params.update({"local_temperature": x}), local_temperature_gr, None) - local_repetition_penalty_gr.change(lambda x: params.update({"local_repetition_penalty": x}), local_repetition_penalty_gr, None) + local_temperature_gr.change( + lambda x: params.update({"local_temperature": x}), local_temperature_gr, None + ) + local_repetition_penalty_gr.change( + lambda x: params.update({"local_repetition_penalty": x}), + local_repetition_penalty_gr, + None, + ) # Narrator selection actions narrator_enabled_gr.change(update_narrator_enabled, narrator_enabled_gr, None) non_quoted_text_is_gr.change(update_non_quoted_text_is, non_quoted_text_is_gr, None) - narrator_voice_gr.change(lambda x: params.update({"narrator_voice": x}), narrator_voice_gr, None) + narrator_voice_gr.change( + lambda x: params.update({"narrator_voice": x}), narrator_voice_gr, None + ) # Play preview preview_text.submit(voice_preview, preview_text, preview_audio) From ec1d0e8c5d3b092520a119f9b02a22238eefce95 Mon Sep 17 00:00:00 2001 From: Josh XT Date: Mon, 22 Jan 2024 19:26:23 -0500 Subject: [PATCH 21/25] Check if running in docker --- script.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/script.py b/script.py index a02d79c..5cee0f6 100644 --- a/script.py +++ b/script.py @@ -248,12 +248,12 @@ def signal_handler(sig, frame): # Attach the signal handler to the SIGINT signal (Ctrl+C) signal.signal(signal.SIGINT, signal_handler) - -try: - response = requests.get(f"{base_url}/ready") - if response.status_code == 200: - pass -except: +# Check if we're running in docker +if os.path.isfile("/.dockerenv"): + print( + f"[{params['branding']}Startup] \033[94mRunning in Docker. Please wait.\033[0m" + ) +else: # Start the subprocess process = subprocess.Popen(["python", script_path]) # Check if the subprocess has started successfully From c29de18ad44d679501440916a315976549c1f833 Mon Sep 17 00:00:00 2001 From: Josh XT Date: Mon, 22 Jan 2024 19:41:18 -0500 Subject: [PATCH 22/25] add chmod --- Dockerfile | 1 + nvidia.Dockerfile | 1 + 2 files changed, 2 insertions(+) diff --git a/Dockerfile b/Dockerfile index 0e0cef9..a4da795 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,4 +8,5 @@ WORKDIR /app COPY . . RUN pip install --no-cache-dir -r requirements_other.txt EXPOSE 7851 +RUN chmod +x launch.sh ENTRYPOINT ["sh", "-c", "./launch.sh"] \ No newline at end of file diff --git a/nvidia.Dockerfile b/nvidia.Dockerfile index d7ac052..a273bc5 100644 --- a/nvidia.Dockerfile +++ b/nvidia.Dockerfile @@ -15,4 +15,5 @@ RUN pip install --no-cache-dir -r requirements_nvidia.txt && \ pip install --no-cache-dir -r requirements_finetune.txt && \ pip install --no-cache-dir -r requirements_other.txt EXPOSE 7851 +RUN chmod +x launch.sh ENTRYPOINT ["sh", "-c", "./launch.sh"] \ No newline at end of file From 0ed3cb75b54146eb7006c8da25dc3b6b4efe1ffc Mon Sep 17 00:00:00 2001 From: Josh XT Date: Mon, 22 Jan 2024 20:44:18 -0500 Subject: [PATCH 23/25] Add modeldownload --- launch.sh | 1 + nvidia.Dockerfile | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/launch.sh b/launch.sh index 23dc4d6..0de2cec 100644 --- a/launch.sh +++ b/launch.sh @@ -1,4 +1,5 @@ #!/bin/sh +python modeldownload.py uvicorn tts_server:app --host 0.0.0.0 --port 7581 --workers 1 --proxy-headers & sleep 5 python script.py \ No newline at end of file diff --git a/nvidia.Dockerfile b/nvidia.Dockerfile index a273bc5..475674a 100644 --- a/nvidia.Dockerfile +++ b/nvidia.Dockerfile @@ -13,7 +13,8 @@ ENV CUDA_DOCKER_ARCH=all RUN pip install --no-cache-dir -r requirements_nvidia.txt && \ pip install --no-cache-dir -r requirements_finetune.txt && \ - pip install --no-cache-dir -r requirements_other.txt + pip install --no-cache-dir -r requirements_other.txt && \ + pip install --no-cache-dir deepspeed EXPOSE 7851 RUN chmod +x launch.sh ENTRYPOINT ["sh", "-c", "./launch.sh"] \ No newline at end of file From b3f53e93cc884315d0a147020c29048ef7cadc18 Mon Sep 17 00:00:00 2001 From: Josh XT Date: Mon, 22 Jan 2024 20:46:53 -0500 Subject: [PATCH 24/25] fix typo --- launch.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launch.sh b/launch.sh index 0de2cec..97708c3 100644 --- a/launch.sh +++ b/launch.sh @@ -1,5 +1,5 @@ #!/bin/sh python modeldownload.py -uvicorn tts_server:app --host 0.0.0.0 --port 7581 --workers 1 --proxy-headers & +uvicorn tts_server:app --host 0.0.0.0 --port 7851 --workers 1 --proxy-headers & sleep 5 python script.py \ No newline at end of file From 71ba584e7ce333152dc605dad0e4f47d0e8837a5 Mon Sep 17 00:00:00 2001 From: Josh XT Date: Mon, 22 Jan 2024 21:15:29 -0500 Subject: [PATCH 25/25] Add voices --- docker-compose-cuda.yml | 1 + docker-compose.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/docker-compose-cuda.yml b/docker-compose-cuda.yml index 309609e..909a8f7 100644 --- a/docker-compose-cuda.yml +++ b/docker-compose-cuda.yml @@ -8,6 +8,7 @@ services: volumes: - ./outputs:/app/outputs/ - ./models:/app/models/ + - ./voices:/app/voices/ - ./finetune/put-voice-samples-in-here:/app/finetune/put-voice-samples-in-here - ./dockerconfig.json:/app/confignew.json deploy: diff --git a/docker-compose.yml b/docker-compose.yml index 2ab938b..fefcaaf 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,5 +8,6 @@ services: volumes: - ./outputs:/app/outputs/ - ./models:/app/models/ + - ./voices:/app/voices/ - ./finetune/put-voice-samples-in-here:/app/finetune/put-voice-samples-in-here - ./dockerconfig.json:/app/confignew.json \ No newline at end of file