Commit Graph

13 Commits

Author SHA1 Message Date
EJClaw
0201c7b913 feat: 자막 배경 여백 · 위치 조정 모드 · CPU 추천 · 마이크 입력
Some checks failed
Windows / verify (push) Has been cancelled
요청 네 가지를 넣는다.

1) 자막 배경 여백(padding)
   배경 상자를 창 전체가 아니라 **글자를 감싸는 크기**로 그리도록 바꿨다.
   창 전체를 칠하던 동안에는 여백을 키워도 글자만 안으로 밀릴 뿐 배경
   크기는 그대로여서, 설정 항목을 만들어도 의미가 없었다.

2) 평소 잠금 + '자막 위치 조정'
   locked 기본값을 True 로 바꾼다. 게임 중에 자막을 실수로 끌고 다니는
   사고를 막는 쪽이 기본이어야 한다. 자막 화면의 버튼으로 조정 모드를
   열면 그때만 이동·네 모서리 크기 조절·휠이 열린다. 조정 중에는 클릭
   통과를 강제로 끈다 — 켜둔 채로는 마우스가 창을 지나가 잡을 수 없다.
   크기를 바꾸면 글자 크기가 높이 비율을 그대로 따라간다. 상자만 커지고
   글자가 그대로면 여백만 늘어나 '자막을 키우는' 조작이 되지 않는다.
   조정 모드는 저장하지 않는다. 다음 실행은 다시 잠긴 상태로 시작한다.

3) GPU 가 없을 때 CPU 추천
   티어 표의 recommended 는 GPU 가 넉넉할 때를 전제한 값이라, 그대로
   쓰면 GPU 없는 사람에게 10GB 짜리를 권하게 된다. 환경을 보고 고르는
   recommended_tier() 를 만들고 배지도 그 결과로 붙인다. GPU 가 없으면
   CTranslate2 계열만 후보에 두고 가장 가벼운 쪽을 권한다 — LLM 계열은
   CPU 에서 한 문장에 수십 초가 걸려 실시간 자막이 되지 않는다.
   '추천대로 맞추기' 버튼과, 실제로는 CPU 로 도는데 화면은 GPU 라고
   표시하던 것도 같이 고친다. nvidia-smi 실패 문구가 명령줄을 통째로
   토해내던 것도 사람이 읽을 문장으로 바꿨다.

4) 마이크 등 입력 장치 선택
   InputDeviceCapture 를 추가하고 홈 화면에 목록 전환 버튼을 둔다.
   두 목록을 한 번에 섞지 않는다 — 다 합치면 정작 찾으려던 게임이
   라인입력들 사이에 파묻힌다. 버튼 글자는 '지금 상태'가 아니라
   '누르면 가는 곳'을 적는다. 고른 쪽은 설정에 기억한다.
2026-09-29 13:27:13 +09:00
EJClaw
628280b227 fix: exe 가 켜지자마자 ImportError 로 죽던 것
Some checks failed
Windows / verify (push) Has been cancelled
포터블 exe 를 실행하면 창 대신 오류창만 떴다.

  File "__main__.py", line 1, in <module>
  ImportError: attempted relative import with no known parent package

PyInstaller 는 진입 스크립트를 **패키지 없이** 최상위로 실행한다
(__package__ 가 비어 있다). 그래서 src/livesub/__main__.py 첫 줄의
`from .app import main` 이 그 자리에서 죽는다. 절대 임포트로 바꾼다.
`python -m livesub` 는 둘 다 동작하므로 잃는 것이 없다.

왜 못 잡았나 — exe 점검이 "8초 뒤에도 프로세스가 살아 있으면 통과" 였다.
PyInstaller 오류창은 프로세스를 그대로 띄워둔 채 서 있으므로 통과로
보고됐다. 살아 있는 것은 떴다는 뜻이 아니다. 고친다:

- 프로세스 생존이 아니라 **실제 창**을 본다. onefile 은 자식 프로세스가
  창을 띄우므로 프로세스 트리 전체를 훑는다.
