리뷰 지적(포터블에서 transformers 제외 -> NLLB 로드 실패)을 고치려고 실제
NLLB 를 받아 돌려봤고, 그 과정에서 용어집이 사실상 동작하지 않고 있었다는
것을 발견했다. 단위 테스트는 "모델이 자리표시자를 통과시킨다"는 틀린 전제
위에 서 있었다.
1) 포터블 패키징 (리뷰 지적)
transformers 를 제외 목록에서 빼고 hiddenimports 에 넣었다. NLLB
토크나이저가 AutoTokenizer 를 쓰기 때문이다. transformers 는 torch 가
없으면 토크나이저 전용 모드로 뜨며 그게 우리 용도와 정확히 맞는다.
torch 없는 환경에서 ctranslate2/transformers/faster-whisper import 와
앱 기동을 검증하는 test_portable.py 를 추가했다.
2) 자리표시자 형식 (실측으로 발견)
`⟦0⟧` 는 NLLB 가 괄호를 날려 생존률 0/3 이었다. 용어가 자막에서 그냥
사라지고 있었다 ("Third party incoming" -> "0 들어오는"). 후보 8종을
실제 모델로 비교해 `#0#` 로 교체 (3/3, 다중 4/5).
3) 소실 대비
모델이 문장 일부를 누락하면 자리표시자도 사라진다. 그대로 복원하면
용어가 증발하므로, 하나라도 없으면 보호 없이 재번역한다.
4) 서술어는 문장 전체일 때만 (whole_only)
절/서술어를 문장 중간에서 치환하면 문법이 무너진다.
before: "탄 필요해와 구급상자"
after : "탄약과 구급상자가 필요합니다"
해당 56개 항목을 whole_only 로 지정해 단독 발화일 때만 적용한다.
("Cover me!" -> "엄호해줘" 는 그대로 유지)
5) 조사 교정
역어 받침이 달라 "자기장를" 이 남던 것을 fix_particles() 로 고친다.
을/를, 이/가, 은/는, 과/와, (으)로 — 한글 코드에서 받침을 읽어 판정.
검증: pytest 189개 통과, ruff clean
실제 NLLB-600M(torch 없이 CPU)로 번역 품질 직접 확인
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
294 lines
11 KiB
Markdown
294 lines
11 KiB
Markdown
# LiveSub — 게임 소리를 실시간 자막으로
|
|
|
|

|
|
|
|
게임이나 프로그램에서 나오는 소리를 실시간으로 받아 번역해, 화면 위에 자막으로 얹어줍니다.
|
|
디스코드 오버레이처럼 동작하고, 번역은 전부 **내 컴퓨터의 GPU에서** 돌아갑니다.
|
|
인터넷도, API 키도 필요 없습니다.
|
|
|
|
한국어 · English · 日本語 · 中文 사이를 번역합니다.
|
|
|
|
---
|
|
|
|
## 무엇을 하는 프로그램인가
|
|
|
|
게임을 하는데 영어 음성만 나올 때, 해외 방송을 보는데 자막이 없을 때,
|
|
그 프로그램을 골라서 `번역 시작`만 누르면 화면에 한국어 자막이 뜹니다.
|
|
|
|
```
|
|
게임 소리 → 음성인식 → 번역 → 화면 위 자막
|
|
(Whisper) (Seed-X / NLLB)
|
|
```
|
|
|
|

