#!/bin/bash # ============================================================ # Avvio Pipeline Speech-to-Speech con RAG SERVER-SIDE abilitato # ============================================================ # - Usa gli stessi endpoint/base URL di start_pipeline.sh # - Auto-detect del modello LLM via /v1/models # - Aggiunge tutti i flag --rag_* necessari # - Persistenza indice NPZ automatica (solo 1a build lenta) # ============================================================ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" cd "$SCRIPT_DIR" # ── Determina interprete Python ────────────────────────── # Usa ./venv/bin/python come lo script originale start_pipeline.sh # per essere sicuro di caricare tutte le dipendenze del progetto. if [ -x "./venv/bin/python" ]; then PY="./venv/bin/python" echo "✅ Interprete Python: ./venv/bin/python (virtualenv progetto)" else if command -v python3 &>/dev/null; then PY="$(command -v python3)" echo "⚠️ ./venv/bin/python non trovato, uso python3 di sistema: ${PY}" echo " ⚡ Consigliato: crea il virtualenv con 'python -m venv venv && uv pip install -e .[rag]'" else echo "❌ Nessun interprete Python trovato (né ./venv/bin/python, né python3)." exit 1 fi fi if [ -f ".env" ]; then set -a . ./.env set +a fi # ── Endpoint LLM (ereditati da start_pipeline.sh) ────────── BASE_URL="${LLM_BASE_URL:-http://127.0.0.1:8001/v1}" DEFAULT_MODEL_NAME="${LLM_MODEL_NAME:-Qwen/Qwen3-32B}" MODEL_NAME="$DEFAULT_MODEL_NAME" # ── RAG — Configurazione (personalizza qui) ──────────────── RAG_KB_PATH="${RAG_KB_PATH:-./kb}" # Cartella documenti + indice RAG_TOP_K="${RAG_TOP_K:-3}" # Chunk max per turno RAG_THRESHOLD="${RAG_THRESHOLD:-0.30}" # Soglia similarità coseno [0,1] RAG_LANGUAGE="${RAG_LANGUAGE:-es}" # es / it / en (header prompt) RAG_INJECT_AS="${RAG_INJECT_AS:-system}" # system (consigliato) / user RAG_DEVICE="${RAG_DEVICE:-auto}" # auto / cuda / cpu RAG_EMBEDDING_MODEL="${RAG_EMBEDDING_MODEL:-paraphrase-multilingual-MiniLM-L12-v2}" RAG_CHUNK_SIZE="${RAG_CHUNK_SIZE:-512}" RAG_CHUNK_OVERLAP="${RAG_CHUNK_OVERLAP:-64}" RAG_FORCE_REBUILD="${RAG_FORCE_REBUILD:-0}" # 1 = forza ricostruzione indice # ── Pipeline — porte / repliche ─────────────────────────── WS_HOST="${WS_HOST:-0.0.0.0}" WS_PORT="${WS_PORT:-12345}" NUM_PIPELINES="${NUM_PIPELINES:-2}" LOG_LEVEL="${LOG_LEVEL:-INFO}" # ── TTS (ereditato da start_pipeline.sh) ────────────────── TTS_MODEL="${Qwen3_TTS_MODEL:-Qwen/Qwen3-TTS-12Hz-1.7B-Base}" TTS_REF_AUDIO="${Qwen3_TTS_REF_AUDIO:-female_short.wav}" TTS_REF_TEXT="${Qwen3_TTS_REF_TEXT:-Chile tiene uno de los acentos más reconocibles del mundo hispano y los generadores de español genérico no logran capturarlo.}" echo "🎙️ Avvio Pipeline Audio Realtime + RAG (Porta ${WS_PORT})..." echo "💡 Premi Ctrl+C in questo terminale per fermarla." echo "🔎 Query del modello LLM in uso su ${BASE_URL}/models..." DETECTED_MODEL_NAME=$( curl -fsS "${BASE_URL}/models" 2>/dev/null | "$PY" -c ' import json import sys data = json.load(sys.stdin) models = data.get("data") or [] first = models[0] if models else {} print(first.get("id", ""), end="") ' 2>/dev/null || true ) if [ -n "$DETECTED_MODEL_NAME" ]; then MODEL_NAME="$DETECTED_MODEL_NAME" echo "🧠 Modello LLM rilevato: $MODEL_NAME" else echo "⚠️ Query /models fallita, uso fallback configurato: $MODEL_NAME" fi echo "" echo "📚 === Configurazione RAG ===" echo " KB path : ${RAG_KB_PATH}" echo " Embedding model: ${RAG_EMBEDDING_MODEL}" echo " Device : ${RAG_DEVICE}" echo " Top-K : ${RAG_TOP_K}" echo " Soglia : ${RAG_THRESHOLD}" echo " Lingua prompt : ${RAG_LANGUAGE}" echo " Inietta come : ${RAG_INJECT_AS}" echo " Chunk size : ${RAG_CHUNK_SIZE} (overlap ${RAG_CHUNK_OVERLAP})" echo " Force rebuild : $([[ "$RAG_FORCE_REBUILD" == "1" ]] && echo "SI ⚠️" || echo "no")" echo "============================" echo "" echo "🧩 === Configurazione pipeline ===" echo " WS endpoint : ws://${WS_HOST}:${WS_PORT}" echo " Pipeline attive : ${NUM_PIPELINES}" echo " LLM backend : chat-completions" echo " TTS model : ${TTS_MODEL}" echo " Log level : ${LOG_LEVEL}" echo "==================================" echo "" echo "🚀 Avvio tra 2 secondi..." sleep 2 RAG_FORCE_FLAG="" if [[ "$RAG_FORCE_REBUILD" == "1" ]]; then RAG_FORCE_FLAG="--rag_force_rebuild" echo "♻️ RAG FORCE REBUILD attivo — indice verrà ricostruito da zero." fi PYTHONPATH=src exec "$PY" src/speech_to_speech/s2s_pipeline.py \ --mode realtime \ --ws_host "${WS_HOST}" \ --ws_port "${WS_PORT}" \ --num_pipelines "${NUM_PIPELINES}" \ --log_level "${LOG_LEVEL}" \ \ --llm_backend chat-completions \ --model_name "${MODEL_NAME}" \ --responses_api_base_url "${BASE_URL}" \ --responses_api_api_key "EMPTY" \ \ --qwen3_tts_backend torch \ --qwen3_tts_model_name "${TTS_MODEL}" \ --qwen3_tts_ref_audio "${TTS_REF_AUDIO}" \ --qwen3_tts_ref_text "${TTS_REF_TEXT}" \ \ --rag_enabled \ --rag_kb_path "${RAG_KB_PATH}" \ --rag_embedding_model "${RAG_EMBEDDING_MODEL}" \ --rag_device "${RAG_DEVICE}" \ --rag_top_k "${RAG_TOP_K}" \ --rag_threshold "${RAG_THRESHOLD}" \ --rag_language "${RAG_LANGUAGE}" \ --rag_inject_as "${RAG_INJECT_AS}" \ --rag_chunk_size "${RAG_CHUNK_SIZE}" \ --rag_chunk_overlap "${RAG_CHUNK_OVERLAP}" \ ${RAG_FORCE_FLAG}