- "Unhandled exception" / "Failed to execute script" 오류창을 보면
  그 자리에서 실패로 판정한다.
- APPDATA 를 빈 폴더로 돌려 첫 실행(저장 위치 화면)과 두 번째 실행
  (본 화면)을 각각 확인한다. 둘 다 실제 창 제목으로 확인한다.
- 같은 회귀를 리눅스에서도 잡도록 runpy 로 패키지 없는 실행을 재현하는
  테스트를 추가한다. 되돌려보면 실제로 실패하는 것을 확인했다.
2026-09-28 18:06:09 +09:00
EJClaw
81e0271b69 feat: 저장 위치를 첫 실행 때 고르고 기억한다
Some checks failed
Windows / verify (push) Has been cancelled
모델이 티어에 따라 2~17GB 를 차지하는데 %APPDATA% 에 박혀 있어서 C 드라이브가
좁은 사람은 손쓸 방법이 없었다. 처음 켤 때 한 번 묻고, 그 선택을 기억하고,
설정에서 바꿀 수 있게 한다.

닭과 달걀 문제가 하나 있다 — "어디에 둘지" 는 사용자가 정하는데 그 선택 자체는
고정된 곳에 적어둬야 다음 실행에 찾을 수 있다. 그래서 OS 표준 폴더에는 위치를
가리키는 쪽지(location.json) 한 장만 두고, 내용물은 전부 고른 폴더에 둔다.

- storage.py 신설: 쪽지 읽기/쓰기, 경로 검증, 여유 공간, 데이터 이동
- config.py 의 CONFIG_PATH 를 config_path() 로 바꾼다. import 시점 상수라
  위치를 바꿔도 옛 경로를 계속 가리켰다
- 위치가 정해지기 전에는 파일 로그를 열지 않는다. 열면 고르지도 않은 기본
  폴더가 만들어지고 거기에 로그가 남는다
- 이전 버전 사용자에게는 묻지 않는다. 기본 위치에 쓰던 흔적이 있으면 그대로
  쓴다 — 같은 자리를 다시 고르는 헛수고를 시킬 이유가 없다
- 고른 디스크가 빠져도 죽지 않고 기본 위치로 물러난다
- 위치를 바꿀 때 받아둔 모델을 옮길지 물어본다. 수 GB 라 창이 얼어붙지
  않도록 별도 스레드에서 옮긴다
- windows_smoke 에 이 화면 렌더링 점검을 추가하고, 스크린샷을 호스트로
  회수한다. 경로 표기와 디스크 조회는 OS 마다 다르게 도는 부분이다
2026-09-26 00:57:04 +09:00
EJClaw
e234ad4401 fix: webrtcvad 가 깔린 환경에서만 분할기 테스트 5개가 깨지던 원인 제거
Windows CI 에서 test_segmenter.py 5개가 실패하고 로컬에서는 통과했다.
플랫폼 차이가 아니라 선택 의존성 차이였다.

테스트 입력은 220Hz 순음이다. `_is_speech` 는 에너지 판정과 webrtcvad 를
AND 로 묶는데, webrtcvad 는 사람 목소리로 학습돼 있어 순음을 발화로 보지
않는다. 포터블 exe 의 requirements 에 webrtcvad-wheels 가 들어 있으니
Windows CI 는 게이트가 켜진 환경이고, 개발 venv 에는 없어서 안 드러났다.
(개발 venv 에 webrtcvad-wheels 를 넣으면 리눅스에서도 5개가 똑같이,
같은 수치로 깨지는 것을 확인했다.)

- 이 파일이 검증하려는 건 분할 상태 기계이므로 autouse fixture 로
  선택 의존성을 끊어 환경과 무관하게 같은 경로를 시험한다
- 게이트 동작 자체는 test_webrtcvad_gate_filters_pure_tone 이 따로 본다
  (webrtcvad 없으면 skip)
- dev extras 에 webrtcvad-wheels 를 넣어 같은 환경 드리프트가 재발하지
  않게 한다
