로컬 어시스턴트를 위한 소형 온디바이스 음성 프런트엔드 구축: 원하는 웨이크 워드를 입력하고, STT 전 사용자 목소리만 유지하는 방법 (5개
요약
본 글은 로컬 온디바이스 환경에서 작동하는 소형 음성 프런트엔드 시스템 'Alkove'를 소개합니다. 이 시스템은 웨이크 워드를 텍스트로 처리하고, 사용자 목소리만 유지하며, STT 전에 노이즈와 다른 사람의 대화를 효과적으로 제거하여 실시간 음성 에이전트의 정확도를 높이는 데 중점을 둡니다.
핵심 포인트
- Alkove는 Lex, Spot, Timbre, Focus, Cue 등 5가지 소형 모델로 구성되어 온디바이스에서 작동합니다.
- Focus 모듈은 사용자 목소리만 유지하고 노이즈 및 다른 사람의 대화를 제거하여 STT 정확도를 높입니다.
- 시스템은 Rust 기반의 경량 추론 엔진을 사용하며 WebAssembly, Python, Android 네이티브 환경을 지원합니다.
- 브라우저 AudioWorklet에서 모델을 실행할 수 있어 COOP/COEP 헤더가 필요 없습니다.
GitHub: https://github.com/alkove-ai/alkove (Apache-2.0, 코드 및 가중치)
안녕하세요 r/LocalLLaMA 여러분,
먼저 저에 대해 간단히 말씀드리자면, 저는 프로덕션 환경에서 LLM 시스템을 구축하는 일을 합니다. RAG가 포함된 툴 호출 어시스턴트와 두 개의 오디오 중심 파이프라인을 다루고 있습니다.
첫 번째 파이프라인은 회사 최신 콘텐츠를 여러 언어로 된 두 호스트의 라디오 쇼로 변환합니다: 출처별 요약, LLM 검증기 및 코드 체크를 거쳐 출처와 대조되는 구조화된 스크립트, 턴(turn)마다 TTS 호출을 통해 Whisper가 모든 턴을 전사하여 잘리거나 지어낸 발화를 포착하고, 마지막으로 코드와 ffmpeg로 마스터링합니다 (턴별 레벨링, 호스트 간 시뮬레이션 오버랩, 라우드니스 정규화, 단어 타임스탬프에 맞춰진 자막).
두 번째는 브라우저에서 작동하는 실시간 음성 에이전트입니다: 클라이언트 측 VAD 및 노이즈 감소(denoising), STT 폴백 체인, 각 세그먼트를 기반으로 턴 종료 여부, 바지인(barge-in) 및 '정지'를 판단하는 소형 결정 모델, 그리고 문장 단위로 읽어주는 TTS입니다. 이 에이전트에서 가장 큰 문제는 LLM 자체에 있는 것이 아니라 그 이전 단계에 있었습니다: 사용자를 둘러싼 사람들의 대화가 전사본에 포함되어 잘못된 바지인을 유발했고, 노이즈 감소기 역시 다른 목소리도 음성이기 때문에 도움을 줄 수 없었습니다. 그래서 저는 이 오디오 레이어, 즉 Speech-to-Text와 LLM보다 먼저 실행되는 부분에 대한 작업을 시작했으며, 이를 초기 프리뷰로 공유합니다. 이것은 Alkove라는 이름의 다섯 가지 소형 모델이 기기에서 함께 작동하도록 설계된 것입니다.
- Lex (1.8 MB): 입력된 단어를 가장 가능성 있는 발음으로 변환하여 웨이크 워드가 단순히 텍스트일 수 있게 합니다. 학습이나 녹음 세션이 필요 없습니다.
- Spot (2.8 MB): 7개 언어에서 이러한 발음을 청취합니다.
- Timbre (0.74 MB): 목소리 지문(voiceprints)을 만듭니다. 웨이크 워드를 세 번 말하면 첫 번째 지문이 생성되며, 사용자가 말하는 동안 계속 학습합니다.
- Focus (1.1 MB): 사용자 목소리(가장 가까운 목소리 또는 지문과 일치하는 목소리)를 유지하고, STT 전에 노이즈, 음악 및 다른 목소리를 제거합니다.
- Cue (1.1 MB): 30ms마다 음성을 감지합니다.
사용자의 인쇄물에 집중(Focus)할 때, 사용자의 차례는 오직 음성으로 시작하고 끝나기 때문에 옆에서 말하는 사람이 새로운 차례를 열지 않습니다. 음성 지문(voiceprint)은 선택 사항이며, 동일한 지문이 세 가지 모두에 사용됩니다: 웨이크 워드는 다른 사람을 무시하고, Focus는 사용자만 유지하며, Cue는 개인적인 VAD(Voice Activity Detection)가 됩니다. 기술적 세부 사항 몇 가지를 알려드리겠습니다. - 이는 onnxruntime이 아닌 Rust로 작성된 자체 소형 추론 엔진에서 실행됩니다. 한 코어는 브라우저용 WebAssembly와 Python 및 Android 네이티브용으로 컴파일되었으며, ARM, x86, wasm의 비트 모두에 동일한 출력을 제공합니다. - 브라우저에서는 AudioWorklet을 통해 공급되는 워커(workers)에서 모델이 실행되며, COOP/COEP 헤더가 필요 없습니다. 엔진 크기는 134 KB(brotli)입니다. - 휴대폰 한 개의 스레드에서의 네이티브 속도는 Focus가 오디오 초당 38.6ms, Spot이 7.5ms, Cue가 1.7ms입니다. - 패키지는 npm(브라우저 및 Node), pip(Linux, macOS, Windows, 유일한 의존성으로 numpy), Android(Kotlin)이며, LiveKit Agents와 Pipecat용 플러그인도 제공됩니다. 코드와 가중치는 Apache-2.0 라이선스입니다. 저장소의 bench 폴더에 있는 프로토콜을 기준으로 몇 가지 수치를 알려드리겠습니다: - 헤드셋 마이크로 녹음된 AMI 회의에서, 다른 사람의 말이 기록되는 횟수는 Focus와 음성 지문을 사용했을 때 분당 약 17회에서 0.5회로 줄어듭니다. - Spot은 타이핑된 단일 단어에 대해 영어에서 67%(시간당 오경보 1회), 프랑스어에서 90%, 포르투갈어에서 85%를 회상합니다. 따라서 특정 고정 영어 단어의 경우, 해당 단어로 훈련된 모델이 더 잘 작동할 수 있습니다. 아직 잘 처리하지 못하는 부분(이는 0.x 프리뷰이며 API가 변경될 수 있음): - 이는 근접 마이크와 한 사람을 위해 만들어졌습니다: 휴대폰, 헤드셋, 노트북 등. 테이블 중앙의 방 전체 마이크에서는 다른 참가자들도 제거합니다. - 두 사람이 정확히 같은 시간에 말할 때, Focus는 부분적으로만 분리하며, 동일한 음역대의 목소리 두 개(남성 두 명 또는 여성 두 명)는 훨씬 더 어렵습니다. 이것이 제가 다음에 작업할 주요 내용입니다. - 오디오는 16kHz로 처리되며, 따라서 최대 8kHz의 음성을 지원합니다.
로컬 음성 비서 사용자분들의 피드백을 특히 부탁드립니다. 어느 부분에서 문제가 발생하는지, 어떤 통합 기능이 다음으로 필요한지, 그리고 API가 적절한지에 대한 의견을 주시면 좋겠습니다. 제출자: /u/cocktailpartyfixer [link] [comments]
AI 자동 생성 콘텐츠
본 콘텐츠는 Reddit AI Engineering의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기