예제 소스
바둑 on-policy 학습: 대국 로그를 KataGo 라벨로 바꾸기 · 파일 169개
README.md
# Baduk VLM Server (Gemma 4, Apple Silicon)
19×19 바둑 (`baduk` Qt 클라이언트) 와 짝을 이루는 **VLM TCP 서버**입니다.
Apple Silicon 위에서 [`mlx-vlm`](https://github.com/Blaizzy/mlx-vlm) 으로
**Google Gemma 4** 멀티모달 모델을 돌려, 매 차례 보드 이미지를 보고 다음 수를 결정합니다.
## 요구 사항
- macOS arm64 (M1/M2/M3/M4...)
- Python 3.10 이상
- Hugging Face 계정 (원본 `google/gemma-4-*` 모델은 라이선스 동의 필요. 양자화본 `mlx-community/gemma-4-*` 는 보통 토큰 없이 받을 수 있습니다.)
## 설치
```bash
cd ~/mywork/rl/go
python3 -m venv .venv
source .venv/bin/activate
pip install -r vlm_server/requirements.txt
```
## 모델 다운로드
기본 모델은 `mlx-community/gemma-4-e4b-it-4bit` (≈ 6 GB, Apple Silicon 권장).
```bash
python -m vlm_server download
# 가벼운 대안 (≈ 1.5 GB)
python -m vlm_server download --model mlx-community/gemma-4-e2b-it-4bit
```
원본 google 모델을 받고 싶다면 먼저 `huggingface-cli login` 하세요:
```bash
huggingface-cli login # 토큰 입력
python -m vlm_server download --model google/gemma-4-E4B-it
```
## 서버 실행
```bash
python -m vlm_server serve --port 9319 \
--model mlx-community/gemma-4-e4b-it-4bit
```
옵션:
- `--host ********` (기본): 모든 인터페이스 바인딩
- `--port 9319` (기본): C++ 클라이언트 기본 포트와 동일
- `--max-new-tokens 96` (기본)
- `--temperature 0.2` (기본)
- `--no-load`: 모델을 로드하지 않고 무작위 합법수만 반환 (네트워크/프로토콜 디버그용)
- `--log-jsonl path.jsonl`: 매 요청/응답을 JSONL 로 기록
## 프로토콜 (GO19)
C++ 클라이언트가 보내는 형식:
```
"GO19" (4)
u32 BE body_len
body = u8 size(=19)
u8 ai_side (1=Black, 2=White)
u32 BE png_len
png_bytes
size*size board bytes (0=빈, 1=흑, 2=백, row-major)
```
서버 응답:
```
성공: "RPLY" (4) + u8 flag=1 + u8 row + u8 col (255,255 = 패스)
실패: "RPLY" (4) + u8 flag=0 + u16 BE err_len + utf8 err
PING : "PING" → 응답 "PONG"
```
## 동작 개요
1. 첫 연결 시 모델을 한 번 로드 (영구 메모리 상주). 이후 같은 소켓에서 다중 요청 처리.
2. 매 요청 마다:
- PNG 디코드 → PIL 이미지
- 보드 격자 + AI 색을 텍스트로 직렬화 (좌상단 (0,0) ~ (18,18))
- Gemma 4 에 system + user 프롬프트로 전달, JSON `{"row": int, "col": int}` 또는 `{"pass": true}` 를 요청
- 응답에서 좌표 추출. 위치 점유/범위 외/자살수면 합법수 중 임의 선택 (안전망).
3. 실패 시 RPLY flag=0 으로 에러 메시지 반환.
## 개발 메모
- mlx-vlm 의 `generate()` 는 PIL 이미지 객체도 직접 받습니다.
- prompt 는 `apply_chat_template(processor, config, prompt, num_images=1)` 로 만들어야 모델 종류별 토큰이 올바르게 들어갑니다.
- Gemma 4 의 비전 인코더는 가변 종횡비를 지원하므로 우리 보드 이미지는 720x720 그대로 보내도 OK 입니다.