2026-09-25 23:38:17 +09:00
EJClaw
8a86e7e7ac fix: 티어 게이트가 실제 제약(autoawq·VRAM)을 보도록 수정
Some checks failed
Windows / verify (push) Has been cancelled
실제 GPU 로 검증을 돌리다 발견한 버그다. tier_availability() 가 torch 유무만
봐서, RTX 5050(7.5GB)에서도 정밀·극한 티어를 "사용 가능"이라고 답했다.

  정밀(AWQ Int4)  autoawq 가 있어야 로드된다. requirements.txt 에 없는
                  선택 의존성이라 대개 없다.
  극한(Qwen3-8B)  min_vram_gb=16. 7.5GB 카드에서는 영영 불가능하다.

둘 다 "고를 수 있다"고 해놓고 로드에서 죽는다. 사용자는 원인을 알 수 없다.
UI 에 min_vram_gb 경고 배지는 있었지만 경고만 하고 선택은 막지 않았다.

- tier_availability(tier, gpu=None) 에 autoawq·VRAM 검사 추가.
  새 필드를 만들지 않고 이미 있던 min_vram_gb 를 쓴다.
  free 가 아니라 total 로 본다 — free 로 막으면 다른 프로그램 때문에
  "아까는 되던 티어가 지금은 안 보인다"가 된다.
  CT2 티어(1~3)는 조기 반환이라 detect_gpu 를 아예 부르지 않는다.
  (포터블에서 torch 도 GPU 도 없이 돌아야 하므로)

- GpuInfo 를 인자로 받아 루프에서 nvidia-smi 반복 호출을 막았다.
  models_page 는 티어 카드 5개를 만들며 매번 조회하던 것을 __init__ 에서
  한 번만 하도록 바꿨다. 빌더 함수의 부수효과에 의존하던 것도 제거.

- 점검기의 판정 기준도 고쳤다. 기존엔 "4·5티어가 전부 열려야 통과"였는데
  VRAM 작은 GPU 에서 막히는 건 정상이라 오탐이었다. 이제 게이트는 판정
  없이 보고만 하고, "게이트가 된다고 한 티어가 실제로 올라가는지" 가
  판정한다. 게이트가 전부 막았으면 검증 대상이 없다는 사실을 남기고
  통과시킨다 — 하드웨어 한계이지 회귀가 아니다.

- scripts/gpu-check.sh 추가. CTranslate2 가 libcublas.so.12 를 직접 찾는데
  torch 의 nvidia 패키지 안에 있어 LD_LIBRARY_PATH 가 필요하다. 없으면
  GPU 번역만 조용히 실패한다. 스크립트가 경로를 자동으로 잡는다.

검증: pytest 190 passed (신규 4개 중 3개는 torch 필요 -> gpu-venv 에서
      실제로 실행해 9 passed 확인), ruff clean,
      RTX 5050 에서 scripts/gpu-check.sh 6/6 통과 (종료코드 0)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-09-23 03:55:22 +09:00
EJClaw
8d91087f85 ci: GPU 없는 서버 Windows VM 지원 + 전 파이프라인 자동 검증
Some checks failed
Windows / verify (push) Has been cancelled
RTX 5050 은 PCIe 패스스루로 이 VM(.9)이 독점하므로 Proxmox 에 Windows VM 을
띄워도 GPU 를 못 준다. 그래서 "Windows 검증에 GPU 가 정말 필요한가"를 실제로
재봤다 — GPU 를 완전히 가린 채 점검기를 돌린 결과, 실패한 건 'GPU 인식' 하나뿐이고
그건 이미 경고 처리라 빌드를 막지 않는다. 나머지(단축키·모니터·오디오 열거·
exe 빌드·기동·오버레이 렌더링)는 전부 통과한다. 즉 GPU 없는 서버 VM 으로 충분하고,
CUDA/VRAM 관련은 GPU 가 물려 있는 .9 에서 이미 검증 중이다.

- tests/fixtures/en_callout_16k.wav (139KB)
  MeloTTS 로 만든 4.4초 영어 콜아웃. CI 가 실제 음성으로 검증할 수 있게 커밋.

