Some checks failed
Release / semantic-release (push) Successful in 19s
tests / Unit tests (Linux, Python 3.11) (push) Successful in 9m54s
Release / build-linux (push) Failing after 7m14s
Release / build-windows (push) Has been cancelled
Release / build-macos (arm64, macos-latest) (push) Has been cancelled
Release / build-macos (x64, macos-15-intel) (push) Has been cancelled
Release / release-main (push) Has been cancelled
Release / release-develop (push) Has been cancelled
GPU acceleration is now on by default and verified end-to-end on the Blackwell RTX 5050 (sm_120): - Ollama offloads 100% to GPU (log: library=CUDA compute=12.0, BLACKWELL_NATIVE_FP4=1). compose passes GPU via CDI (devices: nvidia.com/gpu=all) to both ollama and javis. - Whisper STT on GPU: faster-whisper>=1.1.0 + nvidia-cublas/cudnn cu12, LD_LIBRARY_PATH baked into the image. Verified float16 transcribe on sm_120; bridge auto-falls back to CPU when no GPU is present. - Model: default chat model -> qwen3:8b (best 8GB-VRAM tool-calling, ~5GB Q4). Embed stays nomic-embed-text. - README documents the host one-time setup (nvidia-container-toolkit + `nvidia-ctk cdi generate`) and GPU on/off. Verified: image builds; GPU visible in both containers via compose; ollama ps = 100% GPU; faster-whisper cuda OK + CPU fallback OK; bridge /health 200.
194 lines
9.3 KiB
Markdown
194 lines
9.3 KiB
Markdown
# Javis Bot
|
|
|
|
Ubuntu 데스크톱(VNC) 위에서 도는 **디스코드 네이티브 음성 비서**입니다.
|
|
[isair/jarvis](https://github.com/isair/jarvis)의 성숙한 AI "두뇌"(메모리·툴·답변엔진·STT/TTS)를 그대로 쓰면서,
|
|
입출력 인터페이스를 로컬 마이크/스피커에서 **디스코드 음성 + 화면 방송**으로 바꾼 하이브리드 구성입니다.
|
|
|
|
- 🎙️ 디스코드 음성 채널에서 말로 대화 (음성 입력 → 두뇌 → 음성 출력)
|
|
- 🖥️ VNC 화면을 디스코드로 송출해서 같이 보기 (셀프봇 실시간 / noVNC / 스크린샷 선택)
|
|
- ⌨️ `/자비스` 슬래시 명령으로 호출 — 호출한 사람이 음성 채널에 있으면 그 채널로 접속
|
|
- 🔒 모든 슬래시 명령 응답은 **호출한 사람만 보이는 ephemeral** 메시지
|
|
- 🧠 크롬/웹 제어, 메모리, MCP 툴 등 jarvis의 기능 유지
|
|
|
|
> 언어 선택 근거(Python 유지 vs 재작성)는 [docs/language-comparison.md](docs/language-comparison.md) 참고.
|
|
> VNC + XFCE 호스트 셋업은 [docs/vnc-xfce-setup.md](docs/vnc-xfce-setup.md) 참고.
|
|
> 원본 jarvis README는 [docs/UPSTREAM-README.md](docs/UPSTREAM-README.md)에 보존했습니다.
|
|
|
|
---
|
|
|
|
## 아키텍처 (하이브리드)
|
|
|
|
```
|
|
Discord ──voice / video / slash──▶ bot/ (Node + bun, discord.js)
|
|
│ HTTP(localhost)
|
|
▼
|
|
bridge/ (Python, Flask)
|
|
│ in-process import
|
|
▼
|
|
src/jarvis (기존 두뇌: STT·답변엔진·메모리·툴·TTS)
|
|
```
|
|
|
|
- **bot/** — 디스코드 관련 전부. 슬래시 명령, 음성 송수신, VNC 화면 송출. AI 로직 없음.
|
|
- **bridge/** — 얇은 HTTP 서비스. 음성(WAV) → 텍스트(STT) → 두뇌(답변) → 음성(TTS).
|
|
- **src/jarvis** — 원본 jarvis 두뇌. 거의 손대지 않음. (PyQt 데스크톱 GUI/단축키 받아쓰기는 이 배포에선 사용하지 않음.)
|
|
|
|
왜 이렇게? 디스코드 봇은 정책상 영상(Go Live)을 송출할 수 없고, 봇 영상 송출이 되는 라이브러리는 Node 전용 + 셀프봇만 가능합니다. 반면 jarvis 두뇌는 검증된 Python 39k줄입니다. 그래서 영상이 가능한 Node로 인터페이스만 새로 짜고 두뇌는 Python 그대로 두는 하이브리드가 비용/위험 대비 최선입니다.
|
|
|
|
---
|
|
|
|
## 요구 사항
|
|
|
|
- Ubuntu 데스크톱 + TigerVNC(:1) — `docs/vnc-xfce-setup.md`
|
|
- Python 3.11+ (두뇌/브릿지), `ffmpeg`
|
|
- [bun](https://bun.sh) (디스코드 봇)
|
|
- Ollama (jarvis 두뇌의 LLM 백엔드)
|
|
- 디스코드 **봇** 토큰 1개 (음성/슬래시)
|
|
- (셀프봇 송출 사용 시) 디스코드 **버너 유저** 토큰 1개
|
|
|
|
---
|
|
|
|
## 실행 — Docker (권장)
|
|
|
|
환경 설정 없이 통째로 컨테이너에서 돌립니다. VNC 데스크톱 + 크롬 + Python 브릿지 + Node 봇이 한 컨테이너(`javis`)에, LLM 백엔드(Ollama)가 별도 컨테이너에 뜹니다. **올리기만 하면 Ollama 모델까지 자동으로** 받아집니다.
|
|
|
|
```bash
|
|
# 빌드 & 기동 — 이게 전부입니다.
|
|
docker compose up -d --build
|
|
```
|
|
|
|
`docker compose up` 한 번이면 자동으로:
|
|
- Ollama 서버가 뜨고, `ollama-init`이 채팅/임베딩 모델을 **자동 pull**
|
|
- VNC+XFCE 데스크톱 + 크롬 + Python 브릿지가 기동
|
|
- Whisper STT 모델 / Piper TTS 음성 자동 다운로드(볼륨에 캐시)
|
|
|
|
화면 보기: VNC 뷰어 → `localhost:5901` (비밀번호 = `.env`의 `VNC_PASSWORD`, 기본 `javis123`) 또는 브라우저 → `http://localhost:6080/vnc.html`.
|
|
로그: `docker compose logs -f javis`.
|
|
|
|
### 디스코드 토큰은 마지막에
|
|
|
|
토큰 없이도 위의 모든 게 정상 동작합니다(봇만 대기). 준비되면:
|
|
|
|
```bash
|
|
cp .env.example .env # DISCORD_BOT_TOKEN / DISCORD_APP_ID / DISCORD_GUILD_ID 채우기
|
|
docker compose up -d # 봇이 시작되고 /자비스 명령 등록
|
|
```
|
|
|
|
디스코드에서 `/자비스 join` 으로 호출하세요. (`OLLAMA_CHAT_MODEL` 등 모델을 바꾸려면 `.env`에서 지정 후 `docker compose up -d`.)
|
|
|
|
### GPU 가속 (기본 ON)
|
|
|
|
LLM(Ollama)과 Whisper STT가 **기본적으로 GPU(RTX 5050, Blackwell sm_120)** 에서 돕니다. 검증 완료: Ollama 100% GPU 오프로드, faster-whisper float16 GPU 동작.
|
|
|
|
호스트 사전 준비(1회):
|
|
|
|
```bash
|
|
# nvidia-container-toolkit 설치 후 CDI 스펙 생성 (Docker 29 CDI 방식, 데몬 재시작 불필요)
|
|
sudo nvidia-ctk cdi generate --output=/etc/cdi/nvidia.yaml
|
|
docker run --rm --device nvidia.com/gpu=all ubuntu nvidia-smi -L # GPU 보이면 OK
|
|
```
|
|
|
|
`docker-compose.yml`은 두 컨테이너에 `devices: ["nvidia.com/gpu=all"]`(CDI)로 GPU를 넣습니다.
|
|
|
|
- 모델: 기본 `qwen3:8b` — 8GB VRAM에서 도구호출(tool calling)이 가장 안정적이고 ~5GB(Q4)로 잘 맞습니다. 더 가볍게/무겁게 쓰려면 `.env`의 `OLLAMA_CHAT_MODEL` 변경.
|
|
- Whisper는 `WHISPER_DEVICE=cuda`/`float16` 기본. **GPU가 없으면 자동으로 CPU로 폴백**하므로 안전합니다.
|
|
- GPU가 아예 없는 호스트라면 `docker-compose.yml`의 두 `devices:` 블록을 지우고 `.env`에 `WHISPER_DEVICE=cpu`를 두면 됩니다.
|
|
|
|
- 데이터(메모리 DB), Whisper 캐시, Piper 음성은 named volume에 영속됩니다.
|
|
- 셀프봇 영상 송출 의존성은 이미지에 기본 포함하지 않습니다. 쓰려면 컨테이너에서 `cd /app/bot && bun add discord.js-selfbot-v13 @dank074/discord-video-stream` 후 재시작(또는 Dockerfile에 추가).
|
|
|
|
---
|
|
|
|
## 실행 — 수동(도커 없이)
|
|
|
|
```bash
|
|
# 1) 환경 변수
|
|
cp .env.example .env
|
|
# DISCORD_BOT_TOKEN / DISCORD_APP_ID / DISCORD_GUILD_ID 등 채우기
|
|
|
|
# 2) Python 두뇌 + 브릿지 의존성
|
|
python -m venv .venv && . .venv/bin/activate
|
|
pip install -r requirements.txt # jarvis 두뇌
|
|
pip install flask # 브릿지(없으면)
|
|
|
|
# 3) 디스코드 봇 의존성 (bun)
|
|
cd bot && bun install && cd ..
|
|
|
|
# 4) 한 번에 실행 (브릿지 + 봇)
|
|
./scripts/dev.sh
|
|
# 또는 따로:
|
|
# ./scripts/start_bridge.sh
|
|
# ./scripts/start_bot.sh
|
|
```
|
|
|
|
봇이 뜨면 디스코드에서 `/자비스 join` 으로 음성 채널에 부르세요.
|
|
|
|
---
|
|
|
|
## 슬래시 명령 (`/자비스`)
|
|
|
|
| 명령 | 동작 |
|
|
|---|---|
|
|
| `/자비스 join` | 호출자가 있는 음성 채널에 접속해 듣기 시작 |
|
|
| `/자비스 leave` | 음성 채널에서 나감 |
|
|
| `/자비스 ask 질문:<내용>` | 텍스트로 질문하고 답을 받음 |
|
|
| `/자비스 stream` | VNC 화면을 디스코드에 송출 시작 |
|
|
| `/자비스 stop` | 송출 중단 |
|
|
| `/자비스 status` | 브릿지 두뇌/세션/송출 상태 확인 |
|
|
|
|
모든 응답은 **호출한 사람에게만** 보입니다(ephemeral).
|
|
|
|
---
|
|
|
|
## VNC 화면 송출 백엔드 (`STREAM_BACKEND`)
|
|
|
|
`.env`에서 교체 가능합니다. 코드 변경 없이 위험/방식만 바꿉니다.
|
|
|
|
| 값 | 방식 | 실시간 | 디스코드 native | 밴 위험 |
|
|
|---|---|---|---|---|
|
|
| `selfbot` (기본) | 버너 유저 계정으로 Go Live 실시간 송출 | ✅ | ✅ | ⚠️ ToS 위반·정지 위험 |
|
|
| `novnc` | noVNC 브라우저 링크 공유 | ✅ | ❌ | 없음 |
|
|
| `screenshot` | N초마다 채널에 스크린샷 업로드 | ❌ | ❌ | 없음 |
|
|
| `none` | 비활성화 | — | — | — |
|
|
|
|
### 셀프봇(selfbot) 주의
|
|
|
|
- 디스코드 봇은 영상 송출이 불가능해, 실시간 화면 방송은 **유저 계정 토큰(셀프봇)** 으로만 됩니다.
|
|
- 이는 Discord ToS 위반이며 계정이 영구 정지될 수 있습니다.
|
|
- 반드시 **버너(일회용) 계정**을 만들어 그 토큰을 `DISCORD_SELFBOT_TOKEN`에 넣고, 본계정은 절대 쓰지 마세요.
|
|
- 영상 송출만 조용히 하는 패턴은 상대적으로 위험이 낮지만 0은 아닙니다.
|
|
- 의존성(네이티브)은 선택 설치입니다:
|
|
```bash
|
|
cd bot && bun add discord.js-selfbot-v13 @dank074/discord-video-stream
|
|
```
|
|
|
|
---
|
|
|
|
## 환경 변수
|
|
|
|
전체 목록과 설명은 [`.env.example`](.env.example)에 있습니다. 핵심:
|
|
|
|
- `DISCORD_BOT_TOKEN`, `DISCORD_APP_ID`, `DISCORD_GUILD_ID` — 봇/길드
|
|
- `BRIDGE_URL` — 봇이 호출할 브릿지 주소 (기본 `http://127.0.0.1:8765`)
|
|
- `STREAM_BACKEND`, `DISCORD_SELFBOT_TOKEN`, `NOVNC_URL` — 화면 송출
|
|
- `VNC_DISPLAY=:1`, `VNC_RESOLUTION`, `VNC_FRAMERATE`, `VNC_BITRATE_KBPS` — 캡처
|
|
- `WHISPER_DEVICE/COMPUTE_TYPE` — RTX 5050이면 `cuda`/`float16` 권장
|
|
|
|
---
|
|
|
|
## 현재 상태 / 남은 작업
|
|
|
|
이 레포는 동작하는 **스캐폴드**입니다. 구조·명령·송출 백엔드·브릿지 연동은 완성되어 있고, 실제 토큰/모델/VNC 디스플레이를 붙여 런타임 검증이 필요한 부분이 남아 있습니다.
|
|
|
|
- [ ] 실제 디스코드 봇/버너 토큰으로 음성 송수신 end-to-end 검증
|
|
- [ ] faster-whisper(CUDA) + Piper 모델로 STT/TTS 실측
|
|
- [ ] 셀프봇 영상 송출 라이브러리 버전별 API 실연결(현재 v6 API 기준 작성)
|
|
- [ ] Ollama 모델 다운로드 및 두뇌 응답 품질 점검
|
|
|
|
---
|
|
|
|
## 크레딧
|
|
|
|
- 두뇌: [isair/jarvis](https://github.com/isair/jarvis) (라이선스는 [LICENSE](LICENSE) 참고)
|
|
- 디스코드 음성: [discord.js](https://discord.js.org) / [@discordjs/voice](https://github.com/discordjs/voice)
|
|
- 영상 송출: [@dank074/discord-video-stream](https://github.com/Discord-RE/Discord-video-stream)
|