프로젝트 종료
SoriShelf Android, 한국어 이름으로 말서랍 프로젝트를 여기서 종료하기로 했다.
처음 목표는 단순했다. 음성을 녹음하고, 그 녹음 내용을 텍스트로 바꾸고, 필요하면 회의록 형태로 정리해서 보관하는 Android 앱을 만들어보는 것이었다.
중간에는 생각보다 많은 방향을 지나왔다.
처음에는 Android 기본 음성 인식으로 녹음 중 받아쓴 내용을 저장했다. 이후에는 저장된 WAV 파일을 sherpa_onnx로 오프라인 전사하는 방식으로 바꿨다. SenseVoice int8 모델을 시도했고, 품질 문제 때문에 Whisper small int8로 전환했다. 회의록 정리는 규칙 기반으로 시작했다가 Qwen GGUF 모델을 기기 안에서 실행하는 방향까지 실험했다.
앱도 실험 수준을 넘어 어느 정도 흐름을 갖췄다.
- Android 음성 녹음
- 16 kHz mono WAV 저장
- 녹음 목록과 상세 화면
- 기록 제목 변경
- 기록 상단 고정
- 원본 음성 재생/삭제/공유
- 녹음 내용 PDF 공유
- 회의록 PDF 공유
- 녹음 내용/회의록 클립보드 복사
- sherpa-onnx 기반 오프라인 음성-텍스트 변환
- Qwen GGUF 기반 로컬 회의록 생성 시도
- 모델 다운로드 진행 상태 유지
- 전사 작업 중 페이지 이동 지원
여기까지 만들고 나니 한 가지 판단이 분명해졌다.
기술적으로는 재미있고 배운 것도 많았지만, 내가 만들려던 실사용 노트 앱으로 계속 가져가기에는 현재 로컬 모델 방식의 용량과 성능 한계가 컸다.
공개로 전환한 이유
프로젝트는 종료하지만, 저장소는 공개로 전환했다.
공개 저장소 주소는 아래와 같다.
https://github.com/ChoDaeYun/sorishelf-android
음성 인식 모델 릴리즈는 별도 모델 저장소 쪽에 정리되어 있다.
https://github.com/moagalstudio/sorishelf-models/releases/download/sherpa-whisper-small-int8
공개로 전환한 이유는 단순하다.
완성된 제품은 아니지만, 누군가에게는 참고할 만한 실험 기록이 될 수 있다고 봤다. Flutter에서 녹음을 저장하고, 로컬 파일을 관리하고, sherpa-onnx 모델을 다운로드하고, 오프라인 전사를 돌리고, PDF 공유까지 이어가는 흐름은 작게라도 남겨둘 가치가 있었다.
다만 이 저장소는 프로덕션 앱이 아니다.
README에도 적어두었듯이 현재 상태는 동작 가능한 프로토타입이다. 공개되어 있다고 해서 바로 서비스로 쓸 수 있는 완성본은 아니다. 프로젝트 자체 라이선스도 아직 정하지 않았고, 모델과 폰트, 네이티브 바이너리, 외부 라이브러리는 각각의 라이선스를 따라야 한다.
그래서 공개 전에는 THIRD_PARTY_NOTICES.md도 추가했다. 모델 파일은 앱 저장소에 포함하지 않았고, 모델 바이너리를 재배포하거나 다운로드하는 앱을 배포하기 전에는 각 모델의 원본 라이선스를 반드시 확인해야 한다.
공개 전에 정리한 것들
공개 전에는 README를 다시 정리했다.
프로젝트가 무엇인지, 무엇을 할 수 있는지, 어떤 한계가 있는지 먼저 보이게 했다.
주요 기능은 다음처럼 정리했다.
- Android 음성 녹음
- 녹음 목록 및 상세 화면
- 기록 제목 변경
sherpa_onnx기반 오프라인 음성-텍스트 변환llama_cpp_dart기반 기기 내 GGUF 모델 회의록 생성- 페이지를 이동해도 유지되는 모델 다운로드 진행 상태
- 원본 음성 공유
- 녹음 내용 및 회의록 PDF 공유
- 녹음 내용 및 회의록 클립보드 복사
그리고 현재 한계도 숨기지 않았다.
- 긴 녹음은 모바일 기기에서 실제 녹음 길이와 비슷하거나 그 이상으로 전사 시간이 걸릴 수 있다.
- 오프라인 전사 품질은 상용 서버 기반 노트 서비스보다 낮다.
- Whisper small 전환 후 한국어/영어 혼합 음성 인식은 개선됐지만 모든 상황에서 안정적인 품질을 보장하기 어렵다.
- 앱 안에서는 한 번에 하나의 처리 작업만 실행한다.
- 앱 프로세스가 종료되면 진행 중인 전사나 회의록 생성은 처음부터 다시 시작해야 한다.
이런 내용을 적어둔 이유는, 누군가 저장소를 봤을 때 “왜 여기서 멈췄는지”를 바로 알 수 있게 하기 위해서다.
모델을 바꾸며 알게 된 것
이번 프로젝트에서 가장 오래 고민한 부분은 음성 인식 모델이었다.
처음에는 SenseVoice int8을 사용했다. SenseVoice는 상대적으로 가볍고 한국어도 지원해서 시작점으로는 좋았다. 하지만 영어가 섞인 음성이나 노래 샘플에서 결과가 흔들렸다. 영어 가사가 한국어 발음처럼 나오거나, 이상한 숫자로 바뀌는 경우가 있었다.
그래서 Whisper small int8로 바꿨다.
Whisper small은 품질 면에서 더 나았다. 한국어와 영어가 섞인 음성에서 더 안정적이었고, SenseVoice에서 크게 깨지던 샘플도 어느 정도 개선됐다.
하지만 대가가 컸다.
모델 파일 크기만 대략 375 MB다.
encoder.int8.onnx: 약 112 MBdecoder.int8.onnx: 약 262 MBtokens.txt: 약 0.8 MB
모델을 내려받는 데 시간이 걸리고, 앱 저장소도 많이 사용한다. 더 큰 문제는 속도다. 5분 녹음 파일을 전사하는 데 5분에 가까운 시간이 걸릴 수 있었다. 즉, N분 녹음은 N분에 가까운 시간이 필요할 수 있다.
이건 사용 경험에서 꽤 큰 문제다.
회의 녹음은 5분보다 길다. 30분, 60분짜리 녹음도 흔하다. 사용자가 녹음을 끝낸 뒤 같은 시간만큼 기다려야 한다면, 개인 프로젝트로는 재미있어도 실사용 앱으로는 부담이 크다.
결국 모델 선택은 항상 균형이었다.
- SenseVoice: 가볍지만 품질이 아쉬움
- Whisper small: 품질은 낫지만 무겁고 느림
- Qwen GGUF: 로컬 회의록 생성 가능성은 있지만 모바일에서 속도와 안정성 부담
이 균형을 내가 원하는 수준까지 맞추는 데는 더 많은 모델 실험과 최적화가 필요했다.
왜 여기서 멈췄나
가장 큰 이유는 실사용 기준이다.
내가 원했던 것은 “로컬 모델이 돌아가는 앱” 자체가 아니었다. 음성을 남기고, 그 내용을 빠르게 확인하고, 필요한 정리까지 편하게 보는 앱이었다.
그런데 같은 시점에 이미 상용 서비스는 훨씬 좋은 사용 경험을 제공하고 있었다.
결과적으로 에이닷 노트 성능이 너무 좋았다.
직접 만들어보니 더 체감됐다. 녹음 후 텍스트가 만들어지는 속도, 인식 품질, 노트 정리 경험, 사용자가 기다리는 시간까지 생각하면, 현재 내가 만든 로컬 모델 방식은 상용 서비스와 비교하기 어려웠다.
물론 방향이 틀렸다는 뜻은 아니다.
로컬 처리에는 분명한 장점이 있다. 사용자의 음성을 외부 전사 API로 보내지 않는다는 점은 여전히 중요하다. 민감한 기록을 다루는 앱이라면 로컬 처리의 가치는 크다. 다만 개인 프로젝트로 당장 만족스러운 품질, 속도, 용량을 모두 맞추기는 쉽지 않았다.
그래서 이 프로젝트는 여기서 종료한다.
그래도 남겨두고 싶은 가능성
이 저장소를 공개로 둔 이유는, 누군가 더 좋은 모델이나 더 나은 구조를 적용해볼 수 있기를 바라기 때문이다.
특히 다음 조건을 만족하는 모델이 있다면 말서랍은 다시 꽤 흥미로운 프로젝트가 될 수 있다.
- Whisper small보다 훨씬 작은 용량
- 모바일 Android에서 빠른 전사 속도
- 한국어 인식 품질
- 한국어/영어 혼합 음성 처리
- 긴 녹음에서 안정적인 처리
- 오프라인 실행 가능
- 명확한 라이선스
현재 구조는 완벽하지 않지만, 실험을 이어가기에 필요한 기본 뼈대는 있다.
- WAV 녹음 저장
- 녹음 목록/상세 관리
- 모델 다운로드
- 오프라인 전사 서비스 추상화
- 전사 결과 저장
- 회의록 생성 서비스 추상화
- PDF 공유
- 클립보드 복사
누군가 더 좋은 용량과 성능을 만족하는 모델을 찾는다면, TranscriptionService 쪽을 바꾸거나 모델 다운로드 구조를 확장해서 개선할 수 있을 것이다.
내가 더 이어간다면 다음 방향이었을 것 같다.
- 빠른 모델과 정확한 모델을 나누는 2모드 구조
- 기본은 빠른 변환, 필요할 때만 정확한 변환
- 녹음 중 Android 기본 음성 인식으로 임시 텍스트 표시
- 저장 후 로컬 모델로 정식 전사
- 실패 시 임시 텍스트 보존
- 모델 다운로드 취소/재시도/Wi-Fi 안내
- 긴 녹음 처리 시간과 발열 측정
하지만 여기서 멈추기로 했다.
프로젝트에서 얻은 것
SoriShelf는 완성된 앱은 아니지만, 좋은 실험이었다.
Flutter에서 Android 녹음 앱을 만들 때 고려해야 할 것들이 꽤 선명해졌다.
- 녹음 파일 포맷
- 마이크 권한
- 로컬 파일 저장
- 원본 음성 보관/삭제
- 전사 결과 저장
- 모델 파일 다운로드
- 모델 크기와 라이선스
- Android 기기 성능 차이
- PDF 공유와 한글 폰트
- 앱 중단 시 작업 상태 복구
특히 로컬 AI는 생각보다 앱이 직접 책임져야 할 것이 많았다. 서버 API를 쓰면 모델 실행 환경은 서버가 가져간다. 로컬 모델을 쓰면 개인정보 측면에서는 좋아지지만, 모델 파일 크기, 다운로드, 메모리, 속도, 발열, 배터리, 기기별 차이를 앱이 감당해야 한다.
그 현실을 직접 겪어본 것만으로도 의미가 있었다.
마무리
말서랍은 여기서 종료한다.
아쉬움은 있지만, 미련은 크지 않다. 내가 만들고 싶었던 방향을 직접 확인했고, 어디가 어려운지도 알게 됐다. 그리고 공개 저장소로 남겨두었으니, 누군가 더 좋은 모델을 붙여보거나 다른 방식으로 이어갈 수도 있다.
공개 저장소:
https://github.com/ChoDaeYun/sorishelf-android
모델 릴리즈:
https://github.com/moagalstudio/sorishelf-models/releases/download/sherpa-whisper-small-int8
“직접 만들어보니, 좋은 노트 앱은 모델만으로 되는 것이 아니라 기다리는 시간까지 설계해야 한다는 걸 알게 됐다.”
그리고 솔직히 말하면,
에이닷 노트가 너무 잘한다. ㅎ
2026.07.29 종료 정리
- SoriShelf Android 프로젝트는 프로토타입 단계에서 종료
- 저장소는 공개 전환:
https://github.com/ChoDaeYun/sorishelf-android - 공개 전 README와
THIRD_PARTY_NOTICES.md정리 - Whisper small int8 기반 오프라인 전사는 동작하지만 용량과 속도 한계가 큼
- N분 녹음은 N분에 가까운 전사 시간이 필요할 수 있음
- 상용 서비스, 특히 에이닷 노트의 사용 경험이 현재 직접 구현보다 훨씬 좋다고 판단
- 더 작고 빠르며 한국어 품질이 좋은 모델이 있다면 이후 개선 가능성은 남아 있음