- windows_smoke.py --pipeline
  오디오 파일 -> 음성인식 -> 번역 -> 한국어 자막까지 끝까지 확인한다.
  부품이 다 통과해도 이어 붙이면 안 되는 경우를 잡기 위한 것.
  CPU + 가장 가벼운 티어로 돌려 GPU 없는 VM 에서도 그대로 된다.
  실측: 27초, 'Enemy coming from the left, fall back now.'
        -> '적 왼쪽에서 오는, 지금 뒤로 물러서.'
  음성인식 결과에 핵심 단어가 있는지, 자막에 한글이 있는지까지 검사한다.

- 워크플로에 해당 단계 추가 (30분 타임아웃, 첫 회만 모델 다운로드)

- docs/WINDOWS-TESTING.md 에 서버 VM 구축 절차
  Proxmox qm create 예시와 함께, 빠뜨리면 조용히 실패하는 두 가지를 명시:
  (1) --audio0 없으면 오디오 장치가 안 잡혀 WASAPI 점검이 실패
  (2) 자동 로그온이 없으면 데스크톱 세션이 없어 GUI/스크린샷이 전부 실패
      (러너를 서비스로 돌리면 안 되는 실질적 이유이기도 하다)

검증: pytest 189개 통과, ruff clean, 워크플로 11스텝 파싱 확인(bash 0개),
      GPU 숨긴 조건에서 점검기 실행, --pipeline 실제 통과

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-09-23 03:32:35 +09:00
EJClaw
bede94ee48 fix: 포터블에 transformers 포함 + 실제 모델로 드러난 용어집 결함 수정
리뷰 지적(포터블에서 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>
2026-09-23 01:20:42 +09:00
EJClaw
71436843d8 feat: 존댓말/반말 모드, 포터블 exe 빌드, AI 로고/배너
말투 (존댓말 기본, 반말 선택)
- 원문이 실제로 존댓말이면 반말 모드여도 존댓말을 지킨다. 상대가 정중하게
  말했는데 자막이 반말이면 뉘앙스가 뒤집히기 때문.
- 영어·중국어는 문법적 높임이 없으므로 항상 고른 모드를 따른다.
  "please" 를 존댓말 근거로 삼으면 오탐이 많아 쓰지 않았다.
- 낮춤 변환은 한글 자모를 분해해 실제 활용 규칙(모음조화 + 축약)을 구현했다.
  오+아->와, 지+어->져, 하+어->해, 았/었 뒤는 항상 어, 치겠습니다->칠게.
  어미를 나열하는 방식보다 훨씬 넓게 맞는다.
- 변환 방향은 존댓말->반말 한쪽만 한다. 번역 모델의 한국어 출력이 이미
  격식체라 존댓말 모드는 손댈 필요가 없고, 반대 방향은 훨씬 자주 틀린다.
- 지시문을 이해하는 Qwen3 에는 프롬프트로도 전달한다. Seed-X 는 지시문을
  못 알아듣는 모델이라 후처리로만 맞춘다.

포터블 exe
- PyInstaller 명세 + 빌드 스크립트. torch 를 의도적으로 제외했다.
  torch+CUDA 만 2.5GB 라 onefile 로 묶으면 실행할 때마다 그걸 임시폴더에
  푸느라 1분 넘게 걸려 쓸 수 없다.
- 음성인식(faster-whisper)도 번역(NLLB)도 CTranslate2 위에서 돌아 torch 가
  필요 없다. 덕분에 1~3티어는 그대로 다 되고 exe 는 3GB -> 500MB 가 된다.
- 4~5티어는 못 쓰므로 tier_availability() 로 판정해 모델 화면에 '사용 불가'와
  이유를 표시한다. torch 없는 환경에서 앱 전체가 뜨는 것을 확인했다.

AI 이미지
- SDXL-turbo 로 아이콘/배경 생성 (로컬 GPU, 피크 VRAM 1.9GB).
- 글자는 AI 가 제대로 못 쓰므로 아트만 AI 로 만들고 타이포그래피는
  정확히 렌더링해 합성했다. icon.ico 는 16~256px 멀티해상도.

검증: pytest 163개 통과 (말투 53개 신규), ruff clean

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-09-23 01:06:23 +09:00
EJClaw
e4a048c8d5 fix: 필수 팩 기본 활성화 + 저부하 모드 토글 반영 + 용어 겹침 수정
리뷰 지적 2건과, 그것을 고치다 드러난 용어집 버그 1건을 함께 처리했다.

1) 저부하 모드 토글이 모델에 반영되지 않던 버그
   ModelManager 는 생성 시점의 low_power 로 정밀도를 정하는데 설정에서
   토글해도 갱신되지 않았고, stop() 은 모델을 내리지 않아 이전 정밀도
   모델이 그대로 남았다. TranslationEngine.sync_performance() 를 추가해
   값이 바뀌면 언로드 후 갱신하고, _bootstrap 과 재시작 경로에서 부른다.

