ajh-code commited on
Commit
2c8c506
·
verified ·
1 Parent(s): 16f5171

Add files using upload-large-folder tool

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. vendor/fish-speech/.dockerignore +158 -0
  2. vendor/fish-speech/.github/pull_request_template.md +7 -0
  3. vendor/fish-speech/.pre-commit-config.yaml +25 -0
  4. vendor/fish-speech/LICENSE +94 -0
  5. vendor/fish-speech/awesome_webui/.gitignore +24 -0
  6. vendor/fish-speech/awesome_webui/README.md +73 -0
  7. vendor/fish-speech/awesome_webui/eslint.config.js +23 -0
  8. vendor/fish-speech/awesome_webui/index.html +15 -0
  9. vendor/fish-speech/awesome_webui/package-lock.json +0 -0
  10. vendor/fish-speech/awesome_webui/package.json +45 -0
  11. vendor/fish-speech/awesome_webui/tsconfig.app.json +38 -0
  12. vendor/fish-speech/awesome_webui/tsconfig.json +7 -0
  13. vendor/fish-speech/awesome_webui/tsconfig.node.json +34 -0
  14. vendor/fish-speech/awesome_webui/vite.config.ts +113 -0
  15. vendor/fish-speech/docker/Dockerfile +398 -0
  16. vendor/fish-speech/docker/Dockerfile.rocm +106 -0
  17. vendor/fish-speech/docs/CNAME +1 -0
  18. vendor/fish-speech/docs/README.ar.md +199 -0
  19. vendor/fish-speech/docs/README.es.md +188 -0
  20. vendor/fish-speech/docs/README.ja.md +199 -0
  21. vendor/fish-speech/docs/README.ko.md +199 -0
  22. vendor/fish-speech/docs/README.pt-BR.md +199 -0
  23. vendor/fish-speech/docs/README.zh.md +199 -0
  24. vendor/fish-speech/docs/requirements.txt +3 -0
  25. vendor/fish-speech/fish_speech/callbacks/__init__.py +4 -0
  26. vendor/fish-speech/fish_speech/callbacks/grad_norm.py +113 -0
  27. vendor/fish-speech/fish_speech/callbacks/progress_bar.py +16 -0
  28. vendor/fish-speech/fish_speech/configs/base.yaml +90 -0
  29. vendor/fish-speech/fish_speech/configs/modded_dac_vq.yaml +50 -0
  30. vendor/fish-speech/fish_speech/configs/text2semantic_finetune.yaml +86 -0
  31. vendor/fish-speech/fish_speech/content_sequence.py +403 -0
  32. vendor/fish-speech/fish_speech/conversation.py +174 -0
  33. vendor/fish-speech/fish_speech/datasets/concat_repeat.py +53 -0
  34. vendor/fish-speech/fish_speech/datasets/protos/text-data.proto +24 -0
  35. vendor/fish-speech/fish_speech/datasets/protos/text_data_pb2.py +34 -0
  36. vendor/fish-speech/fish_speech/datasets/protos/text_data_stream.py +36 -0
  37. vendor/fish-speech/fish_speech/datasets/semantic.py +627 -0
  38. vendor/fish-speech/fish_speech/datasets/vqgan.py +145 -0
  39. vendor/fish-speech/fish_speech/i18n/README.md +27 -0
  40. vendor/fish-speech/fish_speech/i18n/__init__.py +3 -0
  41. vendor/fish-speech/fish_speech/i18n/core.py +40 -0
  42. vendor/fish-speech/fish_speech/i18n/locale/ar_SA.json +123 -0
  43. vendor/fish-speech/fish_speech/i18n/locale/en_US.json +123 -0
  44. vendor/fish-speech/fish_speech/i18n/locale/es_ES.json +123 -0
  45. vendor/fish-speech/fish_speech/i18n/locale/ja_JP.json +123 -0
  46. vendor/fish-speech/fish_speech/i18n/locale/ko_KR.json +123 -0
  47. vendor/fish-speech/fish_speech/i18n/locale/pt_BR.json +132 -0
  48. vendor/fish-speech/fish_speech/i18n/locale/zh_CN.json +123 -0
  49. vendor/fish-speech/fish_speech/i18n/scan.py +122 -0
  50. vendor/fish-speech/fish_speech/inference_engine/__init__.py +192 -0
