feat(talkbot): add optional llama.cpp API key and stop double-posting text after audio
This commit is contained in:
@@ -1,39 +0,0 @@
|
||||
[Unit]
|
||||
Description=Qwen3-TTS Server (CPU)
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Container]
|
||||
Image=localhost/qwen-tts:cpu
|
||||
ContainerName=qwen-tts
|
||||
|
||||
# HTTP API
|
||||
PublishPort=8000:8000
|
||||
|
||||
# Persist downloaded model weights across restarts
|
||||
# Adjust the host path to wherever you want the models cached
|
||||
Volume=/srv/containers/qwen-tts/models:/app/models:Z
|
||||
|
||||
# Which model(s) to load at startup: "customvoice", "voiceclone", or both
|
||||
# (default, comma-separated). Loading both lets a single instance serve
|
||||
# /speech (preset voices) and /speech/clone (voice cloning) at once.
|
||||
#Environment=QWEN_TTS_LOAD=customvoice,voiceclone
|
||||
# Optional: override the default checkpoints
|
||||
#Environment=QWEN_TTS_CUSTOMVOICE_MODEL=Qwen/Qwen3-TTS-12Hz-1.7B-CustomVoice
|
||||
#Environment=QWEN_TTS_VOICECLONE_MODEL=Qwen/Qwen3-TTS-12Hz-1.7B-Base
|
||||
|
||||
|
||||
# CPU-only container: no GPU devices needed
|
||||
PodmanArgs=--pids-limit=-1
|
||||
|
||||
# Resource limits (tune to your host; a 1.7B model on CPU needs headroom)
|
||||
#Memory=8g
|
||||
#CPUs=4
|
||||
|
||||
[Service]
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
TimeoutStartSec=300
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
@@ -1,83 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
BUILD_DIR="$(pwd)/qwentts-src"
|
||||
BIN_DIR="$(pwd)/bin-vulkan"
|
||||
|
||||
echo "=== Qwentts.cpp Build Script for Vulkan ==="
|
||||
echo ""
|
||||
|
||||
# Step 1: Install dependencies
|
||||
echo "[1/5] Installing build dependencies..."
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y \
|
||||
build-essential \
|
||||
cmake \
|
||||
git \
|
||||
libvulkan-dev \
|
||||
vulkan-tools \
|
||||
glslc \
|
||||
spirv-tools \
|
||||
pkg-config
|
||||
|
||||
# Step 2: Clone qwentts.cpp with submodules
|
||||
echo ""
|
||||
echo "[2/5] Cloning qwentts.cpp repository with submodules..."
|
||||
if [ -d "$BUILD_DIR" ]; then
|
||||
rm -rf "$BUILD_DIR"
|
||||
fi
|
||||
git clone --recurse-submodules https://github.com/ServeurpersoCom/qwentts.cpp "$BUILD_DIR"
|
||||
cd "$BUILD_DIR"
|
||||
|
||||
# Step 3: Build with Vulkan backend
|
||||
echo ""
|
||||
echo "[3/5] Building qwentts with Vulkan support..."
|
||||
./buildvulkan.sh
|
||||
|
||||
# Step 4: Copy binaries to bin-vulkan/
|
||||
echo ""
|
||||
echo "[4/5] Copying binaries to bin-vulkan/..."
|
||||
if [ -d "$BIN_DIR" ]; then
|
||||
rm -rf "$BIN_DIR"
|
||||
fi
|
||||
mkdir -p "$BIN_DIR"
|
||||
|
||||
# Copy executables
|
||||
cp build/qwen-tts "$BIN_DIR/"
|
||||
cp build/qwen-codec "$BIN_DIR/"
|
||||
|
||||
# Copy any shared libraries if they exist
|
||||
if [ -d "build/lib" ]; then
|
||||
cp -r build/lib "$BIN_DIR/"
|
||||
fi
|
||||
|
||||
# Step 5: Create entrypoint script
|
||||
echo ""
|
||||
echo "[5/5] Creating entrypoint script..."
|
||||
cat > "$(pwd)/../entrypoint.sh" <<'ENTRYPOINT_EOF'
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Export Vulkan driver path
|
||||
export VK_DRIVER_FILES=/usr/share/vulkan/icd.d/radeon_icd.x86_64.json
|
||||
export LD_LIBRARY_PATH=/app/lib:$LD_LIBRARY_PATH
|
||||
|
||||
# Default to help if no arguments
|
||||
if [ $# -eq 0 ]; then
|
||||
/app/bin/qwen-tts --help
|
||||
else
|
||||
exec "$@"
|
||||
fi
|
||||
ENTRYPOINT_EOF
|
||||
|
||||
chmod +x "$(pwd)/../entrypoint.sh"
|
||||
|
||||
echo ""
|
||||
echo "=== Build Complete ==="
|
||||
echo "Binaries are in: $BIN_DIR"
|
||||
echo "Models should be placed in: $(pwd)/../models/"
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo "1. Download models: https://huggingface.co/Serveurperso/Qwen3-TTS-GGUF"
|
||||
echo "2. Build Podman image: podman build -t qwentts:vulkan-amd64 -f qwentts-vulkan.Containerfile ."
|
||||
echo "3. Test: podman run --rm qwentts:vulkan-amd64"
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
# Qwen3-TTS entrypoint script
|
||||
# Qwen3 TTS entrypoint script
|
||||
# Starts the FastAPI server; model weights are downloaded automatically
|
||||
# on first request via from_pretrained() and cached under /app/models
|
||||
set -e
|
||||
@@ -1,31 +0,0 @@
|
||||
FROM debian:13-slim
|
||||
|
||||
# Install Vulkan runtime libraries
|
||||
RUN apt-get update && apt-get install -y \
|
||||
libvulkan1 \
|
||||
vulkan-tools \
|
||||
mesa-vulkan-drivers \
|
||||
libdrm-amdgpu1 \
|
||||
ca-certificates \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Create app directory
|
||||
WORKDIR /app
|
||||
|
||||
# Copy pre-compiled binaries and models
|
||||
COPY bin-vulkan/ /app/bin/
|
||||
COPY entrypoint.sh /app/
|
||||
|
||||
# Create directories for models and output
|
||||
RUN mkdir -p /app/models /app/output
|
||||
|
||||
# Set library path for Vulkan
|
||||
ENV LD_LIBRARY_PATH=/app/lib:$LD_LIBRARY_PATH
|
||||
ENV VK_DRIVER_FILES=/usr/share/vulkan/icd.d/radeon_icd.x86_64.json
|
||||
|
||||
# Expose port for API server (if used)
|
||||
EXPOSE 8080
|
||||
|
||||
# Default command
|
||||
ENTRYPOINT ["/app/entrypoint.sh"]
|
||||
CMD ["--help"]
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
### Qwen3-TTS Container - CPU only
|
||||
### Qwen3 TTS Container
|
||||
### Text-to-Speech using Qwen3-TTS: https://github.com/QwenLM/Qwen3-TTS
|
||||
###
|
||||
### BUILD: podman build -t qwen-tts:cpu -f qwen-tts-cpu.Containerfile .
|
||||
### RUN: podman run --rm -p 8000:8000 -v /path/to/models:/app/models qwen-tts:cpu
|
||||
### BUILD: podman build -t qwentts:latest -f qwentts.Containerfile .
|
||||
### RUN: podman run --rm -p 8000:8000 -v /path/to/models:/app/models qwentts:latest
|
||||
FROM python:3.12-slim
|
||||
|
||||
USER root
|
||||
@@ -1,343 +0,0 @@
|
||||
# Qwentts - Text-to-Speech with Voice Cloning and Voice Design
|
||||
|
||||
C++17 port di Qwen3-TTS (Alibaba/Qwen team) con supporto per Text-to-Speech, voice cloning zero-shot e voice design. Supporta 10+ lingue con dialetti Mandarin e output 24 kHz mono.
|
||||
|
||||
## Requisiti
|
||||
|
||||
- Podman rootless
|
||||
- Network `internal.network` configurata
|
||||
- Nginx come reverse proxy
|
||||
- GPU AMD con Vulkan (opzionale, consigliato)
|
||||
- Spazio disco: almeno 30 GB per i modelli
|
||||
- RAM: 16+ GB per il modello 1.7B
|
||||
- Dipendenze di compilazione (cmake, git, gcc, vulkan-dev)
|
||||
|
||||
## Build Container
|
||||
|
||||
### 1. Compilare qwentts.cpp
|
||||
|
||||
```bash
|
||||
cd /home/badstorm/Source/bdi/bdi_podman_serverconf/containers/qwentts
|
||||
./build-container.sh
|
||||
```
|
||||
|
||||
Lo script:
|
||||
- Installa dipendenze (cmake, git, vulkan-dev, glslc, spirv-tools)
|
||||
- Clona qwentts.cpp con submoduli ricorsivi
|
||||
- Compila con `./buildvulkan.sh` per supporto Vulkan
|
||||
- Copia i binari (`qwen-tts`, `qwen-codec`) in `bin-vulkan/`
|
||||
- Crea l'entrypoint script
|
||||
|
||||
### 2. Buildare l'immagine Podman
|
||||
|
||||
```bash
|
||||
podman build -t qwentts:vulkan-amd64 -f qwentts-vulkan.Containerfile .
|
||||
```
|
||||
|
||||
### 3. Verificare l'immagine
|
||||
|
||||
```bash
|
||||
podman images | grep qwentts
|
||||
podman run --rm qwentts:vulkan-amd64 --help
|
||||
```
|
||||
|
||||
## Setup Runtime
|
||||
|
||||
### 1. Creare le directory di dati
|
||||
|
||||
```bash
|
||||
mkdir -p /srv/containers/qwentts/models
|
||||
mkdir -p /srv/containers/qwentts/output
|
||||
chmod 755 /srv/containers/qwentts
|
||||
chmod 755 /srv/containers/qwentts/models
|
||||
chmod 755 /srv/containers/qwentts/output
|
||||
```
|
||||
|
||||
### 2. Scaricare i modelli
|
||||
|
||||
I modelli pre-convertiti sono disponibili su Hugging Face: https://huggingface.co/Serveurperso/Qwen3-TTS-GGUF
|
||||
|
||||
Scarica almeno un modello talker e il tokenizer:
|
||||
|
||||
```bash
|
||||
cd /srv/containers/qwentts/models
|
||||
pip install huggingface-hub
|
||||
|
||||
# Download Base Model (1.7B, default voice)
|
||||
huggingface-cli download Serveurperso/Qwen3-TTS-GGUF \
|
||||
qwen-talker-1.7b-base-Q8_0.gguf \
|
||||
qwen-tokenizer-12hz-Q8_0.gguf \
|
||||
--local-dir .
|
||||
|
||||
# Optional: Download CustomVoice Model (named speakers)
|
||||
huggingface-cli download Serveurperso/Qwen3-TTS-GGUF \
|
||||
qwen-talker-1.7b-customvoice-Q8_0.gguf \
|
||||
--local-dir .
|
||||
|
||||
# Optional: Download VoiceDesign Model (voice attributes)
|
||||
huggingface-cli download Serveurperso/Qwen3-TTS-GGUF \
|
||||
qwen-talker-1.7b-voicedesign-Q8_0.gguf \
|
||||
--local-dir .
|
||||
|
||||
# Optional: Smaller 0.6B models for faster inference
|
||||
huggingface-cli download Serveurperso/Qwen3-TTS-GGUF \
|
||||
qwen-talker-0.6b-base-Q8_0.gguf \
|
||||
--local-dir .
|
||||
```
|
||||
|
||||
**Opzioni di quantizzazione disponibili:**
|
||||
- `Q8_0` - Nessuna perdita di qualità, ~50% riduzione dimensione
|
||||
- `Q4_K_M` - Quantizzazione mista, miglior rapporto qualità/dimensione
|
||||
- `F32` - Massima qualità, dimensione massima
|
||||
|
||||
### 3. Copiare il file quadlet
|
||||
|
||||
```bash
|
||||
cp qwentts.container ~/.config/containers/systemd/
|
||||
```
|
||||
|
||||
### 4. Configurare il dominio
|
||||
|
||||
Modifica il file `~/.config/containers/systemd/qwentts.container` se necessario:
|
||||
- Volumi di modelli e output
|
||||
- Limiti di memoria (attualmente 16GB)
|
||||
- Limiti CPU
|
||||
|
||||
### 5. Copiare la configurazione Nginx
|
||||
|
||||
```bash
|
||||
cp qwentts.nginx /etc/nginx/conf.d/qwentts.conf
|
||||
```
|
||||
|
||||
Modifica il file per sostituire:
|
||||
- `qwentts.example.com` con il tuo dominio reale
|
||||
- Percorsi SSL (standard Let's Encrypt)
|
||||
|
||||
### 6. Configurare SSL
|
||||
|
||||
```bash
|
||||
sudo certbot certonly --standalone -d qwentts.tuodominio.com
|
||||
```
|
||||
|
||||
### 7. Riavviare Nginx
|
||||
|
||||
```bash
|
||||
sudo systemctl reload nginx
|
||||
# oppure per container nginx:
|
||||
systemctl --user restart nginx
|
||||
```
|
||||
|
||||
### 8. Avviare Qwentts
|
||||
|
||||
```bash
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user start qwentts
|
||||
systemctl --user enable qwentts
|
||||
```
|
||||
|
||||
## Verifica
|
||||
|
||||
Controlla che il container sia in esecuzione:
|
||||
|
||||
```bash
|
||||
podman ps | grep qwentts
|
||||
podman logs qwentts
|
||||
```
|
||||
|
||||
## Utilizzo CLI
|
||||
|
||||
Qwentts fornisce due tool CLI: `qwen-tts` per la sintesi e `qwen-codec` per la gestione codec.
|
||||
|
||||
### Text-to-Speech Base (voce predefinita)
|
||||
|
||||
```bash
|
||||
echo "Hello, this is a test." | podman exec qwentts qwen-tts \
|
||||
--model /app/models/qwen-talker-1.7b-base-Q8_0.gguf \
|
||||
--codec /app/models/qwen-tokenizer-12hz-Q8_0.gguf \
|
||||
--lang English \
|
||||
-o /app/output/test.wav
|
||||
```
|
||||
|
||||
### Voice Cloning (Zero-Shot)
|
||||
|
||||
**Opzione 1: Usa WAV + Testo di riferimento**
|
||||
|
||||
```bash
|
||||
echo "I am cloning this voice." | podman exec qwentts qwen-tts \
|
||||
--model /app/models/qwen-talker-1.7b-base-Q8_0.gguf \
|
||||
--codec /app/models/qwen-tokenizer-12hz-Q8_0.gguf \
|
||||
--ref-wav /app/output/reference.wav \
|
||||
--ref-text "This is my reference voice sample" \
|
||||
--lang English \
|
||||
-o /app/output/cloned.wav
|
||||
```
|
||||
|
||||
**Opzione 2: Pre-encode il riferimento (più efficiente)**
|
||||
|
||||
```bash
|
||||
# Estrai speaker embedding e codici
|
||||
podman exec qwentts qwen-codec \
|
||||
--model /app/models/qwen-tokenizer-12hz-Q8_0.gguf \
|
||||
--talker /app/models/qwen-talker-1.7b-base-Q8_0.gguf \
|
||||
-i /app/output/reference.wav
|
||||
|
||||
# Sintetizza usando i file pre-encodati
|
||||
echo "Now I can synthesize with this voice." | podman exec qwentts qwen-tts \
|
||||
--model /app/models/qwen-talker-1.7b-base-Q8_0.gguf \
|
||||
--codec /app/models/qwen-tokenizer-12hz-Q8_0.gguf \
|
||||
--ref-spk /app/output/reference.spk \
|
||||
--ref-rvq /app/output/reference.rvq \
|
||||
--ref-text "This is my reference voice sample" \
|
||||
--lang English \
|
||||
-o /app/output/synthesized.wav
|
||||
```
|
||||
|
||||
### Named Speakers (CustomVoice Mode)
|
||||
|
||||
Voci predefinite disponibili: serena, vivian, uncle_fu, ryan, aiden, ono_anna, sohee, eric (dialetto sichuan), dylan (dialetto beijing)
|
||||
|
||||
```bash
|
||||
echo "Hello from a named speaker." | podman exec qwentts qwen-tts \
|
||||
--model /app/models/qwen-talker-1.7b-customvoice-Q8_0.gguf \
|
||||
--codec /app/models/qwen-tokenizer-12hz-Q8_0.gguf \
|
||||
--speaker vivian \
|
||||
--lang English \
|
||||
-o /app/output/vivian.wav
|
||||
```
|
||||
|
||||
### Voice Design (Attributi di Voce)
|
||||
|
||||
Descrivi gli attributi della voce desiderata in testo libero:
|
||||
|
||||
```bash
|
||||
echo "A very friendly and warm conversation starter." | podman exec qwentts qwen-tts \
|
||||
--model /app/models/qwen-talker-1.7b-voicedesign-Q8_0.gguf \
|
||||
--codec /app/models/qwen-tokenizer-12hz-Q8_0.gguf \
|
||||
--instruct "female, young adult, cheerful, moderate pitch" \
|
||||
--lang English \
|
||||
-o /app/output/designed.wav
|
||||
```
|
||||
|
||||
Esempi di descrizioni:
|
||||
- "male, professional, deep voice, authoritative"
|
||||
- "female, elderly, warm and nurturing"
|
||||
- "non-binary, young, energetic and upbeat"
|
||||
- "child, playful, high-pitched, innocent"
|
||||
|
||||
## Lingue Supportate
|
||||
|
||||
- English
|
||||
- Mandarin (Standard)
|
||||
- Mandarin Sichuan (eric speaker)
|
||||
- Mandarin Beijing (dylan speaker)
|
||||
- Cantonese
|
||||
- Japanese
|
||||
- Korean
|
||||
- Spanish
|
||||
- French
|
||||
- German
|
||||
- Russian
|
||||
- And more...
|
||||
|
||||
Specifica con il flag `--lang`
|
||||
|
||||
## Modelli Disponibili
|
||||
|
||||
### Base Mode (Voce predefinita)
|
||||
- **Size**: 1.7B o 0.6B
|
||||
- **Quantization**: Q8_0, Q4_K_M, F32
|
||||
- **Caratteristiche**: Voce singola fissa, voice cloning
|
||||
- **Use case**: Sintesi rapida con voice cloning da riferimento
|
||||
|
||||
### CustomVoice Mode (Altoparlanti nominati)
|
||||
- **Speakers**: 8 voci predefinite con nomi e dialetti
|
||||
- **Size**: 1.7B
|
||||
- **Caratteristiche**: Scelta rapida tra voci note
|
||||
- **Use case**: Produzione di contenuto con voci consistenti
|
||||
|
||||
### VoiceDesign Mode (Attributi di voce)
|
||||
- **Size**: 1.7B
|
||||
- **Caratteristiche**: Sintesi controllata via attributi in testo libero
|
||||
- **Use case**: Creazione di voci custom con prompt descrittivi
|
||||
|
||||
### Dimensioni Modelli
|
||||
|
||||
| Modello | Dimensione (F32) | Q8_0 | Q4_K_M | RTF (GPU) |
|
||||
|---------|-----------------|------|--------|-----------|
|
||||
| 0.6B | 2.4 GB | 1.2 GB | 0.6 GB | < 0.5x |
|
||||
| 1.7B | 6.8 GB | 3.4 GB | 1.7 GB | < 1.0x |
|
||||
|
||||
RTF = Real-Time Factor (< 1.0 significa più veloce del tempo reale)
|
||||
|
||||
## Performance
|
||||
|
||||
### Benchmark (Estimated)
|
||||
|
||||
**CPU (AMD Ryzen 9950X3D):**
|
||||
- Sintesi 10 secondi: ~2-5 secondi
|
||||
|
||||
**GPU (NVIDIA A100 o AMD GPU equivalente con Vulkan):**
|
||||
- Sintesi 10 secondi: < 1 secondo
|
||||
|
||||
### Ottimizzazione
|
||||
|
||||
Per migliore performance:
|
||||
1. Usa modello 0.6B per latenza bassa
|
||||
2. Usa quantizzazione Q8_0 o superiore
|
||||
3. Pre-encode i riferimenti con `qwen-codec --talker` per voice cloning
|
||||
4. Aumenta memoria allocata nel quadlet se disponibile
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Build falls con dipendenze mancanti
|
||||
```bash
|
||||
# Esegui con sudo
|
||||
sudo ./build-container.sh
|
||||
```
|
||||
|
||||
### Vulkan non disponibile su container
|
||||
```bash
|
||||
# Verifica driver Vulkan
|
||||
podman run --rm --device=/dev/dri --device=/dev/kfd ghcr.io/library/debian:13-slim vulkaninfo
|
||||
```
|
||||
|
||||
### Modelli non trovati
|
||||
```bash
|
||||
# Verifica volume mounting
|
||||
podman exec qwentts ls -la /app/models
|
||||
```
|
||||
|
||||
### Memory issues
|
||||
Se il container crasha per memoria:
|
||||
```bash
|
||||
# Aumenta memoria nel quadlet (attualmente 16GB)
|
||||
# Oppure usa quantizzazione Q4_K_M per ridurre consumo
|
||||
```
|
||||
|
||||
### Sintesi lenta
|
||||
- Verifica che Vulkan sia attivo
|
||||
- Usa modello 0.6B
|
||||
- Aumenta CPUQuota nel quadlet
|
||||
- Verifica che /dev/dri e /dev/kfd siano accessibili
|
||||
|
||||
## Aggiornamento
|
||||
|
||||
Per aggiornare a una versione più recente di qwentts.cpp:
|
||||
|
||||
```bash
|
||||
# Ricompila
|
||||
./build-container.sh
|
||||
|
||||
# Rebuild immagine
|
||||
podman build -t qwentts:vulkan-amd64 -f qwentts-vulkan.Containerfile .
|
||||
|
||||
# Riavvia container
|
||||
systemctl --user restart qwentts
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
- [Qwentts.cpp GitHub](https://github.com/ServeurpersoCom/qwentts.cpp)
|
||||
- [Models on Hugging Face](https://huggingface.co/Serveurperso/Qwen3-TTS-GGUF)
|
||||
- [Qwen3-TTS Documentation](https://docs.qwenlm.ai/)
|
||||
- [Architecture & API Reference](https://github.com/ServeurpersoCom/qwentts.cpp/blob/master/docs/ARCHITECTURE.md)
|
||||
@@ -1,31 +1,45 @@
|
||||
[Unit]
|
||||
Description=Qwentts (Text-to-Speech with Voice Cloning)
|
||||
After=internal.network
|
||||
Wants=internal.network
|
||||
Description=Qwen3 TTS Server
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Container]
|
||||
Image=localhost/qwentts:vulkan-amd64
|
||||
Image=localhost/qwentts:latest
|
||||
ContainerName=qwentts
|
||||
Hostname=qwentts
|
||||
Network=internal.network
|
||||
PublishPort=127.0.0.1:8080:8080
|
||||
|
||||
Volume=/srv/containers/qwentts/models:/app/models:ro
|
||||
Volume=/srv/containers/qwentts/output:/app/output:rw
|
||||
# ROCm
|
||||
AddDevice=/dev/kfd
|
||||
AddDevice=/dev/dri/renderD128
|
||||
PodmanArgs=--group-add=keep-groups --ipc=host --pids-limit=-1 --security-opt label=disable
|
||||
SecurityLabelType=container_runtime_t
|
||||
|
||||
# GPU access - AMD Vulkan
|
||||
Device=/dev/dri:/dev/dri:rw
|
||||
Device=/dev/kfd:/dev/kfd:rw
|
||||
# HTTP API
|
||||
PublishPort=8000:8000
|
||||
|
||||
# Resource limits (adjust as needed)
|
||||
Memory=16g
|
||||
MemorySwap=24g
|
||||
CPUQuota=50%
|
||||
# Persist downloaded model weights across restarts
|
||||
# Adjust the host path to wherever you want the models cached
|
||||
Volume=/srv/containers/qwen-tts/models:/app/models:Z
|
||||
|
||||
# Restart policy
|
||||
# Which model(s) to load at startup: "customvoice", "voiceclone", or both
|
||||
# (default, comma-separated). Loading both lets a single instance serve
|
||||
# /speech (preset voices) and /speech/clone (voice cloning) at once.
|
||||
#Environment=QWEN_TTS_LOAD=customvoice,voiceclone
|
||||
# Optional: override the default checkpoints
|
||||
#Environment=QWEN_TTS_CUSTOMVOICE_MODEL=Qwen/Qwen3-TTS-12Hz-1.7B-CustomVoice
|
||||
#Environment=QWEN_TTS_VOICECLONE_MODEL=Qwen/Qwen3-TTS-12Hz-1.7B-Base
|
||||
|
||||
|
||||
# CPU-only container: no GPU devices needed
|
||||
PodmanArgs=--pids-limit=-1
|
||||
|
||||
# Resource limits (tune to your host; a 1.7B model on CPU needs headroom)
|
||||
#Memory=8g
|
||||
#CPUs=4
|
||||
|
||||
[Service]
|
||||
Restart=on-failure
|
||||
RestartMaxAttempts=5
|
||||
RestartSec=10s
|
||||
RestartSec=5
|
||||
TimeoutStartSec=300
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
WantedBy=default.target
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name qwentts.example.com;
|
||||
return 301 https://$server_name$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
http2 on;
|
||||
server_name qwentts.example.com;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/qwentts.example.com/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/qwentts.example.com/privkey.pem;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||
ssl_prefer_server_ciphers on;
|
||||
|
||||
client_max_body_size 100m;
|
||||
|
||||
# Re-resolve qwentts's DNS name at request time so a container restart
|
||||
# (new IP on internal.network) doesn't leave nginx stuck on a stale
|
||||
# address until nginx itself is restarted.
|
||||
resolver 10.10.0.1 valid=10s;
|
||||
resolver_timeout 5s;
|
||||
|
||||
# Logging
|
||||
access_log /var/log/nginx/qwentts_access.log;
|
||||
error_log /var/log/nginx/qwentts_error.log;
|
||||
|
||||
location / {
|
||||
set $qwentts_upstream http://qwentts:8080;
|
||||
proxy_pass $qwentts_upstream;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# Timeouts for long-running synthesis requests
|
||||
proxy_connect_timeout 120s;
|
||||
proxy_send_timeout 300s;
|
||||
proxy_read_timeout 300s;
|
||||
send_timeout 300s;
|
||||
|
||||
# Buffering for large audio files
|
||||
proxy_buffering on;
|
||||
proxy_buffer_size 64k;
|
||||
proxy_buffers 8 64k;
|
||||
proxy_busy_buffers_size 128k;
|
||||
}
|
||||
}
|
||||
@@ -129,6 +129,7 @@ conversazione Talk dove il bot è abilitato: vedi sezione "Stato dei test".
|
||||
| `WHISPER_URL` | no | `http://whisper:8080` | Endpoint whisper-server |
|
||||
| `LLAMACPP_URL` | no | `http://llamacpp:7000` | Endpoint llama.cpp (OpenAI-compatible chat) |
|
||||
| `LLAMACPP_MODEL` | no | (vuoto) | Nome modello, se il tuo router llama.cpp lo richiede |
|
||||
| `LLAMACPP_API_KEY` | no | (vuoto) | API key per llama.cpp (header `Authorization: Bearer ...`); se vuoto, nessun header è inviato |
|
||||
| `LLAMACPP_TIMEOUT` | no | `600` | Timeout (secondi) per la chiamata a llama.cpp |
|
||||
| `QWEN_TTS_URL` | no | `http://qwen-tts:8000` | Endpoint qwen-tts (deve girare con `QWEN_TTS_LOAD` includendo sia `customvoice` che `voiceclone`, default) |
|
||||
| `QWEN_TTS_TIMEOUT` | no | `1800` | Timeout (secondi) per la chiamata a qwen-tts |
|
||||
|
||||
@@ -26,6 +26,7 @@ NC_PASSWORD = os.environ["NC_PASSWORD"]
|
||||
WHISPER_URL = os.environ.get("WHISPER_URL", "http://whisper:8080").rstrip("/")
|
||||
LLAMACPP_URL = os.environ.get("LLAMACPP_URL", "http://llamacpp:7000").rstrip("/")
|
||||
LLAMACPP_MODEL = os.environ.get("LLAMACPP_MODEL", "").strip()
|
||||
LLAMACPP_API_KEY = os.environ.get("LLAMACPP_API_KEY", "").strip()
|
||||
LLAMACPP_TIMEOUT = int(os.environ.get("LLAMACPP_TIMEOUT") or "600")
|
||||
LLAMACPP_MAX_TOKENS = int(os.environ.get("LLAMACPP_MAX_TOKENS") or "8192")
|
||||
LLAMACPP_ENABLE_THINKING = (
|
||||
@@ -676,9 +677,14 @@ def translate(
|
||||
if LLAMACPP_MODEL:
|
||||
payload["model"] = LLAMACPP_MODEL
|
||||
|
||||
headers = {}
|
||||
if LLAMACPP_API_KEY:
|
||||
headers["Authorization"] = f"Bearer {LLAMACPP_API_KEY}"
|
||||
|
||||
response = httpx.post(
|
||||
f"{LLAMACPP_URL}/v1/chat/completions",
|
||||
json=payload,
|
||||
headers=headers,
|
||||
timeout=LLAMACPP_TIMEOUT,
|
||||
)
|
||||
|
||||
@@ -1280,6 +1286,10 @@ def process_event(job: dict) -> None:
|
||||
# the worker considers the event successful and removes it.
|
||||
raise
|
||||
|
||||
# Audio messages are translated and posted as audio only; don't also
|
||||
# post the translated text (e.g. a caption sent alongside the file).
|
||||
return
|
||||
|
||||
if message_text:
|
||||
log.info(
|
||||
"Text message %s from %s",
|
||||
|
||||
@@ -35,6 +35,7 @@ Environment=NC_PASSWORD=changeme
|
||||
Environment=WHISPER_URL=http://whisper:8080
|
||||
Environment=LLAMACPP_URL=http://llamacpp:8090
|
||||
#Environment=LLAMACPP_MODEL=
|
||||
#Environment=LLAMACPP_API_KEY=
|
||||
Environment=LLAMACPP_MAX_TOKENS=8192
|
||||
Environment=LLAMACPP_ENABLE_THINKING=false
|
||||
#Environment=LOG_WEBHOOK_PAYLOAD=false
|
||||
|
||||
Reference in New Issue
Block a user