2) 필수 게임 팩이 기본으로 꺼져 있던 문제
   새 설치 기본값을 fps-common + 오버워치 + 배그 + R6 + 워독스로 켰다.

3) (1)(2)를 고치며 드러난 것: 팩 여러 개를 켜면 결과가 체크 순서에
   휘둘렸다. knocked 가 FPS공통 "기절" / 배그 "눕혔다" 로 갈리는 식으로
   19개 용어가 충돌하는데, 사용자는 그 순서를 볼 수도 바꿀 수도 없었다.
   팩에 scope(generic/game) 를 두고 범용 -> 게임 전용 -> 사용자 항목
   순으로 적용해 결정적으로 만들었다. 게임 팩끼리 갈리는 것은 사람이
   판단할 문제라 find_conflicts() 로 뽑아 용어집 화면에 표시한다.

4) 용어 겹침 버그: "the blue"(조각)가 "blue zone" 보다 앞 위치라는
   이유로 먼저 잡혀 "자기장 자기장" 이 됐다. 최장일치 정렬은 같은 시작
   위치에서만 통한다. 조각 항목을 제거하고, 모든 팩을 켠 상태로 각
   용어가 정확히 한 번만 치환되는지 검사하는 테스트를 추가했다.

검증: pytest 110개 통과 (저부하 6 + 팩 계층/충돌/겹침 12 신규), ruff clean

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-09-21 18:05:22 +09:00
EJClaw
a7eafd03e1 feat: 지정 게임 용어집 추가 (워독스·배그·R6·에이펙스)
사용자가 필수로 지정한 게임 중 오버워치를 뺀 세 개가 빠져 있었다.

- 레인보우 식스 시즈 67개 — 보강·하드브리치·앵커/로머·디퓨저·런아웃
- 배틀그라운드 66개 — 자기장·어부·낙하·파밍·3렙헬멧·스쿼드 콜
- 워치독스 59개 — 데드섹·ctOS·블룸·알비온 등 조직명과 해킹/잠입 용어
- 에이펙스 레전드 45개 — 링·배너·리스폰 비컨 (등등 항목으로 추가)

워치독스는 멀티 콜아웃이 아니라 스토리 대사가 주라, 번역기가 특히 잘 틀리는
고유명사(조직명)와 해킹 용어 위주로 골랐다.

전용 팩이 생긴 만큼 'FPS 공통' 설명을 장르 공통 콜로 좁혔다.
필수 게임이 빠지면 바로 잡히도록 test_required_games_are_bundled 추가.

번들 용어 304개 → 541개 (10개 팩)
검증: pytest 92개 통과, ruff clean

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-09-21 17:54:20 +09:00
EJClaw
8b36b244ff feat: LiveSub 2차 — 자막 on/off, 모니터·위치 선택, GPU 저부하, 게임 용어집
이름을 Hearo → LiveSub 로 변경. 말장난보다 하는 일이 바로 보이는 쪽이 낫다.

자막 on/off
- 전역 단축키 Ctrl+Alt+S (자막) / Ctrl+Alt+D (번역) — Windows RegisterHotKey +
  네이티브 이벤트 필터라 게임 창이 떠 있어도 동작. 다른 OS 에서는 no-op
