Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7c7cb72c13 | ||
|
|
3a105ce922 | ||
|
|
690018c4ab | ||
|
|
6808439ca1 | ||
|
|
8cf56faad2 | ||
|
|
cb7d486288 | ||
|
|
086999fc1b | ||
|
|
a1b889108f | ||
|
|
9f18b24465 | ||
|
|
a3f157249c | ||
|
|
eb08d31509 | ||
|
|
1e1b7fdd8c | ||
|
|
5aad7bcc45 | ||
|
|
dd52597f49 | ||
|
|
5f836e08b8 | ||
|
|
b89b6cdc1d | ||
|
|
558aed1888 | ||
|
|
5eab3d28df | ||
|
|
fd76f496a0 | ||
|
|
4d9b44d9a0 | ||
|
|
951df5a239 | ||
|
|
0a35ee2310 | ||
|
|
efeb2e67e0 | ||
|
|
131f14de76 | ||
|
|
4e67931fe9 | ||
|
|
785525327d | ||
|
|
d4647573cd | ||
|
|
c3895b602c | ||
|
|
f18eb9a4a0 | ||
|
|
2834778e8f | ||
|
|
2f42c69d25 | ||
|
|
8c65f026e6 | ||
|
|
fff01107c8 | ||
|
|
0bdc66f6e5 | ||
|
|
1c3fc86085 | ||
|
|
d9eb0876a6 | ||
|
|
9b4130a8eb | ||
|
|
8fb5b4f695 | ||
|
|
65e306a198 | ||
|
|
3dabb63656 | ||
|
|
241fa91473 | ||
|
|
2a5c8dd58a | ||
|
|
2bfa10d7be | ||
|
|
3501e2e2f3 | ||
|
|
679e3a0982 | ||
|
|
35d05c7689 | ||
|
|
084cc2d2a2 | ||
|
|
a96c82ff01 | ||
|
|
aa7ff1940a | ||
|
|
58465ae14e | ||
|
|
2f49f61645 | ||
|
|
58a70caebc | ||
|
|
d0d470db0f | ||
|
|
068fc72346 | ||
|
|
fc5c8c748f | ||
|
|
24f86d08b7 | ||
|
|
99e402664c | ||
|
|
24cf9eae59 | ||
|
|
18b1582d2a | ||
|
|
96d9df9438 | ||
|
|
4ca156a032 | ||
|
|
5aecb5b7fd | ||
|
|
63c308ff05 | ||
|
|
e6e4b0b47f | ||
|
|
af4c63f1ee | ||
|
|
bedc8148ad | ||
|
|
21cd171719 | ||
|
|
856c0c1baa | ||
|
|
09977956f5 | ||
|
|
2c7feb31e5 | ||
|
|
cead53a808 | ||
|
|
e7996ebc7a | ||
|
|
6815ba0f2e | ||
|
|
51fa4ce9e9 | ||
|
|
043648e24a | ||
|
|
b76ff028f8 | ||
|
|
14214cc141 | ||
|
|
872638a198 | ||
|
|
5d2720c118 | ||
|
|
460216819a | ||
|
|
412d1442a6 | ||
|
|
5a1dd31ab6 | ||
|
|
ce84f153ca | ||
|
|
ab3570c899 | ||
|
|
42f08cd19c | ||
|
|
21fb1b58d9 | ||
|
|
d4741edf94 | ||
|
|
e3c7144272 | ||
|
|
27a4fe2338 | ||
|
|
a0913db3c9 | ||
|
|
645c0d3a67 | ||
|
|
e3878b595b | ||
|
|
825e4a7d12 | ||
|
|
6c20f45154 | ||
|
|
97cda27c7e | ||
|
|
a075495a0a | ||
|
|
b205657be3 | ||
|
|
483d6c8e79 | ||
|
|
9bd4665e6b | ||
|
|
62e1ab7e89 | ||
|
|
740c54db1c | ||
|
|
e188467730 | ||
|
|
743f23240e | ||
|
|
66dadbca25 | ||
|
|
8125b46dbe | ||
|
|
d4bd46f203 | ||
|
|
f13d6d336b | ||
|
|
1fa2f2e110 | ||
|
|
9ad4005e52 | ||
|
|
6d6b92d4b2 | ||
|
|
bf5d913cae | ||
|
|
f52ccd3931 | ||
|
|
37e7c8002d | ||
|
|
ad7382ee68 | ||
|
|
2428bfe357 | ||
|
|
74f3acc51f | ||
|
|
90a98f140b | ||
|
|
885311ecd8 | ||
|
|
c2952e9758 | ||
|
|
7e6e18c6d9 | ||
|
|
47eafafeda | ||
|
|
5edaab1356 | ||
|
|
7bde34d2ce | ||
|
|
0aa4638f68 | ||
|
|
22dd9c741c | ||
|
|
e000b8bb87 | ||
|
|
2d26f309df | ||
|
|
22d3e53a28 | ||
|
|
0ea646dbf3 | ||
|
|
282e3ce84c | ||
|
|
772afd47a1 | ||
|
|
1612835c5d | ||
|
|
ea551d3a84 | ||
|
|
47001203cd | ||
|
|
27ff5a12b0 | ||
|
|
0a89407e4d | ||
|
|
a579c5e6d2 | ||
|
|
5a21d14672 | ||
|
|
f4f5f82bb0 | ||
|
|
7b03804f9e | ||
|
|
f46493e6d8 | ||
|
|
2a64f6ad2b | ||
|
|
3368f8b016 | ||
|
|
121585ae84 | ||
|
|
3e6c11740d | ||
|
|
6b111494b3 | ||
|
|
b376a27da2 | ||
|
|
eeec4de703 | ||
|
|
49f98033b3 | ||
|
|
c1470930f4 | ||
|
|
1dec4f027b | ||
|
|
a9ef8edcb4 | ||
|
|
299238be7d | ||
|
|
29c7ea1526 | ||
|
|
e974e14a10 | ||
|
|
59c654bacd | ||
|
|
969b4e3f46 | ||
|
|
86c64fc9ba | ||
|
|
b8c0db6f56 | ||
|
|
57982cb810 | ||
|
|
6387007f56 | ||
|
|
cdf8d695e2 | ||
|
|
833bf3da4f | ||
|
|
f68086db0b | ||
|
|
1f7842ef5a | ||
|
|
9bb0d1fa58 | ||
|
|
015b9033ec | ||
|
|
7f261bb5e9 | ||
|
|
00b93cfe1b | ||
|
|
c0d01ee931 | ||
|
|
d0ceb2bb65 | ||
|
|
3231e61d56 | ||
|
|
32f3b721c2 | ||
|
|
8c588939d2 | ||
|
|
ff1077f282 | ||
|
|
36d0e92ed9 | ||
|
|
8dfb84d7e2 | ||
|
|
4caecdc5eb | ||
|
|
40f2fbf54e | ||
|
|
ab37dd8849 | ||
|
|
03b02e0e4c | ||
|
|
351f46c7b5 | ||
|
|
71ba584e7c | ||
|
|
b3f53e93cc | ||
|
|
0ed3cb75b5 | ||
|
|
c29de18ad4 | ||
|
|
ec1d0e8c5d | ||
|
|
12bf008b3f | ||
|
|
ecdc10ece5 | ||
|
|
360f70cb0a | ||
|
|
51c91c3d70 | ||
|
|
81a9f4c847 | ||
|
|
cdce7511dc | ||
|
|
6d4b6d336b | ||
|
|
6c4a9b19c7 | ||
|
|
82ecf3eecc | ||
|
|
d750959f52 | ||
|
|
bd74de53da | ||
|
|
fcec9d8f5b | ||
|
|
85e5e6ab86 | ||
|
|
d15931bdda | ||
|
|
abc9cf1fb7 | ||
|
|
2b60f5b0da | ||
|
|
e524063ec2 | ||
|
|
d93906a75f | ||
|
|
ad57deed20 | ||
|
|
d0866e3c6c | ||
|
|
af907a299d | ||
|
|
7928af1bb7 | ||
|
|
4d837a0219 | ||
|
|
e50817a234 | ||
|
|
c3bb58d2af | ||
|
|
c17959f142 | ||
|
|
def2d51c5f | ||
|
|
6166d4f751 | ||
|
|
cd164ae258 | ||
|
|
f089e3e85b | ||
|
|
d008c7ab0a | ||
|
|
a199adfbd6 | ||
|
|
61998b4d39 | ||
|
|
55799b2de8 | ||
|
|
ece55ffe06 | ||
|
|
dbc2582fa6 | ||
|
|
535c9b652a | ||
|
|
6c28d58b4a | ||
|
|
c9a222932c | ||
|
|
7010369966 | ||
|
|
525a337835 | ||
|
|
2bd1ef843e | ||
|
|
a9d95fc563 | ||
|
|
1a37ae4ba5 | ||
|
|
8c6fc4853d | ||
|
|
f34ebbd675 | ||
|
|
64cffcdf80 | ||
|
|
2731a559f4 | ||
|
|
a91a83268f | ||
|
|
5d406fbbfb | ||
|
|
cefd1e045b | ||
|
|
bec4e905d3 | ||
|
|
f5e99a5e72 | ||
|
|
631ea6dd8a | ||
|
|
08a04ba506 | ||
|
|
c78927b80a | ||
|
|
04e08c58b8 | ||
|
|
893747c9a9 | ||
|
|
d52dcf86d5 | ||
|
|
ad0eab1224 | ||
|
|
62d1cc05d3 | ||
|
|
b8292da92f | ||
|
|
180adb45dd | ||
|
|
5c0f08d49e | ||
|
|
571872dbe2 | ||
|
|
467bfbea55 | ||
|
|
5a3cbb6366 | ||
|
|
2351e418fd | ||
|
|
b987ff38a7 | ||
|
|
43899028e3 | ||
|
|
2c1ca8b2a3 | ||
|
|
139162c4e6 | ||
|
|
7da78ec045 | ||
|
|
11c70c7432 | ||
|
|
c2822edb1b | ||
|
|
cba7ed7b88 | ||
|
|
471a26f2a4 | ||
|
|
34d1b81ae4 | ||
|
|
f1b4d4b8b6 | ||
|
|
c05237143b | ||
|
|
c5846b832a | ||
|
|
7a38730c56 | ||
|
|
0b1e6f8711 | ||
|
|
8c38e925dd | ||
|
|
df70481934 | ||
|
|
e43c58a56e | ||
|
|
8dc9304a4c | ||
|
|
102424669b | ||
|
|
5210d075c1 | ||
|
|
30db974439 | ||
|
|
c2a558110b | ||
|
|
83ac18b83f | ||
|
|
6e36415746 | ||
|
|
fe7ffb535c | ||
|
|
80b7fccb50 | ||
|
|
2790ee9860 | ||
|
|
74ce2584cc | ||
|
|
8dd11541b4 | ||
|
|
d1317b49f0 | ||
|
|
a50d5a5028 | ||
|
|
33264554cd | ||
|
|
4a116e359a | ||
|
|
36bfb17eda | ||
|
|
697fb098c3 | ||
|
|
51a8e93df7 | ||
|
|
257fa59e70 | ||
|
|
7dbad85fc3 | ||
|
|
510894c793 | ||
|
|
a85058a3ac | ||
|
|
e54c7e4362 | ||
|
|
1f2ad303a0 | ||
|
|
d4a04096c8 | ||
|
|
dd45008e88 | ||
|
|
e9d9f54de6 | ||
|
|
3230397a82 | ||
|
|
840889ac9a | ||
|
|
d3e061b127 | ||
|
|
a428f67a2e | ||
|
|
b223e7b247 | ||
|
|
9296843508 | ||
|
|
f0c9e3e6bb | ||
|
|
22de1bf0c6 | ||
|
|
621f5434a7 | ||
|
|
81c8354cf8 | ||
|
|
3bc55a91e5 | ||
|
|
fc857f464c | ||
|
|
50aa6de96c | ||
|
|
10299194f8 | ||
|
|
d80d1ace3c | ||
|
|
f19f4e9a29 | ||
|
|
7e4ceef0e8 | ||
|
|
c1bc1f26cd | ||
|
|
70d385133d | ||
|
|
13b2eb5fe3 | ||
|
|
ff4b9d9e99 | ||
|
|
a22830f700 | ||
|
|
374c794fa9 | ||
|
|
d2adbd9c1e | ||
|
|
1dc4b8bf50 | ||
|
|
0eba72fc47 | ||
|
|
f2c87dcdab | ||
|
|
4a727ce14a | ||
|
|
6e15d43e63 | ||
|
|
dedc13b3b6 | ||
|
|
7cb206e531 | ||
|
|
4f80b39cd0 | ||
|
|
d5fa6bb46d | ||
|
|
332582baea | ||
|
|
2bd7ebc514 | ||
|
|
e5acc8bdbd | ||
|
|
7718bfd3ea | ||
|
|
002c5ad9db | ||
|
|
2c14847708 | ||
|
|
3647d69007 | ||
|
|
56a7ea1d8f | ||
|
|
863a7cd841 | ||
|
|
2e1709ab58 | ||
|
|
9c4efdc135 | ||
|
|
28675c976c | ||
|
|
afe3b9fe0b | ||
|
|
2e4d52170d | ||
|
|
0e2cc25571 | ||
|
|
abaa56e8f4 | ||
|
|
d0dc9f3212 | ||
|
|
67dcc411ad | ||
|
|
b11a087dc8 | ||
|
|
e068115eef | ||
|
|
0ec580539a | ||
|
|
e9feae12ad | ||
|
|
e183e3a7bb | ||
|
|
8a2b669da9 | ||
|
|
67d2b1c5ea | ||
|
|
f3b44424ef | ||
|
|
3b5c4b9b68 | ||
|
|
e452a926f2 | ||
|
|
b65291d44d | ||
|
|
b28ecaf43e | ||
|
|
ba1328311c | ||
|
|
9e6b9396bc | ||
|
|
2e40db5fe5 | ||
|
|
720bf8697f | ||
|
|
1893d1a130 | ||
|
|
8472baf031 | ||
|
|
6cab618706 | ||
|
|
ebf3b362f7 | ||
|
|
2dd303f53c | ||
|
|
df69fb0b07 | ||
|
|
a0d9771fa6 | ||
|
|
a71c46bb98 | ||
|
|
995f317b4f | ||
|
|
6ef2de2923 | ||
|
|
37c4e86566 | ||
|
|
11071b279b | ||
|
|
5ab7463f35 | ||
|
|
74c9238e3a | ||
|
|
e874e46304 | ||
|
|
b32df6ac15 | ||
|
|
b76dd3561f | ||
|
|
60bfbdcabd | ||
|
|
c128d0851b | ||
|
|
2f3b7762e4 | ||
|
|
0e594f5098 | ||
|
|
14151d4dda | ||
|
|
94ab21fb15 | ||
|
|
1acac3d6c6 | ||
|
|
95ec2dc9d2 | ||
|
|
6b93eb6c1e | ||
|
|
838578a042 | ||
|
|
2f689f0438 | ||
|
|
022025ded6 | ||
|
|
320a7a6aba | ||
|
|
fa82870883 | ||
|
|
a094d4f9da | ||
|
|
bb028af694 | ||
|
|
aeb225ec7c | ||
|
|
06a632459e | ||
|
|
221efbddb4 | ||
|
|
e81a88938a | ||
|
|
65e257077c | ||
|
|
95659d5b7a | ||
|
|
ff57270286 | ||
|
|
4fc61ba99a | ||
|
|
3cd22081f4 | ||
|
|
d20ee95e67 | ||
|
|
cd47f6b123 | ||
|
|
53a2d0a65e | ||
|
|
13318243e4 | ||
|
|
acc457436a | ||
|
|
8d80151889 | ||
|
|
8b0ade5b9f | ||
|
|
9f033e4654 | ||
|
|
1a2b8571d0 | ||
|
|
9ab20be294 | ||
|
|
a34cbfdd55 | ||
|
|
94f5b781cc | ||
|
|
f83e7c3b4e | ||
|
|
607dc89be5 | ||
|
|
47758c4aeb | ||
|
|
26414d4925 | ||
|
|
7ad92e7f5d | ||
|
|
e775cef5bd | ||
|
|
ac9ce144a0 | ||
|
|
f181c06f89 | ||
|
|
9fae4692e3 | ||
|
|
97f0d6441a | ||
|
|
2ea6cb6304 | ||
|
|
5bed68a963 | ||
|
|
be9862d0b0 | ||
|
|
f5a811f0f8 | ||
|
|
dc9d343115 | ||
|
|
c92aa435e5 | ||
|
|
1f425e6bac | ||
|
|
0854544a47 | ||
|
|
52a7922e98 | ||
|
|
558583b16f | ||
|
|
993d065368 | ||
|
|
d7376fa8ef | ||
|
|
2b175b13c4 | ||
|
|
da0445489e | ||
|
|
e4eaa760b9 | ||
|
|
de4017f385 | ||
|
|
f2119aa0f7 | ||
|
|
bb81f3f874 | ||
|
|
fae15eecb1 | ||
|
|
6edcc2125b | ||
|
|
d26909a1d6 | ||
|
|
3be6b842c4 | ||
|
|
e10dc700c3 | ||
|
|
e8e21f949c | ||
|
|
e68a7d72f2 | ||
|
|
fd26db8e8a | ||
|
|
396f1290e7 | ||
|
|
5bc7dd8692 | ||
|
|
b5b68ad51f | ||
|
|
e49ceed40c | ||
|
|
598aec7f52 | ||
|
|
f25d2627cd | ||
|
|
3e6f1bace3 | ||
|
|
fb851ff3f0 | ||
|
|
92bf8f5de8 | ||
|
|
8f318892c2 | ||
|
|
28a62ed39a | ||
|
|
4c08927ed9 | ||
|
|
a93da39711 | ||
|
|
557f4b80b6 |
No files matched your search
@@ -0,0 +1 @@
|
|||||||
|
ko_fi: erew123
|
||||||
@@ -1,13 +1,14 @@
|
|||||||
---
|
---
|
||||||
name: Bug report/Support request
|
name: Support Request/Issue
|
||||||
about: Create a report to help us improve
|
about: Use this to create a support request or report a bug/issue
|
||||||
title: ''
|
title: ''
|
||||||
labels: ''
|
labels: ''
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
🔴 If you have installed AllTalk in a custom Python environment, I will only be able to provide limited assistance/support. AllTalk draws on a variety of scripts and libraries that are not written or managed by myself, and they may fail, error or give strange results in custom built python environments.
|
||||||
|
|
||||||
Please generate a diagnostics report and upload the "diagnostics.log".
|
🔴 Please generate a diagnostics report and upload the "diagnostics.log" as this helps me understand your configuration.
|
||||||
|
|
||||||
https://github.com/erew123/alltalk_tts/tree/main?#-how-to-make-a-diagnostics-report-file
|
https://github.com/erew123/alltalk_tts/tree/main?#-how-to-make-a-diagnostics-report-file
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: Feature request
|
name: Feature request
|
||||||
about: Suggest an idea for this project
|
about: Use this to create a Feature request
|
||||||
title: ''
|
title: ''
|
||||||
labels: ''
|
labels: ''
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
name: Publish Docker image
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
release:
|
||||||
|
types: [published]
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build_and_push:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- dockerfile: "Dockerfile"
|
||||||
|
platforms: "linux/amd64"
|
||||||
|
tag_name: "cpu"
|
||||||
|
- dockerfile: "nvidia.Dockerfile"
|
||||||
|
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: 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: ${{ env.ACTOR_LOWER }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Login to DockerHub
|
||||||
|
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: ./${{ matrix.dockerfile }}
|
||||||
|
platforms: ${{ matrix.platforms }}
|
||||||
|
push: true
|
||||||
|
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
|
||||||
|
${{ 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
|
||||||
|
with:
|
||||||
|
username: ${{ vars.DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
repository: ${{ vars.DOCKERHUB_USERNAME }}/${{ env.REPO_NAME }}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
voices/*.*
|
voices/*.*
|
||||||
models/*.*
|
models/*.*
|
||||||
outputs/*.*
|
outputs/*.*
|
||||||
|
finetune/*.*
|
||||||
config.json
|
config.json
|
||||||
confignew.json
|
confignew.json
|
||||||
models.json
|
models.json
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"files.associations": {
|
||||||
|
"*.html": "jinja-html"
|
||||||
|
},
|
||||||
|
"emmet.includeLanguages": {
|
||||||
|
"jinja-html": "html",
|
||||||
|
"jinja2": "html"
|
||||||
|
},
|
||||||
|
}
|
||||||
@@ -1,285 +0,0 @@
|
|||||||
// Copyright (c) Microsoft Corporation.
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
// DeepSpeed Team
|
|
||||||
|
|
||||||
#include <ATen/cuda/CUDAContext.h>
|
|
||||||
#include <torch/extension.h>
|
|
||||||
#include <cassert>
|
|
||||||
#include <vector>
|
|
||||||
#include "quantization.h"
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
at::Tensor ds_quantize(at::Tensor& vals, int groups, int bits)
|
|
||||||
{
|
|
||||||
auto t_size = vals.sizes();
|
|
||||||
int size = 1;
|
|
||||||
for (auto dim : t_size) size *= dim;
|
|
||||||
|
|
||||||
if ((((size / groups) - 1) / 4096 + 1) <= 256) {
|
|
||||||
launch_fake_quantize_kernel(
|
|
||||||
(T*)vals.data_ptr(), size, groups, bits, at::cuda::getCurrentCUDAStream());
|
|
||||||
}
|
|
||||||
return vals;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
at::Tensor ds_sr_quantize(at::Tensor& vals, int groups, int bits)
|
|
||||||
{
|
|
||||||
auto t_size = vals.sizes();
|
|
||||||
int size = 1;
|
|
||||||
for (auto dim : t_size) size *= dim;
|
|
||||||
|
|
||||||
if (((size / groups) / 4 / 1024) <= 256) {
|
|
||||||
launch_sr_fake_quantize_kernel(
|
|
||||||
(T*)vals.data_ptr(), size, groups, bits, at::cuda::getCurrentCUDAStream());
|
|
||||||
}
|
|
||||||
return vals;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
at::Tensor ds_quantize_asym(at::Tensor& vals, int groups, int bits)
|
|
||||||
{
|
|
||||||
auto t_size = vals.sizes();
|
|
||||||
int size = 1;
|
|
||||||
for (auto dim : t_size) size *= dim;
|
|
||||||
|
|
||||||
if ((((size / groups) - 1) / 4096 + 1) <= 256) {
|
|
||||||
launch_fake_quantize_kernel_asym(
|
|
||||||
(T*)vals.data_ptr(), size, groups, bits, at::cuda::getCurrentCUDAStream());
|
|
||||||
}
|
|
||||||
return vals;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
at::Tensor ds_sr_quantize_asym(at::Tensor& vals, int groups, int bits)
|
|
||||||
{
|
|
||||||
auto t_size = vals.sizes();
|
|
||||||
int size = 1;
|
|
||||||
for (auto dim : t_size) size *= dim;
|
|
||||||
|
|
||||||
if (((size / groups) / 4 / 1024) <= 256) {
|
|
||||||
launch_sr_fake_quantize_kernel_asym(
|
|
||||||
(T*)vals.data_ptr(), size, groups, bits, at::cuda::getCurrentCUDAStream());
|
|
||||||
}
|
|
||||||
return vals;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<at::Tensor> quantize_kernel(at::Tensor& input_vals,
|
|
||||||
int groups,
|
|
||||||
int numBits,
|
|
||||||
quantize::Type quantType)
|
|
||||||
{
|
|
||||||
auto dtype = at::kFloat;
|
|
||||||
auto params_options = at::TensorOptions()
|
|
||||||
.dtype(dtype)
|
|
||||||
.layout(at::kStrided)
|
|
||||||
.device(at::kCUDA)
|
|
||||||
.requires_grad(false);
|
|
||||||
const int param_elems = (quantize::requires_offset(quantType)) ? 2 : 1;
|
|
||||||
auto params = torch::empty({groups, param_elems}, params_options);
|
|
||||||
|
|
||||||
auto output_options = at::TensorOptions()
|
|
||||||
.dtype(at::kChar)
|
|
||||||
.layout(at::kStrided)
|
|
||||||
.device(at::kCUDA)
|
|
||||||
.requires_grad(false);
|
|
||||||
|
|
||||||
auto output_sizes = input_vals.sizes().vec();
|
|
||||||
output_sizes[output_sizes.size() - 1] /= numBits == 8 ? 1 : 2;
|
|
||||||
auto output = torch::empty(output_sizes, output_options);
|
|
||||||
|
|
||||||
const int elems_per_group = at::numel(input_vals) / groups;
|
|
||||||
|
|
||||||
launch_quant((int8_t*)output.data_ptr(),
|
|
||||||
(float*)params.data_ptr(),
|
|
||||||
(__half*)input_vals.data_ptr(),
|
|
||||||
groups,
|
|
||||||
elems_per_group,
|
|
||||||
numBits,
|
|
||||||
quantType,
|
|
||||||
at::cuda::getCurrentCUDAStream());
|
|
||||||
|
|
||||||
return {output, params};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
at::Tensor dequantize(at::Tensor& quantized_data,
|
|
||||||
at::Tensor& params,
|
|
||||||
int groups,
|
|
||||||
int num_bits,
|
|
||||||
quantize::Type quant_type)
|
|
||||||
{
|
|
||||||
auto dtype = (std::is_same<T, float>::value) ? torch::kFloat32 : torch::kFloat16;
|
|
||||||
auto output_options = at::TensorOptions()
|
|
||||||
.dtype(dtype)
|
|
||||||
.layout(at::kStrided)
|
|
||||||
.device(at::kCUDA)
|
|
||||||
.requires_grad(false);
|
|
||||||
|
|
||||||
auto output_sizes = quantized_data.sizes().vec();
|
|
||||||
output_sizes[output_sizes.size() - 1] *= num_bits == 8 ? 1 : 2;
|
|
||||||
auto output = torch::empty(output_sizes, output_options);
|
|
||||||
|
|
||||||
const int total_elems = at::numel(output);
|
|
||||||
const int elems_per_group = total_elems / groups;
|
|
||||||
|
|
||||||
launch_dequantize_kernel((T*)output.data_ptr(),
|
|
||||||
(const int8_t*)quantized_data.data_ptr(),
|
|
||||||
(const float*)params.data_ptr(),
|
|
||||||
quant_type,
|
|
||||||
num_bits,
|
|
||||||
elems_per_group,
|
|
||||||
total_elems,
|
|
||||||
at::cuda::getCurrentCUDAStream());
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
at::Tensor dequantize_int4_to_half_experimental(at::Tensor& data_in,
|
|
||||||
at::Tensor& scale_buffer,
|
|
||||||
at::Tensor& min_val_buffer,
|
|
||||||
int num_group,
|
|
||||||
int group_size)
|
|
||||||
{
|
|
||||||
auto output_options = at::TensorOptions().dtype(at::kHalf).device(at::kCUDA);
|
|
||||||
auto output = torch::empty({num_group, group_size}, output_options);
|
|
||||||
|
|
||||||
launch_dequantize_int4_to_half_experimental((uint8_t*)data_in.data_ptr(),
|
|
||||||
(half*)output.data_ptr(),
|
|
||||||
(half*)scale_buffer.data_ptr(),
|
|
||||||
(half*)min_val_buffer.data_ptr(),
|
|
||||||
num_group,
|
|
||||||
group_size,
|
|
||||||
at::cuda::getCurrentCUDAStream());
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<at::Tensor> ds_swizzle_quant(at::Tensor& input_vals,
|
|
||||||
int groups,
|
|
||||||
int num_bits,
|
|
||||||
quantize::Type quant_type,
|
|
||||||
int pipeline_size,
|
|
||||||
int nodes,
|
|
||||||
int devices_per_node)
|
|
||||||
{
|
|
||||||
auto scales_options = at::TensorOptions()
|
|
||||||
.dtype(at::kFloat)
|
|
||||||
.layout(at::kStrided)
|
|
||||||
.device(at::kCUDA)
|
|
||||||
.requires_grad(false);
|
|
||||||
const int scales_elems = (quantize::requires_offset(quant_type)) ? 2 : 1;
|
|
||||||
auto scales = torch::empty({groups, scales_elems}, scales_options);
|
|
||||||
|
|
||||||
auto output_options = at::TensorOptions()
|
|
||||||
.dtype(at::kChar)
|
|
||||||
.layout(at::kStrided)
|
|
||||||
.device(at::kCUDA)
|
|
||||||
.requires_grad(false);
|
|
||||||
|
|
||||||
const int quantization_scalar = 8 / num_bits;
|
|
||||||
const int compressed_vals = at::numel(input_vals) / quantization_scalar;
|
|
||||||
|
|
||||||
auto output = torch::empty({compressed_vals}, output_options);
|
|
||||||
const int elems_per_group = at::numel(input_vals) / groups;
|
|
||||||
|
|
||||||
launch_swizzled_quant((int8_t*)output.data_ptr(),
|
|
||||||
(float*)scales.data_ptr(),
|
|
||||||
(__half*)input_vals.data_ptr(),
|
|
||||||
num_bits,
|
|
||||||
quant_type,
|
|
||||||
groups,
|
|
||||||
elems_per_group,
|
|
||||||
pipeline_size,
|
|
||||||
nodes,
|
|
||||||
devices_per_node,
|
|
||||||
at::cuda::getCurrentCUDAStream());
|
|
||||||
|
|
||||||
return {output, scales};
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<at::Tensor> quantized_reduction(at::Tensor& input_vals,
|
|
||||||
at::Tensor& input_scales,
|
|
||||||
int in_groups,
|
|
||||||
int out_groups,
|
|
||||||
int num_bits,
|
|
||||||
quantize::Type quant_type,
|
|
||||||
int devices_per_node)
|
|
||||||
{
|
|
||||||
auto scales_options = at::TensorOptions()
|
|
||||||
.dtype(at::kFloat)
|
|
||||||
.layout(at::kStrided)
|
|
||||||
.device(at::kCUDA)
|
|
||||||
.requires_grad(false);
|
|
||||||
const int scales_elems = (quantize::requires_offset(quant_type)) ? 2 : 1;
|
|
||||||
auto scales = torch::empty({out_groups, scales_elems}, scales_options);
|
|
||||||
|
|
||||||
auto output_options = at::TensorOptions()
|
|
||||||
.dtype(at::kChar)
|
|
||||||
.layout(at::kStrided)
|
|
||||||
.device(at::kCUDA)
|
|
||||||
.requires_grad(false);
|
|
||||||
|
|
||||||
std::vector<int64_t> sz_vector(input_vals.sizes().begin(), input_vals.sizes().end());
|
|
||||||
sz_vector[sz_vector.size() - 1] = sz_vector.back() / devices_per_node; // num of GPU per nodes
|
|
||||||
at::IntArrayRef sz(sz_vector);
|
|
||||||
auto output = torch::empty(sz, output_options);
|
|
||||||
|
|
||||||
const int elems_per_in_tensor = at::numel(input_vals) / devices_per_node;
|
|
||||||
const int elems_per_in_group = elems_per_in_tensor / (in_groups / devices_per_node);
|
|
||||||
const int elems_per_out_group = elems_per_in_tensor / out_groups;
|
|
||||||
|
|
||||||
// old code:
|
|
||||||
// std::vector<long int> sz(input_vals.sizes().begin(), input_vals.sizes().end());
|
|
||||||
// sz[sz.size() - 1] = sz.back() / devices_per_node; // num of GPU per nodes
|
|
||||||
// const int elems_per_in_tensor = at::numel(input_vals) / devices_per_node;
|
|
||||||
// auto output = torch::empty(sz, output_options);
|
|
||||||
|
|
||||||
// const int elems_per_in_group = elems_per_in_tensor / (in_groups / devices_per_node);
|
|
||||||
// const int elems_per_out_group = elems_per_in_tensor / out_groups;
|
|
||||||
|
|
||||||
launch_dequant_reduce((int8_t*)output.data_ptr(),
|
|
||||||
(float*)scales.data_ptr(),
|
|
||||||
(const int8_t*)input_vals.data_ptr(),
|
|
||||||
(const float*)input_scales.data_ptr(),
|
|
||||||
devices_per_node,
|
|
||||||
num_bits,
|
|
||||||
quant_type,
|
|
||||||
out_groups,
|
|
||||||
elems_per_out_group,
|
|
||||||
elems_per_in_tensor,
|
|
||||||
in_groups / devices_per_node,
|
|
||||||
elems_per_in_group,
|
|
||||||
at::cuda::getCurrentCUDAStream());
|
|
||||||
return {output, scales};
|
|
||||||
}
|
|
||||||
|
|
||||||
PYBIND11_MODULE(TORCH_EXTENSION_NAME, m)
|
|
||||||
{
|
|
||||||
m.def("ds_quantize_fp32", &ds_quantize<float>, "DeepSpeed Quantize with fp32 (CUDA)");
|
|
||||||
m.def("ds_quantize_fp16", &ds_quantize<__half>, "DeepSpeed Quantize with fp16 (CUDA)");
|
|
||||||
m.def("ds_sr_quantize_fp32", &ds_sr_quantize<float>, "DeepSpeed Quantize with fp32 (CUDA)");
|
|
||||||
m.def("ds_sr_quantize_fp16", &ds_sr_quantize<__half>, "DeepSpeed Quantize with fp16 (CUDA)");
|
|
||||||
m.def("ds_quantize_asym_fp32", &ds_quantize_asym<float>, "DeepSpeed Quantize with fp32 (CUDA)");
|
|
||||||
m.def(
|
|
||||||
"ds_quantize_asym_fp16", &ds_quantize_asym<__half>, "DeepSpeed Quantize with fp16 (CUDA)");
|
|
||||||
m.def("ds_sr_quantize_asym_fp32",
|
|
||||||
&ds_sr_quantize_asym<float>,
|
|
||||||
"DeepSpeed Quantize with fp32 (CUDA)");
|
|
||||||
m.def("ds_sr_quantize_asym_fp16",
|
|
||||||
&ds_sr_quantize_asym<__half>,
|
|
||||||
"DeepSpeed Quantize with fp16 (CUDA)");
|
|
||||||
pybind11::enum_<quantize::Type>(m, "QuantizationType")
|
|
||||||
.value("Symmetric", quantize::Type::Symmetric)
|
|
||||||
.value("Asymmetric", quantize::Type::Asymmetric)
|
|
||||||
.export_values();
|
|
||||||
m.def("quantize", &quantize_kernel);
|
|
||||||
m.def("dequantize", &dequantize<__half>);
|
|
||||||
m.def("dequantize_fp32", &dequantize<float>);
|
|
||||||
m.def("dequantize_int4_to_half_experimental",
|
|
||||||
&dequantize_int4_to_half_experimental,
|
|
||||||
"Dequantize int4 to half (experimental)");
|
|
||||||
m.def("swizzle_quant", &ds_swizzle_quant);
|
|
||||||
m.def("quantized_reduction", &quantized_reduction);
|
|
||||||
}
|
|
||||||
@@ -1,160 +0,0 @@
|
|||||||
# Copyright (c) Microsoft Corporation.
|
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
# DeepSpeed Team
|
|
||||||
|
|
||||||
import os
|
|
||||||
import torch
|
|
||||||
import deepspeed
|
|
||||||
import subprocess
|
|
||||||
import argparse
|
|
||||||
import psutil
|
|
||||||
from .ops.op_builder.all_ops import ALL_OPS
|
|
||||||
from .git_version_info import installed_ops, torch_info
|
|
||||||
from deepspeed.accelerator import get_accelerator
|
|
||||||
|
|
||||||
GREEN = '\033[92m'
|
|
||||||
RED = '\033[91m'
|
|
||||||
YELLOW = '\033[93m'
|
|
||||||
END = '\033[0m'
|
|
||||||
SUCCESS = f"{GREEN} [SUCCESS] {END}"
|
|
||||||
OKAY = f"{GREEN}[OKAY]{END}"
|
|
||||||
WARNING = f"{YELLOW}[WARNING]{END}"
|
|
||||||
FAIL = f'{RED}[FAIL]{END}'
|
|
||||||
INFO = '[INFO]'
|
|
||||||
|
|
||||||
color_len = len(GREEN) + len(END)
|
|
||||||
okay = f"{GREEN}[OKAY]{END}"
|
|
||||||
warning = f"{YELLOW}[WARNING]{END}"
|
|
||||||
|
|
||||||
|
|
||||||
def op_report(verbose=True):
|
|
||||||
max_dots = 23
|
|
||||||
max_dots2 = 11
|
|
||||||
h = ["op name", "installed", "compatible"]
|
|
||||||
print("-" * (max_dots + max_dots2 + len(h[0]) + len(h[1])))
|
|
||||||
print("DeepSpeed C++/CUDA extension op report")
|
|
||||||
print("-" * (max_dots + max_dots2 + len(h[0]) + len(h[1])))
|
|
||||||
|
|
||||||
print("NOTE: Ops not installed will be just-in-time (JIT) compiled at\n"
|
|
||||||
" runtime if needed. Op compatibility means that your system\n"
|
|
||||||
" meet the required dependencies to JIT install the op.")
|
|
||||||
|
|
||||||
print("-" * (max_dots + max_dots2 + len(h[0]) + len(h[1])))
|
|
||||||
print("JIT compiled ops requires ninja")
|
|
||||||
ninja_status = OKAY if ninja_installed() else FAIL
|
|
||||||
print('ninja', "." * (max_dots - 5), ninja_status)
|
|
||||||
print("-" * (max_dots + max_dots2 + len(h[0]) + len(h[1])))
|
|
||||||
print(h[0], "." * (max_dots - len(h[0])), h[1], "." * (max_dots2 - len(h[1])), h[2])
|
|
||||||
print("-" * (max_dots + max_dots2 + len(h[0]) + len(h[1])))
|
|
||||||
installed = f"{GREEN}[YES]{END}"
|
|
||||||
no = f"{YELLOW}[NO]{END}"
|
|
||||||
for op_name, builder in ALL_OPS.items():
|
|
||||||
dots = "." * (max_dots - len(op_name))
|
|
||||||
is_compatible = OKAY if builder.is_compatible(verbose) else no
|
|
||||||
is_installed = installed if installed_ops.get(op_name, False) else no
|
|
||||||
dots2 = '.' * ((len(h[1]) + (max_dots2 - len(h[1]))) - (len(is_installed) - color_len))
|
|
||||||
print(op_name, dots, is_installed, dots2, is_compatible)
|
|
||||||
print("-" * (max_dots + max_dots2 + len(h[0]) + len(h[1])))
|
|
||||||
|
|
||||||
|
|
||||||
def ninja_installed():
|
|
||||||
try:
|
|
||||||
import ninja # noqa: F401 # type: ignore
|
|
||||||
except ImportError:
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
def nvcc_version():
|
|
||||||
import torch.utils.cpp_extension
|
|
||||||
cuda_home = torch.utils.cpp_extension.CUDA_HOME
|
|
||||||
if cuda_home is None:
|
|
||||||
return f"{RED} [FAIL] cannot find CUDA_HOME via torch.utils.cpp_extension.CUDA_HOME={torch.utils.cpp_extension.CUDA_HOME} {END}"
|
|
||||||
try:
|
|
||||||
output = subprocess.check_output([cuda_home + "/bin/nvcc", "-V"], universal_newlines=True)
|
|
||||||
except FileNotFoundError:
|
|
||||||
return f"{RED} [FAIL] nvcc missing {END}"
|
|
||||||
output_split = output.split()
|
|
||||||
release_idx = output_split.index("release")
|
|
||||||
release = output_split[release_idx + 1].replace(',', '').split(".")
|
|
||||||
return ".".join(release)
|
|
||||||
|
|
||||||
|
|
||||||
def get_shm_size():
|
|
||||||
try:
|
|
||||||
temp_dir = os.getenv('TEMP') or os.getenv('TMP') or os.path.join(os.path.expanduser('~'), 'tmp')
|
|
||||||
shm_stats = psutil.disk_usage(temp_dir)
|
|
||||||
shm_size = shm_stats.total
|
|
||||||
shm_hbytes = human_readable_size(shm_size)
|
|
||||||
warn = []
|
|
||||||
if shm_size < 512 * 1024**2:
|
|
||||||
warn.append(
|
|
||||||
f" {YELLOW} [WARNING] Shared memory size might be too small, consider increasing it. {END}"
|
|
||||||
)
|
|
||||||
# Add additional warnings specific to your use case if needed.
|
|
||||||
return shm_hbytes, warn
|
|
||||||
except Exception as e:
|
|
||||||
return "UNKNOWN", [f"Error getting shared memory size: {e}"]
|
|
||||||
|
|
||||||
def human_readable_size(size):
|
|
||||||
units = ['B', 'KB', 'MB', 'GB', 'TB']
|
|
||||||
i = 0
|
|
||||||
while size >= 1024 and i < len(units) - 1:
|
|
||||||
size /= 1024
|
|
||||||
i += 1
|
|
||||||
return f'{size:.2f} {units[i]}'
|
|
||||||
|
|
||||||
|
|
||||||
def debug_report():
|
|
||||||
max_dots = 33
|
|
||||||
|
|
||||||
report = [("torch install path", torch.__path__), ("torch version", torch.__version__),
|
|
||||||
("deepspeed install path", deepspeed.__path__),
|
|
||||||
("deepspeed info", f"{deepspeed.__version__}, {deepspeed.__git_hash__}, {deepspeed.__git_branch__}")]
|
|
||||||
if get_accelerator().device_name() == 'cuda':
|
|
||||||
hip_version = getattr(torch.version, "hip", None)
|
|
||||||
report.extend([("torch cuda version", torch.version.cuda), ("torch hip version", hip_version),
|
|
||||||
("nvcc version", (None if hip_version else nvcc_version())),
|
|
||||||
("deepspeed wheel compiled w.", f"torch {torch_info['version']}, " +
|
|
||||||
(f"hip {torch_info['hip_version']}" if hip_version else f"cuda {torch_info['cuda_version']}"))
|
|
||||||
])
|
|
||||||
else:
|
|
||||||
report.extend([("deepspeed wheel compiled w.", f"torch {torch_info['version']} ")])
|
|
||||||
|
|
||||||
report.append(("shared memory (/dev/shm) size", get_shm_size()))
|
|
||||||
|
|
||||||
print("DeepSpeed general environment info:")
|
|
||||||
for name, value in report:
|
|
||||||
warns = []
|
|
||||||
if isinstance(value, tuple):
|
|
||||||
value, warns = value
|
|
||||||
print(name, "." * (max_dots - len(name)), value)
|
|
||||||
if warns:
|
|
||||||
for warn in warns:
|
|
||||||
print(warn)
|
|
||||||
|
|
||||||
|
|
||||||
def parse_arguments():
|
|
||||||
parser = argparse.ArgumentParser()
|
|
||||||
parser.add_argument('--hide_operator_status',
|
|
||||||
action='store_true',
|
|
||||||
help='Suppress display of installation and compatibility statuses of DeepSpeed operators. ')
|
|
||||||
parser.add_argument('--hide_errors_and_warnings', action='store_true', help='Suppress warning and error messages.')
|
|
||||||
args = parser.parse_args()
|
|
||||||
return args
|
|
||||||
|
|
||||||
|
|
||||||
def main(hide_operator_status=False, hide_errors_and_warnings=False):
|
|
||||||
if not hide_operator_status:
|
|
||||||
op_report(verbose=not hide_errors_and_warnings)
|
|
||||||
debug_report()
|
|
||||||
|
|
||||||
|
|
||||||
def cli_main():
|
|
||||||
args = parse_arguments()
|
|
||||||
main(hide_operator_status=args.hide_operator_status, hide_errors_and_warnings=args.hide_errors_and_warnings)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
@@ -1,299 +0,0 @@
|
|||||||
// Copyright (c) Microsoft Corporation.
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
// DeepSpeed Team
|
|
||||||
|
|
||||||
#include <ATen/cuda/CUDAContext.h>
|
|
||||||
#include <torch/extension.h>
|
|
||||||
#include <cassert>
|
|
||||||
#include <vector>
|
|
||||||
#include "quantization.h"
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
at::Tensor ds_quantize(at::Tensor& vals, int groups, int bits)
|
|
||||||
{
|
|
||||||
auto t_size = vals.sizes();
|
|
||||||
int size = 1;
|
|
||||||
for (auto dim : t_size) size *= dim;
|
|
||||||
|
|
||||||
if ((((size / groups) - 1) / 4096 + 1) <= 256) {
|
|
||||||
launch_fake_quantize_kernel(
|
|
||||||
(T*)vals.data_ptr(), size, groups, bits, at::cuda::getCurrentCUDAStream());
|
|
||||||
}
|
|
||||||
return vals;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
at::Tensor ds_sr_quantize(at::Tensor& vals, int groups, int bits)
|
|
||||||
{
|
|
||||||
auto t_size = vals.sizes();
|
|
||||||
int size = 1;
|
|
||||||
for (auto dim : t_size) size *= dim;
|
|
||||||
|
|
||||||
if (((size / groups) / 4 / 1024) <= 256) {
|
|
||||||
launch_sr_fake_quantize_kernel(
|
|
||||||
(T*)vals.data_ptr(), size, groups, bits, at::cuda::getCurrentCUDAStream());
|
|
||||||
}
|
|
||||||
return vals;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
at::Tensor ds_quantize_asym(at::Tensor& vals, int groups, int bits)
|
|
||||||
{
|
|
||||||
auto t_size = vals.sizes();
|
|
||||||
int size = 1;
|
|
||||||
for (auto dim : t_size) size *= dim;
|
|
||||||
|
|
||||||
if ((((size / groups) - 1) / 4096 + 1) <= 256) {
|
|
||||||
launch_fake_quantize_kernel_asym(
|
|
||||||
(T*)vals.data_ptr(), size, groups, bits, at::cuda::getCurrentCUDAStream());
|
|
||||||
}
|
|
||||||
return vals;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
at::Tensor ds_sr_quantize_asym(at::Tensor& vals, int groups, int bits)
|
|
||||||
{
|
|
||||||
auto t_size = vals.sizes();
|
|
||||||
int size = 1;
|
|
||||||
for (auto dim : t_size) size *= dim;
|
|
||||||
|
|
||||||
if (((size / groups) / 4 / 1024) <= 256) {
|
|
||||||
launch_sr_fake_quantize_kernel_asym(
|
|
||||||
(T*)vals.data_ptr(), size, groups, bits, at::cuda::getCurrentCUDAStream());
|
|
||||||
}
|
|
||||||
return vals;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<at::Tensor> quantize_kernel(at::Tensor& input_vals,
|
|
||||||
int groups,
|
|
||||||
int numBits,
|
|
||||||
quantize::Type quantType)
|
|
||||||
{
|
|
||||||
auto dtype = at::kFloat;
|
|
||||||
auto params_options = at::TensorOptions()
|
|
||||||
.dtype(dtype)
|
|
||||||
.layout(at::kStrided)
|
|
||||||
.device(at::kCUDA)
|
|
||||||
.requires_grad(false);
|
|
||||||
const int param_elems = (quantize::requires_offset(quantType)) ? 2 : 1;
|
|
||||||
auto params = torch::empty({groups, param_elems}, params_options);
|
|
||||||
|
|
||||||
auto output_options = at::TensorOptions()
|
|
||||||
.dtype(at::kChar)
|
|
||||||
.layout(at::kStrided)
|
|
||||||
.device(at::kCUDA)
|
|
||||||
.requires_grad(false);
|
|
||||||
|
|
||||||
auto output_sizes = input_vals.sizes().vec();
|
|
||||||
output_sizes[output_sizes.size() - 1] /= numBits == 8 ? 1 : 2;
|
|
||||||
auto output = torch::empty(output_sizes, output_options);
|
|
||||||
|
|
||||||
const int elems_per_group = at::numel(input_vals) / groups;
|
|
||||||
|
|
||||||
launch_quant((int8_t*)output.data_ptr(),
|
|
||||||
(float*)params.data_ptr(),
|
|
||||||
(__half*)input_vals.data_ptr(),
|
|
||||||
groups,
|
|
||||||
elems_per_group,
|
|
||||||
numBits,
|
|
||||||
quantType,
|
|
||||||
at::cuda::getCurrentCUDAStream());
|
|
||||||
|
|
||||||
return {output, params};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
at::Tensor dequantize(at::Tensor& quantized_data,
|
|
||||||
at::Tensor& params,
|
|
||||||
int groups,
|
|
||||||
int num_bits,
|
|
||||||
quantize::Type quant_type)
|
|
||||||
{
|
|
||||||
auto dtype = (std::is_same<T, float>::value) ? torch::kFloat32 : torch::kFloat16;
|
|
||||||
auto output_options = at::TensorOptions()
|
|
||||||
.dtype(dtype)
|
|
||||||
.layout(at::kStrided)
|
|
||||||
.device(at::kCUDA)
|
|
||||||
.requires_grad(false);
|
|
||||||
|
|
||||||
auto output_sizes = quantized_data.sizes().vec();
|
|
||||||
output_sizes[output_sizes.size() - 1] *= num_bits == 8 ? 1 : 2;
|
|
||||||
auto output = torch::empty(output_sizes, output_options);
|
|
||||||
|
|
||||||
const int total_elems = at::numel(output);
|
|
||||||
const int elems_per_group = total_elems / groups;
|
|
||||||
|
|
||||||
launch_dequantize_kernel((T*)output.data_ptr(),
|
|
||||||
(const int8_t*)quantized_data.data_ptr(),
|
|
||||||
(const float*)params.data_ptr(),
|
|
||||||
quant_type,
|
|
||||||
num_bits,
|
|
||||||
elems_per_group,
|
|
||||||
total_elems,
|
|
||||||
at::cuda::getCurrentCUDAStream());
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
at::Tensor dequantize_int4_to_half_experimental(at::Tensor& data_in,
|
|
||||||
at::Tensor& scale_buffer,
|
|
||||||
at::Tensor& min_val_buffer,
|
|
||||||
int num_group,
|
|
||||||
int group_size)
|
|
||||||
{
|
|
||||||
auto output_options = at::TensorOptions().dtype(at::kHalf).device(at::kCUDA);
|
|
||||||
auto output = torch::empty({num_group, group_size}, output_options);
|
|
||||||
|
|
||||||
launch_dequantize_int4_to_half_experimental((uint8_t*)data_in.data_ptr(),
|
|
||||||
(half*)output.data_ptr(),
|
|
||||||
(half*)scale_buffer.data_ptr(),
|
|
||||||
(half*)min_val_buffer.data_ptr(),
|
|
||||||
num_group,
|
|
||||||
group_size,
|
|
||||||
at::cuda::getCurrentCUDAStream());
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
at::Tensor dequantize_int8_to_half_experimental(at::Tensor& data_in,
|
|
||||||
at::Tensor& scale_buffer,
|
|
||||||
at::Tensor& min_val_buffer,
|
|
||||||
int num_group,
|
|
||||||
int group_size)
|
|
||||||
{
|
|
||||||
auto output_options = at::TensorOptions().dtype(at::kHalf).device(at::kCUDA);
|
|
||||||
auto output = torch::empty({num_group, group_size}, output_options);
|
|
||||||
|
|
||||||
launch_dequantize_int8_to_half_experimental((uint8_t*)data_in.data_ptr(),
|
|
||||||
(half*)output.data_ptr(),
|
|
||||||
(half*)scale_buffer.data_ptr(),
|
|
||||||
(half*)min_val_buffer.data_ptr(),
|
|
||||||
num_group,
|
|
||||||
group_size,
|
|
||||||
at::cuda::getCurrentCUDAStream());
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<at::Tensor> ds_swizzle_quant(at::Tensor& input_vals,
|
|
||||||
int groups,
|
|
||||||
int num_bits,
|
|
||||||
quantize::Type quant_type,
|
|
||||||
int pipeline_size,
|
|
||||||
int nodes,
|
|
||||||
int devices_per_node)
|
|
||||||
{
|
|
||||||
auto scales_options = at::TensorOptions()
|
|
||||||
.dtype(at::kFloat)
|
|
||||||
.layout(at::kStrided)
|
|
||||||
.device(at::kCUDA)
|
|
||||||
.requires_grad(false);
|
|
||||||
const int scales_elems = (quantize::requires_offset(quant_type)) ? 2 : 1;
|
|
||||||
auto scales = torch::empty({groups, scales_elems}, scales_options);
|
|
||||||
|
|
||||||
auto output_options = at::TensorOptions()
|
|
||||||
.dtype(at::kChar)
|
|
||||||
.layout(at::kStrided)
|
|
||||||
.device(at::kCUDA)
|
|
||||||
.requires_grad(false);
|
|
||||||
|
|
||||||
const int quantization_scalar = 8 / num_bits;
|
|
||||||
const int compressed_vals = at::numel(input_vals) / quantization_scalar;
|
|
||||||
|
|
||||||
auto output = torch::empty({compressed_vals}, output_options);
|
|
||||||
const int elems_per_group = at::numel(input_vals) / groups;
|
|
||||||
|
|
||||||
launch_swizzled_quant((int8_t*)output.data_ptr(),
|
|
||||||
(float*)scales.data_ptr(),
|
|
||||||
(__half*)input_vals.data_ptr(),
|
|
||||||
num_bits,
|
|
||||||
quant_type,
|
|
||||||
groups,
|
|
||||||
elems_per_group,
|
|
||||||
pipeline_size,
|
|
||||||
nodes,
|
|
||||||
devices_per_node,
|
|
||||||
at::cuda::getCurrentCUDAStream());
|
|
||||||
|
|
||||||
return {output, scales};
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<at::Tensor> quantized_reduction(at::Tensor& input_vals,
|
|
||||||
at::Tensor& input_scales,
|
|
||||||
int in_groups,
|
|
||||||
int out_groups,
|
|
||||||
int num_bits,
|
|
||||||
quantize::Type quant_type,
|
|
||||||
int devices_per_node)
|
|
||||||
{
|
|
||||||
auto scales_options = at::TensorOptions()
|
|
||||||
.dtype(at::kFloat)
|
|
||||||
.layout(at::kStrided)
|
|
||||||
.device(at::kCUDA)
|
|
||||||
.requires_grad(false);
|
|
||||||
const int scales_elems = (quantize::requires_offset(quant_type)) ? 2 : 1;
|
|
||||||
auto scales = torch::empty({out_groups, scales_elems}, scales_options);
|
|
||||||
|
|
||||||
auto output_options = at::TensorOptions()
|
|
||||||
.dtype(at::kChar)
|
|
||||||
.layout(at::kStrided)
|
|
||||||
.device(at::kCUDA)
|
|
||||||
.requires_grad(false);
|
|
||||||
|
|
||||||
std::vector<int64_t> sz_vector(input_vals.sizes().begin(), input_vals.sizes().end());
|
|
||||||
sz_vector[sz_vector.size() - 1] = sz_vector.back() / devices_per_node; // num of GPU per nodes
|
|
||||||
at::IntArrayRef sz(sz_vector);
|
|
||||||
auto output = torch::empty(sz, output_options);
|
|
||||||
|
|
||||||
const int elems_per_in_tensor = at::numel(input_vals) / devices_per_node;
|
|
||||||
const int elems_per_in_group = elems_per_in_tensor / (in_groups / devices_per_node);
|
|
||||||
const int elems_per_out_group = elems_per_in_tensor / out_groups;
|
|
||||||
|
|
||||||
launch_dequant_reduce((int8_t*)output.data_ptr(),
|
|
||||||
(float*)scales.data_ptr(),
|
|
||||||
(const int8_t*)input_vals.data_ptr(),
|
|
||||||
(const float*)input_scales.data_ptr(),
|
|
||||||
devices_per_node,
|
|
||||||
num_bits,
|
|
||||||
quant_type,
|
|
||||||
out_groups,
|
|
||||||
elems_per_out_group,
|
|
||||||
elems_per_in_tensor,
|
|
||||||
in_groups / devices_per_node,
|
|
||||||
elems_per_in_group,
|
|
||||||
at::cuda::getCurrentCUDAStream());
|
|
||||||
return {output, scales};
|
|
||||||
}
|
|
||||||
|
|
||||||
PYBIND11_MODULE(TORCH_EXTENSION_NAME, m)
|
|
||||||
{
|
|
||||||
m.def("ds_quantize_fp32", &ds_quantize<float>, "DeepSpeed Quantize with fp32 (CUDA)");
|
|
||||||
m.def("ds_quantize_fp16", &ds_quantize<__half>, "DeepSpeed Quantize with fp16 (CUDA)");
|
|
||||||
m.def("ds_sr_quantize_fp32", &ds_sr_quantize<float>, "DeepSpeed Quantize with fp32 (CUDA)");
|
|
||||||
m.def("ds_sr_quantize_fp16", &ds_sr_quantize<__half>, "DeepSpeed Quantize with fp16 (CUDA)");
|
|
||||||
m.def("ds_quantize_asym_fp32", &ds_quantize_asym<float>, "DeepSpeed Quantize with fp32 (CUDA)");
|
|
||||||
m.def(
|
|
||||||
"ds_quantize_asym_fp16", &ds_quantize_asym<__half>, "DeepSpeed Quantize with fp16 (CUDA)");
|
|
||||||
m.def("ds_sr_quantize_asym_fp32",
|
|
||||||
&ds_sr_quantize_asym<float>,
|
|
||||||
"DeepSpeed Quantize with fp32 (CUDA)");
|
|
||||||
m.def("ds_sr_quantize_asym_fp16",
|
|
||||||
&ds_sr_quantize_asym<__half>,
|
|
||||||
"DeepSpeed Quantize with fp16 (CUDA)");
|
|
||||||
pybind11::enum_<quantize::Type>(m, "QuantizationType")
|
|
||||||
.value("Symmetric", quantize::Type::Symmetric)
|
|
||||||
.value("Asymmetric", quantize::Type::Asymmetric)
|
|
||||||
.export_values();
|
|
||||||
m.def("quantize", &quantize_kernel);
|
|
||||||
m.def("dequantize", &dequantize<__half>);
|
|
||||||
m.def("dequantize_fp32", &dequantize<float>);
|
|
||||||
m.def("dequantize_int4_to_half_experimental",
|
|
||||||
&dequantize_int4_to_half_experimental,
|
|
||||||
"Dequantize int4 to half (experimental)");
|
|
||||||
m.def("dequantize_int8_to_half_experimental",
|
|
||||||
&dequantize_int8_to_half_experimental,
|
|
||||||
"Dequantize int8 to half (experimental)");
|
|
||||||
m.def("swizzle_quant", &ds_swizzle_quant);
|
|
||||||
m.def("quantized_reduction", &quantized_reduction);
|
|
||||||
}
|
|
||||||
@@ -1,161 +0,0 @@
|
|||||||
# Copyright (c) Microsoft Corporation.
|
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
# DeepSpeed Team
|
|
||||||
|
|
||||||
import os
|
|
||||||
import torch
|
|
||||||
import deepspeed
|
|
||||||
import subprocess
|
|
||||||
import argparse
|
|
||||||
import psutil
|
|
||||||
from .ops.op_builder.all_ops import ALL_OPS
|
|
||||||
from .git_version_info import installed_ops, torch_info
|
|
||||||
from deepspeed.accelerator import get_accelerator
|
|
||||||
|
|
||||||
GREEN = '\033[92m'
|
|
||||||
RED = '\033[91m'
|
|
||||||
YELLOW = '\033[93m'
|
|
||||||
END = '\033[0m'
|
|
||||||
SUCCESS = f"{GREEN} [SUCCESS] {END}"
|
|
||||||
OKAY = f"{GREEN}[OKAY]{END}"
|
|
||||||
WARNING = f"{YELLOW}[WARNING]{END}"
|
|
||||||
FAIL = f'{RED}[FAIL]{END}'
|
|
||||||
INFO = '[INFO]'
|
|
||||||
|
|
||||||
color_len = len(GREEN) + len(END)
|
|
||||||
okay = f"{GREEN}[OKAY]{END}"
|
|
||||||
warning = f"{YELLOW}[WARNING]{END}"
|
|
||||||
|
|
||||||
|
|
||||||
def op_report(verbose=True):
|
|
||||||
max_dots = 23
|
|
||||||
max_dots2 = 11
|
|
||||||
h = ["op name", "installed", "compatible"]
|
|
||||||
print("-" * (max_dots + max_dots2 + len(h[0]) + len(h[1])))
|
|
||||||
print("DeepSpeed C++/CUDA extension op report")
|
|
||||||
print("-" * (max_dots + max_dots2 + len(h[0]) + len(h[1])))
|
|
||||||
|
|
||||||
print("NOTE: Ops not installed will be just-in-time (JIT) compiled at\n"
|
|
||||||
" runtime if needed. Op compatibility means that your system\n"
|
|
||||||
" meet the required dependencies to JIT install the op.")
|
|
||||||
|
|
||||||
print("-" * (max_dots + max_dots2 + len(h[0]) + len(h[1])))
|
|
||||||
print("JIT compiled ops requires ninja")
|
|
||||||
ninja_status = OKAY if ninja_installed() else FAIL
|
|
||||||
print('ninja', "." * (max_dots - 5), ninja_status)
|
|
||||||
print("-" * (max_dots + max_dots2 + len(h[0]) + len(h[1])))
|
|
||||||
print(h[0], "." * (max_dots - len(h[0])), h[1], "." * (max_dots2 - len(h[1])), h[2])
|
|
||||||
print("-" * (max_dots + max_dots2 + len(h[0]) + len(h[1])))
|
|
||||||
installed = f"{GREEN}[YES]{END}"
|
|
||||||
no = f"{YELLOW}[NO]{END}"
|
|
||||||
for op_name, builder in ALL_OPS.items():
|
|
||||||
dots = "." * (max_dots - len(op_name))
|
|
||||||
is_compatible = OKAY if builder.is_compatible(verbose) else no
|
|
||||||
is_installed = installed if installed_ops.get(op_name, False) else no
|
|
||||||
dots2 = '.' * ((len(h[1]) + (max_dots2 - len(h[1]))) - (len(is_installed) - color_len))
|
|
||||||
print(op_name, dots, is_installed, dots2, is_compatible)
|
|
||||||
print("-" * (max_dots + max_dots2 + len(h[0]) + len(h[1])))
|
|
||||||
|
|
||||||
|
|
||||||
def ninja_installed():
|
|
||||||
try:
|
|
||||||
import ninja # noqa: F401 # type: ignore
|
|
||||||
except ImportError:
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
def nvcc_version():
|
|
||||||
import torch.utils.cpp_extension
|
|
||||||
cuda_home = torch.utils.cpp_extension.CUDA_HOME
|
|
||||||
if cuda_home is None:
|
|
||||||
return f"{RED} [FAIL] cannot find CUDA_HOME via torch.utils.cpp_extension.CUDA_HOME={torch.utils.cpp_extension.CUDA_HOME} {END}"
|
|
||||||
try:
|
|
||||||
output = subprocess.check_output([cuda_home + "/bin/nvcc", "-V"], universal_newlines=True)
|
|
||||||
except FileNotFoundError:
|
|
||||||
return f"{RED} [FAIL] nvcc missing {END}"
|
|
||||||
output_split = output.split()
|
|
||||||
release_idx = output_split.index("release")
|
|
||||||
release = output_split[release_idx + 1].replace(',', '').split(".")
|
|
||||||
return ".".join(release)
|
|
||||||
|
|
||||||
|
|
||||||
def get_shm_size():
|
|
||||||
try:
|
|
||||||
temp_dir = os.getenv('TEMP') or os.getenv('TMP') or os.path.join(os.path.expanduser('~'), 'tmp')
|
|
||||||
shm_stats = psutil.disk_usage(temp_dir)
|
|
||||||
shm_size = shm_stats.total
|
|
||||||
shm_hbytes = human_readable_size(shm_size)
|
|
||||||
warn = []
|
|
||||||
if shm_size < 512 * 1024**2:
|
|
||||||
warn.append(
|
|
||||||
f" {YELLOW} [WARNING] Shared memory size might be too small, consider increasing it. {END}"
|
|
||||||
)
|
|
||||||
# Add additional warnings specific to your use case if needed.
|
|
||||||
return shm_hbytes, warn
|
|
||||||
except Exception as e:
|
|
||||||
return "UNKNOWN", [f"Error getting shared memory size: {e}"]
|
|
||||||
|
|
||||||
|
|
||||||
def human_readable_size(size):
|
|
||||||
units = ['B', 'KB', 'MB', 'GB', 'TB']
|
|
||||||
i = 0
|
|
||||||
while size >= 1024 and i < len(units) - 1:
|
|
||||||
size /= 1024
|
|
||||||
i += 1
|
|
||||||
return f'{size:.2f} {units[i]}'
|
|
||||||
|
|
||||||
|
|
||||||
def debug_report():
|
|
||||||
max_dots = 33
|
|
||||||
|
|
||||||
report = [("torch install path", torch.__path__), ("torch version", torch.__version__),
|
|
||||||
("deepspeed install path", deepspeed.__path__),
|
|
||||||
("deepspeed info", f"{deepspeed.__version__}, {deepspeed.__git_hash__}, {deepspeed.__git_branch__}")]
|
|
||||||
if get_accelerator().device_name() == 'cuda':
|
|
||||||
hip_version = getattr(torch.version, "hip", None)
|
|
||||||
report.extend([("torch cuda version", torch.version.cuda), ("torch hip version", hip_version),
|
|
||||||
("nvcc version", (None if hip_version else nvcc_version())),
|
|
||||||
("deepspeed wheel compiled w.", f"torch {torch_info['version']}, " +
|
|
||||||
(f"hip {torch_info['hip_version']}" if hip_version else f"cuda {torch_info['cuda_version']}"))
|
|
||||||
])
|
|
||||||
else:
|
|
||||||
report.extend([("deepspeed wheel compiled w.", f"torch {torch_info['version']} ")])
|
|
||||||
|
|
||||||
report.append(("shared memory (/dev/shm) size", get_shm_size()))
|
|
||||||
|
|
||||||
print("DeepSpeed general environment info:")
|
|
||||||
for name, value in report:
|
|
||||||
warns = []
|
|
||||||
if isinstance(value, tuple):
|
|
||||||
value, warns = value
|
|
||||||
print(name, "." * (max_dots - len(name)), value)
|
|
||||||
if warns:
|
|
||||||
for warn in warns:
|
|
||||||
print(warn)
|
|
||||||
|
|
||||||
|
|
||||||
def parse_arguments():
|
|
||||||
parser = argparse.ArgumentParser()
|
|
||||||
parser.add_argument('--hide_operator_status',
|
|
||||||
action='store_true',
|
|
||||||
help='Suppress display of installation and compatibility statuses of DeepSpeed operators. ')
|
|
||||||
parser.add_argument('--hide_errors_and_warnings', action='store_true', help='Suppress warning and error messages.')
|
|
||||||
args = parser.parse_args()
|
|
||||||
return args
|
|
||||||
|
|
||||||
|
|
||||||
def main(hide_operator_status=False, hide_errors_and_warnings=False):
|
|
||||||
if not hide_operator_status:
|
|
||||||
op_report(verbose=not hide_errors_and_warnings)
|
|
||||||
debug_report()
|
|
||||||
|
|
||||||
|
|
||||||
def cli_main():
|
|
||||||
args = parse_arguments()
|
|
||||||
main(hide_operator_status=args.hide_operator_status, hide_errors_and_warnings=args.hide_errors_and_warnings)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
These are the modified files you would need for a MANUAL build of DeepSpeed 11.1 or 11.2.
|
|
||||||
|
|
||||||
They were created by a mix of instructions from erew123 and S95Sedan.
|
|
||||||
|
|
||||||
|
|
||||||
- You still have to download the DeepSpeed v11.1 or v11.2 installation files from Microsoft to use these files.
|
|
||||||
|
|
||||||
https://github.com/microsoft/DeepSpeed/releases/tag/v0.11.2
|
|
||||||
|
|
||||||
|
|
||||||
- These files were provided by S95Sedan here:
|
|
||||||
|
|
||||||
https://github.com/S95Sedan/Deepspeed-Windows
|
|
||||||
|
|
||||||
|
|
||||||
- They are related to the manual build of DeepSpeed for AllTalk, which is linked here:
|
|
||||||
|
|
||||||
https://github.com/erew123/alltalk_tts/tree/main?tab=readme-ov-file#-option-2---a-bit-more-complicated
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
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 portaudio19-dev \
|
||||||
|
python3 python3-pip gcc wget \
|
||||||
|
ocl-icd-opencl-dev opencl-headers clinfo \
|
||||||
|
libclblast-dev libopenblas-dev libaio-dev \
|
||||||
|
&& 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
|
||||||
|
RUN pip install --no-cache-dir --no-deps -r system/requirements/requirements_docker.txt && \
|
||||||
|
pip install --no-cache-dir deepspeed
|
||||||
|
|
||||||
|
EXPOSE 7851 7852
|
||||||
|
RUN chmod +x launch.sh
|
||||||
|
ENTRYPOINT ["sh", "-c", "./launch.sh"]
|
||||||
@@ -0,0 +1,659 @@
|
|||||||
|
@echo off
|
||||||
|
cd /D "%~dp0"
|
||||||
|
setlocal enabledelayedexpansion
|
||||||
|
@set "PATH=%PATH%;%SystemRoot%\system32"
|
||||||
|
|
||||||
|
:: Generate the ESC character
|
||||||
|
for /F %%a in ('echo prompt $E ^| cmd') do set "ESC=%%a"
|
||||||
|
|
||||||
|
:: Standard Colors
|
||||||
|
set "BLACK=%ESC%[30m"
|
||||||
|
set "RED=%ESC%[31m"
|
||||||
|
set "GREEN=%ESC%[32m"
|
||||||
|
set "YELLOW=%ESC%[33m"
|
||||||
|
set "BLUE=%ESC%[34m"
|
||||||
|
set "MAGENTA=%ESC%[35m"
|
||||||
|
set "CYAN=%ESC%[36m"
|
||||||
|
set "WHITE=%ESC%[37m"
|
||||||
|
set "L_BLACK=%ESC%[90m"
|
||||||
|
set "L_RED=%ESC%[91m"
|
||||||
|
set "L_GREEN=%ESC%[92m"
|
||||||
|
set "L_YELLOW=%ESC%[93m"
|
||||||
|
set "L_BLUE=%ESC%[94m"
|
||||||
|
set "L_MAGENTA=%ESC%[95m"
|
||||||
|
set "L_CYAN=%ESC%[96m"
|
||||||
|
set "L_WHITE=%ESC%[97m"
|
||||||
|
set "RESET=%ESC%[0m"
|
||||||
|
|
||||||
|
echo "%CD%"| findstr /C:" " >nul && echo. && echo %L_BLUE%ALLTALK WINDOWS SETUP UTILITY%RESET% && echo. && echo. && echo You are trying to install AllTalk in a folder that has a space in the folder path e.g. && echo. && echo C:\%L_RED%program files%RESET%\alltalk_tts && echo. && echo This causes errors with Conda and Python scripts. Please follow this link for reference: && echo. && echo %L_CYAN%https://docs.anaconda.com/free/working-with-conda/reference/faq/#installing-anaconda%RESET% && echo. && echo Please use a folder path that has no spaces in it e.g. && echo. && echo C:\myfiles\alltalk_tts\ && echo. && echo. && pause && goto :end
|
||||||
|
|
||||||
|
@rem Check for special characters in installation path
|
||||||
|
set "SPCHARMESSAGE="WARNING: Special characters were detected in the installation path!" " This can cause the installation to fail!""
|
||||||
|
echo "%CD%"| findstr /R /C:"[!#\$%&()\*+,;<=>?@\[\]\^`{|}~]" >nul && (
|
||||||
|
call :PrintBigMessage %SPCHARMESSAGE%
|
||||||
|
)
|
||||||
|
set SPCHARMESSAGE=
|
||||||
|
|
||||||
|
@rem Check if curl is available
|
||||||
|
curl --version >nul 2>&1
|
||||||
|
if "%ERRORLEVEL%" NEQ "0" (
|
||||||
|
echo curl is not available on this system. Please install curl then re-run the script https://curl.se/
|
||||||
|
echo or perform a manual installation of a Conda Python environment.
|
||||||
|
goto end
|
||||||
|
)
|
||||||
|
|
||||||
|
:MainMenu
|
||||||
|
cls
|
||||||
|
echo.
|
||||||
|
echo %L_BLUE%ALLTALK WINDOWS SETUP UTILITY%RESET%
|
||||||
|
echo.
|
||||||
|
echo INSTALLATION TYPE
|
||||||
|
echo 1) I am using AllTalk as part of %L_GREEN%Text-generation-webui%RESET%
|
||||||
|
echo 2) I am using AllTalk as a %L_GREEN%Standalone Application%RESET%
|
||||||
|
echo.
|
||||||
|
echo 9) %L_RED%Exit/Quit%RESET%
|
||||||
|
echo.
|
||||||
|
set /p UserOption=" Enter your choice: "
|
||||||
|
|
||||||
|
if "%UserOption%"=="1" goto WebUIMenu
|
||||||
|
if "%UserOption%"=="2" goto StandaloneMenu
|
||||||
|
if "%UserOption%"=="9" goto End
|
||||||
|
goto MainMenu
|
||||||
|
|
||||||
|
:WebUIMenu
|
||||||
|
cls
|
||||||
|
echo.
|
||||||
|
echo %L_BLUE%TEXT-GENERATION-WEBUI SETUP%RESET%
|
||||||
|
echo.
|
||||||
|
echo Please ensure you have started your Text-generation-webui Python
|
||||||
|
echo environment. If you have NOT done this, please run %L_GREEN%cmd_windows.bat%RESET%
|
||||||
|
echo in the %L_GREEN%text-generation-webui%RESET% folder and then re-run this script.
|
||||||
|
echo.
|
||||||
|
echo BASE REQUIREMENTS
|
||||||
|
echo 1) Apply/Re-Apply the requirements for %L_GREEN%Text-generation-webui%RESET%.
|
||||||
|
echo.
|
||||||
|
echo OPTIONAL
|
||||||
|
echo 2) Git Pull the latest AllTalk updates from Github
|
||||||
|
echo.
|
||||||
|
echo DEEPSPEED FOR %L_YELLOW=%PyTorch 2.1.x%RESET%
|
||||||
|
echo 4) Install DeepSpeed v11.2 for CUDA %L_GREEN%11.8%RESET% and Python-3.11.x and %L_YELLOW%PyTorch 2.1.x%RESET%.
|
||||||
|
echo 5) Install DeepSpeed v11.2 for CUDA %L_GREEN%12.1%RESET% and Python-3.11.x and %L_YELLOW%PyTorch 2.1.x%RESET%.
|
||||||
|
echo.
|
||||||
|
echo DEEPSPEED FOR %L_YELLOW=%PyTorch 2.2.x%RESET% (March 2024 builds of Text-gen-webui and later)
|
||||||
|
echo 6) Install DeepSpeed v14.0 for CUDA %L_GREEN%12.1%RESET% and Python-3.11.x and %L_YELLOW%PyTorch 2.2.x%RESET%.
|
||||||
|
echo 7) Install DeepSpeed v14.0 for CUDA %L_GREEN%11.8%RESET% and Python-3.11.x and %L_YELLOW%PyTorch 2.2.x%RESET%.
|
||||||
|
echo.
|
||||||
|
echo U) Uninstall DeepSpeed.
|
||||||
|
echo.
|
||||||
|
echo. OTHER
|
||||||
|
echo 8) Generate a diagnostics file.
|
||||||
|
echo.
|
||||||
|
echo 9) %L_RED%Exit/Quit%RESET%
|
||||||
|
echo.
|
||||||
|
set /p WebUIOption="Enter your choice: "
|
||||||
|
if "%WebUIOption%"=="1" goto InstallNvidiaTextGen
|
||||||
|
if "%WebUIOption%"=="2" goto TGGitpull
|
||||||
|
if "%WebUIOption%"=="4" goto InstallDeepSpeed118TextGen
|
||||||
|
if "%WebUIOption%"=="5" goto InstallDeepSpeed121TextGen
|
||||||
|
if "%WebUIOption%"=="6" goto InstallDeepSpeed121TextGenPytorch221
|
||||||
|
if "%WebUIOption%"=="7" goto InstallDeepSpeed118TextGenPytorch221
|
||||||
|
if "%WebUIOption%"=="U" goto UnInstallDeepSpeed
|
||||||
|
if "%WebUIOption%"=="u" goto UnInstallDeepSpeed
|
||||||
|
if "%WebUIOption%"=="8" goto GenerateDiagsTextGen
|
||||||
|
if "%WebUIOption%"=="9" goto End
|
||||||
|
goto WebUIMenu
|
||||||
|
|
||||||
|
:StandaloneMenu
|
||||||
|
cls
|
||||||
|
echo.
|
||||||
|
echo %L_BLUE%ALLTALK STANDALONE APPLICATION SETUP%RESET%
|
||||||
|
echo.
|
||||||
|
echo BASE REQUIREMENTS
|
||||||
|
echo 1) Install AllTalk as a Standalone Application
|
||||||
|
echo.
|
||||||
|
echo OPTIONAL
|
||||||
|
echo 2) Git Pull the latest AllTalk updates from Github
|
||||||
|
echo 3) Re-Apply/Update the requirements file
|
||||||
|
echo 4) Delete AllTalk's custom Python environment
|
||||||
|
echo 5) Purge the PIP cache
|
||||||
|
echo.
|
||||||
|
echo. OTHER
|
||||||
|
echo 8) Generate a diagnostics file
|
||||||
|
echo.
|
||||||
|
echo 9) %L_RED%Exit/Quit%RESET%
|
||||||
|
echo.
|
||||||
|
set /p StandaloneOption="Enter your choice: "
|
||||||
|
if "%StandaloneOption%"=="1" goto InstallCustomStandalone
|
||||||
|
if "%StandaloneOption%"=="2" goto STGitpull
|
||||||
|
if "%StandaloneOption%"=="3" goto STReapplyrequirements
|
||||||
|
if "%StandaloneOption%"=="4" goto STDeleteCustomStandalone
|
||||||
|
if "%StandaloneOption%"=="5" goto STPurgepipcache
|
||||||
|
if "%StandaloneOption%"=="8" goto GenerateDiagsStandalone
|
||||||
|
if "%StandaloneOption%"=="9" goto EndStandalone
|
||||||
|
goto StandaloneMenu
|
||||||
|
|
||||||
|
:InstallNvidiaTextGen
|
||||||
|
pip install -r system\requirements\requirements_textgen.txt
|
||||||
|
if %ERRORLEVEL% neq 0 (
|
||||||
|
echo.
|
||||||
|
echo There was an error installing the requirements.
|
||||||
|
echo Have you started your Text-gen-webui Python environment
|
||||||
|
echo with cmd_{yourOS} before running atsetup.bat?
|
||||||
|
echo Press any key to return to the menu.
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
|
goto WebUIMenu
|
||||||
|
)
|
||||||
|
Echo.
|
||||||
|
echo.
|
||||||
|
Echo Requirements installed successfully.
|
||||||
|
Echo.
|
||||||
|
pause
|
||||||
|
goto WebUIMenu
|
||||||
|
|
||||||
|
:TGGitpull
|
||||||
|
git pull
|
||||||
|
if %ERRORLEVEL% neq 0 (
|
||||||
|
echo.
|
||||||
|
echo There was an error pulling from Github.
|
||||||
|
echo Press any key to return to the menu.
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
|
goto WebUIMenu
|
||||||
|
)
|
||||||
|
Echo.
|
||||||
|
echo AllTalk Updated from Github. Please re-apply
|
||||||
|
echo the latest requirements file. Option 1
|
||||||
|
Echo.
|
||||||
|
pause
|
||||||
|
goto WebUIMenu
|
||||||
|
|
||||||
|
:InstallDeepSpeed118TextGen
|
||||||
|
echo Downloading DeepSpeed...
|
||||||
|
curl -LO https://github.com/erew123/alltalk_tts/releases/download/deepspeed/deepspeed-0.11.2+cuda118-cp311-cp311-win_amd64.whl
|
||||||
|
if %ERRORLEVEL% neq 0 (
|
||||||
|
echo.
|
||||||
|
echo Failed to download DeepSpeed wheel file.
|
||||||
|
echo Please check your internet connection or try again later.
|
||||||
|
echo Press any key to return to the menu.
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
|
goto WebUIMenu
|
||||||
|
)
|
||||||
|
echo DeepSpeed wheel file downloaded successfully.
|
||||||
|
echo Installing DeepSpeed...
|
||||||
|
pip install deepspeed-0.11.2+cuda118-cp311-cp311-win_amd64.whl
|
||||||
|
if %ERRORLEVEL% neq 0 (
|
||||||
|
echo.
|
||||||
|
echo Failed to install DeepSpeed.
|
||||||
|
echo Please check if the wheel file is compatible with your system.
|
||||||
|
echo Press any key to return to the menu.
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
|
goto WebUIMenu
|
||||||
|
)
|
||||||
|
Echo.
|
||||||
|
echo.
|
||||||
|
Echo DeepSpeed installed successfully.
|
||||||
|
Echo.
|
||||||
|
del deepspeed-0.11.2+cuda118-cp311-cp311-win_amd64.whl
|
||||||
|
pause
|
||||||
|
goto WebUIMenu
|
||||||
|
|
||||||
|
:InstallDeepSpeed121TextGen
|
||||||
|
echo Downloading DeepSpeed...
|
||||||
|
curl -LO https://github.com/erew123/alltalk_tts/releases/download/deepspeed/deepspeed-0.11.2+cuda121-cp311-cp311-win_amd64.whl
|
||||||
|
if %ERRORLEVEL% neq 0 (
|
||||||
|
echo.
|
||||||
|
echo Failed to download DeepSpeed wheel file.
|
||||||
|
echo Please check your internet connection or try again later.
|
||||||
|
echo Press any key to return to the menu.
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
|
goto WebUIMenu
|
||||||
|
)
|
||||||
|
echo DeepSpeed wheel file downloaded successfully.
|
||||||
|
echo Installing DeepSpeed...
|
||||||
|
pip install deepspeed-0.11.2+cuda121-cp311-cp311-win_amd64.whl
|
||||||
|
if %ERRORLEVEL% neq 0 (
|
||||||
|
echo.
|
||||||
|
echo Failed to install DeepSpeed.
|
||||||
|
echo Please check if the wheel file is compatible with your system.
|
||||||
|
echo Press any key to return to the menu.
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
|
goto WebUIMenu
|
||||||
|
)
|
||||||
|
Echo.
|
||||||
|
echo.
|
||||||
|
Echo DeepSpeed installed successfully.
|
||||||
|
Echo.
|
||||||
|
del deepspeed-0.11.2+cuda121-cp311-cp311-win_amd64.whl
|
||||||
|
pause
|
||||||
|
goto WebUIMenu
|
||||||
|
|
||||||
|
:InstallDeepSpeed121TextGenPytorch221
|
||||||
|
echo Downloading DeepSpeed...
|
||||||
|
curl -LO https://github.com/erew123/alltalk_tts/releases/download/DeepSpeed-14.0/deepspeed-0.14.0+ce78a63-cp311-cp311-win_amd64.whl
|
||||||
|
if %ERRORLEVEL% neq 0 (
|
||||||
|
echo.
|
||||||
|
echo Failed to download DeepSpeed wheel file.
|
||||||
|
echo Please check your internet connection or try again later.
|
||||||
|
echo Press any key to return to the menu.
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
|
goto WebUIMenu
|
||||||
|
)
|
||||||
|
echo DeepSpeed wheel file downloaded successfully.
|
||||||
|
echo Installing DeepSpeed...
|
||||||
|
pip install deepspeed-0.14.0+ce78a63-cp311-cp311-win_amd64.whl
|
||||||
|
if %ERRORLEVEL% neq 0 (
|
||||||
|
echo.
|
||||||
|
echo Failed to install DeepSpeed.
|
||||||
|
echo Please check if the wheel file is compatible with your system.
|
||||||
|
echo Press any key to return to the menu.
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
|
goto WebUIMenu
|
||||||
|
)
|
||||||
|
Echo.
|
||||||
|
echo.
|
||||||
|
Echo DeepSpeed installed successfully.
|
||||||
|
Echo.
|
||||||
|
del deepspeed-0.14.0+ce78a63-cp311-cp311-win_amd64.whl
|
||||||
|
pause
|
||||||
|
goto WebUIMenu
|
||||||
|
|
||||||
|
:InstallDeepSpeed118TextGenPytorch221
|
||||||
|
echo Downloading DeepSpeed...
|
||||||
|
curl -LO https://github.com/erew123/alltalk_tts/releases/download/DeepSpeed-14.0/deepspeed-0.14.0+cu118-cp311-cp311-win_amd64.whl
|
||||||
|
if %ERRORLEVEL% neq 0 (
|
||||||
|
echo.
|
||||||
|
echo Failed to download DeepSpeed wheel file.
|
||||||
|
echo Please check your internet connection or try again later.
|
||||||
|
echo Press any key to return to the menu.
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
|
goto WebUIMenu
|
||||||
|
)
|
||||||
|
echo DeepSpeed wheel file downloaded successfully.
|
||||||
|
echo Installing DeepSpeed...
|
||||||
|
pip install deepspeed-0.14.0+cu118-cp311-cp311-win_amd64.whl
|
||||||
|
if %ERRORLEVEL% neq 0 (
|
||||||
|
echo.
|
||||||
|
echo Failed to install DeepSpeed.
|
||||||
|
echo Please check if the wheel file is compatible with your system.
|
||||||
|
echo Press any key to return to the menu.
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
|
goto WebUIMenu
|
||||||
|
)
|
||||||
|
Echo.
|
||||||
|
echo.
|
||||||
|
Echo DeepSpeed installed successfully.
|
||||||
|
Echo.
|
||||||
|
del deepspeed-0.14.0+cu118-cp311-cp311-win_amd64.whl
|
||||||
|
pause
|
||||||
|
goto WebUIMenu
|
||||||
|
|
||||||
|
:UnInstallDeepSpeed
|
||||||
|
pip uninstall deepspeed
|
||||||
|
if %ERRORLEVEL% neq 0 (
|
||||||
|
echo.
|
||||||
|
echo There was an error uninstalling DeepSpeed.
|
||||||
|
echo Press any key to return to the menu.
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
|
goto WebUIMenu
|
||||||
|
)
|
||||||
|
echo.
|
||||||
|
Echo DeepSpeed uninstalled successfully.
|
||||||
|
Echo.
|
||||||
|
pause
|
||||||
|
goto WebUIMenu
|
||||||
|
|
||||||
|
:GenerateDiagsTextGen
|
||||||
|
Python diagnostics.py
|
||||||
|
if %ERRORLEVEL% neq 0 (
|
||||||
|
echo.
|
||||||
|
echo There was an error running diagnostics. Have you correctly started your
|
||||||
|
echo Text-generation-webui Python environment with %L_GREEN%cmd_windows.bat%RESET%?
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
|
goto WebUIMenu
|
||||||
|
)
|
||||||
|
Echo.
|
||||||
|
echo.
|
||||||
|
Echo Diagnostics.log generated. Please scroll up to look over the log.
|
||||||
|
Echo.
|
||||||
|
pause
|
||||||
|
goto WebUIMenu
|
||||||
|
|
||||||
|
:InstallCustomStandalone
|
||||||
|
set PATH=%PATH%;%SystemRoot%\system32
|
||||||
|
|
||||||
|
@rem Check if curl is available
|
||||||
|
curl --version >nul 2>&1
|
||||||
|
if "%ERRORLEVEL%" NEQ "0" (
|
||||||
|
echo curl is not available on this system. Please install curl then re-run the script https://curl.se/
|
||||||
|
echo or perform a manual installation of a Conda Python environment.
|
||||||
|
goto end
|
||||||
|
)
|
||||||
|
echo "%CD%"| findstr /C:" " >nul && echo This script relies on Miniconda which can not be silently installed under a path with spaces. Please correct your folder names and re-try installation. && goto exit
|
||||||
|
|
||||||
|
@rem Check for special characters in installation path
|
||||||
|
set "SPCHARMESSAGE=WARNING: Special characters were detected in the installation path! This can cause the installation to fail!"
|
||||||
|
echo "%CD%"| findstr /R /C:"[!#\$%&()\*+,;<=>?@\[\]\^`{|}~]" >nul && (
|
||||||
|
call :PrintBigMessage %SPCHARMESSAGE%
|
||||||
|
)
|
||||||
|
set SPCHARMESSAGE=
|
||||||
|
|
||||||
|
@rem fix failed install when installing to a separate drive
|
||||||
|
set TMP=%cd%\alltalk_environment
|
||||||
|
set TEMP=%cd%\alltalk_environment
|
||||||
|
|
||||||
|
@rem deactivate existing conda envs as needed to avoid conflicts
|
||||||
|
(call conda deactivate && call conda deactivate && call conda deactivate) 2>nul
|
||||||
|
|
||||||
|
@rem config
|
||||||
|
set INSTALL_DIR=%cd%\alltalk_environment
|
||||||
|
set CONDA_ROOT_PREFIX=%cd%\alltalk_environment\conda
|
||||||
|
set INSTALL_ENV_DIR=%cd%\alltalk_environment\env
|
||||||
|
set MINICONDA_DOWNLOAD_URL=https://repo.anaconda.com/miniconda/Miniconda3-py310_23.3.1-0-Windows-x86_64.exe
|
||||||
|
set conda_exists=F
|
||||||
|
|
||||||
|
@rem figure out whether git and conda need to be installed
|
||||||
|
call "%CONDA_ROOT_PREFIX%\_conda.exe" --version >nul 2>&1
|
||||||
|
if "%ERRORLEVEL%" EQU "0" (
|
||||||
|
set conda_exists=T
|
||||||
|
call "%CONDA_ROOT_PREFIX%\condabin\conda.bat" activate "%INSTALL_ENV_DIR%"
|
||||||
|
goto RunScript
|
||||||
|
)
|
||||||
|
|
||||||
|
@rem download and install conda if not installed
|
||||||
|
echo Downloading Miniconda from %MINICONDA_DOWNLOAD_URL% to %INSTALL_DIR%\miniconda_installer.exe
|
||||||
|
mkdir "%INSTALL_DIR%"
|
||||||
|
call curl -Lk "%MINICONDA_DOWNLOAD_URL%" > "%INSTALL_DIR%\miniconda_installer.exe" || ( echo. && echo Miniconda failed to download. && goto end )
|
||||||
|
echo Installing Miniconda to %CONDA_ROOT_PREFIX%
|
||||||
|
start /wait "" "%INSTALL_DIR%\miniconda_installer.exe" /InstallationType=JustMe /NoShortcuts=1 /AddToPath=0 /RegisterPython=0 /NoRegistry=1 /S /D=%CONDA_ROOT_PREFIX%
|
||||||
|
echo Miniconda version:
|
||||||
|
call "%CONDA_ROOT_PREFIX%\_conda.exe" --version || ( echo. && echo Miniconda not found. && goto end )
|
||||||
|
|
||||||
|
@rem create the installer env
|
||||||
|
echo Packages to install: %PACKAGES_TO_INSTALL%
|
||||||
|
call "%CONDA_ROOT_PREFIX%\_conda.exe" create --no-shortcuts -y -k --prefix "%INSTALL_ENV_DIR%" python=3.11 || ( echo. && echo Conda environment creation failed. && goto end )
|
||||||
|
|
||||||
|
@rem check if conda environment was actually created
|
||||||
|
if not exist "%INSTALL_ENV_DIR%\python.exe" ( echo. && echo Conda environment is empty. && goto end )
|
||||||
|
|
||||||
|
@rem activate installer env
|
||||||
|
call "%CONDA_ROOT_PREFIX%\condabin\conda.bat" activate "%INSTALL_ENV_DIR%" || ( echo. && echo Miniconda hook not found. && goto end )
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo Downloading and installing PyTorch. This step can take a long time
|
||||||
|
echo depending on your internet connection and hard drive speed. Please
|
||||||
|
echo be patient.
|
||||||
|
echo.
|
||||||
|
pip install torch==2.2.2+cu121 torchaudio>=2.2.2+cu121 --upgrade --force-reinstall --extra-index-url https://download.pytorch.org/whl/cu121
|
||||||
|
echo Installing other requirements.
|
||||||
|
echo.
|
||||||
|
pip install -r system\requirements\requirements_standalone.txt
|
||||||
|
curl -LO https://github.com/erew123/alltalk_tts/releases/download/DeepSpeed-14.0/deepspeed-0.14.0+ce78a63-cp311-cp311-win_amd64.whl
|
||||||
|
echo Installing DeepSpeed...
|
||||||
|
pip install deepspeed-0.14.0+ce78a63-cp311-cp311-win_amd64.whl
|
||||||
|
del deepspeed-0.14.0+ce78a63-cp311-cp311-win_amd64.whl
|
||||||
|
|
||||||
|
|
||||||
|
@rem Create start_environment.bat to run AllTalk environment
|
||||||
|
echo @echo off > start_environment.bat
|
||||||
|
echo cd /D "%~dp0" >> start_environment.bat
|
||||||
|
echo set CONDA_ROOT_PREFIX=%cd%\alltalk_environment\conda >> start_environment.bat
|
||||||
|
echo set INSTALL_ENV_DIR=%cd%\alltalk_environment\env >> start_environment.bat
|
||||||
|
echo call "%CONDA_ROOT_PREFIX%\condabin\conda.bat" activate "%INSTALL_ENV_DIR%" >> start_environment.bat
|
||||||
|
@rem Create start_alltalk.bat to run AllTalk
|
||||||
|
echo @echo off > start_alltalk.bat
|
||||||
|
echo cd /D "%~dp0" >> start_alltalk.bat
|
||||||
|
echo set CONDA_ROOT_PREFIX=%cd%\alltalk_environment\conda >> start_alltalk.bat
|
||||||
|
echo set INSTALL_ENV_DIR=%cd%\alltalk_environment\env >> start_alltalk.bat
|
||||||
|
echo call "%CONDA_ROOT_PREFIX%\condabin\conda.bat" activate "%INSTALL_ENV_DIR%" >> start_alltalk.bat
|
||||||
|
echo call python script.py >> start_alltalk.bat
|
||||||
|
@rem Create start_finetune.bat to run AllTalk
|
||||||
|
echo @echo off > start_finetune.bat
|
||||||
|
echo cd /D "%~dp0" >> start_finetune.bat
|
||||||
|
echo set CONDA_ROOT_PREFIX=%cd%\alltalk_environment\conda >> start_finetune.bat
|
||||||
|
echo set INSTALL_ENV_DIR=%cd%\alltalk_environment\env >> start_finetune.bat
|
||||||
|
echo call "%CONDA_ROOT_PREFIX%\condabin\conda.bat" activate "%INSTALL_ENV_DIR%" >> start_finetune.bat
|
||||||
|
echo call python finetune.py >> start_finetune.bat
|
||||||
|
Echo.
|
||||||
|
Echo Run %L_YELLOW%start_alltalk.bat%RESET% to start AllTalk.
|
||||||
|
Echo Run %L_YELLOW%start_finetune.bat%RESET% to start Finetuning.
|
||||||
|
Echo Run %L_YELLOW%start_environment.bat%RESET% to start the AllTalk Python environment.
|
||||||
|
Echo.
|
||||||
|
pause
|
||||||
|
goto StandaloneMenu
|
||||||
|
|
||||||
|
:STDeleteCustomStandalone
|
||||||
|
@rem Check if the alltalk_environment directory exists
|
||||||
|
if not exist "%cd%\alltalk_environment\" (
|
||||||
|
echo.
|
||||||
|
echo %L_GREEN%alltalk_environment%RESET% directory does not exist. No need to delete.
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
|
goto StandaloneMenu
|
||||||
|
)
|
||||||
|
@rem Check if a Conda environment is active
|
||||||
|
if not defined CONDA_PREFIX goto NoCondaEnvDeleteCustomStandalone
|
||||||
|
@rem Deactivate Conda environment if it's active
|
||||||
|
Echo Exiting the Conda Environment. Please run %L_GREEN%atsetup.bat%RESET% again and delete the environment.
|
||||||
|
conda deactivate
|
||||||
|
:NoCondaEnvDeleteCustomStandalone
|
||||||
|
echo Deleting "alltalk_environment". Please wait.
|
||||||
|
rd /s /q "alltalk_environment"
|
||||||
|
del start_alltalk.bat
|
||||||
|
del start_environment.bat
|
||||||
|
if %ERRORLEVEL% neq 0 (
|
||||||
|
echo.
|
||||||
|
echo Failed to delete alltalk_environment folder.
|
||||||
|
echo Please make sure it is not in use and try again.
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
|
goto StandaloneMenu
|
||||||
|
)
|
||||||
|
echo.
|
||||||
|
Echo.
|
||||||
|
echo Environment %L_GREEN%alltalk_environment%RESET% deleted. Please set up the environment again.
|
||||||
|
Echo.
|
||||||
|
pause
|
||||||
|
goto StandaloneMenu
|
||||||
|
|
||||||
|
:GenerateDiagsStandalone
|
||||||
|
cd /D "%~dp0"
|
||||||
|
set CONDA_ROOT_PREFIX=%cd%\alltalk_environment\conda
|
||||||
|
set INSTALL_ENV_DIR=%cd%\alltalk_environment\env
|
||||||
|
@rem Check if the Conda environment exists
|
||||||
|
if not exist "%INSTALL_ENV_DIR%\python.exe" (
|
||||||
|
echo.
|
||||||
|
echo The Conda environment at "%INSTALL_ENV_DIR%" does not exist.
|
||||||
|
echo Please install the environment before proceeding.
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
|
goto StandaloneMenu
|
||||||
|
)
|
||||||
|
@rem Attempt to activate the Conda environment
|
||||||
|
call "%CONDA_ROOT_PREFIX%\condabin\conda.bat" activate "%INSTALL_ENV_DIR%"
|
||||||
|
if errorlevel 1 (
|
||||||
|
echo.
|
||||||
|
echo Failed to activate the Conda environment.
|
||||||
|
echo Please check your installation and try again.
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
|
goto StandaloneMenu
|
||||||
|
)
|
||||||
|
@rem Run diagnostics
|
||||||
|
Python diagnostics.py
|
||||||
|
if %ERRORLEVEL% neq 0 (
|
||||||
|
echo.
|
||||||
|
echo There was an error running diagnostics.
|
||||||
|
echo Press any key to return to the menu.
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
|
goto StandaloneMenu
|
||||||
|
)
|
||||||
|
Echo.
|
||||||
|
Echo.
|
||||||
|
Echo Diagnostics.log generated. Please scroll up to look over the log.
|
||||||
|
Echo.
|
||||||
|
pause
|
||||||
|
goto StandaloneMenu
|
||||||
|
|
||||||
|
:STReapplyrequirements
|
||||||
|
cd /D "%~dp0"
|
||||||
|
set CONDA_ROOT_PREFIX=%cd%\alltalk_environment\conda
|
||||||
|
set INSTALL_ENV_DIR=%cd%\alltalk_environment\env
|
||||||
|
@rem Check if the Conda environment exists
|
||||||
|
if not exist "%INSTALL_ENV_DIR%\python.exe" (
|
||||||
|
echo.
|
||||||
|
echo The Conda environment at "%INSTALL_ENV_DIR%" does not exist.
|
||||||
|
echo Please install the environment before proceeding.
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
|
goto StandaloneMenu
|
||||||
|
)
|
||||||
|
@rem Attempt to activate the Conda environment
|
||||||
|
call "%CONDA_ROOT_PREFIX%\condabin\conda.bat" activate "%INSTALL_ENV_DIR%"
|
||||||
|
if errorlevel 1 (
|
||||||
|
echo.
|
||||||
|
echo Failed to activate the Conda environment.
|
||||||
|
echo Please check your installation and try again.
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
|
goto StandaloneMenu
|
||||||
|
)
|
||||||
|
@rem Run Reapply requirements
|
||||||
|
echo.
|
||||||
|
echo Downloading and installing PyTorch. This step can take a long time
|
||||||
|
echo depending on your internet connection and hard drive speed. Please
|
||||||
|
echo be patient.
|
||||||
|
echo.
|
||||||
|
pip install torch==2.2.2+cu121 torchaudio>=2.2.2+cu121 --upgrade --force-reinstall --extra-index-url https://download.pytorch.org/whl/cu121
|
||||||
|
echo Installing other requirements.
|
||||||
|
echo.
|
||||||
|
pip install -r system\requirements\requirements_standalone.txt
|
||||||
|
C:/Windows/system32/curl.exe -LO https://github.com/erew123/alltalk_tts/releases/download/DeepSpeed-14.0/deepspeed-0.14.0+ce78a63-cp311-cp311-win_amd64.whl
|
||||||
|
echo Installing DeepSpeed...
|
||||||
|
pip install deepspeed-0.14.0+ce78a63-cp311-cp311-win_amd64.whl
|
||||||
|
del deepspeed-0.14.0+ce78a63-cp311-cp311-win_amd64.whl
|
||||||
|
if %ERRORLEVEL% neq 0 (
|
||||||
|
echo.
|
||||||
|
echo There was an error.
|
||||||
|
echo Press any key to return to the menu.
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
|
goto StandaloneMenu
|
||||||
|
)
|
||||||
|
Echo.
|
||||||
|
Echo.
|
||||||
|
Echo Requirements have been re-applied/updated.
|
||||||
|
Echo.
|
||||||
|
pause
|
||||||
|
goto StandaloneMenu
|
||||||
|
|
||||||
|
:STPurgepipcache
|
||||||
|
cd /D "%~dp0"
|
||||||
|
set CONDA_ROOT_PREFIX=%cd%\alltalk_environment\conda
|
||||||
|
set INSTALL_ENV_DIR=%cd%\alltalk_environment\env
|
||||||
|
@rem Check if the Conda environment exists
|
||||||
|
if not exist "%INSTALL_ENV_DIR%\python.exe" (
|
||||||
|
echo.
|
||||||
|
echo The Conda environment at "%INSTALL_ENV_DIR%" does not exist.
|
||||||
|
echo Please install the environment before proceeding.
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
|
goto StandaloneMenu
|
||||||
|
)
|
||||||
|
@rem Attempt to activate the Conda environment
|
||||||
|
call "%CONDA_ROOT_PREFIX%\condabin\conda.bat" activate "%INSTALL_ENV_DIR%"
|
||||||
|
if errorlevel 1 (
|
||||||
|
echo.
|
||||||
|
echo Failed to activate the Conda environment.
|
||||||
|
echo Please check your installation and try again.
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
|
goto StandaloneMenu
|
||||||
|
)
|
||||||
|
@rem Clear the PIP cache
|
||||||
|
echo.
|
||||||
|
echo Purging the PIP cache of downloaded files.
|
||||||
|
echo.
|
||||||
|
pip cache purge
|
||||||
|
if %ERRORLEVEL% neq 0 (
|
||||||
|
echo.
|
||||||
|
echo There was an error.
|
||||||
|
echo Press any key to return to the menu.
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
|
goto StandaloneMenu
|
||||||
|
)
|
||||||
|
Echo.
|
||||||
|
Echo The PIP cache has been purged.
|
||||||
|
Echo.
|
||||||
|
pause
|
||||||
|
goto StandaloneMenu
|
||||||
|
|
||||||
|
:STGitpull
|
||||||
|
cd /D "%~dp0"
|
||||||
|
set CONDA_ROOT_PREFIX=%cd%\alltalk_environment\conda
|
||||||
|
set INSTALL_ENV_DIR=%cd%\alltalk_environment\env
|
||||||
|
@rem Check if the Conda environment exists
|
||||||
|
if not exist "%INSTALL_ENV_DIR%\python.exe" (
|
||||||
|
echo.
|
||||||
|
echo The Conda environment at "%INSTALL_ENV_DIR%" does not exist.
|
||||||
|
echo Please install the environment before proceeding.
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
|
goto StandaloneMenu
|
||||||
|
)
|
||||||
|
@rem Attempt to activate the Conda environment
|
||||||
|
call "%CONDA_ROOT_PREFIX%\condabin\conda.bat" activate "%INSTALL_ENV_DIR%"
|
||||||
|
if errorlevel 1 (
|
||||||
|
echo.
|
||||||
|
echo Failed to activate the Conda environment.
|
||||||
|
echo Please check your installation and try again.
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
|
goto StandaloneMenu
|
||||||
|
)
|
||||||
|
@rem Pull from Github
|
||||||
|
echo.
|
||||||
|
echo Pulling the latest updates. Please re-apply
|
||||||
|
echo the latest requirements file. Option 3
|
||||||
|
echo.
|
||||||
|
git pull
|
||||||
|
if %ERRORLEVEL% neq 0 (
|
||||||
|
echo.
|
||||||
|
echo There was an error pulling from Github.
|
||||||
|
echo Press any key to return to the menu.
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
|
goto StandaloneMenu
|
||||||
|
)
|
||||||
|
Echo.
|
||||||
|
echo AllTalk Updated from Github. Please re-apply
|
||||||
|
echo the latest requirements file. Option 3
|
||||||
|
Echo.
|
||||||
|
pause
|
||||||
|
goto StandaloneMenu
|
||||||
|
|
||||||
|
:EndStandalone
|
||||||
|
echo Exiting AllTalk Setup Utility...
|
||||||
|
echo.
|
||||||
|
Echo Remember, after installation you can....
|
||||||
|
Echo Run %L_YELLOW%start_alltalk.bat%RESET% to start AllTalk.
|
||||||
|
Echo Run %L_YELLOW%start_finetune.bat%RESET% to start Finetuning.
|
||||||
|
Echo Run %L_YELLOW%start_environment.bat%RESET% to start the AllTalk Python environment.
|
||||||
|
Echo.
|
||||||
|
exit /b
|
||||||
|
|
||||||
|
:End
|
||||||
|
echo Exiting AllTalk Setup Utility...
|
||||||
|
exit /b
|
||||||
@@ -0,0 +1,520 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# ANSI color codes
|
||||||
|
RED='\033[1;31m'
|
||||||
|
GREEN='\033[1;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[1;34m'
|
||||||
|
CYAN='\033[1;36m'
|
||||||
|
MAGENTA='\033[1;35m'
|
||||||
|
WHITE='\033[1;37m'
|
||||||
|
L_RED='\033[1;91m'
|
||||||
|
L_GREEN='\033[1;92m'
|
||||||
|
L_YELLOW='\033[1;93m'
|
||||||
|
L_BLUE='\033[1;94m'
|
||||||
|
L_CYAN='\033[1;96m'
|
||||||
|
L_MAGENTA='\033[1;95m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# Navigate to the script's directory
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
|
# Function to check if curl is installed
|
||||||
|
check_curl() {
|
||||||
|
if ! command -v curl &> /dev/null; then
|
||||||
|
echo "curl is not available on this system. Please install curl then re-run the script https://curl.se/"
|
||||||
|
echo "or perform a manual installation of a Conda Python environment."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if the current directory path contains a space
|
||||||
|
containsSpace=false
|
||||||
|
currentPath=$(pwd)
|
||||||
|
if echo "$currentPath" | grep -q ' '; then
|
||||||
|
containsSpace=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$containsSpace" = true ]; then
|
||||||
|
echo
|
||||||
|
echo -e " ${L_BLUE}ALLTALK LINUX SETUP UTILITY${NC}"
|
||||||
|
echo
|
||||||
|
echo
|
||||||
|
echo -e " You are trying to install AllTalk in a folder that has a space in the"
|
||||||
|
echo -e " folder path e.g."
|
||||||
|
echo
|
||||||
|
echo -e " /home/${L_RED}program files${NC}/alltalk_tts"
|
||||||
|
echo
|
||||||
|
echo -e " This causes errors with Conda and Python scripts. Please follow this"
|
||||||
|
echo -e " link for reference:"
|
||||||
|
echo
|
||||||
|
echo -e " ${L_CYAN}https://docs.anaconda.com/free/working-with-conda/reference/faq/#installing-anaconda${NC}"
|
||||||
|
echo
|
||||||
|
echo -e " Please use a folder path that has no spaces in it e.g."
|
||||||
|
echo
|
||||||
|
echo -e " /home/myfiles/alltalk_tts/"
|
||||||
|
echo
|
||||||
|
echo
|
||||||
|
read -p "Press Enter to continue..."
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
# Continue with the main menu
|
||||||
|
echo "Continue with the main menu."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Main Menu
|
||||||
|
main_menu() {
|
||||||
|
while true; do
|
||||||
|
clear
|
||||||
|
echo
|
||||||
|
echo -e " ${L_BLUE}ALLTALK LINUX SETUP UTILITY${NC}"
|
||||||
|
echo
|
||||||
|
echo " INSTALLATION TYPE"
|
||||||
|
echo -e " 1) I am using AllTalk as part of ${L_GREEN}Text-generation-webui${NC}"
|
||||||
|
echo -e " 2) I am using AllTalk as a ${L_GREEN}Standalone Application${NC}"
|
||||||
|
echo
|
||||||
|
echo -e " 9)${L_RED} Exit/Quit${NC}"
|
||||||
|
echo
|
||||||
|
read -p " Enter your choice: " user_option
|
||||||
|
|
||||||
|
case $user_option in
|
||||||
|
1) webui_menu ;;
|
||||||
|
2) standalone_menu ;;
|
||||||
|
9) exit 0 ;;
|
||||||
|
*) echo "Invalid option"; sleep 2 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Text-generation-webui Menu
|
||||||
|
webui_menu() {
|
||||||
|
while true; do
|
||||||
|
clear
|
||||||
|
echo
|
||||||
|
echo -e " ${L_BLUE}TEXT-GENERATION-WEBUI SETUP${NC}"
|
||||||
|
echo
|
||||||
|
echo -e " Please ensure you have started your Text-generation-webui Python"
|
||||||
|
echo -e " environment. If you have NOT done this, please run ${L_GREEN}/cmd_linux.sh${NC}"
|
||||||
|
echo -e " in the ${L_GREEN}text-generation-webui${NC} folder and then re-run this script."
|
||||||
|
echo
|
||||||
|
echo " BASE REQUIREMENTS"
|
||||||
|
echo -e " 1) Apply/Re-Apply the requirements for an ${L_GREEN}Text-generation-webui${NC}"
|
||||||
|
echo
|
||||||
|
echo " OPTIONAL"
|
||||||
|
echo " 2) Git Pull the latest AllTalk updates from Github"
|
||||||
|
echo
|
||||||
|
echo " DEEPSPEED"
|
||||||
|
echo " 4) Install DeepSpeed."
|
||||||
|
echo " 5) Uninstall DeepSpeed."
|
||||||
|
echo
|
||||||
|
echo " OTHER"
|
||||||
|
echo " 6) Generate a diagnostics file."
|
||||||
|
echo
|
||||||
|
echo -e " 9)${L_RED} Exit/Quit${NC}"
|
||||||
|
echo
|
||||||
|
read -p " Enter your choice: " webui_option
|
||||||
|
|
||||||
|
case $webui_option in
|
||||||
|
1) install_nvidia_textgen ;;
|
||||||
|
2) tg_gitpull ;;
|
||||||
|
4) install_deepspeed ;;
|
||||||
|
5) uninstall_deepspeed ;;
|
||||||
|
6) generate_diagnostics_textgen ;;
|
||||||
|
9) exit 0 ;;
|
||||||
|
*) echo "Invalid option"; sleep 2 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
install_nvidia_textgen() {
|
||||||
|
local requirements_file="system/requirements/requirements_textgen.txt"
|
||||||
|
echo " Installing Requirements from $requirements_file..."
|
||||||
|
if ! pip install -r "$requirements_file"; then
|
||||||
|
echo
|
||||||
|
echo " There was an error pulling from Github."
|
||||||
|
echo " Please check the output for details."
|
||||||
|
read -p " Press any key to return to the menu. " -n 1
|
||||||
|
echo
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
echo " Requirements installed successfully."
|
||||||
|
echo
|
||||||
|
echo -e " To install ${L_YELLOW}DeepSpeed${NC} on Linux, there are additional"
|
||||||
|
echo -e " steps required. Please see the Github or documentation on DeepSeed."
|
||||||
|
echo
|
||||||
|
read -p " Press any key to continue. " -n 1
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
tg_gitpull() {
|
||||||
|
echo
|
||||||
|
if ! git pull; then
|
||||||
|
echo
|
||||||
|
echo " There was an error installing the requirements."
|
||||||
|
echo " Please check the output for details."
|
||||||
|
echo
|
||||||
|
read -p " Press any key to return to the menu. " -n 1
|
||||||
|
echo
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
echo " AllTalk Updated from Github. Please re-apply"
|
||||||
|
echo " the latest requirements file. (Option 1)"
|
||||||
|
echo
|
||||||
|
read -p " Press any key to continue. " -n 1
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to install DeepSpeed
|
||||||
|
install_deepspeed() {
|
||||||
|
clear
|
||||||
|
echo
|
||||||
|
echo -e " ${L_BLUE}DEEPSPEED INSTALLATION REQUIREMENTS${NC}"
|
||||||
|
echo
|
||||||
|
echo -e " - NVIDIA CUDA Toolkit must be installed from your ${L_GREEN}Linux package manager${NC}"
|
||||||
|
echo -e " or ${L_GREEN}https://developer.nvidia.com/cuda-toolkit-archive${NC}"
|
||||||
|
echo -e " - The environment variable ${L_GREEN}CUDA_HOME${NC} must be set in your Python env"
|
||||||
|
echo -e " e.g. export CUDA_HOME=/usr/local/cuda."
|
||||||
|
echo -e " - ${L_GREEN}libaio-dev${NC} must be installed."
|
||||||
|
echo
|
||||||
|
echo -e " See the following link for full instructions:"
|
||||||
|
echo -e " ${L_GREEN}https://github.com/erew123/alltalk_tts?#-deepspeed-installation-options${NC}"
|
||||||
|
echo
|
||||||
|
echo -e " ${L_BLUE}Please ${L_RED}confirm${L_BLUE} that you have completed these steps before continuing"
|
||||||
|
echo -e " with the DeepSpeed installation, or the install ${L_RED}will fail.${NC}"
|
||||||
|
echo
|
||||||
|
read -p " Have you completed all the above steps? (y/n): " confirm
|
||||||
|
|
||||||
|
if [ "$confirm" != "y" ]; then
|
||||||
|
echo -e " ${RED}DeepSpeed installation cannot proceed without completing the prerequisites.${NC}"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "\n ${GREEN}Proceeding with DeepSpeed installation...${NC}"
|
||||||
|
pip install deepspeed
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo -e " ${RED}There was an error installing DeepSpeed.${NC}"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e " ${GREEN}DeepSpeed installed successfully.${NC}"
|
||||||
|
read -p " Press any key to continue. " -n 1
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
uninstall_deepspeed() {
|
||||||
|
echo "Uninstalling DeepSpeed..."
|
||||||
|
pip uninstall -y deepspeed
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo
|
||||||
|
echo " There was an error uninstalling DeepSpeed."
|
||||||
|
echo
|
||||||
|
echo " Press any key to return to the menu."
|
||||||
|
read -n 1
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
echo " DeepSpeed uninstalled successfully."
|
||||||
|
echo
|
||||||
|
echo " Press any key to continue."
|
||||||
|
read -n 1
|
||||||
|
}
|
||||||
|
|
||||||
|
generate_diagnostics_textgen() {
|
||||||
|
# Run diagnostics
|
||||||
|
if ! python diagnostics.py; then
|
||||||
|
echo
|
||||||
|
echo " There was an error running diagnostics."
|
||||||
|
echo
|
||||||
|
read -p " Press any key to return to the menu. " -n 1
|
||||||
|
echo
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
echo " Diagnostics log file generated successfully."
|
||||||
|
echo " Please see diagnostics.log"
|
||||||
|
echo
|
||||||
|
read -p " Press any key to continue. " -n 1
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
# Standalone Menu
|
||||||
|
standalone_menu() {
|
||||||
|
while true; do
|
||||||
|
clear
|
||||||
|
echo
|
||||||
|
echo -e " ${L_BLUE}ALLTALK STANDALONE APPLICATION SETUP${NC}"
|
||||||
|
echo
|
||||||
|
echo " BASE REQUIREMENTS"
|
||||||
|
echo " 1) Install AllTalk as a Standalone Application"
|
||||||
|
echo
|
||||||
|
echo " OPTIONAL"
|
||||||
|
echo " 2) Git Pull the latest AllTalk updates from Github"
|
||||||
|
echo " 3) Re-Apply/Update the requirements file"
|
||||||
|
echo " 4) Delete AllTalk's custom Python environment"
|
||||||
|
echo " 5) Purge the PIP cache"
|
||||||
|
echo
|
||||||
|
echo " DEEPSPEED"
|
||||||
|
echo " 6) DeepSpeed Instructions/Install"
|
||||||
|
echo
|
||||||
|
echo " OTHER"
|
||||||
|
echo " 8) Generate a diagnostics file"
|
||||||
|
echo
|
||||||
|
echo -e " 9)${L_RED} Exit/Quit${NC}"
|
||||||
|
echo
|
||||||
|
read -p " Enter your choice: " standalone_option
|
||||||
|
|
||||||
|
case $standalone_option in
|
||||||
|
1) install_custom_standalone ;;
|
||||||
|
2) gitpull_standalone ;;
|
||||||
|
3) reapply_standalone ;;
|
||||||
|
4) delete_custom_standalone ;;
|
||||||
|
5) pippurge_standalone ;;
|
||||||
|
6) install_deepspeed ;;
|
||||||
|
8) generate_diagnostics_standalone ;;
|
||||||
|
9) exit 0 ;;
|
||||||
|
*) echo "Invalid option"; sleep 2 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
install_custom_standalone() {
|
||||||
|
cd "$(dirname "${BASH_SOURCE[0]}")"
|
||||||
|
|
||||||
|
if [[ "$(pwd)" =~ " " ]]; then
|
||||||
|
echo "This script relies on Miniconda which can not be silently installed under a path with spaces."
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Deactivate existing conda envs as needed to avoid conflicts
|
||||||
|
{ conda deactivate && conda deactivate && conda deactivate; } 2> /dev/null
|
||||||
|
|
||||||
|
OS_ARCH=$(uname -m)
|
||||||
|
case "${OS_ARCH}" in
|
||||||
|
x86_64*) OS_ARCH="x86_64" ;;
|
||||||
|
arm64* | aarch64*) OS_ARCH="aarch64" ;;
|
||||||
|
*) echo "Unknown system architecture: $OS_ARCH! This script runs only on x86_64 or arm64" && exit ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Config
|
||||||
|
INSTALL_DIR="$(pwd)/alltalk_environment"
|
||||||
|
CONDA_ROOT_PREFIX="${INSTALL_DIR}/conda"
|
||||||
|
INSTALL_ENV_DIR="${INSTALL_DIR}/env"
|
||||||
|
MINICONDA_DOWNLOAD_URL="https://repo.anaconda.com/miniconda/Miniconda3-py310_23.3.1-0-Linux-${OS_ARCH}.sh"
|
||||||
|
|
||||||
|
if [ ! -x "${CONDA_ROOT_PREFIX}/bin/conda" ]; then
|
||||||
|
echo "Downloading Miniconda from $MINICONDA_DOWNLOAD_URL to ${INSTALL_DIR}/miniconda_installer.sh"
|
||||||
|
mkdir -p "${INSTALL_DIR}"
|
||||||
|
curl -L "${MINICONDA_DOWNLOAD_URL}" -o "${INSTALL_DIR}/miniconda_installer.sh"
|
||||||
|
chmod +x "${INSTALL_DIR}/miniconda_installer.sh"
|
||||||
|
bash "${INSTALL_DIR}/miniconda_installer.sh" -b -p "${CONDA_ROOT_PREFIX}"
|
||||||
|
echo "Miniconda installed."
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -d "${INSTALL_ENV_DIR}" ]; then
|
||||||
|
"${CONDA_ROOT_PREFIX}/bin/conda" create -y --prefix "${INSTALL_ENV_DIR}" python=3.11
|
||||||
|
echo "Conda environment created at ${INSTALL_ENV_DIR}."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Activate the environment and install requirements
|
||||||
|
source "${CONDA_ROOT_PREFIX}/etc/profile.d/conda.sh"
|
||||||
|
conda activate "${INSTALL_ENV_DIR}"
|
||||||
|
echo
|
||||||
|
echo " Downloading and installing PyTorch. This step can take a long time"
|
||||||
|
echo " depending on your internet connection and hard drive speed. Please"
|
||||||
|
echo " be patient."
|
||||||
|
pip install torch>=2.2.1+cu121 torchaudio>=2.2.1+cu121 --upgrade --force-reinstall --extra-index-url https://download.pytorch.org/whl/cu121
|
||||||
|
echo
|
||||||
|
echo " Installing additional requirements."
|
||||||
|
echo
|
||||||
|
pip install -r system/requirements/requirements_standalone.txt
|
||||||
|
# Create start_environment.sh to run AllTalk
|
||||||
|
cat << EOF > start_environment.sh
|
||||||
|
#!/bin/bash
|
||||||
|
cd "$(dirname "${BASH_SOURCE[0]}")"
|
||||||
|
if [[ "$(pwd)" =~ " " ]]; then echo This script relies on Miniconda which can not be silently installed under a path with spaces. && exit; fi
|
||||||
|
# deactivate existing conda envs as needed to avoid conflicts
|
||||||
|
{ conda deactivate && conda deactivate && conda deactivate; } 2> /dev/null
|
||||||
|
# config
|
||||||
|
CONDA_ROOT_PREFIX="$(pwd)/alltalk_environment/conda"
|
||||||
|
INSTALL_ENV_DIR="$(pwd)/alltalk_environment/env"
|
||||||
|
# environment isolation
|
||||||
|
export PYTHONNOUSERSITE=1
|
||||||
|
unset PYTHONPATH
|
||||||
|
unset PYTHONHOME
|
||||||
|
export CUDA_PATH="$INSTALL_ENV_DIR"
|
||||||
|
export CUDA_HOME="$CUDA_PATH"
|
||||||
|
export LD_LIBRARY_PATH=`python3 -c 'import os; import nvidia.cublas.lib; import nvidia.cudnn.lib; print(os.path.dirname(nvidia.cublas.lib.__file__) + ":" + os.path.dirname(nvidia.cudnn.lib.__file__))'`
|
||||||
|
# activate env
|
||||||
|
bash --init-file <(echo "source \"$CONDA_ROOT_PREFIX/etc/profile.d/conda.sh\" && conda activate \"$INSTALL_ENV_DIR\"")
|
||||||
|
EOF
|
||||||
|
# Create start_alltalk.sh to run AllTalk
|
||||||
|
cat << EOF > start_alltalk.sh
|
||||||
|
#!/bin/bash
|
||||||
|
export LD_LIBRARY_PATH=`python3 -c 'import os; import nvidia.cublas.lib; import nvidia.cudnn.lib; print(os.path.dirname(nvidia.cublas.lib.__file__) + ":" + os.path.dirname(nvidia.cudnn.lib.__file__))'`
|
||||||
|
source "${CONDA_ROOT_PREFIX}/etc/profile.d/conda.sh"
|
||||||
|
conda activate "${INSTALL_ENV_DIR}"
|
||||||
|
python script.py
|
||||||
|
EOF
|
||||||
|
# Create start_finetune.sh to run AllTalk
|
||||||
|
cat << EOF > start_finetune.sh
|
||||||
|
#!/bin/bash
|
||||||
|
export TRAINER_TELEMETRY=0
|
||||||
|
export LD_LIBRARY_PATH=`python3 -c 'import os; import nvidia.cublas.lib; import nvidia.cudnn.lib; print(os.path.dirname(nvidia.cublas.lib.__file__) + ":" + os.path.dirname(nvidia.cudnn.lib.__file__))'`
|
||||||
|
source "${CONDA_ROOT_PREFIX}/etc/profile.d/conda.sh"
|
||||||
|
conda activate "${INSTALL_ENV_DIR}"
|
||||||
|
python finetune.py
|
||||||
|
EOF
|
||||||
|
chmod +x start_alltalk.sh
|
||||||
|
chmod +x start_environment.sh
|
||||||
|
chmod +x start_finetune.sh
|
||||||
|
echo
|
||||||
|
echo
|
||||||
|
echo -e " Run ${L_YELLOW}./start_alltalk.sh${NC} to start AllTalk."
|
||||||
|
echo -e " Run ${L_YELLOW}./start_finetune.sh${NC} to start Finetuning."
|
||||||
|
echo -e " Run ${L_YELLOW}./start_environment.sh${NC} to start the AllTalk Python environment."
|
||||||
|
echo
|
||||||
|
echo -e " To install ${L_YELLOW}DeepSpeed${NC} on Linux, there are additional"
|
||||||
|
echo -e " steps required. Please see the Github or documentation on DeepSeed."
|
||||||
|
echo
|
||||||
|
read -p " Press any key to continue. " -n 1
|
||||||
|
}
|
||||||
|
|
||||||
|
delete_custom_standalone() {
|
||||||
|
local env_dir="$PWD/alltalk_environment"
|
||||||
|
# Check if the alltalk_environment directory exists
|
||||||
|
if [ ! -d "$env_dir" ]; then
|
||||||
|
echo " \"$env_dir\" directory does not exist. No need to delete."
|
||||||
|
read -p " Press any key to continue. " -n 1
|
||||||
|
echo
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
# Check if a Conda environment is active and deactivate it
|
||||||
|
if [ -n "$CONDA_PREFIX" ]; then
|
||||||
|
echo " Exiting the Conda environment. You may need to start ./atstart.sh again"
|
||||||
|
conda deactivate
|
||||||
|
fi
|
||||||
|
echo "Deleting \"$env_dir\". Please wait."
|
||||||
|
rm -rf "$env_dir"
|
||||||
|
if [ -d "$env_dir" ]; then
|
||||||
|
echo " Failed to delete \"$env_dir\" folder."
|
||||||
|
echo " Please make sure it is not in use and try again."
|
||||||
|
else
|
||||||
|
echo " Environment \"$env_dir\" deleted successfully."
|
||||||
|
fi
|
||||||
|
read -p " Press any key to continue. " -n 1
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
generate_diagnostics_standalone() {
|
||||||
|
local env_dir="$PWD/alltalk_environment"
|
||||||
|
local conda_root_prefix="${env_dir}/conda"
|
||||||
|
local install_env_dir="${env_dir}/env"
|
||||||
|
if [ ! -d "${install_env_dir}" ]; then
|
||||||
|
echo
|
||||||
|
echo " The Conda environment at '${install_env_dir}' does not exist."
|
||||||
|
echo " Please install the environment before proceeding."
|
||||||
|
echo
|
||||||
|
read -p " Press any key to return to the menu. " -n 1
|
||||||
|
echo
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
source "${conda_root_prefix}/etc/profile.d/conda.sh"
|
||||||
|
conda activate "${install_env_dir}"
|
||||||
|
if ! python diagnostics.py; then
|
||||||
|
echo
|
||||||
|
echo " There was an error running diagnostics."
|
||||||
|
echo
|
||||||
|
read -p " Press any key to return to the menu. " -n 1
|
||||||
|
echo
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
echo " Diagnostics completed successfully."
|
||||||
|
read -p " Press any key to continue. " -n 1
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
gitpull_standalone() {
|
||||||
|
local env_dir="$PWD/alltalk_environment"
|
||||||
|
local conda_root_prefix="${env_dir}/conda"
|
||||||
|
local install_env_dir="${env_dir}/env"
|
||||||
|
if [ ! -d "${install_env_dir}" ]; then
|
||||||
|
echo
|
||||||
|
echo " The Conda environment at '${install_env_dir}' does not exist."
|
||||||
|
echo " Please install the environment before proceeding."
|
||||||
|
echo
|
||||||
|
read -p " Press any key to return to the menu. " -n 1
|
||||||
|
echo
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
source "${conda_root_prefix}/etc/profile.d/conda.sh"
|
||||||
|
conda activate "${install_env_dir}"
|
||||||
|
if ! git pull; then
|
||||||
|
echo
|
||||||
|
echo " There was an error pulling from Github."
|
||||||
|
echo
|
||||||
|
read -p " Press any key to return to the menu. " -n 1
|
||||||
|
echo
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
echo " AllTalk Updated from Github. Please re-apply."
|
||||||
|
echo " the latest requirements file. (Option 3)"
|
||||||
|
echo
|
||||||
|
read -p " Press any key to continue. " -n 1
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
pippurge_standalone() {
|
||||||
|
if ! pip cache purge; then
|
||||||
|
echo
|
||||||
|
echo " There was an error."
|
||||||
|
echo
|
||||||
|
read -p " Press any key to return to the menu. " -n 1
|
||||||
|
echo
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
echo " The PIP cache has been purged."
|
||||||
|
echo
|
||||||
|
read -p " Press any key to continue. " -n 1
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
reapply_standalone() {
|
||||||
|
local env_dir="$PWD/alltalk_environment"
|
||||||
|
local conda_root_prefix="${env_dir}/conda"
|
||||||
|
local install_env_dir="${env_dir}/env"
|
||||||
|
if [ ! -d "${install_env_dir}" ]; then
|
||||||
|
echo
|
||||||
|
echo " The Conda environment at '${install_env_dir}' does not exist."
|
||||||
|
echo " Please install the environment before proceeding."
|
||||||
|
echo
|
||||||
|
read -p " Press any key to return to the menu. " -n 1
|
||||||
|
echo
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
source "${conda_root_prefix}/etc/profile.d/conda.sh"
|
||||||
|
conda activate "${install_env_dir}"
|
||||||
|
echo
|
||||||
|
echo " Downloading and installing PyTorch. This step can take a long time"
|
||||||
|
echo " depending on your internet connection and hard drive speed. Please"
|
||||||
|
echo " be patient."
|
||||||
|
pip install torch>=2.2.1+cu121 torchaudio>=2.2.1+cu121 --upgrade --force-reinstall --extra-index-url https://download.pytorch.org/whl/cu121
|
||||||
|
echo
|
||||||
|
echo " Installing additional requirements."
|
||||||
|
echo
|
||||||
|
pip install -r system/requirements/requirements_standalone.txt
|
||||||
|
echo
|
||||||
|
echo " Requirements have been re-applied/updated."
|
||||||
|
echo
|
||||||
|
read -p " Press any key to continue. " -n 1
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Start the main menu
|
||||||
|
main_menu
|
||||||
@@ -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"}
|
{
|
||||||
|
"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"
|
||||||
|
}
|
||||||
@@ -6,20 +6,26 @@ try:
|
|||||||
import torch
|
import torch
|
||||||
import os # Import the os module
|
import os # Import the os module
|
||||||
import re
|
import re
|
||||||
|
import sys
|
||||||
import glob
|
import glob
|
||||||
|
import site
|
||||||
import textwrap
|
import textwrap
|
||||||
|
import torch
|
||||||
import packaging.version
|
import packaging.version
|
||||||
import packaging.specifiers
|
import packaging.specifiers
|
||||||
from packaging.specifiers import SpecifierSet
|
from packaging.specifiers import SpecifierSet
|
||||||
from packaging.specifiers import SpecifierSet
|
from packaging.specifiers import SpecifierSet
|
||||||
from packaging.version import parse as parse_version
|
from packaging.version import parse as parse_version
|
||||||
|
from pathlib import Path
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
print(f"\033[91mError importing module: {e}\033[0m\n")
|
print(f"\033[91mError importing module: {e}\033[0m\n")
|
||||||
print("\033[94mPlease ensure you started the Text-generation-webUI Python environment with either\033[0m")
|
print("\033[94mPlease ensure you started the Text-generation-webUI Python environment with either\033[0m")
|
||||||
print("\033[92mcmd_linux.sh\033[0m, \033[92mcmd_windows.bat\033[0m, \033[92mcmd_macos.sh\033[0m, or \033[92mcmd_wsl.bat\033[0m")
|
print("\033[92mcmd_linux.sh\033[0m, \033[92mcmd_windows.bat\033[0m, \033[92mcmd_macos.sh\033[0m, or \033[92mcmd_wsl.bat\033[0m")
|
||||||
print("\033[94mand then try running the diagnostics again.\033[0m")
|
print("\033[94mfrom the text-generation-webui directory, and then try running the diagnostics again.\033[0m")
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
|
this_dir = Path(__file__).parent
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import psutil
|
import psutil
|
||||||
except ImportError:
|
except ImportError:
|
||||||
@@ -28,24 +34,30 @@ except ImportError:
|
|||||||
import psutil
|
import psutil
|
||||||
|
|
||||||
def get_requirements_file():
|
def get_requirements_file():
|
||||||
requirements_files = glob.glob("requirements*.txt")
|
this_dir = Path(__file__).parent # Assuming 'this_dir' is defined as the script's directory
|
||||||
|
requirements_dir = this_dir / 'system' / 'requirements'
|
||||||
|
requirements_files = list(requirements_dir.glob('requirements*.txt')) # Using pathlib for globbing
|
||||||
|
|
||||||
if not requirements_files:
|
if not requirements_files:
|
||||||
print("\033[91mNo requirements files found.\033[0m")
|
print("\033[91mNo requirements files found.\033[0m")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
print("\033[94m\nSelect a requirements file to check against (or press Enter for default 'requirements.txt'):\033[0m\n")
|
print("\033[94m\nSelect a requirements file to check against (or press Enter for default 'requirements.txt'):\033[0m\n")
|
||||||
for i, file in enumerate(requirements_files, start=1):
|
for i, file_path in enumerate(requirements_files, start=1):
|
||||||
print(f"{i}. {file}")
|
print(f" {i}. {file_path.name}") # Only print the filename
|
||||||
|
|
||||||
choice = input("\nEnter the number of your choice: ")
|
choice = input("\nEnter the number of your choice: ")
|
||||||
try:
|
try:
|
||||||
choice = int(choice) - 1
|
choice = int(choice) - 1
|
||||||
return requirements_files[choice]
|
return str(requirements_files[choice]) # Return the full path as a string
|
||||||
except (ValueError, IndexError):
|
except (ValueError, IndexError):
|
||||||
return "requirements.txt"
|
return str(requirements_dir / "requirements.txt") # Return the default path as a string
|
||||||
|
|
||||||
# Set up logging with filemode='w'
|
# Set up logging with filemode='w'
|
||||||
logging.basicConfig(filename='diagnostics.log', filemode='w', level=logging.INFO)
|
logging.basicConfig(filename='diagnostics.log',
|
||||||
|
filemode='w',
|
||||||
|
level=logging.INFO,
|
||||||
|
format='%(message)s') # Custom format
|
||||||
|
|
||||||
# Function to get GPU information using subprocess
|
# Function to get GPU information using subprocess
|
||||||
def get_gpu_info():
|
def get_gpu_info():
|
||||||
@@ -55,6 +67,22 @@ def get_gpu_info():
|
|||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
return "NVIDIA GPU information not available"
|
return "NVIDIA GPU information not available"
|
||||||
|
|
||||||
|
def get_cpu_info():
|
||||||
|
cpu_info = {
|
||||||
|
'physical_cores': psutil.cpu_count(logical=False),
|
||||||
|
'total_cores': psutil.cpu_count(logical=True),
|
||||||
|
'max_frequency': psutil.cpu_freq().max
|
||||||
|
}
|
||||||
|
return cpu_info
|
||||||
|
|
||||||
|
def get_disk_info():
|
||||||
|
disk_info = []
|
||||||
|
partitions = psutil.disk_partitions()
|
||||||
|
for p in partitions:
|
||||||
|
usage = psutil.disk_usage(p.mountpoint)
|
||||||
|
disk_info.append(f" Drive: {p.device} | Total: {usage.total / (1024 ** 3):.2f} GB | Used: {usage.used / (1024 ** 3):.2f} GB | Free: {usage.free / (1024 ** 3):.2f} GB | Type: {p.fstype}")
|
||||||
|
return disk_info
|
||||||
|
|
||||||
# Function to check if a port is in use
|
# Function to check if a port is in use
|
||||||
def is_port_in_use(port):
|
def is_port_in_use(port):
|
||||||
for conn in psutil.net_connections():
|
for conn in psutil.net_connections():
|
||||||
@@ -72,6 +100,38 @@ def satisfies_wildcard(installed_version, required_version):
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def test_cuda():
|
||||||
|
cuda_available = torch.cuda.is_available()
|
||||||
|
if cuda_available:
|
||||||
|
try:
|
||||||
|
# Attempt to create a tensor on GPU
|
||||||
|
torch.tensor([1.0, 2.0]).cuda()
|
||||||
|
return "Success - CUDA is available and working."
|
||||||
|
except Exception as e:
|
||||||
|
return f"Fail - CUDA is available but not working. Error: {e}"
|
||||||
|
else:
|
||||||
|
return "Fail - CUDA is not available."
|
||||||
|
|
||||||
|
def find_files_in_path_with_wildcard(pattern):
|
||||||
|
# Get the site-packages directory of the current Python environment
|
||||||
|
site_packages_path = site.getsitepackages()
|
||||||
|
found_paths = []
|
||||||
|
# Adjust the sub-directory based on the operating system
|
||||||
|
sub_directory = "nvidia/cublas"
|
||||||
|
if platform.system() == "Linux":
|
||||||
|
sub_directory = os.path.join(sub_directory, "lib")
|
||||||
|
else:
|
||||||
|
sub_directory = os.path.join(sub_directory, "bin")
|
||||||
|
# Iterate over each site-packages directory (there can be more than one)
|
||||||
|
for directory in site_packages_path:
|
||||||
|
# Construct the search directory path
|
||||||
|
search_directory = os.path.join(directory, sub_directory)
|
||||||
|
# Use glob to find all files matching the pattern in this directory
|
||||||
|
for file_path in glob.glob(os.path.join(search_directory, pattern)):
|
||||||
|
if os.path.isfile(file_path): # Ensure it's a file
|
||||||
|
found_paths.append(file_path)
|
||||||
|
return found_paths
|
||||||
|
|
||||||
# Function to log and print system information
|
# Function to log and print system information
|
||||||
def log_system_info():
|
def log_system_info():
|
||||||
# System information
|
# System information
|
||||||
@@ -87,6 +147,9 @@ def log_system_info():
|
|||||||
|
|
||||||
# Torch version
|
# Torch version
|
||||||
torch_version = torch.__version__
|
torch_version = torch.__version__
|
||||||
|
cuda_test_result = test_cuda()
|
||||||
|
cpu_info = get_cpu_info()
|
||||||
|
disk_info = get_disk_info()
|
||||||
|
|
||||||
# System RAM using psutil
|
# System RAM using psutil
|
||||||
try:
|
try:
|
||||||
@@ -110,6 +173,22 @@ def log_system_info():
|
|||||||
# Package versions using importlib_metadata
|
# Package versions using importlib_metadata
|
||||||
package_versions = {d.metadata['Name']: d.version for d in distributions()}
|
package_versions = {d.metadata['Name']: d.version for d in distributions()}
|
||||||
|
|
||||||
|
# Python environment information
|
||||||
|
python_executable = sys.executable
|
||||||
|
python_version_info = sys.version_info
|
||||||
|
python_virtual_env = os.environ.get('VIRTUAL_ENV', 'N/A')
|
||||||
|
|
||||||
|
# Conda environment information
|
||||||
|
conda_env = os.environ.get('CONDA_DEFAULT_ENV', 'N/A')
|
||||||
|
|
||||||
|
# Get Path environment information
|
||||||
|
search_path = sys.path
|
||||||
|
path_env = os.environ.get('PATH', 'N/A')
|
||||||
|
|
||||||
|
# Check for cublas
|
||||||
|
file_name = 'cublas64_11.*' if platform.system() == "Windows" else 'libcublas.so.11*'
|
||||||
|
found_paths = find_files_in_path_with_wildcard(file_name)
|
||||||
|
|
||||||
# Compare with requirements file
|
# Compare with requirements file
|
||||||
requirements_file = get_requirements_file()
|
requirements_file = get_requirements_file()
|
||||||
if requirements_file:
|
if requirements_file:
|
||||||
@@ -133,32 +212,72 @@ def log_system_info():
|
|||||||
logging.info(f"NOTE {requirements_file} not found. Skipping version checks.")
|
logging.info(f"NOTE {requirements_file} not found. Skipping version checks.")
|
||||||
|
|
||||||
# Log and print information
|
# Log and print information
|
||||||
|
logging.info(f"OPERATING SYSTEM:")
|
||||||
logging.info(f" OS Version: {os_version}")
|
logging.info(f" OS Version: {os_version}")
|
||||||
logging.info(f"Note: Windows 11 build is 10.x.22xxx")
|
logging.info(f" Note: Windows 11 will list as build is 10.x.22xxx")
|
||||||
logging.info(f"Python Version: {python_version}")
|
logging.info(f"\nHARDWARE ENVIRONMENT:")
|
||||||
logging.info(f"Torch Version: {torch_version}")
|
logging.info(f" CPU: Physical Cores: {cpu_info['physical_cores']}, Total Cores: {cpu_info['total_cores']}, Max Frequency: {cpu_info['max_frequency']} MHz")
|
||||||
logging.info(f" System RAM: {system_ram}")
|
logging.info(f" System RAM: {system_ram}")
|
||||||
logging.info(f"CUDA_HOME: {cuda_home}")
|
logging.info(f"\nGPU INFORMATION:{gpu_info}")
|
||||||
|
logging.info("DISK INFORMATION:")
|
||||||
|
for disk in disk_info:
|
||||||
|
logging.info(disk)
|
||||||
|
logging.info("\nNETWORK PORT:")
|
||||||
logging.info(f" Port Status: {port_status}")
|
logging.info(f" Port Status: {port_status}")
|
||||||
|
logging.info("\nCUDA:")
|
||||||
|
logging.info(f" CUDA Working: {cuda_test_result}")
|
||||||
|
logging.info(f" CUDA_HOME: {cuda_home}")
|
||||||
|
if found_paths:
|
||||||
|
logging.info(f" Cublas64_11 Path: {', '.join(found_paths)}")
|
||||||
|
else:
|
||||||
|
logging.info(f" Cublas64_11 Path: Not found in any search path directories.")
|
||||||
|
logging.info("\nPYTHON & PYTORCH:")
|
||||||
|
logging.info(f" Torch Version: {torch_version}")
|
||||||
|
logging.info(f" Python Version: {platform.python_version()}")
|
||||||
|
logging.info(f" Python Version Info: {python_version_info}")
|
||||||
|
logging.info(f" Python Executable: {python_executable}")
|
||||||
|
logging.info(f" Python Virtual Environment: {python_virtual_env} (Should be N/A when in Text-generation-webui Conda Python environment)")
|
||||||
|
logging.info(f" Conda Environment: {conda_env}")
|
||||||
|
logging.info("\nPython Search Path:")
|
||||||
|
for path in search_path:
|
||||||
|
logging.info(f" {path}")
|
||||||
|
logging.info("\nOS SEARCHPATH ENVIRONMENT:")
|
||||||
|
for path in path_env.split(';'):
|
||||||
|
logging.info(f" {path}")
|
||||||
if required_packages: # Check if the dictionary is not empty
|
if required_packages: # Check if the dictionary is not empty
|
||||||
logging.info("Package Versions:")
|
logging.info("\nPACKAGE VERSIONS vs REQUIREMENTS FILE:")
|
||||||
max_package_length = max(len(package) for package in required_packages.keys())
|
max_package_length = max(len(package) for package in required_packages.keys())
|
||||||
for package_name, (operator, required_version) in required_packages.items():
|
for package_name, (operator, required_version) in required_packages.items():
|
||||||
installed_version = installed_packages.get(package_name, 'Not installed')
|
installed_version = installed_packages.get(package_name, 'Not installed')
|
||||||
logging.info(f" {package_name.ljust(max_package_length)} Required: {operator} {required_version.ljust(12)} Installed: {installed_version}")
|
logging.info(f" {package_name.ljust(max_package_length)} Required: {operator} {required_version.ljust(12)} Installed: {installed_version}")
|
||||||
logging.info(f"GPU Information:\n{gpu_info}")
|
logging.info("\nPYTHON PACKAGES:")
|
||||||
logging.info("Package Versions:")
|
|
||||||
for package, version in package_versions.items():
|
for package, version in package_versions.items():
|
||||||
logging.info(f" {package}>= {version}")
|
logging.info(f" {package}>= {version}")
|
||||||
|
|
||||||
# Print to screen
|
# Print to screen
|
||||||
print(f"\n\033[94mOS Version:\033[0m \033[92m{os_version}\033[0m")
|
print(f"\n\033[94mOS Version:\033[0m \033[92m{os_version}\033[0m")
|
||||||
print(f"\033[94mOS Ver note:\033[0m \033[92mWindows 11 build is 10.x.22xxx\033[0m")
|
print(f"\033[94mOS Ver note:\033[0m \033[92m(Windows 11 will say build is 10.x.22xxx)\033[0m")
|
||||||
print(f"\033[94mCUDA_HOME:\033[0m \033[92m{cuda_home}\033[0m")
|
|
||||||
print(f"\033[94mSystem RAM:\033[0m \033[92m{system_ram}\033[0m")
|
print(f"\033[94mSystem RAM:\033[0m \033[92m{system_ram}\033[0m")
|
||||||
print(f"\033[94mPort Status:\033[0m \033[92m{port_status}\033[0m")
|
for disk in disk_info:
|
||||||
print(f"\033[94mTorch Version:\033[0m \033[92m{torch_version}\033[0m")
|
print(f"\033[94mDisk:\033[0m \033[92m{disk}\033[0m")
|
||||||
print(f"\033[94mPython Version:\033[0m \033[92m{python_version}\033[0m")
|
print(f"\033[94m\nGPU Information:\033[0m {gpu_info}")
|
||||||
|
print(f"\033[94mPort Status:\033[0m \033[92m{port_status}\033[0m\n")
|
||||||
|
if "Fail" in cuda_test_result:
|
||||||
|
print(f"\033[91mCUDA Working:\033[0m \033[91m{cuda_test_result}\033[0m")
|
||||||
|
else:
|
||||||
|
print(f"\033[94mCUDA Working:\033[0m \033[92m{cuda_test_result}\033[0m")
|
||||||
|
print(f"\033[94mCUDA_HOME:\033[0m \033[92m{cuda_home}\033[0m")
|
||||||
|
if found_paths:
|
||||||
|
print(f"\033[94mCublas64_11 Path:\033[0m \033[92m{', '.join(found_paths)}\033[0m")
|
||||||
|
else:
|
||||||
|
print(f"\033[94mCublas64_11 Path:\033[0m \033[91mNot found in any search path directories.\033[0m")
|
||||||
|
print(f"\033[94m\nTorch Version:\033[0m \033[92m{torch_version}\033[0m")
|
||||||
|
print(f"\033[94mPython Version:\033[0m \033[92m{platform.python_version()}\033[0m")
|
||||||
|
print(f"\033[94mPython Executable:\033[0m \033[92m{python_executable}\033[0m")
|
||||||
|
print(f"\033[94mConda Environment:\033[0m \033[92m{conda_env}\033[0m")
|
||||||
|
print(f"\n\033[94mPython Search Path:\033[0m")
|
||||||
|
for path in search_path:
|
||||||
|
print(f" {path}")
|
||||||
if required_packages: # Check if the dictionary is not empty
|
if required_packages: # Check if the dictionary is not empty
|
||||||
print("\033[94m\nRequirements file package comparison:\033[0m")
|
print("\033[94m\nRequirements file package comparison:\033[0m")
|
||||||
max_package_length = max(len(package) for package in required_packages.keys())
|
max_package_length = max(len(package) for package in required_packages.keys())
|
||||||
@@ -182,6 +301,13 @@ def log_system_info():
|
|||||||
|
|
||||||
# Print colored output
|
# Print colored output
|
||||||
print(f" {package_name.ljust(max_package_length)} Required: {color_required}{operator} {required_version.ljust(12)}\033[0m Installed: {color_installed}{installed_version}\033[0m")
|
print(f" {package_name.ljust(max_package_length)} Required: {color_required}{operator} {required_version.ljust(12)}\033[0m Installed: {color_installed}{installed_version}\033[0m")
|
||||||
|
|
||||||
|
print("\nOn Nvidia Graphics cards machines, if your \033[92mInstalled\033[0m version of \033[92mTorch\033[0m and \033[92mTorchaudio\033[0m does")
|
||||||
|
print("not have \033[92m+cu118\033[0m (Cuda 11.8) or \033[92m+cu121\033[0m (Cuda 12.1) listed after them, you do not have CUDA")
|
||||||
|
print("installed for Torch or Torchaudio in this Python environment. This will cause you problems")
|
||||||
|
print("with \033[94mAllTalk\033[0m and \033[94mFinetuning.\033[0m You may have to 'pip install' a new version of torch and")
|
||||||
|
print("torchaudio, using '\033[94m--upgrade --force-reinstall\033[0m' with the correct version of PyTorch for\033[0m")
|
||||||
|
print("your Python environment.\033[0m")
|
||||||
print("\033[94m\nRequirements file specifier meanings:\033[0m")
|
print("\033[94m\nRequirements file specifier meanings:\033[0m")
|
||||||
explanation = textwrap.dedent("""
|
explanation = textwrap.dedent("""
|
||||||
== Exact version != Any version except < Less than
|
== Exact version != Any version except < Less than
|
||||||
@@ -191,9 +317,9 @@ def log_system_info():
|
|||||||
""")
|
""")
|
||||||
print(explanation.strip())
|
print(explanation.strip())
|
||||||
print("")
|
print("")
|
||||||
print(f"GPU Information:{gpu_info}")
|
print(f"\033[94mDiagnostic log created:\033[0m \033[92mdiagnostics.log. \033[94mA brief summary of results is displayed above on\033[0m")
|
||||||
print(f"\033[94mDiagnostic log created:\033[0m \033[92mdiagnostics.log\033[0m")
|
print(f"\033[94mscreen. Please see the log file for more detail.\033[0m")
|
||||||
print(f"\033[94mPlease upload the log file with any support ticket.\033[0m")
|
print(f"\033[94m\nPlease upload the log file with any support ticket.\033[0m")
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
log_system_info()
|
log_system_info()
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
version: '3.8'
|
||||||
|
services:
|
||||||
|
alltalk-tts:
|
||||||
|
image: erew123/alltalk_tts:cuda
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "7851:7851"
|
||||||
|
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:
|
||||||
|
resources:
|
||||||
|
reservations:
|
||||||
|
devices:
|
||||||
|
- driver: nvidia
|
||||||
|
count: all
|
||||||
|
capabilities: [ gpu ]
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
version: '3.8'
|
||||||
|
services:
|
||||||
|
alltalk-tts:
|
||||||
|
image: alltalk:v1-9c
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "7851:7851"
|
||||||
|
- "7852:7852"
|
||||||
|
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:
|
||||||
|
resources:
|
||||||
|
reservations:
|
||||||
|
devices:
|
||||||
|
- driver: nvidia
|
||||||
|
count: all
|
||||||
|
capabilities: [ gpu ]
|
||||||
@@ -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"
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
python modeldownload.py
|
||||||
|
uvicorn tts_server:app --host 0.0.0.0 --port 7851 --workers 1 --proxy-headers &
|
||||||
|
sleep 5
|
||||||
|
python script.py
|
||||||
@@ -6,6 +6,9 @@
|
|||||||
"README.md": "https://huggingface.co/coqui/XTTS-v2/resolve/v2.0.2/README.md?download=true",
|
"README.md": "https://huggingface.co/coqui/XTTS-v2/resolve/v2.0.2/README.md?download=true",
|
||||||
"config.json": "https://huggingface.co/coqui/XTTS-v2/resolve/v2.0.2/config.json?download=true",
|
"config.json": "https://huggingface.co/coqui/XTTS-v2/resolve/v2.0.2/config.json?download=true",
|
||||||
"model.pth": "https://huggingface.co/coqui/XTTS-v2/resolve/v2.0.2/model.pth?download=true",
|
"model.pth": "https://huggingface.co/coqui/XTTS-v2/resolve/v2.0.2/model.pth?download=true",
|
||||||
|
"dvae.pth": "https://huggingface.co/coqui/XTTS-v2/resolve/v2.0.2/dvae.pth?download=true",
|
||||||
|
"mel_stats.pth": "https://huggingface.co/coqui/XTTS-v2/resolve/v2.0.2/mel_stats.pth?download=true",
|
||||||
|
"speakers_xtts.pth": "https://huggingface.co/coqui/XTTS-v2/resolve/v2.0.2/speakers_xtts.pth?download=true",
|
||||||
"vocab.json": "https://huggingface.co/coqui/XTTS-v2/resolve/v2.0.2/vocab.json?download=true"
|
"vocab.json": "https://huggingface.co/coqui/XTTS-v2/resolve/v2.0.2/vocab.json?download=true"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,13 @@
|
|||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import requests
|
import requests
|
||||||
|
from requests.exceptions import ConnectionError
|
||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
import importlib.metadata as metadata
|
import importlib.metadata as metadata
|
||||||
import json
|
import json
|
||||||
from packaging import version
|
from packaging import version
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
#################################################################
|
#################################################################
|
||||||
#### LOAD PARAMS FROM confignew.json - REQUIRED FOR BRANDING ####
|
#### LOAD PARAMS FROM confignew.json - REQUIRED FOR BRANDING ####
|
||||||
@@ -12,14 +15,12 @@ from packaging import version
|
|||||||
# STARTUP VARIABLE - Create "this_dir" variable as the current script directory
|
# STARTUP VARIABLE - Create "this_dir" variable as the current script directory
|
||||||
this_dir = Path(__file__).parent.resolve()
|
this_dir = Path(__file__).parent.resolve()
|
||||||
|
|
||||||
|
|
||||||
# load standard config file in and get settings
|
# load standard config file in and get settings
|
||||||
def load_config(file_path):
|
def load_config(file_path):
|
||||||
with open(file_path, "r") as config_file:
|
with open(file_path, "r") as config_file:
|
||||||
config = json.load(config_file)
|
config = json.load(config_file)
|
||||||
return config
|
return config
|
||||||
|
|
||||||
|
|
||||||
config_file_path = this_dir / "confignew.json"
|
config_file_path = this_dir / "confignew.json"
|
||||||
params = load_config(config_file_path)
|
params = load_config(config_file_path)
|
||||||
|
|
||||||
@@ -37,34 +38,26 @@ if modeldownload_config_file_path.exists():
|
|||||||
files_to_download = settings.get("files_to_download", {})
|
files_to_download = settings.get("files_to_download", {})
|
||||||
else:
|
else:
|
||||||
# Default settings if the JSON file doesn't exist or is empty
|
# Default settings if the JSON file doesn't exist or is empty
|
||||||
print(
|
print(f"[{params['branding']}Startup] \033[91mWarning\033[0m modeldownload.json is missing so please re-download it and save it in the coquii_tts main folder.")
|
||||||
f"[{params['branding']}Startup] \033[91mWarning\033[0m modeldownload.json is missing so please re-download it and save it in the coquii_tts main folder."
|
print(f"[{params['branding']}Startup] \033[91mWarning\033[0m API Local and XTTSv2 Local will error unless this is corrected.")
|
||||||
)
|
|
||||||
print(
|
|
||||||
f"[{params['branding']}Startup] \033[91mWarning\033[0m API Local and XTTSv2 Local will error unless this is corrected."
|
|
||||||
)
|
|
||||||
|
|
||||||
# Read the version specifier from requirements_nvidia.txt
|
# Read the version specifier from requirements_nvidia.txt
|
||||||
with open(this_dir / "requirements_nvidia.txt", "r") as req_file:
|
with open(this_dir / "system" / "requirements" / "requirements_standalone.txt", "r") as req_file:
|
||||||
requirements = req_file.readlines()
|
requirements = req_file.readlines()
|
||||||
|
|
||||||
tts_version_required = None
|
tts_version_required = None
|
||||||
for req in requirements:
|
for req in requirements:
|
||||||
if req.startswith("TTS>="):
|
if req.startswith("TTS=="):
|
||||||
tts_version_required = req.strip().split(">=")[1]
|
tts_version_required = req.strip().split("==")[1]
|
||||||
break
|
break
|
||||||
|
|
||||||
if tts_version_required is None:
|
if tts_version_required is None:
|
||||||
raise ValueError(
|
raise ValueError(f"[{params['branding']}Startup] \033[91mWarning\033[0m Could not find TTS version specifier in requirements file")
|
||||||
f"[{params['branding']}Startup] \033[91mWarning\033[0m Could not find TTS version specifier in requirements_nvidia.txt"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def create_directory_if_not_exists(directory):
|
def create_directory_if_not_exists(directory):
|
||||||
if not directory.exists():
|
if not directory.exists():
|
||||||
directory.mkdir(parents=True)
|
directory.mkdir(parents=True)
|
||||||
|
|
||||||
|
|
||||||
def download_file(url, destination):
|
def download_file(url, destination):
|
||||||
response = requests.get(url, stream=True)
|
response = requests.get(url, stream=True)
|
||||||
total_size_in_bytes = int(response.headers.get("content-length", 0))
|
total_size_in_bytes = int(response.headers.get("content-length", 0))
|
||||||
@@ -83,63 +76,118 @@ def download_file(url, destination):
|
|||||||
def check_tts_version():
|
def check_tts_version():
|
||||||
try:
|
try:
|
||||||
tts_version = metadata.version("tts")
|
tts_version = metadata.version("tts")
|
||||||
print(
|
print(f"[{params['branding']}Startup] \033[92mCurrent TTS Version : \033[93m"+tts_version+"\033[0m")
|
||||||
f"[{params['branding']}Startup] TTS version installed: \033[93m"
|
|
||||||
+ tts_version
|
|
||||||
+ "\033[0m"
|
|
||||||
)
|
|
||||||
|
|
||||||
if version.parse(tts_version) < version.parse(tts_version_required):
|
if version.parse(tts_version) < version.parse(tts_version_required):
|
||||||
print(
|
print(f"[{params['branding']}Startup] \033[91mWarning\033[0m TTS version is too old. Please upgrade to version \033[93m"+tts_version_required+"\033[0m or later.\033[0m")
|
||||||
f"[{params['branding']}Startup] \033[91mWarning\033[0m TTS version is too old. Please upgrade to version \033[93m"
|
print(f"[{params['branding']}Startup] \033[91mWarning\033[0m At your terminal/command prompt \033[94mpip install --upgrade tts\033[0m")
|
||||||
+ tts_version_required
|
|
||||||
+ "\033[0m or later.\033[0m"
|
|
||||||
)
|
|
||||||
print(
|
|
||||||
f"[{params['branding']}Startup] \033[91mWarning\033[0m At your terminal/command prompt \033[94mpip install --upgrade tts\033[0m"
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
print(f"[{params['branding']}Startup] TTS version is up to date.")
|
print(f"[{params['branding']}Startup] \033[92mCurrent TTS Version is :\033[93m Up to date\033[0m")
|
||||||
except metadata.PackageNotFoundError:
|
except metadata.PackageNotFoundError:
|
||||||
print(
|
print(f"[{params['branding']}Startup] \033[91mWarning\033[0m TTS is not installed")
|
||||||
f"[{params['branding']}Startup] \033[91mWarning\033[0m TTS is not installed."
|
|
||||||
)
|
|
||||||
|
|
||||||
|
def check_torch_version():
|
||||||
|
import torch
|
||||||
|
pytorch_version = torch.__version__
|
||||||
|
cuda_version = torch.version.cuda
|
||||||
|
major, minor, micro = sys.version_info[:3]
|
||||||
|
python_version = f"{major}.{minor}.{micro}"
|
||||||
|
print(f"[{params['branding']}Startup] \033[92mCurrent Python Version :\033[93m {python_version}\033[0m")
|
||||||
|
print(f"[{params['branding']}Startup] \033[92mCurrent PyTorch Version:\033[93m {pytorch_version}\033[0m")
|
||||||
|
if cuda_version is None:
|
||||||
|
print(f"[{params['branding']}Startup] \033[92mCurrent CUDA Version :\033[91m CUDA is not available\033[0m")
|
||||||
|
else:
|
||||||
|
print(f"[{params['branding']}Startup] \033[92mCurrent CUDA Version :\033[93m {cuda_version}\033[0m")
|
||||||
|
|
||||||
|
def ordinal(n):
|
||||||
|
return "%d%s" % (n, "th" if 4 <= n % 100 <= 20 else {1: "st", 2: "nd", 3: "rd"}.get(n % 10, "th"))
|
||||||
|
|
||||||
|
def format_datetime(iso_str):
|
||||||
|
# Parse the ISO 8601 string to datetime
|
||||||
|
dt = datetime.strptime(iso_str, "%Y-%m-%dT%H:%M:%SZ")
|
||||||
|
# Format the datetime into a more readable string
|
||||||
|
return dt.strftime(f"{ordinal(dt.day)} %B %Y at %H:%M")
|
||||||
|
|
||||||
|
def fetch_latest_commit_sha_and_date(owner, repo):
|
||||||
|
url = f"https://api.github.com/repos/{owner}/{repo}/commits"
|
||||||
|
try:
|
||||||
|
response = requests.get(url)
|
||||||
|
if response.status_code == 200:
|
||||||
|
latest_commit = response.json()[0]
|
||||||
|
latest_commit_sha = latest_commit['sha']
|
||||||
|
latest_commit_date = latest_commit['commit']['committer']['date']
|
||||||
|
return latest_commit_sha, latest_commit_date
|
||||||
|
else:
|
||||||
|
print(f"[{params['branding']}Startup] \033[92m{params['branding']}Github updated :\033[91m Failed to fetch the latest commits due to an unexpected response from GitHub")
|
||||||
|
return None, None
|
||||||
|
except ConnectionError:
|
||||||
|
# This block is executed when a connection error occurs
|
||||||
|
print(f"[{params['branding']}Startup] \033[92m{params['branding']}Github updated :\033[91m Could not reach GitHub to check for updates\033[0m")
|
||||||
|
return None, None
|
||||||
|
|
||||||
|
def read_or_initialize_sha(file_path):
|
||||||
|
if os.path.exists(file_path):
|
||||||
|
with open(file_path, 'r') as file:
|
||||||
|
data = json.load(file)
|
||||||
|
return data.get("last_known_commit_sha")
|
||||||
|
else:
|
||||||
|
# File doesn't exist, fetch the latest SHA and create the file
|
||||||
|
latest_commit_sha = fetch_latest_commit_sha_and_date(github_site, github_repository)
|
||||||
|
if latest_commit_sha:
|
||||||
|
with open(file_path, 'w') as file:
|
||||||
|
json.dump({"last_known_commit_sha": latest_commit_sha}, file)
|
||||||
|
return latest_commit_sha
|
||||||
|
else:
|
||||||
|
# Handle the case where GitHub couldn't be reached
|
||||||
|
return None
|
||||||
|
|
||||||
|
def update_sha_file(file_path, new_sha):
|
||||||
|
with open(file_path, 'w') as file:
|
||||||
|
json.dump({"last_known_commit_sha": new_sha}, file)
|
||||||
|
|
||||||
# Check and create directories
|
# Check and create directories
|
||||||
if str(base_path) == "models":
|
if str(base_path) == "models":
|
||||||
create_directory_if_not_exists(this_dir / base_path / model_path)
|
create_directory_if_not_exists(this_dir / base_path / model_path)
|
||||||
else:
|
else:
|
||||||
create_directory_if_not_exists(base_path / model_path)
|
create_directory_if_not_exists(base_path / model_path)
|
||||||
print(
|
print(f"[{params['branding']}Startup] \033[94mInfo\033[0m Custom path set in \033[93mmodeldownload.json\033[0m. Using the following settings:")
|
||||||
f"[{params['branding']}Startup] \033[94mInfo\033[0m Custom path set in \033[93mmodeldownload.json\033[0m. Using the following settings:"
|
print(f"[{params['branding']}Startup] \033[94mInfo\033[0m Base folder Path:\033[93m",base_path,"\033[0m",)
|
||||||
)
|
print(f"[{params['branding']}Startup] \033[94mInfo\033[0m Model folder Path:\033[93m",model_path,"\033[0m",)
|
||||||
print(
|
print(f"[{params['branding']}Startup] \033[94mInfo\033[0m Full Path:\033[93m",base_path / model_path,"\033[0m",)
|
||||||
f"[{params['branding']}Startup] \033[94mInfo\033[0m Base folder Path:\033[93m",
|
|
||||||
base_path,
|
|
||||||
"\033[0m",
|
|
||||||
)
|
|
||||||
print(
|
|
||||||
f"[{params['branding']}Startup] \033[94mInfo\033[0m Model folder Path:\033[93m",
|
|
||||||
model_path,
|
|
||||||
"\033[0m",
|
|
||||||
)
|
|
||||||
print(
|
|
||||||
f"[{params['branding']}Startup] \033[94mInfo\033[0m Full Path:\033[93m",
|
|
||||||
base_path / model_path,
|
|
||||||
"\033[0m",
|
|
||||||
)
|
|
||||||
|
|
||||||
# Download files if they don't exist
|
# Download files if they don't exist
|
||||||
print("[" + params["branding"] + "Startup] Checking Model is Downloaded.")
|
print(f"[{params['branding']}Startup] \033[92mModel is available :\033[93m Checking\033[0m")
|
||||||
for filename, url in files_to_download.items():
|
for filename, url in files_to_download.items():
|
||||||
if str(base_path) == "models":
|
if str(base_path) == "models":
|
||||||
destination = this_dir / base_path / model_path / filename
|
destination = this_dir / base_path / model_path / filename
|
||||||
else:
|
else:
|
||||||
destination = Path(base_path) / model_path / filename
|
destination = Path(base_path) / model_path / filename
|
||||||
|
|
||||||
if not destination.exists():
|
if not destination.exists():
|
||||||
print(f"[{params['branding']}Startup] Downloading " + filename + "...")
|
print(f"[{params['branding']}Startup] \033[92mModel Downloading file : \033[93m" + filename + "\033[0m")
|
||||||
download_file(url, destination)
|
download_file(url, destination)
|
||||||
|
print(f"[{params['branding']}Startup] \033[92mModel is available :\033[93m Checked\033[0m")
|
||||||
|
|
||||||
|
github_site = "erew123"
|
||||||
|
github_repository = "alltalk_tts"
|
||||||
|
|
||||||
|
check_torch_version()
|
||||||
check_tts_version()
|
check_tts_version()
|
||||||
|
# Define the file path based on your directory structure
|
||||||
|
sha_file_path = this_dir / "system" / "config" / "at_github_sha.json"
|
||||||
|
|
||||||
|
# Read or initialize the SHA (adjusted for handling both SHA and date)
|
||||||
|
last_known_commit_sha = read_or_initialize_sha(sha_file_path) # Assuming adjustment for date
|
||||||
|
|
||||||
|
# Assuming you have fetched the latest commit SHA and date
|
||||||
|
latest_commit_sha, latest_commit_date = fetch_latest_commit_sha_and_date(github_site, github_repository)
|
||||||
|
|
||||||
|
formatted_date = format_datetime(latest_commit_date) if latest_commit_date else "an unknown date"
|
||||||
|
|
||||||
|
if latest_commit_sha and latest_commit_sha != last_known_commit_sha:
|
||||||
|
#print(f"There's an update available for alltalk_tts.")
|
||||||
|
print(f"[{params['branding']}Startup] \033[92m{params['branding']}Github updated :\033[93m {formatted_date}\033[0m")
|
||||||
|
# Update the file with the new SHA
|
||||||
|
update_sha_file(sha_file_path, latest_commit_sha)
|
||||||
|
elif latest_commit_sha == last_known_commit_sha:
|
||||||
|
#print(f"Your alltalk_tts software is up to date.")
|
||||||
|
print(f"[{params['branding']}Startup] \033[92m{params['branding']}Github updated :\033[93m {formatted_date}\033[0m")
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
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 portaudio19-dev \
|
||||||
|
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 \
|
||||||
|
&& ln -s /usr/bin/python3 /usr/bin/python
|
||||||
|
|
||||||
|
RUN mkdir /app/pip_cache
|
||||||
|
ENV PIP_CACHE_DIR=/app/pip_cache
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
COPY . .
|
||||||
|
ENV CUDA_DOCKER_ARCH=all
|
||||||
|
RUN pip install --no-cache-dir --no-deps -r system/requirements/requirements_standalone.txt --cache-dir=/app/pip_cache && \
|
||||||
|
pip install --no-cache-dir deepspeed --cache-dir=/app/pip_cache
|
||||||
|
|
||||||
|
EXPOSE 7851
|
||||||
|
RUN chmod +x launch.sh
|
||||||
|
ENTRYPOINT ["sh", "-c", "./launch.sh"]
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
numpy>=1.22.0
|
|
||||||
soundfile>=0.12.1
|
|
||||||
uvicorn>=0.24.0.post1
|
|
||||||
TTS>=0.22.0
|
|
||||||
torch>=2.1.0+cu118
|
|
||||||
torchaudio>=2.1.0+cu118
|
|
||||||
fastapi>=0.104.1
|
|
||||||
Jinja2>=3.1.2
|
|
||||||
requests>=2.31.0
|
|
||||||
tqdm>=4.66.1
|
|
||||||
importlib-metadata>=4.8.1
|
|
||||||
packaging>=23.2
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
numpy>=1.22.0
|
|
||||||
soundfile>=0.12.1
|
|
||||||
uvicorn>=0.24.0.post1
|
|
||||||
TTS>=0.22.0
|
|
||||||
torch>=2.1.0
|
|
||||||
torchaudio>=2.1.0
|
|
||||||
fastapi>=0.104.1
|
|
||||||
Jinja2>=3.1.2
|
|
||||||
requests>=2.31.0
|
|
||||||
tqdm>=4.66.1
|
|
||||||
importlib-metadata>=4.8.1
|
|
||||||
packaging>=23.2
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
.SDAP .hires_opts input[type="number"] {
|
|
||||||
width: 6em !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* silero_tts preview */
|
|
||||||
.form:has(> #silero_preview_text) {
|
|
||||||
min-width: 75%
|
|
||||||
}
|
|
||||||
|
After Width: | Height: | Size: 97 KiB |
|
After Width: | Height: | Size: 11 KiB |
@@ -89,25 +89,25 @@
|
|||||||
<h3>AllTalk Startup Settings</h3><br>
|
<h3>AllTalk Startup Settings</h3><br>
|
||||||
<form action="/update-settings" method="post">
|
<form action="/update-settings" method="post">
|
||||||
|
|
||||||
<label for="activate" style="color: #33cc33;">Activate TTS:</label>
|
<label for="activate" style="color: #b273fa;">TG-webui Activate TTS:</label>
|
||||||
<select id="activate" name="activate" required="">
|
<select id="activate" name="activate" required="">
|
||||||
<option {% if data.activate %}selected{% endif %} value="true">True</option>
|
<option {% if data.activate %}selected{% endif %} value="true">True</option>
|
||||||
<option {% if not data.activate %}selected{% endif %} value="false">False</option>
|
<option {% if not data.activate %}selected{% endif %} value="false">False</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<label for="autoplay" style="color: #33cc33;"> Autoplay TTS output:</label>
|
<label for="autoplay" style="color: #b273fa;"> TG-webui Autoplay TTS:</label>
|
||||||
<select id="autoplay" name="autoplay" required="">
|
<select id="autoplay" name="autoplay" required="">
|
||||||
<option {% if data.autoplay %}selected{% endif %} value="true">True</option>
|
<option {% if data.autoplay %}selected{% endif %} value="true">True</option>
|
||||||
<option {% if not data.autoplay %}selected{% endif %} value="false">False</option>
|
<option {% if not data.autoplay %}selected{% endif %} value="false">False</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<label for="show_text" style="color: #33cc33;"> Show Text on generation:</label>
|
<label for="show_text" style="color: #b273fa;">TG-webui Show Text:</label>
|
||||||
<select id="show_text" name="show_text" required="">
|
<select id="show_text" name="show_text" required="">
|
||||||
<option {% if data.show_text %}selected{% endif %} value="true">True</option>
|
<option {% if data.show_text %}selected{% endif %} value="true">True</option>
|
||||||
<option {% if not data.show_text %}selected{% endif %} value="false">False</option>
|
<option {% if not data.show_text %}selected{% endif %} value="false">False</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<label for="voice" style="color: #33cc33;"> Default voice:</label>
|
<label for="voice" style="color: #b273fa;"> TG-webui Default voice:</label>
|
||||||
<select id="voice" name="voice" required="">
|
<select id="voice" name="voice" required="">
|
||||||
{% for file in wav_files %}
|
{% for file in wav_files %}
|
||||||
<option value="{{ file }}" {% if data.voice==file %}selected{% endif %}>{{ file }}</option>
|
<option value="{{ file }}" {% if data.voice==file %}selected{% endif %}>{{ file }}</option>
|
||||||
@@ -115,7 +115,7 @@
|
|||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
|
||||||
<label for="language" style="color: #33cc33;">Default Language:</label>
|
<label for="language" style="color: #b273fa;">TG-webui Default Language:</label>
|
||||||
<select id="language" name="language" required="">
|
<select id="language" name="language" required="">
|
||||||
<option value="Arabic" {% if data.language=='Arabic' %}selected{% endif %}>Arabic</option>
|
<option value="Arabic" {% if data.language=='Arabic' %}selected{% endif %}>Arabic</option>
|
||||||
<option value="Chinese" {% if data.language=='Chinese' %}selected{% endif %}>Chinese</option>
|
<option value="Chinese" {% if data.language=='Chinese' %}selected{% endif %}>Chinese</option>
|
||||||
@@ -124,6 +124,7 @@
|
|||||||
<option value="English" {% if data.language=='English' %}selected{% endif %}>English</option>
|
<option value="English" {% if data.language=='English' %}selected{% endif %}>English</option>
|
||||||
<option value="French" {% if data.language=='French' %}selected{% endif %}>French</option>
|
<option value="French" {% if data.language=='French' %}selected{% endif %}>French</option>
|
||||||
<option value="German" {% if data.language=='German' %}selected{% endif %}>German</option>
|
<option value="German" {% if data.language=='German' %}selected{% endif %}>German</option>
|
||||||
|
<option value="Hindi" {% if data.language=='Hindi' %}selected{% endif %}>Hindi</option>
|
||||||
<option value="Hungarian" {% if data.language=='Hungarian' %}selected{% endif %}>Hungarian</option>
|
<option value="Hungarian" {% if data.language=='Hungarian' %}selected{% endif %}>Hungarian</option>
|
||||||
<option value="Italian" {% if data.language=='Italian' %}selected{% endif %}>Italian</option>
|
<option value="Italian" {% if data.language=='Italian' %}selected{% endif %}>Italian</option>
|
||||||
<option value="Japanese" {% if data.language=='Japanese' %}selected{% endif %}>Japanese</option>
|
<option value="Japanese" {% if data.language=='Japanese' %}selected{% endif %}>Japanese</option>
|
||||||
@@ -135,20 +136,20 @@
|
|||||||
<option value="Turkish" {% if data.language=='Turkish' %}selected{% endif %}>Turkish</option>
|
<option value="Turkish" {% if data.language=='Turkish' %}selected{% endif %}>Turkish</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<label for="narrator_voice" style="color: #33cc33;"> Narrator voice:</label>
|
<label for="narrator_voice" style="color: #b273fa;"> TG-webui Narrator voice:</label>
|
||||||
<select id="narrator_voice" name="narrator_voice" required="">
|
<select id="narrator_voice" name="narrator_voice" required="">
|
||||||
{% for file in wav_files %}
|
{% for file in wav_files %}
|
||||||
<option value="{{ file }}" {% if data.narrator_voice==file %}selected{% endif %}>{{ file }}</option>
|
<option value="{{ file }}" {% if data.narrator_voice==file %}selected{% endif %}>{{ file }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<label for="remove_trailing_dots" style="color: #33cc33;"> Remove Trailing Dots:</label>
|
<label for="remove_trailing_dots" style="color: #b273fa;">TG-webui Remove Trailing Dots:</label>
|
||||||
<select id="remove_trailing_dots" name="remove_trailing_dots" required="">
|
<select id="remove_trailing_dots" name="remove_trailing_dots" required="">
|
||||||
<option {% if data.remove_trailing_dots %}selected{% endif %} value="true">True</option>
|
<option {% if data.remove_trailing_dots %}selected{% endif %} value="true">True</option>
|
||||||
<option {% if not data.remove_trailing_dots %}selected{% endif %} value="false">False</option>
|
<option {% if not data.remove_trailing_dots %}selected{% endif %} value="false">False</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<label for="narrator_enabled" style="color: #33cc33;"> Narrator enabled:</label>
|
<label for="narrator_enabled" style="color: #b273fa;"> TG-webui Narrator enabled:</label>
|
||||||
<select id="narrator_enabled" name="narrator_enabled" required="">
|
<select id="narrator_enabled" name="narrator_enabled" required="">
|
||||||
<option {% if data.narrator_enabled %}selected{% endif %} value="true">True</option>
|
<option {% if data.narrator_enabled %}selected{% endif %} value="true">True</option>
|
||||||
<option {% if not data.narrator_enabled %}selected{% endif %} value="false">False</option>
|
<option {% if not data.narrator_enabled %}selected{% endif %} value="false">False</option>
|
||||||
|
After Width: | Height: | Size: 216 KiB |
|
After Width: | Height: | Size: 173 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 57 KiB |
|
After Width: | Height: | Size: 59 KiB |
|
After Width: | Height: | Size: 91 KiB |
|
After Width: | Height: | Size: 52 KiB |
@@ -0,0 +1,2 @@
|
|||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
{
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
"English": "en",
|
"English": "en",
|
||||||
"French": "fr",
|
"French": "fr",
|
||||||
"German": "de",
|
"German": "de",
|
||||||
|
"Hindi": "hi",
|
||||||
"Hungarian": "hu",
|
"Hungarian": "hu",
|
||||||
"Italian": "it",
|
"Italian": "it",
|
||||||
"Japanese": "ja",
|
"Japanese": "ja",
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,869 @@
|
|||||||
|
import os
|
||||||
|
import re
|
||||||
|
import textwrap
|
||||||
|
from functools import cached_property
|
||||||
|
|
||||||
|
import pypinyin
|
||||||
|
import torch
|
||||||
|
from hangul_romanize import Transliter
|
||||||
|
from hangul_romanize.rule import academic
|
||||||
|
from num2words import num2words
|
||||||
|
from spacy.lang.ar import Arabic
|
||||||
|
from spacy.lang.en import English
|
||||||
|
from spacy.lang.es import Spanish
|
||||||
|
from spacy.lang.ja import Japanese
|
||||||
|
from spacy.lang.zh import Chinese
|
||||||
|
from tokenizers import Tokenizer
|
||||||
|
|
||||||
|
from TTS.tts.layers.xtts.zh_num2words import TextNorm as zh_num2words
|
||||||
|
|
||||||
|
|
||||||
|
def get_spacy_lang(lang):
|
||||||
|
if lang == "zh":
|
||||||
|
return Chinese()
|
||||||
|
elif lang == "ja":
|
||||||
|
return Japanese()
|
||||||
|
elif lang == "ar":
|
||||||
|
return Arabic()
|
||||||
|
elif lang == "es":
|
||||||
|
return Spanish()
|
||||||
|
else:
|
||||||
|
# For most languages, Enlish does the job
|
||||||
|
return English()
|
||||||
|
|
||||||
|
|
||||||
|
def split_sentence(text, lang, text_split_length=250):
|
||||||
|
"""Preprocess the input text"""
|
||||||
|
text_splits = []
|
||||||
|
if text_split_length is not None and len(text) >= text_split_length:
|
||||||
|
text_splits.append("")
|
||||||
|
nlp = get_spacy_lang(lang)
|
||||||
|
nlp.add_pipe("sentencizer")
|
||||||
|
doc = nlp(text)
|
||||||
|
for sentence in doc.sents:
|
||||||
|
if len(text_splits[-1]) + len(str(sentence)) <= text_split_length:
|
||||||
|
# if the last sentence + the current sentence is less than the text_split_length
|
||||||
|
# then add the current sentence to the last sentence
|
||||||
|
text_splits[-1] += " " + str(sentence)
|
||||||
|
text_splits[-1] = text_splits[-1].lstrip()
|
||||||
|
elif len(str(sentence)) > text_split_length:
|
||||||
|
# if the current sentence is greater than the text_split_length
|
||||||
|
for line in textwrap.wrap(
|
||||||
|
str(sentence),
|
||||||
|
width=text_split_length,
|
||||||
|
drop_whitespace=True,
|
||||||
|
break_on_hyphens=False,
|
||||||
|
tabsize=1,
|
||||||
|
):
|
||||||
|
text_splits.append(str(line))
|
||||||
|
else:
|
||||||
|
text_splits.append(str(sentence))
|
||||||
|
|
||||||
|
if len(text_splits) > 1:
|
||||||
|
if text_splits[0] == "":
|
||||||
|
del text_splits[0]
|
||||||
|
else:
|
||||||
|
text_splits = [text.lstrip()]
|
||||||
|
|
||||||
|
return text_splits
|
||||||
|
|
||||||
|
|
||||||
|
_whitespace_re = re.compile(r"\s+")
|
||||||
|
|
||||||
|
# List of (regular expression, replacement) pairs for abbreviations:
|
||||||
|
_abbreviations = {
|
||||||
|
"en": [
|
||||||
|
(re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1])
|
||||||
|
for x in [
|
||||||
|
("mrs", "misess"),
|
||||||
|
("mr", "mister"),
|
||||||
|
("dr", "doctor"),
|
||||||
|
("st", "saint"),
|
||||||
|
("co", "company"),
|
||||||
|
("jr", "junior"),
|
||||||
|
("maj", "major"),
|
||||||
|
("gen", "general"),
|
||||||
|
("drs", "doctors"),
|
||||||
|
("rev", "reverend"),
|
||||||
|
("lt", "lieutenant"),
|
||||||
|
("hon", "honorable"),
|
||||||
|
("sgt", "sergeant"),
|
||||||
|
("capt", "captain"),
|
||||||
|
("esq", "esquire"),
|
||||||
|
("ltd", "limited"),
|
||||||
|
("col", "colonel"),
|
||||||
|
("ft", "fort"),
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"es": [
|
||||||
|
(re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1])
|
||||||
|
for x in [
|
||||||
|
("sra", "señora"),
|
||||||
|
("sr", "señor"),
|
||||||
|
("dr", "doctor"),
|
||||||
|
("dra", "doctora"),
|
||||||
|
("st", "santo"),
|
||||||
|
("co", "compañía"),
|
||||||
|
("jr", "junior"),
|
||||||
|
("ltd", "limitada"),
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"fr": [
|
||||||
|
(re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1])
|
||||||
|
for x in [
|
||||||
|
("mme", "madame"),
|
||||||
|
("mr", "monsieur"),
|
||||||
|
("dr", "docteur"),
|
||||||
|
("st", "saint"),
|
||||||
|
("co", "compagnie"),
|
||||||
|
("jr", "junior"),
|
||||||
|
("ltd", "limitée"),
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"de": [
|
||||||
|
(re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1])
|
||||||
|
for x in [
|
||||||
|
("fr", "frau"),
|
||||||
|
("dr", "doktor"),
|
||||||
|
("st", "sankt"),
|
||||||
|
("co", "firma"),
|
||||||
|
("jr", "junior"),
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"pt": [
|
||||||
|
(re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1])
|
||||||
|
for x in [
|
||||||
|
("sra", "senhora"),
|
||||||
|
("sr", "senhor"),
|
||||||
|
("dr", "doutor"),
|
||||||
|
("dra", "doutora"),
|
||||||
|
("st", "santo"),
|
||||||
|
("co", "companhia"),
|
||||||
|
("jr", "júnior"),
|
||||||
|
("ltd", "limitada"),
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"it": [
|
||||||
|
(re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1])
|
||||||
|
for x in [
|
||||||
|
# ("sig.ra", "signora"),
|
||||||
|
("sig", "signore"),
|
||||||
|
("dr", "dottore"),
|
||||||
|
("st", "santo"),
|
||||||
|
("co", "compagnia"),
|
||||||
|
("jr", "junior"),
|
||||||
|
("ltd", "limitata"),
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"pl": [
|
||||||
|
(re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1])
|
||||||
|
for x in [
|
||||||
|
("p", "pani"),
|
||||||
|
("m", "pan"),
|
||||||
|
("dr", "doktor"),
|
||||||
|
("sw", "święty"),
|
||||||
|
("jr", "junior"),
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"ar": [
|
||||||
|
(re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1])
|
||||||
|
for x in [
|
||||||
|
# There are not many common abbreviations in Arabic as in English.
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"zh": [
|
||||||
|
(re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1])
|
||||||
|
for x in [
|
||||||
|
# Chinese doesn't typically use abbreviations in the same way as Latin-based scripts.
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"cs": [
|
||||||
|
(re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1])
|
||||||
|
for x in [
|
||||||
|
("dr", "doktor"), # doctor
|
||||||
|
("ing", "inženýr"), # engineer
|
||||||
|
("p", "pan"), # Could also map to pani for woman but no easy way to do it
|
||||||
|
# Other abbreviations would be specialized and not as common.
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"ru": [
|
||||||
|
(re.compile("\\b%s\\b" % x[0], re.IGNORECASE), x[1])
|
||||||
|
for x in [
|
||||||
|
("г-жа", "госпожа"), # Mrs.
|
||||||
|
("г-н", "господин"), # Mr.
|
||||||
|
("д-р", "доктор"), # doctor
|
||||||
|
# Other abbreviations are less common or specialized.
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"nl": [
|
||||||
|
(re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1])
|
||||||
|
for x in [
|
||||||
|
("dhr", "de heer"), # Mr.
|
||||||
|
("mevr", "mevrouw"), # Mrs.
|
||||||
|
("dr", "dokter"), # doctor
|
||||||
|
("jhr", "jonkheer"), # young lord or nobleman
|
||||||
|
# Dutch uses more abbreviations, but these are the most common ones.
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"tr": [
|
||||||
|
(re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1])
|
||||||
|
for x in [
|
||||||
|
("b", "bay"), # Mr.
|
||||||
|
("byk", "büyük"), # büyük
|
||||||
|
("dr", "doktor"), # doctor
|
||||||
|
# Add other Turkish abbreviations here if needed.
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"hu": [
|
||||||
|
(re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1])
|
||||||
|
for x in [
|
||||||
|
("dr", "doktor"), # doctor
|
||||||
|
("b", "bácsi"), # Mr.
|
||||||
|
("nőv", "nővér"), # nurse
|
||||||
|
# Add other Hungarian abbreviations here if needed.
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"ko": [
|
||||||
|
(re.compile("\\b%s\\." % x[0], re.IGNORECASE), x[1])
|
||||||
|
for x in [
|
||||||
|
# Korean doesn't typically use abbreviations in the same way as Latin-based scripts.
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"ja": [
|
||||||
|
(re.compile("\\b%s\\b" % x[0]), x[1])
|
||||||
|
for x in [
|
||||||
|
("氏", "さん"), # Mr.
|
||||||
|
("夫人", "おんなのひと"), # Mrs.
|
||||||
|
("博士", "はかせ"), # Doctor or PhD
|
||||||
|
("株", "株式会社"), # Corporation
|
||||||
|
("有", "有限会社"), # Limited company
|
||||||
|
("大学", "だいがく"), # University
|
||||||
|
("先生", "せんせい"), # Teacher/Professor/Master
|
||||||
|
("君", "くん") # Used at the end of boys' names to express familiarity or affection.
|
||||||
|
]
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def expand_abbreviations_multilingual(text, lang="en"):
|
||||||
|
for regex, replacement in _abbreviations[lang]:
|
||||||
|
text = re.sub(regex, replacement, text)
|
||||||
|
return text
|
||||||
|
|
||||||
|
|
||||||
|
_symbols_multilingual = {
|
||||||
|
"en": [
|
||||||
|
(re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1])
|
||||||
|
for x in [
|
||||||
|
("&", " and "),
|
||||||
|
("@", " at "),
|
||||||
|
("%", " percent "),
|
||||||
|
("#", " hash "),
|
||||||
|
("$", " dollar "),
|
||||||
|
("£", " pound "),
|
||||||
|
("°", " degree "),
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"es": [
|
||||||
|
(re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1])
|
||||||
|
for x in [
|
||||||
|
("&", " y "),
|
||||||
|
("@", " arroba "),
|
||||||
|
("%", " por ciento "),
|
||||||
|
("#", " numeral "),
|
||||||
|
("$", " dolar "),
|
||||||
|
("£", " libra "),
|
||||||
|
("°", " grados "),
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"fr": [
|
||||||
|
(re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1])
|
||||||
|
for x in [
|
||||||
|
("&", " et "),
|
||||||
|
("@", " arobase "),
|
||||||
|
("%", " pour cent "),
|
||||||
|
("#", " dièse "),
|
||||||
|
("$", " dollar "),
|
||||||
|
("£", " livre "),
|
||||||
|
("°", " degrés "),
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"de": [
|
||||||
|
(re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1])
|
||||||
|
for x in [
|
||||||
|
("&", " und "),
|
||||||
|
("@", " at "),
|
||||||
|
("%", " prozent "),
|
||||||
|
("#", " raute "),
|
||||||
|
("$", " dollar "),
|
||||||
|
("£", " pfund "),
|
||||||
|
("°", " grad "),
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"pt": [
|
||||||
|
(re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1])
|
||||||
|
for x in [
|
||||||
|
("&", " e "),
|
||||||
|
("@", " arroba "),
|
||||||
|
("%", " por cento "),
|
||||||
|
("#", " cardinal "),
|
||||||
|
("$", " dólar "),
|
||||||
|
("£", " libra "),
|
||||||
|
("°", " graus "),
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"it": [
|
||||||
|
(re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1])
|
||||||
|
for x in [
|
||||||
|
("&", " e "),
|
||||||
|
("@", " chiocciola "),
|
||||||
|
("%", " per cento "),
|
||||||
|
("#", " cancelletto "),
|
||||||
|
("$", " dollaro "),
|
||||||
|
("£", " sterlina "),
|
||||||
|
("°", " gradi "),
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"pl": [
|
||||||
|
(re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1])
|
||||||
|
for x in [
|
||||||
|
("&", " i "),
|
||||||
|
("@", " małpa "),
|
||||||
|
("%", " procent "),
|
||||||
|
("#", " krzyżyk "),
|
||||||
|
("$", " dolar "),
|
||||||
|
("£", " funt "),
|
||||||
|
("°", " stopnie "),
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"ar": [
|
||||||
|
# Arabic
|
||||||
|
(re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1])
|
||||||
|
for x in [
|
||||||
|
("&", " و "),
|
||||||
|
("@", " على "),
|
||||||
|
("%", " في المئة "),
|
||||||
|
("#", " رقم "),
|
||||||
|
("$", " دولار "),
|
||||||
|
("£", " جنيه "),
|
||||||
|
("°", " درجة "),
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"zh": [
|
||||||
|
# Chinese
|
||||||
|
(re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1])
|
||||||
|
for x in [
|
||||||
|
("&", " 和 "),
|
||||||
|
("@", " 在 "),
|
||||||
|
("%", " 百分之 "),
|
||||||
|
("#", " 号 "),
|
||||||
|
("$", " 美元 "),
|
||||||
|
("£", " 英镑 "),
|
||||||
|
("°", " 度 "),
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"cs": [
|
||||||
|
# Czech
|
||||||
|
(re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1])
|
||||||
|
for x in [
|
||||||
|
("&", " a "),
|
||||||
|
("@", " na "),
|
||||||
|
("%", " procento "),
|
||||||
|
("#", " křížek "),
|
||||||
|
("$", " dolar "),
|
||||||
|
("£", " libra "),
|
||||||
|
("°", " stupně "),
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"ru": [
|
||||||
|
# Russian
|
||||||
|
(re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1])
|
||||||
|
for x in [
|
||||||
|
("&", " и "),
|
||||||
|
("@", " собака "),
|
||||||
|
("%", " процентов "),
|
||||||
|
("#", " номер "),
|
||||||
|
("$", " доллар "),
|
||||||
|
("£", " фунт "),
|
||||||
|
("°", " градус "),
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"nl": [
|
||||||
|
# Dutch
|
||||||
|
(re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1])
|
||||||
|
for x in [
|
||||||
|
("&", " en "),
|
||||||
|
("@", " bij "),
|
||||||
|
("%", " procent "),
|
||||||
|
("#", " hekje "),
|
||||||
|
("$", " dollar "),
|
||||||
|
("£", " pond "),
|
||||||
|
("°", " graden "),
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"tr": [
|
||||||
|
(re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1])
|
||||||
|
for x in [
|
||||||
|
("&", " ve "),
|
||||||
|
("@", " at "),
|
||||||
|
("%", " yüzde "),
|
||||||
|
("#", " diyez "),
|
||||||
|
("$", " dolar "),
|
||||||
|
("£", " sterlin "),
|
||||||
|
("°", " derece "),
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"hu": [
|
||||||
|
(re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1])
|
||||||
|
for x in [
|
||||||
|
("&", " és "),
|
||||||
|
("@", " kukac "),
|
||||||
|
("%", " százalék "),
|
||||||
|
("#", " kettőskereszt "),
|
||||||
|
("$", " dollár "),
|
||||||
|
("£", " font "),
|
||||||
|
("°", " fok "),
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"ko": [
|
||||||
|
# Korean
|
||||||
|
(re.compile(r"%s" % re.escape(x[0]), re.IGNORECASE), x[1])
|
||||||
|
for x in [
|
||||||
|
("&", " 그리고 "),
|
||||||
|
("@", " 에 "),
|
||||||
|
("%", " 퍼센트 "),
|
||||||
|
("#", " 번호 "),
|
||||||
|
("$", " 달러 "),
|
||||||
|
("£", " 파운드 "),
|
||||||
|
("°", " 도 "),
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"ja": [
|
||||||
|
(re.compile(r"%s" % re.escape(x[0])), x[1])
|
||||||
|
for x in [
|
||||||
|
("&", " と "),
|
||||||
|
("@", " アットマーク "),
|
||||||
|
("%", " パーセント "),
|
||||||
|
("#", " ナンバー "),
|
||||||
|
("$", " ドル "),
|
||||||
|
("£", " ポンド "),
|
||||||
|
("°", " 度"),
|
||||||
|
]
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def expand_symbols_multilingual(text, lang="en"):
|
||||||
|
for regex, replacement in _symbols_multilingual[lang]:
|
||||||
|
text = re.sub(regex, replacement, text)
|
||||||
|
text = text.replace(" ", " ") # Ensure there are no double spaces
|
||||||
|
return text.strip()
|
||||||
|
|
||||||
|
|
||||||
|
_ordinal_re = {
|
||||||
|
"en": re.compile(r"([0-9]+)(st|nd|rd|th)"),
|
||||||
|
"es": re.compile(r"([0-9]+)(º|ª|er|o|a|os|as)"),
|
||||||
|
"fr": re.compile(r"([0-9]+)(º|ª|er|re|e|ème)"),
|
||||||
|
"de": re.compile(r"([0-9]+)(st|nd|rd|th|º|ª|\.(?=\s|$))"),
|
||||||
|
"pt": re.compile(r"([0-9]+)(º|ª|o|a|os|as)"),
|
||||||
|
"it": re.compile(r"([0-9]+)(º|°|ª|o|a|i|e)"),
|
||||||
|
"pl": re.compile(r"([0-9]+)(º|ª|st|nd|rd|th)"),
|
||||||
|
"ar": re.compile(r"([0-9]+)(ون|ين|ث|ر|ى)"),
|
||||||
|
"cs": re.compile(r"([0-9]+)\.(?=\s|$)"), # In Czech, a dot is often used after the number to indicate ordinals.
|
||||||
|
"ru": re.compile(r"([0-9]+)(-й|-я|-е|-ое|-ье|-го)"),
|
||||||
|
"nl": re.compile(r"([0-9]+)(de|ste|e)"),
|
||||||
|
"tr": re.compile(r"([0-9]+)(\.|inci|nci|uncu|üncü|\.)"),
|
||||||
|
"hu": re.compile(r"([0-9]+)(\.|adik|edik|odik|edik|ödik|ödike|ik)"),
|
||||||
|
"ko": re.compile(r"([0-9]+)(번째|번|차|째)"),
|
||||||
|
"ja": re.compile(r"([0-9]+)(番|回|つ|目|等|位)")
|
||||||
|
}
|
||||||
|
_number_re = re.compile(r"[0-9]+")
|
||||||
|
_currency_re = {
|
||||||
|
"USD": re.compile(r"((\$[0-9\.\,]*[0-9]+)|([0-9\.\,]*[0-9]+\$))"),
|
||||||
|
"GBP": re.compile(r"((£[0-9\.\,]*[0-9]+)|([0-9\.\,]*[0-9]+£))"),
|
||||||
|
"EUR": re.compile(r"(([0-9\.\,]*[0-9]+€)|((€[0-9\.\,]*[0-9]+)))"),
|
||||||
|
}
|
||||||
|
|
||||||
|
_comma_number_re = re.compile(r"\b\d{1,3}(,\d{3})*(\.\d+)?\b")
|
||||||
|
_dot_number_re = re.compile(r"\b\d{1,3}(.\d{3})*(\,\d+)?\b")
|
||||||
|
_decimal_number_re = re.compile(r"([0-9]+[.,][0-9]+)")
|
||||||
|
|
||||||
|
|
||||||
|
def _remove_commas(m):
|
||||||
|
text = m.group(0)
|
||||||
|
if "," in text:
|
||||||
|
text = text.replace(",", "")
|
||||||
|
return text
|
||||||
|
|
||||||
|
|
||||||
|
def _remove_dots(m):
|
||||||
|
text = m.group(0)
|
||||||
|
if "." in text:
|
||||||
|
text = text.replace(".", "")
|
||||||
|
return text
|
||||||
|
|
||||||
|
|
||||||
|
def _expand_decimal_point(m, lang="en"):
|
||||||
|
amount = m.group(1).replace(",", ".")
|
||||||
|
return num2words(float(amount), lang=lang if lang != "cs" else "cz")
|
||||||
|
|
||||||
|
|
||||||
|
def _expand_currency(m, lang="en", currency="USD"):
|
||||||
|
amount = float((re.sub(r"[^\d.]", "", m.group(0).replace(",", "."))))
|
||||||
|
full_amount = num2words(amount, to="currency", currency=currency, lang=lang if lang != "cs" else "cz")
|
||||||
|
|
||||||
|
and_equivalents = {
|
||||||
|
"en": ", ",
|
||||||
|
"es": " con ",
|
||||||
|
"fr": " et ",
|
||||||
|
"de": " und ",
|
||||||
|
"pt": " e ",
|
||||||
|
"it": " e ",
|
||||||
|
"pl": ", ",
|
||||||
|
"cs": ", ",
|
||||||
|
"ru": ", ",
|
||||||
|
"nl": ", ",
|
||||||
|
"ar": ", ",
|
||||||
|
"tr": ", ",
|
||||||
|
"hu": ", ",
|
||||||
|
"ko": ", ",
|
||||||
|
}
|
||||||
|
|
||||||
|
if amount.is_integer():
|
||||||
|
last_and = full_amount.rfind(and_equivalents[lang])
|
||||||
|
if last_and != -1:
|
||||||
|
full_amount = full_amount[:last_and]
|
||||||
|
|
||||||
|
return full_amount
|
||||||
|
|
||||||
|
|
||||||
|
def _expand_ordinal(m, lang="en"):
|
||||||
|
return num2words(int(m.group(1)), ordinal=True, lang=lang if lang != "cs" else "cz")
|
||||||
|
|
||||||
|
|
||||||
|
def _expand_number(m, lang="en"):
|
||||||
|
return num2words(int(m.group(0)), lang=lang if lang != "cs" else "cz")
|
||||||
|
|
||||||
|
|
||||||
|
def expand_numbers_multilingual(text, lang="en"):
|
||||||
|
if lang == "zh":
|
||||||
|
text = zh_num2words()(text)
|
||||||
|
else:
|
||||||
|
if lang in ["en", "ru"]:
|
||||||
|
text = re.sub(_comma_number_re, _remove_commas, text)
|
||||||
|
else:
|
||||||
|
text = re.sub(_dot_number_re, _remove_dots, text)
|
||||||
|
try:
|
||||||
|
text = re.sub(_currency_re["GBP"], lambda m: _expand_currency(m, lang, "GBP"), text)
|
||||||
|
text = re.sub(_currency_re["USD"], lambda m: _expand_currency(m, lang, "USD"), text)
|
||||||
|
text = re.sub(_currency_re["EUR"], lambda m: _expand_currency(m, lang, "EUR"), text)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
if lang != "tr":
|
||||||
|
text = re.sub(_decimal_number_re, lambda m: _expand_decimal_point(m, lang), text)
|
||||||
|
text = re.sub(_ordinal_re[lang], lambda m: _expand_ordinal(m, lang), text)
|
||||||
|
text = re.sub(_number_re, lambda m: _expand_number(m, lang), text)
|
||||||
|
return text
|
||||||
|
|
||||||
|
|
||||||
|
def lowercase(text):
|
||||||
|
return text.lower()
|
||||||
|
|
||||||
|
|
||||||
|
def collapse_whitespace(text):
|
||||||
|
return re.sub(_whitespace_re, " ", text)
|
||||||
|
|
||||||
|
|
||||||
|
def multilingual_cleaners(text, lang):
|
||||||
|
text = text.replace('"', "")
|
||||||
|
if lang == "tr":
|
||||||
|
text = text.replace("İ", "i")
|
||||||
|
text = text.replace("Ö", "ö")
|
||||||
|
text = text.replace("Ü", "ü")
|
||||||
|
text = lowercase(text)
|
||||||
|
text = expand_numbers_multilingual(text, lang)
|
||||||
|
text = expand_abbreviations_multilingual(text, lang)
|
||||||
|
text = expand_symbols_multilingual(text, lang=lang)
|
||||||
|
text = collapse_whitespace(text)
|
||||||
|
return text
|
||||||
|
|
||||||
|
|
||||||
|
def basic_cleaners(text):
|
||||||
|
"""Basic pipeline that lowercases and collapses whitespace without transliteration."""
|
||||||
|
text = lowercase(text)
|
||||||
|
text = collapse_whitespace(text)
|
||||||
|
return text
|
||||||
|
|
||||||
|
|
||||||
|
def chinese_transliterate(text):
|
||||||
|
return "".join(
|
||||||
|
[p[0] for p in pypinyin.pinyin(text, style=pypinyin.Style.TONE3, heteronym=False, neutral_tone_with_five=True)]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def japanese_cleaners(text, katsu):
|
||||||
|
text = katsu.romaji(text)
|
||||||
|
text = lowercase(text)
|
||||||
|
return text
|
||||||
|
|
||||||
|
|
||||||
|
def korean_transliterate(text):
|
||||||
|
r = Transliter(academic)
|
||||||
|
return r.translit(text)
|
||||||
|
|
||||||
|
|
||||||
|
DEFAULT_VOCAB_FILE = os.path.join(os.path.dirname(os.path.realpath(__file__)), "../data/tokenizer.json")
|
||||||
|
|
||||||
|
|
||||||
|
class VoiceBpeTokenizer:
|
||||||
|
def __init__(self, vocab_file=None):
|
||||||
|
self.tokenizer = None
|
||||||
|
if vocab_file is not None:
|
||||||
|
self.tokenizer = Tokenizer.from_file(vocab_file)
|
||||||
|
self.char_limits = {
|
||||||
|
"en": 250,
|
||||||
|
"de": 253,
|
||||||
|
"fr": 273,
|
||||||
|
"es": 239,
|
||||||
|
"it": 213,
|
||||||
|
"pt": 203,
|
||||||
|
"pl": 224,
|
||||||
|
"zh": 82,
|
||||||
|
"ar": 166,
|
||||||
|
"cs": 186,
|
||||||
|
"ru": 182,
|
||||||
|
"nl": 251,
|
||||||
|
"tr": 226,
|
||||||
|
"ja": 71,
|
||||||
|
"hu": 224,
|
||||||
|
"ko": 95,
|
||||||
|
}
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def katsu(self):
|
||||||
|
import cutlet
|
||||||
|
|
||||||
|
return cutlet.Cutlet()
|
||||||
|
|
||||||
|
def check_input_length(self, txt, lang):
|
||||||
|
lang = lang.split("-")[0] # remove the region
|
||||||
|
limit = self.char_limits.get(lang, 250)
|
||||||
|
if len(txt) > limit:
|
||||||
|
print(
|
||||||
|
f"[!] Warning: The text length exceeds the character limit of {limit} for language '{lang}', this might cause truncated audio."
|
||||||
|
)
|
||||||
|
|
||||||
|
def preprocess_text(self, txt, lang):
|
||||||
|
if lang in {"ar", "cs", "de", "en", "es", "fr", "hu", "it", "nl", "pl", "pt", "ru", "tr", "zh", "ko"}:
|
||||||
|
txt = multilingual_cleaners(txt, lang)
|
||||||
|
if lang == "zh":
|
||||||
|
txt = chinese_transliterate(txt)
|
||||||
|
if lang == "ko":
|
||||||
|
txt = korean_transliterate(txt)
|
||||||
|
elif lang == "ja":
|
||||||
|
txt = japanese_cleaners(txt, self.katsu)
|
||||||
|
elif lang == "hi":
|
||||||
|
# @manmay will implement this
|
||||||
|
txt = basic_cleaners(txt)
|
||||||
|
else:
|
||||||
|
raise NotImplementedError(f"Language '{lang}' is not supported.")
|
||||||
|
return txt
|
||||||
|
|
||||||
|
def encode(self, txt, lang):
|
||||||
|
lang = lang.split("-")[0] # remove the region
|
||||||
|
self.check_input_length(txt, lang)
|
||||||
|
txt = self.preprocess_text(txt, lang)
|
||||||
|
lang = "zh-cn" if lang == "zh" else lang
|
||||||
|
txt = f"[{lang}]{txt}"
|
||||||
|
txt = txt.replace(" ", "[SPACE]")
|
||||||
|
return self.tokenizer.encode(txt).ids
|
||||||
|
|
||||||
|
def decode(self, seq):
|
||||||
|
if isinstance(seq, torch.Tensor):
|
||||||
|
seq = seq.cpu().numpy()
|
||||||
|
txt = self.tokenizer.decode(seq, skip_special_tokens=False).replace(" ", "")
|
||||||
|
txt = txt.replace("[SPACE]", " ")
|
||||||
|
txt = txt.replace("[STOP]", "")
|
||||||
|
txt = txt.replace("[UNK]", "")
|
||||||
|
return txt
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return self.tokenizer.get_vocab_size()
|
||||||
|
|
||||||
|
def get_number_tokens(self):
|
||||||
|
return max(self.tokenizer.get_vocab().values()) + 1
|
||||||
|
|
||||||
|
|
||||||
|
def test_expand_numbers_multilingual():
|
||||||
|
test_cases = [
|
||||||
|
# English
|
||||||
|
("In 12.5 seconds.", "In twelve point five seconds.", "en"),
|
||||||
|
("There were 50 soldiers.", "There were fifty soldiers.", "en"),
|
||||||
|
("This is a 1st test", "This is a first test", "en"),
|
||||||
|
("That will be $20 sir.", "That will be twenty dollars sir.", "en"),
|
||||||
|
("That will be 20€ sir.", "That will be twenty euro sir.", "en"),
|
||||||
|
("That will be 20.15€ sir.", "That will be twenty euro, fifteen cents sir.", "en"),
|
||||||
|
("That's 100,000.5.", "That's one hundred thousand point five.", "en"),
|
||||||
|
# French
|
||||||
|
("En 12,5 secondes.", "En douze virgule cinq secondes.", "fr"),
|
||||||
|
("Il y avait 50 soldats.", "Il y avait cinquante soldats.", "fr"),
|
||||||
|
("Ceci est un 1er test", "Ceci est un premier test", "fr"),
|
||||||
|
("Cela vous fera $20 monsieur.", "Cela vous fera vingt dollars monsieur.", "fr"),
|
||||||
|
("Cela vous fera 20€ monsieur.", "Cela vous fera vingt euros monsieur.", "fr"),
|
||||||
|
("Cela vous fera 20,15€ monsieur.", "Cela vous fera vingt euros et quinze centimes monsieur.", "fr"),
|
||||||
|
("Ce sera 100.000,5.", "Ce sera cent mille virgule cinq.", "fr"),
|
||||||
|
# German
|
||||||
|
("In 12,5 Sekunden.", "In zwölf Komma fünf Sekunden.", "de"),
|
||||||
|
("Es gab 50 Soldaten.", "Es gab fünfzig Soldaten.", "de"),
|
||||||
|
("Dies ist ein 1. Test", "Dies ist ein erste Test", "de"), # Issue with gender
|
||||||
|
("Das macht $20 Herr.", "Das macht zwanzig Dollar Herr.", "de"),
|
||||||
|
("Das macht 20€ Herr.", "Das macht zwanzig Euro Herr.", "de"),
|
||||||
|
("Das macht 20,15€ Herr.", "Das macht zwanzig Euro und fünfzehn Cent Herr.", "de"),
|
||||||
|
# Spanish
|
||||||
|
("En 12,5 segundos.", "En doce punto cinco segundos.", "es"),
|
||||||
|
("Había 50 soldados.", "Había cincuenta soldados.", "es"),
|
||||||
|
("Este es un 1er test", "Este es un primero test", "es"),
|
||||||
|
("Eso le costará $20 señor.", "Eso le costará veinte dólares señor.", "es"),
|
||||||
|
("Eso le costará 20€ señor.", "Eso le costará veinte euros señor.", "es"),
|
||||||
|
("Eso le costará 20,15€ señor.", "Eso le costará veinte euros con quince céntimos señor.", "es"),
|
||||||
|
# Italian
|
||||||
|
("In 12,5 secondi.", "In dodici virgola cinque secondi.", "it"),
|
||||||
|
("C'erano 50 soldati.", "C'erano cinquanta soldati.", "it"),
|
||||||
|
("Questo è un 1° test", "Questo è un primo test", "it"),
|
||||||
|
("Ti costerà $20 signore.", "Ti costerà venti dollari signore.", "it"),
|
||||||
|
("Ti costerà 20€ signore.", "Ti costerà venti euro signore.", "it"),
|
||||||
|
("Ti costerà 20,15€ signore.", "Ti costerà venti euro e quindici centesimi signore.", "it"),
|
||||||
|
# Portuguese
|
||||||
|
("Em 12,5 segundos.", "Em doze vírgula cinco segundos.", "pt"),
|
||||||
|
("Havia 50 soldados.", "Havia cinquenta soldados.", "pt"),
|
||||||
|
("Este é um 1º teste", "Este é um primeiro teste", "pt"),
|
||||||
|
("Isso custará $20 senhor.", "Isso custará vinte dólares senhor.", "pt"),
|
||||||
|
("Isso custará 20€ senhor.", "Isso custará vinte euros senhor.", "pt"),
|
||||||
|
(
|
||||||
|
"Isso custará 20,15€ senhor.",
|
||||||
|
"Isso custará vinte euros e quinze cêntimos senhor.",
|
||||||
|
"pt",
|
||||||
|
), # "cêntimos" should be "centavos" num2words issue
|
||||||
|
# Polish
|
||||||
|
("W 12,5 sekundy.", "W dwanaście przecinek pięć sekundy.", "pl"),
|
||||||
|
("Było 50 żołnierzy.", "Było pięćdziesiąt żołnierzy.", "pl"),
|
||||||
|
("To będzie kosztować 20€ panie.", "To będzie kosztować dwadzieścia euro panie.", "pl"),
|
||||||
|
("To będzie kosztować 20,15€ panie.", "To będzie kosztować dwadzieścia euro, piętnaście centów panie.", "pl"),
|
||||||
|
# Arabic
|
||||||
|
("في الـ 12,5 ثانية.", "في الـ اثنا عشر , خمسون ثانية.", "ar"),
|
||||||
|
("كان هناك 50 جنديًا.", "كان هناك خمسون جنديًا.", "ar"),
|
||||||
|
# ("ستكون النتيجة $20 يا سيد.", 'ستكون النتيجة عشرون دولار يا سيد.', 'ar'), # $ and € are mising from num2words
|
||||||
|
# ("ستكون النتيجة 20€ يا سيد.", 'ستكون النتيجة عشرون يورو يا سيد.', 'ar'),
|
||||||
|
# Czech
|
||||||
|
("Za 12,5 vteřiny.", "Za dvanáct celá pět vteřiny.", "cs"),
|
||||||
|
("Bylo tam 50 vojáků.", "Bylo tam padesát vojáků.", "cs"),
|
||||||
|
("To bude stát 20€ pane.", "To bude stát dvacet euro pane.", "cs"),
|
||||||
|
("To bude 20.15€ pane.", "To bude dvacet euro, patnáct centů pane.", "cs"),
|
||||||
|
# Russian
|
||||||
|
("Через 12.5 секунды.", "Через двенадцать запятая пять секунды.", "ru"),
|
||||||
|
("Там было 50 солдат.", "Там было пятьдесят солдат.", "ru"),
|
||||||
|
("Это будет 20.15€ сэр.", "Это будет двадцать евро, пятнадцать центов сэр.", "ru"),
|
||||||
|
("Это будет стоить 20€ господин.", "Это будет стоить двадцать евро господин.", "ru"),
|
||||||
|
# Dutch
|
||||||
|
("In 12,5 seconden.", "In twaalf komma vijf seconden.", "nl"),
|
||||||
|
("Er waren 50 soldaten.", "Er waren vijftig soldaten.", "nl"),
|
||||||
|
("Dat wordt dan $20 meneer.", "Dat wordt dan twintig dollar meneer.", "nl"),
|
||||||
|
("Dat wordt dan 20€ meneer.", "Dat wordt dan twintig euro meneer.", "nl"),
|
||||||
|
# Chinese (Simplified)
|
||||||
|
("在12.5秒内", "在十二点五秒内", "zh"),
|
||||||
|
("有50名士兵", "有五十名士兵", "zh"),
|
||||||
|
# ("那将是$20先生", '那将是二十美元先生', 'zh'), currency doesn't work
|
||||||
|
# ("那将是20€先生", '那将是二十欧元先生', 'zh'),
|
||||||
|
# Turkish
|
||||||
|
# ("12,5 saniye içinde.", 'On iki virgül beş saniye içinde.', 'tr'), # decimal doesn't work for TR
|
||||||
|
("50 asker vardı.", "elli asker vardı.", "tr"),
|
||||||
|
("Bu 1. test", "Bu birinci test", "tr"),
|
||||||
|
# ("Bu 100.000,5.", 'Bu yüz bin virgül beş.', 'tr'),
|
||||||
|
# Hungarian
|
||||||
|
("12,5 másodperc alatt.", "tizenkettő egész öt tized másodperc alatt.", "hu"),
|
||||||
|
("50 katona volt.", "ötven katona volt.", "hu"),
|
||||||
|
("Ez az 1. teszt", "Ez az első teszt", "hu"),
|
||||||
|
# Korean
|
||||||
|
("12.5 초 안에.", "십이 점 다섯 초 안에.", "ko"),
|
||||||
|
("50 명의 병사가 있었다.", "오십 명의 병사가 있었다.", "ko"),
|
||||||
|
("이것은 1 번째 테스트입니다", "이것은 첫 번째 테스트입니다", "ko"),
|
||||||
|
]
|
||||||
|
for a, b, lang in test_cases:
|
||||||
|
out = expand_numbers_multilingual(a, lang=lang)
|
||||||
|
assert out == b, f"'{out}' vs '{b}'"
|
||||||
|
|
||||||
|
|
||||||
|
def test_abbreviations_multilingual():
|
||||||
|
test_cases = [
|
||||||
|
# English
|
||||||
|
("Hello Mr. Smith.", "Hello mister Smith.", "en"),
|
||||||
|
("Dr. Jones is here.", "doctor Jones is here.", "en"),
|
||||||
|
# Spanish
|
||||||
|
("Hola Sr. Garcia.", "Hola señor Garcia.", "es"),
|
||||||
|
("La Dra. Martinez es muy buena.", "La doctora Martinez es muy buena.", "es"),
|
||||||
|
# French
|
||||||
|
("Bonjour Mr. Dupond.", "Bonjour monsieur Dupond.", "fr"),
|
||||||
|
("Mme. Moreau est absente aujourd'hui.", "madame Moreau est absente aujourd'hui.", "fr"),
|
||||||
|
# German
|
||||||
|
("Frau Dr. Müller ist sehr klug.", "Frau doktor Müller ist sehr klug.", "de"),
|
||||||
|
# Portuguese
|
||||||
|
("Olá Sr. Silva.", "Olá senhor Silva.", "pt"),
|
||||||
|
("Dra. Costa, você está disponível?", "doutora Costa, você está disponível?", "pt"),
|
||||||
|
# Italian
|
||||||
|
("Buongiorno, Sig. Rossi.", "Buongiorno, signore Rossi.", "it"),
|
||||||
|
# ("Sig.ra Bianchi, posso aiutarti?", 'signora Bianchi, posso aiutarti?', 'it'), # Issue with matching that pattern
|
||||||
|
# Polish
|
||||||
|
("Dzień dobry, P. Kowalski.", "Dzień dobry, pani Kowalski.", "pl"),
|
||||||
|
("M. Nowak, czy mogę zadać pytanie?", "pan Nowak, czy mogę zadać pytanie?", "pl"),
|
||||||
|
# Czech
|
||||||
|
("P. Novák", "pan Novák", "cs"),
|
||||||
|
("Dr. Vojtěch", "doktor Vojtěch", "cs"),
|
||||||
|
# Dutch
|
||||||
|
("Dhr. Jansen", "de heer Jansen", "nl"),
|
||||||
|
("Mevr. de Vries", "mevrouw de Vries", "nl"),
|
||||||
|
# Russian
|
||||||
|
("Здравствуйте Г-н Иванов.", "Здравствуйте господин Иванов.", "ru"),
|
||||||
|
("Д-р Смирнов здесь, чтобы увидеть вас.", "доктор Смирнов здесь, чтобы увидеть вас.", "ru"),
|
||||||
|
# Turkish
|
||||||
|
("Merhaba B. Yılmaz.", "Merhaba bay Yılmaz.", "tr"),
|
||||||
|
("Dr. Ayşe burada.", "doktor Ayşe burada.", "tr"),
|
||||||
|
# Hungarian
|
||||||
|
("Dr. Szabó itt van.", "doktor Szabó itt van.", "hu"),
|
||||||
|
]
|
||||||
|
|
||||||
|
for a, b, lang in test_cases:
|
||||||
|
out = expand_abbreviations_multilingual(a, lang=lang)
|
||||||
|
assert out == b, f"'{out}' vs '{b}'"
|
||||||
|
|
||||||
|
|
||||||
|
def test_symbols_multilingual():
|
||||||
|
test_cases = [
|
||||||
|
("I have 14% battery", "I have 14 percent battery", "en"),
|
||||||
|
("Te veo @ la fiesta", "Te veo arroba la fiesta", "es"),
|
||||||
|
("J'ai 14° de fièvre", "J'ai 14 degrés de fièvre", "fr"),
|
||||||
|
("Die Rechnung beträgt £ 20", "Die Rechnung beträgt pfund 20", "de"),
|
||||||
|
("O meu email é ana&joao@gmail.com", "O meu email é ana e joao arroba gmail.com", "pt"),
|
||||||
|
("linguaggio di programmazione C#", "linguaggio di programmazione C cancelletto", "it"),
|
||||||
|
("Moja temperatura to 36.6°", "Moja temperatura to 36.6 stopnie", "pl"),
|
||||||
|
("Mám 14% baterie", "Mám 14 procento baterie", "cs"),
|
||||||
|
("Těším se na tebe @ party", "Těším se na tebe na party", "cs"),
|
||||||
|
("У меня 14% заряда", "У меня 14 процентов заряда", "ru"),
|
||||||
|
("Я буду @ дома", "Я буду собака дома", "ru"),
|
||||||
|
("Ik heb 14% batterij", "Ik heb 14 procent batterij", "nl"),
|
||||||
|
("Ik zie je @ het feest", "Ik zie je bij het feest", "nl"),
|
||||||
|
("لدي 14% في البطارية", "لدي 14 في المئة في البطارية", "ar"),
|
||||||
|
("我的电量为 14%", "我的电量为 14 百分之", "zh"),
|
||||||
|
("Pilim %14 dolu.", "Pilim yüzde 14 dolu.", "tr"),
|
||||||
|
("Az akkumulátorom töltöttsége 14%", "Az akkumulátorom töltöttsége 14 százalék", "hu"),
|
||||||
|
("배터리 잔량이 14%입니다.", "배터리 잔량이 14 퍼센트입니다.", "ko"),
|
||||||
|
]
|
||||||
|
|
||||||
|
for a, b, lang in test_cases:
|
||||||
|
out = expand_symbols_multilingual(a, lang=lang)
|
||||||
|
assert out == b, f"'{out}' vs '{b}'"
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
test_expand_numbers_multilingual()
|
||||||
|
test_abbreviations_multilingual()
|
||||||
|
test_symbols_multilingual()
|
||||||
@@ -0,0 +1,173 @@
|
|||||||
|
absl-py==2.1.0
|
||||||
|
aiofiles==23.2.1
|
||||||
|
aiohttp==3.9.3
|
||||||
|
aiosignal==1.3.1
|
||||||
|
altair==5.2.0
|
||||||
|
annotated-types==0.6.0
|
||||||
|
anyascii==0.3.2
|
||||||
|
anyio==4.3.0
|
||||||
|
attrs==23.2.0
|
||||||
|
audioread==3.0.1
|
||||||
|
av==11.0.0
|
||||||
|
Babel==2.14.0
|
||||||
|
bangla==0.0.2
|
||||||
|
blinker==1.7.0
|
||||||
|
blis==0.7.11
|
||||||
|
bnnumerizer==0.0.2
|
||||||
|
bnunicodenormalizer==0.1.6
|
||||||
|
catalogue==2.0.10
|
||||||
|
certifi==2024.2.2
|
||||||
|
cffi==1.16.0
|
||||||
|
charset-normalizer==3.3.2
|
||||||
|
click==8.1.7
|
||||||
|
cloudpathlib==0.16.0
|
||||||
|
colorama==0.4.6
|
||||||
|
coloredlogs==15.0.1
|
||||||
|
confection==0.1.4
|
||||||
|
contourpy==1.2.0
|
||||||
|
coqpit==0.0.17
|
||||||
|
ctranslate2==4.1.0
|
||||||
|
cutlet==0.4.0
|
||||||
|
cycler==0.12.1
|
||||||
|
cymem==2.0.8
|
||||||
|
Cython==3.0.9
|
||||||
|
dateparser==1.1.8
|
||||||
|
decorator==5.1.1
|
||||||
|
docopt==0.6.2
|
||||||
|
einops==0.7.0
|
||||||
|
encodec==0.1.1
|
||||||
|
exceptiongroup
|
||||||
|
fastapi==0.110.0
|
||||||
|
faster-whisper==1.0.1
|
||||||
|
ffmpy==0.3.2
|
||||||
|
filelock==3.13.3
|
||||||
|
Flask==3.0.2
|
||||||
|
flatbuffers==24.3.25
|
||||||
|
fonttools==4.50.0
|
||||||
|
frozenlist==1.4.1
|
||||||
|
fsspec==2024.3.1
|
||||||
|
fugashi==1.3.1
|
||||||
|
fuzzywuzzy>=0.18.0
|
||||||
|
g2pkk==0.1.2
|
||||||
|
gradio==3.50.2
|
||||||
|
gradio_client==0.6.1
|
||||||
|
grpcio==1.62.1
|
||||||
|
gruut==2.2.3
|
||||||
|
gruut-ipa==0.13.0
|
||||||
|
gruut-lang-de==2.0.0
|
||||||
|
gruut-lang-en==2.0.0
|
||||||
|
gruut-lang-es==2.0.0
|
||||||
|
gruut-lang-fr==2.0.2
|
||||||
|
h11==0.14.0
|
||||||
|
hangul-romanize==0.1.0
|
||||||
|
httpcore==1.0.4
|
||||||
|
httpx==0.27.0
|
||||||
|
huggingface-hub==0.22.1
|
||||||
|
humanfriendly==10.0
|
||||||
|
idna==3.6
|
||||||
|
importlib_metadata==7.1.0
|
||||||
|
importlib_resources==6.4.0
|
||||||
|
inflect==7.0.0
|
||||||
|
itsdangerous==2.1.2
|
||||||
|
jaconv==0.3.4
|
||||||
|
jamo==0.4.1
|
||||||
|
jieba==0.42.1
|
||||||
|
Jinja2==3.1.3
|
||||||
|
joblib==1.3.2
|
||||||
|
jsonlines==1.2.0
|
||||||
|
jsonschema==4.21.1
|
||||||
|
jsonschema-specifications==2023.12.1
|
||||||
|
kiwisolver==1.4.5
|
||||||
|
langcodes==3.3.0
|
||||||
|
lazy_loader==0.3
|
||||||
|
librosa==0.10.1
|
||||||
|
llvmlite==0.42.0
|
||||||
|
Markdown==3.6
|
||||||
|
MarkupSafe==2.1.5
|
||||||
|
matplotlib==3.8.3
|
||||||
|
mojimoji==0.0.13
|
||||||
|
mpmath==1.3.0
|
||||||
|
msgpack==1.0.8
|
||||||
|
multidict==6.0.5
|
||||||
|
murmurhash==1.0.10
|
||||||
|
networkx==2.8.8
|
||||||
|
nltk==3.8.1
|
||||||
|
num2words==0.5.13
|
||||||
|
numba==0.59.1
|
||||||
|
numpy==1.26.4
|
||||||
|
nvidia-cublas-cu11>=11.11.3.6
|
||||||
|
nvidia-cudnn-cu11>=9.0.0.312
|
||||||
|
onnxruntime==1.17.1
|
||||||
|
orjson==3.9.15
|
||||||
|
packaging==24.0
|
||||||
|
pandas==1.5.3
|
||||||
|
pillow==10.2.0
|
||||||
|
platformdirs==4.2.0
|
||||||
|
pooch==1.8.1
|
||||||
|
preshed==3.0.9
|
||||||
|
protobuf==5.26.0
|
||||||
|
psutil==5.9.8
|
||||||
|
pycparser==2.21
|
||||||
|
pydantic==2.6.4
|
||||||
|
pydantic_core==2.16.3
|
||||||
|
pydub==0.25.1
|
||||||
|
pynndescent==0.5.11
|
||||||
|
pyparsing==3.1.2
|
||||||
|
pypinyin==0.51.0
|
||||||
|
pyreadline3==3.4.1
|
||||||
|
pysbd==0.3.4
|
||||||
|
python-crfsuite==0.9.10
|
||||||
|
python-dateutil==2.9.0.post0
|
||||||
|
python-Levenshtein>=0.25.0
|
||||||
|
python-multipart==0.0.9
|
||||||
|
pytz==2024.1
|
||||||
|
PyYAML==6.0.1
|
||||||
|
referencing==0.34.0
|
||||||
|
regex==2023.12.25
|
||||||
|
requests==2.31.0
|
||||||
|
rpds-py==0.18.0
|
||||||
|
safetensors==0.4.2
|
||||||
|
scikit-learn==1.4.1.post1
|
||||||
|
scipy==1.12.0
|
||||||
|
semantic-version==2.10.0
|
||||||
|
six==1.16.0
|
||||||
|
smart-open==6.4.0
|
||||||
|
sniffio==1.3.1
|
||||||
|
sounddevice==0.4.6
|
||||||
|
soundfile==0.12.1
|
||||||
|
soxr==0.3.7
|
||||||
|
spacy==3.7.4
|
||||||
|
spacy-legacy==3.0.12
|
||||||
|
spacy-loggers==1.0.5
|
||||||
|
srsly==2.4.8
|
||||||
|
starlette==0.36.3
|
||||||
|
SudachiDict-core==20240109
|
||||||
|
SudachiPy==0.6.8
|
||||||
|
sympy==1.12
|
||||||
|
tensorboard==2.16.2
|
||||||
|
tensorboard-data-server==0.7.2
|
||||||
|
thinc==8.2.3
|
||||||
|
threadpoolctl==3.4.0
|
||||||
|
tokenizers==0.15.2
|
||||||
|
toolz==0.12.1
|
||||||
|
torch>=2.2.0
|
||||||
|
torchaudio>=2.2.0
|
||||||
|
tqdm==4.66.2
|
||||||
|
trainer==0.0.36
|
||||||
|
transformers==4.39.1
|
||||||
|
TTS==0.22.0
|
||||||
|
typer==0.9.4
|
||||||
|
typing_extensions==4.10.0
|
||||||
|
tzdata==2024.1
|
||||||
|
tzlocal==5.2
|
||||||
|
umap-learn==0.5.5
|
||||||
|
Unidecode==1.3.8
|
||||||
|
unidic-lite==1.0.8
|
||||||
|
urllib3==2.2.1
|
||||||
|
uvicorn==0.29.0
|
||||||
|
wasabi==1.1.2
|
||||||
|
weasel==0.3.4
|
||||||
|
websockets==11.0.3
|
||||||
|
Werkzeug==3.0.1
|
||||||
|
yarl==1.9.4
|
||||||
|
zipp==3.18.1
|
||||||
@@ -0,0 +1,171 @@
|
|||||||
|
absl-py==2.1.0
|
||||||
|
aiofiles==23.2.1
|
||||||
|
aiohttp==3.9.3
|
||||||
|
aiosignal==1.3.1
|
||||||
|
altair==5.2.0
|
||||||
|
annotated-types==0.6.0
|
||||||
|
anyascii==0.3.2
|
||||||
|
anyio==4.3.0
|
||||||
|
attrs==23.2.0
|
||||||
|
audioread==3.0.1
|
||||||
|
av==11.0.0
|
||||||
|
Babel==2.14.0
|
||||||
|
bangla==0.0.2
|
||||||
|
blinker==1.7.0
|
||||||
|
blis==0.7.11
|
||||||
|
bnnumerizer==0.0.2
|
||||||
|
bnunicodenormalizer==0.1.6
|
||||||
|
catalogue==2.0.10
|
||||||
|
certifi==2024.2.2
|
||||||
|
cffi==1.16.0
|
||||||
|
charset-normalizer==3.3.2
|
||||||
|
click==8.1.7
|
||||||
|
cloudpathlib==0.16.0
|
||||||
|
colorama==0.4.6
|
||||||
|
coloredlogs==15.0.1
|
||||||
|
confection==0.1.4
|
||||||
|
contourpy==1.2.0
|
||||||
|
coqpit==0.0.17
|
||||||
|
ctranslate2==4.1.0
|
||||||
|
cutlet==0.4.0
|
||||||
|
cycler==0.12.1
|
||||||
|
cymem==2.0.8
|
||||||
|
Cython==3.0.9
|
||||||
|
dateparser==1.1.8
|
||||||
|
decorator==5.1.1
|
||||||
|
docopt==0.6.2
|
||||||
|
einops==0.7.0
|
||||||
|
encodec==0.1.1
|
||||||
|
fastapi==0.110.0
|
||||||
|
faster-whisper==1.0.1
|
||||||
|
ffmpy==0.3.2
|
||||||
|
filelock==3.13.3
|
||||||
|
Flask==3.0.2
|
||||||
|
flatbuffers==24.3.25
|
||||||
|
fonttools==4.50.0
|
||||||
|
frozenlist==1.4.1
|
||||||
|
fsspec==2024.3.1
|
||||||
|
fugashi==1.3.1
|
||||||
|
fuzzywuzzy>=0.18.0
|
||||||
|
g2pkk==0.1.2
|
||||||
|
gradio==3.50.2
|
||||||
|
gradio_client==0.6.1
|
||||||
|
grpcio==1.62.1
|
||||||
|
gruut==2.2.3
|
||||||
|
gruut-ipa==0.13.0
|
||||||
|
gruut-lang-de==2.0.0
|
||||||
|
gruut-lang-en==2.0.0
|
||||||
|
gruut-lang-es==2.0.0
|
||||||
|
gruut-lang-fr==2.0.2
|
||||||
|
h11==0.14.0
|
||||||
|
hangul-romanize==0.1.0
|
||||||
|
httpcore==1.0.4
|
||||||
|
httpx==0.27.0
|
||||||
|
huggingface-hub==0.22.1
|
||||||
|
humanfriendly==10.0
|
||||||
|
idna==3.6
|
||||||
|
importlib_metadata==7.1.0
|
||||||
|
importlib_resources==6.4.0
|
||||||
|
inflect==7.0.0
|
||||||
|
itsdangerous==2.1.2
|
||||||
|
jaconv==0.3.4
|
||||||
|
jamo==0.4.1
|
||||||
|
jieba==0.42.1
|
||||||
|
Jinja2==3.1.3
|
||||||
|
joblib==1.3.2
|
||||||
|
jsonlines==1.2.0
|
||||||
|
jsonschema==4.21.1
|
||||||
|
jsonschema-specifications==2023.12.1
|
||||||
|
kiwisolver==1.4.5
|
||||||
|
langcodes==3.3.0
|
||||||
|
lazy_loader==0.3
|
||||||
|
librosa==0.10.1
|
||||||
|
llvmlite==0.42.0
|
||||||
|
Markdown==3.6
|
||||||
|
MarkupSafe==2.1.5
|
||||||
|
matplotlib==3.8.3
|
||||||
|
mojimoji==0.0.13
|
||||||
|
mpmath==1.3.0
|
||||||
|
msgpack==1.0.8
|
||||||
|
multidict==6.0.5
|
||||||
|
murmurhash==1.0.10
|
||||||
|
networkx==2.8.8
|
||||||
|
nltk==3.8.1
|
||||||
|
num2words==0.5.13
|
||||||
|
numba==0.59.1
|
||||||
|
numpy>=1.17.0,<1.29.0
|
||||||
|
nvidia-cublas-cu11>=11.11.3.6
|
||||||
|
nvidia-cudnn-cu11>=9.0.0.312
|
||||||
|
onnxruntime==1.17.1
|
||||||
|
orjson==3.9.15
|
||||||
|
packaging==24.0
|
||||||
|
pandas==1.5.3
|
||||||
|
pillow==10.2.0
|
||||||
|
platformdirs==4.2.0
|
||||||
|
pooch==1.8.1
|
||||||
|
preshed==3.0.9
|
||||||
|
protobuf==5.26.0
|
||||||
|
psutil==5.9.8
|
||||||
|
pycparser==2.21
|
||||||
|
pydantic==2.6.4
|
||||||
|
pydantic_core==2.16.3
|
||||||
|
pydub==0.25.1
|
||||||
|
pynndescent==0.5.11
|
||||||
|
pyparsing==3.1.2
|
||||||
|
pypinyin==0.51.0
|
||||||
|
pyreadline3==3.4.1
|
||||||
|
pysbd==0.3.4
|
||||||
|
python-crfsuite==0.9.10
|
||||||
|
python-dateutil==2.9.0.post0
|
||||||
|
python-Levenshtein>=0.25.0
|
||||||
|
python-multipart==0.0.9
|
||||||
|
pytz==2024.1
|
||||||
|
PyYAML==6.0.1
|
||||||
|
referencing==0.34.0
|
||||||
|
regex==2023.12.25
|
||||||
|
requests==2.31.0
|
||||||
|
rpds-py==0.18.0
|
||||||
|
safetensors==0.4.2
|
||||||
|
scikit-learn==1.4.1.post1
|
||||||
|
scipy==1.12.0
|
||||||
|
semantic-version==2.10.0
|
||||||
|
six==1.16.0
|
||||||
|
smart-open==6.4.0
|
||||||
|
sniffio==1.3.1
|
||||||
|
sounddevice==0.4.6
|
||||||
|
soundfile==0.12.1
|
||||||
|
soxr==0.3.7
|
||||||
|
spacy==3.7.4
|
||||||
|
spacy-legacy==3.0.12
|
||||||
|
spacy-loggers==1.0.5
|
||||||
|
srsly==2.4.8
|
||||||
|
starlette==0.36.3
|
||||||
|
SudachiDict-core==20240109
|
||||||
|
SudachiPy==0.6.8
|
||||||
|
sympy==1.12
|
||||||
|
tensorboard==2.16.2
|
||||||
|
tensorboard-data-server==0.7.2
|
||||||
|
thinc==8.2.3
|
||||||
|
threadpoolctl==3.4.0
|
||||||
|
tokenizers==0.15.2
|
||||||
|
toolz==0.12.1
|
||||||
|
torch>=2.2.0
|
||||||
|
torchaudio>=2.2.0
|
||||||
|
tqdm==4.66.2
|
||||||
|
trainer==0.0.36
|
||||||
|
transformers==4.39.1
|
||||||
|
typer==0.9.4
|
||||||
|
typing_extensions==4.10.0
|
||||||
|
tzdata==2024.1
|
||||||
|
tzlocal==5.2
|
||||||
|
umap-learn==0.5.5
|
||||||
|
Unidecode==1.3.8
|
||||||
|
unidic-lite==1.0.8
|
||||||
|
urllib3==2.2.1
|
||||||
|
uvicorn==0.29.0
|
||||||
|
wasabi==1.1.2
|
||||||
|
weasel==0.3.4
|
||||||
|
websockets==11.0.3
|
||||||
|
Werkzeug==3.0.1
|
||||||
|
yarl==1.9.4
|
||||||
|
zipp==3.18.1
|
||||||
@@ -0,0 +1,172 @@
|
|||||||
|
absl-py==2.1.0
|
||||||
|
aiofiles==23.2.1
|
||||||
|
aiohttp==3.9.3
|
||||||
|
aiosignal==1.3.1
|
||||||
|
altair==5.2.0
|
||||||
|
annotated-types==0.6.0
|
||||||
|
anyascii==0.3.2
|
||||||
|
anyio==4.3.0
|
||||||
|
attrs==23.2.0
|
||||||
|
audioread==3.0.1
|
||||||
|
av==11.0.0
|
||||||
|
Babel==2.14.0
|
||||||
|
bangla==0.0.2
|
||||||
|
blinker==1.7.0
|
||||||
|
blis==0.7.11
|
||||||
|
bnnumerizer==0.0.2
|
||||||
|
bnunicodenormalizer==0.1.6
|
||||||
|
catalogue==2.0.10
|
||||||
|
certifi==2024.2.2
|
||||||
|
cffi==1.16.0
|
||||||
|
charset-normalizer==3.3.2
|
||||||
|
click==8.1.7
|
||||||
|
cloudpathlib==0.16.0
|
||||||
|
colorama==0.4.6
|
||||||
|
coloredlogs==15.0.1
|
||||||
|
confection==0.1.4
|
||||||
|
contourpy==1.2.0
|
||||||
|
coqpit==0.0.17
|
||||||
|
ctranslate2==4.1.0
|
||||||
|
cutlet==0.4.0
|
||||||
|
cycler==0.12.1
|
||||||
|
cymem==2.0.8
|
||||||
|
Cython==3.0.9
|
||||||
|
dateparser==1.1.8
|
||||||
|
decorator==5.1.1
|
||||||
|
docopt==0.6.2
|
||||||
|
einops==0.7.0
|
||||||
|
encodec==0.1.1
|
||||||
|
fastapi==0.110.0
|
||||||
|
faster-whisper==1.0.1
|
||||||
|
ffmpy==0.3.2
|
||||||
|
filelock==3.13.3
|
||||||
|
Flask==3.0.2
|
||||||
|
flatbuffers==24.3.25
|
||||||
|
fonttools==4.50.0
|
||||||
|
frozenlist==1.4.1
|
||||||
|
fsspec==2024.3.1
|
||||||
|
fugashi==1.3.1
|
||||||
|
fuzzywuzzy>=0.18.0
|
||||||
|
g2pkk==0.1.2
|
||||||
|
gradio==3.50.2
|
||||||
|
gradio_client==0.6.1
|
||||||
|
grpcio==1.62.1
|
||||||
|
gruut==2.2.3
|
||||||
|
gruut-ipa==0.13.0
|
||||||
|
gruut-lang-de==2.0.0
|
||||||
|
gruut-lang-en==2.0.0
|
||||||
|
gruut-lang-es==2.0.0
|
||||||
|
gruut-lang-fr==2.0.2
|
||||||
|
h11==0.14.0
|
||||||
|
hangul-romanize==0.1.0
|
||||||
|
httpcore==1.0.4
|
||||||
|
httpx==0.27.0
|
||||||
|
huggingface-hub==0.22.1
|
||||||
|
humanfriendly==10.0
|
||||||
|
idna==3.6
|
||||||
|
importlib_metadata==7.1.0
|
||||||
|
importlib_resources==6.4.0
|
||||||
|
inflect==7.0.0
|
||||||
|
itsdangerous==2.1.2
|
||||||
|
jaconv==0.3.4
|
||||||
|
jamo==0.4.1
|
||||||
|
jieba==0.42.1
|
||||||
|
Jinja2==3.1.3
|
||||||
|
joblib==1.3.2
|
||||||
|
jsonlines==1.2.0
|
||||||
|
jsonschema==4.21.1
|
||||||
|
jsonschema-specifications==2023.12.1
|
||||||
|
kiwisolver==1.4.5
|
||||||
|
langcodes==3.3.0
|
||||||
|
lazy_loader==0.3
|
||||||
|
librosa==0.10.1
|
||||||
|
llvmlite==0.42.0
|
||||||
|
Markdown==3.6
|
||||||
|
MarkupSafe==2.1.5
|
||||||
|
matplotlib==3.8.3
|
||||||
|
mojimoji==0.0.13
|
||||||
|
mpmath==1.3.0
|
||||||
|
msgpack==1.0.8
|
||||||
|
multidict==6.0.5
|
||||||
|
murmurhash==1.0.10
|
||||||
|
networkx==2.8.8
|
||||||
|
nltk==3.8.1
|
||||||
|
num2words==0.5.13
|
||||||
|
numba==0.59.1
|
||||||
|
numpy==1.26.4
|
||||||
|
nvidia-cublas-cu11>=11.11.3.6
|
||||||
|
nvidia-cudnn-cu11>=9.0.0.312
|
||||||
|
onnxruntime==1.17.1
|
||||||
|
orjson==3.9.15
|
||||||
|
packaging==24.0
|
||||||
|
pandas==1.5.3
|
||||||
|
pillow==10.2.0
|
||||||
|
platformdirs==4.2.0
|
||||||
|
pooch==1.8.1
|
||||||
|
preshed==3.0.9
|
||||||
|
protobuf==5.26.0
|
||||||
|
psutil==5.9.8
|
||||||
|
pycparser==2.21
|
||||||
|
pydantic==2.6.4
|
||||||
|
pydantic_core==2.16.3
|
||||||
|
pydub==0.25.1
|
||||||
|
pynndescent==0.5.11
|
||||||
|
pyparsing==3.1.2
|
||||||
|
pypinyin==0.51.0
|
||||||
|
pyreadline3==3.4.1
|
||||||
|
pysbd==0.3.4
|
||||||
|
python-crfsuite==0.9.10
|
||||||
|
python-dateutil==2.9.0.post0
|
||||||
|
python-Levenshtein>=0.25.0
|
||||||
|
python-multipart==0.0.9
|
||||||
|
pytz==2024.1
|
||||||
|
PyYAML==6.0.1
|
||||||
|
referencing==0.34.0
|
||||||
|
regex==2023.12.25
|
||||||
|
requests==2.31.0
|
||||||
|
rpds-py==0.18.0
|
||||||
|
safetensors==0.4.2
|
||||||
|
scikit-learn==1.4.1.post1
|
||||||
|
scipy==1.12.0
|
||||||
|
semantic-version==2.10.0
|
||||||
|
six==1.16.0
|
||||||
|
smart-open==6.4.0
|
||||||
|
sniffio==1.3.1
|
||||||
|
sounddevice==0.4.6
|
||||||
|
soundfile==0.12.1
|
||||||
|
soxr==0.3.7
|
||||||
|
spacy==3.7.4
|
||||||
|
spacy-legacy==3.0.12
|
||||||
|
spacy-loggers==1.0.5
|
||||||
|
srsly==2.4.8
|
||||||
|
starlette==0.36.3
|
||||||
|
SudachiDict-core==20240109
|
||||||
|
SudachiPy==0.6.8
|
||||||
|
sympy==1.12
|
||||||
|
tensorboard==2.16.2
|
||||||
|
tensorboard-data-server==0.7.2
|
||||||
|
thinc==8.2.3
|
||||||
|
threadpoolctl==3.4.0
|
||||||
|
tokenizers==0.15.2
|
||||||
|
toolz==0.12.1
|
||||||
|
torch>=2.2.0
|
||||||
|
torchaudio>=2.2.0
|
||||||
|
tqdm==4.66.2
|
||||||
|
trainer==0.0.36
|
||||||
|
transformers==4.39.1
|
||||||
|
TTS==0.22.0
|
||||||
|
typer==0.9.4
|
||||||
|
typing_extensions==4.10.0
|
||||||
|
tzdata==2024.1
|
||||||
|
tzlocal==5.2
|
||||||
|
umap-learn==0.5.5
|
||||||
|
Unidecode==1.3.8
|
||||||
|
unidic-lite==1.0.8
|
||||||
|
urllib3==2.2.1
|
||||||
|
uvicorn==0.29.0
|
||||||
|
wasabi==1.1.2
|
||||||
|
weasel==0.3.4
|
||||||
|
websockets==11.0.3
|
||||||
|
Werkzeug==3.0.1
|
||||||
|
yarl==1.9.4
|
||||||
|
zipp==3.18.1
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
numpy>=1.22.0
|
||||||
|
soundfile>=0.12.1
|
||||||
|
uvicorn>=0.24.0.post1
|
||||||
|
transformers>=4.37.1
|
||||||
|
TTS>=0.22.0
|
||||||
|
torch>=2.1.0+cu118
|
||||||
|
torchaudio>=2.1.0+cu118
|
||||||
|
fastapi>=0.104.1
|
||||||
|
Jinja2>=3.1.2
|
||||||
|
requests>=2.31.0
|
||||||
|
tqdm>=4.66.1
|
||||||
|
importlib-metadata>=4.8.1
|
||||||
|
packaging>=23.2
|
||||||
|
pydantic>=1.10.13
|
||||||
|
sounddevice>=0.4.6
|
||||||
|
python-multipart>=0.0.6
|
||||||
|
cutlet>=0.3.0
|
||||||
|
unidic-lite>=1.0.8
|
||||||
|
faster-whisper>=0.10.0
|
||||||
|
pandas>=1.5.0
|
||||||
|
nvidia-cublas-cu11>=11.11.3.6
|
||||||
|
nvidia-cudnn-cu11>=9.0.0.312
|
||||||
|
fuzzywuzzy>=0.18.0
|
||||||
|
python-Levenshtein>=0.25.0
|
||||||
|
spacy>=3.7.2
|
||||||
@@ -0,0 +1,833 @@
|
|||||||
|
import { doExtrasFetch, getApiUrl, modules } from '../../extensions.js';
|
||||||
|
import { saveTtsProviderSettings } from './index.js';
|
||||||
|
|
||||||
|
export { AllTalkTtsProvider };
|
||||||
|
|
||||||
|
class AllTalkTtsProvider {
|
||||||
|
//########//
|
||||||
|
// Config //
|
||||||
|
//########//
|
||||||
|
|
||||||
|
settings = {};
|
||||||
|
constructor() {
|
||||||
|
// Initialize with default settings if they are not already set
|
||||||
|
this.settings = {
|
||||||
|
provider_endpoint: this.settings.provider_endpoint || 'http://localhost:7851',
|
||||||
|
language: this.settings.language || 'en',
|
||||||
|
voiceMap: this.settings.voiceMap || {},
|
||||||
|
at_generation_method: this.settings.at_generation_method || 'standard_generation',
|
||||||
|
narrator_enabled: this.settings.narrator_enabled || 'false',
|
||||||
|
at_narrator_text_not_inside: this.settings.at_narrator_text_not_inside || 'narrator',
|
||||||
|
narrator_voice_gen: this.settings.narrator_voice_gen || 'female_01.wav',
|
||||||
|
finetuned_model: this.settings.finetuned_model || 'false'
|
||||||
|
};
|
||||||
|
// Separate property for dynamically updated settings from the server
|
||||||
|
this.dynamicSettings = {
|
||||||
|
modelsAvailable: [],
|
||||||
|
currentModel: '',
|
||||||
|
deepspeed_available: false,
|
||||||
|
deepSpeedEnabled: false,
|
||||||
|
lowVramEnabled: false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
ready = false;
|
||||||
|
voices = [];
|
||||||
|
separator = '. ';
|
||||||
|
audioElement = document.createElement('audio');
|
||||||
|
|
||||||
|
languageLabels = {
|
||||||
|
'Arabic': 'ar',
|
||||||
|
'Brazilian Portuguese': 'pt',
|
||||||
|
'Chinese': 'zh-cn',
|
||||||
|
'Czech': 'cs',
|
||||||
|
'Dutch': 'nl',
|
||||||
|
'English': 'en',
|
||||||
|
'French': 'fr',
|
||||||
|
'German': 'de',
|
||||||
|
'Italian': 'it',
|
||||||
|
'Polish': 'pl',
|
||||||
|
'Russian': 'ru',
|
||||||
|
'Spanish': 'es',
|
||||||
|
'Turkish': 'tr',
|
||||||
|
'Japanese': 'ja',
|
||||||
|
'Korean': 'ko',
|
||||||
|
'Hungarian': 'hu',
|
||||||
|
'Hindi': 'hi',
|
||||||
|
};
|
||||||
|
|
||||||
|
get settingsHtml() {
|
||||||
|
let html = `<div class="at-settings-separator">AllTalk Settings</div>`;
|
||||||
|
|
||||||
|
html += `<div class="at-settings-row">
|
||||||
|
|
||||||
|
<div class="at-settings-option">
|
||||||
|
<label for="at_generation_method">AllTalk TTS Generation Method</label>
|
||||||
|
<select id="at_generation_method">
|
||||||
|
<option value="standard_generation">Standard Audio Generation (AT Narrator - Optional)</option>
|
||||||
|
<option value="streaming_enabled">Streaming Audio Generation (AT Narrator - Disabled)</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
html += `<div class="at-settings-row">
|
||||||
|
|
||||||
|
<div class="at-settings-option">
|
||||||
|
<label for="at_narrator_enabled">AT Narrator</label>
|
||||||
|
<select id="at_narrator_enabled">
|
||||||
|
<option value="true">Enabled</option>
|
||||||
|
<option value="false">Disabled</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="at-settings-option">
|
||||||
|
<label for="at_narrator_text_not_inside">Text Not Inside * or " is</label>
|
||||||
|
<select id="at_narrator_text_not_inside">
|
||||||
|
<option value="narrator">Narrator</option>
|
||||||
|
<option value="character">Character</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
html += `<div class="at-settings-row">
|
||||||
|
<div class="at-settings-option">
|
||||||
|
<label for="narrator_voice">Narrator Voice</label>
|
||||||
|
<select id="narrator_voice">`;
|
||||||
|
if (this.voices) {
|
||||||
|
for (let voice of this.voices) {
|
||||||
|
html += `<option value="${voice.voice_id}">${voice.name}</option>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
html += `</select>
|
||||||
|
</div>
|
||||||
|
<div class="at-settings-option">
|
||||||
|
<label for="language_options">Language</label>
|
||||||
|
<select id="language_options">`;
|
||||||
|
for (let language in this.languageLabels) {
|
||||||
|
html += `<option value="${this.languageLabels[language]}" ${this.languageLabels[language] === this.settings?.language ? 'selected="selected"' : ''}>${language}</option>`;
|
||||||
|
}
|
||||||
|
html += `</select>
|
||||||
|
</div>
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
|
||||||
|
html += `<div class="at-model-endpoint-row">
|
||||||
|
<div class="at-model-option">
|
||||||
|
<label for="switch_model">Switch Model</label>
|
||||||
|
<select id="switch_model">
|
||||||
|
<option value="api_tts">API TTS</option>
|
||||||
|
<option value="api_local">API Local</option>
|
||||||
|
<option value="xttsv2_local">XTTSv2 Local</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="at-endpoint-option">
|
||||||
|
<label for="at_server">AllTalk Endpoint:</label>
|
||||||
|
<input id="at_server" type="text" class="text_pole" maxlength="80" value="${this.settings.provider_endpoint}"/>
|
||||||
|
</div>
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
|
||||||
|
html += `<div class="at-model-endpoint-row">
|
||||||
|
<div class="at-settings-option">
|
||||||
|
<label for="low_vram">Low VRAM</label>
|
||||||
|
<input id="low_vram" type="checkbox"/>
|
||||||
|
</div>
|
||||||
|
<div class="at-settings-option">
|
||||||
|
<label for="deepspeed">DeepSpeed</label>
|
||||||
|
<input id="deepspeed" type="checkbox"/>
|
||||||
|
</div>
|
||||||
|
<div class="at-settings-option status-option">
|
||||||
|
<span>Status: <span id="status_info">Ready</span></span>
|
||||||
|
</div>
|
||||||
|
<div class="at-settings-option empty-option">
|
||||||
|
<!-- This div remains empty for spacing -->
|
||||||
|
</div>
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
|
||||||
|
html += `<div class="at-website-row">
|
||||||
|
<div class="at-website-option">
|
||||||
|
<span>AllTalk <a target="_blank" href="${this.settings.provider_endpoint}">Config & Docs</a>.</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="at-website-option">
|
||||||
|
<span>AllTalk <a target="_blank" href="https://github.com/erew123/alltalk_tts/">Website</a>.</span>
|
||||||
|
</div>
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
html += `<div class="at-website-row">
|
||||||
|
<div class="at-website-option">
|
||||||
|
<span><strong>Text-generation-webui</strong> users - Uncheck <strong>Enable TTS</strong> in Text-generation-webui.</span>
|
||||||
|
</div>
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//#################//
|
||||||
|
// Startup ST & AT //
|
||||||
|
//#################//
|
||||||
|
|
||||||
|
async loadSettings(settings) {
|
||||||
|
updateStatus('Offline');
|
||||||
|
|
||||||
|
if (Object.keys(settings).length === 0) {
|
||||||
|
console.info('Using default AllTalk TTS Provider settings');
|
||||||
|
} else {
|
||||||
|
// Populate settings with provided values, ignoring server-provided settings
|
||||||
|
for (const key in settings) {
|
||||||
|
if (key in this.settings) {
|
||||||
|
this.settings[key] = settings[key];
|
||||||
|
} else {
|
||||||
|
console.debug(`Ignoring non-user-configurable setting: ${key}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update UI elements to reflect the loaded settings
|
||||||
|
$('#at_server').val(this.settings.provider_endpoint);
|
||||||
|
$('#language_options').val(this.settings.language);
|
||||||
|
//$('#voicemap').val(this.settings.voiceMap);
|
||||||
|
$('#at_generation_method').val(this.settings.at_generation_method);
|
||||||
|
$('#at_narrator_enabled').val(this.settings.narrator_enabled);
|
||||||
|
$('#at_narrator_text_not_inside').val(this.settings.at_narrator_text_not_inside);
|
||||||
|
$('#narrator_voice').val(this.settings.narrator_voice_gen);
|
||||||
|
|
||||||
|
console.debug('AllTalkTTS: Settings loaded');
|
||||||
|
try {
|
||||||
|
// Check if TTS provider is ready
|
||||||
|
await this.checkReady();
|
||||||
|
await this.updateSettingsFromServer(); // Fetch dynamic settings from the TTS server
|
||||||
|
await this.fetchTtsVoiceObjects(); // Fetch voices only if service is ready
|
||||||
|
this.updateNarratorVoicesDropdown();
|
||||||
|
this.updateLanguageDropdown();
|
||||||
|
this.setupEventListeners();
|
||||||
|
this.applySettingsToHTML();
|
||||||
|
updateStatus('Ready');
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error loading settings:", error);
|
||||||
|
updateStatus('Offline');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
applySettingsToHTML() {
|
||||||
|
// Apply loaded settings or use defaults
|
||||||
|
const narratorVoiceSelect = document.getElementById('narrator_voice');
|
||||||
|
const atNarratorSelect = document.getElementById('at_narrator_enabled');
|
||||||
|
const textNotInsideSelect = document.getElementById('at_narrator_text_not_inside');
|
||||||
|
const generationMethodSelect = document.getElementById('at_generation_method');
|
||||||
|
this.settings.narrator_voice = this.settings.narrator_voice_gen;
|
||||||
|
// Apply settings to Narrator Voice dropdown
|
||||||
|
if (narratorVoiceSelect && this.settings.narrator_voice) {
|
||||||
|
narratorVoiceSelect.value = this.settings.narrator_voice.replace('.wav', '');
|
||||||
|
}
|
||||||
|
// Apply settings to AT Narrator Enabled dropdown
|
||||||
|
if (atNarratorSelect) {
|
||||||
|
// Sync the state with the checkbox in index.js
|
||||||
|
const ttsPassAsterisksCheckbox = document.getElementById('tts_pass_asterisks'); // Access the checkbox from index.js
|
||||||
|
const ttsNarrateQuotedCheckbox = document.getElementById('tts_narrate_quoted'); // Access the checkbox from index.js
|
||||||
|
const ttsNarrateDialoguesCheckbox = document.getElementById('tts_narrate_dialogues'); // Access the checkbox from index.js
|
||||||
|
// Sync the state with the checkbox in index.js
|
||||||
|
if (this.settings.narrator_enabled) {
|
||||||
|
ttsPassAsterisksCheckbox.checked = false;
|
||||||
|
$('#tts_pass_asterisks').click(); // Simulate a click event
|
||||||
|
$('#tts_pass_asterisks').trigger('change');
|
||||||
|
}
|
||||||
|
if (!this.settings.narrator_enabled) {
|
||||||
|
ttsPassAsterisksCheckbox.checked = true;
|
||||||
|
$('#tts_pass_asterisks').click(); // Simulate a click event
|
||||||
|
$('#tts_pass_asterisks').trigger('change');
|
||||||
|
}
|
||||||
|
// Uncheck and set tts_narrate_quoted to false if narrator is enabled
|
||||||
|
if (this.settings.narrator_enabledd) {
|
||||||
|
ttsNarrateQuotedCheckbox.checked = true;
|
||||||
|
ttsNarrateDialoguesCheckbox.checked = true;
|
||||||
|
// Trigger click events instead of change events
|
||||||
|
$('#tts_narrate_quoted').click();
|
||||||
|
$('#tts_narrate_quoted').trigger('change');
|
||||||
|
$('#tts_narrate_dialogues').click();
|
||||||
|
$('#tts_narrate_dialogues').trigger('change');
|
||||||
|
}
|
||||||
|
atNarratorSelect.value = this.settings.narrator_enabled.toString();
|
||||||
|
this.settings.narrator_enabled = this.settings.narrator_enabled.toString();
|
||||||
|
}
|
||||||
|
// Apply settings to the Language dropdown
|
||||||
|
const languageSelect = document.getElementById('language_options');
|
||||||
|
if (languageSelect && this.settings.language) {
|
||||||
|
languageSelect.value = this.settings.language;
|
||||||
|
}
|
||||||
|
// Apply settings to Text Not Inside dropdown
|
||||||
|
if (textNotInsideSelect && this.settings.text_not_inside) {
|
||||||
|
textNotInsideSelect.value = this.settings.text_not_inside;
|
||||||
|
this.settings.at_narrator_text_not_inside = this.settings.text_not_inside;
|
||||||
|
}
|
||||||
|
// Apply settings to Generation Method dropdown
|
||||||
|
if (generationMethodSelect && this.settings.at_generation_method) {
|
||||||
|
generationMethodSelect.value = this.settings.at_generation_method;
|
||||||
|
}
|
||||||
|
// Additional logic to disable/enable dropdowns based on the selected generation method
|
||||||
|
const isStreamingEnabled = this.settings.at_generation_method === 'streaming_enabled';
|
||||||
|
if (isStreamingEnabled) {
|
||||||
|
// Disable certain dropdowns when streaming is enabled
|
||||||
|
if (atNarratorSelect) atNarratorSelect.disabled = true;
|
||||||
|
if (textNotInsideSelect) textNotInsideSelect.disabled = true;
|
||||||
|
if (narratorVoiceSelect) narratorVoiceSelect.disabled = true;
|
||||||
|
} else {
|
||||||
|
// Enable dropdowns for standard generation
|
||||||
|
if (atNarratorSelect) atNarratorSelect.disabled = false;
|
||||||
|
if (textNotInsideSelect) textNotInsideSelect.disabled = !this.settings.narrator_enabled;
|
||||||
|
if (narratorVoiceSelect) narratorVoiceSelect.disabled = !this.settings.narrator_enabled;
|
||||||
|
}
|
||||||
|
const modelSelect = document.getElementById('switch_model');
|
||||||
|
if (this.settings.finetuned_model === true) {
|
||||||
|
const ftOption = document.createElement('option');
|
||||||
|
ftOption.value = 'XTTSv2 FT';
|
||||||
|
ftOption.textContent = 'XTTSv2 FT';
|
||||||
|
modelSelect.appendChild(ftOption);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//##############################//
|
||||||
|
// Check AT Server is Available //
|
||||||
|
//##############################//
|
||||||
|
|
||||||
|
async checkReady() {
|
||||||
|
try {
|
||||||
|
const response = await fetch(`${this.settings.provider_endpoint}/api/ready`);
|
||||||
|
// Check if the HTTP request was successful
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`HTTP Error Response: ${response.status} ${response.statusText}`);
|
||||||
|
}
|
||||||
|
const statusText = await response.text();
|
||||||
|
// Check if the response is 'Ready'
|
||||||
|
if (statusText === 'Ready') {
|
||||||
|
this.ready = true; // Set the ready flag to true
|
||||||
|
console.log('TTS service is ready.');
|
||||||
|
} else {
|
||||||
|
this.ready = false;
|
||||||
|
console.log('TTS service is not ready.');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error checking TTS service readiness:', error);
|
||||||
|
this.ready = false; // Ensure ready flag is set to false in case of error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//######################//
|
||||||
|
// Get Available Voices //
|
||||||
|
//######################//
|
||||||
|
|
||||||
|
async fetchTtsVoiceObjects() {
|
||||||
|
const response = await fetch(`${this.settings.provider_endpoint}/api/voices`);
|
||||||
|
if (!response.ok) {
|
||||||
|
const errorText = await response.text();
|
||||||
|
throw new Error(`HTTP ${response.status}: ${errorText}`);
|
||||||
|
}
|
||||||
|
const data = await response.json();
|
||||||
|
const voices = data.voices.map(filename => {
|
||||||
|
const voiceName = filename.replace('.wav', '');
|
||||||
|
return {
|
||||||
|
name: voiceName,
|
||||||
|
voice_id: voiceName,
|
||||||
|
preview_url: null, // Preview URL will be dynamically generated
|
||||||
|
lang: 'en' // Default language
|
||||||
|
};
|
||||||
|
});
|
||||||
|
this.voices = voices; // Assign to the class property
|
||||||
|
return voices; // Also return this list
|
||||||
|
}
|
||||||
|
|
||||||
|
//##########################################//
|
||||||
|
// Get Current AT Server Config & Update ST //
|
||||||
|
//##########################################//
|
||||||
|
|
||||||
|
async updateSettingsFromServer() {
|
||||||
|
try {
|
||||||
|
// Fetch current settings
|
||||||
|
const response = await fetch(`${this.settings.provider_endpoint}/api/currentsettings`);
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`Failed to fetch current settings: ${response.statusText}`);
|
||||||
|
}
|
||||||
|
const currentSettings = await response.json();
|
||||||
|
// Update internal settings
|
||||||
|
this.settings.modelsAvailable = currentSettings.models_available;
|
||||||
|
this.settings.currentModel = currentSettings.current_model_loaded;
|
||||||
|
this.settings.deepspeed_available = currentSettings.deepspeed_available;
|
||||||
|
this.settings.deepSpeedEnabled = currentSettings.deepspeed_status;
|
||||||
|
this.settings.lowVramEnabled = currentSettings.low_vram_status;
|
||||||
|
this.settings.finetuned_model = currentSettings.finetuned_model
|
||||||
|
// Update HTML elements
|
||||||
|
this.updateModelDropdown();
|
||||||
|
this.updateCheckboxes();
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error updating settings from server: ${error}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//###################################################//
|
||||||
|
// Get Current AT Server Config & Update ST (Models) //
|
||||||
|
//###################################################//
|
||||||
|
|
||||||
|
updateModelDropdown() {
|
||||||
|
const modelSelect = document.getElementById('switch_model');
|
||||||
|
if (modelSelect) {
|
||||||
|
modelSelect.innerHTML = ''; // Clear existing options
|
||||||
|
this.settings.modelsAvailable.forEach(model => {
|
||||||
|
const option = document.createElement('option');
|
||||||
|
option.value = model.model_name;
|
||||||
|
option.textContent = model.model_name; // Use model_name instead of name
|
||||||
|
option.selected = model.model_name === this.settings.currentModel;
|
||||||
|
modelSelect.appendChild(option);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//#######################################################//
|
||||||
|
// Get Current AT Server Config & Update ST (DS and LVR) //
|
||||||
|
//#######################################################//
|
||||||
|
|
||||||
|
updateCheckboxes() {
|
||||||
|
const deepspeedCheckbox = document.getElementById('deepspeed');
|
||||||
|
const lowVramCheckbox = document.getElementById('low_vram');
|
||||||
|
if (lowVramCheckbox) lowVramCheckbox.checked = this.settings.lowVramEnabled;
|
||||||
|
if (deepspeedCheckbox) {
|
||||||
|
deepspeedCheckbox.checked = this.settings.deepSpeedEnabled;
|
||||||
|
deepspeedCheckbox.disabled = !this.settings.deepspeed_available; // Disable checkbox if deepspeed is not available
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//###############################################################//
|
||||||
|
// Get Current AT Server Config & Update ST (AT Narrator Voices) //
|
||||||
|
//###############################################################//
|
||||||
|
|
||||||
|
updateNarratorVoicesDropdown() {
|
||||||
|
const narratorVoiceSelect = document.getElementById('narrator_voice');
|
||||||
|
if (narratorVoiceSelect && this.voices) {
|
||||||
|
// Clear existing options
|
||||||
|
narratorVoiceSelect.innerHTML = '';
|
||||||
|
// Add new options
|
||||||
|
for (let voice of this.voices) {
|
||||||
|
const option = document.createElement('option');
|
||||||
|
option.value = voice.voice_id;
|
||||||
|
option.textContent = voice.name;
|
||||||
|
narratorVoiceSelect.appendChild(option);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//######################################################//
|
||||||
|
// Get Current AT Server Config & Update ST (Languages) //
|
||||||
|
//######################################################//
|
||||||
|
|
||||||
|
updateLanguageDropdown() {
|
||||||
|
const languageSelect = document.getElementById('language_options');
|
||||||
|
if (languageSelect) {
|
||||||
|
// Ensure default language is set
|
||||||
|
this.settings.language = this.settings.language;
|
||||||
|
|
||||||
|
languageSelect.innerHTML = '';
|
||||||
|
for (let language in this.languageLabels) {
|
||||||
|
const option = document.createElement('option');
|
||||||
|
option.value = this.languageLabels[language];
|
||||||
|
option.textContent = language;
|
||||||
|
if (this.languageLabels[language] === this.settings.language) {
|
||||||
|
option.selected = true;
|
||||||
|
}
|
||||||
|
languageSelect.appendChild(option);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//########################################//
|
||||||
|
// Start AT TTS extenstion page listeners //
|
||||||
|
//########################################//
|
||||||
|
|
||||||
|
setupEventListeners() {
|
||||||
|
|
||||||
|
let debounceTimeout;
|
||||||
|
const debounceDelay = 500; // Milliseconds
|
||||||
|
|
||||||
|
// Define the event handler function
|
||||||
|
const onModelSelectChange = async (event) => {
|
||||||
|
console.log("Model select change event triggered"); // Debugging statement
|
||||||
|
const selectedModel = event.target.value;
|
||||||
|
console.log(`Selected model: ${selectedModel}`); // Debugging statement
|
||||||
|
// Set status to Processing
|
||||||
|
updateStatus('Processing');
|
||||||
|
try {
|
||||||
|
const response = await fetch(`${this.settings.provider_endpoint}/api/reload?tts_method=${encodeURIComponent(selectedModel)}`, {
|
||||||
|
method: 'POST'
|
||||||
|
});
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`HTTP Error: ${response.status}`);
|
||||||
|
}
|
||||||
|
const data = await response.json();
|
||||||
|
console.log("POST response data:", data); // Debugging statement
|
||||||
|
// Set status to Ready if successful
|
||||||
|
updateStatus('Ready');
|
||||||
|
} catch (error) {
|
||||||
|
console.error("POST request error:", error); // Debugging statement
|
||||||
|
// Set status to Error in case of failure
|
||||||
|
updateStatus('Error');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle response or error
|
||||||
|
};
|
||||||
|
|
||||||
|
const debouncedModelSelectChange = (event) => {
|
||||||
|
clearTimeout(debounceTimeout);
|
||||||
|
debounceTimeout = setTimeout(() => {
|
||||||
|
onModelSelectChange(event);
|
||||||
|
}, debounceDelay);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Switch Model Listener
|
||||||
|
const modelSelect = document.getElementById('switch_model');
|
||||||
|
if (modelSelect) {
|
||||||
|
// Remove the event listener if it was previously added
|
||||||
|
modelSelect.removeEventListener('change', debouncedModelSelectChange);
|
||||||
|
// Add the debounced event listener
|
||||||
|
modelSelect.addEventListener('change', debouncedModelSelectChange);
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepSpeed Listener
|
||||||
|
const deepspeedCheckbox = document.getElementById('deepspeed');
|
||||||
|
if (deepspeedCheckbox) {
|
||||||
|
deepspeedCheckbox.addEventListener('change', async (event) => {
|
||||||
|
const deepSpeedValue = event.target.checked ? 'True' : 'False';
|
||||||
|
// Set status to Processing
|
||||||
|
updateStatus('Processing');
|
||||||
|
try {
|
||||||
|
const response = await fetch(`${this.settings.provider_endpoint}/api/deepspeed?new_deepspeed_value=${deepSpeedValue}`, {
|
||||||
|
method: 'POST'
|
||||||
|
});
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`HTTP Error: ${response.status}`);
|
||||||
|
}
|
||||||
|
const data = await response.json();
|
||||||
|
console.log("POST response data:", data); // Debugging statement
|
||||||
|
// Set status to Ready if successful
|
||||||
|
updateStatus('Ready');
|
||||||
|
} catch (error) {
|
||||||
|
console.error("POST request error:", error); // Debugging statement
|
||||||
|
// Set status to Error in case of failure
|
||||||
|
updateStatus('Error');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Low VRAM Listener
|
||||||
|
const lowVramCheckbox = document.getElementById('low_vram');
|
||||||
|
if (lowVramCheckbox) {
|
||||||
|
lowVramCheckbox.addEventListener('change', async (event) => {
|
||||||
|
const lowVramValue = event.target.checked ? 'True' : 'False';
|
||||||
|
// Set status to Processing
|
||||||
|
updateStatus('Processing');
|
||||||
|
try {
|
||||||
|
const response = await fetch(`${this.settings.provider_endpoint}/api/lowvramsetting?new_low_vram_value=${lowVramValue}`, {
|
||||||
|
method: 'POST'
|
||||||
|
});
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`HTTP Error: ${response.status}`);
|
||||||
|
}
|
||||||
|
const data = await response.json();
|
||||||
|
console.log("POST response data:", data); // Debugging statement
|
||||||
|
// Set status to Ready if successful
|
||||||
|
updateStatus('Ready');
|
||||||
|
} catch (error) {
|
||||||
|
console.error("POST request error:", error); // Debugging statement
|
||||||
|
// Set status to Error in case of failure
|
||||||
|
updateStatus('Error');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Narrator Voice Dropdown Listener
|
||||||
|
const narratorVoiceSelect = document.getElementById('narrator_voice');
|
||||||
|
if (narratorVoiceSelect) {
|
||||||
|
narratorVoiceSelect.addEventListener('change', (event) => {
|
||||||
|
this.settings.narrator_voice_gen = `${event.target.value}.wav`;
|
||||||
|
this.onSettingsChange(); // Save the settings after change
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const textNotInsideSelect = document.getElementById('at_narrator_text_not_inside');
|
||||||
|
if (textNotInsideSelect) {
|
||||||
|
textNotInsideSelect.addEventListener('change', (event) => {
|
||||||
|
this.settings.text_not_inside = event.target.value;
|
||||||
|
this.onSettingsChange(); // Save the settings after change
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// AT Narrator Dropdown Listener
|
||||||
|
const atNarratorSelect = document.getElementById('at_narrator_enabled');
|
||||||
|
const ttsPassAsterisksCheckbox = document.getElementById('tts_pass_asterisks'); // Access the checkbox from index.js
|
||||||
|
const ttsNarrateQuotedCheckbox = document.getElementById('tts_narrate_quoted'); // Access the checkbox from index.js
|
||||||
|
const ttsNarrateDialoguesCheckbox = document.getElementById('tts_narrate_dialogues'); // Access the checkbox from index.js
|
||||||
|
|
||||||
|
if (atNarratorSelect && textNotInsideSelect && narratorVoiceSelect) {
|
||||||
|
atNarratorSelect.addEventListener('change', (event) => {
|
||||||
|
const isNarratorEnabled = event.target.value === 'true';
|
||||||
|
this.settings.narrator_enabled = isNarratorEnabled; // Update the setting here
|
||||||
|
textNotInsideSelect.disabled = !isNarratorEnabled;
|
||||||
|
narratorVoiceSelect.disabled = !isNarratorEnabled;
|
||||||
|
|
||||||
|
// Sync the state with the checkbox in index.js
|
||||||
|
if (isNarratorEnabled) {
|
||||||
|
ttsPassAsterisksCheckbox.checked = false;
|
||||||
|
$('#tts_pass_asterisks').click(); // Simulate a click event
|
||||||
|
$('#tts_pass_asterisks').trigger('change');
|
||||||
|
}
|
||||||
|
if (!isNarratorEnabled) {
|
||||||
|
ttsPassAsterisksCheckbox.checked = true;
|
||||||
|
$('#tts_pass_asterisks').click(); // Simulate a click event
|
||||||
|
$('#tts_pass_asterisks').trigger('change');
|
||||||
|
}
|
||||||
|
// Uncheck and set tts_narrate_quoted to false if narrator is enabled
|
||||||
|
if (isNarratorEnabled) {
|
||||||
|
ttsNarrateQuotedCheckbox.checked = true;
|
||||||
|
ttsNarrateDialoguesCheckbox.checked = true;
|
||||||
|
// Trigger click events instead of change events
|
||||||
|
$('#tts_narrate_quoted').click();
|
||||||
|
$('#tts_narrate_quoted').trigger('change');
|
||||||
|
$('#tts_narrate_dialogues').click();
|
||||||
|
$('#tts_narrate_dialogues').trigger('change');
|
||||||
|
}
|
||||||
|
this.onSettingsChange(); // Save the settings after change
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Event Listener for AT Generation Method Dropdown
|
||||||
|
const atGenerationMethodSelect = document.getElementById('at_generation_method');
|
||||||
|
const atNarratorEnabledSelect = document.getElementById('at_narrator_enabled');
|
||||||
|
if (atGenerationMethodSelect) {
|
||||||
|
atGenerationMethodSelect.addEventListener('change', (event) => {
|
||||||
|
const selectedMethod = event.target.value;
|
||||||
|
|
||||||
|
if (selectedMethod === 'streaming_enabled') {
|
||||||
|
// Disable and unselect AT Narrator
|
||||||
|
atNarratorEnabledSelect.disabled = true;
|
||||||
|
atNarratorEnabledSelect.value = 'false';
|
||||||
|
textNotInsideSelect.disabled = true;
|
||||||
|
narratorVoiceSelect.disabled = true;
|
||||||
|
} else if (selectedMethod === 'standard_generation') {
|
||||||
|
// Enable AT Narrator
|
||||||
|
atNarratorEnabledSelect.disabled = false;
|
||||||
|
}
|
||||||
|
this.settings.at_generation_method = selectedMethod; // Update the setting here
|
||||||
|
this.onSettingsChange(); // Save the settings after change
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Listener for Language Dropdown
|
||||||
|
const languageSelect = document.getElementById('language_options');
|
||||||
|
if (languageSelect) {
|
||||||
|
languageSelect.addEventListener('change', (event) => {
|
||||||
|
this.settings.language = event.target.value;
|
||||||
|
this.onSettingsChange(); // Save the settings after change
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Listener for AllTalk Endpoint Input
|
||||||
|
const atServerInput = document.getElementById('at_server');
|
||||||
|
if (atServerInput) {
|
||||||
|
atServerInput.addEventListener('input', (event) => {
|
||||||
|
this.settings.provider_endpoint = event.target.value;
|
||||||
|
this.onSettingsChange(); // Save the settings after change
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//#############################//
|
||||||
|
// Store ST interface settings //
|
||||||
|
//#############################//
|
||||||
|
|
||||||
|
onSettingsChange() {
|
||||||
|
// Update settings based on the UI elements
|
||||||
|
//this.settings.provider_endpoint = $('#at_server').val();
|
||||||
|
this.settings.language = $('#language_options').val();
|
||||||
|
//this.settings.voiceMap = $('#voicemap').val();
|
||||||
|
this.settings.at_generation_method = $('#at_generation_method').val();
|
||||||
|
this.settings.narrator_enabled = $('#at_narrator_enabled').val();
|
||||||
|
this.settings.at_narrator_text_not_inside = $('#at_narrator_text_not_inside').val();
|
||||||
|
this.settings.narrator_voice_gen = $('#narrator_voice').val();
|
||||||
|
// Save the updated settings
|
||||||
|
saveTtsProviderSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
//#########################//
|
||||||
|
// ST Handle Reload button //
|
||||||
|
//#########################//
|
||||||
|
|
||||||
|
async onRefreshClick() {
|
||||||
|
await this.checkReady(); // Check if the TTS provider is ready
|
||||||
|
await this.loadSettings(this.settings); // Reload the settings
|
||||||
|
// Additional actions as needed
|
||||||
|
}
|
||||||
|
|
||||||
|
//##################//
|
||||||
|
// Preview AT Voice //
|
||||||
|
//##################//
|
||||||
|
|
||||||
|
async previewTtsVoice(voiceName) {
|
||||||
|
try {
|
||||||
|
// Prepare data for POST request
|
||||||
|
const postData = new URLSearchParams();
|
||||||
|
postData.append("voice", `${voiceName}.wav`);
|
||||||
|
// Making the POST request
|
||||||
|
const response = await fetch(`${this.settings.provider_endpoint}/api/previewvoice/`, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded'
|
||||||
|
},
|
||||||
|
body: postData,
|
||||||
|
});
|
||||||
|
if (!response.ok) {
|
||||||
|
const errorText = await response.text();
|
||||||
|
console.error(`[previewTtsVoice] Error Response Text:`, errorText);
|
||||||
|
throw new Error(`HTTP ${response.status}: ${errorText}`);
|
||||||
|
}
|
||||||
|
// Assuming the server returns a URL to the .wav file
|
||||||
|
const data = await response.json();
|
||||||
|
if (data.output_file_url) {
|
||||||
|
// Use an audio element to play the .wav file
|
||||||
|
const audioElement = new Audio(data.output_file_url);
|
||||||
|
audioElement.play().catch(e => console.error("Error playing audio:", e));
|
||||||
|
} else {
|
||||||
|
console.warn("[previewTtsVoice] No output file URL received in the response");
|
||||||
|
throw new Error("No output file URL received in the response");
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error("[previewTtsVoice] Exception caught during preview generation:", error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//#####################//
|
||||||
|
// Populate ST voices //
|
||||||
|
//#####################//
|
||||||
|
|
||||||
|
async getVoice(voiceName, generatePreview = false) {
|
||||||
|
// Ensure this.voices is populated
|
||||||
|
if (this.voices.length === 0) {
|
||||||
|
// Fetch voice objects logic
|
||||||
|
}
|
||||||
|
// Find the object where the name matches voiceName
|
||||||
|
const match = this.voices.find(voice => voice.name === voiceName);
|
||||||
|
if (!match) {
|
||||||
|
// Error handling
|
||||||
|
}
|
||||||
|
// Generate preview URL only if requested
|
||||||
|
if (!match.preview_url && generatePreview) {
|
||||||
|
// Generate preview logic
|
||||||
|
}
|
||||||
|
return match; // Return the found voice object
|
||||||
|
}
|
||||||
|
|
||||||
|
//##########################################//
|
||||||
|
// Generate TTS Streaming or call Standard //
|
||||||
|
//##########################################//
|
||||||
|
|
||||||
|
async generateTts(inputText, voiceId) {
|
||||||
|
try {
|
||||||
|
if (this.settings.at_generation_method === 'streaming_enabled') {
|
||||||
|
// Construct the streaming URL
|
||||||
|
const streamingUrl = `${this.settings.provider_endpoint}/api/tts-generate-streaming?text=${encodeURIComponent(inputText)}&voice=${encodeURIComponent(voiceId)}.wav&language=${encodeURIComponent(this.settings.language)}&output_file=stream_output.wav`;
|
||||||
|
console.log("Streaming URL:", streamingUrl);
|
||||||
|
|
||||||
|
// Return the streaming URL directly
|
||||||
|
return streamingUrl;
|
||||||
|
} else {
|
||||||
|
// For standard method
|
||||||
|
const outputUrl = await this.fetchTtsGeneration(inputText, voiceId);
|
||||||
|
const audioResponse = await fetch(outputUrl);
|
||||||
|
if (!audioResponse.ok) {
|
||||||
|
throw new Error(`HTTP ${audioResponse.status}: Failed to fetch audio data`);
|
||||||
|
}
|
||||||
|
return audioResponse; // Return the fetch response directly
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error in generateTts:", error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//####################//
|
||||||
|
// Generate Standard //
|
||||||
|
//####################//
|
||||||
|
|
||||||
|
async fetchTtsGeneration(inputText, voiceId) {
|
||||||
|
// Prepare the request payload
|
||||||
|
const requestBody = new URLSearchParams({
|
||||||
|
'text_input': inputText,
|
||||||
|
'text_filtering': "standard",
|
||||||
|
'character_voice_gen': voiceId + ".wav",
|
||||||
|
'narrator_enabled': this.settings.narrator_enabled,
|
||||||
|
'narrator_voice_gen': this.settings.narrator_voice_gen + ".wav",
|
||||||
|
'text_not_inside': this.settings.at_narrator_text_not_inside,
|
||||||
|
'language': this.settings.language,
|
||||||
|
'output_file_name': "st_output",
|
||||||
|
'output_file_timestamp': "true",
|
||||||
|
'autoplay': "false",
|
||||||
|
'autoplay_volume': "0.8"
|
||||||
|
}).toString();
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await doExtrasFetch(
|
||||||
|
`${this.settings.provider_endpoint}/api/tts-generate`,
|
||||||
|
{
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded',
|
||||||
|
'Cache-Control': 'no-cache',
|
||||||
|
},
|
||||||
|
body: requestBody
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
const errorText = await response.text();
|
||||||
|
console.error(`[fetchTtsGeneration] Error Response Text:`, errorText);
|
||||||
|
// toastr.error(response.statusText, 'TTS Generation Failed');
|
||||||
|
throw new Error(`HTTP ${response.status}: ${errorText}`);
|
||||||
|
}
|
||||||
|
const data = await response.json();
|
||||||
|
const outputUrl = data.output_file_url;
|
||||||
|
return outputUrl; // Return only the output_file_url
|
||||||
|
} catch (error) {
|
||||||
|
console.error("[fetchTtsGeneration] Exception caught:", error);
|
||||||
|
throw error; // Rethrow the error for further handling
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//#########################//
|
||||||
|
// Update Status Messages //
|
||||||
|
//#########################//
|
||||||
|
|
||||||
|
function updateStatus(message) {
|
||||||
|
const statusElement = document.getElementById('status_info');
|
||||||
|
if (statusElement) {
|
||||||
|
statusElement.textContent = message;
|
||||||
|
switch (message) {
|
||||||
|
case 'Offline':
|
||||||
|
statusElement.style.color = 'red';
|
||||||
|
break;
|
||||||
|
case 'Ready':
|
||||||
|
statusElement.style.color = 'lightgreen';
|
||||||
|
break;
|
||||||
|
case 'Processing':
|
||||||
|
statusElement.style.color = 'blue';
|
||||||
|
break;
|
||||||
|
case 'Error':
|
||||||
|
statusElement.style.color = 'red';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,159 @@
|
|||||||
|
#tts_media_control {
|
||||||
|
/* order: 100; */
|
||||||
|
/* width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
margin: 0;
|
||||||
|
padding: 1px; */
|
||||||
|
outline: none;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
/* transition: 0.3s;
|
||||||
|
opacity: 0.7; */
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
/* justify-content: center; */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#ttsExtensionMenuItem {
|
||||||
|
transition: 0.3s;
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ttsExtensionMenuItem:hover {
|
||||||
|
opacity: 1;
|
||||||
|
filter: brightness(1.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#tts_media_control:hover {
|
||||||
|
opacity: 1;
|
||||||
|
filter: brightness(1.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.voice_preview {
|
||||||
|
margin: 0.25rem 0.5rem;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.voice_preview .voice_name {
|
||||||
|
text-align: left;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.voice_preview .voice_lang {
|
||||||
|
width: 4rem;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.voice_preview .fa-play {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tts-button {
|
||||||
|
margin: 0;
|
||||||
|
outline: none;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: 0.3s;
|
||||||
|
opacity: 0.7;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.tts-button:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tts_block {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
column-gap: 5px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tts_custom_voices {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
gap: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.novel_tts_hints {
|
||||||
|
font-size: calc(0.9 * var(--mainFontSize));
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 5px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.at-settings-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.at-settings-option {
|
||||||
|
flex: 1;
|
||||||
|
margin: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.at-endpoint-option {
|
||||||
|
flex: 1;
|
||||||
|
margin: 0 10px;
|
||||||
|
margin-right: 25px;
|
||||||
|
width: 38%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.at-website-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: start;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.at-website-option {
|
||||||
|
flex: 1;
|
||||||
|
margin-right: 10px;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.at-settings-separator {
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
padding: 18x;
|
||||||
|
font-weight: bold;
|
||||||
|
border-top: 1px solid #e1e1e1; /* Grey line */
|
||||||
|
border-bottom: 1px solid #e1e1e1; /* Grey line */
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.at-status-message {
|
||||||
|
flex: 1;
|
||||||
|
margin: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.at-model-endpoint-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.at-model-option, .endpoint-option {
|
||||||
|
flex: 1;
|
||||||
|
margin: 0 10px;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.at-endpoint-option {
|
||||||
|
width: 38%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#at-status_info {
|
||||||
|
color: lightgreen;
|
||||||
|
}
|
||||||
@@ -0,0 +1,269 @@
|
|||||||
|
import json
|
||||||
|
import argparse
|
||||||
|
from pathlib import Path
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
import platform
|
||||||
|
import site
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
# version 0.8
|
||||||
|
|
||||||
|
def find_files_in_path_with_wildcard(pattern):
|
||||||
|
# Get the site-packages directory of the current Python environment
|
||||||
|
site_packages_path = site.getsitepackages()
|
||||||
|
found_paths = []
|
||||||
|
# Adjust the sub-directory based on the operating system
|
||||||
|
sub_directory = "nvidia/cublas"
|
||||||
|
if platform.system() == "Linux":
|
||||||
|
sub_directory = os.path.join(sub_directory, "lib")
|
||||||
|
else:
|
||||||
|
sub_directory = os.path.join(sub_directory, "bin")
|
||||||
|
|
||||||
|
# Iterate over each site-packages directory (there can be more than one)
|
||||||
|
for directory in site_packages_path:
|
||||||
|
# Construct the search directory path
|
||||||
|
search_directory = os.path.join(directory, sub_directory)
|
||||||
|
# Use glob to find all files matching the pattern in this directory
|
||||||
|
for file_path in glob.glob(os.path.join(search_directory, pattern)):
|
||||||
|
if os.path.isfile(file_path): # Ensure it's a file
|
||||||
|
found_paths.append(file_path)
|
||||||
|
return found_paths
|
||||||
|
|
||||||
|
def detect_cublas():
|
||||||
|
# Use different file patterns based on the operating system
|
||||||
|
file_name_pattern = 'cublas64_11.*' if platform.system() == "Windows" else 'libcublas.so.11*'
|
||||||
|
found_paths = find_files_in_path_with_wildcard(file_name_pattern)
|
||||||
|
if found_paths:
|
||||||
|
print("[AllTalk TTSDiff] \033[94mCublas:\033[0m \033[92mDetected\033[0m", found_paths)
|
||||||
|
else:
|
||||||
|
print("[AllTalk TTSDiff] \033[94mCublas:\033[0m \033[91mERROR Not Detected\033[0m")
|
||||||
|
print("[AllTalk TTSDiff] \033[94mPlease install Cublas from the Nvidia CUDA Toolkit \033[0mhttps://developer.nvidia.com/cuda-downloads")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description="Compare TTS output with the original text using detailed comparison.")
|
||||||
|
parser.add_argument("--threshold", type=int, default=98, help="Similarity threshold for considering a match (default: 98)")
|
||||||
|
parser.add_argument("--ttslistpath", help="Path to the ttsList.json file")
|
||||||
|
parser.add_argument("--wavfilespath", help="Path to the wav outputs folder")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
if not args.ttslistpath:
|
||||||
|
parser.error("[AllTalk TTSDiff] Please specify the path to the ttslist.json file using the --ttslistpath argument.")
|
||||||
|
if not args.wavfilespath:
|
||||||
|
parser.error("[AllTalk TTSDiff] Please specify the path to the wavs output folder file using the --wavfilespath argument.")
|
||||||
|
|
||||||
|
json_file_path = Path(args.ttslistpath).resolve()
|
||||||
|
wav_file_path = Path(args.wavfilespath).resolve()
|
||||||
|
accuracy_threshold = args.threshold
|
||||||
|
|
||||||
|
def disclaimer_text():
|
||||||
|
print(f"\nDESCRIPTION: ")
|
||||||
|
print(f" This script is designed to assist in identifying bad TTS generation ID's from the TTS Generator.\n")
|
||||||
|
print(f" This will download the Whisper Large-v2 model (if not already downloaded), and use it to compare your text to")
|
||||||
|
print(f" to the generated TTS. If it finds an issue, it will flag the ID number that has the issue. This does NOT 100%")
|
||||||
|
print(f" ensure that all TTS generated is perfect, sounds good etc, but it should flag up glaring issues and help with")
|
||||||
|
print(f" the process of identifying bad TTS generations.")
|
||||||
|
print(f"\nNOTES ON USE: ")
|
||||||
|
print(f" - Ensure AllTalk is running in its own command prompt/terminal.")
|
||||||
|
print(f" - This script should be running in its own command prompt/terminal window in the same Python Environment that")
|
||||||
|
print(f" AllTalk is running in.")
|
||||||
|
print(f" - After generating your text in the TTS Generator, you need to `Export List to JSON` and save the file in the")
|
||||||
|
print(f" same folder/directory this script is running from.")
|
||||||
|
print(f" - You can use `--threshold` with a numerical value from 1 to 100 to set accuracy detection. For example it may")
|
||||||
|
print(f" detect/transcribe `their` as `there`, which of course, both words sound the same. If you want 100% accuracy")
|
||||||
|
print(f" you will set 100 as the threshold. You will more than likely want a number in the high 90's. Default is set")
|
||||||
|
print(f" at 98, which gives a little flexibility.")
|
||||||
|
print(f" - The JSON file must be named \033[93mttsList.json\033[0m")
|
||||||
|
print(f" - When you have your ID list, go back into the TTS Generator, correct any lines and regenerate them. If you")
|
||||||
|
print(f" want to re-test everthing again after re-generating, you will need to export your list again and re-run this")
|
||||||
|
print(f" script again, against your newly exported JSON list.")
|
||||||
|
print(f" - This requires access to \033[93mcublas64_11\033[0m, the same as Finetuning.")
|
||||||
|
print(f" https://github.com/erew123/alltalk_tts/tree/main?#-important-requirements-cuda-118\n")
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
from faster_whisper import WhisperModel
|
||||||
|
import re
|
||||||
|
import string
|
||||||
|
import spacy
|
||||||
|
import torch
|
||||||
|
from fuzzywuzzy import fuzz
|
||||||
|
except ImportError as e:
|
||||||
|
print(f"[AllTalk TTSDiff] ERROR STARTING SCRIPT:")
|
||||||
|
print("[AllTalk TTSDiff] An error occurred importing one or more required libraries.")
|
||||||
|
print("[AllTalk TTSDiff] Please ensure you have \033[94mactivated your Python environment \033[0mand \033[94minstalled all requirements.\033[0m")
|
||||||
|
print("[AllTalk TTSDiff] \033[94mMissing library:\033[93m", str(e), "\033[0m")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
# Attempt to load the spaCy model
|
||||||
|
try:
|
||||||
|
# Load a medium-sized spaCy model, adjust to "en_core_web_md" or "en_core_web_lg" as needed
|
||||||
|
nlp = spacy.load("en_core_web_md")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[AllTalk TTSDiff] ERROR STARTING SCRIPT:")
|
||||||
|
print("[AllTalk TTSDiff] Failed to load the spaCy language model.")
|
||||||
|
|
||||||
|
# Attempt to download the spaCy model automatically
|
||||||
|
try:
|
||||||
|
print("[AllTalk TTSDiff] Attempting to automatically download the spaCy language model...")
|
||||||
|
subprocess.run([sys.executable, "-m", "spacy", "download", "en_core_web_md"], check=True)
|
||||||
|
|
||||||
|
# Try to load the model again after downloading
|
||||||
|
nlp = spacy.load("en_core_web_md")
|
||||||
|
print("[AllTalk TTSDiff] Model downloaded and loaded successfully.")
|
||||||
|
except Exception as download_exception:
|
||||||
|
print("[AllTalk TTSDiff] Automatic download failed.")
|
||||||
|
print("[AllTalk TTSDiff] Please manually install the spaCy language model by running:")
|
||||||
|
print("[AllTalk TTSDiff] \033[93mpython -m spacy download en_core_web_md\033[0m")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
def texts_are_similar(text1, text2, threshold=0.8):
|
||||||
|
# Preliminary check for short texts
|
||||||
|
if len(text1) < 10 or len(text2) < 10:
|
||||||
|
ratio = fuzz.ratio(text1, text2) / 100.0 # Use FuzzyWuzzy for short texts
|
||||||
|
return ratio > threshold
|
||||||
|
|
||||||
|
# Process the texts through the NLP model for longer texts
|
||||||
|
doc1 = nlp(text1)
|
||||||
|
doc2 = nlp(text2)
|
||||||
|
|
||||||
|
# Compute semantic similarity
|
||||||
|
similarity = doc1.similarity(doc2)
|
||||||
|
|
||||||
|
return similarity >= threshold
|
||||||
|
|
||||||
|
def normalize_text(text):
|
||||||
|
# Normalize or remove CRLF and other non-standard whitespaces
|
||||||
|
text = text.replace("\r\n", " ").replace("\n", " ").replace("\r", " ")
|
||||||
|
|
||||||
|
# Convert to lowercase
|
||||||
|
text = text.lower()
|
||||||
|
|
||||||
|
# Standardize and then remove quotation marks
|
||||||
|
text = text.replace("“", '"').replace("”", '"').replace("‘", "'").replace("’", "'")
|
||||||
|
text = text.translate(str.maketrans('', '', '"\''))
|
||||||
|
|
||||||
|
# Remove all other punctuation except hyphens to preserve compound words
|
||||||
|
text = text.translate(str.maketrans('', '', string.punctuation.replace("-", "")))
|
||||||
|
|
||||||
|
# Collapse any sequence of whitespace (including spaces) into a single space
|
||||||
|
text = re.sub(r'\s+', ' ', text)
|
||||||
|
|
||||||
|
return text.strip()
|
||||||
|
|
||||||
|
spoken_punctuation_mapping = {
|
||||||
|
"dot": ".",
|
||||||
|
"comma": ",",
|
||||||
|
# Add more mappings as needed
|
||||||
|
}
|
||||||
|
|
||||||
|
def contains_spoken_punctuation(transcribed_text):
|
||||||
|
for spoken, punctuation in spoken_punctuation_mapping.items():
|
||||||
|
if spoken in transcribed_text:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def detailed_comparison(original_text, transcribed_text, threshold=98):
|
||||||
|
original_clean = normalize_text(original_text)
|
||||||
|
transcribed_clean = normalize_text(transcribed_text)
|
||||||
|
ratio = fuzz.ratio(original_clean, transcribed_clean)
|
||||||
|
return ratio > threshold
|
||||||
|
|
||||||
|
def access_local_file(url):
|
||||||
|
# Extract the file name from the URL
|
||||||
|
file_name = url.split('/')[-1]
|
||||||
|
# Construct the full path to the file on disk
|
||||||
|
file_path = wav_file_path / file_name
|
||||||
|
# Check if the file exists
|
||||||
|
if not file_path.exists():
|
||||||
|
print(f"[AllTalk TTSDiff] File does not exist: {file_path}")
|
||||||
|
return None
|
||||||
|
return file_path
|
||||||
|
|
||||||
|
def transcribe_and_compare(file_url, original_text, model, item_id, flagged_ids):
|
||||||
|
audio_file_path = access_local_file(file_url)
|
||||||
|
if audio_file_path is None:
|
||||||
|
print(f"[AllTalk TTSDiff] Could not access local file for URL: {file_url}")
|
||||||
|
return # Skip this file if it can't be accessed
|
||||||
|
|
||||||
|
try:
|
||||||
|
segments, info = model.transcribe(str(audio_file_path), beam_size=5)
|
||||||
|
transcribed_text = " ".join([segment.text for segment in segments])
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[AllTalk TTSDiff] Error transcribing file {audio_file_path}: {e}")
|
||||||
|
return # Skip this file if transcription fails
|
||||||
|
|
||||||
|
segments, info = model.transcribe(str(audio_file_path), beam_size=5)
|
||||||
|
transcribed_text = " ".join([segment.text for segment in segments])
|
||||||
|
|
||||||
|
# Normalize texts for comparison
|
||||||
|
original_text_normalized = normalize_text(original_text)
|
||||||
|
transcribed_text_normalized = normalize_text(transcribed_text)
|
||||||
|
|
||||||
|
# Enhanced comparison using detailed fuzzy matching
|
||||||
|
is_detailed_match = detailed_comparison(original_text_normalized, transcribed_text_normalized, args.threshold)
|
||||||
|
has_spoken_punctuation = contains_spoken_punctuation(transcribed_text_normalized) and not contains_spoken_punctuation(original_text_normalized)
|
||||||
|
|
||||||
|
# Adjust is_match based on detailed comparison and spoken punctuation check
|
||||||
|
is_match = is_detailed_match and not has_spoken_punctuation
|
||||||
|
|
||||||
|
# Only log and flag IDs for review if there's a mismatch or detected issues
|
||||||
|
if not is_match:
|
||||||
|
#print(f"\033[93mMismatch Detected - ID:\033[0m {item_id}")
|
||||||
|
print(f"[AllTalk TTSDiff] \033[93mText:\033[0m {original_text}")
|
||||||
|
print(f"[AllTalk TTSDiff] \033[91mTTS :\033[0m{transcribed_text}")
|
||||||
|
if has_spoken_punctuation:
|
||||||
|
print(f"[AllTalk TTSDiff] Note: Potential incorrect spoken punctuation detected.")
|
||||||
|
flagged_ids.append(item_id) # Track the ID for review
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print(f"[AllTalk TTSDiff]")
|
||||||
|
print(f"[AllTalk TTSDiff]")
|
||||||
|
print("[AllTalk TTSDiff] \033[92mStarting Compare of Text vs TTS:\033[0m")
|
||||||
|
print("[AllTalk TTSDiff]")
|
||||||
|
print("[AllTalk TTSDiff] \033[94mJSON file :\033[92m", json_file_path, "\033[0m")
|
||||||
|
print("[AllTalk TTSDiff] \033[94mWAV files :\033[92m", wav_file_path, "\033[0m")
|
||||||
|
print("[AllTalk TTSDiff] \033[94mAccuracy :\033[92m", accuracy_threshold, "%", "\033[0m")
|
||||||
|
detect_cublas()
|
||||||
|
model_size = "large-v2"
|
||||||
|
device = "cuda" if torch.cuda.is_available() else "cpu"
|
||||||
|
model = WhisperModel(model_size, device=device, compute_type="float32")
|
||||||
|
|
||||||
|
flagged_ids = [] # Initialize the list to track IDs needing review
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(json_file_path, "r", encoding="utf-8") as f:
|
||||||
|
tts_list = json.load(f)
|
||||||
|
except FileNotFoundError:
|
||||||
|
print(f"[AllTalk TTSDiff] ERROR STARTING SCRIPT:")
|
||||||
|
print("[AllTalk TTSDiff] Error: \033[93mttsList.json\033[0m file not found.")
|
||||||
|
print("[AllTalk TTSDiff] Please ensure you follow these steps:")
|
||||||
|
print("[AllTalk TTSDiff] After generating your text in the TTS Generator, you need to `Export List to JSON` and save the file in the")
|
||||||
|
print("[AllTalk TTSDiff] same folder/directory this script is running from.")
|
||||||
|
print("[AllTalk TTSDiff] The JSON file must be named \033[93mttsList.json\033[0m")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
print(f"[AllTalk TTSDiff]")
|
||||||
|
|
||||||
|
for item in tts_list:
|
||||||
|
print(f"[AllTalk TTSDiff] Processing ID: {item['id']}")
|
||||||
|
transcribe_and_compare(item['fileUrl'], item['text'], model, item['id'], flagged_ids)
|
||||||
|
|
||||||
|
print(f"[AllTalk TTSDiff]")
|
||||||
|
# Print summary information at the end
|
||||||
|
if flagged_ids:
|
||||||
|
print(f"[AllTalk TTSDiff] \033[94mIDs needing review:\033[0m", ', '.join(map(str, flagged_ids)))
|
||||||
|
print(f"[AllTalk TTSDiff]")
|
||||||
|
print(f"[AllTalk TTSDiff] Review ID's and correct any lines by editing & regenerating as necessary.")
|
||||||
|
else:
|
||||||
|
print("[AllTalk TTSDiff] \033[94mIDs needing review:\033[0m No issues detected.")
|
||||||
|
summary_data = {
|
||||||
|
"flagged_ids": flagged_ids
|
||||||
|
}
|
||||||
|
with open(wav_file_path / "analysis_summary.json", "w") as summary_file:
|
||||||
|
json.dump(summary_data, summary_file)
|
||||||
|
print("[AllTalk TTSDiff]")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,179 @@
|
|||||||
|
export interface CrunkerConstructorOptions {
|
||||||
|
/**
|
||||||
|
* Sample rate for Crunker's internal audio context.
|
||||||
|
*
|
||||||
|
* @default 44100
|
||||||
|
*/
|
||||||
|
sampleRate: number;
|
||||||
|
}
|
||||||
|
export type CrunkerInputTypes = string | File | Blob;
|
||||||
|
/**
|
||||||
|
* An exported Crunker audio object.
|
||||||
|
*/
|
||||||
|
export interface ExportedCrunkerAudio {
|
||||||
|
blob: Blob;
|
||||||
|
url: string;
|
||||||
|
element: HTMLAudioElement;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Crunker is the simple way to merge, concatenate, play, export and download audio files using the Web Audio API.
|
||||||
|
*/
|
||||||
|
export default class Crunker {
|
||||||
|
private readonly _sampleRate;
|
||||||
|
private readonly _context;
|
||||||
|
/**
|
||||||
|
* Creates a new instance of Crunker with the provided options.
|
||||||
|
*
|
||||||
|
* If `sampleRate` is not defined, it will auto-select an appropriate sample rate
|
||||||
|
* for the device being used.
|
||||||
|
*/
|
||||||
|
constructor({ sampleRate }?: Partial<CrunkerConstructorOptions>);
|
||||||
|
/**
|
||||||
|
* Creates Crunker's internal AudioContext.
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
private _createContext;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* The internal AudioContext used by Crunker.
|
||||||
|
*/
|
||||||
|
get context(): AudioContext;
|
||||||
|
/**
|
||||||
|
* Asynchronously fetches multiple audio files and returns an array of AudioBuffers.
|
||||||
|
*/
|
||||||
|
fetchAudio(...filepaths: CrunkerInputTypes[]): Promise<AudioBuffer[]>;
|
||||||
|
/**
|
||||||
|
* Merges (layers) multiple AudioBuffers into a single AudioBuffer.
|
||||||
|
*
|
||||||
|
* **Visual representation:**
|
||||||
|
*
|
||||||
|
* 
|
||||||
|
*/
|
||||||
|
mergeAudio(buffers: AudioBuffer[]): AudioBuffer;
|
||||||
|
/**
|
||||||
|
* Concatenates multiple AudioBuffers into a single AudioBuffer.
|
||||||
|
*
|
||||||
|
* **Visual representation:**
|
||||||
|
*
|
||||||
|
* 
|
||||||
|
*/
|
||||||
|
concatAudio(buffers: AudioBuffer[]): AudioBuffer;
|
||||||
|
/**
|
||||||
|
* Pads a specified AudioBuffer with silence from a specified start time,
|
||||||
|
* for a specified length of time.
|
||||||
|
*
|
||||||
|
* Accepts float values as well as whole integers.
|
||||||
|
*
|
||||||
|
* @param buffer AudioBuffer to pad
|
||||||
|
* @param padStart Time to start padding (in seconds)
|
||||||
|
* @param seconds Duration to pad for (in seconds)
|
||||||
|
*/
|
||||||
|
padAudio(buffer: AudioBuffer, padStart?: number, seconds?: number): AudioBuffer;
|
||||||
|
/**
|
||||||
|
* Slices an AudioBuffer from the specified start time to the end time, with optional fade in and out.
|
||||||
|
*
|
||||||
|
* @param buffer AudioBuffer to slice
|
||||||
|
* @param start Start time (in seconds)
|
||||||
|
* @param end End time (in seconds)
|
||||||
|
* @param fadeIn Fade in duration (in seconds, default is 0)
|
||||||
|
* @param fadeOut Fade out duration (in seconds, default is 0)
|
||||||
|
*/
|
||||||
|
sliceAudio(buffer: AudioBuffer, start: number, end: number, fadeIn?: number, fadeOut?: number): AudioBuffer;
|
||||||
|
/**
|
||||||
|
* Plays the provided AudioBuffer in an AudioBufferSourceNode.
|
||||||
|
*/
|
||||||
|
play(buffer: AudioBuffer): AudioBufferSourceNode;
|
||||||
|
/**
|
||||||
|
* Exports the specified AudioBuffer to a Blob, Object URI and HTMLAudioElement.
|
||||||
|
*
|
||||||
|
* Note that changing the MIME type does not change the actual file format. The
|
||||||
|
* file format will **always** be a WAVE file due to how audio is stored in the
|
||||||
|
* browser.
|
||||||
|
*
|
||||||
|
* @param buffer Buffer to export
|
||||||
|
* @param type MIME type (default: `audio/wav`)
|
||||||
|
*/
|
||||||
|
export(buffer: AudioBuffer, type?: string): ExportedCrunkerAudio;
|
||||||
|
/**
|
||||||
|
* Downloads the provided Blob.
|
||||||
|
*
|
||||||
|
* @param blob Blob to download
|
||||||
|
* @param filename An optional file name to use for the download (default: `crunker`)
|
||||||
|
*/
|
||||||
|
download(blob: Blob, filename?: string): HTMLAnchorElement;
|
||||||
|
/**
|
||||||
|
* Executes a callback if the browser does not support the Web Audio API.
|
||||||
|
*
|
||||||
|
* Returns the result of the callback, or `undefined` if the Web Audio API is supported.
|
||||||
|
*
|
||||||
|
* @param callback callback to run if the browser does not support the Web Audio API
|
||||||
|
*/
|
||||||
|
notSupported<T>(callback: () => T): T | undefined;
|
||||||
|
/**
|
||||||
|
* Closes Crunker's internal AudioContext.
|
||||||
|
*/
|
||||||
|
close(): this;
|
||||||
|
/**
|
||||||
|
* Returns the largest duration of the longest AudioBuffer.
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
private _maxDuration;
|
||||||
|
/**
|
||||||
|
* Returns the largest number of channels in an array of AudioBuffers.
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
private _maxNumberOfChannels;
|
||||||
|
/**
|
||||||
|
* Returns the sum of the lengths of an array of AudioBuffers.
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
private _totalLength;
|
||||||
|
/**
|
||||||
|
* Returns whether the browser supports the Web Audio API.
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
private _isSupported;
|
||||||
|
/**
|
||||||
|
* Writes the WAV headers for the specified Float32Array.
|
||||||
|
*
|
||||||
|
* Returns a DataView containing the WAV headers and file content.
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
private _writeHeaders;
|
||||||
|
/**
|
||||||
|
* Converts a Float32Array to 16-bit PCM.
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
private _floatTo16BitPCM;
|
||||||
|
/**
|
||||||
|
* Writes a string to a DataView at the specified offset.
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
private _writeString;
|
||||||
|
/**
|
||||||
|
* Converts an AudioBuffer to a Float32Array.
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
private _interleave;
|
||||||
|
/**
|
||||||
|
* Creates an HTMLAudioElement whose source is the specified Blob.
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
private _renderAudioElement;
|
||||||
|
/**
|
||||||
|
* Creates an Object URL for the specified Blob.
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
private _renderURL;
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
var e={d:(t,n)=>{for(var r in n)e.o(n,r)&&!e.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:n[r]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};function n(e){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},n(e)}function r(e){return function(e){if(Array.isArray(e))return a(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return a(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return a(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function a(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function i(e,t){for(var r=0;r<t.length;r++){var a=t[r];a.enumerable=a.enumerable||!1,a.configurable=!0,"value"in a&&(a.writable=!0),Object.defineProperty(e,(o=a.key,i=void 0,i=function(e,t){if("object"!==n(e)||null===e)return e;var r=e[Symbol.toPrimitive];if(void 0!==r){var a=r.call(e,t||"default");if("object"!==n(a))return a;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(o,"string"),"symbol"===n(i)?i:String(i)),a)}var o,i}e.d(t,{Z:()=>u});var u=function(){function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=t.sampleRate;o(this,e),this._context=this._createContext(n),n||(n=this._context.sampleRate),this._sampleRate=n}var t,n,a;return t=e,n=[{key:"_createContext",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:44100;return window.AudioContext=window.AudioContext||window.webkitAudioContext||window.mozAudioContext,new AudioContext({sampleRate:e})}},{key:"context",get:function(){return this._context}},{key:"fetchAudio",value:async function(){for(var e=this,t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];return await Promise.all(n.map((async function(t){var n;return n=t instanceof File||t instanceof Blob?await t.arrayBuffer():await fetch(t).then((function(e){return e.headers.has("Content-Type")&&!e.headers.get("Content-Type").includes("audio/")&&console.warn("Crunker: Attempted to fetch an audio file, but its MIME type is `".concat(e.headers.get("Content-Type").split(";")[0],"`. We'll try and continue anyway. (file: \"").concat(t,'")')),e.arrayBuffer()})),await e._context.decodeAudioData(n)})))}},{key:"mergeAudio",value:function(e){var t=this._context.createBuffer(this._maxNumberOfChannels(e),this._sampleRate*this._maxDuration(e),this._sampleRate);return e.forEach((function(e){for(var n=0;n<e.numberOfChannels;n++){for(var r=t.getChannelData(n),a=e.getChannelData(n),o=e.getChannelData(n).length-1;o>=0;o--)r[o]+=a[o];t.getChannelData(n).set(r)}})),t}},{key:"concatAudio",value:function(e){var t=this._context.createBuffer(this._maxNumberOfChannels(e),this._totalLength(e),this._sampleRate),n=0;return e.forEach((function(e){for(var r=0;r<e.numberOfChannels;r++)t.getChannelData(r).set(e.getChannelData(r),n);n+=e.length})),t}},{key:"padAudio",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0;if(0===n)return e;if(t<0)throw new Error('Crunker: Parameter "padStart" in padAudio must be positive');if(n<0)throw new Error('Crunker: Parameter "seconds" in padAudio must be positive');for(var r=this._context.createBuffer(e.numberOfChannels,Math.ceil(e.length+n*e.sampleRate),e.sampleRate),a=0;a<e.numberOfChannels;a++){var o=e.getChannelData(a);r.getChannelData(a).set(o.subarray(0,Math.ceil(t*e.sampleRate)+1),0),r.getChannelData(a).set(o.subarray(Math.ceil(t*e.sampleRate)+2,r.length+1),Math.ceil((t+n)*e.sampleRate))}return r}},{key:"sliceAudio",value:function(e,t,n){var r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:0,a=arguments.length>4&&void 0!==arguments[4]?arguments[4]:0;if(t>=n)throw new Error('Crunker: "start" time should be less than "end" time in sliceAudio method');for(var o=Math.round((n-t)*this._sampleRate),i=Math.round(t*this._sampleRate),u=this._context.createBuffer(e.numberOfChannels,o,this._sampleRate),l=0;l<e.numberOfChannels;l++)for(var s=e.getChannelData(l),c=u.getChannelData(l),f=0;f<o;f++)c[f]=s[i+f],f<r*this._sampleRate&&(c[f]*=f/(r*this._sampleRate)),f>o-a*this._sampleRate&&(c[f]*=(o-f)/(a*this._sampleRate));return u}},{key:"play",value:function(e){var t=this._context.createBufferSource();return t.buffer=e,t.connect(this._context.destination),t.start(),Line truncated
|
||||||
|
//# sourceMappingURL=crunker.esm.js.map
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"crunker.esm.js","mappings":"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 truncated
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,4 @@
|
|||||||
|
/*! howler.js v2.2.4 | (c) 2013-2020, James Simpson of GoldFire Studios | MIT License | howlerjs.com */
|
||||||
|
!function(){"use strict";var e=function(){this.init()};e.prototype={init:function(){var e=this||n;return e._counter=1e3,e._html5AudioPool=[],e.html5PoolSize=10,e._codecs={},e._howls=[],e._muted=!1,e._volume=1,e._canPlayEvent="canplaythrough",e._navigator="undefined"!=typeof window&&window.navigator?window.navigator:null,e.masterGain=null,e.noAudio=!1,e.usingWebAudio=!0,e.autoSuspend=!0,e.ctx=null,e.autoUnlock=!0,e._setup(),e},volume:function(e){var o=this||n;if(e=parseFloat(e),o.ctx||_(),void 0!==e&&e>=0&&e<=1){if(o._volume=e,o._muted)return o;o.usingWebAudio&&o.masterGain.gain.setValueAtTime(e,n.ctx.currentTime);for(var t=0;t<o._howls.length;t++)if(!o._howls[t]._webAudio)for(var r=o._howls[t]._getSoundIds(),a=0;a<r.length;a++){var u=o._howls[t]._soundById(r[a]);u&&u._node&&(u._node.volume=u._volume*e)}return o}return o._volume},mute:function(e){var o=this||n;o.ctx||_(),o._muted=e,o.usingWebAudio&&o.masterGain.gain.setValueAtTime(e?0:o._volume,n.ctx.currentTime);for(var t=0;t<o._howls.length;t++)if(!o._howls[t]._webAudio)for(var r=o._howls[t]._getSoundIds(),a=0;a<r.length;a++){var u=o._howls[t]._soundById(r[a]);u&&u._node&&(u._node.muted=!!e||u._muted)}return o},stop:function(){for(var e=this||n,o=0;o<e._howls.length;o++)e._howls[o].stop();return e},unload:function(){for(var e=this||n,o=e._howls.length-1;o>=0;o--)e._howls[o].unload();return e.usingWebAudio&&e.ctx&&void 0!==e.ctx.close&&(e.ctx.close(),e.ctx=null,_()),e},codecs:function(e){return(this||n)._codecs[e.replace(/^x-/,"")]},_setup:function(){var e=this||n;if(e.state=e.ctx?e.ctx.state||"suspended":"suspended",e._autoSuspend(),!e.usingWebAudio)if("undefined"!=typeof Audio)try{var o=new Audio;void 0===o.oncanplaythrough&&(e._canPlayEvent="canplay")}catch(n){e.noAudio=!0}else e.noAudio=!0;try{var o=new Audio;o.muted&&(e.noAudio=!0)}catch(e){}return e.noAudio||e._setupCodecs(),e},_setupCodecs:function(){var e=this||n,o=null;try{o="undefined"!=typeof Audio?new Audio:null}catch(n){return e}if(!o||"function"!=typeof o.canPlayType)return e;var t=o.canPlayType("audio/mpeg;").replace(/^no$/,""),r=e._navigator?e._navigator.userAgent:"",a=r.match(/OPR\/(\d+)/g),u=a&&parseInt(a[0].split("/")[1],10)<33,d=-1!==r.indexOf("Safari")&&-1===r.indexOf("Chrome"),i=r.match(/Version\/(.*?) /),_=d&&i&&parseInt(i[1],10)<15;return e._codecs={mp3:!(u||!t&&!o.canPlayType("audio/mp3;").replace(/^no$/,"")),mpeg:!!t,opus:!!o.canPlayType('audio/ogg; codecs="opus"').replace(/^no$/,""),ogg:!!o.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),oga:!!o.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),wav:!!(o.canPlayType('audio/wav; codecs="1"')||o.canPlayType("audio/wav")).replace(/^no$/,""),aac:!!o.canPlayType("audio/aac;").replace(/^no$/,""),caf:!!o.canPlayType("audio/x-caf;").replace(/^no$/,""),m4a:!!(o.canPlayType("audio/x-m4a;")||o.canPlayType("audio/m4a;")||o.canPlayType("audio/aac;")).replace(/^no$/,""),m4b:!!(o.canPlayType("audio/x-m4b;")||o.canPlayType("audio/m4b;")||o.canPlayType("audio/aac;")).replace(/^no$/,""),mp4:!!(o.canPlayType("audio/x-mp4;")||o.canPlayType("audio/mp4;")||o.canPlayType("audio/aac;")).replace(/^no$/,""),weba:!(_||!o.canPlayType('audio/webm; codecs="vorbis"').replace(/^no$/,"")),webm:!(_||!o.canPlayType('audio/webm; codecs="vorbis"').replace(/^no$/,"")),dolby:!!o.canPlayType('audio/mp4; codecs="ec-3"').replace(/^no$/,""),flac:!!(o.canPlayType("audio/x-flac;")||o.canPlayType("audio/flac;")).replace(/^no$/,"")},e},_unlockAudio:function(){var e=this||n;if(!e._audioUnlocked&&e.ctx){e._audioUnlocked=!1,e.autoUnlock=!1,e._mobileUnloaded||44100===e.ctx.sampleRate||(e._mobileUnloaded=!0,e.unload()),e._scratchBuffer=e.ctx.createBuffer(1,1,22050);var o=function(n){for(;e._html5AudioPool.length<e.html5PoolSize;)try{var t=new Audio;t._unlocked=!0,e._releaseHtml5Audio(t)}catch(n){e.noAudio=!0;break}for(var r=0;r<e._howls.length;r++)if(!e._howls[r]._webAudio)for(var a=e._howls[r]._getSoundIds(),u=0;u<a.length;u++){var d=e._howls[r]._soundById(a[u]);d&&d._node&&!d._node._unlocked&&(d._node._unlocked=!0,d._node.load())}e._autoResume();var i=e.ctx.createBufferSource();i.buffer=e._scratchBuffer,i.connect(e.ctx.destination),void 0===i.start?i.noteOn(0):i.start(0),"function"==typeof e.ctx.resume&&e.ctx.resume(),i.onended=function(){i.disconnect(0),e._audioUnlocked=!0,document.removeEventListener("touchstart",o,!0),document.removeEventListener("touchend",o,!0),document.removeEventListener("click",o,!0),document.removeEventListener("keydown",o,!0);for(var n=0;n<e._howls.length;n++)e._howls[n]._emit("unlock")}};return document.addEventListener("touchstart",o,!0),document.addEventListener("touchend",o,!0),document.addEventListener("click",o,!0),document.addEventListener("keydown",o,!0),e}},_obtainHtml5Audio:function(){var e=this||n;if(e._html5AudioPool.length)return e._html5AudioPool.pop();var o=(new Audio).play();return o&&"undefined"!=typeof Promise&&(o instanceof Promise||"function"==typeof o.then)&&o.catch(function(){console.warn("HTML5 Audio pool eLine truncated
|
||||||
|
/*! Spatial Plugin */
|
||||||
|
!function(){"use strict";HowlerGlobal.prototype._pos=[0,0,0],HowlerGlobal.prototype._orientation=[0,0,-1,0,1,0],HowlerGlobal.prototype.stereo=function(e){var n=this;if(!n.ctx||!n.ctx.listener)return n;for(var t=n._howls.length-1;t>=0;t--)n._howls[t].stereo(e);return n},HowlerGlobal.prototype.pos=function(e,n,t){var r=this;return r.ctx&&r.ctx.listener?(n="number"!=typeof n?r._pos[1]:n,t="number"!=typeof t?r._pos[2]:t,"number"!=typeof e?r._pos:(r._pos=[e,n,t],void 0!==r.ctx.listener.positionX?(r.ctx.listener.positionX.setTargetAtTime(r._pos[0],Howler.ctx.currentTime,.1),r.ctx.listener.positionY.setTargetAtTime(r._pos[1],Howler.ctx.currentTime,.1),r.ctx.listener.positionZ.setTargetAtTime(r._pos[2],Howler.ctx.currentTime,.1)):r.ctx.listener.setPosition(r._pos[0],r._pos[1],r._pos[2]),r)):r},HowlerGlobal.prototype.orientation=function(e,n,t,r,o,i){var a=this;if(!a.ctx||!a.ctx.listener)return a;var p=a._orientation;return n="number"!=typeof n?p[1]:n,t="number"!=typeof t?p[2]:t,r="number"!=typeof r?p[3]:r,o="number"!=typeof o?p[4]:o,i="number"!=typeof i?p[5]:i,"number"!=typeof e?p:(a._orientation=[e,n,t,r,o,i],void 0!==a.ctx.listener.forwardX?(a.ctx.listener.forwardX.setTargetAtTime(e,Howler.ctx.currentTime,.1),a.ctx.listener.forwardY.setTargetAtTime(n,Howler.ctx.currentTime,.1),a.ctx.listener.forwardZ.setTargetAtTime(t,Howler.ctx.currentTime,.1),a.ctx.listener.upX.setTargetAtTime(r,Howler.ctx.currentTime,.1),a.ctx.listener.upY.setTargetAtTime(o,Howler.ctx.currentTime,.1),a.ctx.listener.upZ.setTargetAtTime(i,Howler.ctx.currentTime,.1)):a.ctx.listener.setOrientation(e,n,t,r,o,i),a)},Howl.prototype.init=function(e){return function(n){var t=this;return t._orientation=n.orientation||[1,0,0],t._stereo=n.stereo||null,t._pos=n.pos||null,t._pannerAttr={coneInnerAngle:void 0!==n.coneInnerAngle?n.coneInnerAngle:360,coneOuterAngle:void 0!==n.coneOuterAngle?n.coneOuterAngle:360,coneOuterGain:void 0!==n.coneOuterGain?n.coneOuterGain:0,distanceModel:void 0!==n.distanceModel?n.distanceModel:"inverse",maxDistance:void 0!==n.maxDistance?n.maxDistance:1e4,panningModel:void 0!==n.panningModel?n.panningModel:"HRTF",refDistance:void 0!==n.refDistance?n.refDistance:1,rolloffFactor:void 0!==n.rolloffFactor?n.rolloffFactor:1},t._onstereo=n.onstereo?[{fn:n.onstereo}]:[],t._onpos=n.onpos?[{fn:n.onpos}]:[],t._onorientation=n.onorientation?[{fn:n.onorientation}]:[],e.call(this,n)}}(Howl.prototype.init),Howl.prototype.stereo=function(n,t){var r=this;if(!r._webAudio)return r;if("loaded"!==r._state)return r._queue.push({event:"stereo",action:function(){r.stereo(n,t)}}),r;var o=void 0===Howler.ctx.createStereoPanner?"spatial":"stereo";if(void 0===t){if("number"!=typeof n)return r._stereo;r._stereo=n,r._pos=[n,0,0]}for(var i=r._getSoundIds(t),a=0;a<i.length;a++){var p=r._soundById(i[a]);if(p){if("number"!=typeof n)return p._stereo;p._stereo=n,p._pos=[n,0,0],p._node&&(p._pannerAttr.panningModel="equalpower",p._panner&&p._panner.pan||e(p,o),"spatial"===o?void 0!==p._panner.positionX?(p._panner.positionX.setValueAtTime(n,Howler.ctx.currentTime),p._panner.positionY.setValueAtTime(0,Howler.ctx.currentTime),p._panner.positionZ.setValueAtTime(0,Howler.ctx.currentTime)):p._panner.setPosition(n,0,0):p._panner.pan.setValueAtTime(n,Howler.ctx.currentTime)),r._emit("stereo",p._id)}}return r},Howl.prototype.pos=function(n,t,r,o){var i=this;if(!i._webAudio)return i;if("loaded"!==i._state)return i._queue.push({event:"pos",action:function(){i.pos(n,t,r,o)}}),i;if(t="number"!=typeof t?0:t,r="number"!=typeof r?-.5:r,void 0===o){if("number"!=typeof n)return i._pos;i._pos=[n,t,r]}for(var a=i._getSoundIds(o),p=0;p<a.length;p++){var s=i._soundById(a[p]);if(s){if("number"!=typeof n)return s._pos;s._pos=[n,t,r],s._node&&(s._panner&&!s._panner.pan||e(s,"spatial"),void 0!==s._panner.positionX?(s._panner.positionX.setValueAtTime(n,Howler.ctx.currentTime),s._panner.positionY.setValueAtTime(t,Howler.ctx.currentTime),s._panner.positionZ.setValueAtTime(r,Howler.ctx.currentTime)):s._panner.setPosition(n,t,r)),i._emit("pos",s._id)}}return i},Howl.prototype.orientation=function(n,t,r,o){var i=this;if(!i._webAudio)return i;if("loaded"!==i._state)return i._queue.push({event:"orientation",action:function(){i.orientation(n,t,r,o)}}),i;if(t="number"!=typeof t?i._orientation[1]:t,r="number"!=typeof r?i._orientation[2]:r,void 0===o){if("number"!=typeof n)return i._orientation;i._orientation=[n,t,r]}for(var a=i._getSoundIds(o),p=0;p<a.length;p++){var s=i._soundById(a[p]);if(s){if("number"!=typeof n)return s._orientation;s._orientation=[n,t,r],s._node&&(s._panner||(s._pos||(s._pos=i._pos||[0,0,-.5]),e(s,"spatial")),void 0!==s._panner.orientationX?(s._panner.orientationX.setValueAtTime(n,Howler.ctx.currentTime),s._panner.orientationY.setValueAtTime(t,Howler.ctx.currentTime),s._panner.orientationZ.setValueAtTime(r,Howler.ctx.currentTime)):s._panner.setOrientation(n,t,r)),i._emit("orientation",s._id)}}return i},Howl.prototype.pannerAttr=function(){var n,t,r,o=this,i=arguments;if(!o._webAudioLine truncated
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
import json
|
||||||
|
import argparse
|
||||||
|
import soundfile as sf
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description="Compare TTS output with the original text using detailed comparison.")
|
||||||
|
parser.add_argument("--ttslistpath", help="Path to the ttsList.json file")
|
||||||
|
parser.add_argument("--wavfilespath", help="Path to the wav outputs folder")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
if not args.ttslistpath:
|
||||||
|
parser.error("[AllTalk TTSSRT] Please specify the path to the ttslist.json file using the --ttslistpath argument.")
|
||||||
|
if not args.wavfilespath:
|
||||||
|
parser.error("[AllTalk TTSSRT] Please specify the path to the wavs output folder file using the --wavfilespath argument.")
|
||||||
|
|
||||||
|
json_file_path = Path(args.ttslistpath).resolve()
|
||||||
|
audio_files_base_path = Path(args.wavfilespath).resolve()
|
||||||
|
|
||||||
|
print(f"[AllTalk TTSSRT]")
|
||||||
|
print("[AllTalk TTSSRT] \033[92mStarting SRT Subtitle generation:\033[0m")
|
||||||
|
print("[AllTalk TTSSRT]")
|
||||||
|
print("[AllTalk TTSSRT] \033[94mJSON file :\033[92m", json_file_path, "\033[0m")
|
||||||
|
print("[AllTalk TTSSRT] \033[94mWAV files :\033[92m", audio_files_base_path, "\033[0m")
|
||||||
|
print("[AllTalk TTSSRT]")
|
||||||
|
|
||||||
|
# Function to convert time in seconds to SRT time format
|
||||||
|
def format_srt_time(seconds):
|
||||||
|
hours = int(seconds // 3600)
|
||||||
|
minutes = int((seconds % 3600) // 60)
|
||||||
|
seconds = seconds % 60
|
||||||
|
milliseconds = int((seconds - int(seconds)) * 1000)
|
||||||
|
return f"{hours:02}:{minutes:02}:{int(seconds):02},{milliseconds:03}"
|
||||||
|
|
||||||
|
# Load the JSON data
|
||||||
|
with open(json_file_path, 'r') as json_file:
|
||||||
|
data = json.load(json_file)
|
||||||
|
|
||||||
|
# Initialize start time and SRT lines
|
||||||
|
start_time = 0.0
|
||||||
|
srt_lines = []
|
||||||
|
|
||||||
|
# Loop through the JSON data to build SRT entries
|
||||||
|
for entry in data:
|
||||||
|
file_name = Path(entry['fileUrl']).name # Get the file name from the URL
|
||||||
|
file_path = audio_files_base_path / file_name
|
||||||
|
print(f"[AllTalk TTSSRT] Processing file: {file_name}")
|
||||||
|
|
||||||
|
if not file_path.exists():
|
||||||
|
print(f"[AllTalk TTSSRT] Audio file does not exist: {file_path}")
|
||||||
|
continue
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Use soundfile to read the duration of the WAV file
|
||||||
|
with sf.SoundFile(str(file_path), 'r') as f:
|
||||||
|
duration = len(f) / f.samplerate
|
||||||
|
end_time = start_time + duration
|
||||||
|
|
||||||
|
# Format the SRT entry
|
||||||
|
start_timestamp = format_srt_time(start_time)
|
||||||
|
end_timestamp = format_srt_time(end_time)
|
||||||
|
srt_lines.append(f"{len(srt_lines)+1}\n{start_timestamp} --> {end_timestamp}\n{entry['text']}\n")
|
||||||
|
|
||||||
|
# Update the start time for the next entry
|
||||||
|
start_time = end_time
|
||||||
|
except RuntimeError as e:
|
||||||
|
print(f"[AllTalk TTSSRT] Error reading {file_path}: {e}")
|
||||||
|
|
||||||
|
# Join all SRT lines into the final SRT content
|
||||||
|
srt_content = "\n".join(srt_lines)
|
||||||
|
|
||||||
|
# Save the SRT content to a file
|
||||||
|
srt_file_path = audio_files_base_path / "subtitles.srt"
|
||||||
|
with open(srt_file_path, "w") as srt_file:
|
||||||
|
srt_file.write(srt_content)
|
||||||
|
|
||||||
|
print("[AllTalk TTSSRT]")
|
||||||
|
print(f"[AllTalk TTSSRT] \033[94mSRT file created at \033[0m{srt_file_path}")
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
/*! For license information please see 1995fcd6d39cade7d871.js.LICENSE.txt */
|
||||||
|
function _typeof(t){return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof(t)}function _regeneratorRuntime(){"use strict";_regeneratorRuntime=function(){return e};var t,e={},r=Object.prototype,n=r.hasOwnProperty,o=Object.defineProperty||function(t,e,r){t[e]=r.value},i="function"==typeof Symbol?Symbol:{},a=i.iterator||"@@iterator",c=i.asyncIterator||"@@asyncIterator",u=i.toStringTag||"@@toStringTag";function l(t,e,r){return Object.defineProperty(t,e,{value:r,enumerable:!0,configurable:!0,writable:!0}),t[e]}try{l({},"")}catch(t){l=function(t,e,r){return t[e]=r}}function f(t,e,r,n){var i=e&&e.prototype instanceof m?e:m,a=Object.create(i.prototype),c=new G(n||[]);return o(a,"_invoke",{value:S(t,r,c)}),a}function s(t,e,r){try{return{type:"normal",arg:t.call(e,r)}}catch(t){return{type:"throw",arg:t}}}e.wrap=f;var h="suspendedStart",p="suspendedYield",y="executing",d="completed",v={};function m(){}function g(){}function w(){}var x={};l(x,a,(function(){return this}));var E=Object.getPrototypeOf,b=E&&E(E(B([])));b&&b!==r&&n.call(b,a)&&(x=b);var T=w.prototype=m.prototype=Object.create(x);function _(t){["next","throw","return"].forEach((function(e){l(t,e,(function(t){return this._invoke(e,t)}))}))}function L(t,e){function r(o,i,a,c){var u=s(t[o],t,i);if("throw"!==u.type){var l=u.arg,f=l.value;return f&&"object"==_typeof(f)&&n.call(f,"__await")?e.resolve(f.__await).then((function(t){r("next",t,a,c)}),(function(t){r("throw",t,a,c)})):e.resolve(f).then((function(t){l.value=t,a(l)}),(function(t){return r("throw",t,a,c)}))}c(u.arg)}var i;o(this,"_invoke",{value:function(t,n){function o(){return new e((function(e,o){r(t,n,e,o)}))}return i=i?i.then(o,o):o()}})}function S(e,r,n){var o=h;return function(i,a){if(o===y)throw new Error("Generator is already running");if(o===d){if("throw"===i)throw a;return{value:t,done:!0}}for(n.method=i,n.arg=a;;){var c=n.delegate;if(c){var u=I(c,n);if(u){if(u===v)continue;return u}}if("next"===n.method)n.sent=n._sent=n.arg;else if("throw"===n.method){if(o===h)throw o=d,n.arg;n.dispatchException(n.arg)}else"return"===n.method&&n.abrupt("return",n.arg);o=y;var l=s(e,r,n);if("normal"===l.type){if(o=n.done?d:p,l.arg===v)continue;return{value:l.arg,done:n.done}}"throw"===l.type&&(o=d,n.method="throw",n.arg=l.arg)}}}function I(e,r){var n=r.method,o=e.iterator[n];if(o===t)return r.delegate=null,"throw"===n&&e.iterator.return&&(r.method="return",r.arg=t,I(e,r),"throw"===r.method)||"return"!==n&&(r.method="throw",r.arg=new TypeError("The iterator does not provide a '"+n+"' method")),v;var i=s(o,e.iterator,r.arg);if("throw"===i.type)return r.method="throw",r.arg=i.arg,r.delegate=null,v;var a=i.arg;return a?a.done?(r[e.resultName]=a.value,r.next=e.nextLoc,"return"!==r.method&&(r.method="next",r.arg=t),r.delegate=null,v):a:(r.method="throw",r.arg=new TypeError("iterator result is not an object"),r.delegate=null,v)}function O(t){var e={tryLoc:t[0]};1 in t&&(e.catchLoc=t[1]),2 in t&&(e.finallyLoc=t[2],e.afterLoc=t[3]),this.tryEntries.push(e)}function j(t){var e=t.completion||{};e.type="normal",delete e.arg,t.completion=e}function G(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(O,this),this.reset(!0)}function B(e){if(e||""===e){var r=e[a];if(r)return r.call(e);if("function"==typeof e.next)return e;if(!isNaN(e.length)){var o=-1,i=function r(){for(;++o<e.length;)if(n.call(e,o))return r.value=e[o],r.done=!1,r;return r.value=t,r.done=!0,r};return i.next=i}}throw new TypeError(_typeof(e)+" is not iterable")}return g.prototype=w,o(T,"constructor",{value:w,configurable:!0}),o(w,"constructor",{value:g,configurable:!0}),g.displayName=l(w,u,"GeneratorFunction"),e.isGeneratorFunction=function(t){var e="function"==typeof t&&t.constructor;return!!e&&(e===g||"GeneratorFunction"===(e.displayName||e.name))},e.mark=function(t){return Object.setPrototypeOf?Object.setPrototypeOf(t,w):(t.__proto__=w,l(t,u,"GeneratorFunction")),t.prototype=Object.create(T),t},e.awrap=function(t){return{__await:t}},_(L.prototype),l(L.prototype,c,(function(){return this})),e.AsyncIterator=L,e.async=function(t,r,n,o,i){void 0===i&&(i=Promise);var a=new L(f(t,r,n,o),i);return e.isGeneratorFunction(r)?a:a.next().then((function(t){return t.done?t.value:a.next()}))},_(T),l(T,u,"Generator"),l(T,a,(function(){return this})),l(T,"toString",(function(){return"[object Generator]"})),e.keys=function(t){var e=Object(t),r=[];for(var n in e)r.push(n);return r.reverse(),function t(){for(;r.length;){var n=r.pop();if(n in e)return t.value=n,t.done=!1,t}return t.done=!0,t}},e.values=B,G.prototype={constructor:G,reset:function(e){if(this.prev=0,this.next=0,this.sent=this._sent=t,this.done=!1,this.delegate=null,this.method="next",this.arg=t,this.tryEntries.forEach(j),!e)for(var r in this)"t"===r.charAt(0)&&n.call(this,r)&&!isNaN(+r.slice(1))&&(this[r]=t)},stop:function(){this.done=!0;var t=this.tryELine truncated
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
||||||
|
* See LICENSE in the project root for license information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ms-welcome__header {
|
||||||
|
padding: 20px;
|
||||||
|
padding-bottom: 30px;
|
||||||
|
padding-top: 100px;
|
||||||
|
display: -webkit-flex;
|
||||||
|
display: flex;
|
||||||
|
-webkit-flex-direction: column;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ms-welcome__main {
|
||||||
|
display: -webkit-flex;
|
||||||
|
display: flex;
|
||||||
|
-webkit-flex-direction: column;
|
||||||
|
flex-direction: column;
|
||||||
|
-webkit-flex-wrap: nowrap;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
-webkit-align-items: center;
|
||||||
|
align-items: center;
|
||||||
|
-webkit-flex: 1 0 0;
|
||||||
|
flex: 1 0 0;
|
||||||
|
padding: 10px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ms-welcome__main > h2 {
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ms-welcome__features {
|
||||||
|
list-style-type: none;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ms-welcome__features.ms-List .ms-ListItem {
|
||||||
|
padding-bottom: 20px;
|
||||||
|
display: -webkit-flex;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ms-welcome__features.ms-List .ms-ListItem > .ms-Icon {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ms-welcome__action.ms-Button--hero {
|
||||||
|
margin-top: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ms-Button.ms-Button--hero .ms-Button-label {
|
||||||
|
color: #0078d7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ms-Button.ms-Button--hero:hover .ms-Button-label,
|
||||||
|
.ms-Button.ms-Button--hero:focus .ms-Button-label{
|
||||||
|
color: #005a9e;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
b {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 839 B |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 8.8 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 99 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<!doctype html><html><head><meta charset="UTF-8"/><meta http-equiv="X-UA-Compatible" content="IE=Edge"/><script src="https://appsforoffice.microsoft.com/lib/1.1/hosted/office.js"></script><script defer="defer" src="polyfill.js"></script><script defer="defer" src="commands.js"></script></head><body></body></html>
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
!function(){var e={};e.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),Office.onReady((function(){})),("undefined"!=typeof self?self:"undefined"!=typeof window?window:void 0!==e.g?e.g:void 0).action=function(e){var n={type:Office.MailboxEnums.ItemNotificationMessageType.InformationalMessage,message:"Performed action.",icon:"Icon.80x80",persistent:!0};Office.context.mailbox.item.notificationMessages.replaceAsync("action",n),e.completed()}}();
|
||||||
|
//# sourceMappingURL=commands.js.map
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"commands.js","mappings":"YACA,IAAIA,EAAsB,CAAC,ECD3BA,EAAoBC,EAAI,WACvB,GAA0B,iBAAfC,WAAyB,OAAOA,WAC3C,IACC,OAAOC,MAAQ,IAAIC,SAAS,cAAb,EAChB,CAAE,MAAOC,GACR,GAAsB,iBAAXC,OAAqB,OAAOA,MACxC,CACA,CAPuB,GCOxBC,OAAOC,SAAQ,WACb,KAuBuB,oBAATC,KACVA,KACkB,oBAAXH,OACPA,YACkB,IAAXI,EAAAA,EACPA,EAAAA,OACAC,GAMJC,OA5BF,SAAgBC,GACd,IAAMC,EAAU,CACdC,KAAMR,OAAOS,aAAaC,4BAA4BC,qBACtDJ,QAAS,oBACTK,KAAM,aACNC,YAAY,GAIdb,OAAOc,QAAQC,QAAQC,KAAKC,qBAAqBC,aAAa,SAAUX,GAGxED,EAAMa,WACR,C","sources":["webpack://office-addin-taskpane-js/webpack/bootstrap","webpack://office-addin-taskpane-js/webpack/runtime/global","webpack://office-addin-taskpane-js/./src/commands/commands.js"],"sourcesContent":["// The require scope\nvar __webpack_require__ = {};\n\n","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","/*\n * Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n * See LICENSE in the project root for license information.\n */\n\n/* global global, Office, self, window */\n\nOffice.onReady(() => {\n // If needed, Office.js is ready to be called\n});\n\n/**\n * Shows a notification when the add-in command is executed.\n * @param event {Office.AddinCommands.Event}\n */\nfunction action(event) {\n const message = {\n type: Office.MailboxEnums.ItemNotificationMessageType.InformationalMessage,\n message: \"Performed action.\",\n icon: \"Icon.80x80\",\n persistent: true,\n };\n\n // Show a notification message\n Office.context.mailbox.item.notificationMessages.replaceAsync(\"action\", message);\n\n // Be sure to indicate when the add-in command function is complete\n event.completed();\n}\n\nfunction getGlobal() {\n return typeof self !== \"undefined\"\n ? self\n : typeof window !== \"undefined\"\n ? window\n : typeof global !== \"undefined\"\n ? global\n : undefined;\n}\n\nconst g = getGlobal();\n\n// The add-in command functions need to be available in global scope\ng.action = action;\n"],"names":["__webpack_require__","g","globalThis","this","Function","e","window","Office","onReady","self","global","undefined","action","event","message","type","MailboxEnums","ItemNotificationMessageType","InformationalMessage","icon","persistent","context","mailbox","item","notificationMessages","replaceAsync","completed"],"sourceRoot":""}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
<OfficeApp xmlns="http://schemas.microsoft.com/office/appforoffice/1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bt="http://schemas.microsoft.com/office/officeappbasictypes/1.0" xmlns:ov="http://schemas.microsoft.com/office/taskpaneappversionoverrides" xsi:type="TaskPaneApp">
|
||||||
|
<Id>68b6ad53-4f72-42a8-a971-a9643c2f409a</Id>
|
||||||
|
<Version>1.0.0.0</Version>
|
||||||
|
<ProviderName>AllTalk</ProviderName>
|
||||||
|
<DefaultLocale>en-US</DefaultLocale>
|
||||||
|
<DisplayName DefaultValue="AllTalk TTS"/>
|
||||||
|
<Description DefaultValue="Enhance your document creation with AllTalk TTS's advanced text-to-voice functionality. Requires connection to AllTalk server."/>
|
||||||
|
<IconUrl DefaultValue="http://127.0.0.1:7851/api/word_addin/assets/icon-32.png"/>
|
||||||
|
<HighResolutionIconUrl DefaultValue="http://127.0.0.1:7851/api/word_addin/assets/icon-64.png"/>
|
||||||
|
<SupportUrl DefaultValue="https://github.com/erew123/alltalk_tts/issues"/>
|
||||||
|
<AppDomains>
|
||||||
|
<AppDomain>https://www.contoso.com</AppDomain>
|
||||||
|
</AppDomains>
|
||||||
|
<Hosts>
|
||||||
|
<Host Name="Document"/>
|
||||||
|
</Hosts>
|
||||||
|
<DefaultSettings>
|
||||||
|
<SourceLocation DefaultValue="http://127.0.0.1:7851/api/word_addin/taskpane.html"/>
|
||||||
|
</DefaultSettings>
|
||||||
|
<Permissions>ReadWriteDocument</Permissions>
|
||||||
|
<VersionOverrides xmlns="http://schemas.microsoft.com/office/taskpaneappversionoverrides" xsi:type="VersionOverridesV1_0">
|
||||||
|
<Hosts>
|
||||||
|
<Host xsi:type="Document">
|
||||||
|
<DesktopFormFactor>
|
||||||
|
<!-- You can add GetStarted information here if needed -->
|
||||||
|
<FunctionFile resid="Commands.Url"/>
|
||||||
|
<ExtensionPoint xsi:type="PrimaryCommandSurface">
|
||||||
|
<OfficeTab id="TabHome">
|
||||||
|
<Group id="AllTalkGroup">
|
||||||
|
<Label resid="AllTalkGroup.Label"/>
|
||||||
|
<Icon>
|
||||||
|
<bt:Image size="16" resid="Icon.16x16"/>
|
||||||
|
<bt:Image size="32" resid="Icon.32x32"/>
|
||||||
|
<bt:Image size="80" resid="Icon.80x80"/>
|
||||||
|
</Icon>
|
||||||
|
<Control xsi:type="Button" id="AllTalkTaskpaneButton">
|
||||||
|
<Label resid="AllTalkTaskpaneButton.Label"/>
|
||||||
|
<Supertip>
|
||||||
|
<Title resid="AllTalkTaskpaneButton.Label"/>
|
||||||
|
<Description resid="AllTalkTaskpaneButton.Tooltip"/>
|
||||||
|
</Supertip>
|
||||||
|
<Icon>
|
||||||
|
<bt:Image size="16" resid="Icon.16x16"/>
|
||||||
|
<bt:Image size="32" resid="Icon.32x32"/>
|
||||||
|
<bt:Image size="80" resid="Icon.80x80"/>
|
||||||
|
</Icon>
|
||||||
|
<Action xsi:type="ShowTaskpane">
|
||||||
|
<TaskpaneId>ButtonId1</TaskpaneId>
|
||||||
|
<SourceLocation resid="Taskpane.Url"/>
|
||||||
|
</Action>
|
||||||
|
</Control>
|
||||||
|
</Group>
|
||||||
|
</OfficeTab>
|
||||||
|
</ExtensionPoint>
|
||||||
|
</DesktopFormFactor>
|
||||||
|
</Host>
|
||||||
|
</Hosts>
|
||||||
|
<Resources>
|
||||||
|
<bt:Images>
|
||||||
|
<bt:Image id="Icon.16x16" DefaultValue="http://127.0.0.1:7851/api/word_addin/assets/icon-16.png"/>
|
||||||
|
<bt:Image id="Icon.32x32" DefaultValue="http://127.0.0.1:7851/api/word_addin/assets/icon-32.png"/>
|
||||||
|
<bt:Image id="Icon.80x80" DefaultValue="http://127.0.0.1:7851/api/word_addin/assets/icon-80.png"/>
|
||||||
|
</bt:Images>
|
||||||
|
<bt:Urls>
|
||||||
|
<!-- Ensure that these URLs are pointing to valid locations -->
|
||||||
|
<bt:Url id="Commands.Url" DefaultValue="http://127.0.0.1:7851/api/word_addin/commands.html"/>
|
||||||
|
<bt:Url id="Taskpane.Url" DefaultValue="http://127.0.0.1:7851/api/word_addin/taskpane.html"/>
|
||||||
|
</bt:Urls>
|
||||||
|
<bt:ShortStrings>
|
||||||
|
<bt:String id="AllTalkGroup.Label" DefaultValue="AllTalk Controls"/>
|
||||||
|
<bt:String id="AllTalkTaskpaneButton.Label" DefaultValue="Open AllTalk"/>
|
||||||
|
</bt:ShortStrings>
|
||||||
|
<bt:LongStrings>
|
||||||
|
<bt:String id="AllTalkTaskpaneButton.Tooltip" DefaultValue="Open the AllTalk task pane to start using the add-in."/>
|
||||||
|
</bt:LongStrings>
|
||||||
|
</Resources>
|
||||||
|
</VersionOverrides>
|
||||||
|
</OfficeApp>
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
!function(){var t={35666:function(t){var r=function(t){"use strict";var r,e=Object.prototype,n=e.hasOwnProperty,i=Object.defineProperty||function(t,r,e){t[r]=e.value},o="function"==typeof Symbol?Symbol:{},u=o.iterator||"@@iterator",a=o.asyncIterator||"@@asyncIterator",c=o.toStringTag||"@@toStringTag";function s(t,r,e){return Object.defineProperty(t,r,{value:e,enumerable:!0,configurable:!0,writable:!0}),t[r]}try{s({},"")}catch(t){s=function(t,r,e){return t[r]=e}}function f(t,r,e,n){var o=r&&r.prototype instanceof y?r:y,u=Object.create(o.prototype),a=new j(n||[]);return i(u,"_invoke",{value:R(t,e,a)}),u}function l(t,r,e){try{return{type:"normal",arg:t.call(r,e)}}catch(t){return{type:"throw",arg:t}}}t.wrap=f;var h="suspendedStart",p="suspendedYield",v="executing",g="completed",d={};function y(){}function m(){}function b(){}var x={};s(x,u,(function(){return this}));var w=Object.getPrototypeOf,E=w&&w(w(P([])));E&&E!==e&&n.call(E,u)&&(x=E);var S=b.prototype=y.prototype=Object.create(x);function A(t){["next","throw","return"].forEach((function(r){s(t,r,(function(t){return this._invoke(r,t)}))}))}function O(t,r){function e(i,o,u,a){var c=l(t[i],t,o);if("throw"!==c.type){var s=c.arg,f=s.value;return f&&"object"==typeof f&&n.call(f,"__await")?r.resolve(f.__await).then((function(t){e("next",t,u,a)}),(function(t){e("throw",t,u,a)})):r.resolve(f).then((function(t){s.value=t,u(s)}),(function(t){return e("throw",t,u,a)}))}a(c.arg)}var o;i(this,"_invoke",{value:function(t,n){function i(){return new r((function(r,i){e(t,n,r,i)}))}return o=o?o.then(i,i):i()}})}function R(t,r,e){var n=h;return function(i,o){if(n===v)throw new Error("Generator is already running");if(n===g){if("throw"===i)throw o;return k()}for(e.method=i,e.arg=o;;){var u=e.delegate;if(u){var a=T(u,e);if(a){if(a===d)continue;return a}}if("next"===e.method)e.sent=e._sent=e.arg;else if("throw"===e.method){if(n===h)throw n=g,e.arg;e.dispatchException(e.arg)}else"return"===e.method&&e.abrupt("return",e.arg);n=v;var c=l(t,r,e);if("normal"===c.type){if(n=e.done?g:p,c.arg===d)continue;return{value:c.arg,done:e.done}}"throw"===c.type&&(n=g,e.method="throw",e.arg=c.arg)}}}function T(t,e){var n=e.method,i=t.iterator[n];if(i===r)return e.delegate=null,"throw"===n&&t.iterator.return&&(e.method="return",e.arg=r,T(t,e),"throw"===e.method)||"return"!==n&&(e.method="throw",e.arg=new TypeError("The iterator does not provide a '"+n+"' method")),d;var o=l(i,t.iterator,e.arg);if("throw"===o.type)return e.method="throw",e.arg=o.arg,e.delegate=null,d;var u=o.arg;return u?u.done?(e[t.resultName]=u.value,e.next=t.nextLoc,"return"!==e.method&&(e.method="next",e.arg=r),e.delegate=null,d):u:(e.method="throw",e.arg=new TypeError("iterator result is not an object"),e.delegate=null,d)}function I(t){var r={tryLoc:t[0]};1 in t&&(r.catchLoc=t[1]),2 in t&&(r.finallyLoc=t[2],r.afterLoc=t[3]),this.tryEntries.push(r)}function M(t){var r=t.completion||{};r.type="normal",delete r.arg,t.completion=r}function j(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(I,this),this.reset(!0)}function P(t){if(t){var e=t[u];if(e)return e.call(t);if("function"==typeof t.next)return t;if(!isNaN(t.length)){var i=-1,o=function e(){for(;++i<t.length;)if(n.call(t,i))return e.value=t[i],e.done=!1,e;return e.value=r,e.done=!0,e};return o.next=o}}return{next:k}}function k(){return{value:r,done:!0}}return m.prototype=b,i(S,"constructor",{value:b,configurable:!0}),i(b,"constructor",{value:m,configurable:!0}),m.displayName=s(b,c,"GeneratorFunction"),t.isGeneratorFunction=function(t){var r="function"==typeof t&&t.constructor;return!!r&&(r===m||"GeneratorFunction"===(r.displayName||r.name))},t.mark=function(t){return Object.setPrototypeOf?Object.setPrototypeOf(t,b):(t.__proto__=b,s(t,c,"GeneratorFunction")),t.prototype=Object.create(S),t},t.awrap=function(t){return{__await:t}},A(O.prototype),s(O.prototype,a,(function(){return this})),t.AsyncIterator=O,t.async=function(r,e,n,i,o){void 0===o&&(o=Promise);var u=new O(f(r,e,n,i),o);return t.isGeneratorFunction(e)?u:u.next().then((function(t){return t.done?t.value:u.next()}))},A(S),s(S,c,"Generator"),s(S,u,(function(){return this})),s(S,"toString",(function(){return"[object Generator]"})),t.keys=function(t){var r=Object(t),e=[];for(var n in r)e.push(n);return e.reverse(),function t(){for(;e.length;){var n=e.pop();if(n in r)return t.value=n,t.done=!1,t}return t.done=!0,t}},t.values=P,j.prototype={constructor:j,reset:function(t){if(this.prev=0,this.next=0,this.sent=this._sent=r,this.done=!1,this.delegate=null,this.method="next",this.arg=r,this.tryEntries.forEach(M),!t)for(var e in this)"t"===e.charAt(0)&&n.call(this,e)&&!isNaN(+e.slice(1))&&(this[e]=r)},stop:function(){this.done=!0;var t=this.tryEntries[0].completion;if("throw"===t.type)throw t.arg;return this.rval},dispatchException:function(t){if(this.done)throw t;var e=this;function i(n,i){return a.type="throw",a.arg=t,e.next=n,i&&(e.method="next",e.arg=r),!!i}for(var o=this.tryEntries.length-1;o>=0;--o){var u=this.tryEntries[o],aLine truncated
|
||||||
|
//# sourceMappingURL=polyfill.js.map
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"polyfill.js","mappings":"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 truncated
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||||
|
<title>AllTalk TTS Add-in</title>
|
||||||
|
<script src="https://appsforoffice.microsoft.com/lib/1.1/hosted/office.js"></script>
|
||||||
|
<link rel="stylesheet"
|
||||||
|
href="https://static2.sharepointonline.com/files/fabric/office-ui-fabric-core/11.0.0/css/fabric.min.css" />
|
||||||
|
<link href="1fda685b81e1123773f6.css" rel="stylesheet" />
|
||||||
|
<style>
|
||||||
|
label {
|
||||||
|
font-weight: 700;
|
||||||
|
display: block;
|
||||||
|
margin-top: 10px
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
width: 100%;
|
||||||
|
padding: 5px
|
||||||
|
}
|
||||||
|
|
||||||
|
.nice-button {
|
||||||
|
background-color: #0078d4;
|
||||||
|
color: #fff;
|
||||||
|
padding: 10px 20px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 16px;
|
||||||
|
transition: background-color .3s ease
|
||||||
|
}
|
||||||
|
|
||||||
|
.nice-button:hover {
|
||||||
|
background-color: #005a9e
|
||||||
|
}
|
||||||
|
|
||||||
|
#audioSource {
|
||||||
|
width: 300px;
|
||||||
|
height: 50px
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
margin-right: 10px
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group {
|
||||||
|
display: flex;
|
||||||
|
justify-content: start;
|
||||||
|
align-items: flex-end
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group>.input-container {
|
||||||
|
flex: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
width: 100%
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script defer="defer" src="polyfill.js"></script>
|
||||||
|
<script defer="defer" src="taskpane.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="ms-font-m ms-welcome ms-Fabric">
|
||||||
|
<header class="ms-welcome__header ms-bgColor-neutralLighter"><img width="90" height="90"
|
||||||
|
src="http://127.0.0.1:7851/api/word_addin/assets/logo-filled.png" alt="AllTalk TTS" title="AllTalk TTS" />
|
||||||
|
<h1 class="ms-font-su">AllTalk TTS</h1>
|
||||||
|
</header>
|
||||||
|
<main class="ms-welcome__main"><textarea id="text" rows="4" placeholder="Enter text here"
|
||||||
|
style="display:none"></textarea> <label for="voice">Voice:</label> <select id="voice" name="voice"
|
||||||
|
required></select> <label for="language">Language:</label> <select id="language" name="language"
|
||||||
|
value="English" required>
|
||||||
|
<option value="en" selected="selected">English</option>
|
||||||
|
<option value="ar">Arabic</option>
|
||||||
|
<option value="zh-cn">Chinese</option>
|
||||||
|
<option value="cs">Czech</option>
|
||||||
|
<option value="nl">Dutch</option>
|
||||||
|
<option value="fr">French</option>
|
||||||
|
<option value="de">German</option>
|
||||||
|
<option value="hu">Hungarian</option>
|
||||||
|
<option value="it">Italian</option>
|
||||||
|
<option value="ja">Japanese</option>
|
||||||
|
<option value="ko">Korean</option>
|
||||||
|
<option value="pl">Polish</option>
|
||||||
|
<option value="pt">Portuguese</option>
|
||||||
|
<option value="ru">Russian</option>
|
||||||
|
<option value="es">Spanish</option>
|
||||||
|
<option value="tr">Turkish</option>
|
||||||
|
</select><br><audio id="audioSource" controls autoplay></audio><br><button id="sendTextButton"
|
||||||
|
class="nice-button">Send Text to TTS</button><br><br><br><br>
|
||||||
|
<div class="input-group">
|
||||||
|
<div class="input-container"><label for="serverIP">Server IP:</label> <input id="serverIP" name="serverIP"
|
||||||
|
value="127.0.0.1" required></div>
|
||||||
|
<div class="input-container"><label for="portNumber">Port Number:</label> <input type="number"
|
||||||
|
id="portNumber" name="portNumber" value="7851" required></div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
<script src="1995fcd6d39cade7d871.js"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
/*! For license information please see taskpane.js.LICENSE.txt */
|
||||||
|
!function(){var t={27091:function(t){"use strict";t.exports=function(t,e){return e||(e={}),t?(t=String(t.__esModule?t.default:t),e.hash&&(t+=e.hash),e.maybeNeedQuotes&&/[\t\n\f\r "'=<>`]/.test(t)?'"'.concat(t,'"'):t):t}},44944:function(t,e,r){"use strict";t.exports=r.p+"assets/logo-filled.png"},36076:function(t,e,r){"use strict";t.exports=r.p+"1995fcd6d39cade7d871.js"},60806:function(t,e,r){"use strict";t.exports=r.p+"1fda685b81e1123773f6.css"}},e={};function r(n){var o=e[n];if(void 0!==o)return o.exports;var i=e[n]={exports:{}};return t[n](i,i.exports,r),i.exports}r.m=t,r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,{a:e}),e},r.d=function(t,e){for(var n in e)r.o(e,n)&&!r.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:e[n]})},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(t){if("object"==typeof window)return window}}(),r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},function(){var t;r.g.importScripts&&(t=r.g.location+"");var e=r.g.document;if(!t&&e&&(e.currentScript&&(t=e.currentScript.src),!t)){var n=e.getElementsByTagName("script");if(n.length)for(var o=n.length-1;o>-1&&!t;)t=n[o--].src}if(!t)throw new Error("Automatic publicPath is not supported in this browser");t=t.replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),r.p=t}(),r.b=document.baseURI||self.location.href,function(){function t(e){return t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},t(e)}function e(){"use strict";e=function(){return n};var r,n={},o=Object.prototype,i=o.hasOwnProperty,c=Object.defineProperty||function(t,e,r){t[e]=r.value},a="function"==typeof Symbol?Symbol:{},u=a.iterator||"@@iterator",f=a.asyncIterator||"@@asyncIterator",s=a.toStringTag||"@@toStringTag";function l(t,e,r){return Object.defineProperty(t,e,{value:r,enumerable:!0,configurable:!0,writable:!0}),t[e]}try{l({},"")}catch(r){l=function(t,e,r){return t[e]=r}}function h(t,e,r,n){var o=e&&e.prototype instanceof w?e:w,i=Object.create(o.prototype),a=new k(n||[]);return c(i,"_invoke",{value:I(t,r,a)}),i}function p(t,e,r){try{return{type:"normal",arg:t.call(e,r)}}catch(t){return{type:"throw",arg:t}}}n.wrap=h;var y="suspendedStart",v="suspendedYield",d="executing",m="completed",g={};function w(){}function b(){}function x(){}var E={};l(E,u,(function(){return this}));var L=Object.getPrototypeOf,_=L&&L(L(T([])));_&&_!==o&&i.call(_,u)&&(E=_);var j=x.prototype=w.prototype=Object.create(E);function O(t){["next","throw","return"].forEach((function(e){l(t,e,(function(t){return this._invoke(e,t)}))}))}function S(e,r){function n(o,c,a,u){var f=p(e[o],e,c);if("throw"!==f.type){var s=f.arg,l=s.value;return l&&"object"==t(l)&&i.call(l,"__await")?r.resolve(l.__await).then((function(t){n("next",t,a,u)}),(function(t){n("throw",t,a,u)})):r.resolve(l).then((function(t){s.value=t,a(s)}),(function(t){return n("throw",t,a,u)}))}u(f.arg)}var o;c(this,"_invoke",{value:function(t,e){function i(){return new r((function(r,o){n(t,e,r,o)}))}return o=o?o.then(i,i):i()}})}function I(t,e,n){var o=y;return function(i,c){if(o===d)throw new Error("Generator is already running");if(o===m){if("throw"===i)throw c;return{value:r,done:!0}}for(n.method=i,n.arg=c;;){var a=n.delegate;if(a){var u=P(a,n);if(u){if(u===g)continue;return u}}if("next"===n.method)n.sent=n._sent=n.arg;else if("throw"===n.method){if(o===y)throw o=m,n.arg;n.dispatchException(n.arg)}else"return"===n.method&&n.abrupt("return",n.arg);o=d;var f=p(t,e,n);if("normal"===f.type){if(o=n.done?m:v,f.arg===g)continue;return{value:f.arg,done:n.done}}"throw"===f.type&&(o=m,n.method="throw",n.arg=f.arg)}}}function P(t,e){var n=e.method,o=t.iterator[n];if(o===r)return e.delegate=null,"throw"===n&&t.iterator.return&&(e.method="return",e.arg=r,P(t,e),"throw"===e.method)||"return"!==n&&(e.method="throw",e.arg=new TypeError("The iterator does not provide a '"+n+"' method")),g;var i=p(o,t.iterator,e.arg);if("throw"===i.type)return e.method="throw",e.arg=i.arg,e.delegate=null,g;var c=i.arg;return c?c.done?(e[t.resultName]=c.value,e.next=t.nextLoc,"return"!==e.method&&(e.method="next",e.arg=r),e.delegate=null,g):c:(e.method="throw",e.arg=new TypeError("iterator result is not an object"),e.delegate=null,g)}function B(t){var e={tryLoc:t[0]};1 in t&&(e.catchLoc=t[1]),2 in t&&(e.finallyLoc=t[2],e.afterLoc=t[3]),this.tryEntries.push(e)}function N(t){var e=t.completion||{};e.type="normal",delete e.arg,t.completion=e}function k(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(B,this),this.reset(!0)}function T(e){if(e||""===e){var n=e[u];if(n)return n.call(e);if("function"==typeof e.next)return e;if(!isNaN(e.length)){var o=-1,c=function t(){for(;++o<e.length;)if(i.call(e,o))return t.value=e[o],t.done=!1,t;return t.value=r,t.done=!0,t};return c.next=c}}throw new TLine truncated
|
||||||
|
//# sourceMappingURL=taskpane.js.map
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"taskpane.js","mappings":"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 truncated
|
||||||
|
Before Width: | Height: | Size: 476 KiB |
|
Before Width: | Height: | Size: 547 KiB |
|
Before Width: | Height: | Size: 156 KiB |
@@ -9,4 +9,6 @@ Author BBC
|
|||||||
This file is licensed under the Creative Commons Attribution 3.0 Unported license.
|
This file is licensed under the Creative Commons Attribution 3.0 Unported license.
|
||||||
https://creativecommons.org/licenses/by/3.0/deed.en
|
https://creativecommons.org/licenses/by/3.0/deed.en
|
||||||
|
|
||||||
Downsampled to 22050hz, mono and cut shorter
|
Downsampled to 22050hz, mono and cut shorter.
|
||||||
|
|
||||||
|
This license applies to both the original file ( «Clint_Eastwood CC3.wav» ) and it's derivative, the enhanced file ( «Clint_Eastwood (enhanced)CC3.wav» ).
|
||||||