vendor/fish-speech/.dockerignore ADDED
@@ -0,0 +1,158 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # .dockerignore
2
+
3
+ # Git and version control
4
+ .git
5
+ .gitignore
6
+ .gitattributes
7
+ .gitmodules
8
+
9
+ # IDE and editor files
10
+ .vscode/
11
+ .idea/
12
+ *.swp
13
+ *.swo
14
+ *~
15
+ .DS_Store
16
+ Thumbs.db
17
+
18
+ # Python cache and build artifacts
19
+ __pycache__/
20
+ *.py[cod]
21
+ *$py.class
22
+ *.so
23
+ .Python
24
+ build/
25
+ develop-eggs/
26
+ dist/
27
+ downloads/
28
+ eggs/
29
+ .eggs/
30
+ lib/
31
+ lib64/
32
+ parts/
33
+ sdist/
34
+ var/
35
+ wheels/
36
+ *.egg-info/
37
+ .installed.cfg
38
+ *.egg
39
+ MANIFEST
40
+
41
+ # Virtual environments
42
+ venv/
43
+ env/
44
+ ENV/
45
+ .venv/
46
+ .env/
47
+
48
+ # Testing
49
+ .pytest_cache/
50
+ .coverage
51
+ htmlcov/
52
+ .tox/
53
+ .nox/
54
+ coverage.xml
55
+ *.cover
56
+ .hypothesis/
57
+
58
+ # Jupyter Notebook
59
+ .ipynb_checkpoints
60
+ *.ipynb
61
+
62
+ # Logs
63
+ *.log
64
+ logs/
65
+
66
+ # Temporary files
67
+ tmp/
68
+ temp/
69
+ *.tmp
70
+ *.temp
71
+
72
+ # OS generated files
73
+ .DS_Store
74
+ .DS_Store?
75
+ ._*
76
+ .Spotlight-V100
77
+ .Trashes
78
+ ehthumbs.db
79
+ Thumbs.db
80
+
81
+ # Docker files (except the one being used)
82
+ docker/
83
+ Dockerfile*
84
+ docker-compose*.yml
85
+ .dockerignore
86
+
87
+ # Checkpoints and models (should be mounted)
88
+ checkpoints/
89
+ models/
90
+ *.pth
91
+ *.ckpt
92
+ *.safetensors
93
+ *.bin
94
+
95
+ # Reference voices (should be mounted)
96
+ references/
97
+
98
+ # Generated audio files
99
+ *.wav
100
+ *.mp3
101
+ *.flac
102
+ *.ogg
103
+ generated_audio.wav
104
+ fake.wav
105
+ fake.npy
106
+
107
+ # Cache directories
108
+ .cache/
109
+ cache/
110
+ .uv_cache/
111
+
112
+ # Development files
113
+ .env
114
+ .env.local
115
+ .env.development
116
+ .env.test
117
+ .env.production
118
+
119
+ # Test files
120
+ test_*.py
121
+ *_test.py
122
+ tests/
123
+
124
+ # CI/CD
125
+ .github/
126
+ .gitlab-ci.yml
127
+ .travis.yml
128
+ .circleci/
129
+ azure-pipelines.yml
130
+
131
+ # Monitoring and profiling
132
+ .prof
133
+ *.prof
134
+
135
+ # Backup files
136
+ *.bak
137
+ *.backup
138
+ *.old
139
+
140
+ # Large data files
141
+ *.csv
142
+ *.jsonl
143
+ *.parquet
144
+ *.h5
145
+ *.hdf5
146
+
147
+ # Audio processing temporary files
148
+ *.tmp.wav
149
+ *.temp.wav
150
+
151
+ # OLD:
152
+ # .github
153
+ # results
154
+ # data
155
+ # *.filelist
156
+ # /data_server/target
157
+ # checkpoints
158
+ # .venv
vendor/fish-speech/.github/pull_request_template.md ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ **Is this PR adding new feature or fix a BUG?**
2
+
3
+ Add feature / Fix BUG.
4
+
5
+ **Is this pull request related to any issue? If yes, please link the issue.**
6
+
7
+ #xxx
vendor/fish-speech/.pre-commit-config.yaml ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ci:
2
+ autoupdate_schedule: monthly
3
+
4
+ repos:
5
+ - repo: https://github.com/pycqa/isort
6
+ rev: 9.0.0a3
7
+ hooks:
8
+ - id: isort
9
+ args: [--profile=black]
10
+
11
+ - repo: https://github.com/psf/black-pre-commit-mirror
12
+ rev: 26.3.1
13
+ hooks:
14
+ - id: black
15
+
16
+ - repo: https://github.com/pre-commit/pre-commit-hooks
17
+ rev: v6.0.0
18
+ hooks:
19
+ - id: end-of-file-fixer
20
+ - id: check-yaml
21
+ - id: check-json
22
+ - id: mixed-line-ending
23
+ args: ["--fix=lf"]
24
+ - id: check-added-large-files
25
+ args: ["--maxkb=5000"]
vendor/fish-speech/LICENSE ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # FISH AUDIO RESEARCH LICENSE AGREEMENT
2
+
3
+ **Last Updated: March 7, 2026**
4
+
5
+ ## I. INTRODUCTION
6
+
7
+ This Agreement applies to any individual person or entity ("You", "Your" or "Licensee") that uses or distributes any portion or element of the Fish Audio Materials or Derivative Works thereof for any Research, Non-Commercial, or Commercial purpose. Capitalized terms not otherwise defined herein are defined in Section V below.
8
+
9
+ This Agreement is intended to allow research and non-commercial uses of the Materials free of charge. Any Commercial use of the Materials requires a separate license from Fish Audio.
10
+
11
+ By clicking "I Accept" or by using, distributing, or accessing any portion or element of the Fish Audio Materials or Derivative Works, You agree that You have read, understood and are bound by the terms of this Agreement. If You are acting on behalf of a company, organization or other entity, then "You" includes you and that entity, and You agree that You: (i) are an authorized representative of such entity with the authority to bind such entity to this Agreement, and (ii) You agree to the terms of this Agreement on that entity's behalf.
12
+
13
+ ## II. RESEARCH & NON-COMMERCIAL USE LICENSE
14
+
15
+ Subject to the terms of this Agreement, Fish Audio grants You a non-exclusive, worldwide, non-transferable, non-sublicensable, revocable and royalty-free limited license under Fish Audio's intellectual property or other rights owned by Fish Audio embodied in the Fish Audio Materials to use, reproduce, distribute, and create Derivative Works of, and make modifications to, the Fish Audio Materials for any Research or Non-Commercial Purpose.
16
+
17
+ "Research Purpose" means academic or scientific advancement, and in each case, is not primarily intended for commercial advantage or monetary compensation to You or others.
18
+
19
+ "Non-Commercial Purpose" means any purpose other than a Research Purpose that is not primarily intended for commercial advantage or monetary compensation to You or others, such as personal use (i.e., hobbyist) or evaluation and testing.
20
+
21
+ ## III. COMMERCIAL USE
22
+
23
+ **Any use of the Fish Audio Materials or Derivative Works for a Commercial Purpose requires a separate written license agreement from Fish Audio.** No commercial rights are granted under this Agreement.
24
+
25
+ "Commercial Purpose" means any purpose other than a Research Purpose or Non-Commercial Purpose that is primarily intended for or directed toward commercial advantage or monetary compensation to You or others, including but not limited to: (i) creating, modifying, or distributing Your product or service, including via a hosted service or application programming interface, (ii) Your business's or organization's internal operations, and (iii) any use in connection with a product or service for which You charge a fee or generate revenue, whether directly or indirectly.
26
+
27
+ To obtain a commercial license, please contact Fish Audio at:
28
+
29
+ - **Website:** [https://fish.audio](https://fish.audio)
30
+ - **Email:** business@fish.audio
31
+
32
+ ## IV. GENERAL TERMS
33
+
34
+ Your Research and Non-Commercial License under this Agreement is subject to the following terms.
35
+
36
+ ### a. Distribution & Attribution
37
+
38
+ If You distribute or make available the Fish Audio Materials or a Derivative Work to a third party, or a product or service that uses any portion of them, You shall: (i) provide a copy of this Agreement to that third party, (ii) retain the following attribution notice within a "Notice" text file distributed as a part of such copies: "This model is licensed under the Fish Audio Research License, Copyright © 39 AI, INC. All Rights Reserved.", and (iii) prominently display "Built with Fish Audio" on a related website, user interface, blogpost, about page, or product documentation.
39
+
40
+ If You create a Derivative Work, You may add your own attribution notice(s) to the "Notice" text file included with that Derivative Work, provided that You clearly indicate which attributions apply to the Fish Audio Materials and state in the "Notice" text file that You changed the Fish Audio Materials and how it was modified.
41
+
42
+ ### b. Use Restrictions
43
+
44
+ Your use of the Fish Audio Materials and Derivative Works, including any output or results of the Fish Audio Materials or Derivative Works, must comply with applicable laws and regulations (including Trade Control Laws and equivalent regulations) and adhere to Fish Audio's Acceptable Use Policy, which is hereby incorporated by reference.
45
+
46
+ Furthermore, You will not use the Fish Audio Materials or Derivative Works, or any output or results of the Fish Audio Materials or Derivative Works, to create or improve any foundational generative AI model (excluding the Models or Derivative Works).
47
+
48
+ ### c. Intellectual Property
49
+
50
+ **(i) Trademark License.** No trademark licenses are granted under this Agreement, and in connection with the Fish Audio Materials or Derivative Works, You may not use any name or mark owned by or associated with Fish Audio or any of its Affiliates, except as required under Section IV(a) herein.
51
+
52
+ **(ii) Ownership of Derivative Works.** As between You and Fish Audio, You are the owner of Derivative Works You create, subject to Fish Audio's ownership of the Fish Audio Materials and any Derivative Works made by or for Fish Audio.
53
+
54
+ **(iii) Ownership of Outputs.** As between You and Fish Audio, You own any outputs generated from the Models or Derivative Works to the extent permitted by applicable law.
55
+
56
+ **(iv) Disputes.** If You or Your Affiliate(s) institute litigation or other proceedings against Fish Audio (including a cross-claim or counterclaim in a lawsuit) alleging that the Fish Audio Materials, Derivative Works or associated outputs or results, or any portion of any of the foregoing, constitutes infringement of intellectual property or other rights owned or licensable by You, then any licenses granted to You under this Agreement shall terminate as of the date such litigation or claim is filed or instituted. You will indemnify and hold harmless Fish Audio from and against any claim by any third party arising out of or related to Your use or distribution of the Fish Audio Materials or Derivative Works in violation of this Agreement.
57
+
58
+ **(v) Feedback.** From time to time, You may provide Fish Audio with verbal and/or written suggestions, comments or other feedback related to Fish Audio's existing or prospective technology, products or services (collectively, "Feedback"). You are not obligated to provide Fish Audio with Feedback, but to the extent that You do, You hereby grant Fish Audio a perpetual, irrevocable, royalty-free, fully-paid, sub-licensable, transferable, non-exclusive, worldwide right and license to exploit the Feedback in any manner without restriction. Your Feedback is provided "AS IS" and You make no warranties whatsoever about any Feedback.
59
+
60
+ ### d. Disclaimer of Warranty
61
+
62
+ UNLESS REQUIRED BY APPLICABLE LAW, THE FISH AUDIO MATERIALS AND ANY OUTPUT AND RESULTS THEREFROM ARE PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. YOU ARE SOLELY RESPONSIBLE FOR DETERMINING THE APPROPRIATENESS OR LAWFULNESS OF USING OR REDISTRIBUTING THE FISH AUDIO MATERIALS, DERIVATIVE WORKS OR ANY OUTPUT OR RESULTS AND ASSUME ANY RISKS ASSOCIATED WITH YOUR USE OF THE FISH AUDIO MATERIALS, DERIVATIVE WORKS AND ANY OUTPUT AND RESULTS.
63
+
64
+ ### e. Limitation of Liability
65
+
66
+ IN NO EVENT WILL FISH AUDIO OR ITS AFFILIATES BE LIABLE UNDER ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, TORT, NEGLIGENCE, PRODUCTS LIABILITY, OR OTHERWISE, ARISING OUT OF THIS AGREEMENT, FOR ANY LOST PROFITS OR ANY DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL, EXEMPLARY OR PUNITIVE DAMAGES, EVEN IF FISH AUDIO OR ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF ANY OF THE FOREGOING.
67
+
68
+ ### f. Term and Termination
69
+
70
+ The term of this Agreement will commence upon Your acceptance of this Agreement or access to the Fish Audio Materials and will continue in full force and effect until terminated in accordance with the terms and conditions herein. Fish Audio may terminate this Agreement if You are in breach of any term or condition of this Agreement. Upon termination of this Agreement, You shall delete and cease use of any Fish Audio Materials or Derivative Works. Sections IV(d), (e), and (g) shall survive the termination of this Agreement.
71
+
72
+ ### g. Governing Law
73
+
74
+ This Agreement will be governed by and construed in accordance with the laws of the United States and the State of California without regard to choice of law principles, and the UN Convention on Contracts for International Sale of Goods does not apply to this Agreement.
75
+
76
+ ## V. DEFINITIONS
77
+
78
+ **"Affiliate(s)"** means any entity that directly or indirectly controls, is controlled by, or is under common control with the subject entity; for purposes of this definition, "control" means direct or indirect ownership or control of more than 50% of the voting interests of the subject entity.
79
+
80
+ **"Agreement"** means this Fish Audio Research License Agreement.
81
+
82
+ **"Derivative Work(s)"** means (a) any derivative work of the Fish Audio Materials as recognized by U.S. copyright laws and (b) any modifications to a Model, and any other model created which is based on or derived from the Model or the Model's output, including "fine tune" and "low-rank adaptation" models derived from a Model or a Model's output, but do not include the output of any Model.
83
+
84
+ **"Documentation"** means any specifications, manuals, documentation, and other written information provided by Fish Audio related to the Software or Models.
85
+
86
+ **"Fish Audio"** or **"we"** means 39 AI, INC. and its Affiliates.
87
+
88
+ **"Model(s)"** means, collectively, Fish Audio's proprietary models and algorithms, including machine-learning models, trained model weights and other elements of the foregoing.
89
+
90
+ **"Software"** means Fish Audio's proprietary software made available under this Agreement now or in the future.
91
+
92
+ **"Fish Audio Materials"** means, collectively, Fish Audio's proprietary Models, Software and Documentation (and any portion or combination thereof) made available under this Agreement.
93
+
94
+ **"Trade Control Laws"** means any applicable U.S. and non-U.S. export control and trade sanctions laws and regulations.
vendor/fish-speech/awesome_webui/.gitignore ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Logs
2
+ logs
3
+ *.log
4
+ npm-debug.log*
5
+ yarn-debug.log*
6
+ yarn-error.log*
7
+ pnpm-debug.log*
8
+ lerna-debug.log*
9
+
10
+ node_modules
11
+ dist
12
+ dist-ssr
13
+ *.local
14
+
15
+ # Editor directories and files
16
+ .vscode/*
17
+ !.vscode/extensions.json
18
+ .idea
19
+ .DS_Store
20
+ *.suo
21
+ *.ntvs*
22
+ *.njsproj
23
+ *.sln
24
+ *.sw?
vendor/fish-speech/awesome_webui/README.md ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # React + TypeScript + Vite
2
+
3
+ This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
4
+
5
+ Currently, two official plugins are available:
6
+
7
+ - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) (or [oxc](https://oxc.rs) when used in [rolldown-vite](https://vite.dev/guide/rolldown)) for Fast Refresh
8
+ - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
9
+
10
+ ## React Compiler
11
+
12
+ The React Compiler is currently not compatible with SWC. See [this issue](https://github.com/vitejs/vite-plugin-react/issues/428) for tracking the progress.
13
+
14
+ ## Expanding the ESLint configuration
15
+
16
+ If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
17
+
18
+ ```js
19
+ export default defineConfig([
20
+ globalIgnores(['dist']),
21
+ {
22
+ files: ['**/*.{ts,tsx}'],
23
+ extends: [
24
+ // Other configs...
25
+
26
+ // Remove tseslint.configs.recommended and replace with this
27
+ tseslint.configs.recommendedTypeChecked,
28
+ // Alternatively, use this for stricter rules
29
+ tseslint.configs.strictTypeChecked,
30
+ // Optionally, add this for stylistic rules
31
+ tseslint.configs.stylisticTypeChecked,
32
+
33
+ // Other configs...
34
+ ],
35
+ languageOptions: {
36
+ parserOptions: {
37
+ project: ['./tsconfig.node.json', './tsconfig.app.json'],
38
+ tsconfigRootDir: import.meta.dirname,
39
+ },
40
+ // other options...
41
+ },
42
+ },
43
+ ])
44
+ ```
45
+
46
+ You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:
47
+
48
+ ```js
49
+ // eslint.config.js
50
+ import reactX from 'eslint-plugin-react-x'
51
+ import reactDom from 'eslint-plugin-react-dom'
52
+
53
+ export default defineConfig([
54
+ globalIgnores(['dist']),
55
+ {
56
+ files: ['**/*.{ts,tsx}'],
57
+ extends: [
58
+ // Other configs...
59
+ // Enable lint rules for React
60
+ reactX.configs['recommended-typescript'],
61
+ // Enable lint rules for React DOM
62
+ reactDom.configs.recommended,
63
+ ],
64
+ languageOptions: {
65
+ parserOptions: {
66
+ project: ['./tsconfig.node.json', './tsconfig.app.json'],
67
+ tsconfigRootDir: import.meta.dirname,
68
+ },
69
+ // other options...
70
+ },
71
+ },
72
+ ])
73
+ ```
vendor/fish-speech/awesome_webui/eslint.config.js ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import js from '@eslint/js'
2
+ import globals from 'globals'
3
+ import reactHooks from 'eslint-plugin-react-hooks'
4
+ import reactRefresh from 'eslint-plugin-react-refresh'
5
+ import tseslint from 'typescript-eslint'
6
+ import { defineConfig, globalIgnores } from 'eslint/config'
7
+
8
+ export default defineConfig([
9
+ globalIgnores(['dist']),
10
+ {
11
+ files: ['**/*.{ts,tsx}'],
12
+ extends: [
13
+ js.configs.recommended,
14
+ tseslint.configs.recommended,
15
+ reactHooks.configs.flat.recommended,
16
+ reactRefresh.configs.vite,
17
+ ],
18
+ languageOptions: {
19
+ ecmaVersion: 2020,
20
+ globals: globals.browser,
21
+ },
22
+ },
23
+ ])
vendor/fish-speech/awesome_webui/index.html ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!doctype html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>Awesome WebUI</title>
8
+ </head>
9
+
10
+ <body>
11
+ <div id="root"></div>
12
+ <script type="module" src="/src/main.tsx"></script>
13
+ </body>
14
+
15
+ </html>
vendor/fish-speech/awesome_webui/package-lock.json ADDED
The diff for this file is too large to render. See raw diff
 
vendor/fish-speech/awesome_webui/package.json ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "awesome_webui",
3
+ "private": true,
4
+ "version": "0.0.0",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite",
8
+ "build": "tsc -b && vite build",
9
+ "lint": "eslint .",
10
+ "preview": "vite preview"
11
+ },
12
+ "dependencies": {
13
+ "@radix-ui/react-collapsible": "^1.1.12",
14
+ "@radix-ui/react-dialog": "^1.1.15",
15
+ "@radix-ui/react-label": "^2.1.8",
16
+ "@radix-ui/react-scroll-area": "^1.2.10",
17
+ "@radix-ui/react-separator": "^1.1.8",
18
+ "@radix-ui/react-slider": "^1.3.6",
19
+ "@radix-ui/react-slot": "^1.2.4",
20
+ "@radix-ui/react-switch": "^1.2.6",
21
+ "@radix-ui/react-toggle-group": "^1.1.11",
22
+ "@tailwindcss/vite": "^4.2.1",
23
+ "class-variance-authority": "^0.7.1",
24
+ "clsx": "^2.1.1",
25
+ "lucide-react": "^0.577.0",
26
+ "react": "^19.2.0",
27
+ "react-dom": "^19.2.0",
28
+ "tailwind-merge": "^3.5.0",
29
+ "tailwindcss": "^4.2.1"
30
+ },
31
+ "devDependencies": {
32
+ "@eslint/js": "^9.39.1",
33
+ "@types/node": "^24.10.1",
34
+ "@types/react": "^19.2.7",
35
+ "@types/react-dom": "^19.2.3",
36
+ "@vitejs/plugin-react-swc": "^4.2.2",
37
+ "eslint": "^9.39.1",
38
+ "eslint-plugin-react-hooks": "^7.0.1",
39
+ "eslint-plugin-react-refresh": "^0.4.24",
40
+ "globals": "^16.5.0",
41
+ "typescript": "~5.9.3",
42
+ "typescript-eslint": "^8.48.0",
43
+ "vite": "^7.3.1"
44
+ }
45
+ }
vendor/fish-speech/awesome_webui/tsconfig.app.json ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "compilerOptions": {
3
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
4
+ "target": "ES2022",
5
+ "useDefineForClassFields": true,
6
+ "lib": [
7
+ "ES2022",
8
+ "DOM",
9
+ "DOM.Iterable"
10
+ ],
11
+ "module": "ESNext",
12
+ "types": [
13
+ "vite/client"
14
+ ],
15
+ "skipLibCheck": true,
16
+ "baseUrl": ".",
17
+ "paths": {
18
+ "@/*": [
19
+ "./src/*"
20
+ ]
21
+ },
22
+ "moduleResolution": "bundler",
23
+ "allowImportingTsExtensions": true,
24
+ "verbatimModuleSyntax": true,
25
+ "moduleDetection": "force",
26
+ "noEmit": true,
27
+ "jsx": "react-jsx",
28
+ "strict": true,
29
+ "noUnusedLocals": true,
30
+ "noUnusedParameters": true,
31
+ "erasableSyntaxOnly": true,
32
+ "noFallthroughCasesInSwitch": true,
33
+ "noUncheckedSideEffectImports": true
34
+ },
35
+ "include": [
36
+ "src"
37
+ ]
38
+ }
vendor/fish-speech/awesome_webui/tsconfig.json ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ {
2
+ "files": [],
3
+ "references": [
4
+ { "path": "./tsconfig.app.json" },
5
+ { "path": "./tsconfig.node.json" }
6
+ ]
7
+ }
vendor/fish-speech/awesome_webui/tsconfig.node.json ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "compilerOptions": {
3
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
4
+ "target": "ES2023",
5
+ "lib": [
6
+ "ES2023"
7
+ ],
8
+ "module": "ESNext",
9
+ "types": [
10
+ "node"
11
+ ],
12
+ "skipLibCheck": true,
13
+ "baseUrl": ".",
14
+ "paths": {
15
+ "@/*": [
16
+ "./src/*"
17
+ ]
18
+ },
19
+ "moduleResolution": "bundler",
20
+ "allowImportingTsExtensions": true,
21
+ "verbatimModuleSyntax": true,
22
+ "moduleDetection": "force",
23
+ "noEmit": true,
24
+ "strict": true,
25
+ "noUnusedLocals": true,
26
+ "noUnusedParameters": true,
27
+ "erasableSyntaxOnly": true,
28
+ "noFallthroughCasesInSwitch": true,
29
+ "noUncheckedSideEffectImports": true
30
+ },
31
+ "include": [
32
+ "vite.config.ts"
33
+ ]
34
+ }
vendor/fish-speech/awesome_webui/vite.config.ts ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import fs from 'node:fs'
2
+ import { defineConfig, type Plugin } from 'vite'
3
+ import react from '@vitejs/plugin-react-swc'
4
+ import tailwindcss from '@tailwindcss/vite'
5
+ import path from 'node:path'
6
+
7
+ function inlineEntryAssets(): Plugin {
8
+ let resolvedOutDir = ''
9
+
10
+ return {
11
+ name: 'inline-entry-assets',
12
+ apply: 'build',
13
+ configResolved(config) {
14
+ resolvedOutDir = path.resolve(config.root, config.build.outDir)
15
+ },
16
+ closeBundle() {
17
+ const indexHtmlPath = path.join(resolvedOutDir, 'index.html')
18
+ if (!fs.existsSync(indexHtmlPath)) {
19
+ return
20
+ }
21
+
22
+ const filesToDelete = new Set<string>()
23
+ const escapeInlineScript = (code: string) => code.replace(/<\/script/gi, '<\\/script')
24
+ const escapeInlineStyle = (code: string) => code.replace(/<\/style/gi, '<\\/style')
25
+ const normalizeFileName = (assetPath: string) =>
26
+ assetPath.replace(/^\//, '').replace(/^\.\//, '')
27
+ const readBuiltAsset = (assetPath: string) => {
28
+ const fileName = normalizeFileName(assetPath)
29
+ const absolutePath = path.join(resolvedOutDir, fileName)
30
+ if (!fs.existsSync(absolutePath)) {
31
+ return null
32
+ }
33
+
34
+ filesToDelete.add(absolutePath)
35
+ return fs.readFileSync(absolutePath, 'utf8')
36
+ }
37
+
38
+ let html = fs.readFileSync(indexHtmlPath, 'utf8')
39
+
40
+ html = html.replace(
41
+ /<link rel="modulepreload"[^>]+href="([^"]+)"[^>]*>/g,
42
+ (_fullMatch, href: string) => {
43
+ const absolutePath = path.join(resolvedOutDir, normalizeFileName(href))
44
+ if (fs.existsSync(absolutePath)) {
45
+ filesToDelete.add(absolutePath)
46
+ }
47
+ return ''
48
+ },
49
+ )
50
+
51
+ html = html.replace(
52
+ /<link rel="stylesheet"[^>]+href="([^"]+)"[^>]*>/g,
53
+ (fullMatch, href: string) => {
54
+ const assetSource = readBuiltAsset(href)
55
+ if (!assetSource) {
56
+ return fullMatch
57
+ }
58
+
59
+ return `<style>${escapeInlineStyle(assetSource)}</style>`
60
+ },
61
+ )
62
+
63
+ html = html.replace(
64
+ /<script type="module"[^>]+src="([^"]+)"[^>]*><\/script>/g,
65
+ (fullMatch, src: string) => {
66
+ const chunkCode = readBuiltAsset(src)
67
+ if (!chunkCode) {
68
+ return fullMatch
69
+ }
70
+
71
+ return `<script type="module">${escapeInlineScript(chunkCode)}</script>`
72
+ },
73
+ )
74
+
75
+ fs.writeFileSync(indexHtmlPath, html)
76
+
77
+ for (const filePath of filesToDelete) {
78
+ fs.rmSync(filePath, { force: true })
79
+ }
80
+
81
+ fs.rmSync(path.join(resolvedOutDir, 'vite.svg'), { force: true })
82
+ fs.rmSync(path.join(resolvedOutDir, 'assets'), { recursive: true, force: true })
83
+ },
84
+ }
85
+ }
86
+
87
+ // https://vite.dev/config/
88
+ export default defineConfig({
89
+ plugins: [react(), tailwindcss(), inlineEntryAssets()],
90
+ publicDir: false,
91
+ resolve: {
92
+ alias: {
93
+ '@': path.resolve(__dirname, './src'),
94
+ },
95
+ },
96
+ build: {
97
+ assetsInlineLimit: Number.MAX_SAFE_INTEGER,
98
+ cssCodeSplit: false,
99
+ modulePreload: false,
100
+ rollupOptions: {
101
+ output: {
102
+ inlineDynamicImports: true,
103
+ },
104
+ },
105
+ },
106
+ server: {
107
+ proxy: {
108
+ '/v1': 'http://localhost:8888',
109
+ '/v2': 'http://localhost:8888',
110
+ '/health': 'http://localhost:8888',
111
+ },
112
+ },
113
+ })
vendor/fish-speech/docker/Dockerfile ADDED
@@ -0,0 +1,398 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # docker/Dockerfile
2
+
3
+ # IMPORTANT: The docker images do not contain the checkpoints. You need to mount the checkpoints to the container.
4
+
5
+ # Build the image:
6
+ # docker build \
7
+ # --platform linux/amd64 \
8
+ # -f docker/Dockerfile \
9
+ # --build-arg BACKEND=[cuda, cpu] \
10
+ # --target [webui, server] \
11
+ # -t fish-speech-[webui, server]:[cuda, cpu] .
12
+
13
+ # e.g. for building the webui:
14
+ # docker build \
15
+ # --platform linux/amd64 \
16
+ # -f docker/Dockerfile \
17
+ # --build-arg BACKEND=cuda \
18
+ # --target webui \
19
+ # -t fish-speech-webui:cuda .
20
+
21
+ # e.g. for building the server:
22
+ # docker build \
23
+ # --platform linux/amd64 \
24
+ # -f docker/Dockerfile \
25
+ # --build-arg BACKEND=cuda \
26
+ # --target server \
27
+ # -t fish-speech-server:cuda .
28
+
29
+
30
+
31
+ # Multi-platform build:
32
+ # docker buildx build \
33
+ # --platform linux/amd64,linux/arm64 \
34
+ # -f docker/Dockerfile \
35
+ # --build-arg BACKEND=cpu \
36
+ # --target webui \
37
+ # -t fish-speech-webui:cpu .
38
+
39
+
40
+ # Running the image interactively:
41
+ # docker run \
42
+ # --gpus all \
43
+ # -v /path/to/fish-speech/checkpoints:/app/checkpoints \
44
+ # -e COMPILE=1 \ ... or -e COMPILE=0 \
45
+ # -it fish-speech-[webui, server]:[cuda, cpu]
46
+
47
+ # E.g. running the webui:
48
+ # docker run \
49
+ # --gpus all \
50
+ # -v ./checkpoints:/app/checkpoints \
51
+ # -e COMPILE=1 \
52
+ # -p 7860:7860 \
53
+ # fish-speech-webui:cuda
54
+
55
+ # E.g. running the server:
56
+ # docker run \
57
+ # --gpus all \
58
+ # -v ./checkpoints:/app/checkpoints \
59
+ # -p 8080:8080 \
60
+ # -it fish-speech-server:cuda
61
+
62
+
63
+ # Select the specific cuda version (see https://hub.docker.com/r/nvidia/cuda/)
64
+ ARG CUDA_VER=12.9.0
65
+ # Adapt the uv extra to fit the cuda version (one of [cu126, cu128, cu129])
66
+ ARG UV_EXTRA=cu129
67
+ ARG BACKEND=cuda
68
+
69
+ ARG UBUNTU_VER=24.04
70
+ ARG PY_VER=3.12
71
+ ARG UV_VERSION=0.8.15
72
+
73
+ # Create non-root user early for security
74
+ ARG USERNAME=fish
75
+ ARG USER_UID=1000
76
+ ARG USER_GID=1000
77
+
78
+ ##############################################################
79
+ # Base stage per backend
80
+ ##############################################################
81
+
82
+ # --- CUDA (x86_64) ---
83
+ FROM nvidia/cuda:${CUDA_VER}-cudnn-runtime-ubuntu${UBUNTU_VER} AS base-cuda
84
+ ENV DEBIAN_FRONTEND=noninteractive
85
+
86
+ # Install system dependencies in a single layer with cleanup
87
+ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
88
+ --mount=type=cache,target=/var/lib/apt,sharing=locked \
89
+ set -eux \
90
+ && rm -f /etc/apt/apt.conf.d/docker-clean \
91
+ && echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' >/etc/apt/apt.conf.d/keep-cache \
92
+ && apt-get update \
93
+ && apt-get install -y --no-install-recommends \
94
+ python3-pip \
95
+ python3-dev \
96
+ git \
97
+ ca-certificates \
98
+ curl \
99
+ && apt-get clean \
100
+ && rm -rf /var/lib/apt/lists/*
101
+
102
+ # --- CPU-only (portable x86_64) ---
103
+ FROM python:${PY_VER}-slim AS base-cpu
104
+ ENV UV_EXTRA=cpu
105
+
106
+ # Install system dependencies in a single layer with cleanup
107
+ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
108
+ --mount=type=cache,target=/var/lib/apt,sharing=locked \
109
+ set -eux \
110
+ && rm -f /etc/apt/apt.conf.d/docker-clean \
111
+ && echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' >/etc/apt/apt.conf.d/keep-cache \
112
+ && apt-get update \
113
+ && apt-get install -y --no-install-recommends \
114
+ git \
115
+ ca-certificates \
116
+ curl \
117
+ && apt-get clean \
118
+ && rm -rf /var/lib/apt/lists/*
119
+
120
+
121
+ ##############################################################
122
+ # UV stage
123
+ ##############################################################
124
+
125
+ ARG UV_VERSION
126
+ FROM ghcr.io/astral-sh/uv:${UV_VERSION} AS uv-bin
127
+
128
+ ##############################################################
129
+ # Shared app base stage
130
+ ##############################################################
131
+
132
+ FROM base-${BACKEND} AS app-base
133
+
134
+ ARG PY_VER
135
+ ARG BACKEND
136
+ ARG USERNAME
137
+ ARG USER_UID
138
+ ARG USER_GID
139
+ ARG UV_VERSION
140
+ ARG UV_EXTRA
141
+
142
+ ENV BACKEND=${BACKEND} \
143
+ DEBIAN_FRONTEND=noninteractive \
144
+ PYTHONDONTWRITEBYTECODE=1 \
145
+ PYTHONUNBUFFERED=1
146
+
147
+ # System dependencies for audio processing
148
+ ARG DEPENDENCIES=" \
149
+ libsox-dev \
150
+ build-essential \
151
+ cmake \
152
+ libasound-dev \
153
+ portaudio19-dev \
154
+ libportaudio2 \
155
+ libportaudiocpp0 \
156
+ ffmpeg"
157
+
158
+ # Install system dependencies with caching and cleanup
159
+ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
160
+ --mount=type=cache,target=/var/lib/apt,sharing=locked \
161
+ set -eux \
162
+ && rm -f /etc/apt/apt.conf.d/docker-clean \
163
+ && echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' >/etc/apt/apt.conf.d/keep-cache \
164
+ && apt-get update \
165
+ && apt-get install -y --no-install-recommends ${DEPENDENCIES} \
166
+ && apt-get clean \
167
+ && rm -rf /var/lib/apt/lists/*
168
+
169
+ # Install specific uv version
170
+ COPY --from=uv-bin /uv /uvx /bin/
171
+
172
+ # RUN groupadd --gid ${USER_GID} ${USERNAME} \
173
+ # && useradd --uid ${USER_UID} --gid ${USER_GID} -m ${USERNAME} \
174
+ # && mkdir -p /app /home/${USERNAME}/.cache \
175
+ # && chown -R ${USERNAME}:${USERNAME} /app /home/${USERNAME}/.cache
176
+
177
+ # Create non-root user (or use existing user)
178
+ RUN set -eux; \
179
+ if getent group ${USER_GID} >/dev/null 2>&1; then \
180
+ echo "Group ${USER_GID} already exists"; \
181
+ else \
182
+ groupadd -g ${USER_GID} ${USERNAME}; \
183
+ fi; \
184
+ if id -u ${USER_UID} >/dev/null 2>&1; then \
185
+ echo "User ${USER_UID} already exists, using existing user"; \
186
+ EXISTING_USER=$(id -un ${USER_UID}); \
187
+ mkdir -p /app /home/${EXISTING_USER}/.cache; \
188
+ chown -R ${USER_UID}:${USER_GID} /app /home/${EXISTING_USER}/.cache; \
189
+ else \
190
+ useradd -m -u ${USER_UID} -g ${USER_GID} ${USERNAME}; \
191
+ mkdir -p /app /home/${USERNAME}/.cache; \
192
+ chown -R ${USERNAME}:${USERNAME} /app /home/${USERNAME}/.cache; \
193
+ fi
194
+
195
+ # Create references directory with proper permissions for the non-root user
196
+ RUN mkdir -p /app/references \
197
+ && chown -R ${USER_UID}:${USER_GID} /app/references \
198
+ && chmod 755 /app/references
199
+
200
+ # Set working directory
201
+ WORKDIR /app
202
+
203
+ # Copy dependency files first for better caching
204
+ COPY --chown=${USER_UID}:${USER_GID} pyproject.toml uv.lock README.md ./
205
+
206
+ # Switch to non-root user for package installation
207
+ USER ${USER_UID}:${USER_GID}
208
+
209
+ # Install Python dependencies (cacheable by lockfiles)
210
+ # Use a generic cache path that works regardless of username
211
+ RUN --mount=type=cache,target=/tmp/uv-cache,uid=${USER_UID},gid=${USER_GID} \
212
+ uv python pin ${PY_VER} \
213
+ && uv sync --extra ${UV_EXTRA} --frozen --no-install-project
214
+
215
+ # Copy application code
216
+ COPY --chown=${USER_UID}:${USER_GID} . .
217
+
218
+ # Install the local package after copying source code
219
+ RUN uv sync --extra ${UV_EXTRA} --frozen
220
+
221
+ # Create common entrypoint script
222
+ RUN printf '%s\n' \
223
+ '#!/bin/bash' \
224
+ 'set -euo pipefail' \
225
+ '' \
226
+ '# Set user info from build args' \
227
+ 'USER_UID='${USER_UID} \
228
+ 'USER_GID='${USER_GID} \
229
+ '' \
230
+ '# Logging function' \
231
+ 'log() { echo "[$(date +"%Y-%m-%d %H:%M:%S")] $*" >&2; }' \
232
+ '' \
233
+ '# Validate environment' \
234
+ 'validate_env() {' \
235
+ ' if [ ! -d "/app/checkpoints" ]; then' \
236
+ ' log "WARNING: /app/checkpoints directory not found. Please mount your checkpoints."' \
237
+ ' fi' \
238
+ ' if [ ! -d "/app/references" ]; then' \
239
+ ' log "WARNING: /app/references directory not found. Please mount your references."' \
240
+ ' else' \
241
+ ' # Check if we can write to references directory' \
242
+ ' if [ ! -w "/app/references" ]; then' \
243
+ ' log "ERROR: Cannot write to /app/references directory. Please ensure the mounted directory has proper permissions for user with UID ${USER_UID}."' \
244
+ ' log "You can fix this by running: sudo chown -R ${USER_UID}:${USER_GID} /path/to/your/references"' \
245
+ ' exit 1' \
246
+ ' fi' \
247
+ ' fi' \
248
+ '}' \
249
+ '' \
250
+ '# Build device arguments' \
251
+ 'build_device_args() {' \
252
+ ' if [ "${BACKEND:-}" = "cpu" ]; then' \
253
+ ' echo "--device cpu"' \
254
+ ' fi' \
255
+ '}' \
256
+ '' \
257
+ '# Build compile arguments' \
258
+ 'build_compile_args() {' \
259
+ ' if [ "${1:-}" = "compile" ] || [ "${COMPILE:-}" = "1" ] || [ "${COMPILE:-}" = "true" ]; then' \
260
+ ' echo "--compile"' \
261
+ ' shift' \
262
+ ' fi' \
263
+ ' echo "$@"' \
264
+ '}' \
265
+ '' \
266
+ '# Health check function' \
267
+ 'health_check() {' \
268
+ ' local port=${1:-7860}' \
269
+ ' local endpoint=${2:-/health}' \
270
+ ' curl -f http://localhost:${port}${endpoint} 2>/dev/null || exit 1' \
271
+ '}' \
272
+ > /app/common.sh && chmod +x /app/common.sh
273
+
274
+ ##############################################################
275
+ # App stages
276
+ ##############################################################
277
+
278
+ # Gradio WebUI
279
+ FROM app-base AS webui
280
+ ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1
281
+
282
+ ARG GRADIO_SERVER_NAME="0.0.0.0"
283
+ ARG GRADIO_SERVER_PORT=7860
284
+ ARG LLAMA_CHECKPOINT_PATH="checkpoints/s2-pro"
285
+ ARG DECODER_CHECKPOINT_PATH="checkpoints/s2-pro/codec.pth"
286
+ ARG DECODER_CONFIG_NAME="modded_dac_vq"
287
+
288
+
289
+ # Expose port
290
+ EXPOSE ${GRADIO_SERVER_PORT}
291
+
292
+ # Set environment variables
293
+ ENV GRADIO_SERVER_NAME=${GRADIO_SERVER_NAME}
294
+ ENV GRADIO_SERVER_PORT=${GRADIO_SERVER_PORT}
295
+ ENV LLAMA_CHECKPOINT_PATH=${LLAMA_CHECKPOINT_PATH}
296
+ ENV DECODER_CHECKPOINT_PATH=${DECODER_CHECKPOINT_PATH}
297
+ ENV DECODER_CONFIG_NAME=${DECODER_CONFIG_NAME}
298
+
299
+ # Create webui entrypoint
300
+ RUN printf '%s\n' \
301
+ '#!/bin/bash' \
302
+ 'source /app/common.sh' \
303
+ '' \
304
+ 'log "Starting Fish Speech WebUI..."' \
305
+ 'validate_env' \
306
+ '' \
307
+ 'DEVICE_ARGS=$(build_device_args)' \
308
+ 'COMPILE_ARGS=$(build_compile_args "$@")' \
309
+ '' \
310
+ 'log "Device args: ${DEVICE_ARGS:-none}"' \
311
+ 'log "Compile args: ${COMPILE_ARGS}"' \
312
+ 'log "Server: ${GRADIO_SERVER_NAME}:${GRADIO_SERVER_PORT}"' \
313
+ '' \
314
+ 'exec uv run tools/run_webui.py \' \
315
+ ' --llama-checkpoint-path "${LLAMA_CHECKPOINT_PATH}" \' \
316
+ ' --decoder-checkpoint-path "${DECODER_CHECKPOINT_PATH}" \' \
317
+ ' --decoder-config-name "${DECODER_CONFIG_NAME}" \' \
318
+ ' ${DEVICE_ARGS} ${COMPILE_ARGS}' \
319
+ > /app/start_webui.sh && chmod +x /app/start_webui.sh
320
+
321
+ # Health check
322
+ HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
323
+ CMD curl -f http://localhost:${GRADIO_SERVER_PORT}/health || exit 1
324
+
325
+ ENTRYPOINT ["/app/start_webui.sh"]
326
+
327
+ # API Server
328
+ FROM app-base AS server
329
+ ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1
330
+
331
+ ARG API_SERVER_NAME="0.0.0.0"
332
+ ARG API_SERVER_PORT=8080
333
+ ARG LLAMA_CHECKPOINT_PATH="checkpoints/s2-pro"
334
+ ARG DECODER_CHECKPOINT_PATH="checkpoints/s2-pro/codec.pth"
335
+ ARG DECODER_CONFIG_NAME="modded_dac_vq"
336
+
337
+ # Expose port
338
+ EXPOSE ${API_SERVER_PORT}
339
+
340
+ # Set environment variables
341
+ ENV API_SERVER_NAME=${API_SERVER_NAME}
342
+ ENV API_SERVER_PORT=${API_SERVER_PORT}
343
+ ENV LLAMA_CHECKPOINT_PATH=${LLAMA_CHECKPOINT_PATH}
344
+ ENV DECODER_CHECKPOINT_PATH=${DECODER_CHECKPOINT_PATH}
345
+ ENV DECODER_CONFIG_NAME=${DECODER_CONFIG_NAME}
346
+
347
+ # Create server entrypoint
348
+ RUN printf '%s\n' \
349
+ '#!/bin/bash' \
350
+ 'source /app/common.sh' \
351
+ '' \
352
+ 'log "Starting Fish Speech API Server..."' \
353
+ 'validate_env' \
354
+ '' \
355
+ 'DEVICE_ARGS=$(build_device_args)' \
356
+ 'COMPILE_ARGS=$(build_compile_args "$@")' \
357
+ '' \
358
+ 'log "Device args: ${DEVICE_ARGS:-none}"' \
359
+ 'log "Compile args: ${COMPILE_ARGS}"' \
360
+ 'log "Server: ${API_SERVER_NAME}:${API_SERVER_PORT}"' \
361
+ '' \
362
+ 'exec uv run tools/api_server.py \' \
363
+ ' --listen "${API_SERVER_NAME}:${API_SERVER_PORT}" \' \
364
+ ' --llama-checkpoint-path "${LLAMA_CHECKPOINT_PATH}" \' \
365
+ ' --decoder-checkpoint-path "${DECODER_CHECKPOINT_PATH}" \' \
366
+ ' --decoder-config-name "${DECODER_CONFIG_NAME}" \' \
367
+ ' ${DEVICE_ARGS} ${COMPILE_ARGS}' \
368
+ > /app/start_server.sh && chmod +x /app/start_server.sh
369
+
370
+ # Health check
371
+ HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
372
+ CMD curl -f http://localhost:${API_SERVER_PORT}/v1/health || exit 1
373
+
374
+ ENTRYPOINT ["/app/start_server.sh"]
375
+
376
+ # Development stage
377
+ FROM app-base AS dev
378
+ USER root
379
+
380
+ # Install development tools
381
+ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
382
+ --mount=type=cache,target=/var/lib/apt,sharing=locked \
383
+ apt-get update \
384
+ && apt-get install -y --no-install-recommends \
385
+ vim \
386
+ htop \
387
+ strace \
388
+ gdb \
389
+ && apt-get clean \
390
+ && rm -rf /var/lib/apt/lists/*
391
+
392
+ USER ${USER_UID}:${USER_GID}
393
+
394
+ # Install development dependencies
395
+ RUN uv sync --extra ${UV_EXTRA} --dev
396
+
397
+ # Default to bash for development
398
+ ENTRYPOINT ["/bin/bash"]
vendor/fish-speech/docker/Dockerfile.rocm ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # docker/Dockerfile.rocm
2
+ #
3
+ # Fish Speech on AMD ROCm (RDNA3 / RDNA4).
4
+ # The checkpoints are NOT bundled — mount them at /app/checkpoints.
5
+ #
6
+ # Build:
7
+ # docker build -f docker/Dockerfile.rocm --target webui -t fish-speech-webui:rocm .
8
+ # docker build -f docker/Dockerfile.rocm --target server -t fish-speech-server:rocm .
9
+ #
10
+ # Run (webui):
11
+ # docker run --device=/dev/kfd --device=/dev/dri \
12
+ # --group-add video --group-add render \
13
+ # -e ROCBLAS_USE_HIPBLASLT=0 \
14
+ # -v ./checkpoints:/app/checkpoints \
15
+ # -p 7860:7860 fish-speech-webui:rocm
16
+
17
+ ARG ROCM_VERSION=7.2.3
18
+ ARG BASE_IMAGE=rocm/pytorch:rocm${ROCM_VERSION}_ubuntu24.04_py3.12_pytorch_release_2.9.1
19
+
20
+ FROM ${BASE_IMAGE} AS app-base
21
+
22
+ ENV DEBIAN_FRONTEND=noninteractive \
23
+ PYTHONDONTWRITEBYTECODE=1 \
24
+ PYTHONUNBUFFERED=1 \
25
+ ROCBLAS_USE_HIPBLASLT=0
26
+
27
+ RUN apt-get update \
28
+ && apt-get install -y --no-install-recommends \
29
+ git ffmpeg libsox-dev build-essential cmake \
30
+ libasound-dev portaudio19-dev libportaudio2 libportaudiocpp0 \
31
+ && apt-get clean \
32
+ && rm -rf /var/lib/apt/lists/*
33
+
34
+ WORKDIR /app
35
+
36
+ COPY . /app
37
+
38
+ # Install runtime dependencies WITHOUT torch/torchaudio — the ROCm base image
39
+ # already ships a gfx-tuned torch (2.9.1+rocm7.2.3). Then install the package
40
+ # itself with --no-deps so pip does not try to pull a CUDA/CPU torch.
41
+ RUN pip install --no-cache-dir --upgrade pip setuptools wheel \
42
+ && pip install --no-cache-dir \
43
+ numpy "transformers<=4.57.3" datasets lightning pytorch_lightning \
44
+ hydra-core natsort einops librosa rich "gradio>5.0.0" wandb grpcio kui \
45
+ uvicorn loguru loralib pyrootutils resampy "einx[torch]==0.2.2" zstandard \
46
+ pydub "modelscope==1.17.1" "opencc-python-reimplemented==0.1.7" \
47
+ silero-vad ormsgpack tiktoken "pydantic==2.9.2" cachetools \
48
+ descript-audio-codec safetensors soundfile vector_quantize_pytorch \
49
+ && pip install --no-cache-dir --no-build-isolation pyaudio \
50
+ && pip install --no-cache-dir --no-deps -e . \
51
+ # descript-audiotools pins protobuf<3.20, but fish-speech's generated proto
52
+ # code needs >=3.20. Override after install (mirrors pyproject's uv override).
53
+ && pip install --no-cache-dir --no-deps --upgrade "protobuf>=4.25,<6.0"
54
+
55
+ EXPOSE 7860 8080
56
+
57
+ # torch.compile is enabled by default (verified working on gfx1201/RDNA4).
58
+ # Set COMPILE=0 to disable.
59
+ ENV COMPILE=1
60
+
61
+ ##############################################################
62
+ # Gradio WebUI
63
+ ##############################################################
64
+ FROM app-base AS webui
65
+
66
+ ARG GRADIO_SERVER_NAME="0.0.0.0"
67
+ ARG GRADIO_SERVER_PORT=7860
68
+ ENV GRADIO_SERVER_NAME=${GRADIO_SERVER_NAME} \
69
+ GRADIO_SERVER_PORT=${GRADIO_SERVER_PORT}
70
+
71
+ RUN printf '%s\n' \
72
+ '#!/bin/bash' \
73
+ 'set -e' \
74
+ 'ARGS=()' \
75
+ 'if [ "${COMPILE:-0}" = "1" ] || [ "${COMPILE:-}" = "true" ]; then ARGS+=(--compile); fi' \
76
+ 'exec python tools/run_webui.py \' \
77
+ ' --llama-checkpoint-path checkpoints/s2-pro \' \
78
+ ' --decoder-checkpoint-path checkpoints/s2-pro/codec.pth \' \
79
+ ' --decoder-config-name modded_dac_vq "${ARGS[@]}"' \
80
+ > /app/start_webui.sh && chmod +x /app/start_webui.sh
81
+
82
+ ENTRYPOINT ["/app/start_webui.sh"]
83
+
84
+ ##############################################################
85
+ # API Server
86
+ ##############################################################
87
+ FROM app-base AS server
88
+
89
+ ARG API_SERVER_NAME="0.0.0.0"
90
+ ARG API_SERVER_PORT=8080
91
+ ENV API_SERVER_NAME=${API_SERVER_NAME} \
92
+ API_SERVER_PORT=${API_SERVER_PORT}
93
+
94
+ RUN printf '%s\n' \
95
+ '#!/bin/bash' \
96
+ 'set -e' \
97
+ 'ARGS=()' \
98
+ 'if [ "${COMPILE:-0}" = "1" ] || [ "${COMPILE:-}" = "true" ]; then ARGS+=(--compile); fi' \
99
+ 'exec python tools/api_server.py \' \
100
+ ' --listen 0.0.0.0:8080 \' \
101
+ ' --llama-checkpoint-path checkpoints/s2-pro \' \
102
+ ' --decoder-checkpoint-path checkpoints/s2-pro/codec.pth \' \
103
+ ' --decoder-config-name modded_dac_vq "${ARGS[@]}"' \
104
+ > /app/start_server.sh && chmod +x /app/start_server.sh
105
+
106
+ ENTRYPOINT ["/app/start_server.sh"]
vendor/fish-speech/docs/CNAME ADDED
@@ -0,0 +1 @@
 
 
1
+ speech.fish.audio
vendor/fish-speech/docs/README.ar.md ADDED
@@ -0,0 +1,199 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div align="center">
2
+ <h1>Fish Speech</h1>
3
+
4
+ [English](../README.md) | [简体中文](README.zh.md) | [Portuguese](README.pt-BR.md) | [日本語](README.ja.md) | [한국어](README.ko.md) | **العربية** | [Español](docs/README.es.md) <br>
5
+
6
+ <a href="https://www.producthunt.com/products/fish-speech?embed=true&utm_source=badge-top-post-badge&utm_medium=badge&utm_source=badge-fish&#0045;audio&#0045;s1" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/top-post-badge.svg?post_id=1023740&theme=light&period=daily&t=1761164814710" alt="Fish&#0032;Audio&#0032;S1 - Expressive&#0032;Voice&#0032;Cloning&#0032;and&#0032;Text&#0045;to&#0045;Speech | Product Hunt" style="width: 250px; height: 54px;" width="250" height="54" /></a>
7
+ <a href="https://trendshift.io/repositories/7014" target="_blank">
8
+ <img src="https://trendshift.io/api/badge/repositories/7014" alt="fishaudio%2Ffish-speech | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/>
9
+ </a>
10
+ <br>
11
+ </div>
12
+ <br>
13
+
14
+ <div align="center">
15
+ <img src="https://count.getloli.com/get/@fish-speech?theme=asoul" /><br>
16
+ </div>
17
+
18
+ <br>
19
+
20
+ <div align="center">
21
+ <a target="_blank" href="https://discord.gg/Es5qTB9BcN">
22
+ <img alt="Discord" src="https://img.shields.io/discord/1214047546020728892?color=%23738ADB&label=Discord&logo=discord&logoColor=white&style=flat-square"/>
23
+ </a>
24
+ <a target="_blank" href="https://hub.docker.com/r/fishaudio/fish-speech">
25
+ <img alt="Docker" src="https://img.shields.io/docker/pulls/fishaudio/fish-speech?style=flat-square&logo=docker"/>
26
+ </a>
27
+ <a target="_blank" href="https://pd.qq.com/s/bwxia254o">
28
+ <img alt="QQ Channel" src="https://img.shields.io/badge/QQ-blue?logo=tencentqq">
29
+ </a>
30
+ </div>
31
+
32
+ <div align="center">
33
+ <a target="_blank" href="https://huggingface.co/fishaudio/s2-pro">
34
+ <img alt="HuggingFace Model" src="https://img.shields.io/badge/🤗%20-models-orange"/>
35
+ </a>
36
+ <a target="_blank" href="https://fish.audio/blog/fish-audio-open-sources-s2/">
37
+ <img alt="Fish Audio Blog" src="https://img.shields.io/badge/Blog-Fish_Audio_S2-1f7a8c?style=flat-square&logo=readme&logoColor=white"/>
38
+ </a>
39
+ <a target="_blank" href="https://arxiv.org/abs/2603.08823">
40
+ <img alt="Paper | Technical Report" src="https://img.shields.io/badge/Paper-Technical_Report-b31b1b?style=flat-square"/>
41
+ </a>
42
+ </div>
43
+
44
+ > [!IMPORTANT]
45
+ > **إشعار الترخيص**
46
+ > يتم إصدار قاعدة الأكواد هذه وأوزان النماذج المرتبطة بها تحت **[FISH AUDIO RESEARCH LICENSE](../LICENSE)**. يرجى الرجوع إلى ملف [LICENSE](../LICENSE) لمزيد من التفاصيل.
47
+
48
+
49
+ > [!WARNING]
50
+ > **إخلاء المسؤولية القانونية**
51
+ > نحن لا نتحمل أي مسؤولية عن أي استخدام غير قانوني لقاعدة الأكواد. يرجى الرجوع إلى القوانين المحلية المتعلقة بـ DMCA والقوانين الأخرى ذات الصلة.
52
+
53
+ ## البداية السريعة
54
+
55
+ ### روابط التوثيق
56
+
57
+ هذا هو التوثيق الرسمي لـ Fish Audio S2، يرجى اتباع التعليمات للبدء بسهولة.
58
+
59
+ - [التثبيت](https://speech.fish.audio/ar/install/)
60
+ - [الاستدلال عبر خط الأوامر](https://speech.fish.audio/ar/inference/)
61
+ - [الاستدلال عبر واجهة الويب](https://speech.fish.audio/ar/inference/)
62
+ - [استدلال الخادم](https://speech.fish.audio/ar/server/)
63
+ - [نشر Docker](https://speech.fish.audio/ar/install/)
64
+
65
+ > [!IMPORTANT]
66
+ > **إذا كنت ترغب في استخدام خادم SGLang، فيرجى الرجوع إلى [SGLang-Omni README](https://github.com/sgl-project/sglang-omni/blob/main/sglang_omni/models/fishaudio_s2_pro/README.md).**
67
+ >
68
+ > **إذا كنت ترغب في استخدام خادم vLLM Omni، فيرجى الرجوع إلى [vLLM-Omni Fish Speech S2 Pro Recipe](https://github.com/vllm-project/vllm-omni/blob/main/recipes/fishaudio/Fish-Speech-S2-Pro.md) و[دليل المستخدم](https://github.com/vllm-project/vllm-omni/blob/main/docs/user_guide/examples/online_serving/text_to_speech.md#fish-speech-s2-pro).**
69
+
70
+ ### دليل وكيل LLM
71
+
72
+ ```
73
+ يرجى قراءة https://speech.fish.audio/ar/install/ أولاً، وتثبيت وتكوين Fish Audio S2 وفقاً للوثائق.
74
+ ```
75
+
76
+ ## Fish Audio S2 Pro
77
+ **نظام تحويل النص إلى كلام (TTS) متعدد اللغات الرائد في الصناعة، والذي يعيد تعريف حدود توليد الصوت.**
78
+
79
+ Fish Audio S2 Pro هو أحدث طراز متعدد الوسائط تم تطويره بواسطة [Fish Audio](https://fish.audio/). تم تدريبه على أكثر من **10 ملايين ساعة** من البيانات الصوتية الهائلة، التي تغطي أكثر من **80 لغة** حول العالم. من خلال بنية **ثنائية الانحدار الذاتي (Dual-AR)** المبتكرة وتقني�� توافق التعلم التعزيزي (RL)، يمكن لـ S2 Pro توليد كلام يتمتع بإحساس طبيعي وواقعي وعمق عاطفي كبير، مما يجعله رائداً في المنافسة بين الأنظمة المفتوحة والمغلقة المصدر.
80
+
81
+ تكمن القوة الضاربة لـ S2 Pro في دعمه للتحكم الدقيق للغاية في النبرة والعاطفة على مستوى **ما دون الكلمة (Sub-word Level)** من خلال وسوم اللغة الطبيعية (مثل `[whisper]` و `[excited]` و `[angry]`) ، مع دعم أصلي لتوليد متحدثين متعددين وحوارات متعددة الجولات بسياق طويل جداً.
82
+
83
+ تفضل بزيارة [موقع Fish Audio الرسمي](https://fish.audio/) الآن لتجربة العرض المباشر، أو اقرأ [تقريرنا الفني](https://arxiv.org/abs/2603.08823) و[مقال المدونة](https://fish.audio/blog/fish-audio-open-sources-s2/) للتعرف على المزيد.
84
+
85
+ ### متغيرات النموذج
86
+
87
+ | النموذج | الحجم | التوفر | الوصف |
88
+ |------|------|-------------|-------------|
89
+ | S2-Pro | 4 مليار معلمة | [HuggingFace](https://huggingface.co/fishaudio/s2-pro) | النموذج الرائد كامل الميزات، مع أعلى جودة واستقرار |
90
+
91
+ لمزيد من التفاصيل حول النماذج، يرجى مراجعة [التقرير الفني](https://arxiv.org/abs/2411.01156).
92
+
93
+ ## نتائج الاختبارات المرجعية (Benchmarks)
94
+
95
+ | الاختبار | Fish Audio S2 |
96
+ |------|------|
97
+ | Seed-TTS Eval — WER (الصينية) | **0.54%** (الأفضل إجمالاً) |
98
+ | Seed-TTS Eval — WER (الإنجليزية) | **0.99%** (الأفضل إجمالاً) |
99
+ | Audio Turing Test (مع التعليمات) | **0.515** متوسط خلفي (Posterior mean) |
100
+ | EmergentTTS-Eval — معدل الفوز | **81.88%** (الأعلى إجمالاً) |
101
+ | Fish Instruction Benchmark — TAR | **93.3%** |
102
+ | Fish Instruction Benchmark — الجودة | **4.51 / 5.0** |
103
+ | متعدد اللغات (MiniMax Testset) — أفضل WER | **11** لغة من أصل **24** |
104
+ | متعدد اللغات (MiniMax Testset) — أفضل SIM | **17** لغة من أصل **24** |
105
+
106
+ في تقييم Seed-TTS، حقق S2 أقل معدل خطأ في الكلمات (WER) بين جميع النماذج التي تم تقييمها (بما في ذلك الأنظمة مغلقة المصدر): Qwen3-TTS (0.77/1.24)، و MiniMax Speech-02 (0.99/1.90)، و Seed-TTS (1.12/2.25). وفي اختبار Audio Turing Test، سجل S2 قيمة 0.515 بزيادة قدرها 24% مقارنة بـ Seed-TTS (0.417) و 33% مقارنة بـ MiniMax-Speech (0.387). وفي EmergentTTS-Eval، تميز S2 بشكل خاص في أبعاد مثل اللغويات المصاحبة (معدل فوز 91.61%)، والجمل الاستفهامية (84.41%)، والتعقيد النحوي (83.39%).
107
+
108
+ ## أبرز المميزات
109
+
110
+ <img src="./assets/totalability.png" width=200%>
111
+
112
+ ### تحكم دقيق للغاية عبر اللغة الطبيعية
113
+
114
+ يمنح S2 Pro الصوت "روحاً" لا مثيل لها. من خلال صيغة `[tag]` البسيطة، يمكنك تضمين تعليمات عاطفية بدقة في أي موضع من النص.
115
+ - **دعم أكثر من 15,000 وسم فريد**: لا يقتصر على الإعدادات المسبقة الثابتة، بل يدعم **أوصاف النص الحر**. يمكنك تجربة `[whisper in small voice]` (همس بصوت منخفض)، أو `[professional broadcast tone]` (نبرة إذاعية احترافية)، أو `[pitch up]` (رفع طبقة الصوت).
116
+ - **مكتبة عواطف غنية**:
117
+ `[pause]` `[emphasis]` `[laughing]` `[inhale]` `[chuckle]` `[tsk]` `[singing]` `[excited]` `[laughing tone]` `[interrupting]` `[chuckling]` `[excited tone]` `[volume up]` `[echo]` `[angry]` `[low volume]` `[sigh]` `[low voice]` `[whisper]` `[screaming]` `[shouting]` `[loud]` `[surprised]` `[short pause]` `[exhale]` `[delight]` `[panting]` `[audience laughter]` `[with strong accent]` `[volume down]` `[clearing throat]` `[sad]` `[moaning]` `[shocked]`
118
+
119
+ ### بنية مبتكرة ثنائية الانحدار الذاتي (Dual-Autoregressive)
120
+
121
+ يعتمد S2 Pro بنية Dual-AR بنظام "رئيسي-تابع"، تتكون من Decoder-only Transformer وترميز صوتي RVQ (10 قواميس أكواد، بمعدل إطارات يبلغ حوالي 21 هرتز):
122
+
123
+ - **Slow AR (4 مليار معلمة)**: يعمل على طول المحور الزمني، ويتنبأ بقاموس الأكواد الدلالي الأساسي.
124
+ - **Fast AR (400 مليون معلمة)**: يولد الـ 9 قواميس المتبقية في كل خطوة زمنية، لاستعادة أدق التفاصيل الصوتية ببراعة.
125
+
126
+ يحقق هذا التصغير غير المتماثل أقصى درجات الدقة الصوتية مع زيادة سرعة الاستدلال بشكل كبير.
127
+
128
+ ### توافق التعلم التعزيزي (RL Alignment)
129
+
130
+ يستخدم S2 Pro تقنية **Group Relative Policy Optimization (GRPO)** للتوافق بعد التدريب. نستخدم نفس مجموعة النماذج المستخدمة في تنظيف البيانات وتصنيفها مباشرة كنماذج مكافأة (Reward Model)، مما يحل بشكل مثالي مشكلة عدم التطابق بين توزيع بيانات ما قبل التدريب وأهداف ما بعد التدريب.
131
+ - **إشارات مكافأة متعددة الأبعاد**: تقييم شامل للدقة الدلالية، والقدرة على اتباع التعليمات، وتسجيل التفضيل الصوتي، وتماثل نبرة الصوت، لضمان أن كل ثانية من الكلام المولد تتوافق مع الحدس البشري.
132
+
133
+ ### أداء استدلال تدفقي فائق (يعتمد على SGLang)
134
+
135
+ نظراً لأن بنية Dual-AR تتماثل هيكلياً مع بنية LLM القياسية، فإن S2 Pro يدعم أصلاً جميع ميزات تسريع الاستدلال في SGLang، بما في ذلك الدفعات المستمرة (Continuous Batching)، و Paged KV Cache، و CUDA Graph، والتخزين المؤقت للبادئة القائم على RadixAttention.
136
+
137
+ **أداء وحدة معالجة رسومات NVIDIA H200 واحدة:**
138
+ - **عامل الوقت الحقيقي (RTF)**: 0.195
139
+ - **تأخر الصوت الأول (TTFA)**: حوالي 100 مللي ثانية
140
+ - **إنتاجية فائقة السرعة**: تصل إلى 3000+ وسم صوتي/ثانية مع الحفاظ على RTF < 0.5
141
+
142
+ ### دعم قوي للغات المتعددة
143
+
144
+ يدعم S2 Pro أكثر من 80 لغة، مما يتيح تركيباً عالياً الجودة دون الحاجة إلى وحدات صوتية (phonemes) أو معالجة محددة لكل لغة:
145
+
146
+ - **المستوى الأول (Tier 1)**: اليابانية (ja)، الإنجليزية (en)، الصينية (zh)
147
+ - **المستوى الثاني (Tier 2)**: الكورية (ko)، الإسبانية (es)، البرتغالية (pt)، العربية (ar)، الروسية (ru)، الفرنسية (fr)، الألمانية (de)
148
+ - **تغطية عالمية**: sv, it, tr, no, nl, cy, eu, ca, da, gl, ta, hu, fi, pl, et, hi, la, ur, th, vi, jw, bn, yo, xsl, cs, sw, nn, he, ms, uk, id, kk, bg, lv, my, tl, sk, ne, fa, af, el, bo, hr, ro, sn, mi, yi, am, be, km, is, az, sd, br, sq, ps, mn, ht, ml, sr, sa, te, ka, bs, pa, lt, kn, si, hy, mr, as, gu, fo والمزيد.
149
+
150
+ ### توليد متحدثين متعددين أصلي
151
+
152
+ <img src="./assets/chattemplate.png" width=200%>
153
+
154
+ يسمح Fish Audio S2 للمستخدمين بتحميل عينة مرجعية تحتوي على متحدثين متعددين، وسيقوم النموذج بمعالجة ميزات كل متحدث عبر وسم `<|speaker:i|>`. بعد ذلك، يمكنك التحكم في أداء النموذج عبر وسم معرف المتحدث، مما يتيح لتوليد واحد أن يتضمن متحدثين متعددين. لم تعد هناك حاجة لتحميل عينة مرجعية منفصلة وتوليد صوت لكل متحدث على حدة كما كان في السابق.
155
+
156
+ ### توليد حوارات متعددة الجولات
157
+
158
+ بفضل توسيع سياق النموذج، يمكن لنموذجنا الآن الاستفادة من المعلومات السابقة لتحسين التعبير في المحتوى المولد لاحقاً، مما يعزز من طبيعية المحتوى.
159
+
160
+ ### استنساخ الصوت السريع
161
+
162
+ يدعم Fish Audio S2 استنساخاً دقيقاً للصوت باستخدام عينات مرجعية قصيرة (عادةً 10-30 ثانية). يلتقط النموذج نبرة الصوت وأسلوب الكلام والميول العاطفية، مما يولد أصواتاً مستنسخة واقعية ومتسقة دون الحاجة إلى ضبط دقيق إضافي.
163
+ لاستخدام خادم SGLang، يرجى الرجوع إلى [SGLang-Omni README](https://github.com/sgl-project/sglang-omni/blob/main/sglang_omni/models/fishaudio_s2_pro/README.md).
164
+
165
+ ---
166
+
167
+ ## شكر وتقدير
168
+
169
+ - [VITS2 (daniilrobnikov)](https://github.com/daniilrobnikov/vits2)
170
+ - [Bert-VITS2](https://github.com/fishaudio/Bert-VITS2)
171
+ - [GPT VITS](https://github.com/innnky/gpt-vits)
172
+ - [MQTTS](https://github.com/b04901014/MQTTS)
173
+ - [GPT Fast](https://github.com/pytorch-labs/gpt-fast)
174
+ - [GPT-SoVITS](https://github.com/RVC-Boss/GPT-SoVITS)
175
+ - [Qwen3](https://github.com/QwenLM/Qwen3)
176
+
177
+ ## التقرير الفني
178
+
179
+ ```bibtex
180
+ @misc{fish-speech-v1.4,
181
+ title={Fish-Speech: Leveraging Large Language Models for Advanced Multilingual Text-to-Speech Synthesis},
182
+ author={Shijia Liao and Yuxuan Wang and Tianyu Li and Yifan Cheng and Ruoyi Zhang and Rongzhi Zhou and Yijin Xing},
183
+ year={2024},
184
+ eprint={2411.01156},
185
+ archivePrefix={arXiv},
186
+ primaryClass={cs.SD},
187
+ url={https://arxiv.org/abs/2411.01156},
188
+ }
189
+
190
+ @misc{liao2026fishaudios2technical,
191
+ title={Fish Audio S2 Technical Report},
192
+ author={Shijia Liao and Yuxuan Wang and Songting Liu and Yifan Cheng and Ruoyi Zhang and Tianyu Li and Shidong Li and Yisheng Zheng and Xingwei Liu and Qingzheng Wang and Zhizhuo Zhou and Jiahua Liu and Xin Chen and Dawei Han},
193
+ year={2026},
194
+ eprint={2603.08823},
195
+ archivePrefix={arXiv},
196
+ primaryClass={cs.SD},
197
+ url={https://arxiv.org/abs/2603.08823},
198
+ }
199
+ ```
vendor/fish-speech/docs/README.es.md ADDED
@@ -0,0 +1,188 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div align="center">
2
+ <h1>Fish Speech</h1>
3
+
4
+ [English](../README.md) | [简体中文](docs/README.zh.md) | [Portuguese](docs/README.pt-BR.md) | [日本語](docs/README.ja.md) | [한국어](docs/README.ko.md) | [العربية](docs/README.ar.md) | **Español** <br>
5
+
6
+ <a href="https://www.producthunt.com/products/fish-speech?embed=true&utm_source=badge-top-post-badge&utm_medium=badge&utm_source=badge-fish&#0045;audio&#0045;s1" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/top-post-badge.svg?post_id=1023740&theme=light&period=daily&t=1761164814710" alt="Fish&#0032;Audio&#0032;S1 - Clonación&#0032;de&#0032;voz&#0032;expresiva&#0032;y&#0032;texto&#0045;a&#0045;voz | Product Hunt" style="width: 250px; height: 54px;" width="250" height="54" /></a> <a href="https://trendshift.io/repositories/7014" target="_blank"> <img src="https://trendshift.io/api/badge/repositories/7014" alt="fishaudio%2Ffish-speech | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/> </a> <br>
7
+
8
+ </div>
9
+ <br>
10
+
11
+ <div align="center">
12
+ <img src="https://count.getloli.com/get/@fish-speech?theme=asoul" /><br>
13
+ </div>
14
+
15
+ <br>
16
+
17
+ <div align="center">
18
+ <a target="_blank" href="https://discord.gg/Es5qTB9BcN">
19
+ <img alt="Discord" src="https://img.shields.io/discord/1214047546020728892?color=%23738ADB&label=Discord&logo=discord&logoColor=white&style=flat-square"/>
20
+ </a>
21
+ <a target="_blank" href="https://hub.docker.com/r/fishaudio/fish-speech">
22
+ <img alt="Docker" src="https://img.shields.io/docker/pulls/fishaudio/fish-speech?style=flat-square&logo=docker"/>
23
+ </a>
24
+ <a target="_blank" href="https://pd.qq.com/s/bwxia254o">
25
+ <img alt="QQ Channel" src="https://img.shields.io/badge/QQ-blue?logo=tencentqq">
26
+ </a>
27
+ </div>
28
+
29
+ <div align="center">
30
+ <a target="_blank" href="https://huggingface.co/fishaudio/s2-pro">
31
+ <img alt="HuggingFace Model" src="https://img.shields.io/badge/🤗%20-models-orange"/>
32
+ </a>
33
+ <a target="_blank" href="https://fish.audio/blog/fish-audio-open-sources-s2/">
34
+ <img alt="Fish Audio Blog" src="https://img.shields.io/badge/Blog-Fish_Audio_S2-1f7a8c?style=flat-square&logo=readme&logoColor=white"/>
35
+ </a>
36
+ <a target="_blank" href="https://arxiv.org/abs/2603.08823">
37
+ <img alt="Paper | Informe Técnico" src="https://img.shields.io/badge/Paper-Technical_Report-b31b1b?style=flat-square"/>
38
+ </a>
39
+ </div>
40
+
41
+ > [!IMPORTANT]
42
+ > **Aviso de Licencia**
43
+ > Este código y los pesos de modelo asociados se publican bajo la **[FISH AUDIO RESEARCH LICENSE](LICENSE)**. Consulta [LICENSE](LICENSE) para más detalles. Se tomarán acciones ante cualquier violación de la licencia.
44
+
45
+ > [!WARNING]
46
+ > **Descargo de Responsabilidad Legal**
47
+ > No asumimos ninguna responsabilidad por el uso ilegal de este código. Consulta las leyes locales relacionadas con DMCA y otras normativas aplicables.
48
+
49
+ ## Inicio Rápido
50
+
51
+ ### Para humanos
52
+
53
+ Aquí tienes la documentación oficial de Fish Audio S2. Sigue las instrucciones para comenzar fácilmente.
54
+
55
+ * [Instalación](https://speech.fish.audio/install/)
56
+ * [Inferencia por línea de comandos](https://speech.fish.audio/inference/#command-line-inference)
57
+ * [Inferencia con WebUI](https://speech.fish.audio/inference/#webui-inference)
58
+ * [Inferencia en servidor](https://speech.fish.audio/server/)
59
+ * [Configuración de Docker](https://speech.fish.audio/install/#docker-setup)
60
+
61
+ > [!IMPORTANT]
62
+ > **Para el servidor SGLang, consulta [SGLang-Omni README](https://github.com/sgl-project/sglang-omni/blob/main/sglang_omni/models/fishaudio_s2_pro/README.md).**
63
+ >
64
+ > **Para el servidor vLLM Omni, consulta [vLLM-Omni Fish Speech S2 Pro Recipe](https://github.com/vllm-project/vllm-omni/blob/main/recipes/fishaudio/Fish-Speech-S2-Pro.md) y la [Guía de usuario](https://github.com/vllm-project/vllm-omni/blob/main/docs/user_guide/examples/online_serving/text_to_speech.md#fish-speech-s2-pro).**
65
+
66
+ ### Para agentes LLM
67
+
68
+ ```
69
+ Instala y configura Fish-Audio S2 siguiendo las instrucciones aquí: https://speech.fish.audio/install/
70
+ ```
71
+
72
+ ## Fish Audio S2 Pro
73
+
74
+ **Sistema de texto a voz (TTS) multilingüe de última generación, redefiniendo los límites de la generación de voz.**
75
+
76
+ Fish Audio S2 Pro es el modelo multimodal más avanzado desarrollado por Fish Audio. Entrenado con más de **10 millones de horas** de datos de audio que abarcan más de **80 idiomas**, S2 Pro combina una arquitectura **Dual-Autoregressive (Dual-AR)** con alineación mediante aprendizaje por refuerzo (RL) para generar voz extremadamente natural, realista y emocionalmente rica, liderando tanto sistemas open-source como closed-source.
77
+
78
+ La principal fortaleza de S2 Pro es su soporte para control fino a nivel **sub-palabra (sub-word level)** de prosodia y emoción usando etiquetas en lenguaje natural (por ejemplo `[whisper]`, `[excited]`, `[angry]`), además de soportar de forma nativa generación multi-speaker y conversaciones multi-turno.
79
+
80
+ Visita el sitio web de Fish Audio para probarlo en vivo, o lee el informe técnico y el blog para más detalles.
81
+
82
+ ### Variantes del modelo
83
+
84
+ | Modelo | Tamaño | Disponibilidad | Descripción |
85
+ | ------ | ------------- | ------------------------------------------------------ | --------------------------------------------------------- |
86
+ | S2-Pro | 4B parámetros | [HuggingFace](https://huggingface.co/fishaudio/s2-pro) | Modelo insignia completo con máxima calidad y estabilidad |
87
+
88
+ Más detalles pueden encontrarse en el informe técnico.
89
+
90
+ ## Resultados de benchmarks
91
+
92
+ | Benchmark | Fish Audio S2 |
93
+ | ----------------------------------------- | -------------------------- |
94
+ | Seed-TTS Eval — WER (Chino) | **0.54%** (mejor global) |
95
+ | Seed-TTS Eval — WER (Inglés) | **0.99%** (mejor global) |
96
+ | Audio Turing Test (con instrucciones) | **0.515** media posterior |
97
+ | EmergentTTS-Eval — Tasa de victoria | **81.88%** (máximo global) |
98
+ | Fish Instruction Benchmark — TAR | **93.3%** |
99
+ | Fish Instruction Benchmark — Calidad | **4.51 / 5.0** |
100
+ | Multilingüe (MiniMax Testset) — Mejor WER | **11 de 24** idiomas |
101
+ | Multilingüe (MiniMax Testset) — Mejor SIM | **17 de 24** idiomas |
102
+
103
+ En Seed-TTS Eval, S2 logra el menor WER entre todos los modelos evaluados, incluyendo sistemas cerrados: Qwen3-TTS (0.77/1.24), MiniMax Speech-02 (0.99/1.90), Seed-TTS (1.12/2.25). En el Audio Turing Test, 0.515 supera a Seed-TTS (0.417) en un 24% y a MiniMax-Speech (0.387) en un 33%. En EmergentTTS-Eval, S2 destaca especialmente en paralingüística (91.61%), preguntas (84.41%) y complejidad sintáctica (83.39%).
104
+
105
+ ## Highlights
106
+
107
+ <img src="./docs/assets/totalability.png" width=200%>
108
+
109
+ ### Control fino inline mediante lenguaje natural
110
+
111
+ S2 Pro aporta un nivel de “alma” sin precedentes a la voz. Usando sintaxis `[tag]`, puedes insertar instrucciones emocionales con precisión en cualquier parte del texto.
112
+
113
+ * **Más de 15,000 tags únicos soportados**
114
+ * Soporta descripciones libres como `[whisper in small voice]`, `[professional broadcast tone]`, `[pitch up]`
115
+
116
+ ### Arquitectura Dual-Autoregressive (Dual-AR)
117
+
118
+ * **Slow AR (4B parámetros)**: modela la estructura temporal
119
+ * **Fast AR (400M parámetros)**: reconstruye detalles acústicos finos
120
+
121
+ ### Alineación mediante RL
122
+
123
+ * Usa GRPO
124
+ * Señales de recompensa multidimensionales
125
+
126
+ ### Rendimiento extremo en streaming
127
+
128
+ * RTF: 0.195
129
+ * TTFA: ~100 ms
130
+ * +3000 tokens/s
131
+
132
+ ### Soporte multilingüe robusto
133
+
134
+ * Más de 80 idiomas
135
+ * Sin necesidad de phonemes específicos
136
+
137
+ ### Generación multi-speaker nativa
138
+
139
+ <img src="./docs/assets/chattemplate.png" width=200%>
140
+
141
+ Permite múltiples hablantes usando `<|speaker:i|>` en una sola generación.
142
+
143
+ ### Generación multi-turno
144
+
145
+ Mantiene contexto para mejorar la naturalidad.
146
+
147
+ ### Clonación de voz rápida
148
+
149
+ * Solo 10–30 segundos de audio
150
+ * Alta fidelidad de timbre y estilo
151
+
152
+ Para usar con SGLang Server, consulta el README correspondiente.
153
+
154
+ ---
155
+
156
+ ## Créditos
157
+
158
+ * [VITS2 (daniilrobnikov)](https://github.com/daniilrobnikov/vits2)
159
+ * [Bert-VITS2](https://github.com/fishaudio/Bert-VITS2)
160
+ * [GPT VITS](https://github.com/innnky/gpt-vits)
161
+ * [MQTTS](https://github.com/b04901014/MQTTS)
162
+ * [GPT Fast](https://github.com/pytorch-labs/gpt-fast)
163
+ * [GPT-SoVITS](https://github.com/RVC-Boss/GPT-SoVITS)
164
+ * [Qwen3](https://github.com/QwenLM/Qwen3)
165
+
166
+ ## Informe Técnico
167
+
168
+ ```bibtex
169
+ @misc{fish-speech-v1.4,
170
+ title={Fish-Speech: Leveraging Large Language Models for Advanced Multilingual Text-to-Speech Synthesis},
171
+ author={Shijia Liao and Yuxuan Wang and Tianyu Li and Yifan Cheng and Ruoyi Zhang and Rongzhi Zhou and Yijin Xing},
172
+ year={2024},
173
+ eprint={2411.01156},
174
+ archivePrefix={arXiv},
175
+ primaryClass={cs.SD},
176
+ url={https://arxiv.org/abs/2411.01156},
177
+ }
178
+
179
+ @misc{liao2026fishaudios2technical,
180
+ title={Fish Audio S2 Technical Report},
181
+ author={Shijia Liao and Yuxuan Wang and Songting Liu and Yifan Cheng and Ruoyi Zhang and Tianyu Li and Shidong Li and Yisheng Zheng and Xingwei Liu and Qingzheng Wang and Zhizhuo Zhou and Jiahua Liu and Xin Chen and Dawei Han},
182
+ year={2026},
183
+ eprint={2603.08823},
184
+ archivePrefix={arXiv},
185
+ primaryClass={cs.SD},
186
+ url={https://arxiv.org/abs/2603.08823},
187
+ }
188
+ ```
vendor/fish-speech/docs/README.ja.md ADDED
@@ -0,0 +1,199 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div align="center">
2
+ <h1>Fish Speech</h1>
3
+
4
+ [English](../README.md) | [简体中文](README.zh.md) | [Portuguese](README.pt-BR.md) | **日本語** | [한국어](README.ko.md) | [العربية](README.ar.md) | [Español](docs/README.es.md) <br>
5
+
6
+ <a href="https://www.producthunt.com/products/fish-speech?embed=true&utm_source=badge-top-post-badge&utm_medium=badge&utm_source=badge-fish&#0045;audio&#0045;s1" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/top-post-badge.svg?post_id=1023740&theme=light&period=daily&t=1761164814710" alt="Fish&#0032;Audio&#0032;S1 - Expressive&#0032;Voice&#0032;Cloning&#0032;and&#0032;Text&#0045;to&#0045;Speech | Product Hunt" style="width: 250px; height: 54px;" width="250" height="54" /></a>
7
+ <a href="https://trendshift.io/repositories/7014" target="_blank">
8
+ <img src="https://trendshift.io/api/badge/repositories/7014" alt="fishaudio%2Ffish-speech | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/>
9
+ </a>
10
+ <br>
11
+ </div>
12
+ <br>
13
+
14
+ <div align="center">
15
+ <img src="https://count.getloli.com/get/@fish-speech?theme=asoul" /><br>
16
+ </div>
17
+
18
+ <br>
19
+
20
+ <div align="center">
21
+ <a target="_blank" href="https://discord.gg/Es5qTB9BcN">
22
+ <img alt="Discord" src="https://img.shields.io/discord/1214047546020728892?color=%23738ADB&label=Discord&logo=discord&logoColor=white&style=flat-square"/>
23
+ </a>
24
+ <a target="_blank" href="https://hub.docker.com/r/fishaudio/fish-speech">
25
+ <img alt="Docker" src="https://img.shields.io/docker/pulls/fishaudio/fish-speech?style=flat-square&logo=docker"/>
26
+ </a>
27
+ <a target="_blank" href="https://pd.qq.com/s/bwxia254o">
28
+ <img alt="QQ Channel" src="https://img.shields.io/badge/QQ-blue?logo=tencentqq">
29
+ </a>
30
+ </div>
31
+
32
+ <div align="center">
33
+ <a target="_blank" href="https://huggingface.co/fishaudio/s2-pro">
34
+ <img alt="HuggingFace Model" src="https://img.shields.io/badge/🤗%20-models-orange"/>
35
+ </a>
36
+ <a target="_blank" href="https://fish.audio/blog/fish-audio-open-sources-s2/">
37
+ <img alt="Fish Audio Blog" src="https://img.shields.io/badge/Blog-Fish_Audio_S2-1f7a8c?style=flat-square&logo=readme&logoColor=white"/>
38
+ </a>
39
+ <a target="_blank" href="https://arxiv.org/abs/2603.08823">
40
+ <img alt="Paper | Technical Report" src="https://img.shields.io/badge/Paper-Technical_Report-b31b1b?style=flat-square"/>
41
+ </a>
42
+ </div>
43
+
44
+ > [!IMPORTANT]
45
+ > **ライセンス注意事項**
46
+ > このコードベースおよび関連するモデルウェイトは **[FISH AUDIO RESEARCH LICENSE](../LICENSE)** の下でリリースされています。詳細については [LICENSE](../LICENSE) をご参照ください。
47
+
48
+
49
+ > [!WARNING]
50
+ > **法的免責事項**
51
+ > 私たちはコードベースの不法な使用について一切の責任を負いません。DMCA 及びその他の関連法律について、現地の法律をご参照ください。
52
+
53
+ ## クイックスタート
54
+
55
+ ### ドキュメント入口
56
+
57
+ Fish Audio S2 の公式ドキュメントです。以下からすぐに始められます。
58
+
59
+ - [インストール](https://speech.fish.audio/ja/install/)
60
+ - [コマンドライン推論](https://speech.fish.audio/ja/inference/)
61
+ - [WebUI 推論](https://speech.fish.audio/ja/inference/)
62
+ - [サーバー推論](https://speech.fish.audio/ja/server/)
63
+ - [Docker デプロイ](https://speech.fish.audio/ja/install/)
64
+
65
+ > [!IMPORTANT]
66
+ > **SGLang サーバーについては [SGLang-Omni README](https://github.com/sgl-project/sglang-omni/blob/main/sglang_omni/models/fishaudio_s2_pro/README.md) を参照してください。**
67
+ >
68
+ > **vLLM Omni サーバーについては [vLLM-Omni Fish Speech S2 Pro Recipe](https://github.com/vllm-project/vllm-omni/blob/main/recipes/fishaudio/Fish-Speech-S2-Pro.md) と [ユーザーガイド](https://github.com/vllm-project/vllm-omni/blob/main/docs/user_guide/examples/online_serving/text_to_speech.md#fish-speech-s2-pro) を参照してください。**
69
+
70
+ ### LLM Agent 指南
71
+
72
+ ```
73
+ https://speech.fish.audio/ja/install/ の手順に従って、Fish Audio S2 をインストール・設定してください。
74
+ ```
75
+
76
+ ## Fish Audio S2 Pro
77
+ **業界最先端の多言語テキスト読み上げ (TTS) システム。音声生成の限界を再定義します。**
78
+
79
+ Fish Audio S2 Pro は [Fish Audio](https://fish.audio/) が開発した最高峰のマルチモーダルモデルです。世界 **80 言語以上**、**1,000 万時間** を超える膨大な音声データで学習されています。革新的な **二重自己回帰 (Dual-AR)** アーキテクチャと強化学習 (RL) アライメント技術を組み合わせることで、極めて自然でリアル、かつ感情豊かな音声を生成し、オープンソースおよびクローズドソースの双方でリーダーシップを発揮しています。
80
+
81
+ S2 Pro の最大の特徴は、自然言語タグ(例:`[whisper]`、`[excited]`、`[angry]`)による韻律や感情の **サブワードレベル (Sub-word Level)** での極めて細やかなインライン制御が可能である点です。また、マルチスピーカー生成や長文コンテキストのマルチターン対話生成にもネイティブ対応しています。
82
+
83
+ 今すぐ [Fish Audio 公式サイト](https://fish.audio/) でプレイグラウンドを体験するか、[技術レポート](https://arxiv.org/abs/2603.08823) や [ブログ記事](https://fish.audio/blog/fish-audio-open-sources-s2/) を読んで詳細を確認してください。
84
+
85
+ ### モデルバリアント
86
+
87
+ | モデル | サイズ | 利用可能性 | 説明 |
88
+ |------|------|-------------|-------------|
89
+ | S2-Pro | 4B パラメータ | [HuggingFace](https://huggingface.co/fishaudio/s2-pro) | 品質と安定性を最大化した、フル機能のフラッグシップモデル |
90
+
91
+ モデルの詳細は[技術レポート](https://arxiv.org/abs/2411.01156)をご参照ください。
92
+
93
+ ## ベンチマーク結果
94
+
95
+ | ベンチマーク | Fish Audio S2 |
96
+ |------|------|
97
+ | Seed-TTS Eval — WER(中国語) | **0.54%**(全体最良) |
98
+ | Seed-TTS Eval — WER(英語) | **0.99%**(全体最良) |
99
+ | Audio Turing Test(指示あり) | **0.515** 事後平均値 |
100
+ | EmergentTTS-Eval — 勝率 | **81.88%**(全体最高) |
101
+ | Fish Instruction Benchmark — TAR | **93.3%** |
102
+ | Fish Instruction Benchmark — 品質 | **4.51 / 5.0** |
103
+ | 多言語(MiniMax Testset)— 最良 WER | **24 言語中 11 言語** |
104
+ | 多言語(MiniMax Testset)— 最良 SIM | **24 言語中 17 言語** |
105
+
106
+ Seed-TTS Eval では、S2 はクローズドソースを含む全評価モデルの中で最小 WER を達成しました:Qwen3-TTS(0.77/1.24)、MiniMax Speech-02(0.99/1.90)、Seed-TTS(1.12/2.25)。Audio Turing Test では 0.515 を記録し、Seed-TTS(0.417)比で 24%、MiniMax-Speech(0.387)比で 33% 上回りました。EmergentTTS-Eval では、副言語情報(91.61%)、疑問文(84.41%)、統語的複雑性(83.39%)で特に高い成績を示しています。
107
+
108
+ ## ハイライト
109
+
110
+ <img src="./assets/totalability.png" width=200%>
111
+
112
+ ### 自然言語による細粒度インライン制御
113
+
114
+ S2 Pro は音声にこれまでにない「魂」を宿らせます。シンプルな `[tag]` 構文を使用して、テキスト内の任意の場所に感情の指示を正確に埋め込むことができます。
115
+ - **1万5,000以上のユニークタグに対応**:固定のプリセットに限定されず、**自由形式のテキスト記述** をサポートします。`[whisper in small voice]` (ささやき声で), `[professional broadcast tone]` (プロのナレーション風), `[pitch up]` (ピッチを上げる) などを試してみてください。
116
+ - **豊富な感情ライブラリ**:
117
+ `[pause]` `[emphasis]` `[laughing]` `[inhale]` `[chuckle]` `[tsk]` `[singing]` `[excited]` `[laughing tone]` `[interrupting]` `[chuckling]` `[excited tone]` `[volume up]` `[echo]` `[angry]` `[low volume]` `[sigh]` `[low voice]` `[whisper]` `[screaming]` `[shouting]` `[loud]` `[surprised]` `[short pause]` `[exhale]` `[delight]` `[panting]` `[audience laughter]` `[with strong accent]` `[volume down]` `[clearing throat]` `[sad]` `[moaning]` `[shocked]`
118
+
119
+ ### 革新的な二重自己回帰 (Dual-Autoregressive) アーキテクチャ
120
+
121
+ S2 Pro は、Decoder-only Transformer と RVQ オーディオコーデック(10 コードブック、約 21 Hz)で構成されるマスター・スレーブ型の Dual-AR アーキテクチャを採用しています:
122
+
123
+ - **Slow AR (4B パラメータ)**: 時間軸方向に動作し、核となるセマンティックコードブックを予測。
124
+ - **Fast AR (400M パラメータ)**: 各時間ステップで残り 9 個の残差コードブックを生成し、極めて繊細な音響ディテールを復元。
125
+
126
+ この非対称設計により、究極のオーディオ忠実度を維持しながら、推論速度を大幅に向上させています。
127
+
128
+ ### 強化学習 (RL) アライメント
129
+
130
+ S2 Pro は、事後学習アライメントに **Group Relative Policy Optimization (GRPO)** 技術を採用しています。データのクリーニングとアノテーションに使用したモデルセットをそのまま報酬モデル (Reward Model) として使用することで、事前学習データの分布と事後学習の目標との間のミスマッチを完璧に解決しました。
131
+ - **多次元の報酬信号**: 意味の正確性、指示追従性、音響的な好み、音色の類似性を総合的に評価し、生成される一秒一秒の音声が人間の直感に沿うようにしています。
132
+
133
+ ### SGLang による究極のストリーミング推論性能
134
+
135
+ Dual-AR アーキテクチャは標準的な LLM 構造と同型であるため、S2 Pro は SGLang のすべての推論加速機能をネイティブにサポートしています。これには、Continuous Batching、Paged KV Cache、CUDA Graph、RadixAttention ベースの Prefix Caching が含まれます。
136
+
137
+ **NVIDIA H200 GPU 1枚でのパ���ォーマンス表現:**
138
+ - **リアルタイム係数 (RTF)**: 0.195
139
+ - **初回音声出力までの時間 (TTFA)**: 約 100 ms
140
+ - **極速スループット**: RTF < 0.5 を維持しつつ 3,000+ acoustic tokens/s
141
+
142
+ ### 強力な多言語サポート
143
+
144
+ S2 Pro は 80 以上の言語をサポートしており、音素や特定の言語に対する前処理なしで高品質な合成を実現します:
145
+
146
+ - **第1層 (Tier 1)**: 日本語 (ja), 英語 (en), 中国語 (zh)
147
+ - **第2層 (Tier 2)**: 韓国語 (ko), スペイン語 (es), ポルトガル語 (pt), アラビア語 (ar), ロシア語 (ru), フランス語 (fr), ドイツ語 (de)
148
+ - **グローバルカバレッジ**: sv, it, tr, no, nl, cy, eu, ca, da, gl, ta, hu, fi, pl, e!t, hi, la, ur, th, vi, jw, bn, yo, xsl, cs, sw, nn, he, ms, uk, id, kk, bg, lv, my, tl, sk, ne, fa, af, el, bo, hr, ro, sn, mi, yi, am, be, km, is, az, sd, br, sq, ps, mn, ht, ml, sr, sa, te, ka, bs, pa, lt, kn, si, hy, mr, as, gu, fo など。
149
+
150
+ ### ネイティブなマルチスピーカー生成
151
+
152
+ <img src="./assets/chattemplate.png" width=200%>
153
+
154
+ Fish Audio S2 では、複数のスピーカーを含む参照オーディオをアップロードでき、モデルは `<|speaker:i|>` トークンを介して各スピーカーの特徴を処理します。スピーカー ID トークンを使用してモデルの出力を制御することで、1回の生成に複数のスピーカーを混在させることが可能です。個別のスピーカーごとに参照オーディオをアップロードし直す手間はもう不要です。
155
+
156
+ ### マルチターン対話生成
157
+
158
+ コンテキストの拡張により、以前のターンの情報を利用して後続の生成内容の表現力を高めることができ、対話としての自然さが大幅に向上しました。
159
+
160
+ ### 高速音声クローニング
161
+
162
+ Fish Audio S2 は、短い参照サンプル(通常 10〜30 秒)を使用した正確な音声クローニングをサポートしています。モデルは音色、話し方、感情を捉え、追加の微調整なしでリアルで一貫したクローン音声を生成します。
163
+ SGLang サーバーの利用については、[SGLang-Omni README](https://github.com/sgl-project/sglang-omni/blob/main/sglang_omni/models/fishaudio_s2_pro/README.md) を参照してください。
164
+
165
+ ---
166
+
167
+ ## 謝辞
168
+
169
+ - [VITS2 (daniilrobnikov)](https://github.com/daniilrobnikov/vits2)
170
+ - [Bert-VITS2](https://github.com/fishaudio/Bert-VITS2)
171
+ - [GPT VITS](https://github.com/innnky/gpt-vits)
172
+ - [MQTTS](https://github.com/b04901014/MQTTS)
173
+ - [GPT Fast](https://github.com/pytorch-labs/gpt-fast)
174
+ - [GPT-SoVITS](https://github.com/RVC-Boss/GPT-SoVITS)
175
+ - [Qwen3](https://github.com/QwenLM/Qwen3)
176
+
177
+ ## 技術レポート
178
+
179
+ ```bibtex
180
+ @misc{fish-speech-v1.4,
181
+ title={Fish-Speech: Leveraging Large Language Models for Advanced Multilingual Text-to-Speech Synthesis},
182
+ author={Shijia Liao and Yuxuan Wang and Tianyu Li and Yifan Cheng and Ruoyi Zhang and Rongzhi Zhou and Yijin Xing},
183
+ year={2024},
184
+ eprint={2411.01156},
185
+ archivePrefix={arXiv},
186
+ primaryClass={cs.SD},
187
+ url={https://arxiv.org/abs/2411.01156},
188
+ }
189
+
190
+ @misc{liao2026fishaudios2technical,
191
+ title={Fish Audio S2 Technical Report},
192
+ author={Shijia Liao and Yuxuan Wang and Songting Liu and Yifan Cheng and Ruoyi Zhang and Tianyu Li and Shidong Li and Yisheng Zheng and Xingwei Liu and Qingzheng Wang and Zhizhuo Zhou and Jiahua Liu and Xin Chen and Dawei Han},
193
+ year={2026},
194
+ eprint={2603.08823},
195
+ archivePrefix={arXiv},
196
+ primaryClass={cs.SD},
197
+ url={https://arxiv.org/abs/2603.08823},
198
+ }
199
+ ```
vendor/fish-speech/docs/README.ko.md ADDED
@@ -0,0 +1,199 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div align="center">
2
+ <h1>Fish Speech</h1>
3
+
4
+ [English](../README.md) | [简体中文](README.zh.md) | [Portuguese](README.pt-BR.md) | [日本語](README.ja.md) | **한국어** | [العربية](README.ar.md) | [Español](docs/README.es.md) <br>
5
+
6
+ <a href="https://www.producthunt.com/products/fish-speech?embed=true&utm_source=badge-top-post-badge&utm_medium=badge&utm_source=badge-fish&#0045;audio&#0045;s1" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/top-post-badge.svg?post_id=1023740&theme=light&period=daily&t=1761164814710" alt="Fish&#0032;Audio&#0032;S1 - Expressive&#0032;Voice&#0032;Cloning&#0032;and&#0032;Text&#0045;to&#0045;Speech | Product Hunt" style="width: 250px; height: 54px;" width="250" height="54" /></a>
7
+ <a href="https://trendshift.io/repositories/7014" target="_blank">
8
+ <img src="https://trendshift.io/api/badge/repositories/7014" alt="fishaudio%2Ffish-speech | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/>
9
+ </a>
10
+ <br>
11
+ </div>
12
+ <br>
13
+
14
+ <div align="center">
15
+ <img src="https://count.getloli.com/get/@fish-speech?theme=asoul" /><br>
16
+ </div>
17
+
18
+ <br>
19
+
20
+ <div align="center">
21
+ <a target="_blank" href="https://discord.gg/Es5qTB9BcN">
22
+ <img alt="Discord" src="https://img.shields.io/discord/1214047546020728892?color=%23738ADB&label=Discord&logo=discord&logoColor=white&style=flat-square"/>
23
+ </a>
24
+ <a target="_blank" href="https://hub.docker.com/r/fishaudio/fish-speech">
25
+ <img alt="Docker" src="https://img.shields.io/docker/pulls/fishaudio/fish-speech?style=flat-square&logo=docker"/>
26
+ </a>
27
+ <a target="_blank" href="https://pd.qq.com/s/bwxia254o">
28
+ <img alt="QQ Channel" src="https://img.shields.io/badge/QQ-blue?logo=tencentqq">
29
+ </a>
30
+ </div>
31
+
32
+ <div align="center">
33
+ <a target="_blank" href="https://huggingface.co/fishaudio/s2-pro">
34
+ <img alt="HuggingFace Model" src="https://img.shields.io/badge/🤗%20-models-orange"/>
35
+ </a>
36
+ <a target="_blank" href="https://fish.audio/blog/fish-audio-open-sources-s2/">
37
+ <img alt="Fish Audio Blog" src="https://img.shields.io/badge/Blog-Fish_Audio_S2-1f7a8c?style=flat-square&logo=readme&logoColor=white"/>
38
+ </a>
39
+ <a target="_blank" href="https://arxiv.org/abs/2603.08823">
40
+ <img alt="Paper | Technical Report" src="https://img.shields.io/badge/Paper-Technical_Report-b31b1b?style=flat-square"/>
41
+ </a>
42
+ </div>
43
+
44
+ > [!IMPORTANT]
45
+ > **라이선스 고지**
46
+ > 이 코드베이스 및 관련 모델 가중치는 **[FISH AUDIO RESEARCH LICENSE](../LICENSE)** 에 따라 배포됩니다. 자세한 내용은 [LICENSE](../LICENSE)를 참조하십시오.
47
+
48
+
49
+ > [!WARNING]
50
+ > **법적 면책 조항**
51
+ > 당사는 코드베이스의 불법적인 사용에 대해 어떠한 책임도 지지 않습니다. 해당 지역의 DMCA 및 기타 관련 법률을 참조하십시오.
52
+
53
+ ## 빠른 시작
54
+
55
+ ### 문서 입구
56
+
57
+ Fish Audio S2의 공식 문서입니다. 지침에 따라 쉽게 시작하십시오.
58
+
59
+ - [설치](https://speech.fish.audio/ko/install/)
60
+ - [명령줄 추론](https://speech.fish.audio/ko/inference/)
61
+ - [WebUI 추론](https://speech.fish.audio/ko/inference/)
62
+ - [서버 추론](https://speech.fish.audio/ko/server/)
63
+ - [Docker 배포](https://speech.fish.audio/ko/install/)
64
+
65
+ > [!IMPORTANT]
66
+ > **SGLang 서버를 사용하려면 [SGLang-Omni README](https://github.com/sgl-project/sglang-omni/blob/main/sglang_omni/models/fishaudio_s2_pro/README.md)를 참조하십시오.**
67
+ >
68
+ > **vLLM Omni 서버를 사용하려면 [vLLM-Omni Fish Speech S2 Pro Recipe](https://github.com/vllm-project/vllm-omni/blob/main/recipes/fishaudio/Fish-Speech-S2-Pro.md)와 [사용자 가이드](https://github.com/vllm-project/vllm-omni/blob/main/docs/user_guide/examples/online_serving/text_to_speech.md#fish-speech-s2-pro)를 참조하십시오.**
69
+
70
+ ### LLM Agent 가이드
71
+
72
+ ```
73
+ 먼저 https://speech.fish.audio/ko/install/ 을 읽고 문서에 따라 Fish Audio S2를 설치 및 구성하십시오.
74
+ ```
75
+
76
+ ## Fish Audio S2 Pro
77
+ **음성 생성의 경계를 재정의하는 업계 최고의 다국어 텍스트 음성 변환(TTS) 시스템.**
78
+
79
+ Fish Audio S2 Pro는 [Fish Audio](https://fish.audio/)에서 개발한 최첨단 멀티모달 모델입니다. 전 세계 **80개 이상의 언어**를 아우르는 **1,000만 시간** 이상의 방대한 오디오 데이터로 학습되었습니다. 혁신적인 **이중 자기회귀(Dual-AR)** 아키텍처와 강화 학습(RL) 정렬 기술을 통해 S2 Pro는 극도로 자연스럽고 사실적이며 감정이 풍부한 음성을 생성하며, 오픈 소스와 클ローズ드 소스 경쟁 모두에서 선두를 달리고 있습니다.
80
+
81
+ S2 Pro의 핵심 강점은 자연어 태그(예: `[whisper]`, `[excited]`, `[angry]`)를 통해 운율과 감정을 **하위 단어 수준(Sub-word Level)**에서 매우 세밀하게 인라인 제어할 수 있다는 점입니다. 또한 다중 화자 생성 및 긴 컨텍스트의 다중 턴 대화 생성을 기본적으로 지원합니다.
82
+
83
+ 지금 바로 [Fish Audio 공식 웹사이트](https://fish.audio/)에서 온라인 데모를 체험하거나, [기술 보고서](https://arxiv.org/abs/2603.08823) 및 [블로그 게시물](https://fish.audio/blog/fish-audio-open-sources-s2/)을 통해 자세히 알아보십시오.
84
+
85
+ ### 모델 변체
86
+
87
+ | 모델 | 크기 | 가용성 | 설명 |
88
+ |------|------|-------------|-------------|
89
+ | S2-Pro | 4B 파라미터 | [HuggingFace](https://huggingface.co/fishaudio/s2-pro) | 최고의 품질과 안정성을 갖춘 모든 기능을 갖춘 플래그십 모델 |
90
+
91
+ 모델에 대한 자세한 내용은 [기술 보고서](https://arxiv.org/abs/2411.01156)를 참조하십시오.
92
+
93
+ ## 벤치마크 결과
94
+
95
+ | 벤치마크 | Fish Audio S2 |
96
+ |------|------|
97
+ | Seed-TTS Eval — WER(중국어) | **0.54%** (전체 최고) |
98
+ | Seed-TTS Eval — WER(영어) | **0.99%** (전체 최고) |
99
+ | Audio Turing Test (지침 포함) | **0.515** 후험 평균 |
100
+ | EmergentTTS-Eval — 승률 | **81.88%** (전체 최고) |
101
+ | Fish Instruction Benchmark — TAR | **93.3%** |
102
+ | Fish Instruction Benchmark — 품질 | **4.51 / 5.0** |
103
+ | 다국어 (MiniMax Testset) — 최고 WER | **24개 언어 중 11개** |
104
+ | 다국어 (MiniMax Testset) — 최고 SIM | **24개 언어 중 17개** |
105
+
106
+ Seed-TTS Eval에서 S2는 클ローズ드 소스 시스템을 포함한 모든 평가 모델 중 가장 낮은 WER을 달성했습니다: Qwen3-TTS (0.77/1.24), MiniMax Speech-02 (0.99/1.90), Seed-TTS (1.12/2.25). Audio Turing Test에서 S2의 0.515는 Seed-TTS (0.417) 대비 24%, MiniMax-Speech (0.387) 대비 33% 향상된 수치입니다. EmergentTTS-Eval에서 S2는 부차 언어학(91.61% 승률), 의문문(84.41%), 구문 복잡성(83.39%) 등의 측면에서 특히 두드러진 성과를 보였습니다.
107
+
108
+ ## 하이라이트
109
+
110
+ <img src="./assets/totalability.png" width=200%>
111
+
112
+ ### 자연어를 통한 초미세 인라인 제어
113
+
114
+ S2 Pro는 음성에 전례 없는 "영혼"을 부여합니다. 간단한 `[tag]` 구문을 사용하여 텍스트의 어느 위치에나 감정 지침을 정확하게 삽입할 수 있습니다.
115
+ - **15,000개 이상의 고유 태그 지원**: 고정된 사전 설정에 국한되지 않고 **자유 형식의 텍스트 설명**을 지원합니다. `[whisper in small voice]` (작은 목소리로 속삭임), `[professional broadcast tone]` (전문 방송 톤), `[pitch up]` (음높이 높임) 등을 시도해 보십시오.
116
+ - **풍부한 감정 라이브러리**:
117
+ `[pause]` `[emphasis]` `[laughing]` `[inhale]` `[chuckle]` `[tsk]` `[singing]` `[excited]` `[laughing tone]` `[interrupting]` `[chuckling]` `[excited tone]` `[volume up]` `[echo]` `[angry]` `[low volume]` `[sigh]` `[low voice]` `[whisper]` `[screaming]` `[shouting]` `[loud]` `[surprised]` `[short pause]` `[exhale]` `[delight]` `[panting]` `[audience laughter]` `[with strong accent]` `[volume down]` `[clearing throat]` `[sad]` `[moaning]` `[shocked]`
118
+
119
+ ### 혁신적인 이중 자기회귀 (Dual-Autoregressive) 아키텍처
120
+
121
+ S2 Pro는 Decoder-only Transformer와 RVQ 오디오 코덱(10개 코드북, 약 21Hz 프레임 속도)으로 구성된 마스터-슬레이브 방식의 Dual-AR 아키텍처를 채택했습니다.
122
+
123
+ - **Slow AR (4B 파라미터)**: 시간 축을 따라 작동하며 핵심 의미 코드북을 예측합니다.
124
+ - **Fast AR (400M 파라미터)**: 각 타임스텝에서 나머지 9개의 잔차 코드북을 생성하여 극도로 정교한 음향 세부 사항을 복원합니다.
125
+
126
+ 이러한 비대칭 설계는 오디오의 최고 충실도를 보장하는 동시에 추론 속도를 대폭 향상시킵니다.
127
+
128
+ ### 강화 학습 (RL) 정렬
129
+
130
+ S2 Pro는 사후 학습 정렬을 위해 **Group Relative Policy Optimization (GRPO)** 기술을 채택했습니다. 데이터 정제 및 주석 처리에 사용된 것과 동일한 모델 세트를 보상 모델(Reward Model)로 직접 사용함으로써 사전 학습 데이터 분포와 사후 학습 목표 간의 불일치 문제를 완벽하게 해결했습니다.
131
+ - **다차원 보상 신호**: 의미 체계의 정확성, 지침 준수 능력, 음향 선호도 점수 및 음색 유사성을 종합적으로 평가하여 생성된 음성의 매초가 인간의 직관에 부합하도록 보장합니다.
132
+
133
+ ### SGLang 기반의 극한 스트리밍 추론 성능
134
+
135
+ Dual-AR 아키텍처는 표준 LLM 구조와 동형이므로 S2 Pro는 Continuous Batching, Paged KV Cache, CUDA Graph 및 RadixAttention 기반 Prefix Caching을 포함한 SGLang의 모든 추론 가속 기능을 기본적으로 지원합니다.
136
+
137
+ **단일 NVIDIA H200 GPU 성능 지표:**
138
+ - **실시간 계수 (RTF)**: 0.195
139
+ - **첫 음성 지연 (TTFA)**: 약 100 ms
140
+ - **초고속 처리량**: RTF < 0.5 유지 시 처리량 3,000+ acoustic tokens/s 달성
141
+
142
+ ### 강력한 다국어 지원
143
+
144
+ S2 Pro는 음소나 특정 언어 처리가 필요 없는 고품질 합성을 80개 이상의 언어에서 지원합니다.
145
+
146
+ - **1계층 (Tier 1)**: 일본어 (ja), 영어 (en), 중국어 (zh)
147
+ - **2계층 (Tier 2)**: 한국어 (ko), 스페인어 (es), 포르투갈어 (pt), 아랍어 (ar), 러시아어 (ru), 프랑스어 (fr), 독일어 (de)
148
+ - **글로벌 커버리지**: sv, it, tr, no, nl, cy, eu, ca, da, gl, ta, hu, fi, pl, et, hi, la, ur, th, vi, jw, bn, yo, xsl, cs, sw, nn, he, ms, uk, id, kk, bg, lv, my, tl, sk, ne, fa, af, el, bo, hr, ro, sn, mi, yi, am, be, km, is, az, sd, br, sq, ps, mn, ht, ml, sr, sa, te, ka, bs, pa, lt, kn, si, hy, mr, as, gu, fo 등.
149
+
150
+ ### 네이티브 다중 화자 생성
151
+
152
+ <img src="./assets/chattemplate.png" width=200%>
153
+
154
+ Fish Audio S2를 사용하면 사용자가 여러 화자가 포함된 참조 오디오를 업로드할 수 있으며, 모델은 `<|speaker:i|>` 토큰을 통해 각 화자의 특징을 처리합니다. 이후 화자 ID 토큰을 사용하여 모델의 표현을 제어함으로써 한 번의 생성에 여러 화자를 포함할 수 있습니다. 더 이상 화자마다 별도의 참조 오디오를 업로드하고 음성을 생성할 필요가 없습니다.
155
+
156
+ ### 다중 턴 대화 생성
157
+
158
+ 모델 컨텍스트 확장에 힘입어 이제 이전 정보의 도움을 받아 후속 생성 내용의 표현력을 높이고 콘텐츠의 자연스러움을 향상시킬 수 있습니다.
159
+
160
+ ### 고속 음성 복제
161
+
162
+ Fish Audio S2는 짧은 참조 샘플(보통 10-30초)을 사용한 정확한 음성 복제를 지원합니다. 모델은 음색, 말하기 스타일 및 감정적 경향을 포착하여 추가적인 미세 조정 없이도 사실적이고 일관된 복제 음성을 생성합니다.
163
+ SGLang 서버 사용에 대해서는 [SGLang-Omni README](https://github.com/sgl-project/sglang-omni/blob/main/sglang_omni/models/fishaudio_s2_pro/README.md)를 참조하십시오.
164
+
165
+ ---
166
+
167
+ ## 감사의 말
168
+
169
+ - [VITS2 (daniilrobnikov)](https://github.com/daniilrobnikov/vits2)
170
+ - [Bert-VITS2](https://github.com/fishaudio/Bert-VITS2)
171
+ - [GPT VITS](https://github.com/innnky/gpt-vits)
172
+ - [MQTTS](https://github.com/b04901014/MQTTS)
173
+ - [GPT Fast](https://github.com/pytorch-labs/gpt-fast)
174
+ - [GPT-SoVITS](https://github.com/RVC-Boss/GPT-SoVITS)
175
+ - [Qwen3](https://github.com/QwenLM/Qwen3)
176
+
177
+ ## 기술 보고서
178
+
179
+ ```bibtex
180
+ @misc{fish-speech-v1.4,
181
+ title={Fish-Speech: Leveraging Large Language Models for Advanced Multilingual Text-to-Speech Synthesis},
182
+ author={Shijia Liao and Yuxuan Wang and Tianyu Li and Yifan Cheng and Ruoyi Zhang and Rongzhi Zhou and Yijin Xing},
183
+ year={2024},
184
+ eprint={2411.01156},
185
+ archivePrefix={arXiv},
186
+ primaryClass={cs.SD},
187
+ url={https://arxiv.org/abs/2411.01156},
188
+ }
189
+
190
+ @misc{liao2026fishaudios2technical,
191
+ title={Fish Audio S2 Technical Report},
192
+ author={Shijia Liao and Yuxuan Wang and Songting Liu and Yifan Cheng and Ruoyi Zhang and Tianyu Li and Shidong Li and Yisheng Zheng and Xingwei Liu and Qingzheng Wang and Zhizhuo Zhou and Jiahua Liu and Xin Chen and Dawei Han},
193
+ year={2026},
194
+ eprint={2603.08823},
195
+ archivePrefix={arXiv},
196
+ primaryClass={cs.SD},
197
+ url={https://arxiv.org/abs/2603.08823},
198
+ }
199
+ ```
vendor/fish-speech/docs/README.pt-BR.md ADDED
@@ -0,0 +1,199 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div align="center">
2
+ <h1>Fish Speech</h1>
3
+
4
+ [English](../README.md) | [简体中文](README.zh.md) | **Portuguese** | [日本語](README.ja.md) | [한국어](README.ko.md) | [العربية](README.ar.md) | [Español](docs/README.es.md) <br>
5
+
6
+ <a href="https://www.producthunt.com/products/fish-speech?embed=true&utm_source=badge-top-post-badge&utm_medium=badge&utm_source=badge-fish&#0045;audio&#0045;s1" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/top-post-badge.svg?post_id=1023740&theme=light&period=daily&t=1761164814710" alt="Fish&#0032;Audio&#0032;S1 - Expressive&#0032;Voice&#0032;Cloning&#0032;and&#0032;Text&#0045;to&#0045;Speech | Product Hunt" style="width: 250px; height: 54px;" width="250" height="54" /></a>
7
+ <a href="https://trendshift.io/repositories/7014" target="_blank">
8
+ <img src="https://trendshift.io/api/badge/repositories/7014" alt="fishaudio%2Ffish-speech | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/>
9
+ </a>
10
+ <br>
11
+ </div>
12
+ <br>
13
+
14
+ <div align="center">
15
+ <img src="https://count.getloli.com/get/@fish-speech?theme=asoul" /><br>
16
+ </div>
17
+
18
+ <br>
19
+
20
+ <div align="center">
21
+ <a target="_blank" href="https://discord.gg/Es5qTB9BcN">
22
+ <img alt="Discord" src="https://img.shields.io/discord/1214047546020728892?color=%23738ADB&label=Discord&logo=discord&logoColor=white&style=flat-square"/>
23
+ </a>
24
+ <a target="_blank" href="https://hub.docker.com/r/fishaudio/fish-speech">
25
+ <img alt="Docker" src="https://img.shields.io/docker/pulls/fishaudio/fish-speech?style=flat-square&logo=docker"/>
26
+ </a>
27
+ <a target="_blank" href="https://pd.qq.com/s/bwxia254o">
28
+ <img alt="QQ Channel" src="https://img.shields.io/badge/QQ-blue?logo=tencentqq">
29
+ </a>
30
+ </div>
31
+
32
+ <div align="center">
33
+ <a target="_blank" href="https://huggingface.co/fishaudio/s2-pro">
34
+ <img alt="HuggingFace Model" src="https://img.shields.io/badge/🤗%20-models-orange"/>
35
+ </a>
36
+ <a target="_blank" href="https://fish.audio/blog/fish-audio-open-sources-s2/">
37
+ <img alt="Fish Audio Blog" src="https://img.shields.io/badge/Blog-Fish_Audio_S2-1f7a8c?style=flat-square&logo=readme&logoColor=white"/>
38
+ </a>
39
+ <a target="_blank" href="https://arxiv.org/abs/2603.08823">
40
+ <img alt="Paper | Technical Report" src="https://img.shields.io/badge/Paper-Technical_Report-b31b1b?style=flat-square"/>
41
+ </a>
42
+ </div>
43
+
44
+ > [!IMPORTANT]
45
+ > **Aviso de Licença**
46
+ > Este repositório de código e seus pesos de modelo associados são lançados sob a **[FISH AUDIO RESEARCH LICENSE](../LICENSE)**. Consulte [LICENSE](../LICENSE) para obter mais detalhes.
47
+
48
+
49
+ > [!WARNING]
50
+ > **Aviso Legal**
51
+ > Não nos responsabilizamos por qualquer uso ilegal deste repositório. Consulte as leis locais sobre DMCA e outras regulamentações relevantes.
52
+
53
+ ## Início Rápido
54
+
55
+ ### Links da Documentação
56
+
57
+ Esta é a documentação oficial do Fish Audio S2, siga as instruções para começar facilmente.
58
+
59
+ - [Instalação](https://speech.fish.audio/install/)
60
+ - [Inferência por Linha de Comando](https://speech.fish.audio/inference/)
61
+ - [Inferência por WebUI](https://speech.fish.audio/inference/)
62
+ - [Inferência por Servidor](https://speech.fish.audio/server/)
63
+ - [Implantação Docker](https://speech.fish.audio/install/)
64
+
65
+ > [!IMPORTANT]
66
+ > **Caso deseje utilizar o SGLang Server, consulte o [SGLang-Omni README](https://github.com/sgl-project/sglang-omni/blob/main/sglang_omni/models/fishaudio_s2_pro/README.md).**
67
+ >
68
+ > **Caso deseje utilizar o vLLM Omni Server, consulte o [vLLM-Omni Fish Speech S2 Pro Recipe](https://github.com/vllm-project/vllm-omni/blob/main/recipes/fishaudio/Fish-Speech-S2-Pro.md) e o [Guia do Usuário](https://github.com/vllm-project/vllm-omni/blob/main/docs/user_guide/examples/online_serving/text_to_speech.md#fish-speech-s2-pro).**
69
+
70
+ ### Guia para Agentes de LLM
71
+
72
+ ```
73
+ Leia primeiro https://speech.fish.audio/install/ e siga a documentação para instalar e configurar o Fish Audio S2.
74
+ ```
75
+
76
+ ## Fish Audio S2 Pro
77
+ **O sistema de conversão de texto em fala (TTS) multilíngue líder do setor, redefinindo as fronteiras da geração de voz.**
78
+
79
+ Fish Audio S2 Pro é o modelo multimodal mais avançado desenvolvido pela [Fish Audio](https://fish.audio/). Treinado em mais de **10 milhões de horas** de dados de áudio massivos, cobrindo mais de **80 idiomas** globais. Através de uma arquitetura inovadora de **Dual-Autoregressive (Dual-AR)** e tecnologia de alinhamento por aprendizado por reforço (RL), o S2 Pro é capaz de gerar fala com um senso de naturalidade, realismo e riqueza emocional extremos, liderando tanto em competições de código aberto quanto proprietário.
80
+
81
+ O grande diferencial do S2 Pro reside em seu suporte para controle inline de granularidade ultra-fina de prosódia e emoção ao nível de **sub-palavra (Sub-word Level)** via tags de linguagem natural (como `[whisper]`, `[excited]`, `[angry]`), além de suporte nativo para múltiplos falantes e geração de diálogos de múltiplos turnos com contexto ultra-longo.
82
+
83
+ Visite agora o [site oficial da Fish Audio](https://fish.audio/) para experimentar a demonstração online, ou leia nosso [relatório técnico](https://arxiv.org/abs/2603.08823) e [artigo no blog](https://fish.audio/blog/fish-audio-open-sources-s2/) para saber mais.
84
+
85
+ ### Variantes de Modelo
86
+
87
+ | Modelo | Tamanho | Disponibilidade | Descrição |
88
+ |------|------|-------------|-------------|
89
+ | S2-Pro | 4B parâmetros | [HuggingFace](https://huggingface.co/fishaudio/s2-pro) | Modelo flagship completo, com máxima qualidade e estabilidade |
90
+
91
+ Para mais detalhes sobre os modelos, consulte o [relatório técnico](https://arxiv.org/abs/2411.01156).
92
+
93
+ ## Resultados de Benchmark
94
+
95
+ | Benchmark | Fish Audio S2 |
96
+ |------|------|
97
+ | Seed-TTS Eval — WER (Chinês) | **0.54%** (Melhor geral) |
98
+ | Seed-TTS Eval — WER (Inglês) | **0.99%** (Melhor geral) |
99
+ | Audio Turing Test (Com instrução) | **0.515** Média posterior |
100
+ | EmergentTTS-Eval — Taxa de Vitória | **81.88%** (Maior geral) |
101
+ | Fish Instruction Benchmark — TAR | **93.3%** |
102
+ | Fish Instruction Benchmark — Qualidade | **4.51 / 5.0** |
103
+ | Multilíngue (MiniMax Testset) — Melhor WER | **11 de 24** idiomas |
104
+ | Multilíngue (MiniMax Testset) — Melhor SIM | **17 de 24** idiomas |
105
+
106
+ No Seed-TTS Eval, o S2 alcançou o menor WER entre todos os modelos avaliados (incluindo sistemas proprietários): Qwen3-TTS (0.77/1.24), MiniMax Speech-02 (0.99/1.90), Seed-TTS (1.12/2.25). No Audio Turing Test, o valor de 0.515 do S2 representa um aumento de 24% em relação ao Seed-TTS (0.417) e 33% em relação ao MiniMax-Speech (0.387). No EmergentTTS-Eval, o S2 destacou-se especialmente em dimensões como paralinguística (taxa de vitória de 91.61%), frases interrogativas (84.41%) e complexidade sintática (83.39%).
107
+
108
+ ## Destaques
109
+
110
+ <img src="./assets/totalability.png" width=200%>
111
+
112
+ ### Controle Inline de Granularidade Ultra-Fina via Linguagem Natural
113
+
114
+ S2 Pro confere à voz uma "espiritualidade" sem precedentes. Através de uma sintaxe simples de `[tag]`, você pode inserir instruções emocionais precisamente em qualquer posição do texto.
115
+ - **Suporte para mais de 15.000 tags únicas**: Não limitado a predefinições fixas, suporta **descrições textuais de formato livre**. Você pode tentar `[whisper in small voice]` (sussurrando), `[professional broadcast tone]` (tom de locução profissional) ou `[pitch up]` (aumentar o tom).
116
+ - **Rica biblioteca de emoções**:
117
+ `[pause]` `[emphasis]` `[laughing]` `[inhale]` `[chuckle]` `[tsk]` `[singing]` `[excited]` `[laughing tone]` `[interrupting]` `[chuckling]` `[excited tone]` `[volume up]` `[echo]` `[angry]` `[low volume]` `[sigh]` `[low voice]` `[whisper]` `[screaming]` `[shouting]` `[loud]` `[surprised]` `[short pause]` `[exhale]` `[delight]` `[panting]` `[audience laughter]` `[with strong accent]` `[volume down]` `[clearing throat]` `[sad]` `[moaning]` `[shocked]`
118
+
119
+ ### Arquitetura Inovadora Dual-Autoregressive (Dual-AR)
120
+
121
+ S2 Pro adota uma arquitetura Dual-AR mestre-escravo, consistindo de um Decoder-only Transformer e um codec de áudio RVQ (10 codebooks, cerca de 21 Hz de taxa de frames):
122
+
123
+ - **Slow AR (4B parâmetros)**: Atua ao longo do eixo temporal, prevendo o codebook semântico central.
124
+ - **Fast AR (400M parâmetros)**: Gera os 9 codebooks residuais restantes em cada passo de tempo, restaurando detalhes acústicos extremos com delicadeza.
125
+
126
+ Este design assimétrico garante fidelidade extrema ao áudio enquanto aumenta significativamente a velocidade de inferência.
127
+
128
+ ### Alinhamento por Aprendizado por Reforço (RL Alignment)
129
+
130
+ S2 Pro utiliza a tecnologia **Group Relative Policy Optimization (GRPO)** para o alinhamento pós-treinamento. Utilizamos o mesmo conjunto de modelos para limpeza e anotação de dados diretamente como modelos de recompensa (Reward Model), resolvendo perfeitamente o problema de descasamento entre a distribuição dos dados de pré-treinamento e os objetivos de pós-treinamento.
131
+ - **Sinais de recompensa multidimensionais**: Avalia de forma abrangente a precisão semântica, a capacidade de seguir instruções, a pontuação de preferência acústica e a similaridade de timbre, garantindo que cada segundo de fala gerada esteja alinhado com a intuição humana.
132
+
133
+ ### Desempenho de Inferência de Streaming Extremo (Baseado em SGLang)
134
+
135
+ Como a arquitetura Dual-AR é estruturalmente isomorfa à estrutura padrão de LLMs, o S2 Pro suporta nativamente todos os recursos de aceleração de inferência do SGLang, incluindo loteamento contínuo (Continuous Batching), Paged KV Cache, CUDA Graph e cache de prefixo baseado em RadixAttention.
136
+
137
+ **Desempenho em uma única GPU NVIDIA H200:**
138
+ - **Fator em Tempo Real (RTF)**: 0.195
139
+ - **Latência do Primeiro Áudio (TTFA)**: aprox. 100 ms
140
+ - **Taxa de Transferência Ultrarrápida**: Alcance de 3.000+ acoustic tokens/s mantendo RTF < 0.5
141
+
142
+ ### Poderoso Suporte Multilíngue
143
+
144
+ S2 Pro suporta mais de 80 idiomas, possibilitando síntese de alta qualidade sem a necessidade de fonemas ou processamento específico por idioma:
145
+
146
+ - **Tier 1**: Japonês (ja), Inglês (en), Chinês (zh)
147
+ - **Tier 2**: Coreano (ko), Espanhol (es), Português (pt), Árabe (ar), Russo (ru), Francês (fr), Alemão (de)
148
+ - **Cobertura Global**: sv, it, tr, no, nl, cy, eu, ca, da, gl, ta, hu, fi, pl, et, hi, la, ur, th, vi, jw, bn, yo, xsl, cs, sw, nn, he, ms, uk, id, kk, bg, lv, my, tl, sk, ne, fa, af, el, bo, hr, ro, sn, mi, yi, am, be, km, is, az, sd, br, sq, ps, mn, ht, ml, sr, sa, te, ka, bs, pa, lt, kn, si, hy, mr, as, gu, fo, etc.
149
+
150
+ ### Geração Nativa Multi-falante
151
+
152
+ <img src="./assets/chattemplate.png" width=200%>
153
+
154
+ O Fish Audio S2 permite que os usuários enviem áudio de referência contendo múltiplos falantes, e o modelo processará as características de cada falante via o token `<|speaker:i|>`. Em seguida, você pode controlar o desempenho do modelo através do token de ID do falante, permitindo incluir múltiplos falantes em uma única geração. Não é mais necessário enviar áudios de referência separadamente para cada falante.
155
+
156
+ ### Geração de Diálogos Multiturnos
157
+
158
+ Graças à expansão do contexto do modelo, nosso modelo agora pode aproveitar as informações prévias para aumentar a expressividade dos conteúdos gerados subsequentemente, elevando assim a naturalidade dos diálogos.
159
+
160
+ ### Clonagem de Voz Rápida
161
+
162
+ O Fish Audio S2 suporta clonagem de voz precisa usando curtas amostras de referência (normalmente 10-30 segundos). O modelo captura o timbre, o estilo de fala e as tendências emocionais, gerando vozes clonadas realistas e consistentes sem necessidade de ajustes finos adicionais.
163
+ Caso deseje utilizar o SGLang Server, consulte o [SGLang-Omni README](https://github.com/sgl-project/sglang-omni/blob/main/sglang_omni/models/fishaudio_s2_pro/README.md).
164
+
165
+ ---
166
+
167
+ ## Agradecimentos
168
+
169
+ - [VITS2 (daniilrobnikov)](https://github.com/daniilrobnikov/vits2)
170
+ - [Bert-VITS2](https://github.com/fishaudio/Bert-VITS2)
171
+ - [GPT VITS](https://github.com/innnky/gpt-vits)
172
+ - [MQTTS](https://github.com/b04901014/MQTTS)
173
+ - [GPT Fast](https://github.com/pytorch-labs/gpt-fast)
174
+ - [GPT-SoVITS](https://github.com/RVC-Boss/GPT-SoVITS)
175
+ - [Qwen3](https://github.com/QwenLM/Qwen3)
176
+
177
+ ## Relatório Técnico
178
+
179
+ ```bibtex
180
+ @misc{fish-speech-v1.4,
181
+ title={Fish-Speech: Leveraging Large Language Models for Advanced Multilingual Text-to-Speech Synthesis},
182
+ author={Shijia Liao and Yuxuan Wang and Tianyu Li and Yifan Cheng and Ruoyi Zhang and Rongzhi Zhou and Yijin Xing},
183
+ year={2024},
184
+ eprint={2411.01156},
185
+ archivePrefix={arXiv},
186
+ primaryClass={cs.SD},
187
+ url={https://arxiv.org/abs/2411.01156},
188
+ }
189
+
190
+ @misc{liao2026fishaudios2technical,
191
+ title={Fish Audio S2 Technical Report},
192
+ author={Shijia Liao and Yuxuan Wang racing Songting Liu and Yifan Cheng and Ruoyi Zhang and Tianyu Li and Shidong Li and Yisheng Zheng and Xingwei Liu and Qingzheng Wang and Zhizhuo Zhou and Jiahua Liu and Xin Chen and Dawei Han},
193
+ year={2026},
194
+ eprint={2603.08823},
195
+ archivePrefix={arXiv},
196
+ primaryClass={cs.SD},
197
+ url={https://arxiv.org/abs/2603.08823},
198
+ }
199
+ ```
vendor/fish-speech/docs/README.zh.md ADDED
@@ -0,0 +1,199 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div align="center">
2
+ <h1>Fish Speech</h1>
3
+
4
+ [English](../README.md) | **简体中文** | [Portuguese](README.pt-BR.md) | [日本語](README.ja.md) | [한국어](README.ko.md) | [العربية](README.ar.md) | [Español](docs/README.es.md) <br>
5
+
6
+ <a href="https://www.producthunt.com/products/fish-speech?embed=true&utm_source=badge-top-post-badge&utm_medium=badge&utm_source=badge-fish&#0045;audio&#0045;s1" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/top-post-badge.svg?post_id=1023740&theme=light&period=daily&t=1761164814710" alt="Fish&#0032;Audio&#0032;S1 - Expressive&#0032;Voice&#0032;Cloning&#0032;and&#0032;Text&#0045;to&#0045;Speech | Product Hunt" style="width: 250px; height: 54px;" width="250" height="54" /></a>
7
+ <a href="https://trendshift.io/repositories/7014" target="_blank">
8
+ <img src="https://trendshift.io/api/badge/repositories/7014" alt="fishaudio%2Ffish-speech | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/>
9
+ </a>
10
+ <br>
11
+ </div>
12
+ <br>
13
+
14
+ <div align="center">
15
+ <img src="https://count.getloli.com/get/@fish-speech?theme=asoul" /><br>
16
+ </div>
17
+
18
+ <br>
19
+
20
+ <div align="center">
21
+ <a target="_blank" href="https://discord.gg/Es5qTB9BcN">
22
+ <img alt="Discord" src="https://img.shields.io/discord/1214047546020728892?color=%23738ADB&label=Discord&logo=discord&logoColor=white&style=flat-square"/>
23
+ </a>
24
+ <a target="_blank" href="https://hub.docker.com/r/fishaudio/fish-speech">
25
+ <img alt="Docker" src="https://img.shields.io/docker/pulls/fishaudio/fish-speech?style=flat-square&logo=docker"/>
26
+ </a>
27
+ <a target="_blank" href="https://pd.qq.com/s/bwxia254o">
28
+ <img alt="QQ Channel" src="https://img.shields.io/badge/QQ-blue?logo=tencentqq">
29
+ </a>
30
+ </div>
31
+
32
+ <div align="center">
33
+ <a target="_blank" href="https://huggingface.co/fishaudio/s2-pro">
34
+ <img alt="HuggingFace Model" src="https://img.shields.io/badge/🤗%20-models-orange"/>
35
+ </a>
36
+ <a target="_blank" href="https://fish.audio/blog/fish-audio-open-sources-s2/">
37
+ <img alt="Fish Audio Blog" src="https://img.shields.io/badge/Blog-Fish_Audio_S2-1f7a8c?style=flat-square&logo=readme&logoColor=white"/>
38
+ </a>
39
+ <a target="_blank" href="https://arxiv.org/abs/2603.08823">
40
+ <img alt="Paper | Technical Report" src="https://img.shields.io/badge/Paper-Technical_Report-b31b1b?style=flat-square"/>
41
+ </a>
42
+ </div>
43
+
44
+ > [!IMPORTANT]
45
+ > **许可证声明**
46
+ > 此代码库及其相关的模型权重均在 **[FISH AUDIO RESEARCH LICENSE](../LICENSE)** 下发布。更多详情请参考 [LICENSE](../LICENSE)。
47
+
48
+
49
+ > [!WARNING]
50
+ > **法律免责声明**
51
+ > 我们不对代码库的任何非法使用承担责任。请参考您当地关于 DMCA 和其他相关法律的法规。
52
+
53
+ ## 快速开始
54
+
55
+ ### 文档入口
56
+
57
+ 这里是 Fish Audio S2 的官方文档,请按照说明轻松入门。
58
+
59
+ - [安装](https://speech.fish.audio/zh/install/)
60
+ - [命令行推理](https://speech.fish.audio/zh/inference/)
61
+ - [WebUI 推理](https://speech.fish.audio/zh/inference/)
62
+ - [服务端推理](https://speech.fish.audio/zh/server/)
63
+ - [Docker 部署](https://speech.fish.audio/zh/install/)
64
+
65
+ > [!IMPORTANT]
66
+ > **如需使用 SGLang Server,请参考 [SGLang-Omni README](https://github.com/sgl-project/sglang-omni/blob/main/sglang_omni/models/fishaudio_s2_pro/README.md)。**
67
+ >
68
+ > **如需使用 vLLM Omni Server,请参考 [vLLM-Omni Fish Speech S2 Pro Recipe](https://github.com/vllm-project/vllm-omni/blob/main/recipes/fishaudio/Fish-Speech-S2-Pro.md) 和[用户指南](https://github.com/vllm-project/vllm-omni/blob/main/docs/user_guide/examples/online_serving/text_to_speech.md#fish-speech-s2-pro)。**
69
+
70
+ ### LLM Agent 指南
71
+
72
+ ```
73
+ 请先阅读 https://speech.fish.audio/zh/install/ ,并按文档安装和配置 Fish Audio S2。
74
+ ```
75
+
76
+ ## Fish Audio S2 Pro
77
+ **行业顶尖的多语言文本转语音 (TTS) 系统,重新定义声音生成的边界。**
78
+
79
+ Fish Audio S2 Pro 是 [Fish Audio](https://fish.audio/) 开发的最先进的多模态模型。S2 Pro 训练自超过 **1000 万小时** 的海量音频数据,覆盖全球 **80 多种语言**。通过创新的 **双自回归 (Dual-AR)** 架构与强化学习 (RL) 对齐技术,S2 Pro 能生成极具自然感、真实感且情感饱满的语音,在开源与闭源竞争中均处于领先地位。
80
+
81
+ S2 Pro 的杀手锏在于支持通过自然语言标签(如 `[whisper]`、`[excited]`、`[angry]`)对韵律与情绪进行 **亚词级(Sub-word Level)** 的极细粒度行内控制,同时原生支持多说话人与超长上下文的多轮对话生成。
82
+
83
+ 立即访问 [Fish Audio 官网](https://fish.audio/) 体验在线演示,或阅读我们的[技术报告](https://arxiv.org/abs/2603.08823)与[博客文章](https://fish.audio/blog/fish-audio-open-sources-s2/)深入了解。
84
+
85
+ ### 模型变体
86
+
87
+ | 模型 | 大小 | 可用性 | 描述 |
88
+ |------|------|-------------|-------------|
89
+ | S2-Pro | 4B 参数 | [HuggingFace](https://huggingface.co/fishaudio/s2-pro) | 功能齐全的旗���模型,具有最高质量和稳定性 |
90
+
91
+ 有关模型的更多详情,请参见[技术报告](https://arxiv.org/abs/2411.01156)。
92
+
93
+ ## 基准测试结果
94
+
95
+ | 基准 | Fish Audio S2 |
96
+ |------|------|
97
+ | Seed-TTS Eval — WER(中文) | **0.54%**(总体最佳) |
98
+ | Seed-TTS Eval — WER(英文) | **0.99%**(总体最佳) |
99
+ | Audio Turing Test(含指令) | **0.515** 后验均值 |
100
+ | EmergentTTS-Eval — 胜率 | **81.88%**(总体最高) |
101
+ | Fish Instruction Benchmark — TAR | **93.3%** |
102
+ | Fish Instruction Benchmark — 质量 | **4.51 / 5.0** |
103
+ | 多语言(MiniMax Testset)— 最佳 WER | **24** 种语言中的 **11** 种 |
104
+ | 多语言(MiniMax Testset)— 最佳 SIM | **24** 种语言中的 **17** 种 |
105
+
106
+ 在 Seed-TTS Eval 上,S2 在所有已评估模型(包括闭源系统)中实现了最低 WER:Qwen3-TTS(0.77/1.24)、MiniMax Speech-02(0.99/1.90)、Seed-TTS(1.12/2.25)。在 Audio Turing Test 上,S2 的 0.515 相比 Seed-TTS(0.417)提升 24%,相比 MiniMax-Speech(0.387)提升 33%。在 EmergentTTS-Eval 中,S2 在副语言学(91.61% 胜率)、疑问句(84.41%)和句法复杂度(83.39%)等维度表现尤为突出。
107
+
108
+ ## 亮点
109
+
110
+ <img src="./assets/totalability.png" width=200%>
111
+
112
+ ### 通过自然语言进行极细粒度行内控制
113
+
114
+ S2 Pro 赋予了语音前所未有的“灵性”。通过简单的 `[tag]` 语法,你可以在文本的任何位置精准嵌入情感指令。
115
+ - **15,000+ 独特标签支持**:不局限于固定的预设,支持 **自由格式的文本描述**。你可以尝试 `[whisper in small voice]` (低声耳语), `[professional broadcast tone]` (专业播音腔), 或 `[pitch up]` (提高音调)。
116
+ - **丰富的情绪库**:
117
+ `[pause]` `[emphasis]` `[laughing]` `[inhale]` `[chuckle]` `[tsk]` `[singing]` `[excited]` `[laughing tone]` `[interrupting]` `[chuckling]` `[excited tone]` `[volume up]` `[echo]` `[angry]` `[low volume]` `[sigh]` `[low voice]` `[whisper]` `[screaming]` `[shouting]` `[loud]` `[surprised]` `[short pause]` `[exhale]` `[delight]` `[panting]` `[audience laughter]` `[with strong accent]` `[volume down]` `[clearing throat]` `[sad]` `[moaning]` `[shocked]`
118
+
119
+ ### 创新的双自回归 (Dual-Autoregressive) 架构
120
+
121
+ S2 Pro 采用了主从式 Dual-AR 架构,由 Decoder-only Transformer 与 RVQ 音频编解码器(10 个码本,约 21 Hz 帧率)组成:
122
+
123
+ - **Slow AR (4B 参数)**:沿时间轴工作,预测核心的语义码本。
124
+ - **Fast AR (400M 参数)**:在每个时间步生成剩余 9 个残差码本,细腻还原极致的音频细节。
125
+
126
+ 这种非对称设计在保证音频极致保真度的同时,大幅提升了推理速度。
127
+
128
+ ### 强化学习对齐 (RL Alignment)
129
+
130
+ S2 Pro 采用了 **Group Relative Policy Optimization (GRPO)** 技术进行后训练对齐。我们将用于数据清洗与标注的同一套模型直接作为奖励模型 (Reward Model),完美解决了预训练数据分布与后训练目标之间的不匹配问题。
131
+ - **多维奖励信号**:综合评估语义准确性、指令遵循能力、声学偏好评分以及音色相似度,确保生成的每一秒语音都符合人类直觉。
132
+
133
+ ### 极致的流式推理性能 (基于 SGLang)
134
+
135
+ 由于 Dual-AR 架构与标准 LLM 结构同构,S2 Pro 原生支持 SGLang 的所有推理加速特性,包括连续批处理 (Continuous Batching)、分页 KV Cache、CUDA Graph 与基于 RadixAttention 的前缀缓存。
136
+
137
+ **单张 NVIDIA H200 GPU 性能表现:**
138
+ - **实时因子 (RTF)**:0.195
139
+ - **首音延迟 (TTFA)**:约 100 ms
140
+ - **极速吞吐**:在保持 RTF < 0.5 时,吞吐量达到 3,000+ acoustic tokens/s
141
+
142
+ ### 强大的多语言支持
143
+
144
+ S2 Pro 支持 80 多种语言,无需音素或特定语言的处理即可实现高质量合成:
145
+
146
+ - **第一梯队 (Tier 1)**:日语 (ja), 英语 (en), 中文 (zh)
147
+ - **第二梯队 (Tier 2)**:韩语 (ko), 西班牙语 (es), 葡萄牙语 (pt), 阿拉伯语 (ar), 俄语 (ru), 法语 (fr), 德语 (de)
148
+ - **全球覆盖**:sv, it, tr, no, nl, cy, eu, ca, da, gl, ta, hu, fi, pl, et, hi, la, ur, th, vi, jw, bn, yo, xsl, cs, sw, nn, he, ms, uk, id, kk, bg, lv, my, tl, sk, ne, fa, af, el, bo, hr, ro, sn, mi, yi, am, be, km, is, az, sd, br, sq, ps, mn, ht, ml, sr, sa, te, ka, bs, pa, lt, kn, si, hy, mr, as, gu, fo 等。
149
+
150
+ ### 原生多说话人生成
151
+
152
+ <img src="./assets/chattemplate.png" width=200%>
153
+
154
+ Fish Audio S2 允许用户上传包含多个说话人的参考音频,模型将通过 `<|speaker:i|>` 令牌处理每个说话人的特征。之后您可以通过说话人 ID 令牌控制模型的表现,从而实现一次生成中包含多个说话人。再也不需要像以前那样针对每个说话人都单独上传参考音频与生成语音了。
155
+
156
+ ### 多轮对话生成
157
+
158
+ 得益于模型上下文的扩展,我们的模型现在可以借助上文的信息提高后续生成内容的表现力,从而提升内容的自然度。
159
+
160
+ ### 快速语音克隆
161
+
162
+ Fish Audio S2 支持使用短参考样本(通常为 10-30 秒)进行准确���语音克隆。模型可以捕捉音色、说话风格和情感倾向,无需额外微调即可生成逼真且一致的克隆语音。
163
+ 如需使用 SGLang Server,请参考 [SGLang-Omni README](https://github.com/sgl-project/sglang-omni/blob/main/sglang_omni/models/fishaudio_s2_pro/README.md) 。
164
+
165
+ ---
166
+
167
+ ## 致谢
168
+
169
+ - [VITS2 (daniilrobnikov)](https://github.com/daniilrobnikov/vits2)
170
+ - [Bert-VITS2](https://github.com/fishaudio/Bert-VITS2)
171
+ - [GPT VITS](https://github.com/innnky/gpt-vits)
172
+ - [MQTTS](https://github.com/b04901014/MQTTS)
173
+ - [GPT Fast](https://github.com/pytorch-labs/gpt-fast)
174
+ - [GPT-SoVITS](https://github.com/RVC-Boss/GPT-SoVITS)
175
+ - [Qwen3](https://github.com/QwenLM/Qwen3)
176
+
177
+ ## 技术报告
178
+
179
+ ```bibtex
180
+ @misc{fish-speech-v1.4,
181
+ title={Fish-Speech: Leveraging Large Language Models for Advanced Multilingual Text-to-Speech Synthesis},
182
+ author={Shijia Liao and Yuxuan Wang and Tianyu Li and Yifan Cheng and Ruoyi Zhang and Rongzhi Zhou and Yijin Xing},
183
+ year={2024},
184
+ eprint={2411.01156},
185
+ archivePrefix={arXiv},
186
+ primaryClass={cs.SD},
187
+ url={https://arxiv.org/abs/2411.01156},
188
+ }
189
+
190
+ @misc{liao2026fishaudios2technical,
191
+ title={Fish Audio S2 Technical Report},
192
+ author={Shijia Liao and Yuxuan Wang and Songting Liu and Yifan Cheng and Ruoyi Zhang and Tianyu Li and Shidong Li and Yisheng Zheng and Xingwei Liu and Qingzheng Wang and Zhizhuo Zhou and Jiahua Liu and Xin Chen and Dawei Han},
193
+ year={2026},
194
+ eprint={2603.08823},
195
+ archivePrefix={arXiv},
196
+ primaryClass={cs.SD},
197
+ url={https://arxiv.org/abs/2603.08823},
198
+ }
199
+ ```
vendor/fish-speech/docs/requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ mkdocs-material
2
+ mkdocs-static-i18n[material]
3
+ mkdocs[i18n]
vendor/fish-speech/fish_speech/callbacks/__init__.py ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ from .grad_norm import GradNormMonitor
2
+ from .progress_bar import GradAccumProgressBar
3
+
4
+ __all__ = ["GradNormMonitor", "GradAccumProgressBar"]
vendor/fish-speech/fish_speech/callbacks/grad_norm.py ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Optional, Union
2
+
3
+ import lightning.pytorch as pl
4
+ import torch
5
+ from lightning import LightningModule, Trainer
6
+ from lightning.pytorch.callbacks import Callback
7
+ from torch import Tensor, nn
8
+ from torch.utils._foreach_utils import (
9
+ _group_tensors_by_device_and_dtype,
10
+ _has_foreach_support,
11
+ )
12
+
13
+
14
+ @torch.no_grad()
15
+ def grad_norm(
16
+ parameters: Union[Tensor, list[Tensor]],
17
+ norm_type: float = 2.0,
18
+ ) -> float:
19
+ """
20
+ Returns the norm of the gradients of the given parameters.
21
+
22
+ Args:
23
+ parameters (Iterable[Tensor] or Tensor): an iterable of Tensors or a
24
+ single Tensor that will have gradients normalized
25
+ norm_type (float): type of the used p-norm.
26
+
27
+ Returns:
28
+ Total norm of the parameter gradients (viewed as a single vector).
29
+ """ # noqa: E501
30
+
31
+ if isinstance(parameters, Tensor):
32
+ parameters = [parameters]
33
+
34
+ grads = [p.grad for p in parameters if p.grad is not None]
35
+ if len(grads) == 0:
36
+ return None
37
+
38
+ first_device = grads[0].device
39
+ grouped_grads: dict[
40
+ tuple[torch.device, torch.dtype], list[list[Tensor]]
41
+ ] = _group_tensors_by_device_and_dtype(
42
+ [[g.detach() for g in grads]]
43
+ ) # type: ignore[assignment]
44
+
45
+ norms = []
46
+ for (device, _), ([grads], _) in grouped_grads.items():
47
+ if _has_foreach_support(grads, device=device):
48
+ norms.extend(torch._foreach_norm(grads, norm_type))
49
+ else:
50
+ norms.extend([torch.norm(g, norm_type) for g in grads])
51
+
52
+ return torch.norm(torch.stack([norm.to(first_device) for norm in norms]), norm_type)
53
+
54
+
55
+ class GradNormMonitor(Callback):
56
+ """
57
+ Callback that computes the gradient norm of the model parameters.
58
+ """
59
+
60
+ def __init__(
61
+ self,
62
+ norm_type: float = 2.0,
63
+ logging_interval: str = "step",
64
+ sub_module: Optional[Union[str, list[str]]] = None,
65
+ ) -> None:
66
+ """
67
+ Args:
68
+ norm_type (float): type of the used p-norm.
69
+ logging_interval (str): "step" or "epoch".
70
+ """
71
+ super().__init__()
72
+
73
+ self.norm_type = norm_type
74
+ self.logging_interval = logging_interval
75
+ self.sub_module = sub_module
76
+
77
+ def on_after_backward(self, trainer: Trainer, model: LightningModule) -> None:
78
+ """
79
+ Computes the gradient norm of the model parameters and logs it to the logger.
80
+
81
+ Args:
82
+ trainer (Trainer): The trainer object
83
+ model (LightningModule): The current lightningModule
84
+ """
85
+
86
+ lightning_model = model
87
+
88
+ if self.sub_module is None:
89
+ return self.log_sub_module_grad_norm(lightning_model, model, "")
90
+
91
+ sub_modules = self.sub_module
92
+ if isinstance(sub_modules, str):
93
+ sub_modules = [sub_modules]
94
+
95
+ for sub_module in sub_modules:
96
+ self.log_sub_module_grad_norm(
97
+ lightning_model, getattr(model, sub_module), f"/{sub_module}"
98
+ )
99
+
100
+ def log_sub_module_grad_norm(
101
+ self, lightning_model: LightningModule, model: nn.Module, path: str
102
+ ) -> None:
103
+ grad_norm_val = grad_norm(model.parameters(), self.norm_type)
104
+ if grad_norm_val is None:
105
+ return
106
+
107
+ on_step = self.logging_interval == "step"
108
+ lightning_model.log(
109
+ f"train{path}/grad_norm",
110
+ grad_norm_val,
111
+ on_step=on_step,
112
+ on_epoch=not on_step,
113
+ )
vendor/fish-speech/fish_speech/callbacks/progress_bar.py ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from lightning.pytorch.callbacks import TQDMProgressBar
2
+
3
+
4
+ class GradAccumProgressBar(TQDMProgressBar):
5
+ """
6
+ Progress bar that accounts for gradient accumulation so the total
7
+ reflects actual forward passes rather than optimizer steps.
8
+ """
9
+
10
+ @property
11
+ def total_train_batches(self):
12
+ total = super().total_train_batches
13
+ accumulate = self.trainer.accumulate_grad_batches
14
+ if isinstance(total, int) and accumulate > 1:
15
+ return total * accumulate
16
+ return total
vendor/fish-speech/fish_speech/configs/base.yaml ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Base configuration for training a model
2
+ paths:
3
+ run_dir: results/${project}
4
+ ckpt_dir: ${paths.run_dir}/checkpoints
5
+
6
+ hydra:
7
+ run:
8
+ dir: ${paths.run_dir}
9
+
10
+ # Lightning Trainer
11
+ trainer:
12
+ _target_: lightning.pytorch.trainer.Trainer
13
+
14
+ default_root_dir: ${paths.run_dir}
15
+ accelerator: gpu
16
+ num_nodes: 1
17
+ devices: auto
18
+ strategy:
19
+ _target_: lightning.pytorch.strategies.DDPStrategy
20
+ process_group_backend: nccl # This should be override when training on windows
21
+
22
+ precision: bf16-mixed
23
+
24
+ # disable validation by epoch end
25
+ check_val_every_n_epoch: null
26
+ val_check_interval: 5000
27
+ max_steps: 100_000
28
+
29
+ # Use torch.backends.cudnn.benchmark to speed up training
30
+ benchmark: true
31
+
32
+ # Callbacks
33
+ callbacks:
34
+ model_checkpoint:
35
+ _target_: lightning.pytorch.callbacks.ModelCheckpoint
36
+ dirpath: ${paths.ckpt_dir}
37
+ filename: "step_{step:09d}"
38
+ save_last: false # additionally always save an exact copy of the last checkpoint to a file last.ckpt
39
+ save_top_k: 5 # save 5 latest checkpoints
40
+ monitor: step # use step to monitor checkpoints
41
+ mode: max # save the latest checkpoint with the highest global_step
42
+ every_n_epochs: null # don't save checkpoints by epoch end
43
+ every_n_train_steps: 5000 # save checkpoints every 5000 steps
44
+ auto_insert_metric_name: false
45
+
46
+ model_summary:
47
+ _target_: lightning.pytorch.callbacks.ModelSummary
48
+ max_depth: 2 # the maximum depth of layer nesting that the summary will include
49
+
50
+ learning_rate_monitor:
51
+ _target_: lightning.pytorch.callbacks.LearningRateMonitor
52
+ logging_interval: step
53
+ log_momentum: false
54
+
55
+ grad_norm_monitor:
56
+ _target_: fish_speech.callbacks.GradNormMonitor
57
+ norm_type: 2
58
+ logging_interval: step
59
+
60
+ progress_bar:
61
+ _target_: fish_speech.callbacks.GradAccumProgressBar
62
+
63
+ # Logger
64
+ logger:
65
+ tensorboard:
66
+ _target_: lightning.pytorch.loggers.tensorboard.TensorBoardLogger
67
+ save_dir: "${paths.run_dir}/tensorboard/"
68
+ name: null
69
+ log_graph: false
70
+ default_hp_metric: true
71
+ prefix: ""
72
+
73
+ # wandb:
74
+ # _target_: lightning.pytorch.loggers.wandb.WandbLogger
75
+ # # name: "" # name of the run (normally generated by wandb)
76
+ # save_dir: "${paths.run_dir}"
77
+ # offline: False
78
+ # id: null # pass correct id to resume experiment!
79
+ # anonymous: null # enable anonymous logging
80
+ # project: "fish-speech"
81
+ # log_model: False # upload lightning ckpts
82
+ # prefix: "" # a string to put at the beginning of metric keys
83
+ # # entity: "" # set to name of your wandb team
84
+ # group: ""
85
+ # tags: ["vq", "hq", "finetune"]
86
+ # job_type: ""
87
+
88
+ # Loop
89
+ train: true
90
+ test: false
vendor/fish-speech/fish_speech/configs/modded_dac_vq.yaml ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ _target_: fish_speech.models.dac.modded_dac.DAC
2
+ # Model setup
3
+ sample_rate: 44100
4
+ encoder_dim: 64
5
+ encoder_rates: [2, 4, 8, 8]
6
+ decoder_dim: 1536
7
+ decoder_rates: [8, 8, 4, 2]
8
+ encoder_transformer_layers: [0, 0, 0, 4]
9
+ decoder_transformer_layers: [4, 0, 0, 0]
10
+ transformer_general_config:
11
+ _target_: fish_speech.models.dac.modded_dac.ModelArgs
12
+ _partial_: true
13
+ block_size: 8192
14
+ n_local_heads: -1
15
+ head_dim: 64
16
+ rope_base: 10000
17
+ norm_eps: 1e-5
18
+ dropout_rate: 0.1
19
+ attn_dropout_rate: 0.1
20
+ channels_first: true
21
+ # Quantization
22
+ quantizer:
23
+ _target_: fish_speech.models.dac.rvq.DownsampleResidualVectorQuantize
24
+ input_dim: 1024
25
+ n_codebooks: 9
26
+ codebook_size: 1024
27
+ codebook_dim: 8
28
+ quantizer_dropout: 0.5
29
+ downsample_factor: [2, 2]
30
+ post_module: &transformer_module
31
+ _target_: fish_speech.models.dac.modded_dac.WindowLimitedTransformer
32
+ causal: true
33
+ window_size: 128 # empirically this does not seem to matter
34
+ input_dim: 1024
35
+ config: &transformer_config
36
+ _target_: fish_speech.models.dac.modded_dac.ModelArgs
37
+ block_size: 2048
38
+ n_layer: 8
39
+ n_head: 16
40
+ dim: 1024
41
+ intermediate_size: 3072
42
+ n_local_heads: -1
43
+ head_dim: 64
44
+ rope_base: 10000
45
+ norm_eps: 1e-5
46
+ dropout_rate: 0.1
47
+ attn_dropout_rate: 0.1
48
+ channels_first: true
49
+ pre_module: *transformer_module
50
+ semantic_codebook_size: 4096
vendor/fish-speech/fish_speech/configs/text2semantic_finetune.yaml ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ defaults:
2
+ - base
3
+ - _self_
4
+
5
+ project: text2semantic_finetune_dual_ar
6
+ max_length: 4096
7
+ pretrained_ckpt_path: checkpoints/openaudio-s1-mini
8
+
9
+ # Lightning Trainer
10
+ trainer:
11
+ accumulate_grad_batches: 1
12
+ gradient_clip_val: 1.0
13
+ gradient_clip_algorithm: "norm"
14
+ max_steps: 10000
15
+ precision: bf16-true
16
+ limit_val_batches: 10
17
+ val_check_interval: 100
18
+ # strategy:
19
+ # find_unused_parameters: true
20
+ # static_graph: true
21
+
22
+ # Dataset Configuration
23
+ tokenizer:
24
+ _target_: fish_speech.tokenizer.FishTokenizer
25
+ model_path: ${pretrained_ckpt_path}/tokenizer.tiktoken
26
+
27
+ # Dataset Configuration
28
+ train_dataset:
29
+ _target_: fish_speech.datasets.semantic.AutoTextSemanticInstructionIterableDataset
30
+ proto_files:
31
+ - data/protos
32
+ tokenizer: ${tokenizer}
33
+ causal: true
34
+ max_length: ${max_length}
35
+ use_speaker: false
36
+ interactive_prob: 0.7
37
+
38
+ val_dataset:
39
+ _target_: fish_speech.datasets.semantic.AutoTextSemanticInstructionIterableDataset
40
+ proto_files:
41
+ - data/protos
42
+ tokenizer: ${tokenizer}
43
+ causal: true
44
+ max_length: ${max_length}
45
+ use_speaker: false
46
+ interactive_prob: 0.7
47
+
48
+ data:
49
+ _target_: fish_speech.datasets.semantic.SemanticDataModule
50
+ train_dataset: ${train_dataset}
51
+ val_dataset: ${val_dataset}
52
+ num_workers: 4
53
+ batch_size: 4
54
+ tokenizer: ${tokenizer}
55
+ max_length: ${max_length}
56
+
57
+ # Model Configuration
58
+ model:
59
+ _target_: fish_speech.models.text2semantic.lit_module.TextToSemantic
60
+ model:
61
+ _target_: fish_speech.models.text2semantic.llama.BaseTransformer.from_pretrained
62
+ path: ${pretrained_ckpt_path}
63
+ load_weights: true
64
+ max_length: ${max_length}
65
+ lora_config: null
66
+
67
+ optimizer:
68
+ _target_: torch.optim.AdamW
69
+ _partial_: true
70
+ lr: 1e-4
71
+ weight_decay: 0
72
+ betas: [0.9, 0.95]
73
+ eps: 1e-5
74
+
75
+ lr_scheduler:
76
+ _target_: torch.optim.lr_scheduler.LambdaLR
77
+ _partial_: true
78
+ lr_lambda:
79
+ _target_: fish_speech.scheduler.get_constant_schedule_with_warmup_lr_lambda
80
+ _partial_: true
81
+ num_warmup_steps: 10
82
+
83
+ # Callbacks
84
+ callbacks:
85
+ model_checkpoint:
86
+ every_n_train_steps: ${trainer.val_check_interval}
vendor/fish-speech/fish_speech/content_sequence.py ADDED
@@ -0,0 +1,403 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from dataclasses import dataclass, field
2
+ from typing import List, Literal, Union
3
+
4
+ import numpy as np
5
+ import torch
6
+
7
+ from fish_speech.tokenizer import (
8
+ IM_END_TOKEN,
9
+ MODALITY_TOKENS,
10
+ FishTokenizer,
11
+ )
12
+
13
+
14
+ def restore_ndarray(obj, to_tensor: bool = False):
15
+ if isinstance(obj, dict) and "__ndarray__" in obj:
16
+ obj = np.frombuffer(obj["data"], dtype=obj["dtype"]).reshape(obj["shape"])
17
+
18
+ if to_tensor and isinstance(obj, np.ndarray):
19
+ obj = torch.from_numpy(obj.copy())
20
+
21
+ return obj
22
+
23
+
24
+ @dataclass
25
+ class BasePart:
26
+ type: Literal["text", "vq", "audio"] | None = None
27
+ cal_loss: bool = False
28
+
29
+
30
+ @dataclass(kw_only=True)
31
+ class VQPart(BasePart):
32
+ type = "vq"
33
+ codes: torch.Tensor
34
+
35
+ def __post_init__(self: "VQPart"):
36
+ self.type = "vq"
37
+ self.codes = restore_ndarray(self.codes, to_tensor=True)
38
+
39
+
40
+ @dataclass(kw_only=True)
41
+ class TextPart(BasePart):
42
+ type = "text"
43
+ text: str | None = None
44
+ tokens: list[int] | None = None
45
+
46
+ def __post_init__(self: "TextPart"):
47
+ self.type = "text"
48
+ if self.text is None and self.tokens is None:
49
+ raise ValueError("Either text or tokens must be provided")
50
+
51
+
52
+ @dataclass(kw_only=True)
53
+ class AudioPart(BasePart):
54
+ type = "audio"
55
+ features: torch.Tensor
56
+
57
+ def __post_init__(self: "AudioPart"):
58
+ self.type = "audio"
59
+ self.features = restore_ndarray(self.features, to_tensor=True)
60
+
61
+
62
+ @dataclass(kw_only=True)
63
+ class EncodedMessage:
64
+ tokens: torch.Tensor
65
+ labels: torch.Tensor
66
+ vq_mask_tokens: torch.Tensor | None = None
67
+ vq_mask_labels: torch.Tensor | None = None
68
+ vq_parts: list[torch.Tensor]
69
+ vq_require_losses: torch.Tensor | None = None
70
+ audio_parts: list[torch.Tensor]
71
+ audio_masks: torch.Tensor | None = None
72
+ metadata: dict | None = None
73
+
74
+
75
+ @dataclass
76
+ class ContentSequence:
77
+ """
78
+ Flexible sequence of content parts that supports interleaved multimodal format.
79
+ Example format: <|interleave|><|speaker:1|> TEXT AUDIO <|im_end|><|speaker:2|> TEXT AUDIO <|im_end|>
80
+ """
81
+
82
+ parts: list[BasePart] = field(default_factory=list)
83
+ modality: Literal["text", "voice", "interleave"] | None = None
84
+ metadata: dict | None = None
85
+
86
+ def __init__(
87
+ self: "ContentSequence",
88
+ parts: list[BasePart | dict] | None = None,
89
+ modality: Literal["text", "voice", "interleave"] | None = None,
90
+ metadata: dict | None = None,
91
+ ):
92
+ self.modality = modality
93
+ self.metadata = metadata or {}
94
+
95
+ fixed_parts = []
96
+ for part in parts or []:
97
+ if isinstance(part, dict):
98
+ if part["type"] == "vq":
99
+ part = VQPart(**part)
100
+ elif part["type"] == "audio":
101
+ part = AudioPart(**part)
102
+ elif part["type"] == "text":
103
+ part = TextPart(**part)
104
+ else:
105
+ raise ValueError(f"Unsupported part type: {part['type']}")
106
+ fixed_parts.append(part)
107
+
108
+ self.parts = fixed_parts
109
+
110
+ # If modality is specified, add it at the beginning if it's not already there
111
+ if self.modality and not (
112
+ len(self.parts) > 0
113
+ and isinstance(self.parts[0], dict) is False
114
+ and isinstance(self.parts[0], TextPart)
115
+ and self.parts[0].text is not None
116
+ and self.parts[0].text.startswith(MODALITY_TOKENS[self.modality])
117
+ ):
118
+ modality_token = MODALITY_TOKENS[self.modality]
119
+ self.parts.insert(0, TextPart(text=modality_token))
120
+
121
+ def append(
122
+ self: "ContentSequence",
123
+ part_or_parts: Union[BasePart, List[BasePart]],
124
+ add_end: bool = False,
125
+ speaker: Union[str, int] | None = None,
126
+ ):
127
+ """
128
+ Append a part or list of parts to the sequence.
129
+
130
+ Args:
131
+ part_or_parts: A single part or list of parts to add
132
+ add_end: Whether to add the IM_END_TOKEN after these parts
133
+ speaker: Optional speaker identifier (name or ID) to add before the parts
134
+ """
135
+ # Convert single part to list
136
+ parts_to_add = (
137
+ [part_or_parts] if not isinstance(part_or_parts, list) else part_or_parts
138
+ )
139
+
140
+ # Add speaker token if specified
141
+ if speaker is not None:
142
+ speaker_token = f"<|speaker:{speaker}|>"
143
+ self.parts.append(TextPart(text=speaker_token))
144
+
145
+ # Add all the parts
146
+ self.parts.extend(parts_to_add)
147
+
148
+ # Add end token if requested
149
+ if add_end:
150
+ self.parts.append(
151
+ TextPart(text=IM_END_TOKEN, cal_loss=self.parts[-1].cal_loss)
152
+ )
153
+
154
+ def encode(
155
+ self: "ContentSequence",
156
+ tokenizer: FishTokenizer,
157
+ add_shift: bool = True,
158
+ ignore_loss_tokens: list[str] = [],
159
+ ) -> EncodedMessage:
160
+ """
161
+ Encode the sequence parts into tokens for the model.
162
+
163
+ Args:
164
+ tokenizer: The tokenizer to use
165
+ add_shift: Whether to shift tokens for next-token prediction
166
+ ignore_loss_tokens: List of token strings to ignore when calculating loss
167
+
168
+ Returns:
169
+ EncodedMessage with tensors ready for the model
170
+ """
171
+ all_tokens = []
172
+ all_labels = []
173
+
174
+ # Multi-modal elements
175
+ vq_parts = []
176
+ vq_masks = []
177
+ vq_require_losses = []
178
+
179
+ audio_parts = []
180
+ audio_masks = []
181
+
182
+ # Optimization: Batch conversion for ignore tokens
183
+ ignore_loss_token_ids = []
184
+ if ignore_loss_tokens:
185
+ # Use the wrapper method which uses convert_tokens_to_ids
186
+ ignore_loss_token_ids = [
187
+ tokenizer.get_token_id(i) for i in ignore_loss_tokens
188
+ ]
189
+
190
+ for part in self.parts:
191
+ if isinstance(part, TextPart):
192
+ if part.tokens is None:
193
+ assert part.text is not None
194
+ # Optimization: Explicitly disable special tokens (BOS/EOS)
195
+ # because we are constructing the sequence manually
196
+ tokens = tokenizer.encode(part.text, add_special_tokens=False)
197
+ else:
198
+ tokens = part.tokens
199
+
200
+ tokens = torch.tensor(tokens, dtype=torch.long)
201
+ elif isinstance(part, VQPart):
202
+ # Critical Optimization: Vectorized mapping
203
+ # Instead of loop lookup: [tokenizer.semantic_id_to_token_id[i] for i in codes]
204
+ # We use arithmetic offset: code + semantic_begin_id
205
+ # This assumes semantic tokens are contiguous in the vocab (DualAR requirement)
206
+ curr_codes = part.codes.clone().to(torch.int)
207
+
208
+ # Use int64 (long) for token IDs to avoid overflow or type mismatch in embedding
209
+ tokens = (curr_codes[0] + tokenizer.semantic_begin_id).to(torch.long)
210
+
211
+ vq_parts.append(curr_codes)
212
+ vq_require_losses.append(part.cal_loss)
213
+ else:
214
+ raise ValueError(f"Unsupported part type: {type(part)}")
215
+
216
+ all_tokens.append(tokens)
217
+
218
+ # Set masks for different part types
219
+ if isinstance(part, VQPart):
220
+ vq_masks.append(torch.ones_like(tokens, dtype=torch.bool))
221
+ audio_masks.append(torch.zeros_like(tokens, dtype=torch.bool))
222
+ elif isinstance(part, AudioPart):
223
+ vq_masks.append(torch.zeros_like(tokens, dtype=torch.bool))
224
+ audio_mask = torch.ones_like(tokens, dtype=torch.bool)
225
+ audio_mask[0] = False # Skip start token
226
+ audio_mask[-1] = False # Skip end token
227
+ audio_masks.append(audio_mask)
228
+ else:
229
+ vq_masks.append(torch.zeros_like(tokens, dtype=torch.bool))
230
+ audio_masks.append(torch.zeros_like(tokens, dtype=torch.bool))
231
+
232
+ # Set labels based on whether we want to calculate loss for this part
233
+ if part.cal_loss and not isinstance(part, AudioPart):
234
+ all_labels.append(tokens.clone())
235
+ else:
236
+ all_labels.append(torch.full_like(tokens, -100))
237
+
238
+ # Concatenate all tensors
239
+ if not all_tokens:
240
+ # Handle empty case safely
241
+ tokens = torch.empty(0, dtype=torch.long)
242
+ labels = torch.empty(0, dtype=torch.long)
243
+ vq_masks = torch.empty(0, dtype=torch.bool)
244
+ audio_masks = torch.empty(0, dtype=torch.bool)
245
+ else:
246
+ tokens = torch.cat(all_tokens, dim=0)
247
+ labels = torch.cat(all_labels, dim=0)
248
+ vq_masks = torch.cat(vq_masks, dim=0)
249
+ audio_masks = torch.cat(audio_masks, dim=0)
250
+
251
+ vq_require_losses = torch.tensor(vq_require_losses, dtype=torch.bool)
252
+
253
+ # Apply shift if needed for next-token prediction
254
+ vq_mask_tokens = vq_masks
255
+ vq_mask_labels = vq_masks
256
+
257
+ if add_shift and len(tokens) > 0:
258
+ tokens = tokens[:-1]
259
+ labels = labels[1:]
260
+ vq_masks = vq_masks[:-1]
261
+ vq_mask_tokens = vq_mask_tokens[:-1]
262
+ vq_mask_labels = vq_mask_labels[1:]
263
+ audio_masks = audio_masks[:-1]
264
+
265
+ # Ignore specified tokens
266
+ for i in ignore_loss_token_ids:
267
+ if i is not None:
268
+ labels[labels == i] = -100
269
+
270
+ return EncodedMessage(
271
+ tokens=tokens,
272
+ labels=labels,
273
+ vq_parts=vq_parts,
274
+ vq_mask_tokens=vq_mask_tokens,
275
+ vq_mask_labels=vq_mask_labels,
276
+ vq_require_losses=vq_require_losses,
277
+ audio_parts=audio_parts,
278
+ audio_masks=audio_masks,
279
+ metadata=self.metadata,
280
+ )
281
+
282
+ def encode_for_inference(
283
+ self: "ContentSequence",
284
+ tokenizer: FishTokenizer,
285
+ num_codebooks: int,
286
+ ) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
287
+ encoded = self.encode(tokenizer, add_shift=False)
288
+ tokens = encoded.tokens
289
+ # Use int32 for prompt cache to save memory, convert to model dtype later if needed
290
+ # Or keep as input_ids (long)
291
+ values = torch.zeros((num_codebooks + 1, len(tokens)), dtype=torch.long)
292
+ values[0] = tokens
293
+
294
+ if (encoded.vq_parts is None or len(encoded.vq_parts) == 0) and (
295
+ encoded.audio_parts is None or len(encoded.audio_parts) == 0
296
+ ):
297
+ return values, None, None
298
+
299
+ audio_parts = None
300
+ audio_masks = None
301
+
302
+ if encoded.vq_parts is not None and len(encoded.vq_parts) > 0:
303
+ vq_parts = encoded.vq_parts
304
+ # List[Tensor(1, T)] -> Tensor(1, Total_T) -> Tensor(1, Total_T)
305
+ # Ensure we are handling the list concatenation correctly
306
+ if len(vq_parts) > 1:
307
+ # We need to be careful here: vq_parts is a list of tensors from different VQPart segments
308
+ # They correspond to encoded.vq_mask_tokens
309
+ # Since we just want to fill the 'values' tensor at the right positions:
310
+ all_vq_codes = torch.cat(
311
+ vq_parts, dim=1
312
+ ) # Shape: (C, Total_Semantic_Tokens)
313
+ else:
314
+ all_vq_codes = vq_parts[0]
315
+
316
+ # Values[0] is already the Main Token ID (Semantic Begin + Code)
317
+ # Values[1:] should be the codes themselves
318
+ values[1:, encoded.vq_mask_tokens] = all_vq_codes.to(dtype=torch.long)
319
+
320
+ if encoded.audio_parts is not None and len(encoded.audio_parts) > 0:
321
+ audio_parts = torch.cat(encoded.audio_parts, dim=0)
322
+ audio_masks = encoded.audio_masks[None, :]
323
+
324
+ return values, audio_masks, audio_parts
325
+
326
+ def visualize(
327
+ self: "ContentSequence",
328
+ tokenizer: FishTokenizer,
329
+ ignore_loss_tokens: list[str] = [],
330
+ merge_semantic_tokens: bool = False,
331
+ ):
332
+ """
333
+ Visualize the encoded sequence with color-coded tokens.
334
+ Blue/cyan tokens contribute to loss, green tokens do not.
335
+ """
336
+ encoded = self.encode(
337
+ tokenizer, add_shift=False, ignore_loss_tokens=ignore_loss_tokens
338
+ )
339
+
340
+ # Colors for alternating tokens
341
+ colors = {
342
+ "blue": "\033[94m", # Light blue
343
+ "cyan": "\033[96m", # Cyan
344
+ "green": "\033[92m", # Light green
345
+ "dark_green": "\033[32m", # Dark green
346
+ }
347
+ blue_idx = 0
348
+ green_idx = 0
349
+
350
+ def print_in_blue(x):
351
+ nonlocal blue_idx
352
+ color = colors["blue"] if blue_idx % 2 == 0 else colors["cyan"]
353
+ print(f"{color}{x}\033[0m", end="")
354
+ blue_idx += 1
355
+
356
+ def print_in_green(x):
357
+ nonlocal green_idx
358
+ color = colors["green"] if green_idx % 2 == 0 else colors["dark_green"]
359
+ print(f"{color}{x}\033[0m", end="")
360
+ green_idx += 1
361
+
362
+ def print_semantic_token(x, count):
363
+ val = f"[<|semantic|>x{count}]"
364
+ if x == -100:
365
+ print_in_green(val)
366
+ else:
367
+ print_in_blue(val)
368
+
369
+ count_semantic_tokens = 0
370
+ semantic_label = None
371
+
372
+ for tok, lab in zip(encoded.tokens, encoded.labels):
373
+ token_id = int(tok.item())
374
+
375
+ if merge_semantic_tokens:
376
+ if (
377
+ tokenizer.semantic_begin_id <= token_id <= tokenizer.semantic_end_id
378
+ and (semantic_label is None or semantic_label == lab)
379
+ ):
380
+ count_semantic_tokens += 1
381
+ semantic_label = lab
382
+ continue
383
+ elif count_semantic_tokens > 0:
384
+ print_semantic_token(semantic_label, count_semantic_tokens)
385
+ count_semantic_tokens = 0
386
+ semantic_label = None
387
+
388
+ # Use HF decode
389
+ val = tokenizer.decode([token_id])
390
+
391
+ # Simple fallback for visualization if decode returns empty or weird stuff for special tokens
392
+ if not val:
393
+ val = f"<{token_id}>"
394
+
395
+ if lab == -100:
396
+ print_in_green(val)
397
+ else:
398
+ print_in_blue(val)
399
+
400
+ if merge_semantic_tokens and count_semantic_tokens > 0:
401
+ print_semantic_token(semantic_label, count_semantic_tokens)
402
+
403
+ print()
vendor/fish-speech/fish_speech/conversation.py ADDED
@@ -0,0 +1,174 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from copy import deepcopy
2
+ from dataclasses import dataclass, field
3
+ from typing import Literal
4
+
5
+ import torch
6
+ from transformers import PreTrainedTokenizerFast
7
+
8
+ from fish_speech.content_sequence import (
9
+ AudioPart,
10
+ BasePart,
11
+ ContentSequence,
12
+ EncodedMessage,
13
+ TextPart,
14
+ VQPart,
15
+ )
16
+ from fish_speech.tokenizer import IM_END_TOKEN, IM_START_TOKEN, MODALITY_TOKENS
17
+
18
+
19
+ @dataclass(kw_only=True)
20
+ class Message:
21
+ role: Literal["system", "user", "assistant"]
22
+ parts: list[BasePart] = field(default_factory=list)
23
+ add_im_start: bool = True
24
+ add_im_end: bool = True
25
+ cal_loss: bool = False
26
+ modality: Literal["text", "voice", "interleave"] | None = None
27
+
28
+ # By default, ignore the loss of the auto-generated im_start token
29
+ ignore_im_start_loss: bool = True
30
+
31
+
32
+ @dataclass
33
+ class Conversation:
34
+ messages: list[Message]
35
+
36
+ def __init__(self: "Conversation", messages: list[Message] | None = None):
37
+ self.messages = messages or []
38
+
39
+ def _build_content_sequence(
40
+ self: "Conversation",
41
+ metadata: dict | None = None,
42
+ ) -> ContentSequence:
43
+ """
44
+ Build a ContentSequence from all messages.
45
+ Handles cal_loss inheritance from message to part level.
46
+ """
47
+ all_parts = []
48
+ for message in self.messages:
49
+ # Add im_start
50
+ if message.add_im_start:
51
+ modality_token = (
52
+ MODALITY_TOKENS[message.modality] if message.modality else ""
53
+ )
54
+ all_parts.append(
55
+ TextPart(
56
+ text=f"{IM_START_TOKEN}{message.role}\n{modality_token}",
57
+ cal_loss=not message.ignore_im_start_loss,
58
+ )
59
+ )
60
+
61
+ # Add message parts
62
+ for part in message.parts:
63
+ # Inherit cal_loss from message if not set at part level
64
+ if not hasattr(part, "cal_loss") or part.cal_loss is False:
65
+ new_part = deepcopy(part)
66
+ new_part.cal_loss = message.cal_loss
67
+ all_parts.append(new_part)
68
+ else:
69
+ all_parts.append(part)
70
+
71
+ # Add im_end
72
+ if message.add_im_end:
73
+ all_parts.append(
74
+ TextPart(text=IM_END_TOKEN + "\n", cal_loss=message.cal_loss)
75
+ )
76
+
77
+ return ContentSequence(parts=all_parts, modality=None, metadata=metadata)
78
+
79
+ def encode(
80
+ self: "Conversation",
81
+ tokenizer: any,
82
+ add_shift: bool = True,
83
+ ignore_loss_tokens: list[str] = [],
84
+ metadata: dict | None = None,
85
+ max_length: int | None = None,
86
+ ) -> EncodedMessage:
87
+ # Build ContentSequence from messages
88
+ content_seq = self._build_content_sequence(metadata=metadata)
89
+ return content_seq.encode(
90
+ tokenizer,
91
+ add_shift=add_shift,
92
+ ignore_loss_tokens=ignore_loss_tokens,
93
+ max_length=max_length,
94
+ )
95
+
96
+ def encode_for_inference(
97
+ self: "Conversation",
98
+ tokenizer: any,
99
+ num_codebooks: int,
100
+ metadata: dict | None = None,
101
+ ):
102
+ content_seq = self._build_content_sequence(metadata=metadata)
103
+ return content_seq.encode_for_inference(tokenizer, num_codebooks=num_codebooks)
104
+
105
+ def visualize(
106
+ self: "Conversation",
107
+ tokenizer: PreTrainedTokenizerFast,
108
+ ignore_loss_tokens: list[str] = [],
109
+ merge_semantic_tokens: bool = False,
110
+ merge_audio_tokens: bool = False,
111
+ use_color: bool = True,
112
+ ):
113
+ """
114
+ Visualize the encoded sequence with color-coded tokens.
115
+ Blue/cyan tokens contribute to loss, green tokens do not.
116
+ """
117
+ # Build ContentSequence from messages and use its visualize method
118
+ content_seq = self._build_content_sequence()
119
+ content_seq.visualize(
120
+ tokenizer,
121
+ ignore_loss_tokens=ignore_loss_tokens,
122
+ merge_semantic_tokens=merge_semantic_tokens,
123
+ )
124
+
125
+ def append(self: "Conversation", message: Message):
126
+ self.messages.append(message)
127
+
128
+ def to_content_sequence(
129
+ self: "Conversation",
130
+ metadata: dict | None = None,
131
+ ) -> ContentSequence:
132
+ """
133
+ Convert the Conversation to a ContentSequence.
134
+
135
+ This method builds a ContentSequence from all messages,
136
+ handling cal_loss inheritance from message to part level.
137
+
138
+ Args:
139
+ metadata: Optional metadata to include in the ContentSequence
140
+
141
+ Returns:
142
+ ContentSequence with all messages converted to parts
143
+ """
144
+ return self._build_content_sequence(metadata=metadata)
145
+
146
+
147
+ if __name__ == "__main__":
148
+ # Test the new implementation with the same API
149
+ message0 = Message(
150
+ role="user",
151
+ parts=[
152
+ TextPart(text="Hello, how are you?"),
153
+ VQPart(codes=torch.zeros((4, 10))),
154
+ ],
155
+ cal_loss=False,
156
+ )
157
+
158
+ message1 = Message(
159
+ role="assistant",
160
+ parts=[TextPart(text="I'm fine, thank you.")],
161
+ cal_loss=True,
162
+ )
163
+ conversation = Conversation([message0, message1])
164
+ tokenizer = PreTrainedTokenizerFast.from_pretrained("checkpoints/agent-0.6b-debug")
165
+
166
+ # Test with enhanced visualization from ContentSequence
167
+ print("Basic visualization:")
168
+ conversation.visualize(tokenizer)
169
+
170
+ print("\nWith merged semantic tokens:")
171
+ conversation.visualize(tokenizer, merge_semantic_tokens=True)
172
+
173
+ print("\nWithout colors:")
174
+ conversation.visualize(tokenizer, use_color=False)
vendor/fish-speech/fish_speech/datasets/concat_repeat.py ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import bisect
2
+ import random
3
+ from typing import Iterable
4
+
5
+ from torch.utils.data import Dataset, IterableDataset
6
+
7
+
8
+ class ConcatRepeatDataset(Dataset):
9
+ datasets: list[Dataset]
10
+ cumulative_sizes: list[int]
11
+ repeats: list[int]
12
+
13
+ @staticmethod
14
+ def cumsum(sequence, repeats):
15
+ r, s = [], 0
16
+ for dataset, repeat in zip(sequence, repeats):
17
+ l = len(dataset) * repeat
18
+ r.append(l + s)
19
+ s += l
20
+ return r
21
+
22
+ def __init__(self, datasets: Iterable[Dataset], repeats: list[int]):
23
+ super().__init__()
24
+
25
+ self.datasets = list(datasets)
26
+ self.repeats = repeats
27
+
28
+ assert len(self.datasets) > 0, "datasets should not be an empty iterable"
29
+ assert len(self.datasets) == len(
30
+ repeats
31
+ ), "datasets and repeats should have the same length"
32
+
33
+ for d in self.datasets:
34
+ assert not isinstance(
35
+ d, IterableDataset
36
+ ), "ConcatRepeatDataset does not support IterableDataset"
37
+
38
+ self.cumulative_sizes = self.cumsum(self.datasets, self.repeats)
39
+
40
+ def __len__(self):
41
+ return self.cumulative_sizes[-1]
42
+
43
+ def __getitem__(self, idx):
44
+ dataset_idx = bisect.bisect_right(self.cumulative_sizes, idx)
45
+
46
+ if dataset_idx == 0:
47
+ sample_idx = idx
48
+ else:
49
+ sample_idx = idx - self.cumulative_sizes[dataset_idx - 1]
50
+
51
+ dataset = self.datasets[dataset_idx]
52
+
53
+ return dataset[sample_idx % len(dataset)]
vendor/fish-speech/fish_speech/datasets/protos/text-data.proto ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ syntax = "proto3";
2
+
3
+ package text_data;
4
+
5
+ message Semantics {
6
+ repeated uint32 values = 1;
7
+ }
8
+
9
+ message Sentence {
10
+ repeated string texts = 1;
11
+ repeated Semantics semantics = 3;
12
+ }
13
+
14
+ message TextData {
15
+ string source = 1;
16
+ string name = 2;
17
+ repeated Sentence sentences = 4;
18
+ }
19
+
20
+ message SampledData {
21
+ string source = 1;
22
+ string name = 2;
23
+ repeated Sentence samples = 3;
24
+ }
vendor/fish-speech/fish_speech/datasets/protos/text_data_pb2.py ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # source: text-data.proto
4
+ # Protobuf Python Version: 4.25.1
5
+ """Generated protocol buffer code."""
6
+
7
+ from google.protobuf import descriptor as _descriptor
8
+ from google.protobuf import descriptor_pool as _descriptor_pool
9
+ from google.protobuf import symbol_database as _symbol_database
10
+ from google.protobuf.internal import builder as _builder
11
+
12
+ # @@protoc_insertion_point(imports)
13
+
14
+ _sym_db = _symbol_database.Default()
15
+
16
+
17
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(
18
+ b'\n\x0ftext-data.proto\x12\ttext_data"\x1b\n\tSemantics\x12\x0e\n\x06values\x18\x01 \x03(\r"B\n\x08Sentence\x12\r\n\x05texts\x18\x01 \x03(\t\x12\'\n\tsemantics\x18\x03 \x03(\x0b\x32\x14.text_data.Semantics"P\n\x08TextData\x12\x0e\n\x06source\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12&\n\tsentences\x18\x04 \x03(\x0b\x32\x13.text_data.Sentence"Q\n\x0bSampledData\x12\x0e\n\x06source\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12$\n\x07samples\x18\x03 \x03(\x0b\x32\x13.text_data.Sentenceb\x06proto3'
19
+ )
20
+
21
+ _globals = globals()
22
+ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
23
+ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "text_data_pb2", _globals)
24
+ if _descriptor._USE_C_DESCRIPTORS == False:
25
+ DESCRIPTOR._options = None
26
+ _globals["_SEMANTICS"]._serialized_start = 30
27
+ _globals["_SEMANTICS"]._serialized_end = 57
28
+ _globals["_SENTENCE"]._serialized_start = 59
29
+ _globals["_SENTENCE"]._serialized_end = 125
30
+ _globals["_TEXTDATA"]._serialized_start = 127
31
+ _globals["_TEXTDATA"]._serialized_end = 207
32
+ _globals["_SAMPLEDDATA"]._serialized_start = 209
33
+ _globals["_SAMPLEDDATA"]._serialized_end = 290
34
+ # @@protoc_insertion_point(module_scope)
vendor/fish-speech/fish_speech/datasets/protos/text_data_stream.py ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import struct
2
+
3
+ from .text_data_pb2 import TextData
4
+
5
+
6
+ def read_pb_stream(f):
7
+ while True:
8
+ buf = f.read(4)
9
+ if len(buf) == 0:
10
+ break
11
+ size = struct.unpack("I", buf)[0]
12
+ buf = f.read(size)
13
+ text_data = TextData()
14
+ text_data.ParseFromString(buf)
15
+ yield text_data
16
+
17
+
18
+ def write_pb_stream(f, text_data):
19
+ buf = text_data.SerializeToString()
20
+ f.write(struct.pack("I", len(buf)))
21
+ f.write(buf)
22
+
23
+
24
+ def pack_pb_stream(text_data):
25
+ buf = text_data.SerializeToString()
26
+ return struct.pack("I", len(buf)) + buf
27
+
28
+
29
+ def split_pb_stream(f):
30
+ while True:
31
+ head = f.read(4)
32
+ if len(head) == 0:
33
+ break
34
+ size = struct.unpack("I", head)[0]
35
+ buf = f.read(size)
36
+ yield head + buf
vendor/fish-speech/fish_speech/datasets/semantic.py ADDED
@@ -0,0 +1,627 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import random
2
+ from dataclasses import dataclass
3
+ from itertools import chain
4
+ from pathlib import Path
5
+ from random import Random
6
+ from typing import Optional, Union
7
+
8
+ import numpy as np
9
+ import pyarrow.parquet as pq
10
+ import torch
11
+ import torch.nn.functional as F
12
+ from datasets.download.streaming_download_manager import xopen
13
+ from huggingface_hub import HfApi
14
+ from lightning import LightningDataModule
15
+ from torch.distributed import get_rank, get_world_size, is_initialized
16
+ from torch.utils.data import DataLoader, Dataset, IterableDataset, get_worker_info
17
+
18
+ from fish_speech.content_sequence import ContentSequence, TextPart, VQPart
19
+
20
+ CODEBOOK_PAD_TOKEN_ID = 0
21
+
22
+ from fish_speech.datasets.protos.text_data_pb2 import SampledData
23
+ from fish_speech.datasets.protos.text_data_stream import read_pb_stream
24
+ from fish_speech.text.clean import clean_text
25
+ from fish_speech.tokenizer import FishTokenizer
26
+ from fish_speech.utils import RankedLogger
27
+ from fish_speech.utils.braceexpand import braceexpand
28
+
29
+ log = RankedLogger(__name__, rank_zero_only=True)
30
+
31
+
32
+ def split_by_rank_worker(files):
33
+ # We need to know the total number of devices
34
+ # to split the data properly
35
+
36
+ total_devices = 1
37
+ if is_initialized():
38
+ total_devices = get_world_size()
39
+
40
+ worker_info = get_worker_info()
41
+ if worker_info is not None:
42
+ total_devices *= worker_info.num_workers
43
+
44
+ if len(files) < total_devices:
45
+ # Repeat the files N times to match the number of devices
46
+ files = files * (total_devices // len(files) + 1)
47
+
48
+ # DDP
49
+ if is_initialized():
50
+ files = files[get_rank() :: get_world_size()]
51
+
52
+ # Split by worker
53
+ if worker_info is not None:
54
+ files = files[worker_info.id :: worker_info.num_workers]
55
+
56
+ return files
57
+
58
+
59
+ class AutoTextSemanticInstructionIterableDataset(IterableDataset):
60
+ """
61
+ Auto Augment Dataset by Speaker
62
+
63
+ 1. Random concatenate multiple sentences from the same speaker to form a longer sentence
64
+ 2. Automatically normalize the text
65
+
66
+ For interactive mode, we use the following format (multiple sequences):
67
+ <s> [INST] [SPK: speaker] text [/INST] ... [INST] text [/INST] </s>
68
+
69
+ For non-interactive mode, we use the following format (one long sequence):
70
+ <s> [INST] text [/INST] ... </s>
71
+ """
72
+
73
+ def __init__(
74
+ self,
75
+ proto_files: list[str],
76
+ seed: int = 42,
77
+ interactive_prob: float = 0.5,
78
+ max_length: int = 1024,
79
+ tokenizer: FishTokenizer = None,
80
+ use_speaker: bool | float = True,
81
+ causal: bool = True,
82
+ num_codebooks: Optional[int] = None,
83
+ skip_text_prob: float = 0.0,
84
+ ):
85
+ """
86
+ Args:
87
+ proto_files: proto buf files if using local data
88
+ seed: random seed
89
+ interactive_prob: probability to use interactive mode
90
+ max_length: max length of the text
91
+ tokenizer: tokenizer
92
+ use_speaker: include speaker information in the prompt
93
+ causal: use causal sampling when using local data, disable will lead to random sampling
94
+ num_codebooks: number of codebooks, if None, it will be automatically detected
95
+ skip_text_prob: probability to skip the text (audio only), this only applies to interactive mode
96
+ """
97
+
98
+ super().__init__()
99
+
100
+ assert 0 <= interactive_prob <= 1, "interactive_prob must be in [0, 1]"
101
+
102
+ self.seed = seed
103
+ self.max_length = max_length
104
+ self.tokenizer = tokenizer
105
+ self.interactive_prob = interactive_prob
106
+ self.use_speaker = use_speaker
107
+ self.proto_files = proto_files
108
+ self.causal = causal
109
+ self.num_codebooks = num_codebooks
110
+ self.skip_text_prob = skip_text_prob
111
+
112
+ self.groups = None
113
+
114
+ def __iter__(self):
115
+ while True:
116
+ yield self.augment()
117
+
118
+ def init_mock_data_server(self):
119
+ if self.groups is not None:
120
+ return
121
+
122
+ # Expand the proto files
123
+ expanded_proto_files = []
124
+ for filename in self.proto_files:
125
+ for i in braceexpand(filename):
126
+ i = Path(i)
127
+ if i.is_file():
128
+ expanded_proto_files.append(i)
129
+ elif i.is_dir():
130
+ expanded_proto_files.extend(i.rglob("*.proto"))
131
+ expanded_proto_files.extend(i.rglob("*.protos"))
132
+ else:
133
+ raise ValueError(f"{i} is not a file or directory")
134
+
135
+ expanded_proto_files = sorted(expanded_proto_files)
136
+ Random(self.seed).shuffle(expanded_proto_files)
137
+
138
+ self.groups = []
139
+ shard_proto_files = split_by_rank_worker(expanded_proto_files)
140
+ log.info(
141
+ f"Reading {len(shard_proto_files)} / {len(expanded_proto_files)} files"
142
+ )
143
+
144
+ count = 0
145
+ for filename in shard_proto_files:
146
+ with open(filename, "rb") as f:
147
+ for text_data in read_pb_stream(f):
148
+ self.groups.append(text_data)
149
+ count += 1
150
+
151
+ log.info(f"Read total {count} groups of data")
152
+
153
+ # Shuffle the lines
154
+ Random(self.seed).shuffle(self.groups)
155
+ self.group_weights = [len(i.sentences) for i in self.groups]
156
+
157
+ def sample_data(self):
158
+ if self.groups is None:
159
+ self.init_mock_data_server()
160
+
161
+ # Shuffle unique lines, estimate that each sample is at least 20 tokens
162
+ num_samples = self.max_length // 20
163
+
164
+ # choice group based on their number of samples
165
+ group = random.choices(self.groups, weights=self.group_weights, k=1)[0]
166
+
167
+ if self.causal:
168
+ # Sample in order
169
+ if num_samples >= len(group.sentences):
170
+ samples = group.sentences
171
+ else:
172
+ begin = random.randint(0, len(group.sentences) - num_samples)
173
+ samples = group.sentences[begin : begin + num_samples]
174
+ else:
175
+ samples = random.choices(
176
+ group.sentences, k=min(num_samples, len(group.sentences))
177
+ )
178
+
179
+ return SampledData(
180
+ source=group.source,
181
+ name=group.name,
182
+ samples=samples,
183
+ )
184
+
185
+ def pack_sentences(
186
+ self,
187
+ sentences: list[str],
188
+ semantics: list,
189
+ # speaker: Optional[str] = None, # speaker is now handled by tokens
190
+ skip_text: bool = False,
191
+ ):
192
+
193
+ seq = ContentSequence()
194
+
195
+ seq.append(TextPart(text="Speak out the provided text."))
196
+
197
+ # User's turn
198
+ cated_sentences = " ".join(sentences)
199
+ if skip_text:
200
+ cated_sentences = "<|skip_text|>"
201
+
202
+ seq.append(
203
+ TextPart(text=f"<|speaker:user|> {cated_sentences}"),
204
+ add_end=True,
205
+ )
206
+
207
+ # Assistant's turn
208
+ vq_codes = [x.values for x in semantics[0]]
209
+ vq_codes_tensor = torch.tensor(vq_codes).to(torch.int32)
210
+
211
+ # 将 cal_loss=True 直接关联到 VQPart 上,这比之前更精确
212
+ vq_part = VQPart(codes=vq_codes_tensor, cal_loss=True)
213
+
214
+ # 将多个 parts 一起添加,最后也加上 <|im_end|>
215
+ seq.append(
216
+ [TextPart(text="<|speaker:assistant|> <|voice|>"), vq_part],
217
+ add_end=True,
218
+ )
219
+
220
+ encoded = seq.encode(
221
+ tokenizer=self.tokenizer,
222
+ )
223
+
224
+ num_codebooks = (
225
+ len(semantics[0]) if self.num_codebooks is None else self.num_codebooks
226
+ )
227
+
228
+ tokens_raw = encoded.tokens
229
+ tokens = torch.zeros((num_codebooks + 1, len(tokens_raw)), dtype=torch.int)
230
+ tokens[0] = tokens_raw
231
+
232
+ vq_parts = encoded.vq_parts
233
+ vq_parts = [part.to(tokens.device) for part in vq_parts]
234
+ vq_parts = torch.cat(vq_parts, dim=1)
235
+ tokens[1:, encoded.vq_mask_tokens] = vq_parts
236
+
237
+ labels_raw = encoded.labels
238
+ labels = torch.full((num_codebooks + 1, len(labels_raw)), -100, dtype=torch.int)
239
+ labels[0, :] = labels_raw
240
+ labels[1:, encoded.vq_mask_labels] = vq_parts
241
+ labels[1:, -1:] = CODEBOOK_PAD_TOKEN_ID
242
+
243
+ tokens = tokens.long()
244
+ labels = labels.long()
245
+
246
+ # Verify the padding is correct, and the last token is eos
247
+ assert (tokens[1:, ~(encoded.vq_mask_tokens)] == CODEBOOK_PAD_TOKEN_ID).all()
248
+ assert (labels[1:, -1:] == CODEBOOK_PAD_TOKEN_ID).all()
249
+
250
+ return tokens, labels
251
+
252
+ def augment(self):
253
+ response = self.sample_data()
254
+ if len(response.samples) == 0:
255
+ # Invalid group
256
+ return None
257
+
258
+ samples = list(response.samples)
259
+ all_tokens, all_labels = [], []
260
+
261
+ while len(samples) > 0:
262
+ sentence = samples.pop(0)
263
+ text = clean_text(random.choice(sentence.texts))
264
+
265
+ tokens, labels = self.pack_sentences(
266
+ sentences=[text],
267
+ semantics=[sentence.semantics],
268
+ # speaker=response.name if use_speaker else None,
269
+ skip_text=random.random() < self.skip_text_prob,
270
+ )
271
+
272
+ all_tokens.append(tokens)
273
+ all_labels.append(labels)
274
+
275
+ tokens = torch.cat(all_tokens, dim=1)
276
+ labels = torch.cat(all_labels, dim=1)
277
+
278
+ # Verify that the length is correct
279
+ assert tokens.size(1) == labels.size(1), f"{tokens.size(1)} != {labels.size(1)}"
280
+
281
+ data = {"tokens": tokens, "labels": labels}
282
+
283
+ return data
284
+
285
+
286
+ class AutoTextSemanticInstructionDataset(Dataset):
287
+ """
288
+ Auto Augment Dataset by Speaker
289
+
290
+ 1. Random concatenate multiple sentences from the same speaker to form a longer sentence
291
+ 2. Automatically normalize the text
292
+
293
+ For interactive mode, we use the following format (multiple sequences):
294
+ <s> [INST] [SPK: speaker] text [/INST] ... [INST] text [/INST] </s>
295
+
296
+ For non-interactive mode, we use the following format (one long sequence):
297
+ <s> [INST] text [/INST] ... </s>
298
+ """
299
+
300
+ def __init__(
301
+ self,
302
+ proto_files: list[str],
303
+ seed: int = 42,
304
+ interactive_prob: float = 0.5,
305
+ max_length: int = 1024,
306
+ tokenizer: FishTokenizer = None,
307
+ use_speaker: bool | float = True,
308
+ causal: bool = True,
309
+ num_codebooks: Optional[int] = None,
310
+ skip_text_prob: float = 0.0,
311
+ ):
312
+ """
313
+ Args:
314
+ proto_files: proto buf files if using local data
315
+ seed: random seed
316
+ interactive_prob: probability to use interactive mode
317
+ max_length: max length of the text
318
+ tokenizer: tokenizer
319
+ use_speaker: include speaker information in the prompt
320
+ causal: use causal sampling when using local data, disable will lead to random sampling
321
+ num_codebooks: number of codebooks, if None, it will be automatically detected
322
+ skip_text_prob: probability to skip the text (audio only), this only applies to interactive mode
323
+ """
324
+ super().__init__()
325
+
326
+ assert 0 <= interactive_prob <= 1, "interactive_prob must be in [0, 1]"
327
+
328
+ self.seed = seed
329
+ self.max_length = max_length
330
+ self.tokenizer = tokenizer
331
+ self.interactive_prob = interactive_prob
332
+ self.use_speaker = use_speaker
333
+ self.proto_files = proto_files
334
+ self.causal = causal
335
+ self.num_codebooks = num_codebooks
336
+ self.skip_text_prob = skip_text_prob
337
+
338
+ self.data = []
339
+ self._init_data()
340
+
341
+ def _init_data(self):
342
+ expanded_proto_files = []
343
+ for filename in self.proto_files:
344
+ for i in braceexpand(filename):
345
+ i = Path(i)
346
+ if i.is_file():
347
+ expanded_proto_files.append(i)
348
+ elif i.is_dir():
349
+ expanded_proto_files.extend(i.rglob("*.proto"))
350
+ expanded_proto_files.extend(i.rglob("*.protos"))
351
+ else:
352
+ raise ValueError(f"{i} is not a file or directory")
353
+
354
+ expanded_proto_files = sorted(expanded_proto_files)
355
+ Random(self.seed).shuffle(expanded_proto_files)
356
+
357
+ groups = []
358
+ shard_proto_files = split_by_rank_worker(expanded_proto_files)
359
+ log.info(
360
+ f"Reading {len(shard_proto_files)} / {len(expanded_proto_files)} files"
361
+ )
362
+
363
+ count = 0
364
+ for filename in shard_proto_files:
365
+ with open(filename, "rb") as f:
366
+ for text_data in read_pb_stream(f):
367
+ groups.append(text_data)
368
+ count += 1
369
+
370
+ log.info(f"Read total {count} groups of data")
371
+
372
+ for group in groups:
373
+ if len(group.sentences) == 0:
374
+ continue
375
+
376
+ samples = list(group.sentences)
377
+ for sentence in samples:
378
+ text = clean_text(random.choice(sentence.texts))
379
+
380
+ tokens, labels = self.pack_sentences(
381
+ sentences=[text],
382
+ semantics=[sentence.semantics],
383
+ skip_text=random.random() < self.skip_text_prob,
384
+ )
385
+
386
+ self.data.append({"tokens": tokens, "labels": labels})
387
+
388
+ random.Random(self.seed).shuffle(self.data)
389
+
390
+ def __len__(self):
391
+ return len(self.data)
392
+
393
+ def __getitem__(self, idx):
394
+ return self.data[idx]
395
+
396
+ def pack_sentences(
397
+ self,
398
+ sentences: list[str],
399
+ semantics: list,
400
+ skip_text: bool = False,
401
+ ):
402
+ messages = [
403
+ Message(
404
+ role="system",
405
+ parts=[TextPart(text="Speak out the provided text.")],
406
+ )
407
+ ]
408
+
409
+ cated_sentences = " ".join(sentences)
410
+ if skip_text:
411
+ cated_sentences = "<|skip_text|>"
412
+
413
+ messages.append(
414
+ Message(
415
+ role="user",
416
+ parts=[TextPart(text=cated_sentences)],
417
+ )
418
+ )
419
+
420
+ vq_codes = [x.values for x in semantics[0]]
421
+ vq_codes_tensor = torch.tensor(vq_codes).to(torch.int32)
422
+ vqpart = VQPart(codes=vq_codes_tensor)
423
+ messages.append(
424
+ Message(
425
+ role="assistant",
426
+ parts=[TextPart(text="<|voice|>"), vqpart],
427
+ cal_loss=True,
428
+ )
429
+ )
430
+
431
+ num_codebooks = (
432
+ len(semantics[0]) if self.num_codebooks is None else self.num_codebooks
433
+ )
434
+
435
+ conversation = Conversation(messages=messages)
436
+ encoded = conversation.encode(
437
+ tokenizer=self.tokenizer,
438
+ )
439
+
440
+ tokens_raw = encoded.tokens
441
+ tokens = torch.zeros((num_codebooks + 1, len(tokens_raw)), dtype=torch.int)
442
+ tokens[0] = tokens_raw
443
+
444
+ vq_parts = encoded.vq_parts
445
+ vq_parts = [part.to(tokens.device) for part in vq_parts]
446
+ vq_parts = torch.cat(vq_parts, dim=1)
447
+ tokens[1:, encoded.vq_mask_tokens] = vq_parts
448
+
449
+ labels_raw = encoded.labels
450
+ labels = torch.full((num_codebooks + 1, len(labels_raw)), -100, dtype=torch.int)
451
+ labels[0, :] = labels_raw
452
+ labels[1:, encoded.vq_mask_labels] = vq_parts
453
+ labels[1:, -1:] = CODEBOOK_PAD_TOKEN_ID
454
+
455
+ tokens = tokens.long()
456
+ labels = labels.long()
457
+
458
+ assert (tokens[1:, ~(encoded.vq_mask_tokens)] == CODEBOOK_PAD_TOKEN_ID).all()
459
+ assert (labels[1:, -1:] == CODEBOOK_PAD_TOKEN_ID).all()
460
+
461
+ return tokens, labels
462
+
463
+
464
+ class InterleaveDataset(IterableDataset):
465
+ def __init__(
466
+ self,
467
+ datasets: list[IterableDataset],
468
+ probabilities: list[float],
469
+ seed: int = 42,
470
+ ):
471
+ super().__init__()
472
+
473
+ self.datasets = datasets
474
+ self.probabilities = probabilities
475
+ self.seed = seed
476
+
477
+ def __iter__(self):
478
+ rng = np.random.default_rng(self.seed)
479
+ dataset_iterators = [iter(dataset) for dataset in self.datasets]
480
+
481
+ while True:
482
+ # Random choice one
483
+ dataset_idx = rng.choice(len(self.datasets), p=self.probabilities)
484
+ dataset_iterator = dataset_iterators[dataset_idx]
485
+
486
+ try:
487
+ yield next(dataset_iterator)
488
+ except StopIteration:
489
+ # Exhausted, create a new iterator
490
+ dataset_iterators[dataset_idx] = iter(self.datasets[dataset_idx])
491
+ yield next(dataset_iterators[dataset_idx])
492
+
493
+
494
+ @dataclass
495
+ class TextDataCollator:
496
+ tokenizer: FishTokenizer
497
+ max_length: int = 1024
498
+
499
+ def __call__(self, examples):
500
+ if "negative_tokens" in examples:
501
+ positive_examples = []
502
+ negative_examples = []
503
+
504
+ for i in examples:
505
+ positive_examples.append(
506
+ {
507
+ "tokens": i["tokens"],
508
+ "labels": i["labels"],
509
+ }
510
+ )
511
+ negative_examples.append(
512
+ {
513
+ "tokens": i["negative_tokens"],
514
+ "labels": i["negative_labels"],
515
+ }
516
+ )
517
+
518
+ examples = positive_examples + negative_examples
519
+
520
+ return self.batchify(examples)
521
+
522
+ def batchify(self, examples, tokens_key="tokens", labels_key="labels"):
523
+ tokens, attention_masks, labels = [], [], []
524
+
525
+ # Calculate the max length
526
+ max_tokens_length = 0
527
+ for example in examples:
528
+ max_tokens_length = max(max_tokens_length, example[tokens_key].size(1))
529
+ max_tokens_length = min(max_tokens_length, self.max_length)
530
+
531
+ for example in examples:
532
+ _tokens = example[tokens_key][:, :max_tokens_length]
533
+ _labels = example[labels_key][:, :max_tokens_length]
534
+ _attention_mask = torch.ones((max_tokens_length,), dtype=torch.bool)
535
+ tokens_length = _tokens.size(1)
536
+ _attention_mask[:tokens_length] = False
537
+
538
+ assert tokens_length == _labels.size(
539
+ 1
540
+ ), f"{tokens_length} != {_labels.size(1)}"
541
+
542
+ if tokens_length < max_tokens_length:
543
+ _tokens = F.pad(
544
+ _tokens,
545
+ (0, max_tokens_length - tokens_length),
546
+ value=self.tokenizer.get_token_id("<|end_of_text|>"),
547
+ )
548
+ _tokens[1:, tokens_length:] = CODEBOOK_PAD_TOKEN_ID
549
+ _labels = F.pad(
550
+ _labels, (0, max_tokens_length - _labels.size(1)), value=-100
551
+ )
552
+
553
+ tokens.append(_tokens)
554
+ attention_masks.append(_attention_mask)
555
+ labels.append(_labels)
556
+
557
+ tokens = torch.stack(tokens, dim=0)
558
+ attention_masks = torch.stack(attention_masks, dim=0)
559
+ labels = torch.stack(labels, dim=0)
560
+
561
+ return {
562
+ "inputs": tokens,
563
+ "attention_masks": attention_masks,
564
+ "labels": labels,
565
+ }
566
+
567
+
568
+ class SemanticDataModule(LightningDataModule):
569
+ def __init__(
570
+ self,
571
+ train_dataset: Union[
572
+ AutoTextSemanticInstructionDataset,
573
+ AutoTextSemanticInstructionIterableDataset,
574
+ InterleaveDataset,
575
+ ],
576
+ val_dataset: Union[
577
+ AutoTextSemanticInstructionDataset,
578
+ AutoTextSemanticInstructionIterableDataset,
579
+ InterleaveDataset,
580
+ ],
581
+ batch_size: int = 32,
582
+ tokenizer: FishTokenizer = None,
583
+ max_length: int = 1024,
584
+ num_workers: int = 4,
585
+ ):
586
+ super().__init__()
587
+
588
+ self.train_dataset = train_dataset
589
+ self.val_dataset = val_dataset
590
+ self.batch_size = batch_size
591
+ self.tokenizer = tokenizer
592
+ self.max_length = max_length
593
+ self.num_workers = num_workers
594
+
595
+ def train_dataloader(self):
596
+ return DataLoader(
597
+ self.train_dataset,
598
+ batch_size=self.batch_size,
599
+ collate_fn=TextDataCollator(self.tokenizer, self.max_length),
600
+ num_workers=self.num_workers,
601
+ persistent_workers=True,
602
+ )
603
+
604
+ def val_dataloader(self):
605
+ return DataLoader(
606
+ self.val_dataset,
607
+ batch_size=self.batch_size,
608
+ collate_fn=TextDataCollator(self.tokenizer, self.max_length),
609
+ num_workers=self.num_workers,
610
+ persistent_workers=True,
611
+ )
612
+
613
+
614
+ if __name__ == "__main__":
615
+ from tqdm import tqdm
616
+
617
+ ds = AutoTextSemanticInstructionDataset(
618
+ ["data/protos"],
619
+ tokenizer=FishTokenizer("checkpoints/fish-speech-1.5/tokenizer.tiktoken"),
620
+ use_speaker=False,
621
+ interactive_prob=1.0,
622
+ skip_text_prob=0.5,
623
+ )
624
+
625
+ for i in range(100):
626
+ # Please uncomment line 235 to visualize the tokenized message
627
+ print(ds[i])
vendor/fish-speech/fish_speech/datasets/vqgan.py ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from dataclasses import dataclass
2
+ from pathlib import Path
3
+ from typing import Optional
4
+
5
+ import librosa
6
+ import numpy as np
7
+ import torch
8
+ from lightning import LightningDataModule
9
+ from torch.utils.data import DataLoader, Dataset
10
+
11
+ from fish_speech.utils import RankedLogger
12
+
13
+ logger = RankedLogger(__name__, rank_zero_only=False)
14
+
15
+
16
+ class VQGANDataset(Dataset):
17
+ def __init__(
18
+ self,
19
+ filelist: str,
20
+ sample_rate: int = 32000,
21
+ hop_length: int = 640,
22
+ slice_frames: Optional[int] = None,
23
+ ):
24
+ super().__init__()
25
+
26
+ filelist = Path(filelist)
27
+ root = filelist.parent
28
+
29
+ self.files = [
30
+ root / line.strip()
31
+ for line in filelist.read_text(encoding="utf-8").splitlines()
32
+ if line.strip()
33
+ ]
34
+ self.sample_rate = sample_rate
35
+ self.hop_length = hop_length
36
+ self.slice_frames = slice_frames
37
+
38
+ def __len__(self):
39
+ return len(self.files)
40
+
41
+ def get_item(self, idx):
42
+ file = self.files[idx]
43
+
44
+ audio, _ = librosa.load(file, sr=self.sample_rate, mono=True)
45
+
46
+ # Slice audio and features
47
+ if (
48
+ self.slice_frames is not None
49
+ and audio.shape[0] > self.slice_frames * self.hop_length
50
+ ):
51
+ start = np.random.randint(
52
+ 0, audio.shape[0] - self.slice_frames * self.hop_length
53
+ )
54
+ audio = audio[start : start + self.slice_frames * self.hop_length]
55
+
56
+ if len(audio) == 0:
57
+ return None
58
+
59
+ max_value = np.abs(audio).max()
60
+ if max_value > 1.0:
61
+ audio = audio / max_value
62
+
63
+ return {
64
+ "audio": torch.from_numpy(audio),
65
+ }
66
+
67
+ def __getitem__(self, idx):
68
+ try:
69
+ return self.get_item(idx)
70
+ except Exception as e:
71
+ import traceback
72
+
73
+ traceback.print_exc()
74
+ logger.error(f"Error loading {self.files[idx]}: {e}")
75
+ return None
76
+
77
+
78
+ @dataclass
79
+ class VQGANCollator:
80
+ def __call__(self, batch):
81
+ batch = [x for x in batch if x is not None]
82
+
83
+ audio_lengths = torch.tensor([len(x["audio"]) for x in batch])
84
+ audio_maxlen = audio_lengths.max()
85
+
86
+ # Rounds up to nearest multiple of 2 (audio_lengths)
87
+ audios = []
88
+ for x in batch:
89
+ audios.append(
90
+ torch.nn.functional.pad(x["audio"], (0, audio_maxlen - len(x["audio"])))
91
+ )
92
+
93
+ return {
94
+ "audios": torch.stack(audios),
95
+ "audio_lengths": audio_lengths,
96
+ }
97
+
98
+
99
+ class VQGANDataModule(LightningDataModule):
100
+ def __init__(
101
+ self,
102
+ train_dataset: VQGANDataset,
103
+ val_dataset: VQGANDataset,
104
+ batch_size: int = 32,
105
+ num_workers: int = 4,
106
+ val_batch_size: Optional[int] = None,
107
+ ):
108
+ super().__init__()
109
+
110
+ self.train_dataset = train_dataset
111
+ self.val_dataset = val_dataset
112
+ self.batch_size = batch_size
113
+ self.val_batch_size = val_batch_size or batch_size
114
+ self.num_workers = num_workers
115
+
116
+ def train_dataloader(self):
117
+ return DataLoader(
118
+ self.train_dataset,
119
+ batch_size=self.batch_size,
120
+ collate_fn=VQGANCollator(),
121
+ num_workers=self.num_workers,
122
+ shuffle=True,
123
+ persistent_workers=True,
124
+ )
125
+
126
+ def val_dataloader(self):
127
+ return DataLoader(
128
+ self.val_dataset,
129
+ batch_size=self.val_batch_size,
130
+ collate_fn=VQGANCollator(),
131
+ num_workers=self.num_workers,
132
+ persistent_workers=True,
133
+ )
134
+
135
+
136
+ if __name__ == "__main__":
137
+ dataset = VQGANDataset("data/LibriTTS_R/vq_train_filelist.txt")
138
+ dataloader = DataLoader(
139
+ dataset, batch_size=4, shuffle=False, collate_fn=VQGANCollator()
140
+ )
141
+
142
+ for batch in dataloader:
143
+ print(batch["audios"].shape)
144
+ print(batch["audio_lengths"])
145
+ break
vendor/fish-speech/fish_speech/i18n/README.md ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## i18n Folder Attribution
2
+
3
+ The `i18n` folder within the `fish_speech` directory contains files initially sourced from the RVC project. In compliance with the MIT license under which these files were released, we acknowledge the original authors and sources below:
4
+
5
+ ### fish_speech/i18n/core.py
6
+
7
+ **Related code from RVC:**
8
+ [https://github.com/RVC-Project/Retrieval-based-Voice-Conversion-WebUI/blob/83d6a64e675d9bbd6e92ee450c5f807ed2bb54d8/i18n/i18n.py](https://github.com/RVC-Project/Retrieval-based-Voice-Conversion-WebUI/blob/83d6a64e675d9bbd6e92ee450c5f807ed2bb54d8/i18n/i18n.py)
9
+
10
+ **Initial commit:**
11
+ add localization(添加本地化) [RVC-Project/Retrieval-based-Voice-Conversion-WebUI#35](https://github.com/RVC-Project/Retrieval-based-Voice-Conversion-WebUI/pull/35)
12
+
13
+ **Initial author:**
14
+ [@L4Ph](https://github.com/L4Ph)
15
+
16
+ ### fish_speech/i18n/scan.py
17
+
18
+ **Related code from RVC:**
19
+ [https://github.com/RVC-Project/Retrieval-based-Voice-Conversion-WebUI/blob/83d6a64e675d9bbd6e92ee450c5f807ed2bb54d8/i18n/scan_i18n.py](https://github.com/RVC-Project/Retrieval-based-Voice-Conversion-WebUI/blob/83d6a64e675d9bbd6e92ee450c5f807ed2bb54d8/i18n/scan_i18n.py)
20
+
21
+ **Initial commit:**
22
+ File for detecting i18n missing keys [RVC-Project/Retrieval-based-Voice-Conversion-WebUI#1058](https://github.com/RVC-Project/Retrieval-based-Voice-Conversion-WebUI/pull/1058)
23
+
24
+ **Initial author:**
25
+ [@towzeur](https://github.com/towzeur)
26
+
27
+ We appreciate the contributions of the RVC project and its authors.
vendor/fish-speech/fish_speech/i18n/__init__.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ from .core import i18n
2
+
3
+ __all__ = ["i18n"]
vendor/fish-speech/fish_speech/i18n/core.py ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import locale
3
+ from pathlib import Path
4
+
5
+ I18N_FILE_PATH = Path(__file__).parent / "locale"
6
+ DEFAULT_LANGUAGE = "en_US"
7
+
8
+
9
+ def load_language_list(language):
10
+ with open(I18N_FILE_PATH / f"{language}.json", "r", encoding="utf-8") as f:
11
+ language_list = json.load(f)
12
+
13
+ return language_list
14
+
15
+
16
+ class I18nAuto:
17
+ def __init__(self):
18
+ i18n_file = Path(".locale")
19
+
20
+ if i18n_file.exists():
21
+ with open(i18n_file, "r", encoding="utf-8") as f:
22
+ language = f.read().strip()
23
+ else:
24
+ # getlocale can't identify the system's language ((None, None))
25
+ language = locale.getdefaultlocale()[0]
26
+
27
+ if (I18N_FILE_PATH / f"{language}.json").exists() is False:
28
+ language = DEFAULT_LANGUAGE
29
+
30
+ self.language = language
31
+ self.language_map = load_language_list(language)
32
+
33
+ def __call__(self, key):
34
+ return self.language_map.get(key, key)
35
+
36
+ def __repr__(self):
37
+ return "Use Language: " + self.language
38
+
39
+
40
+ i18n = I18nAuto()
vendor/fish-speech/fish_speech/i18n/locale/ar_SA.json ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "16-mixed is recommended for 10+ series GPU": "يُنصح بـ 16-mixed لبطاقات الرسوميات من سلسلة 10+ وما فوق",
3
+ "5 to 10 seconds of reference audio, useful for specifying speaker.": "من 5 إلى 10 ثواني من الصوت المرجعي، مفيد لتحديد المتحدث.",
4
+ "A text-to-speech model based on VQ-GAN and Llama developed by [Fish Audio](https://fish.audio).": "نموذج Text-to-Speech مبني على VQ-GAN و Llama، طوّرته [Fish Audio](https://fish.audio).",
5
+ "Accumulate Gradient Batches": "تراكم دفعات الـ Gradient",
6
+ "Add to Processing Area": "أضف إلى منطقة المعالجة",
7
+ "Added path successfully!": "تمت إضافة المسار بنجاح!",
8
+ "Advanced Config": "إعدادات متقدمة",
9
+ "Base LLAMA Model": "نموذج LLAMA الأساسي",
10
+ "Batch Inference": "Batch Inference",
11
+ "Batch Size": "حجم الـ Batch",
12
+ "Changing with the Model Path": "يتغير مع مسار النموذج",
13
+ "Chinese": "الصينية",
14
+ "Compile Model": "تجميع النموذج",
15
+ "Compile the model can significantly reduce the inference time, but will increase cold start time": "تجميع النموذج يقلل وقت الـ Inference بشكل ملحوظ، لكنه يزيد من وقت بدء التشغيل",
16
+ "Copy": "نسخ",
17
+ "Data Preprocessing": "معالجة البيانات المسبقة",
18
+ "Data Preprocessing Path": "مسار معالجة البيانات",
19
+ "Data Source": "مصدر البيانات",
20
+ "Decoder Model Config": "إعدادات نموذج الـ Decoder",
21
+ "Decoder Model Path": "مسار نموذج الـ Decoder",
22
+ "Disabled": "معطّل",
23
+ "Enable Reference Audio": "تفعيل الصوت المرجعي",
24
+ "English": "الإنجليزية",
25
+ "Error Message": "رسالة الخطأ",
26
+ "File Preprocessing": "معالجة الملفات المسبقة",
27
+ "Generate": "توليد",
28
+ "Generated Audio": "الصوت المولَّد",
29
+ "If there is no corresponding text for the audio, apply ASR for assistance, support .txt or .lab format": "إذا لم يكن هناك نص مطابق للصوت، استخدم الـ ASR للمساعدة، يدعم صيغة .txt أو .lab",
30
+ "Infer interface is closed": "تم إغلاق واجهة الـ Inference",
31
+ "Inference Configuration": "إعدادات الـ Inference",
32
+ "Inference Server Configuration": "إعدادات خادم الـ Inference",
33
+ "Inference Server Error": "خطأ في خادم الـ Inference",
34
+ "Inferring interface is launched at {}": "تم تشغيل واجهة الـ Inference على {}",
35
+ "Initial Learning Rate": "معدل التعلم الابتدائي",
36
+ "Input Audio & Source Path for Transcription": "الصوت المدخل ومسار المصدر للنسخ",
37
+ "Input Text": "النص المدخل",
38
+ "Invalid path: {}": "المسار غير صالح: {}",
39
+ "It is recommended to use CUDA, if you have low configuration, use CPU": "يُنصح باستخدام CUDA، أما إذا كان جهازك ضعيفًا فاستخدم CPU",
40
+ "Iterative Prompt Length, 0 means off": "طول الـ Prompt التكراري، 0 يعني إيقاف",
41
+ "Japanese": "اليابانية",
42
+ "LLAMA Configuration": "إعدادات LLAMA",
43
+ "LLAMA Model Config": "إعدادات نموذج LLAMA",
44
+ "LLAMA Model Path": "مسار نموذج LLAMA",
45
+ "Labeling Device": "جهاز التسمية",
46
+ "LoRA Model to be merged": "نموذج LoRA المراد دمجه",
47
+ "Maximum Audio Duration": "الحد الأقصى لمدة الصوت",
48
+ "Maximum Length per Sample": "الحد الأقصى لطول العينة",
49
+ "Maximum Training Steps": "الحد الأقصى لخطوات التدريب",
50
+ "Maximum tokens per batch, 0 means no limit": "الحد الأقصى للـ Tokens لكل Batch، 0 يعني بدون حد",
51
+ "Merge": "دمج",
52
+ "Merge LoRA": "دمج LoRA",
53
+ "Merge successfully": "تم الدمج بنجاح",
54
+ "Minimum Audio Duration": "الحد الأدنى لمدة الصوت",
55
+ "Model Output Path": "مسار إخراج النموذج",
56
+ "Model Size": "حجم النموذج",
57
+ "Move": "نقل",
58
+ "Move files successfully": "تم نقل الملفات بنجاح",
59
+ "No audio generated, please check the input text.": "لم يتم توليد أي صوت، تحقق من النص المدخل.",
60
+ "No selected options": "لم يتم تحديد أي خيار",
61
+ "Number of Workers": "عدد الـ Workers",
62
+ "Open Inference Server": "تشغيل خادم الـ Inference",
63
+ "Open Labeler WebUI": "فتح واجهة التسمية",
64
+ "Open Tensorboard": "فتح Tensorboard",
65
+ "Opened labeler in browser": "تم فتح التسمية في المتصفح",
66
+ "Optional Label Language": "لغة التسمية (اختياري)",
67
+ "Optional online ver": "الإصدار الأونلاين (اختياري)",
68
+ "Output Path": "مسار الإخراج",
69
+ "Path error, please check the model file exists in the corresponding path": "خطأ في ال��سار، تأكد من وجود ملف النموذج في المسار المحدد",
70
+ "Precision": "الـ Precision",
71
+ "Probability of applying Speaker Condition": "احتمالية تطبيق شرط المتحدث",
72
+ "Put your text here.": "ضع نصك هنا.",
73
+ "Reference Audio": "الصوت المرجعي",
74
+ "Reference Text": "النص المرجعي",
75
+ "Related code and weights are released under FISH AUDIO RESEARCH LICENSE.": "الكود والأوزان المرتبطة متاحة تحت رخصة FISH AUDIO RESEARCH.",
76
+ "Remove Selected Data": "حذف البيانات المحددة",
77
+ "Removed path successfully!": "تمت إزالة المسار بنجاح!",
78
+ "Repetition Penalty": "Repetition Penalty",
79
+ "Save model every n steps": "حفظ النموذج كل n خطوة",
80
+ "Select LLAMA ckpt": "اختر ملف الـ LLAMA Checkpoint",
81
+ "Select VITS ckpt": "اختر ملف الـ VITS Checkpoint",
82
+ "Select VQGAN ckpt": "اختر ملف الـ VQGAN Checkpoint",
83
+ "Select source file processing method": "اختر طريقة معالجة الملف المصدر",
84
+ "Select the model to be trained (Depending on the Tab page you are on)": "اختر النموذج للتدريب (حسب التبويب الحالي)",
85
+ "Selected: {}": "المحدد: {}",
86
+ "Speaker": "المتحدث",
87
+ "Speaker is identified by the folder name": "يتم التعرف على المتحدث من اسم المجلد",
88
+ "Start Training": "بدء التدريب",
89
+ "Streaming Audio": "بث الصوت",
90
+ "Streaming Generate": "توليد بث",
91
+ "Tensorboard Host": "Host الـ Tensorboard",
92
+ "Tensorboard Log Path": "مسار سجل Tensorboard",
93
+ "Tensorboard Port": "Port الـ Tensorboard",
94
+ "Tensorboard interface is closed": "تم إغلاق واجهة Tensorboard",
95
+ "Tensorboard interface is launched at {}": "تم تشغيل Tensorboard على {}",
96
+ "Text is too long, please keep it under {} characters.": "النص طويل جدًا، يرجى إبقاؤه أقل من {} حرف.",
97
+ "The path of the input folder on the left or the filelist. Whether checked or not, it will be used for subsequent training in this list.": "مسار المجلد المدخل على اليسار أو قائمة الملفات. سواء كان محددًا أم لا، سيُستخدم في التدريب اللاحق.",
98
+ "Training Configuration": "إعدادات التدريب",
99
+ "Training Error": "خطأ في التدريب",
100
+ "Training stopped": "توقف التدريب",
101
+ "Type name of the speaker": "اكتب اسم المتحدث",
102
+ "Type the path or select from the dropdown": "اكتب المسار أو اختر من القائمة",
103
+ "Use LoRA": "استخدام LoRA",
104
+ "Use LoRA can save GPU memory, but may reduce the quality of the model": "استخدام LoRA يوفر ذاكرة الـ GPU لكنه قد يقلل من جودة النموذج",
105
+ "Use filelist": "استخدام قائمة الملفات",
106
+ "Use large for 10G+ GPU, medium for 5G, small for 2G": "استخدم Large لبطاقات 10G+، Medium لـ 5G، Small لـ 2G",
107
+ "VITS Configuration": "إعدادات VITS",
108
+ "VQGAN Configuration": "إعدادات VQGAN",
109
+ "Validation Batch Size": "حجم دفعة التحقق",
110
+ "View the status of the preprocessing folder (use the slider to control the depth of the tree)": "عرض حالة مجلد المعالجة المسبقة (استخدم الـ Slider للتحكم في عمق الشجرة)",
111
+ "We are not responsible for any misuse of the model, please consider your local laws and regulations before using it.": "نحن غير مسؤولين عن أي استخدام خاطئ للنموذج، يرجى مراعاة القوانين واللوائح المحلية قبل استخدامه.",
112
+ "WebUI Host": "Host الـ WebUI",
113
+ "WebUI Port": "Port الـ WebUI",
114
+ "Whisper Model": "نموذج Whisper",
115
+ "You can find the source code [here](https://github.com/fishaudio/fish-speech) and models [here](https://huggingface.co/fishaudio/fish-speech-1.5).": "يمكنك إيجاد الكود المصدري [هنا](https://github.com/fishaudio/fish-speech) والنماذج [هنا](https://huggingface.co/fishaudio/fish-speech-1.5).",
116
+ "bf16-true is recommended for 30+ series GPU, 16-mixed is recommended for 10+ series GPU": "يُنصح بـ bf16-true لبطاقات سلسلة 30+ وما فوق، و16-mixed لسلسلة 10+ وما فوق",
117
+ "latest": "الأحدث",
118
+ "new": "جديد",
119
+ "Realtime Transform Text": "تحويل النص في الوقت الفعلي",
120
+ "Normalization Result Preview (Currently Only Chinese)": "معاينة نتيجة الـ Normalization (حاليًا للصينية فقط)",
121
+ "Text Normalization": "Normalization النص",
122
+ "Select Example Audio": "اختر مثال صوتي"
123
+ }
vendor/fish-speech/fish_speech/i18n/locale/en_US.json ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "16-mixed is recommended for 10+ series GPU": "16-mixed is recommended for 10+ series GPU",
3
+ "5 to 10 seconds of reference audio, useful for specifying speaker.": "5 to 10 seconds of reference audio, useful for specifying speaker.",
4
+ "A text-to-speech model based on VQ-GAN and Llama developed by [Fish Audio](https://fish.audio).": "A text-to-speech model based on VQ-GAN and Llama developed by [Fish Audio](https://fish.audio).",
5
+ "Accumulate Gradient Batches": "Accumulate Gradient Batches",
6
+ "Add to Processing Area": "Add to Processing Area",
7
+ "Added path successfully!": "Added path successfully!",
8
+ "Advanced Config": "Advanced Config",
9
+ "Base LLAMA Model": "Base LLAMA Model",
10
+ "Batch Inference": "Batch Inference",
11
+ "Batch Size": "Batch Size",
12
+ "Changing with the Model Path": "Changing with the Model Path",
13
+ "Chinese": "Chinese",
14
+ "Compile Model": "Compile Model",
15
+ "Compile the model can significantly reduce the inference time, but will increase cold start time": "Compile the model can significantly reduce the inference time, but will increase cold start time",
16
+ "Copy": "Copy",
17
+ "Data Preprocessing": "Data Preprocessing",
18
+ "Data Preprocessing Path": "Data Preprocessing Path",
19
+ "Data Source": "Data Source",
20
+ "Decoder Model Config": "Decoder Model Config",
21
+ "Decoder Model Path": "Decoder Model Path",
22
+ "Disabled": "Disabled",
23
+ "Enable Reference Audio": "Enable Reference Audio",
24
+ "English": "English",
25
+ "Error Message": "Error Message",
26
+ "File Preprocessing": "File Preprocessing",
27
+ "Generate": "Generate",
28
+ "Generated Audio": "Generated Audio",
29
+ "If there is no corresponding text for the audio, apply ASR for assistance, support .txt or .lab format": "If there is no corresponding text for the audio, apply ASR for assistance, support .txt or .lab format",
30
+ "Infer interface is closed": "Infer interface is closed",
31
+ "Inference Configuration": "Inference Configuration",
32
+ "Inference Server Configuration": "Inference Server Configuration",
33
+ "Inference Server Error": "Inference Server Error",
34
+ "Inferring interface is launched at {}": "Inferring interface is launched at {}",
35
+ "Initial Learning Rate": "Initial Learning Rate",
36
+ "Input Audio & Source Path for Transcription": "Input Audio & Source Path for Transcription",
37
+ "Input Text": "Input Text",
38
+ "Invalid path: {}": "Invalid path: {}",
39
+ "It is recommended to use CUDA, if you have low configuration, use CPU": "It is recommended to use CUDA, if you have low configuration, use CPU",
40
+ "Iterative Prompt Length, 0 means off": "Iterative Prompt Length, 0 means off",
41
+ "Japanese": "Japanese",
42
+ "LLAMA Configuration": "LLAMA Configuration",
43
+ "LLAMA Model Config": "LLAMA Model Config",
44
+ "LLAMA Model Path": "LLAMA Model Path",
45
+ "Labeling Device": "Labeling Device",
46
+ "LoRA Model to be merged": "LoRA Model to be merged",
47
+ "Maximum Audio Duration": "Maximum Audio Duration",
48
+ "Maximum Length per Sample": "Maximum Length per Sample",
49
+ "Maximum Training Steps": "Maximum Training Steps",
50
+ "Maximum tokens per batch, 0 means no limit": "Maximum tokens per batch, 0 means no limit",
51
+ "Merge": "Merge",
52
+ "Merge LoRA": "Merge LoRA",
53
+ "Merge successfully": "Merge successfully",
54
+ "Minimum Audio Duration": "Minimum Audio Duration",
55
+ "Model Output Path": "Model Output Path",
56
+ "Model Size": "Model Size",
57
+ "Move": "Move",
58
+ "Move files successfully": "Move files successfully",
59
+ "No audio generated, please check the input text.": "No audio generated, please check the input text.",
60
+ "No selected options": "No selected options",
61
+ "Number of Workers": "Number of Workers",
62
+ "Open Inference Server": "Open Inference Server",
63
+ "Open Labeler WebUI": "Open Labeler WebUI",
64
+ "Open Tensorboard": "Open Tensorboard",
65
+ "Opened labeler in browser": "Opened labeler in browser",
66
+ "Optional Label Language": "Optional Label Language",
67
+ "Optional online ver": "Optional online ver",
68
+ "Output Path": "Output Path",
69
+ "Path error, please check the model file exists in the corresponding path": "Path error, please check the model file exists in the corresponding path",
70
+ "Precision": "Precision",
71
+ "Probability of applying Speaker Condition": "Probability of applying Speaker Condition",
72
+ "Put your text here.": "Put your text here.",
73
+ "Reference Audio": "Reference Audio",
74
+ "Reference Text": "Reference Text",
75
+ "Related code and weights are released under FISH AUDIO RESEARCH LICENSE.": "Related code and weights are released under FISH AUDIO RESEARCH LICENSE.",
76
+ "Remove Selected Data": "Remove Selected Data",
77
+ "Removed path successfully!": "Removed path successfully!",
78
+ "Repetition Penalty": "Repetition Penalty",
79
+ "Save model every n steps": "Save model every n steps",
80
+ "Select LLAMA ckpt": "Select LLAMA ckpt",
81
+ "Select VITS ckpt": "Select VITS ckpt",
82
+ "Select VQGAN ckpt": "Select VQGAN ckpt",
83
+ "Select source file processing method": "Select source file processing method",
84
+ "Select the model to be trained (Depending on the Tab page you are on)": "Select the model to be trained (Depending on the Tab page you are on)",
85
+ "Selected: {}": "Selected: {}",
86
+ "Speaker": "Speaker",
87
+ "Speaker is identified by the folder name": "Speaker is identified by the folder name",
88
+ "Start Training": "Start Training",
89
+ "Streaming Audio": "Streaming Audio",
90
+ "Streaming Generate": "Streaming Generate",
91
+ "Tensorboard Host": "Tensorboard Host",
92
+ "Tensorboard Log Path": "Tensorboard Log Path",
93
+ "Tensorboard Port": "Tensorboard Port",
94
+ "Tensorboard interface is closed": "Tensorboard interface is closed",
95
+ "Tensorboard interface is launched at {}": "Tensorboard interface is launched at {}",
96
+ "Text is too long, please keep it under {} characters.": "Text is too long, please keep it under {} characters.",
97
+ "The path of the input folder on the left or the filelist. Whether checked or not, it will be used for subsequent training in this list.": "The path of the input folder on the left or the filelist. Whether checked or not, it will be used for subsequent training in this list.",
98
+ "Training Configuration": "Training Configuration",
99
+ "Training Error": "Training Error",
100
+ "Training stopped": "Training stopped",
101
+ "Type name of the speaker": "Type name of the speaker",
102
+ "Type the path or select from the dropdown": "Type the path or select from the dropdown",
103
+ "Use LoRA": "Use LoRA",
104
+ "Use LoRA can save GPU memory, but may reduce the quality of the model": "Use LoRA can save GPU memory, but may reduce the quality of the model",
105
+ "Use filelist": "Use filelist",
106
+ "Use large for 10G+ GPU, medium for 5G, small for 2G": "Use large for 10G+ GPU, medium for 5G, small for 2G",
107
+ "VITS Configuration": "VITS Configuration",
108
+ "VQGAN Configuration": "VQGAN Configuration",
109
+ "Validation Batch Size": "Validation Batch Size",
110
+ "View the status of the preprocessing folder (use the slider to control the depth of the tree)": "View the status of the preprocessing folder (use the slider to control the depth of the tree)",
111
+ "We are not responsible for any misuse of the model, please consider your local laws and regulations before using it.": "We are not responsible for any misuse of the model, please consider your local laws and regulations before using it.",
112
+ "WebUI Host": "WebUI Host",
113
+ "WebUI Port": "WebUI Port",
114
+ "Whisper Model": "Whisper Model",
115
+ "You can find the source code [here](https://github.com/fishaudio/fish-speech) and models [here](https://huggingface.co/fishaudio/fish-speech-1.5).": "You can find the source code [here](https://github.com/fishaudio/fish-speech) and models [here](https://huggingface.co/fishaudio/fish-speech-1.5).",
116
+ "bf16-true is recommended for 30+ series GPU, 16-mixed is recommended for 10+ series GPU": "bf16-true is recommended for 30+ series GPU, 16-mixed is recommended for 10+ series GPU",
117
+ "latest": "latest",
118
+ "new": "new",
119
+ "Realtime Transform Text": "Realtime Transform Text",
120
+ "Normalization Result Preview (Currently Only Chinese)": "Normalization Result Preview (Currently Only Chinese)",
121
+ "Text Normalization": "Text Normalization",
122
+ "Select Example Audio": "Select Example Audio"
123
+ }
vendor/fish-speech/fish_speech/i18n/locale/es_ES.json ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "16-mixed is recommended for 10+ series GPU": "se recomienda 16-mixed para GPU de la serie 10+",
3
+ "5 to 10 seconds of reference audio, useful for specifying speaker.": "5 a 10 segundos de audio de referencia, útil para especificar el hablante.",
4
+ "A text-to-speech model based on VQ-GAN and Llama developed by [Fish Audio](https://fish.audio).": "Un modelo de texto a voz basado en VQ-GAN y Llama desarrollado por [Fish Audio](https://fish.audio).",
5
+ "Accumulate Gradient Batches": "Acumular lotes de gradientes",
6
+ "Add to Processing Area": "Agregar al Área de Procesamiento",
7
+ "Added path successfully!": "¡Ruta agregada exitosamente!",
8
+ "Advanced Config": "Configuración Avanzada",
9
+ "Base LLAMA Model": "Modelo Base LLAMA",
10
+ "Batch Inference": "Inferencia por Lote",
11
+ "Batch Size": "Tamaño del Lote",
12
+ "Changing with the Model Path": "Cambiando con la Ruta del Modelo",
13
+ "Chinese": "Chino",
14
+ "Compile Model": "Compilar Modelo",
15
+ "Compile the model can significantly reduce the inference time, but will increase cold start time": "Compilar el modelo puede reducir significativamente el tiempo de inferencia, pero aumentará el tiempo de inicio en frío",
16
+ "Copy": "Copiar",
17
+ "Data Preprocessing": "Preprocesamiento de Datos",
18
+ "Data Preprocessing Path": "Ruta de Preprocesamiento de Datos",
19
+ "Data Source": "Fuente de Datos",
20
+ "Decoder Model Config": "Configuración del modelo decodificador",
21
+ "Decoder Model Path": "Ruta del modelo decodificador",
22
+ "Disabled": "Desactivado",
23
+ "Enable Reference Audio": "Habilitar Audio de Referencia",
24
+ "English": "Inglés",
25
+ "Error Message": "Mensaje de Error",
26
+ "File Preprocessing": "Preprocesamiento de Archivos",
27
+ "Generate": "Generar",
28
+ "Generated Audio": "Audio Generado",
29
+ "If there is no corresponding text for the audio, apply ASR for assistance, support .txt or .lab format": "Si no hay texto correspondiente para el audio, aplique ASR para asistencia, soporte para formato .txt o .lab",
30
+ "Infer interface is closed": "La interfaz de inferencia está cerrada",
31
+ "Inference Configuration": "Configuración de Inferencia",
32
+ "Inference Server Configuration": "Configuración del Servidor de Inferencia",
33
+ "Inference Server Error": "Error del Servidor de Inferencia",
34
+ "Inferring interface is launched at {}": "La interfaz de inferencia se ha lanzado en {}",
35
+ "Initial Learning Rate": "Tasa de Aprendizaje Inicial",
36
+ "Input Audio & Source Path for Transcription": "Audio de Entrada y Ruta de Origen para Transcripción",
37
+ "Input Text": "Texto de Entrada",
38
+ "Invalid path: {}": "Ruta inválida: {}",
39
+ "It is recommended to use CUDA, if you have low configuration, use CPU": "Se recomienda usar CUDA, si tiene una configuración baja, use CPU",
40
+ "Iterative Prompt Length, 0 means off": "Longitud de la Indicación Iterativa, 0 significa apagado",
41
+ "Japanese": "Japonés",
42
+ "LLAMA Configuration": "Configuración de LLAMA",
43
+ "LLAMA Model Config": "Configuración del Modelo LLAMA",
44
+ "LLAMA Model Path": "Ruta del Modelo LLAMA",
45
+ "Labeling Device": "Dispositivo de Etiquetado",
46
+ "LoRA Model to be merged": "Modelo LoRA a fusionar",
47
+ "Maximum Audio Duration": "Duración máxima de audio",
48
+ "Maximum Length per Sample": "Longitud Máxima por Muestra",
49
+ "Maximum Training Steps": "Pasos Máximos de Entrenamiento",
50
+ "Maximum tokens per batch, 0 means no limit": "Máximo de tokens por lote, 0 significa sin límite",
51
+ "Merge": "Fusionar",
52
+ "Merge LoRA": "Fusionar LoRA",
53
+ "Merge successfully": "Fusionado exitosamente",
54
+ "Minimum Audio Duration": "Duración mínima de audio",
55
+ "Model Output Path": "Ruta de Salida del Modelo",
56
+ "Model Size": "Tamaño del Modelo",
57
+ "Move": "Mover",
58
+ "Move files successfully": "Archivos movidos exitosamente",
59
+ "No audio generated, please check the input text.": "No se generó audio, por favor verifique el texto de entrada.",
60
+ "No selected options": "No hay opciones seleccionadas",
61
+ "Number of Workers": "Número de Trabajadores",
62
+ "Open Inference Server": "Abrir Servidor de Inferencia",
63
+ "Open Labeler WebUI": "Abrir Interfaz Web del Etiquetador",
64
+ "Open Tensorboard": "Abrir Tensorboard",
65
+ "Opened labeler in browser": "Se abrió el etiquetador en el navegador",
66
+ "Optional Label Language": "Idioma de Etiquetado Opcional",
67
+ "Optional online ver": "Ver en línea opcional",
68
+ "Output Path": "Ruta de Salida",
69
+ "Path error, please check the model file exists in the corresponding path": "Error de ruta, por favor verifique que el archivo del modelo exista en la ruta correspondiente",
70
+ "Precision": "Precisión",
71
+ "Probability of applying Speaker Condition": "Probabilidad de aplicar Condición de Hablante",
72
+ "Put your text here.": "Ponga su texto aquí.",
73
+ "Reference Audio": "Audio de Referencia",
74
+ "Reference Text": "Texto de Referencia",
75
+ "Related code and weights are released under FISH AUDIO RESEARCH LICENSE.": "El código relacionado y los pesos se publican bajo la FISH AUDIO RESEARCH LICENSE.",
76
+ "Remove Selected Data": "Eliminar Datos Seleccionados",
77
+ "Removed path successfully!": "¡Ruta eliminada exitosamente!",
78
+ "Repetition Penalty": "Penalización por Repetición",
79
+ "Save model every n steps": "Guardar modelo cada n pasos",
80
+ "Select LLAMA ckpt": "Seleccionar punto de control LLAMA",
81
+ "Select VITS ckpt": "Seleccionar punto de control VITS",
82
+ "Select VQGAN ckpt": "Seleccionar punto de control VQGAN",
83
+ "Select source file processing method": "Seleccione el método de procesamiento de archivos fuente",
84
+ "Select the model to be trained (Depending on the Tab page you are on)": "Seleccione el modelo a entrenar (Dependiendo de la pestaña en la que se encuentre)",
85
+ "Selected: {}": "Seleccionado: {}",
86
+ "Speaker": "Hablante",
87
+ "Speaker is identified by the folder name": "El hablante se identifica por el nombre de la carpeta",
88
+ "Start Training": "Iniciar Entrenamiento",
89
+ "Streaming Audio": "transmisión de audio",
90
+ "Streaming Generate": "síntesis en flujo",
91
+ "Tensorboard Host": "Host de Tensorboard",
92
+ "Tensorboard Log Path": "Ruta de Registro de Tensorboard",
93
+ "Tensorboard Port": "Puerto de Tensorboard",
94
+ "Tensorboard interface is closed": "La interfaz de Tensorboard está cerrada",
95
+ "Tensorboard interface is launched at {}": "La interfaz de Tensorboard se ha lanzado en {}",
96
+ "Text is too long, please keep it under {} characters.": "El texto es demasiado largo, por favor manténgalo por debajo de {} caracteres.",
97
+ "The path of the input folder on the left or the filelist. Whether checked or not, it will be used for subsequent training in this list.": "La ruta de la carpeta de entrada a la izquierda o la lista de archivos. Ya sea que esté marcado o no, se utilizará para el entrenamiento posterior en esta lista.",
98
+ "Training Configuration": "Configuración de Entrenamiento",
99
+ "Training Error": "Error de Entrenamiento",
100
+ "Training stopped": "Entrenamiento detenido",
101
+ "Type name of the speaker": "Escriba el nombre del hablante",
102
+ "Type the path or select from the dropdown": "Escriba la ruta o seleccione de la lista desplegable",
103
+ "Use LoRA": "Usar LoRA",
104
+ "Use LoRA can save GPU memory, but may reduce the quality of the model": "Usar LoRA puede ahorrar memoria GPU, pero puede reducir la calidad del modelo",
105
+ "Use filelist": "Usar lista de archivos",
106
+ "Use large for 10G+ GPU, medium for 5G, small for 2G": "Use grande para GPU de 10G+, mediano para 5G, pequeño para 2G",
107
+ "VITS Configuration": "Configuración de VITS",
108
+ "VQGAN Configuration": "Configuración de VQGAN",
109
+ "Validation Batch Size": "Tamaño del Lote de Validación",
110
+ "View the status of the preprocessing folder (use the slider to control the depth of the tree)": "Vea el estado de la carpeta de preprocesamiento (use el control deslizante para controlar la profundidad del árbol)",
111
+ "We are not responsible for any misuse of the model, please consider your local laws and regulations before using it.": "No somos responsables de ningún mal uso del modelo, por favor considere sus leyes y regulaciones locales antes de usarlo.",
112
+ "WebUI Host": "Host de WebUI",
113
+ "WebUI Port": "Puerto de WebUI",
114
+ "Whisper Model": "Modelo Whisper",
115
+ "You can find the source code [here](https://github.com/fishaudio/fish-speech) and models [here](https://huggingface.co/fishaudio/fish-speech-1.5).": "Puede encontrar el código fuente [aquí](https://github.com/fishaudio/fish-speech) y los modelos [aquí](https://huggingface.co/fishaudio/fish-speech-1.5).",
116
+ "bf16-true is recommended for 30+ series GPU, 16-mixed is recommended for 10+ series GPU": "Se recomienda bf16-true para GPU de la serie 30+, se recomienda 16-mixed para GPU de la serie 10+",
117
+ "latest": "más reciente",
118
+ "new": "nuevo",
119
+ "Realtime Transform Text": "Transformación de Texto en Tiempo Real",
120
+ "Normalization Result Preview (Currently Only Chinese)": "Vista Previa del Resultado de Normalización (Actualmente Solo Chino)",
121
+ "Text Normalization": "Normalización de Texto",
122
+ "Select Example Audio": "Selecionar áudio de exemplo"
123
+ }
vendor/fish-speech/fish_speech/i18n/locale/ja_JP.json ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "16-mixed is recommended for 10+ series GPU": "10シリーズ以降のGPUには16-mixedをお勧めします",
3
+ "5 to 10 seconds of reference audio, useful for specifying speaker.": "話者を指定するのに役立つ、5~10秒のリファレンスオーディオ。",
4
+ "A text-to-speech model based on VQ-GAN and Llama developed by [Fish Audio](https://fish.audio).": "[Fish Audio](https://fish.audio)が開発したVQ-GANとLlamaに基づくテキスト音声合成モデル。",
5
+ "Accumulate Gradient Batches": "勾配バッチの累積",
6
+ "Add to Processing Area": "処理エリアに追加",
7
+ "Added path successfully!": "パスの追加に成功しました!",
8
+ "Advanced Config": "詳細設定",
9
+ "Base LLAMA Model": "基本LLAMAモデル",
10
+ "Batch Inference": "バッチ推論",
11
+ "Batch Size": "バッチサイズ",
12
+ "Changing with the Model Path": "モデルのパスに伴って変化する",
13
+ "Chinese": "中国語",
14
+ "Compile Model": "モデルのコンパイル",
15
+ "Compile the model can significantly reduce the inference time, but will increase cold start time": "モデルをコンパイルすると推論時間を大幅に短縮できますが、コールドスタート時間が長くなります",
16
+ "Copy": "コピー",
17
+ "Data Preprocessing": "データ前処理",
18
+ "Data Preprocessing Path": "データ前処理パス",
19
+ "Data Source": "データソース",
20
+ "Decoder Model Config": "デコーダーモデルの構成",
21
+ "Decoder Model Path": "デコーダーモデルのパス",
22
+ "Disabled": "無効",
23
+ "Enable Reference Audio": "リファレンスオーディオを有効にする",
24
+ "English": "英語",
25
+ "Error Message": "エラーメッセージ",
26
+ "File Preprocessing": "文書前处理",
27
+ "Generate": "生成",
28
+ "Generated Audio": "生成されたオーディオ",
29
+ "If there is no corresponding text for the audio, apply ASR for assistance, support .txt or .lab format": "音声に対応するテキストがない場合は、ASRを適用してサポートします。.txtまたは.lab形式をサポートしています",
30
+ "Infer interface is closed": "推論インターフェースが閉じられています",
31
+ "Inference Configuration": "推論設定",
32
+ "Inference Server Configuration": "推論サーバー設定",
33
+ "Inference Server Error": "推論サーバーエラー",
34
+ "Inferring interface is launched at {}": "推論インターフェースが{}で起動しました",
35
+ "Initial Learning Rate": "初期学習率",
36
+ "Input Audio & Source Path for Transcription": "入力オーディオと文字起こしのソースパス",
37
+ "Input Text": "入力テキスト",
38
+ "Invalid path: {}": "無効なパス: {}",
39
+ "It is recommended to use CUDA, if you have low configuration, use CPU": "CUDAの使用をお勧めします。低い構成の場合はCPUを使用してください",
40
+ "Iterative Prompt Length, 0 means off": "反復プロンプト長。0はオフを意味します",
41
+ "Japanese": "日本語",
42
+ "LLAMA Configuration": "LLAMA設定",
43
+ "LLAMA Model Config": "LLAMAモデル設定",
44
+ "LLAMA Model Path": "LLAMAモデルパス",
45
+ "Labeling Device": "ラベリングデバイス",
46
+ "LoRA Model to be merged": "マージするLoRAモデル",
47
+ "Maximum Audio Duration": "最大オーディオの長さ",
48
+ "Maximum Length per Sample": "サンプルあたりの最大長",
49
+ "Maximum Training Steps": "最大トレーニングステップ数",
50
+ "Maximum tokens per batch, 0 means no limit": "バッチあたりの最大トークン数。0は制限なしを意味します",
51
+ "Merge": "マージ",
52
+ "Merge LoRA": "LoRAのマージ",
53
+ "Merge successfully": "マージに成功しました",
54
+ "Minimum Audio Duration": "最小オーディオの長さ",
55
+ "Model Output Path": "モデル出力パス",
56
+ "Model Size": "モデルサイズ",
57
+ "Move": "移動",
58
+ "Move files successfully": "ファイルの移動に成功しました",
59
+ "No audio generated, please check the input text.": "オーディオが生成されていません。入力テキストを確認してください。",
60
+ "No selected options": "選択されたオプションはありません",
61
+ "Number of Workers": "ワーカー数",
62
+ "Open Inference Server": "推論サーバーを開く",
63
+ "Open Labeler WebUI": "ラベラーWebUIを開く",
64
+ "Open Tensorboard": "Tensorboardを開く",
65
+ "Opened labeler in browser": "ブラウザでラベラーを開きました",
66
+ "Optional Label Language": "オプションのラベル言語",
67
+ "Optional online ver": "オプションのオンラインバージョン",
68
+ "Output Path": "出力パス",
69
+ "Path error, please check the model file exists in the corresponding path": "パスエラー。対応するパスにモデルファイルが存在するか確認してください",
70
+ "Precision": "精度",
71
+ "Probability of applying Speaker Condition": "話者条件を適用する確率",
72
+ "Put your text here.": "ここにテキストを入力してください。",
73
+ "Reference Audio": "リファレンスオーディオ",
74
+ "Reference Text": "リファレンステキスト",
75
+ "Related code and weights are released under FISH AUDIO RESEARCH LICENSE.": "関連コードと重みはFISH AUDIO RESEARCH LICENSEの下でリリースされます。",
76
+ "Remove Selected Data": "選択したデータを削除",
77
+ "Removed path successfully!": "パスの削除に成功しました!",
78
+ "Repetition Penalty": "反復ペナルティ",
79
+ "Save model every n steps": "nステップごとにモデルを保存",
80
+ "Select LLAMA ckpt": " LLAMA チェックポイントを選択",
81
+ "Select VITS ckpt": "VITS チェックポイントを選択",
82
+ "Select VQGAN ckpt": "VQGAN チェックポイントを選択",
83
+ "Select source file processing method": "ソースファイルの処理方法を選択",
84
+ "Select the model to be trained (Depending on the Tab page you are on)": "タブページに応じてトレーニングするモデルを選択してください",
85
+ "Selected: {}": "選択済み: {}",
86
+ "Speaker": "話者",
87
+ "Speaker is identified by the folder name": "話者はフォルダ名で識別されます",
88
+ "Start Training": "トレーニング開始",
89
+ "Streaming Audio": "ストリーミングオーディオ",
90
+ "Streaming Generate": "ストリーミング合成",
91
+ "Tensorboard Host": "Tensorboardホスト",
92
+ "Tensorboard Log Path": "Tensorboardログパス",
93
+ "Tensorboard Port": "Tensorboardポート",
94
+ "Tensorboard interface is closed": "Tensorboardインターフェースが閉じられています",
95
+ "Tensorboard interface is launched at {}": "Tensorboardインターフェースが{}で起動されました",
96
+ "Text is too long, please keep it under {} characters.": "テキストが長すぎます。{}文字以内に抑えてください。",
97
+ "The path of the input folder on the left or the filelist. Whether checked or not, it will be used for subsequent training in this list.": "左側の入力フォルダまたはファイルリストのパス。チェックの有無にかかわらず、このリストの後続のトレーニングに使用されます。",
98
+ "Training Configuration": "トレーニング設定",
99
+ "Training Error": "トレーニングエラー",
100
+ "Training stopped": "トレーニングが停止しました",
101
+ "Type name of the speaker": "話者の名前を入力",
102
+ "Type the path or select from the dropdown": "パスを入力するか、ドロップダウンから選択してください",
103
+ "Use LoRA": "LoRAを使用",
104
+ "Use LoRA can save GPU memory, but may reduce the quality of the model": "LoRAを使用するとGPUメモリを節約できますが、モデルの品質が低下する可能性があります",
105
+ "Use filelist": "ファイルリストを使用",
106
+ "Use large for 10G+ GPU, medium for 5G, small for 2G": "10G以上のGPUには大、5Gには中、2Gには小を使用してください",
107
+ "VITS Configuration": "VITS の構成",
108
+ "VQGAN Configuration": "VQGAN の構成",
109
+ "Validation Batch Size": "検証バッチサイズ",
110
+ "View the status of the preprocessing folder (use the slider to control the depth of the tree)": "前処理フォルダの状態を表示(スライダーを使用してツリーの深さを制御)",
111
+ "We are not responsible for any misuse of the model, please consider your local laws and regulations before using it.": "モデルの誤用については一切責任を負いません。使用する前に、現地の法律と規制を考慮してください。",
112
+ "WebUI Host": "WebUIホスト",
113
+ "WebUI Port": "WebUIポート",
114
+ "Whisper Model": "Whisperモデル",
115
+ "You can find the source code [here](https://github.com/fishaudio/fish-speech) and models [here](https://huggingface.co/fishaudio/fish-speech-1.5).": "ソースコードは[こちら](https://github.com/fishaudio/fish-speech)、モデルは[こちら](https://huggingface.co/fishaudio/fish-speech-1.5)にあります。",
116
+ "bf16-true is recommended for 30+ series GPU, 16-mixed is recommended for 10+ series GPU": "30シリーズ以降のGPUにはbf16-trueを、10シリーズ以降のGPUには16-mixedをお勧めします",
117
+ "latest": "最新",
118
+ "new": "新規",
119
+ "Realtime Transform Text": "リアルタイム変換テキスト",
120
+ "Normalization Result Preview (Currently Only Chinese)": "正規化結果プレビュー(現在は中国語のみ)",
121
+ "Text Normalization": "テキスト正規化",
122
+ "Select Example Audio": "サンプル音声を選択"
123
+ }
vendor/fish-speech/fish_speech/i18n/locale/ko_KR.json ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "16-mixed is recommended for 10+ series GPU": "10+ 시리즈 GPU에는 16-mixed를 권장합니다.",
3
+ "5 to 10 seconds of reference audio, useful for specifying speaker.": "화자를 특정하는 데 유의미한 5~10초의 길이의 참조 오디오 데이터.",
4
+ "A text-to-speech model based on VQ-GAN and Llama developed by [Fish Audio](https://fish.audio).": "[Fish Audio](https://fish.audio)에서 개발한 VQ-GAN 및 Llama 기반의 텍스트 음성 변환 모델.",
5
+ "Accumulate Gradient Batches": "그라디언트 배치 누적",
6
+ "Add to Processing Area": "처리 영역에 추가",
7
+ "Added path successfully!": "경로가 성공적으로 추가되었습니다!",
8
+ "Advanced Config": "고급 설정",
9
+ "Base LLAMA Model": "기본 LLAMA 모델",
10
+ "Batch Inference": "배치 추론",
11
+ "Batch Size": "배치 크기",
12
+ "Changing with the Model Path": "모델 경로에 따라 변경 중",
13
+ "Chinese": "중국어",
14
+ "Compile Model": "모델 컴파일",
15
+ "Compile the model can significantly reduce the inference time, but will increase cold start time": "모델을 컴파일하면 추론 시간이 크게 줄어들지만, 초기 시작 시간이 길어집니다.",
16
+ "Copy": "복사",
17
+ "Data Preprocessing": "데이터 전처리",
18
+ "Data Preprocessing Path": "데이터 전처리 경로",
19
+ "Data Source": "데이터 소스",
20
+ "Decoder Model Config": "디코더 모델 설정",
21
+ "Decoder Model Path": "디코더 모델 경로",
22
+ "Disabled": "비활성화 됨",
23
+ "Enable Reference Audio": "참고 음성 활성화",
24
+ "English": "영어",
25
+ "Error Message": "오류 메시지",
26
+ "File Preprocessing": "파일 전처리",
27
+ "Generate": "생성",
28
+ "Generated Audio": "생성된 오디오",
29
+ "If there is no corresponding text for the audio, apply ASR for assistance, support .txt or .lab format": "오디오애 대응하는 텍스트가 없을 경우, ASR을 적용해 지원하며, .txt 또는 .lab 형식을 지원합니다.",
30
+ "Infer interface is closed": "추론 인터페이스가 닫혔습니다.",
31
+ "Inference Configuration": "추론 설정",
32
+ "Inference Server Configuration": "추론 서버 설정",
33
+ "Inference Server Error": "추론 서버 오류",
34
+ "Inferring interface is launched at {}": "추론 인터페이스가 {}에서 시작되었습니다.",
35
+ "Initial Learning Rate": "초기 학습률",
36
+ "Input Audio & Source Path for Transcription": "전사할 입력 오디오 및 소스 경로",
37
+ "Input Text": "입력 텍스트",
38
+ "Invalid path: {}": "유효하지 않은 경로: {}",
39
+ "It is recommended to use CUDA, if you have low configuration, use CPU": "CUDA 사용을 권장하며, 낮은 사양일 경우 CPU를 사용하는 것을 권장합니다.",
40
+ "Iterative Prompt Length, 0 means off": "반복 프롬프트 길이. (0:비활성화)",
41
+ "Japanese": "일본어",
42
+ "LLAMA Configuration": "LLAMA 설정",
43
+ "LLAMA Model Config": "LLAMA 모델 설정",
44
+ "LLAMA Model Path": "LLAMA 모델 경로",
45
+ "Labeling Device": "라벨링 장치",
46
+ "LoRA Model to be merged": "병합할 LoRA 모델",
47
+ "Maximum Audio Duration": "최대 오디오 길이",
48
+ "Maximum Length per Sample": "샘플당 최대 길이",
49
+ "Maximum Training Steps": "최대 학습 단계",
50
+ "Maximum tokens per batch, 0 means no limit": "배치당 최대 토큰 수(0:제한 없음)",
51
+ "Merge": "병합",
52
+ "Merge LoRA": "LoRA 병합",
53
+ "Merge successfully": "성공적으로 병합 되었습니다.",
54
+ "Minimum Audio Duration": "최소 오디오 길이",
55
+ "Model Output Path": "모델 출력 경로",
56
+ "Model Size": "모델 크기",
57
+ "Move": "이동",
58
+ "Move files successfully": "파일이 성공적으로 이동되었습니다.",
59
+ "No audio generated, please check the input text.": "생성된 오디오가 없습니다. 입력된 텍스트를 확인하세요.",
60
+ "No selected options": "옵션이 선택되지 않았습니다.",
61
+ "Number of Workers": "작업자 수",
62
+ "Open Inference Server": "추론 서버 열기",
63
+ "Open Labeler WebUI": "라벨러 WebUI 열기",
64
+ "Open Tensorboard": "Tensorboard 열기",
65
+ "Opened labeler in browser": "브라우저에서 라벨러가 열렸습니다.",
66
+ "Optional Label Language": "선택적 라벨 언어",
67
+ "Optional online ver": "온라인 버전 선택",
68
+ "Output Path": "출력 경로",
69
+ "Path error, please check the model file exists in the corresponding path": "경로 오류, 해당 경로에 모델 파일이 있는지 확인하십시오.",
70
+ "Precision": "정밀도",
71
+ "Probability of applying Speaker Condition": "화자 조건 적용 확률",
72
+ "Put your text here.": "여기에 텍스트를 입력하세요.",
73
+ "Reference Audio": "참고 오디오",
74
+ "Reference Text": "참고 텍스트",
75
+ "Related code and weights are released under FISH AUDIO RESEARCH LICENSE.": "관련 코드 및 가중치는 FISH AUDIO RESEARCH LICENSE 하에 배포됩니다.",
76
+ "Remove Selected Data": "선택한 데이터 제거",
77
+ "Removed path successfully!": "경로가 성공적으로 제거되었습니다!",
78
+ "Repetition Penalty": "반복 패널티",
79
+ "Save model every n steps": "n 단계마다 모델 저장",
80
+ "Select LLAMA ckpt": "LLAMA ckpt 선택",
81
+ "Select VITS ckpt": "VITS ckpt 선택",
82
+ "Select VQGAN ckpt": "VQGAN ckpt 선택",
83
+ "Select source file processing method": "소스 파일 처리 방법 선택",
84
+ "Select the model to be trained (Depending on the Tab page you are on)": "학습할 모델 선택(탭 페이지에 따라 다름)",
85
+ "Selected: {}": "선택됨: {}",
86
+ "Speaker": "화자",
87
+ "Speaker is identified by the folder name": "화자는 폴더 이름으로 식별됩니다",
88
+ "Start Training": "학습 시작",
89
+ "Streaming Audio": "스트리밍 오디오",
90
+ "Streaming Generate": "스트리밍 생성",
91
+ "Tensorboard Host": "Tensorboard 호스트",
92
+ "Tensorboard Log Path": "Tensorboard 로그 경로",
93
+ "Tensorboard Port": "Tensorboard 포트",
94
+ "Tensorboard interface is closed": "Tensorboard 인터페이스가 닫혔습니다",
95
+ "Tensorboard interface is launched at {}": "Tensorboard 인터페이스가 {}에서 시작되었습니다.",
96
+ "Text is too long, please keep it under {} characters.": "텍스트가 너무 깁니다. {}자 이하로 입력해주세요.",
97
+ "The path of the input folder on the left or the filelist. Whether checked or not, it will be used for subsequent training in this list.": "왼쪽의 입력 폴더 경로 또는 파일 목록의 경로. 체크 여부에 관계없이 이 목록에서 후속 학습에 사용됩니다.",
98
+ "Training Configuration": "학습 설정",
99
+ "Training Error": "학습 오류",
100
+ "Training stopped": "학습이 중지되었습니다.",
101
+ "Type name of the speaker": "화자의 이름을 입력하세요.",
102
+ "Type the path or select from the dropdown": "경로를 입력하거나 드롭다운에서 선택하세요.",
103
+ "Use LoRA": "LoRA 사용",
104
+ "Use LoRA can save GPU memory, but may reduce the quality of the model": "LoRA를 사용하면 GPU 메모리를 절약할 수 있지만, 모델의 품질이 저하될 수 있습니다.",
105
+ "Use filelist": "파일 목록 사용",
106
+ "Use large for 10G+ GPU, medium for 5G, small for 2G": "10G+ GPU 환경에선 large, 5G에선 medium, 2G에선 small을 사용할 것을 권장합니다.",
107
+ "VITS Configuration": "VITS 설정",
108
+ "VQGAN Configuration": "VQGAN 설정",
109
+ "Validation Batch Size": "검증 배치 크기",
110
+ "View the status of the preprocessing folder (use the slider to control the depth of the tree)": "전처리 폴더의 상태를 확인합니다(슬라이더를 사용하여 트리의 깊이를 조절합니다)",
111
+ "We are not responsible for any misuse of the model, please consider your local laws and regulations before using it.": "모델의 오용에 대해 책임지지 않습니다. 사용하기 전에 현지 법률과 규정을 고려하시길 바랍니다.",
112
+ "WebUI Host": "WebUI 호스트",
113
+ "WebUI Port": "WebUI 포트",
114
+ "Whisper Model": "Whisper 모델",
115
+ "You can find the source code [here](https://github.com/fishaudio/fish-speech) and models [here](https://huggingface.co/fishaudio/fish-speech-1.5).": "소스 코드는 [이곳](https://github.com/fishaudio/fish-speech)에서, 모델은 [이곳](https://huggingface.co/fishaudio/fish-speech-1.5)에서 확인하실 수 있습니다.",
116
+ "bf16-true is recommended for 30+ series GPU, 16-mixed is recommended for 10+ series GPU": "30+ 시리즈 GPU에는 bf16-true를, 10+ 시리즈 GPU에는 16-mixed를 권장합니다",
117
+ "latest": "최신",
118
+ "new": "새로운",
119
+ "Realtime Transform Text": "실시간 텍스트 변환",
120
+ "Normalization Result Preview (Currently Only Chinese)": "정규화 결과 미리보기(현재 중국어만 지원)",
121
+ "Text Normalization": "텍스트 정규화",
122
+ "Select Example Audio": "예시 오디오 선택"
123
+ }
vendor/fish-speech/fish_speech/i18n/locale/pt_BR.json ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "5 to 10 seconds of reference audio, useful for specifying speaker.": "5 a 10 segundos de áudio de referência, útil para especificar o orador.",
3
+ "A text-to-speech model based on VQ-GAN and Llama developed by [Fish Audio](https://fish.audio).": "Um modelo de texto para fala baseado em VQ-GAN e Llama desenvolvido por [Fish Audio](https://fish.audio).",
4
+ "Accumulate Gradient Batches": "Acumular Lotes de Gradiente",
5
+ "Add to Processing Area": "Adicionar à Área de Processamento",
6
+ "Added path successfully!": "Caminho adicionado com sucesso!",
7
+ "Advanced Config": "Configuração Avançada",
8
+ "Base LLAMA Model": "Modelo LLAMA Base",
9
+ "Batch Inference": "Inferência em Lote",
10
+ "Batch Size": "Tamanho do Lote",
11
+ "Changing with the Model Path": "Alterando com o Caminho do Modelo",
12
+ "Compile Model": "Compilar Modelo",
13
+ "Compile the model can significantly reduce the inference time, but will increase cold start time": "Compilar o modelo pode reduzir significativamente o tempo de inferência, mas aumentará a latência inicial",
14
+ "Copy": "Copiar",
15
+ "Data Preprocessing": "Pré-processamento de Dados",
16
+ "Data Preprocessing Path": "Caminho de Pré-processamento de Dados",
17
+ "Data Source": "Fonte de Dados",
18
+ "Decoder Model Config": "Configuração do Modelo Decodificador",
19
+ "Decoder Model Path": "Caminho do Modelo Decodificador",
20
+ "Disabled": "Desativado",
21
+ "Enable Initial Prompt": "Habilitar Prompt Inicial",
22
+ "Enable Reference Audio": "Habilitar Áudio de Referência",
23
+ "English": "Inglês",
24
+ "Japanese": "Japonês",
25
+ "Chinese": "Chinês",
26
+ "Portuguese": "Português",
27
+ "Spanish": "Espanhol",
28
+ "Error Message": "Mensagem de Erro",
29
+ "Faster Whisper, Up to 5g GPU memory usage": "Faster Whisper (Usa até 5 GB de vRAM)",
30
+ "File Preprocessing": "Pré-processamento de Arquivos",
31
+ "Generate": "Gerar",
32
+ "Generated Audio": "Áudio Gerado",
33
+ "If there is no corresponding text for the audio, apply ASR for assistance, support .txt or .lab format": "Se não houver texto correspondente ao áudio, utilize o ASR para assistência (formatos .txt ou .lab)",
34
+ "Infer interface is closed": "A interface de inferência foi fechada",
35
+ "Inference Configuration": "Configuração de Inferência",
36
+ "Inference Server Configuration": "Configuração do Servidor de Inferência",
37
+ "Inference Server Error": "Erro do Servidor de Inferência",
38
+ "Inferring interface is launched at {}": "A interface de inferência foi iniciada em {}",
39
+ "Initial Learning Rate": "Taxa de Aprendizagem Inicial",
40
+ "Initial Prompt": "Prompt Inicial",
41
+ "Initial prompt can provide contextual or vocabulary-specific guidance to the model.": "O prompt inicial pode fornecer orientação contextual ou específica de vocabulário para o modelo.",
42
+ "Input Audio & Source Path for Transcription": "Entrada de Áudio/Caminho de Origem para Transcrição",
43
+ "Input Text": "Texto de Entrada",
44
+ "Invalid path: {}": "Caminho inválido: {}",
45
+ "It is recommended to use CUDA, if you have low configuration, use CPU": "Para GPUs Nvidia é recomendado usar CUDA. Se não tiver uma GPU Nvidia, use CPU",
46
+ "Iterative Prompt Length, 0 means off": "Comprimento do Prompt Iterativo (0 = desativado)",
47
+ "LLAMA Configuration": "Configuração do LLAMA",
48
+ "LLAMA Model Config": "Configuração do Modelo LLAMA",
49
+ "LLAMA Model Path": "Caminho do Modelo LLAMA",
50
+ "Labeling Device": "Dispositivo de Rotulagem",
51
+ "LoRA Model to be merged": "Modelo LoRA para mesclagem",
52
+ "Maximum Length per Sample": "Comprimento Máximo por Amostra",
53
+ "Maximum Training Steps": "Etapas Máximas de Treinamento",
54
+ "Maximum tokens per batch, 0 means no limit": "Número máximo de tokens por lote, 0 significa sem limite",
55
+ "Merge": "Mesclar",
56
+ "Merge LoRA": "Mesclar LoRA",
57
+ "Merge successfully": "Mesclado com sucesso",
58
+ "Model Output Path": "Caminho de Saída do Modelo",
59
+ "Model Quantization": "Quantização do Modelo",
60
+ "Model Size": "Tamanho do Modelo",
61
+ "Move": "Mover",
62
+ "Move files successfully": "Arquivos movidos com sucesso",
63
+ "No audio generated, please check the input text.": "Nenhum áudio gerado, verifique o texto de entrada.",
64
+ "No selected options": "Nenhuma opção selecionada",
65
+ "Normalization Result Preview (Currently Only Chinese)": "Pré-visualização do Resultado da Normalização (Atualmente Apenas Chinês)",
66
+ "Number of Workers": "Número de Processos",
67
+ "Open Inference Server": "Abrir Servidor de Inferência",
68
+ "Open Labeler WebUI": "Abrir WebUI de Rotulagem",
69
+ "Open Tensorboard": "Abrir Tensorboard",
70
+ "Opened labeler in browser": "WebUI de rotulagem aberta no navegador",
71
+ "Optional Label Language": "Idioma do Rótulo (Opcional)",
72
+ "Optional online ver": "Versão online (opcional)",
73
+ "Output Path": "Caminho de Saída",
74
+ "Path error, please check the model file exists in the corresponding path": "Erro de caminho, verifique se o arquivo do modelo existe no caminho correspondente",
75
+ "Post-quantification Precision": "Precisão Pós-quantização",
76
+ "Precision": "Precisão",
77
+ "Probability of applying Speaker Condition": "Probabilidade de Aplicar Condição de Orador",
78
+ "Put your text here.": "Insira seu texto aqui.",
79
+ "Quantify": "Quantizar",
80
+ "Quantify successfully": "Quantizado com sucesso",
81
+ "Realtime Transform Text": "Transformar Texto em Tempo Real",
82
+ "Reference Audio": "Áudio de Referência",
83
+ "Reference Text": "Texto de Referência",
84
+ "warning": "Aviso",
85
+ "Pre-processing begins...": "O pré-processamento começou!",
86
+ "Related code and weights are released under FISH AUDIO RESEARCH LICENSE.": "O código relacionado e os pesos são licenciados sob a FISH AUDIO RESEARCH LICENSE.",
87
+ "Remove Selected Data": "Remover Dados Selecionados",
88
+ "Removed path successfully!": "Caminho removido com sucesso!",
89
+ "Repetition Penalty": "Penalidade de Repetição",
90
+ "Save model every n steps": "Salvar modelo a cada n etapas",
91
+ "Select LLAMA ckpt": "Selecionar .ckpt do LLAMA",
92
+ "Select source file processing method": "Escolha como processar o arquivo de origem",
93
+ "Select the model to be trained (Depending on the Tab page you are on)": "Selecione o modelo para o treinamento (dependendo da aba em que você está)",
94
+ "Selected: {}": "Selecionado: {}",
95
+ "Speaker is identified by the folder name": "O orador é identificado pelo nome da pasta",
96
+ "Start Training": "Iniciar Treinamento",
97
+ "Streaming Audio": "Áudio em Streaming",
98
+ "Streaming Generate": "Geração em Streaming",
99
+ "Tensorboard Host": "Host do Tensorboard",
100
+ "Tensorboard Log Path": "Caminho de Log do Tensorboard",
101
+ "Tensorboard Port": "Porta do Tensorboard",
102
+ "Tensorboard interface is closed": "A interface do Tensorboard está fechada",
103
+ "Tensorboard interface is launched at {}": "A interface do Tensorboard foi iniciada em {}",
104
+ "Text Normalization": "Normalização de Texto",
105
+ "Text is too long, please keep it under {} characters.": "O texto é muito longo. Mantenha-o com menos de {} caracteres.",
106
+ "The lower the quantitative precision, the more the effectiveness may decrease, but the greater the efficiency will increase": "Quanto menor a precisão quantitativa, mais a eficácia pode diminuir, mas maior será o aumento da eficiência",
107
+ "The path of the input folder on the left or the filelist. Whether checked or not, it will be used for subsequent training in this list.": "O caminho da pasta de entrada à esquerda ou a lista de arquivos. Independentemente de estar marcada ou não, ela será utilizada para o treinamento subsequente nesta lista.",
108
+ "Training Configuration": "Configuração de Treinamento",
109
+ "Training Error": "Erro de Treinamento",
110
+ "Training stopped": "Treinamento interrompido!",
111
+ "Type the path or select from the dropdown": "Digite o caminho ou selecione no menu suspenso",
112
+ "Use LoRA": "Usar LoRA",
113
+ "Use LoRA can save GPU memory, but may reduce the quality of the model": "O uso de LoRAs pode economizar memória da GPU, mas também pode reduzir a qualidade",
114
+ "Use filelist": "Usar lista de arquivos",
115
+ "VQGAN Configuration": "Configuração do VQGAN",
116
+ "View the status of the preprocessing folder (use the slider to control the depth of the tree)": "Visualizar o status da pasta de pré-processamento (use o controle deslizante para controlar a profundidade da árvore)",
117
+ "We are not responsible for any misuse of the model, please consider your local laws and regulations before using it.": "Não nos responsabilizamos por qualquer uso indevido do modelo. Por favor, considere as leis e regulamentações locais antes de usá-lo.",
118
+ "WebUI Host": "Host da WebUI",
119
+ "WebUI Port": "Porta da WebUI",
120
+ "Whisper Model": "Modelo Whisper",
121
+ "You can find the source code [here](https://github.com/fishaudio/fish-speech) and models [here](https://huggingface.co/fishaudio/fish-speech-1.5).": "Você pode encontrar o código fonte [aqui](https://github.com/fishaudio/fish-speech) e os modelos [aqui](https://huggingface.co/fishaudio/fish-speech-1.5).",
122
+ "auto": "automático",
123
+ "bf16-true is recommended for 30+ series GPU, 16-mixed is recommended for 10+ series GPU": "bf16-true é recomendado para GPUs da série 30+, 16-mixed é recomendado para GPUs da série 10+",
124
+ "latest": "mais recente",
125
+ "new": "novo",
126
+ "This audio introduces the basic concepts and applications of artificial intelligence and machine learning.": "Este áudio introduz os conceitos básicos e aplicações de inteligência artificial e aprendizado de máquina.",
127
+ "You don't need to train this model!": "Não é necessário treinar este modelo!",
128
+ "Yes": "Sim",
129
+ "No": "Não",
130
+ "version:": "versão:",
131
+ "author:": "autor:"
132
+ }
vendor/fish-speech/fish_speech/i18n/locale/zh_CN.json ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "16-mixed is recommended for 10+ series GPU": "10+ 系列 GPU 建议使用 16-mixed",
3
+ "5 to 10 seconds of reference audio, useful for specifying speaker.": "5 到 10 秒的参考音频,适用于指定音色。",
4
+ "A text-to-speech model based on VQ-GAN and Llama developed by [Fish Audio](https://fish.audio).": "由 [Fish Audio](https://fish.audio) 研发的基于 VQ-GAN 和 Llama 的多语种语音合成.",
5
+ "Accumulate Gradient Batches": "梯度累积批次",
6
+ "Add to Processing Area": "加入处理区",
7
+ "Added path successfully!": "添加路径成功!",
8
+ "Advanced Config": "高级参数",
9
+ "Base LLAMA Model": "基础 LLAMA 模型",
10
+ "Batch Inference": "批量推理",
11
+ "Batch Size": "批次大小",
12
+ "Changing with the Model Path": "随模型路径变化",
13
+ "Chinese": "中文",
14
+ "Compile Model": "编译模型",
15
+ "Compile the model can significantly reduce the inference time, but will increase cold start time": "编译模型可以显著减少推理时间,但会增加冷启动时间",
16
+ "Copy": "复制",
17
+ "Data Preprocessing": "数据预处理",
18
+ "Data Preprocessing Path": "数据预处理路径",
19
+ "Data Source": "数据源",
20
+ "Decoder Model Config": "解码器模型配置",
21
+ "Decoder Model Path": "解码器模型路径",
22
+ "Disabled": "禁用",
23
+ "Enable Reference Audio": "启用参考音频",
24
+ "English": "英文",
25
+ "Error Message": "错误信息",
26
+ "File Preprocessing": "文件预处理",
27
+ "Generate": "生成",
28
+ "Generated Audio": "音频",
29
+ "If there is no corresponding text for the audio, apply ASR for assistance, support .txt or .lab format": "如果音频没有对应的文本,可以应用 ASR 辅助,支持 .txt 或 .lab 格式",
30
+ "Infer interface is closed": "推理界面已关闭",
31
+ "Inference Configuration": "推理配置",
32
+ "Inference Server Configuration": "推理服务器配置",
33
+ "Inference Server Error": "推理服务器错误",
34
+ "Inferring interface is launched at {}": "推理界面已在 {} 上启动",
35
+ "Initial Learning Rate": "初始学习率",
36
+ "Input Audio & Source Path for Transcription": "输入音频和转录源路径",
37
+ "Input Text": "输入文本",
38
+ "Invalid path: {}": "无效路径: {}",
39
+ "It is recommended to use CUDA, if you have low configuration, use CPU": "建议使用 CUDA,如果配置较低,使用 CPU",
40
+ "Iterative Prompt Length, 0 means off": "迭代提示长度,0 表示关闭",
41
+ "Japanese": "日文",
42
+ "LLAMA Configuration": "LLAMA 配置",
43
+ "LLAMA Model Config": "LLAMA 模型配置",
44
+ "LLAMA Model Path": "LLAMA 模型路径",
45
+ "Labeling Device": "标注加速设备",
46
+ "LoRA Model to be merged": "要合并的 LoRA 模型",
47
+ "Maximum Audio Duration": "最大音频时长",
48
+ "Maximum Length per Sample": "每个样本的最大长度",
49
+ "Maximum Training Steps": "最大训练步数",
50
+ "Maximum tokens per batch, 0 means no limit": "每批最大令牌数,0 表示无限制",
51
+ "Merge": "合并",
52
+ "Merge LoRA": "合并 LoRA",
53
+ "Merge successfully": "合并成功",
54
+ "Minimum Audio Duration": "最小音频时长",
55
+ "Model Output Path": "模型输出路径",
56
+ "Model Size": "模型规模",
57
+ "Move": "移动",
58
+ "Move files successfully": "移动文件成功",
59
+ "No audio generated, please check the input text.": "没有生成音频,请检查输入文本.",
60
+ "No selected options": "没有选择的选项",
61
+ "Number of Workers": "数据加载进程数",
62
+ "Open Inference Server": "打开推理服务器",
63
+ "Open Labeler WebUI": "打开标注工具",
64
+ "Open Tensorboard": "打开 Tensorboard",
65
+ "Opened labeler in browser": "在浏览器中打开标注工具",
66
+ "Optional Label Language": "[可选] 标注语言",
67
+ "Optional online ver": "[可选] 使用在线版",
68
+ "Output Path": "输出路径",
69
+ "Path error, please check the model file exists in the corresponding path": "路径错误,请检查模型文件是否存在于相应路径",
70
+ "Precision": "精度",
71
+ "Probability of applying Speaker Condition": "应用说话人条件的概率",
72
+ "Put your text here.": "在此处输入文本.",
73
+ "Reference Audio": "参考音频",
74
+ "Reference Text": "参考文本",
75
+ "Related code and weights are released under FISH AUDIO RESEARCH LICENSE.": "相关代码和权重使用 FISH AUDIO RESEARCH LICENSE 许可证发布.",
76
+ "Remove Selected Data": "移除选中数据",
77
+ "Removed path successfully!": "移除路径成功!",
78
+ "Repetition Penalty": "重复惩罚",
79
+ "Save model every n steps": "每 n 步保存模型",
80
+ "Select LLAMA ckpt": "选择 LLAMA 检查点",
81
+ "Select VITS ckpt": "选择 VITS 检查点",
82
+ "Select VQGAN ckpt": "选择 VQGAN 检查点",
83
+ "Select source file processing method": "选择源文件处理方法",
84
+ "Select the model to be trained (Depending on the Tab page you are on)": "根据您所在的选项卡页面选择要训练的模型",
85
+ "Selected: {}": "已选择: {}",
86
+ "Speaker": "说话人",
87
+ "Speaker is identified by the folder name": "自动根据父目录名称识别说话人",
88
+ "Start Training": "开���训练",
89
+ "Streaming Audio": "流式音频",
90
+ "Streaming Generate": "流式合成",
91
+ "Tensorboard Host": "Tensorboard 监听地址",
92
+ "Tensorboard Log Path": "Tensorboard 日志路径",
93
+ "Tensorboard Port": "Tensorboard 端口",
94
+ "Tensorboard interface is closed": "Tensorboard 界面已关闭",
95
+ "Tensorboard interface is launched at {}": "Tensorboard 界面已在 {} 上启动",
96
+ "Text is too long, please keep it under {} characters.": "文本太长,请保持在 {} 个字符以内.",
97
+ "The path of the input folder on the left or the filelist. Whether checked or not, it will be used for subsequent training in this list.": "左侧输入文件夹的路径或文件列表。无论是否选中,都将在此列表中用于后续训练.",
98
+ "Training Configuration": "训练配置",
99
+ "Training Error": "训练错误",
100
+ "Training stopped": "训练已停止",
101
+ "Type name of the speaker": "输入说话人的名称",
102
+ "Type the path or select from the dropdown": "输入路径或从下拉菜单中选择",
103
+ "Use LoRA": "使用 LoRA",
104
+ "Use LoRA can save GPU memory, but may reduce the quality of the model": "使用 LoRA 可以节省 GPU 内存,但可能会降低模型质量",
105
+ "Use filelist": "使用文件列表",
106
+ "Use large for 10G+ GPU, medium for 5G, small for 2G": "10G+ GPU 使用 large, 5G 使用 medium, 2G 使用 small",
107
+ "VITS Configuration": "VITS 配置",
108
+ "VQGAN Configuration": "VQGAN 配置",
109
+ "Validation Batch Size": "验证批次大小",
110
+ "View the status of the preprocessing folder (use the slider to control the depth of the tree)": "查看预处理文件夹的状态 (使用滑块控制树的深度)",
111
+ "We are not responsible for any misuse of the model, please consider your local laws and regulations before using it.": "我们不对模型的任何滥用负责,请在使用之前考虑您当地的法律法规.",
112
+ "WebUI Host": "WebUI 监听地址",
113
+ "WebUI Port": "WebUI 端口",
114
+ "Whisper Model": "Whisper 模型",
115
+ "You can find the source code [here](https://github.com/fishaudio/fish-speech) and models [here](https://huggingface.co/fishaudio/fish-speech-1.5).": "你可以在 [这里](https://github.com/fishaudio/fish-speech) 找到源代码和 [这里](https://huggingface.co/fishaudio/fish-speech-1.5) 找到模型.",
116
+ "bf16-true is recommended for 30+ series GPU, 16-mixed is recommended for 10+ series GPU": "30+ 系列 GPU 建议使用 bf16-true, 10+ 系列 GPU 建议使用 16-mixed",
117
+ "latest": "最近的检查点",
118
+ "new": "创建新的检查点",
119
+ "Realtime Transform Text": "实时规范化文本",
120
+ "Normalization Result Preview (Currently Only Chinese)": "规范化结果预览",
121
+ "Text Normalization": "文本规范化",
122
+ "Select Example Audio": "选择参考音频"
123
+ }
vendor/fish-speech/fish_speech/i18n/scan.py ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import ast
2
+ import glob
3
+ import json
4
+ from collections import OrderedDict
5
+ from pathlib import Path
6
+
7
+ from loguru import logger
8
+
9
+ from .core import DEFAULT_LANGUAGE, I18N_FILE_PATH
10
+
11
+
12
+ def extract_i18n_strings(node):
13
+ i18n_strings = []
14
+
15
+ if (
16
+ isinstance(node, ast.Call)
17
+ and isinstance(node.func, ast.Name)
18
+ and node.func.id == "i18n"
19
+ ):
20
+ for arg in node.args:
21
+ if isinstance(arg, ast.Str):
22
+ i18n_strings.append(arg.s)
23
+
24
+ for child_node in ast.iter_child_nodes(node):
25
+ i18n_strings.extend(extract_i18n_strings(child_node))
26
+
27
+ return i18n_strings
28
+
29
+
30
+ # scan the directory for all .py files (recursively)
31
+ # for each file, parse the code into an AST
32
+ # for each AST, extract the i18n strings
33
+
34
+ strings = []
35
+ folders = ["fish_speech", "tools"]
36
+ # for filename in glob.iglob("**/*.py", recursive=True):
37
+ for folder in folders:
38
+ for f in Path(folder).rglob("*.py"):
39
+ code = f.read_text(encoding="utf-8")
40
+ if "i18n(" in code:
41
+ tree = ast.parse(code)
42
+ i18n_strings = extract_i18n_strings(tree)
43
+ logger.info(f"Found {len(i18n_strings)} i18n strings in {f}")
44
+ strings.extend(i18n_strings)
45
+
46
+ code_keys = set(strings)
47
+ logger.info(f"Total unique: {len(code_keys)}")
48
+
49
+
50
+ standard_file = I18N_FILE_PATH / f"{DEFAULT_LANGUAGE}.json"
51
+ with open(standard_file, "r", encoding="utf-8") as f:
52
+ standard_data = json.load(f, object_pairs_hook=OrderedDict)
53
+ standard_keys = set(standard_data.keys())
54
+
55
+ # Define the standard file name
56
+ unused_keys = standard_keys - code_keys
57
+ logger.info(f"Found {len(unused_keys)} unused keys in {standard_file}")
58
+ for unused_key in unused_keys:
59
+ logger.info(f"\t{unused_key}")
60
+
61
+ missing_keys = code_keys - standard_keys
62
+ logger.info(f"Found {len(missing_keys)} missing keys in {standard_file}")
63
+ for missing_key in missing_keys:
64
+ logger.info(f"\t{missing_key}")
65
+
66
+ code_keys_dict = OrderedDict()
67
+ for s in strings:
68
+ code_keys_dict[s] = s
69
+
70
+ # write back
71
+ with open(standard_file, "w", encoding="utf-8") as f:
72
+ json.dump(code_keys_dict, f, ensure_ascii=False, indent=4, sort_keys=True)
73
+ f.write("\n")
74
+
75
+ logger.info(f"Updated {standard_file}")
76
+
77
+
78
+ # Define the standard file name
79
+ standard_file = I18N_FILE_PATH / f"{DEFAULT_LANGUAGE}.json"
80
+
81
+ # Find all JSON files in the directory
82
+ dir_path = I18N_FILE_PATH
83
+ languages = [f for f in dir_path.glob("*.json") if f.stem != DEFAULT_LANGUAGE]
84
+
85
+ # Load the standard file
86
+ with open(standard_file, "r", encoding="utf-8") as f:
87
+ standard_data = json.load(f, object_pairs_hook=OrderedDict)
88
+
89
+ # Loop through each language file
90
+ for lang_file in languages:
91
+ # Load the language file
92
+ with open(lang_file, "r", encoding="utf-8") as f:
93
+ lang_data = json.load(f, object_pairs_hook=OrderedDict)
94
+
95
+ # Find the difference between the language file and the standard file
96
+ diff = set(standard_data.keys()) - set(lang_data.keys())
97
+
98
+ miss = set(lang_data.keys()) - set(standard_data.keys())
99
+
100
+ # Add any missing keys to the language file
101
+ for key in diff:
102
+ lang_data[key] = "#!" + key
103
+ logger.info(f"Added missing key: {key} to {lang_file}")
104
+
105
+ # Del any extra keys to the language file
106
+ for key in miss:
107
+ del lang_data[key]
108
+ logger.info(f"Del extra key: {key} from {lang_file}")
109
+
110
+ # Sort the keys of the language file to match the order of the standard file
111
+ lang_data = OrderedDict(
112
+ sorted(lang_data.items(), key=lambda x: list(standard_data.keys()).index(x[0]))
113
+ )
114
+
115
+ # Save the updated language file
116
+ with open(lang_file, "w", encoding="utf-8") as f:
117
+ json.dump(lang_data, f, ensure_ascii=False, indent=4, sort_keys=True)
118
+ f.write("\n")
119
+
120
+ logger.info(f"Updated {lang_file}")
121
+
122
+ logger.info("Done")
vendor/fish-speech/fish_speech/inference_engine/__init__.py ADDED
@@ -0,0 +1,192 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gc
2
+ import queue
3
+ from typing import Generator
4
+
5
+ import numpy as np
6
+ import torch
7
+ from loguru import logger
8
+
9
+ from fish_speech.inference_engine.reference_loader import ReferenceLoader
10
+ from fish_speech.inference_engine.utils import InferenceResult, wav_chunk_header
11
+ from fish_speech.inference_engine.vq_manager import VQManager
12
+ from fish_speech.models.dac.modded_dac import DAC
13
+ from fish_speech.models.text2semantic.inference import (
14
+ GenerateRequest,
15
+ GenerateResponse,
16
+ WrappedGenerateResponse,
17
+ )
18
+ from fish_speech.utils import autocast_exclude_mps, set_seed
19
+ from fish_speech.utils.schema import ServeTTSRequest
20
+
21
+
22
+ class TTSInferenceEngine(ReferenceLoader, VQManager):
23
+
24
+ def __init__(
25
+ self,
26
+ llama_queue: queue.Queue,
27
+ decoder_model: DAC,
28
+ precision: torch.dtype,
29
+ compile: bool,
30
+ ) -> None:
31
+
32
+ super().__init__()
33
+
34
+ self.llama_queue = llama_queue
35
+ self.decoder_model = decoder_model
36
+ self.precision = precision
37
+ self.compile = compile
38
+
39
+ @torch.inference_mode()
40
+ def inference(self, req: ServeTTSRequest) -> Generator[InferenceResult, None, None]:
41
+ """
42
+ Main inference function:
43
+ - Loads the reference audio and text.
44
+ - Calls the LLAMA model for inference.
45
+ - Decodes the VQ tokens to audio.
46
+ """
47
+
48
+ ref_id: str | None = req.reference_id
49
+ prompt_tokens, prompt_texts = [], []
50
+ # Load the reference audio and text based on id or hash
51
+ if ref_id is not None:
52
+ prompt_tokens, prompt_texts = self.load_by_id(ref_id, req.use_memory_cache)
53
+
54
+ elif req.references:
55
+ prompt_tokens, prompt_texts = self.load_by_hash(
56
+ req.references, req.use_memory_cache
57
+ )
58
+
59
+ # Set the random seed if provided
60
+ if req.seed is not None:
61
+ set_seed(req.seed)
62
+ logger.warning(f"set seed: {req.seed}")
63
+
64
+ # Get the symbolic tokens from the LLAMA model
65
+ response_queue = self.send_Llama_request(req, prompt_tokens, prompt_texts)
66
+
67
+ # Get the sample rate from the decoder model
68
+ if hasattr(self.decoder_model, "spec_transform"):
69
+ sample_rate = self.decoder_model.spec_transform.sample_rate
70
+ else:
71
+ sample_rate = self.decoder_model.sample_rate
72
+
73
+ # If streaming, send the header
74
+ if req.streaming:
75
+ yield InferenceResult(
76
+ code="header",
77
+ audio=(
78
+ sample_rate,
79
+ np.array(wav_chunk_header(sample_rate=sample_rate)),
80
+ ),
81
+ error=None,
82
+ )
83
+
84
+ segments = []
85
+
86
+ while True:
87
+ # Get the response from the LLAMA model
88
+ wrapped_result: WrappedGenerateResponse = response_queue.get()
89
+ if wrapped_result.status == "error":
90
+ yield InferenceResult(
91
+ code="error",
92
+ audio=None,
93
+ error=(
94
+ wrapped_result.response
95
+ if isinstance(wrapped_result.response, Exception)
96
+ else Exception("Unknown error")
97
+ ),
98
+ )
99
+ break
100
+
101
+ # Check the response type
102
+ if not isinstance(wrapped_result.response, GenerateResponse):
103
+ raise TypeError(
104
+ f"Expected GenerateResponse, got {type(wrapped_result.response).__name__}"
105
+ )
106
+
107
+ result: GenerateResponse = wrapped_result.response
108
+ if result.action != "next":
109
+ segment = self.get_audio_segment(result)
110
+
111
+ if req.streaming: # Used only by the API server
112
+ yield InferenceResult(
113
+ code="segment",
114
+ audio=(sample_rate, segment),
115
+ error=None,
116
+ )
117
+ segments.append(segment)
118
+ else:
119
+ break
120
+
121
+ # Clean up the memory
122
+ if torch.cuda.is_available():
123
+ torch.cuda.empty_cache()
124
+ gc.collect()
125
+
126
+ # Edge case: no audio generated
127
+ if len(segments) == 0:
128
+ yield InferenceResult(
129
+ code="error",
130
+ audio=None,
131
+ error=RuntimeError("No audio generated, please check the input text."),
132
+ )
133
+ else:
134
+ # Streaming or not, return the final audio
135
+ audio = np.concatenate(segments, axis=0)
136
+ yield InferenceResult(
137
+ code="final",
138
+ audio=(sample_rate, audio),
139
+ error=None,
140
+ )
141
+
142
+ return None
143
+
144
+ def send_Llama_request(
145
+ self, req: ServeTTSRequest, prompt_tokens: list, prompt_texts: list
146
+ ) -> queue.Queue:
147
+ """
148
+ Send a request to the LLAMA model to generate the symbolic tokens.
149
+ """
150
+
151
+ # Prepare the request
152
+ request = dict(
153
+ device=self.decoder_model.device,
154
+ max_new_tokens=req.max_new_tokens,
155
+ text=req.text,
156
+ top_p=req.top_p,
157
+ repetition_penalty=req.repetition_penalty,
158
+ temperature=req.temperature,
159
+ compile=self.compile,
160
+ iterative_prompt=req.chunk_length > 0,
161
+ chunk_length=req.chunk_length,
162
+ prompt_tokens=prompt_tokens,
163
+ prompt_text=prompt_texts,
164
+ )
165
+
166
+ # Create a queue to get the response
167
+ response_queue = queue.Queue()
168
+
169
+ # Send the request to the LLAMA model
170
+ self.llama_queue.put(
171
+ GenerateRequest(
172
+ request=request,
173
+ response_queue=response_queue,
174
+ )
175
+ )
176
+
177
+ return response_queue
178
+
179
+ def get_audio_segment(self, result: GenerateResponse) -> np.ndarray:
180
+ """
181
+ Decode the VQ tokens to audio.
182
+ """
183
+
184
+ # Don't use autocast on MPS devices
185
+ with autocast_exclude_mps(
186
+ device_type=self.decoder_model.device.type, dtype=self.precision
187
+ ):
188
+ # Decode the symbolic tokens to audio
189
+ segment = self.decode_vq_tokens(codes=result.codes)
190
+
191
+ # Convert the audio to numpy
192
+ return segment.float().cpu().numpy()