Skip to content

Commit 8b1a49f

Browse files
committed
Fix audio return format in multi-style generation and add bash test script for basic TTS
1 parent 7ad085d commit 8b1a49f

File tree

3 files changed

+271
-1
lines changed

3 files changed

+271
-1
lines changed

src/f5_tts/infer/API_info.MD

Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
# E2/F5‑TTS REST API – Részletes használati útmutató
2+
3+
*Utolsó frissítés: 2025‑06‑13*
4+
5+
---
6+
7+
## Tartalomjegyzék
8+
9+
1. [Bevezetés](#bevezetés)
10+
2. [Gyors indulás](#gyors-indulás)
11+
3. [Alapfogalmak](#alapfogalmak)
12+
4. [Az API alap URL‑sémája](#az-api-alap-url-sémája)
13+
5. [Végpontok áttekintése](#végpontok-áttekintése)
14+
6. [Kérés felépítése](#kérés-felépítése)
15+
7. [Válasz felépítése](#válasz-felépítése)
16+
8. [Példák](#példák)
17+
18+
* 8.1. [`basic_tts`](#81-basic_tts) – egyszerű TTS
19+
* 8.2. [`generate_multistyle_speech`](#82-generate_multistyle_speech) – több hangstílus
20+
* 8.3. [`switch_tts_model` és `set_custom_model`](#83-model-váltás)
21+
* 8.4. Python – `gradio_client`-tel
22+
9. [Hibakezelés](#hibakezelés)
23+
10. [Legjobb gyakorlatok](#legjobb-gyakorlatok)
24+
11. [Függelék A – `/config` és `components`](#függelék-a)
25+
26+
---
27+
28+
## Bevezetés
29+
30+
Ez a dokumentum leírja, hogyan használhatod **REST kérésekkel** a Gradio‑alapú E2/F5‑TTS web UI összes fontos funkcióját (modellváltás, szöveg‑felolvasás, multistílusú TTS, chat TTS). A szerver FastAPI‑t használ, de a Gradio 4.x‑től kezdve minden Gradio‑s végpont a **`/gradio_api/…`** útvonal alá kerül.
31+
32+
> **Fontos:** nincs hagyományos `/docs` vagy numerikus `/api/predict/7`; helyette név‑alapú `api_name`‑eket találsz.
33+
34+
---
35+
36+
## Gyors indulás
37+
38+
```bash
39+
# 1 – indítsd a szervert (API alapból engedélyezett)
40+
python app.py -p 7860 --share # vagy saját flagjeid
41+
42+
# 2 – ellenőrizd, hogy fut-e
43+
curl http://localhost:7860/gradio_api/openapi.json | jq .info
44+
45+
# 3 – listázd a végpontokat és input‑indexeket
46+
curl http://localhost:7860/config | jq '.dependencies[] | {api_name, inputs}'
47+
```
48+
49+
---
50+
51+
## Alapfogalmak
52+
53+
| Fogalom | Magyarázat |
54+
| ------------------- | ------------------------------------------------------------------------------------------------------ |
55+
| **api\_name** | A callback beszédes neve (pl. `basic_tts`). Ez lesz az URL‑ben. |
56+
| **input‑komponens** | Minden UI elem egy számmal azonosítva (pl. `1725`). A sorrend a `.click(inputs=[…])` listával egyezik. |
57+
| **`data[]`** | Kérésnél: értékek listája **ugyanabban a sorrendben**, mint az `inputs=[…]`. |
58+
| **session\_hash** | Tetszőleges string, egy munkamenet azonosítására. Ha sorban több hívást küldesz, használd ugyanazt. |
59+
60+
---
61+
62+
## Az API alap URL‑sémája
63+
64+
```
65+
POST http(s)://<host>:<port>/gradio_api/call/<api_name>
66+
```
67+
68+
* Minden hívás **POST**.
69+
* `Content‑Type: application/json`.
70+
* A törzs két mezőt tartalmaz:
71+
72+
```json
73+
{
74+
"data": [ /* komponensek sorban */ ],
75+
"session_hash": "<bármi_azonosító>"
76+
}
77+
```
78+
79+
---
80+
81+
## Végpontok áttekintése
82+
83+
| api\_name | Funkció | Inputs (darab) | Megjegyzés |
84+
| ---------------------------- | ------------------------------------------------------- | -------------- | ----------------------------------------- |
85+
| `switch_tts_model` | Modellválasztó rádiógomb | 1 | `"F5-TTS_v1"`, `"E2-TTS"` vagy `"Custom"` |
86+
| `set_custom_model` | Egyéni modell 3 paramétere | 3 | ckpt útvonal, vocab útvonal, JSON cfg |
87+
| `basic_tts` | Egyszerű, egyetlen hangos TTS | 10 | l. [8.1](#81-basic_tts) |
88+
| `generate_multistyle_speech` | 100 hangstílusig | 249 | l. [8.2](#82-generate_multistyle_speech) |
89+
| `load_chat_model` | Chat‑LLM betöltése | 1 | pl. `"Qwen/Qwen2.5-3B-Instruct"` |
90+
| `chat_pipeline` | Beszélgetés (ASR→LLM→TTS) | 9 | hang v. szöveg, opciók |
91+
|| további `load_text_from_file_*`, `insert_…`, `delete_…` | változó | UI‑segédek, ritkán kell REST‑ből |
92+
93+
A pontos `inputs` listát mindig nézd meg a `/config` JSON‑ban.
94+
95+
---
96+
97+
## Kérés felépítése
98+
99+
```json
100+
{
101+
"data": [ <input_1>, <input_2>, … , <input_N> ],
102+
"session_hash": "egyedi_hex_vagy_uuid"
103+
}
104+
```
105+
106+
* **Típusok**
107+
108+
* *Fájlnál* – `null` ↔ nincs fájl, vagy **feltöltött URL** (pl. `"file=uploads%2Fabc.wav"`).
109+
* *Bool*`true` / `false`.
110+
* *Audio‑/kép‑output* → base64 URL‑data formátumban érkezik.
111+
112+
---
113+
114+
## Válasz felépítése
115+
116+
```json
117+
{
118+
"data": [ /* callback return értékei */ ],
119+
"is_generating": false,
120+
"duration": 3.18
121+
}
122+
```
123+
124+
* **Audio**`["audio", "data:audio/wav;base64,UklGR…"]`
125+
* **Kép**`"data:image/png;base64,iVBOR…"`
126+
127+
---
128+
129+
## Példák
130+
131+
### 8.1 `basic_tts`
132+
133+
```bash
134+
curl -X POST http://localhost:7860/gradio_api/call/basic_tts \
135+
-H "Content-Type: application/json" \
136+
-d '{
137+
"data": [
138+
null, "", "Hello from API", # 0‑2
139+
false, true, 0, # 3‑5
140+
0.15, 32, 1.0, # 6‑8
141+
"None" # 9
142+
],
143+
"session_hash": "tts_demo"
144+
}' | jq '.data[0]'
145+
```
146+
147+
*Az első elem (`data[0]`) az audio WAV base64‑el; mentheted fájlba.*
148+
149+
### 8.2 `generate_multistyle_speech`
150+
151+
1 kötelező hangstílus (név + audio), minden más `null`/"":
152+
153+
```python
154+
from gradio_client import Client
155+
client = Client("http://localhost:7860")
156+
157+
# adatok összeépítése
158+
payload = [
159+
'{"name":"Narrator"} Once upon a time…', # gen_text_input_multistyle
160+
"Narrator", "file=uploads%2Fvoice.wav", "", # 1. típus (név, audio, ref_text)
161+
] + [None]*297 + [True, "hun"] # üres helyek + globális opciók
162+
163+
wav, *_, meta = client.predict(*payload, api_name="/generate_multistyle_speech")
164+
```
165+
166+
### 8.3 Modell váltása
167+
168+
```bash
169+
# F5 → E2
170+
curl -X POST http://localhost:7860/gradio_api/call/switch_tts_model \
171+
-H "Content-Type: application/json" \
172+
-d '{"data":["E2-TTS"], "session_hash":"model"}'
173+
```
174+
175+
### 8.4 Python példa `gradio_client`-tel
176+
177+
```python
178+
from gradio_client import Client
179+
client = Client("http://localhost:7860")
180+
wav, spec, _, _ = client.predict(
181+
None, "", "Szia világ!", False, True, 0, 0.15, 32, 1.0, "hun",
182+
api_name="/basic_tts")
183+
open("out.wav", "wb").write(wav[1].split(",",1)[1].encode())
184+
```
185+
186+
---
187+
188+
## Hibakezelés
189+
190+
| HTTP kód | Jelentés | Tipikus ok |
191+
| --------- | ------------------------ | -------------------------------------------------- |
192+
| 400 / 422 | Szintaxis vagy típushiba | JSON rossz, `data` méret/típus nem stimmel |
193+
| 404 | Nincs ilyen `api_name` | Elírt URL vagy nincs API engedélyezve (`--no-api`) |
194+
| 500 | Belső kivétel | Modell‑ vagy CUDA‑hiba, hiányzó file |
195+
196+
A válasz `detail` mezője részletesen kiírja, hogy *Expected X inputs, received Y* stb.
197+
198+
---
199+
200+
## Legjobb gyakorlatok
201+
202+
* Használd a **`gradio_client`** könyvtárat, ha Pythonból hívod → nem kell manuálisan buildelni a `data` listát.
203+
* Több kérésnél reutilizáld a **`session_hash`**‑t → gyorsabb load, stabil queue.
204+
* **`null`** minden nem kötelező fájlhelyen; ne üres string.
205+
* Hosszú hívásoknál (TTS > 30 s) számíts sorban állásra (`queue_join`).
206+
* Base64‑es audio nagy; ha csak tesztelsz, küldj `Accept: application/json`‑t (ez az alap).
207+
208+
---
209+
210+
## Függelék A – `/config` és `components`
211+
212+
A `GET /config` válasza:
213+
214+
```json
215+
{
216+
"version": "4.24.0",
217+
"mode": "grpc",
218+
"components": { "4": {"type":"file", "label":"Reference Audio"}, },
219+
"dependencies": [
220+
{ "api_name": "basic_tts", "inputs": [4,1725,6,] },
221+
222+
]
223+
}
224+
```
225+
226+
* A `components` szekcióban látszik, milyen **típus** (`file`, `textbox`, `slider`, …).
227+
* A `dependencies[*].inputs` lista **sorrendje** → ez határozza meg a `data[]` sorrendet.
228+
229+
---
230+
231+
**Ennyi!** Ezzel a leírással önállóan is tudod scriptből vezérelni a TTS‑szervert, modellváltástól a multistílusú hangszintézisig.
232+

src/f5_tts/infer/bash_test.sh

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
REF=${1:-ref.wav} # 1. arg: referencia WAV
5+
TXT=${2:-"Hello from Bash queue!"} # 2. arg: felolvasandó szöveg
6+
HOST=${3:-"localhost:7860"} # 3. arg: host:port
7+
API="http://${HOST}"
8+
SESSION="bash_$$"
9+
10+
[[ -f "$REF" ]] || { echo "❌ nincs ilyen fájl: $REF"; exit 1; }
11+
12+
# 1) WAV feltöltése (kulcs: files!)
13+
TOKEN=$(curl -s -F "files=@${REF}" "$API/gradio_api/upload" | jq -r '.[0]')
14+
[[ -n "$TOKEN" && "$TOKEN" != "null" ]] || { echo "❌ feltöltési hiba"; exit 1; }
15+
16+
# 2) JSON body (10 input a basic_tts-hez)
17+
BODY=$(jq -n --arg file "$TOKEN" --arg txt "$TXT" --arg sid "$SESSION" '
18+
{data:[$file,"",$txt,false,true,0,0.15,32,1.0,"None"], session_hash:$sid}')
19+
20+
# 3) Szinkron hívás a queue ellenére (`simple_format=true`)
21+
echo "▶️ /call/basic_tts?simple_format=true"
22+
RESP=$(curl -sS -H 'Content-Type: application/json' -d "$BODY" \
23+
-X POST "$API/gradio_api/call/basic_tts?simple_format=true")
24+
25+
# 4) Base64 WAV kinyerése
26+
B64=$(echo "$RESP" | jq -r '.data[0][1]?' | cut -d, -f2)
27+
[[ -z "$B64" || "$B64" == "null" ]] && { echo "❌ nincs audio"; echo "$RESP"|jq .; exit 1; }
28+
29+
OUT="tts_$(date +%s).wav"
30+
echo "$B64" | base64 -d > "$OUT" && echo "💾 $OUT$(du -h "$OUT"|cut -f1)"
31+
32+
# 5) Lejátszás (aplay / ffplay / afplay)
33+
play() { command -v "$1" &>/dev/null && "$@"; }
34+
play aplay -q "$OUT" && exit
35+
play ffplay -nodisp -autoexit -loglevel quiet "$OUT" && exit
36+
play afplay "$OUT" && exit
37+
echo "ℹ️ Nyisd meg kézzel a fájlt: $OUT"
38+

src/f5_tts/infer/infer_gradio.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -773,7 +773,7 @@ def generate_multistyle_speech(
773773

774774
if generated_audio_segments:
775775
final_audio_data = np.concatenate(generated_audio_segments)
776-
return (sr, final_audio_data), output_ref_texts, inference_meta_data
776+
return (sr, final_audio_data), *output_ref_texts, inference_meta_data
777777
else:
778778
gr.Warning("No audio segments were successfully generated.")
779779
return None, output_ref_texts, inference_meta_data or None

0 commit comments

Comments
 (0)