|
|
|
|
## 주요 기능
|
|
|
|
- **프로그램 단위 소리 캡처** — 게임 소리만 받고 디스코드 음성은 안 받습니다
|
|
- **게임과 같이 써도 안 무겁게** — GPU를 얼마나 양보할지 직접 정합니다 (아래 참고)
|
|
- **디스코드식 자막 배치** — 모니터를 고르고 9칸 중 하나를 누르면 그 자리에 붙습니다
|
|
- **전역 단축키** — 게임 중에 `Ctrl+Alt+S` 로 자막을 껐다 켭니다
|
|
- **게임별 기본 용어집 내장** — 옵치2·워독스·배그·R6·롤·발로란트·에이펙스 등 **540개** (필수 게임은 기본 켜짐)
|
|
- **5단계 품질 선택** — 속도 우선(0.6초)부터 품질 우선까지
|
|
- **자막 자유 설정** — 글꼴·크기·색·외곽선·투명도·줄 수
|
|
- **추가학습** — 게임/방송 말투로 번역 모델을 LoRA 학습시킬 수 있습니다
|
|
- **존댓말 / 반말 선택** — 기본은 존댓말. 원문이 실제로 존댓말이면 반말 모드여도 존댓말을 지킵니다
|
|
- **포터블 exe** — 설치 없이 파일 하나로 실행 (아래 참고)
|
|
- **완전 로컬** — 음성이 외부로 나가지 않습니다
|
|
|
|
---
|
|
|
|
## 게임과 같이 쓰기 (GPU 절약)
|
|
|
|
게임이 먼저입니다. `설정` 화면의 **저부하 모드**(기본 켜짐)가 이렇게 동작합니다.
|
|
|
|
| 항목 | 기본값 | 하는 일 |
|
|
|---|---|---|
|
|
| 연산 정밀도 | int8 | VRAM 사용량과 연산량을 줄입니다 |
|
|
| VRAM 상한 | 35% | 게임이 쓸 VRAM을 먼저 확보합니다 |
|
|
| GPU 양보 시간 | 60ms | 문장 하나 처리 후 GPU를 잠깐 놓습니다 |
|
|
| 유휴 시 모델 해제 | 300초 | 조용하면 모델을 내려 VRAM을 통째로 반납합니다 |
|
|
| 중간 결과 | 꺼짐 | 같은 오디오를 두 번 인식하지 않습니다 |
|
|
|
|
8GB GPU 기준으로 자막이 약 2.8GB만 쓰고 나머지 5GB 이상을 게임에 남깁니다.
|
|
게임이 여전히 버벅이면 VRAM 상한을 낮추거나 모델 티어를 `1. 번개`로 내리세요.
|
|
|
|

|
|
|
|
## 말투 — 존댓말 / 반말
|
|
|
|
홈 화면에서 고릅니다. **기본은 존댓말**입니다.
|
|
|
|
| 상황 | 존댓말 모드 | 반말 모드 |
|
|
|---|---|---|
|
|
| 영어·중국어 원문 (높임 없음) | 존댓말 | 반말 |
|
|
| 일본어 원문이 `です/ます` | 존댓말 | **존댓말** |
|
|
| 일본어 원문이 반말 | 존댓말 | 반말 |
|
|
|
|
**원문이 실제로 존댓말이면 반말 모드여도 존댓말로 나옵니다.** 상대가 정중하게
|
|
말했는데 자막이 반말이면 뉘앙스가 통째로 뒤집히기 때문입니다.
|
|
영어·중국어는 문법적 높임이 없어서 항상 고른 모드를 따릅니다.
|
|
|
|
```
|
|
Enemy coming from the left 존댓말 → 적이 왼쪽에서 옵니다
|
|
반말 → 적이 왼쪽에서 와
|
|
左から来ます (정중) 존댓말 → 적이 왼쪽에서 옵니다
|
|
반말 → 적이 왼쪽에서 옵니다 ← 원문이 존댓말
|
|
```
|
|
|
|
## 자막 위치 잡기
|
|
|
|
`자막` 화면에서 **모니터를 고르고 네모칸을 누르면** 그 자리에 붙습니다.
|
|
디스코드 오버레이와 같은 방식입니다. 미세 조정은 자막을 직접 드래그하면 되고,
|
|
그러면 그 위치를 그대로 기억합니다.
|
|
|
|

