This repository is an archived snapshot. It represents an earlier iteration of WATUS and is preserved for reference. The current version is under active development and will be made public on release.
Low-latency voice frontend z rozpoznawaniem lidera (ECAPA / SpeechBrain), transkrypcją (Whisper via Faster-Whisper),
kolejką ZMQ oraz TTS (Piper). Łączy się z lokalnym backendem LLM (watus-ai) przez HTTP. Kamera i jej pliki są obowiązkowe – projekt korzysta z detekcji (Ultralytics RT-DETR/YOLO) i zapisuje kontekst do camera.jsonl.
- Opis
- Wymagania
- Szybki start (TL;DR)
- Instalacja — krok po kroku
- Uruchomienie
- Konfiguracja i parametry
- Scenariusze
- Troubleshooting
- Uwaga o plikach w repo
watus.py– nasłuch audio (PortAudio), VAD (WebRTC), rozpoznawanie mówcy (ECAPA/SpeechBrain), transkrypcja (Faster-Whisper tylko; brak openai-whisper), zapis dodialog.jsonl, PUBdialog.leadertylko dla lidera, SUBtts.speaki odtwarzanie (Piper). Loguje czasy etapów (ASR, I/O) w terminalu.reporter.py– SUBdialog.leader, buduje meldunek (tekst + meta + czas systemowy + scenariusz + ostatnie dane z kamery), POST do backendu LLM (/api1/process_question), PUBtts.speakz odpowiedzią (dla Watusia). Ma retry dla 429/timeout i krótki fallback TTS.camera_runner.py(OBOWIĄZKOWO) – zapisuje docamera.jsonlinformacje o wykrytych obiektach i jasności kadru. Domyślnie pracuje bez podglądu; snapshoty i overlay ogarnia komponent kamerowy (tu integrujemy tylko dane).
Przepływ:
Mic → Watus (VAD + STT + ECAPA) → dialog.jsonl → (leader→ZMQ) → Reporter → HTTP→LLM → (odp) ZMQ→Watus → TTS (Piper)
Kamera (ciągle) → camera.jsonl → kontekst w meldunku Repotera
- Python 3.11+
- Wolne porty: 7780, 7781, 8781 oraz 8000 (LLM).
- Piper (binarka + model ONNX + config) i piper-phonemize (biblioteka fonemizacji).
- Głosy Piper (pl):
- Darkman medium:
https://huggingface.co/rhasspy/piper-voices/tree/main/pl/pl_PL/darkman/medium - Piper releases (binarki):
https://github.com/rhasspy/piper/releases/tag/2023.11.14-2 - piper-phonemize (biblioteki .dll/.so/.dylib):
https://github.com/rhasspy/piper-phonemize/releases/tag/2023.11.14-4
- Darkman medium:
- Głosy Piper (pl):
- Biblioteki systemowe: PortAudio + libsndfile.
- ECAPA (SpeechBrain) – wymagane do weryfikacji mówcy.
- Kamera – obowiązkowa: Ultralytics (RT-DETR/YOLO) + OpenCV + Torch + Torchvision (wg systemu).
git clone https://github.com/misialyna/watus_project.git
cd watus_project python3 -m venv .venv
source .venv/bin/activate python -m venv .venv
.\.venv\Scripts\Activate.ps1 pip install -U pip wheel
pip install -r requirements.txt
cp .env.example .env
# uzupełnij: PIPER_BIN, PIPER_MODEL, PIPER_CONFIG, urządzenia audio, ścieżki kameryW linii 30 w reporter.py zmień ścieżkę absolutną na swoją!
CAMERA_JSONL = os.environ.get("CAMERA_JSONL", "/Users/michalinamoszynska/Documents/GitHub/watus_project/camera.jsonl")
#zmień na własnąścieżkę absolutną
CAMERA_JSONL = os.environ.get("CAMERA_JSONL", "Twoja_sciezka_absolutna.")
Repo:
https://github.com/pasjonatprogramowania/watus-ai
uvicorn src.main:app --host 127.0.0.1 --port 8000 --reloadpython3 reporter.py# kamera – patrz sekcja E
python3 camera_runner.py --jsonl ./camera.jsonl --device 0 --rt 1 # RT-DETR (zalecane)
# lub fallback YOLO:
# python3 camera_runner.py --jsonl ./camera.jsonl --device 0python3 watus.pybrew install portaudio libsndfilesudo apt update
sudo apt install -y libportaudio2 libsndfile1Zwykle nic nie trzeba. Jeśli są błędy z PortAudio – doinstaluj odpowiedni pakiet.
python3 -m venv .venv
source .venv/bin/activatepython -m venv .venv
.\.venv\Scripts\Activate.ps1Plik requirements.txt w repo zawiera wszystko poza torch/torchaudio/torchvision i paczkami kamery:
numpy==1.26.4
sounddevice==0.4.6
soundfile==0.12.1
webrtcvad==2.0.10
faster-whisper==1.0.3
pyzmq==25.1.2
requests==2.32.3
python-dotenv==1.0.1
fastapi==0.112.2
uvicorn==0.30.6
speechbrain==0.5.16Instalacja:
pip install -U pip wheel
pip install -r requirements.txtUwaga: nie instalujemy tu Torcha – zrobimy to świadomie w kolejnym kroku, aby dobrać poprawne koło dla danego systemu (eliminujemy konflikty).
pip install "torch==2.6.*"
# (opcjonalnie) bezpieczny fallback na CPU gdy MPS nie wspiera operacji:
export PYTORCH_ENABLE_MPS_FALLBACK=1 # bash/zsh- ECAPA (SpeechBrain) skorzysta z MPS, Faster-Whisper i tak działa głównie na CPU – to OK.
pip install --index-url https://download.pytorch.org/whl/cpu "torch==2.6.*"pip install --index-url https://download.pytorch.org/whl/cu124 "torch==2.6.*"pip install --index-url https://download.pytorch.org/whl/cpu "torch==2.6.*"Po zainstalowaniu Torch dołóż zgodną wersję torchvision:
pip install "torchvision==0.21.*"pip install --index-url https://download.pytorch.org/whl/cpu "torchvision==0.21.*"pip install --index-url https://download.pytorch.org/whl/cu124 "torchvision==0.21.*"
torchaudionie jest wymagane dla Watus/Reporter/Kamery i często generuje zbędne konflikty (zwłaszcza na macOS). Instaluj tylko, jeśli naprawdę potrzebujesz.
Jeżeli chcesz, by Reporter wzbogacał meldunki o kontekst wizji, kamera musi działać – uruchom camera_runner.py, który dopisuje rekordy JSONL do camera.jsonl.
Zależności kamery (instaluj po Torchu/Torchvision):
pip install "ultralytics==8.3.0" opencv-python-headlessWażne pliki w repo:
camera_runner.py– runner zapisujący docamera.jsonlcamera.jsonl– output JSONL (czytany przezreporter.py)- katalog
oczyWatusia/– kod RT-DETR; wagirtdetr-l.pt(nie commitujemy, pobierz i umieść w tym katalogu) - katalog
oczyWatusia_extracted/– może pojawiać się automatycznie przy pierwszym uruchomieniu; jest w.gitignore
Uruchomienie (przykłady):
# urządzenie 0 (np. wbudowana kamera), fallback YOLO
python3 camera_runner.py --jsonl ./camera.jsonl --device 0
# urządzenie 0, RT-DETR (zalecane – szybsze i dokładniejsze, bez podglądu)
python3 camera_runner.py --jsonl ./camera.jsonl --device 0 --rt 1camera_runner.py działa w tle, bez podglądu. Reporter co ~2.5 s (domyślnie CAMERA_WINDOW_SEC) bierze ostatni wpis.
Skopiuj i uzupełnij:
cp .env.example .envKluczowe pola (dopasuj do swoich ścieżek/urządzeń):
# ==== ZMQ ====
ZMQ_PUB_ADDR=tcp://127.0.0.1:7780
ZMQ_SUB_ADDR=tcp://127.0.0.1:7781
# ==== STT (Faster-Whisper only) ====
ASR_BACKEND=faster
WHISPER_MODEL=small # mapowane w kodzie na guillaumekln/faster-whisper-small
WHISHER_DEVICE=cpu # cuda na Linux/Windows z NVIDIA
WHISPER_COMPUTE_TYPE=int8
WATUS_CPU_THREADS=8
WHISPER_NUM_WORKERS=1
# ==== Audio / VAD ====
WATUS_INPUT_DEVICE=1 # ustaw po numerze z listy urządzeń wypisywanych przez watus.py
WATUS_OUTPUT_DEVICE=2
WATUS_SR=16000
WATUS_BLOCKSIZE=160 # 10 ms @ 16 kHz (niska latencja)
WATUS_VAD_MODE=1
WATUS_VAD_MIN_MS=280
WATUS_SIL_MS_END=650
ASR_MIN_DBFS=-34
WATUS_START_MIN_FRAMES=8
WATUS_START_MIN_DBFS=-30
WATUS_MIN_MS_BEFORE_ENDPOINT=500
END_AT_DBFS_DROP=0
EMIT_COOLDOWN_MS=300
MAX_UTT_MS=6500
WAIT_REPLY_S=0.9
# ==== TTS Piper ====
PIPER_BIN=/absolute/path/to/models/piper/piper
PIPER_MODEL=/absolute/path/to/models/piper/pl_PL-darkman-medium.onnx
PIPER_CONFIG=/absolute/path/to/models/piper/pl_PL-darkman-medium.onnx.json
# ==== LLM HTTP (lokalny backend) ====
LLM_HTTP_URL=http://127.0.0.1:8000/api1/process_question
HTTP_TIMEOUT=20
LLM_HTTP_TIMEOUT=30
# ==== Logi / meta ====
LOG_DIR=./
DIALOG_PATH=dialog.jsonl
# (ECAPA)
SPEAKER_VERIFY=1
SPEAKER_REQUIRE_MATCH=1
# ==== Scenariusze ====
WATUS_SCENARIOS_DIR=./scenarios_text
SCENARIO_ACTIVE_PATH=./scenarios_text/active.jsonl
# ==== Kamera / wizja ====
CAMERA_NAME=cam_front
CAMERA_DEVICE=0
CAMERA_JSONL=./camera.jsonl
VISION_SCORE_THR=0.5
VISION_WRITE_HZ=1.0
VISION_USE_RTDETR=1
RTDETR_DIR=./oczyWatusia
RTDETR_WEIGHTS=./oczyWatusia/rtdetr-l.pt
CAMERA_WINDOW_SEC=2.5
# ==== Wątki BLAS ====
OMP_NUM_THREADS=4
MKL_NUM_THREADS=4
# (macOS) pozwala SpeechBrain spadać na CPU, gdy MPS nie wspiera op
PYTORCH_ENABLE_MPS_FALLBACK=1Binarka Piper
https://github.com/rhasspy/piper/releases/tag/2023.11.14-2
Wypakuj np. do models/piper/ i ustaw PIPER_BIN w .env.
Głos PL („darkman/medium”)
https://huggingface.co/rhasspy/piper-voices/tree/main/pl/pl_PL/darkman/medium
Zapisz .onnx i .onnx.json w models/piper/ i ustaw w .env.
piper-phonemize (biblioteki fonemizacji – wymagane)
https://github.com/rhasspy/piper-phonemize/releases/tag/2023.11.14-4
- macOS: paczka
piper-phonemize-...-macos-...→ skopiuj.dylibdomodels/piper/lubmodels/piper/piper-phonemize/lib/.
Przy błędzie typudyld: Library not loaded: @rpath/libpiper_phonemize...:
brew install onnxruntime re2 # ew. skopiuj podstawowe dylib-y obok binarki piper - Linux: paczka
piper-phonemize-...-linux-...→.soobok binarki albo do/usr/local/lib(+ldconfig), w razie braków:
sudo apt install -y espeak-ng-data libespeak-ng1 libsndfile1
- Windows: paczka
piper-phonemize-...-win-...→piper_phonemize.dllobokpiper.exe(lub dodaj folder doPATH).
https://github.com/pasjonatprogramowania/watus-ai
uvicorn src.main:app --host 127.0.0.1 --port 8000 --reloadpython3 reporter.py
# health: http://127.0.0.1:8781/health# YOLO (fallback)
python3 camera_runner.py --jsonl ./camera.jsonl --device 0
# RT-DETR (zalecane)
python3 camera_runner.py --jsonl ./camera.jsonl --device 0 --rt 1python3 watus.pyWatus loguje: LISTENING / THINKING / SPEAKING / IDLE oraz czasy etapów.
unknown_* → zapis do dialog.jsonl, brak wysyłki do LLM.
leader_* → zapis i wysyłka do LLM (ZMQ → Reporter).
WATUS_BLOCKSIZE=160→ 10 ms @ 16 kHz (niska latencja)WATUS_VAD_MIN_MS=280,WATUS_SIL_MS_END=650→ krótkie, naturalne kończenie turWAIT_REPLY_S=0.9→ po wysyłce pytania czekamy na TTS, nie zbieramy „śmieci”
SPEAKER_VERIFY=1,SPEAKER_REQUIRE_MATCH=1– odpowiadamy tylko liderowi- Progi (w
watus.py/.env) uwzględniają „sticky” tolerancję (emocje/zmęczenie)
LLM_HTTP_URL=http://127.0.0.1:8000/api1/process_question,HTTP_TIMEOUT=20- Reporter dodaje
SYS_TIME/SCENARIO/CAMERA_*(ostatnie okno ~2.5 s)
- Pliki tekstowe w
scenarios_text/(np. persona, styl, ograniczenia). - Aktywny scenariusz wskazuje
SCENARIO_ACTIVE_PATH(domyślniescenarios_text/active.jsonl). - Do szybkiej zmiany skorzystaj z helpera
set_scenario.pyalbo podmień plikactive.jsonl.
- Zajęte porty (7780/7781) – zamknij poprzednie procesy
watus.py/reporter.py. - Brak głosu z Piper / błędy .dll/.so/.dylib – sprawdź instalację piper-phonemize i (na macOS)
onnxruntime+re2.
Upewnij się, że biblioteki leżą obok binarki lub są wDYLD_LIBRARY_PATH/PATH/LD_LIBRARY_PATH. - macOS – torchvision/torchaudio –
torchaudionie jest potrzebny;torchvisionpinuj do0.21.*. - GPU dla kamery (CUDA 12.4) – utrzymuj spójny zestaw
torch==2.6.*+torchvision==0.21.*z indexemcu124. - Ultralytics/RT-DETR – instaluj po Torchu; pin
ultralytics==8.3.0(z tym testowano). - Mikrofon (macOS) –
Settings → Privacy & Security → Microphone(zezwól Terminalowi/IDE). - Wysoka latencja – sprawdź
WATUS_BLOCKSIZE=160,SIL_MS_END≈600–700,WHISPER_COMPUTE_TYPE(int8na CPU /float16na CUDA).
- Modele i binarki (Piper/Whisper/ECAPA/RT-DETR) nie są dołączone – pobierz je linkami i ustaw w
.env. - Logi (
dialog.jsonl,meldunki.jsonl,camera.jsonl) oraz katalogi cache/ekstrakcji (np.oczyWatusia_extracted/) są wykluczone przez.gitignore. - Nie usuwaj katalogu
oczyWatusia/ani placeholderu wagirtdetr-l.pt, jeśli używasz kamery. KatalogoczyWatusia_extracted/może się pojawiać automatycznie – jest ignorowany w Git.
- Wybierz scenariusz (opcjonalnie, ale zalecane)
Scenariusze są w
./scenarios_text/.
Aby ustawić aktywny:
python3 set_scenario.py # interaktywnie
# lub:
python3 set_scenario.py <id> # nazwa pliku bez rozszerzeniaAktywny jest ostatni wpis w scenarios_text/active.jsonl.
3) Uruchom backend LLM (repo watus-ai)
Repo:
https://github.com/pasjonatprogramowania/watus-ai
uvicorn src.main:app --host 127.0.0.1 --port 8000 --reload- Uruchom Reporter (terminal A)
python3 reporter.py
# zdrowie serwisu:
# http://127.0.0.1:8781/health- Uruchom kamerę (terminal B) RT-DETR (zalecane, bez podglądu):
python3 camera_runner.py --jsonl ./camera.jsonl --device 0 --rt 1Fallback YOLO (gdy RT-DETR nie jest gotowy):
python3 camera_runner.py --jsonl ./camera.jsonl --device 0Kamera zapisuje camera.jsonl; reporter.py automatycznie dołącza ostatnie detekcje (okno CAMERA_WINDOW_SEC) do meldunku wysyłanego do LLM.
6) Uruchom Watus (terminal C)
python3 watus.pyNa starcie Watus wypisze listę urządzeń audio. Dopasuj WATUS_INPUT_DEVICE i WATUS_OUTPUT_DEVICE w .env, jeśli trzeba, i uruchom ponownie.
- Poczekaj, aż Watus pokaże w terminalu
[Watus][STATE] LISTENING. - Powiedz krótko do mikrofonu, np. „Hej, WATUSiu” i dokończ zdanie/pytanie naturalnie.
- Pierwsza poprawna wypowiedź enroluje Twój głos jako lidera (ECAPA).
Watus wykona: LISTENING → THINKING → SPEAKING i odtworzy odpowiedź (Piper).
Kolejne wypowiedzi: Watus odpowiada tylko liderowi (SPEAKER_REQUIRE_MATCH=1).
- Głosy innych osób są logowane jako
unknown_*i nie idą do LLM.
- Reporter wypisuje
„MELDUNEK”i pokazuje m.in.[SCENARIO=...], [CAMERA=...], [SPEECH=...]orazUSER: .... - W logu widać też
„HTTP→/HTTP←”i publikacjętts.speak. - Watus po odpowiedzi Piper przechodzi znów w
LISTENING. - W logach są czasy etapów:
ASR_ms=...,TTS_play_ms=..., itp. - Kamera tworzy i dopisuje do
camera.jsonl; wreporter.pyw meldunku pojawia się[VISION=...]z podsumowaniem detekcji.
- Brak odpowiedzi / TTS milczy → sprawdź ścieżki w
.env(PIPER_BIN/MODEL/CONFIG)i bibliotekipiper-phonemize. „Address already in use (7780/7781)”→ zakończ poprzednie watus.py/reporter.py.- Kamera nie startuje → najpierw zainstaluj Torch + Torchvision zgodnie z systemem, potem
ultralytics==8.3.0iopencv-python-headless. - ECAPA wolna lub błąd na macOS → zainstaluj torch==2.6.* (MPS), ustaw
PYTORCH_ENABLE_MPS_FALLBACK=1. - Wysoka latencja → w
.envustawWATUS_BLOCKSIZE=160,WHISPER_COMPUTE_TYPE=int8(CPU) lubWHISPER_DEVICE=cuda + compute float16(GPU).
- LLM → uvicorn ...
- Reporter →
python3 reporter.py
Kamera →python3 camera_runner.py --jsonl ./camera.jsonl --device 0 --rt 1
Watus →python3 watus.py
Zatrzymywanie: Ctrl+C w każdym z terminali.
Logi runtime:dialog.jsonl,meldunki.jsonl,camera.jsonl(ignorowane przez Git).
