# realtime_voice_bot 디스코드 음성 채널 또는 로컬 PC 마이크에서 한국어 음성을 인식하고, 완전 로컬 스택으로 답변을 생성한 뒤 다시 음성으로 읽어주는 최소 프로토타입입니다. ## 현재 스택 - STT: `faster-whisper` + Whisper multilingual - LLM: `Ollama` + `qwen3:0.6b` - TTS: - Windows: 시스템 기본 음성 엔진 - Linux/macOS: `kokoro-onnx` + `misaki[ko]` - VAD: `avr-vad` 외부 유료 API나 무료 한도형 API는 쓰지 않습니다. ## 현재 구현 범위 - Discord slash command 기반 제어: `/join`, `/leave`, `/status`, `/reset`, `/say` - 로컬 테스트 모드: PC 마이크로 직접 말하고 바로 응답 확인 - `@discordjs/voice` 기반 음성 채널 입장 및 유저별 오디오 수신 - 48k stereo PCM을 16k mono로 내려서 유저별 VAD 처리 - 화자 발화 시작 시 현재 재생과 대기열 즉시 중단 - Python 로컬 워커를 한 번 띄워 STT/TTS 모델을 메모리에 유지 ## 필수 준비물 - Bun `1.3+` - Node.js `22.12+` - Python `3.11+` - `ffmpeg` - Ollama Discord 모드까지 쓸 거면 추가로: - Discord bot token - Discord application id ## 빠른 시작 ```bash bun install ollama pull qwen3:0.6b bun run setup:local-ai ``` Windows에서 Python 실행기는 환경마다 다릅니다. 둘 중 되는 쪽 하나만 넣으면 됩니다: ```env LOCAL_AI_PYTHON=python # 또는 LOCAL_AI_PYTHON=py -3 ``` 그다음 로컬 장치 확인: ```bash bun run devices ``` 실행: ```bash bun run start:local ``` Discord 모드: ```bash bun run start:discord ``` ## 환경 변수 `.env.example`를 복사해서 `.env`를 채우면 됩니다. Discord 모드에서만 필수: - `DISCORD_BOT_TOKEN` - `DISCORD_APPLICATION_ID` 기본값이 이미 들어있는 로컬 AI 설정: - `OLLAMA_BASE_URL` - `OLLAMA_MODEL` - `OLLAMA_KEEP_ALIVE` - `OLLAMA_NUM_CTX` - `LOCAL_AI_VENV_PATH` - `LOCAL_AI_CACHE_DIR` - `LOCAL_STT_MODEL` - `LOCAL_STT_DEVICE` - `LOCAL_STT_COMPUTE_TYPE` - `LOCAL_STT_BEAM_SIZE` - `LOCAL_TTS_MODEL_PATH` - `LOCAL_TTS_VOICES_PATH` - `LOCAL_TTS_LANGUAGE` - `LOCAL_TTS_SPEAKER` - `LOCAL_TTS_DEVICE` - `LOCAL_TTS_SPEED` 선택: - `DISCORD_COMMAND_GUILD_ID` - 테스트 서버에만 slash command를 즉시 반영하려면 설정 - `LOCAL_AI_PYTHON` - Python 경로 자동 탐지가 안 되면 설정 - 예시: `python` - Windows 예시: `python` 또는 `py -3` - `LOCAL_AUDIO_SOURCE` - 로컬 입력 장치 - Linux는 `pw-record --target`, Windows는 `ffmpeg dshow` 장치 이름 - `LOCAL_AUDIO_SINK` - Linux 로컬 출력 장치 - Windows는 현재 시스템 기본 출력 장치 사용 - `LOCAL_SPEAKER_NAME` - 로컬 테스트에서 프롬프트에 넣을 화자 이름 - `BOT_DEFAULT_LANGUAGE` - 기본값 `ko` - `DEBUG_TEXT_EVENTS` - `true`면 transcript/reply를 콘솔에 같이 출력 Windows에서 GPU STT를 쓰려면 `LOCAL_STT_DEVICE=auto` 그대로 두고 `bun run setup:local-ai`를 다시 실행하세요. 현재 스크립트는 `faster-whisper`와 함께 CUDA 12용 `cuBLAS`, `cuDNN` 런타임 wheel도 같이 설치합니다. 그래도 `cublas64_12.dll` 또는 `cudnn` 오류가 남으면 시스템에 Visual C++ 런타임이 빠졌거나, 별도 CUDA 설치 경로가 PATH에 안 잡힌 경우입니다. ## 속도 우선 기본값 - STT 기본 모델은 `tiny` - LLM 기본 모델은 `qwen3:0.6b` - TTS 기본 보이스는 `af_heart` - TTS 기본 속도는 `1.12` 정확도가 아쉬우면: ```env LOCAL_STT_MODEL=small OLLAMA_MODEL=qwen3:1.7b ``` ## 로컬 테스트 순서 1. `bun install` 2. `ollama pull qwen3:0.6b` 3. Windows면 `.env` 에 `LOCAL_AI_PYTHON=python` 또는 `LOCAL_AI_PYTHON=py -3` 추가 4. `bun run setup:local-ai` 5. `bun run devices` 6. `.env` 에 `LOCAL_AUDIO_SOURCE` 설정 7. `bun run start:local` ## Windows 메모 - `bun run devices` 와 Windows 로컬 녹음은 `ffmpeg`가 필요합니다. - Windows는 TTS를 Python 모델 대신 시스템 기본 음성 엔진으로 처리합니다. - 출력 장치 직접 선택은 아직 미구현이라 시스템 기본 출력 장치로 재생됩니다. - Python 탐지가 안 되면 `.env` 에 `LOCAL_AI_PYTHON=python` 또는 `LOCAL_AI_PYTHON=py -3` 를 넣으면 됩니다. - Windows의 `setup:local-ai`는 STT와 CUDA 런타임 wheel을 함께 설치합니다. - Linux/macOS의 `setup:local-ai`는 Kokoro ONNX 모델 파일도 자동으로 내려받습니다. ## 설계 메모 - 입력은 유저별 병렬 처리 - 출력은 길드 세션당 단일 큐 - 로컬 모드는 단일 화자 입력 기준 - 화자 구분은 `speaker_id`, `speaker_name`을 LLM 프롬프트에 항상 포함 - 모델 다운로드 캐시는 기본적으로 `.local-ai/cache` 아래에 저장