|
|
|
|
| 단축키 | 동작 |
|
|
|---|---|
|
|
| `Ctrl+Alt+S` | 자막 켜기 / 끄기 |
|
|
| `Ctrl+Alt+D` | 번역 시작 / 정지 |
|
|
|
|
전역 단축키라 **게임 창이 떠 있어도 동작합니다** (Windows 전용). `설정`에서 바꿀 수 있습니다.
|
|
|
|
---
|
|
|
|
## 설치 — 둘 중 하나
|
|
|
|
| | 포터블 (권장) | 일반 설치 |
|
|
|---|---|---|
|
|
| 준비물 | `LiveSub.exe` 하나 | Python + PyTorch |
|
|
| 크기 | 약 500~700MB | 약 3GB |
|
|
| 쓸 수 있는 티어 | 1~3 | 1~5 전부 |
|
|
| 번역 품질 | NLLB | NLLB + Seed-X / Qwen3 |
|
|
|
|
포터블은 PyTorch를 빼서 만듭니다 (토크나이저용 `transformers`는 포함). PyTorch+CUDA만 2.5GB라 한 파일로 묶으면
|
|
**실행할 때마다** 그걸 임시폴더에 푸느라 1분 넘게 걸리기 때문입니다.
|
|
음성인식도 번역도 CTranslate2 위에서 돌아가 PyTorch가 필요 없으므로,
|
|
1~3티어는 포터블에서 그대로 다 됩니다.
|
|
|
|
### 포터블 만들기
|
|
|
|
```powershell
|
|
powershell -ExecutionPolicy Bypass -File packaging\build-portable.ps1
|
|
```
|
|
|
|
`dist\LiveSub.exe` 하나만 복사하면 끝입니다. 모델은 exe에 없고 첫 실행 때
|
|
`%APPDATA%\LiveSub\models`로 내려받습니다.
|
|
|
|
---
|
|
|
|
## 일반 설치
|
|
|
|
### 1. 사전 준비
|
|
|
|
- Windows 10 (2004 이상) 또는 Windows 11
|
|
- NVIDIA GPU (권장 VRAM 6GB 이상) + 최신 드라이버
|
|
- Python 3.10 ~ 3.12
|
|
|
|
### 2. PyTorch (CUDA 빌드) 먼저
|
|
|
|
CPU 버전이 깔리면 GPU를 못 씁니다. 반드시 이 순서로 설치하세요.
|
|
|
|
```powershell
|
|
py -3.12 -m venv .venv
|
|
.venv\Scripts\activate
|
|
|
|
# Blackwell(RTX 50 시리즈)은 cu128, 그 이전 세대는 cu124
|
|
pip install torch --index-url https://download.pytorch.org/whl/cu128
|
|
```
|
|
|
|
### 3. 나머지 설치
|
|
|
|
```powershell
|
|
pip install -r requirements.txt
|
|
pip install -e .
|
|
```
|
|
|
|
### 4. 프로그램별 캡처 켜기 (선택, 권장)
|
|
|
|
이걸 빌드하지 않으면 출력 장치 전체 소리를 받습니다 (다른 앱 소리도 섞임).
|
|
|
|
```powershell
|
|
# Visual Studio 2022 Build Tools (C++ 데스크톱) + CMake 필요
|
|
winget install Microsoft.VisualStudio.2022.BuildTools
|
|
winget install Kitware.CMake
|
|
|
|
powershell -ExecutionPolicy Bypass -File native\process_loopback\build.ps1
|
|
```
|
|
|
|
### 5. 실행
|
|
|
|
```powershell
|
|
livesub
|
|
```
|
|
|
|
또는 `python -m livesub`
|
|
|
|
---
|
|
|
|
## 처음 쓸 때
|
|
|
|
1. **홈** 화면에서 소리를 받아올 프로그램을 고릅니다
|
|
2. 원본 언어(자동 감지 권장)와 번역할 언어를 고릅니다
|
|
3. **용어집** 화면에서 하는 게임을 체크합니다 (고유명사 오역이 확 줄어듭니다)
|
|
4. **자막** 화면에서 모니터와 위치를 정합니다
|
|
5. `번역 시작` — 또는 게임 중에 `Ctrl+Alt+D`
|
|
|
|
모델 티어 기본값은 `2. 신속`입니다. 게임과 같이 돌리기 좋은 지점이라 그렇게 잡았고,
|
|
VRAM이 넉넉하면 **모델** 화면에서 올리면 됩니다.
|
|
|
|
모델은 처음 한 번만 자동으로 내려받습니다 (2~17GB, 티어에 따라 다름).
|
|
저장 위치는 `%APPDATA%\LiveSub\models` 입니다.
|
|
|
|