- 단축키·체크박스·우클릭 메뉴가 모두 같은 경로를 타도록 통합

모니터 선택 + 디스코드식 배치
- placement.py: Qt 비의존 배치 계산 (모니터 목록 → 9분할 좌표)
- AnchorGrid 위젯으로 3x3 위치 선택, 드래그하면 자유 배치로 전환
- 모니터 구성이 바뀌어도 자막이 화면 밖으로 사라지지 않도록 클램프

GPU 저부하 모드 (기본 켜짐)
- 연산 정밀도 int8 강등, VRAM 상한 35%, 추론 후 60ms 양보,
  300초 무음 시 모델 언로드, 중간 결과 비활성
- 기본 티어를 균형(6GB) → 신속(4GB) 으로 하향
- 8GB GPU 기준 자막 2.8GB / 게임 5.2GB

게임 용어집 번들 (304개)
- 롤 74 · 발로란트 59 · 오버워치2 49 · FPS공통 46 · 마크 38 · 방송 38
- 체크박스로 켜고 끄며, 사용자가 직접 등록한 항목이 항상 우선

검증: pytest 91개 통과 (배치 14 + 팩 12 + UI 6 신규), ruff clean

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-09-21 17:49:26 +09:00
EJClaw
5596f905d1 fix: Seed-X 프롬프트 형식과 티어별 용어집 전략 수정
4티어(Seed-X-PPO-7B) 번역 경로가 모델 카드 요구사항을 어기고 있었다.

- 프롬프트 끝의 `<ko>` 등 대상 언어 태그가 빠져 있었다. PPO 학습에 쓰인
  신호라 없으면 번역 품질이 흔들린다.
- Seed-X 는 chat template 없는 번역 전용 completion 모델인데 "구어체로
  자연스럽게" 같은 지시문 래퍼를 씌우고 있었다. 학습 분포를 벗어난다.
- 그 결과 MTSpec.supports_prompt_glossary=True 가 사실과 달랐다.
  Seed-X 는 용어집 지시문을 이해하지 못하므로 플레이스홀더 치환을 써야 한다.

수정
- PromptStyle(NONE/SEEDX/INSTRUCT) 도입, supports_prompt_glossary 를
  prompt_style 에서 파생시켜 둘이 어긋날 수 없게 함
- build_seedx_prompt() 로 모델 카드 형식을 분리 (지시문 주입 불가)
- INSTRUCT 경로는 chat template 사용, Qwen3 thinking 모드는 끔
- LANGUAGES 에 seedx 태그 명시
- finetune_mt.py 가 티어의 prompt_style 을 따라가게 해 학습/추론 프롬프트 일치
- AWQ Int4 로드 실패 시 autoawq 설치 안내를 담은 오류 메시지

검증: pytest 52개 통과 (프롬프트 회귀 테스트 13개 추가), ruff clean

근거: https://huggingface.co/ByteDance-Seed/Seed-X-PPO-7B

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-09-21 10:56:49 +09:00
EJClaw
1a87ec6677 feat: Hearo 1차 구현 — 프로그램 소리 실시간 번역 자막
프로그램별 오디오를 캡처해 로컬 GPU에서 음성인식→번역하고 화면 위
자막으로 보여주는 데스크톱 앱. 한/영/일/중 4개 언어.

구성
- audio: WASAPI 프로그램별 캡처(C++ 보조 프로그램) + 장치 루프백 폴백,
  적응형 VAD 발화 분할
- models: 속도~품질 5단계 티어, faster-whisper + CTranslate2/LLM 2백엔드,
  용어집(플레이스홀더 보호 + 프롬프트 주입)
- core: Qt 비의존 파이프라인 엔진 (캡처/분할/추론 3스레드, 큐 연결)
- ui: 사이드바 5화면 + 무테두리 항상위 자막 오버레이, 자체 다크 테마

모델 선정 근거는 docs/MODELS.md, 추가학습 가능 여부와 방법은
docs/FINETUNING.md 참고.

검증: pytest 39개 통과 (GPU·오디오 장치 없이 실행), ruff clean

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-09-21 10:47:11 +09:00