LokalBot이 ASR, 화자 분리, 4B LLM, 자동 완성, 임베딩 및 TTS와 같은 기능들을 위해 다섯 가지 로컬 모델을
요약
LokalBot은 회의 녹음, 전사(transcription), 메모 작성, 검색 및 자동 완성 기능을 위해 여러 오픈 소스 로컬 모델을 구동하는 Mac용 앱입니다. 이 앱은 모든 처리를 장치 내에서 수행하며, Qwen3-ASR, Nemotron 3, Qwen3.5 등 다섯 가지 전문 모델을 활용합니다. 특히 MLX 엔진의 메모리 관리 및 리스(lease) 기반 모델 로딩/언로드 메커니즘에 대한 기술적 깊이를 보여줍니다.
핵심 포인트
- LokalBot은 ASR, 화자 분리, LLM 등 5가지 기능을 위해 다섯 가지 전문 로컬 모델을 통합했습니다.
- 모든 기능이 장치 내에서 실행되며, GPLv3 라이선스를 따르는 오픈 소스 프로젝트입니다.
- MLX 엔진의 GPU 버퍼 풀링 및 리스(lease) 기반 메모리 관리가 구현되어 안정성을 높였습니다.
- M4 Max 단일 기기 기준, 자동 완성은 키 입력당 중앙값 56ms를 기록했습니다.
LokalBot은 제가 지난 6개월 동안 작업해 온 오픈 소스 Mac 앱으로, 여러 유용한 로컬 모델을 구동합니다. 이 모델들은 앱이 회의를 녹음하고, 이를 전사(transcribe)하며, 메모를 작성하고, 모든 내용을 검색하며, 사용자가 타이핑하는 내용을 자동 완성하도록 돕습니다. GPLv3 라이선스를 따르며, 기본적으로 모든 것이 장치 내에서 실행됩니다. 다섯 가지 모델은 다음과 같습니다 (Mac 기본 설정 기준, 디스크 용량 9.6 GB):
| 기능 | 모델 | 구동 방식 | 파일 | 크기 |
|---|---|---|---|---|
| 음성-텍스트 변환(Speech to text) | Qwen3-ASR | MLX, 8-bit | N/A | 2.47 GB |
| 누가 말했는지(Who spoke when) | Nemotron 3 | Core ML | N/A | 0.20 GB |
| 메모, 채팅, 에이전트 | Qwen3.5 | llama.cpp, Q4_K_M | N/A | 2.74 GB |
| 자동 완성(Autocomplete) | Gemma 4 | E2B base, llama.cpp, Q6_K | N/A | 3.85 GB |
| 의미 기반 검색(Search by meaning) | EmbeddingGemma 2 | llama.cpp, Q8_0 | N/A | 0.31 GB |
작동 방식 (How they take turns)
통화를 녹음할 때는 아무것도 로드되지 않습니다. 앱은 두 개의 오디오 트랙만 기록합니다. 전사(Transcription)는 사용자가 통화를 끊을 때까지 기다리며, 자동 완성(Autocomplete)은 사용자가 녹음하는 동안 일시 중지됩니다. 통화가 끝난 후에는 화자 모델과 음성 모델이 로드되어 작업을 수행하고, 120초 동안 유휴 상태가 되면 언로드됩니다. 여기서 한 가지 놀라운 점이 있습니다: MLX는 해제된 GPU 버퍼를 풀(pool)에 유지하기 때문에, 단순히 모델을 제거하는 것만으로는 충분하지 않았습니다. 회의 하나 후에도 앱은 유휴 상태에서 여전히 4.3 GB를 차지하고 있었습니다. 이제 모든 MLX 엔진은 언로드될 때 해당 풀을 정리합니다.
Qwen3.5 4B는 번들된 llama-server(Metal, 32K context)에서 실행되며, 무언가가 요청할 때 시작됩니다. 각 요청은 리스(lease)를 차지하며, 마지막 리스가 발생한 후 10분이 지나면 모델이 언로드됩니다. 임베딩 모델도 자체 서버가 있으며 동일한 규칙을 따릅니다. Gemma 4 E2B는 낮은 지연 시간(latency)을 위해 앱의 프로세스를 통해 libllama로 실행됩니다. 이 모델은 유휴 타이머가 없습니다. macOS가 메모리 압박을 보고할 때까지 유지됩니다. 브로커(broker)는 로드된 가중치(weights)를 기가바이트 RAM의 절반 예산 내에서 유지하며, 가장 최근에 사용되지 않은 모델부터 제거합니다. 리스(lease)는 요청이 실행되는 동안 모델을 고정합니다. 서버를 기다려야 하는 요청들은 다음 순서로 처리됩니다: 시청 중인 것 > 에이전트 > 회의 메모 > 요약 및 인덱싱과 같은 백그라운드 작업.
모든 수치는 48GB 메모리를 갖춘 M4 Max 단일 기기에서 측정되었습니다. 26분 회의 기준으로 모델 워밍업(model warm) 시 33초, 로딩 시간을 포함하여 약 60초가 소요되었으며, 속도는 약 85 tok/s입니다. 자동 완성(Autocomplete)은 키 입력당 중앙값(median) 56ms, P95는 102ms를 기록했습니다. 질의 임베딩(Embedding a query)에는 9ms가 소요됩니다. 화자 모델(Speaker model)의 경우, 8개의 AMI 녹음 파일에서 14.6%의 DER을 보였으며, 실시간 대비 약 500배 속도입니다.
이 수치들은 제가 해당 단일 기기에서만 측정한 한계점들입니다. 16GB Mac이나 M1, M2 또는 M3 모델에서의 수치는 없습니다. 메모리 사용량을 줄이기 위한 경량(Lightweight) 프리셋이 있습니다 (자동 완성을 위해 Qwen3-ASR 0.6B, Qwen3.5 0.8B, 그리고 LFM2.5 1.2B).
제거(Eviction)는 단순한 LRU(Least Recently Used)에 고정(pins) 기능을 추가한 것입니다. 우선순위는 큐를 정렬할 뿐, 누가 제거될지 아직 선택하지 않습니다. 만약 모델이 할당된 예산 내에 들어가지 못하면, 고정되지 않은 모든 것이 제거되고 로드는 어쨌든 진행됩니다.
비디오는 한 가지를 단순화했습니다. 음성 모델이 떠난 후에 메모(notes) 모델이 도착하는 것처럼 보입니다. 실제 앱에서는 음성 모델들이 2분을 카운트다운 하는 동안 메모가 시작됩니다. 내레이션은 제가 직접 클론하고 ElevenLabs를 사용해 생성한 목소리이므로, 이 게시물에서 로컬로 실행되지 않은 유일한 부분입니다.
Windows 및 Linux 빌드는 알파(alpha) 단계입니다. 코드, 벤치마크 및 이 수치 뒤에 숨겨진 스크립트는 https://github.com/stevyhacker/lokalbot 입니다. 만약 16GB Mac에서 실행해 보신다면, 회의 직후 '설정 → 진단(Settings → Diagnostics)'에 무엇이 로드되는지 보고 싶습니다. 그리고 여러 로컬 모델을 위한 스케줄러를 구축하셨다면, 무엇을 가장 먼저 제거하는지 알고 싶습니다.
/u/stevyhacker가 r/LocalLLaMA에 제출했습니다 [링크] [댓글]
AI 자동 생성 콘텐츠
본 콘텐츠는 r/OpenAI Codex (search)의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기