|
|
|
|
---
|
|
|
|
## 모델 티어
|
|
|
|
| # | 이름 | VRAM | 지연 | 설명 |
|
|
|---|---|---|---|---|
|
|
| 1 | 번개 | 2GB | 0.6초 | 속도 최우선. 저사양 GPU |
|
|
| 2 | **신속** | 4GB | 0.9초 | **기본값.** 인식률은 최상급, 번역만 경량 |
|
|
| 3 | 균형 | 6GB | 1.2초 | 게임을 안 켜고 볼 때 무난 |
|
|
| 4 | **정밀** | 10GB | 2.0초 | **추천.** 현 시점 최고 번역 품질 |
|
|
| 5 | 극한 | 16GB | 3.0초 | 추가학습(LoRA)에 최적 |
|
|
|
|
어떤 모델을 왜 골랐는지는 [docs/MODELS.md](docs/MODELS.md)에 정리했습니다.
|
|
|
|
---
|
|
|
|
## 용어집
|
|
|
|
게임 고유명사가 이상하게 번역될 때 씁니다. **학습이 필요 없고 즉시 적용됩니다.**
|
|
|
|
### 기본 제공 용어집
|
|
|
|
**처음 설치하면 `FPS 공통 · 오버워치2 · 배그 · R6 · 워독스`가 이미 켜져 있습니다.**
|
|
안 하는 게임은 체크를 끄면 됩니다.
|
|
|
|
| 팩 | 개수 | 내용 |
|
|
|---|---|---|
|
|
| 리그 오브 레전드 | 74 | 바론·갱·억제기·한타·오브젝트 콜 |
|
|
| 레인보우 식스 시즈 | 67 | 보강·하드브리치·앵커/로머·디퓨저·파밸 |
|
|
| 배틀그라운드 | 65 | 자기장·어부·파밍·낙하·스쿼드 콜 |
|
|
| 발로란트 | 59 | 스파이크·설치·해체·이코·리테이크 |
|
|
| 워치독스 | 59 | 데드섹·ctOS·블룸·해킹/잠입 용어 |
|
|
| 오버워치 2 | 49 | 궁 게이지·거점·화물·역할군 |
|
|
| FPS 공통 | 46 | 장르 전반의 총기·교전·파티 콜 |
|
|
| 에이펙스 레전드 | 45 | 링·배너·리스폰 비컨·스쿼드 콜 |
|
|
| 마인크래프트 | 38 | 블록·몹·차원 이름 (한국어판 공식 번역어) |
|
|
| 방송·스트리밍 | 38 | 후원·구독·클립·메타 등 방송 말투 |
|
|
|
|
#### 여러 팩을 같이 켜면
|
|
|
|
적용 순서는 **장르 공통 → 게임 전용 → 내가 등록한 것** 입니다. 뒤에 오는 쪽이 이기므로
|
|
`knocked`는 배그를 켰으면 항상 "눕혔다"(배그)가 되고, 체크한 순서에 휘둘리지 않습니다.
|
|
|
|
게임 전용 팩끼리 역어가 갈리는 경우(예: `payload`가 오버워치는 "화물", 워독스는 "페이로드")는
|
|
용어집 화면이 어떤 단어인지 알려줍니다. 안 하는 게임을 끄거나, 원하는 역어를 직접
|
|
등록하면 됩니다.
|
|
|
|

|
|
|
|
### 직접 추가하기
|
|
|
|
`용어집` 화면 표에 입력하거나 CSV로 가져오세요.
|
|
**같은 단어를 직접 등록하면 기본 팩보다 항상 우선합니다.**
|
|
|
|
```csv
|
|
원문 용어,한국어 역어,English 역어,日本語 역어,中文 역어,메모
|
|
Nexus,넥서스,Nexus,ネクサス,基地,LoL
|
|
baron,바론,Baron,バロン,男爵,LoL
|
|
```
|
|
|
|
## 추가학습
|
|
|
|
말투나 문장 구조까지 바꾸고 싶다면 LoRA로 학습시킬 수 있습니다.
|
|
언어쌍당 문장 1,000~3,000개가 필요합니다.
|
|
|
|
```powershell
|
|
pip install -e ".[finetune]"
|
|
python scripts\finetune_mt.py --data data\game.jsonl --tier ultimate --output .\adapters\game-ko
|
|
```
|
|
|
|
데이터를 어떻게 모으고 어느 모델을 학습시켜야 하는지는
|
|
[docs/FINETUNING.md](docs/FINETUNING.md)를 참고하세요.
|
|
|
|
---
|
|
|
|
## 자막 창 조작
|
|
|
|
| 동작 | 결과 |
|
|
|---|---|
|
|
| `Ctrl+Alt+S` | 자막 켜기 / 끄기 (게임 중에도 동작) |
|
|
| 드래그 | 위치 이동 (자유 배치로 전환) |
|
|
| 우하단 모서리 드래그 | 크기 조절 |
|
|
| 마우스 휠 | 글자 크기 |
|
|
| 우클릭 | 잠금 / 클릭 통과 / 항상 위에 / 숨기기 |
|
|
|
|
클릭 통과는 기본으로 켜져 있어, 자막 위를 클릭해도 게임으로 전달됩니다.
|
|
위치를 옮기려면 `자막` 화면에서 클릭 통과를 잠깐 끄세요.
|
|
|
|
전체화면 게임에서 자막이 안 보이면 게임을 **테두리 없는 창 모드**로 바꾸세요.
|
|
독점 전체화면(exclusive fullscreen)에서는 어떤 오버레이도 표시되지 않습니다.
|
|
|
|
---
|
|
|
|
## 개발
|
|
|
|
```bash
|
|
pip install -e ".[dev]"
|
|
pytest # GPU·오디오 장치 없이 실행됩니다
|
|
ruff check src tests scripts
|
|
```
|
|
|
|
구조는 [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)를 보세요.
|
|
|
|
## 라이선스
|
|
|
|
MIT. 사용하는 모델은 각자의 라이선스를 따릅니다
|
|
(Whisper: MIT, NLLB: CC-BY-NC, Seed-X: OpenMDW, Qwen3: Apache-2.0).
|
|
**NLLB는 비상업적 이용만 허용됩니다.** 상업적으로 쓰려면 4~5티어를 사용하세요.
|