3.6 KiB
3.6 KiB
realtime_voice_bot
디스코드 음성 채널 또는 로컬 PC 마이크에서 한국어 음성을 인식하고, 완전 로컬 스택으로 답변을 생성한 뒤 다시 음성으로 읽어주는 최소 프로토타입입니다.
현재 스택
- STT:
faster-whisper+ Whisper multilingual - LLM:
Ollama+qwen3:0.6b - TTS:
MeloTTSKorean - 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
빠른 시작
bun install
ollama pull qwen3:0.6b
bun run setup:local-ai
Windows에서 python 에러가 나면 .env 에 먼저 이 값을 넣습니다:
LOCAL_AI_PYTHON=py -3
그다음 로컬 장치 확인:
bun run devices
실행:
bun run start:local
Discord 모드:
bun run start:discord
환경 변수
.env.example를 복사해서 .env를 채우면 됩니다.
Discord 모드에서만 필수:
DISCORD_BOT_TOKENDISCORD_APPLICATION_ID
기본값이 이미 들어있는 로컬 AI 설정:
OLLAMA_BASE_URLOLLAMA_MODELOLLAMA_KEEP_ALIVEOLLAMA_NUM_CTXLOCAL_AI_VENV_PATHLOCAL_AI_CACHE_DIRLOCAL_STT_MODELLOCAL_STT_DEVICELOCAL_STT_COMPUTE_TYPELOCAL_STT_BEAM_SIZELOCAL_TTS_LANGUAGELOCAL_TTS_SPEAKERLOCAL_TTS_DEVICELOCAL_TTS_SPEED
선택:
DISCORD_COMMAND_GUILD_ID- 테스트 서버에만 slash command를 즉시 반영하려면 설정
LOCAL_AI_PYTHON- Python 경로 자동 탐지가 안 되면 설정
- 예시:
python - Windows 예시:
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_EVENTStrue면 transcript/reply를 콘솔에 같이 출력
속도 우선 기본값
- STT 기본 모델은
tiny - LLM 기본 모델은
qwen3:0.6b - TTS 기본 속도는
1.12
정확도가 아쉬우면:
LOCAL_STT_MODEL=small
OLLAMA_MODEL=qwen3:1.7b
로컬 테스트 순서
bun installollama pull qwen3:0.6b- Windows면
.env에LOCAL_AI_PYTHON=py -3추가 bun run setup:local-aibun run devices.env에LOCAL_AUDIO_SOURCE설정bun run start:local
Windows 메모
bun run devices와 Windows 로컬 녹음은ffmpeg가 필요합니다.- 출력 장치 직접 선택은 아직 미구현이라 시스템 기본 출력 장치로 재생됩니다.
- Python 탐지가 안 되면
.env에LOCAL_AI_PYTHON=py -3를 넣으면 됩니다.
설계 메모
- 입력은 유저별 병렬 처리
- 출력은 길드 세션당 단일 큐
- 로컬 모드는 단일 화자 입력 기준
- 화자 구분은
speaker_id,speaker_name을 LLM 프롬프트에 항상 포함 - 모델 다운로드 캐시는 기본적으로
.local-ai/cache아래에 저장