SoriShelf Android 7월 27일 정리 - UI 수정, 공유 기능, 모델 전환

SoriShelf Android 프로젝트에서 UI를 다듬고 공유 기능을 추가하며 SenseVoice에서 Whisper small로 모델을 전환한 이유와 남은 문제 정리

이번 정리

7월 12일에는 SoriShelf/말서랍에서 음성을 글로 바꾸기 위해 어떤 준비를 했는지 정리했다.

그때의 핵심은 저장된 WAV 파일을 sherpa_onnx로 오프라인 전사하고, 그 결과를 Qwen 기반 로컬 회의록 모델이나 규칙 기반 fallback으로 정리하는 흐름이었다. 당시에는 SenseVoice int8 모델을 기준으로 시작했고, 긴 파일 처리와 모델 다운로드 UX가 남은 문제였다.

7월 27일 기준으로는 작업의 초점이 조금 넓어졌다.

이번에는 단순히 “전사가 되는가”를 넘어서, 사용자가 실제 앱처럼 기록을 보고, 상태를 이해하고, 결과를 공유할 수 있는 방향으로 UI와 기능을 다듬었다. 동시에 음성 인식 모델도 SenseVoice에서 Whisper small int8로 바뀌었다.

이번 업데이트를 한 문장으로 정리하면 이렇다.

말서랍이 실험용 전사 화면에서, 기록을 관리하고 공유할 수 있는 앱에 가까워졌다.

아직 개발 완료는 아니다. 특히 현재 모델은 정확도는 좋아졌지만 속도와 용량 문제가 크다. N분 녹음 파일을 변환하는 데 N분에 가까운 시간이 걸릴 수 있다는 점은 다음 단계에서 반드시 다뤄야 할 문제다.

UI에서 바꾼 것들

이번 작업에서 UI는 크게 네 방향으로 수정됐다.

첫 번째는 홈 화면의 정보 밀도 조정이다.

홈에는 최근 기록 10개만 보여주도록 했다. 녹음이 많아질수록 첫 화면이 너무 길어지면 녹음 시작이라는 핵심 액션이 묻힌다. 말서랍의 첫 화면은 기록 보관함이면서 동시에 녹음 시작 화면이다. 그래서 최근 기록은 빠르게 훑을 수 있을 만큼만 보여주고, 더 많은 기록은 전체 목록에서 보게 했다.

두 번째는 전체 기록 목록 화면 추가다.

RecordingsListScreen이 새로 들어갔다. 홈에서 전체 보기를 누르면 전체 기록 목록으로 이동한다. 이 화면에서는 고정 기록과 최근순 기록을 나누어 보여준다. 기록이 많아졌을 때 홈이 복잡해지는 문제를 줄이면서도, 사용자가 과거 기록을 찾을 수 있는 통로를 만든 것이다.

세 번째는 기록 관리 액션이다.

이제 기록 이름 변경과 상단 고정을 지원한다. 상세 화면 상단에는 이름 변경 아이콘과 고정 아이콘이 들어갔다. 전체 기록 목록에서도 고정 여부를 바로 확인하고 토글할 수 있다.

이 기능은 작아 보이지만, 녹음 앱에서는 중요하다. 실제 사용자는 “오늘 테스트 녹음” 같은 자동 이름만으로는 기록을 구분하기 어렵다. 회의 이름이나 주제를 직접 붙일 수 있어야 하고, 중요한 녹음은 위에 고정할 수 있어야 한다.

네 번째는 상태 표시 개선이다.

상세 화면과 목록에서 원본 음성, 녹음 내용, 회의록 상태를 더 명확하게 보여주도록 했다. 완료, 처리 중, 실패 같은 상태가 아이콘과 함께 보이게 되었고, 전사 작업이나 모델 다운로드가 진행 중일 때는 홈이나 목록 상단에 배너가 표시된다.

이전에는 사용자가 버튼을 누른 뒤 “지금 처리 중인가?”를 화면 하나 안에서만 판단해야 했다. 이제는 페이지를 이동해도 작업 상태가 보인다. 앱이 살아 있다는 감각을 주는 쪽으로 한 걸음 나아갔다.

처리 중 상태를 다룬 방식

이번 UI 수정에서 가장 중요한 내부 변화는 작업 상태 관리다.

모델 다운로드는 ModelDownloadJobManager가 전역 작업으로 관리한다. 음성 인식 모델 다운로드와 회의록 AI 모델 다운로드가 같은 구조를 쓴다. 다운로드 중에는 상단에 공통 진행 배너가 표시되고, 다른 페이지로 이동해도 진행 상태가 유지된다.

다운로드 중에는 일부 기능이 제한된다.

  • 새 녹음
  • 음성을 글로 바꾸기
  • 회의록 만들기

동시에 여러 모델 다운로드가 겹치면 저장소와 UI 상태가 복잡해진다. 그래서 현재는 한 번에 하나의 모델 다운로드만 허용한다.

전사 작업도 TranscriptionJobManager로 분리됐다. 녹음 상세 화면에서 전사를 시작해도, 사용자가 홈이나 전체 목록으로 이동할 수 있다. 작업은 계속 진행되고, 홈과 목록에는 전사 중 배너가 보인다.

이 부분은 7월 12일의 문제 의식과 연결된다. 긴 녹음 파일은 처리 시간이 오래 걸린다. 사용자가 상세 화면에 갇혀 있어야 한다면 앱 경험이 답답해진다. 그래서 전사 작업을 화면 상태가 아니라 앱 작업 상태로 올린 것이다.

또 하나 중요한 수정이 있다.

이전에는 전사 중 앱이 죽거나 재시작되면 기록 상태가 processing으로 남아 다시 시작하기 어려웠다. 지금은 앱 시작 시 실제 전사 작업이 없는데 processing으로 남은 기록을 failed로 되돌린다. 완벽한 해결은 아니지만, 사용자가 다시 시도할 수 있는 상태로 복구한다.

나중에는 단순 실패보다 중단됨 같은 별도 상태가 더 자연스러울 수 있다.

공유하기에서 처리한 것들

이번 업데이트에서 공유 기능도 들어갔다.

공유는 세 가지 흐름으로 나뉜다.

  1. 원본 음성 파일 공유
  2. 녹음 내용 PDF 공유
  3. 회의록 PDF 공유

원본 음성은 저장된 WAV 파일을 그대로 외부 앱으로 공유한다. 녹음 파일이 없으면 공유할 수 없으므로, 원본 음성 삭제 상태도 함께 고려해야 한다.

녹음 내용과 회의록은 PDF로 만들어 공유한다. 단순 텍스트 공유도 가능하지만, 회의록이나 녹음 내용은 문서로 보관하고 전달하는 경우가 많다. 그래서 PDF 내보내기를 먼저 넣었다.

PDF 공유에서 가장 먼저 부딪히는 문제는 한글이다.

기본 폰트로 PDF를 만들면 한글이 깨질 수 있다. 그래서 앱 asset에 NotoSansKR-Regular.ttf를 포함했다. PDF 생성 시 이 폰트를 읽어 pdf 패키지의 문서 테마에 넣는다. 이 덕분에 녹음 내용과 회의록을 PDF로 공유할 때 한글이 깨지지 않게 했다.

회의록 PDF는 단순히 저장된 객체를 그대로 출력하지 않는다. RecordingShareService에서 회의록을 공유용 텍스트로 정리한다.

  • 요약
  • 주요 섹션
  • 핵심 포인트
  • 결정사항
  • 할 일
  • 질문/이슈

이 순서로 문서화한다. 회의록 화면에서 보던 구조가 공유 문서에도 이어지게 한 것이다.

또한 녹음 내용과 회의록은 클립보드 복사도 지원한다. PDF 공유가 문서 전달용이라면, 복사는 메신저나 노션, 메모 앱에 빠르게 붙여넣기 위한 기능이다.

이제 말서랍은 “앱 안에서만 볼 수 있는 기록”에서 벗어나기 시작했다.

모델을 왜 바꿨나

7월 12일 기준 음성 인식 모델은 SenseVoice int8 쪽이었다.

SenseVoice는 가볍고 한국어도 지원한다. 처음 오프라인 전사를 붙이기에는 좋은 출발점이었다. 하지만 실제 테스트에서 문제가 보였다.

특히 노래나 영어가 섞인 음성에서 결과가 흔들렸다. 영어 가사가 한국어 발음처럼 나오거나, 이상한 숫자로 바뀌는 문제가 있었다. 일반 회의 녹음에서도 한글/영어가 섞이면 기대한 만큼 안정적이지 않았다.

그래서 Whisper small int8로 전환했다.

현재 앱이 기대하는 sherpa-onnx 모델 파일은 다음과 같다.

  • encoder.int8.onnx
  • decoder.int8.onnx
  • tokens.txt

GitHub Release tag는 sherpa-whisper-small-int8로 잡았다. 저장 경로도 기존 SenseVoice 기준의 sherpa-onnx/sense-voice에서 sherpa-onnx/whisper-small로 바뀌었다.

Whisper 설정은 다음 방향이다.

  • OfflineWhisperModelConfig
  • modelType: whisper
  • task: transcribe
  • 언어는 자동 감지
  • thread는 2개
  • 30초 chunk 단위 처리

SenseVoice에서 Whisper small로 바꾼 이유는 간단하다.

품질이 더 낫기 때문이다.

특히 한국어와 영어가 섞인 녹음, 노래나 발음이 늘어지는 샘플에서 Whisper 쪽이 더 나은 결과를 보였다. 말서랍은 회의와 메모뿐 아니라 사용자가 테스트로 넣는 다양한 음성도 만나게 된다. 이때 너무 엉뚱한 전사 결과가 나오면 앱에 대한 신뢰가 크게 떨어진다.

다만 모델을 바꾸면서 대가도 생겼다.

Whisper small로 바꾸며 생긴 문제

Whisper small은 SenseVoice보다 무겁다.

현재 release asset 크기는 대략 이렇다.

  • encoder.int8.onnx: 약 112 MB
  • decoder.int8.onnx: 약 262 MB
  • tokens.txt: 약 0.8 MB
  • 합계: 약 375 MB

사용자 입장에서는 처음 모델을 받는 데 시간이 걸린다. 네트워크 부담도 있고, 앱 저장소 사용량도 커진다. 그래서 다운로드 진행률 배너와 파일별 진행 표시가 필요했다.

더 큰 문제는 전사 속도다.

Whisper small은 품질은 좋아졌지만 모바일 기기에서는 처리 시간이 길다. 현재 관찰로는 5분 녹음 파일을 전사하는 데 실제 음성 길이와 비슷한 시간이 걸릴 수 있다. 사용자는 “5분 녹음이면 5분을 기다려야 하는구나”라고 느낄 수 있다.

이것은 단순한 버그라기보다 모델 선택의 결과다.

무거운 모델을 로컬에서 돌리면 정확도는 올라가지만, 속도와 발열, 배터리, 메모리 부담이 생긴다. 청크 길이를 조절하거나 thread 수를 올려볼 수는 있지만, 근본적으로 N분 녹음이 N분에 가까운 처리 시간을 요구하는 문제가 남는다.

예를 들어 10분 회의 녹음은 10분 가까이 걸릴 수 있고, 30분 녹음은 사용자가 앱을 켜둔 채 꽤 오래 기다려야 할 수 있다. 실제 제품 경험으로 보면 부담이 크다.

긴 파일 처리에서 바뀐 점

7월 12일에는 긴 파일에서 크래시가 나는 문제가 있었다.

그때의 구조는 WAV 파일 전체를 한 번에 읽고, 전체 샘플을 한 번에 recognizer에 넣는 방식이었다. 10분 이상 파일에서는 메모리 부담이 커질 수밖에 없었다.

이번에는 그 구조를 바꿨다.

현재 전사 서비스는 PCM 16-bit WAV 정보를 직접 읽고, 30초 단위 chunk로 나누어 처리한다. 각 chunk를 OfflineRecognizer stream에 넣고 decode한 뒤, 결과를 TranscriptSegment로 저장한다.

이 변경으로 전체 파일을 한 번에 샘플 배열로 올리는 문제는 줄었다. 또한 전사 결과를 구간별 segment로 남길 수 있게 됐다.

하지만 이걸로 모든 문제가 해결된 것은 아니다.

chunking은 크래시 가능성을 줄이는 구조적 개선이다. 그렇다고 Whisper small 자체가 빨라지는 것은 아니다. 모델이 무겁다면 30초씩 나누어도 전체 처리 시간은 여전히 길다. 즉, 안정성은 나아졌지만 속도 문제는 남아 있다.

전사 결과 후처리

Whisper 결과를 그대로 보여주면 문서처럼 읽기 어려울 수 있다.

그래서 TranscriptTextFormatter가 추가됐다. 이 포매터는 전사 결과를 정리한다.

  • 특수 토큰 제거
  • 공백 정리
  • 문장 끝 후보 기준 마침표 추가
  • 한국어 문장 종결 표현 기준 분리
  • 영어 문장 대문자 처리
  • 3문장 또는 긴 문단 기준 단락 나누기

이 작업은 모델 품질을 바꾸는 것이 아니라, 사용자에게 보이는 기록 품질을 높이는 일이다. 음성 인식 결과가 하나의 긴 줄로 나오면 회의록 이전 단계에서도 읽기 어렵다. 그래서 최소한 문장과 문단을 만들어주는 후처리가 필요했다.

테스트 샘플 추가

디버그 빌드에서는 테스트용 녹음도 자동으로 추가되도록 했다.

현재 샘플은 다음과 같다.

  • 5분 전사 테스트 샘플
  • Drowning 전사 테스트 샘플
  • 왼손잡이 전사 테스트 샘플

테스트 샘플을 넣은 이유는 반복 확인을 쉽게 하기 위해서다. 모델을 바꿀 때마다 직접 녹음만으로 비교하면 기준이 흔들린다. 같은 파일을 여러 모델에 넣어봐야 모델 변경의 효과를 볼 수 있다.

다만 샘플에도 이슈가 있다.

Drowning 전사 테스트 샘플은 현재 약 71초 WAV라 전체 가사를 기준으로는 짧다. 사용자가 기대하는 전체 가사 테스트와 실제 오디오 길이가 다르면, 결과가 짧게 나오는 것이 모델 문제인지 샘플 문제인지 헷갈린다. 그래서 전체 길이 WAV를 다시 만들어야 한다.

UI 측면에서 좋아진 점

이번 수정으로 UI에서 좋아진 점은 크게 네 가지다.

첫째, 작업 상태가 더 잘 보인다.

모델 다운로드 중이면 상단 배너가 보이고, 전사 중이어도 상단에 진행 중 안내가 보인다. 사용자가 상세 화면을 떠나도 앱이 무엇을 하고 있는지 알 수 있다.

둘째, 버튼이 상황에 맞게 제한된다.

모델 다운로드 중에는 새 녹음, 전사, 회의록 생성을 제한한다. 전사 중에는 또 다른 전사를 시작하지 못하게 했다. 무리하게 여러 작업을 동시에 시작하면 모바일 기기에서는 실패 가능성이 커진다.

셋째, 기록 목록이 정리됐다.

홈은 최근 기록 10개만 보여주고, 전체 기록 화면에서 고정 기록과 최근 기록을 나누어 볼 수 있다. 녹음이 쌓여도 앱이 덜 지저분해진다.

넷째, 공유와 복사가 앱 흐름 안에 들어왔다.

녹음 내용과 회의록은 앱 안에서 끝나는 정보가 아니다. 누군가에게 보내거나, 다른 문서 도구에 붙여 넣어야 한다. PDF 공유와 클립보드 복사가 들어가면서 실제 사용성이 좋아졌다.

아직 남은 문제

이번 업데이트로 기능은 많이 늘었지만, 모델 관련 문제는 여전히 크다.

가장 큰 문제는 속도다.

현재 Whisper small은 5분 녹음 파일을 5분에 가깝게 처리할 수 있다. 즉, N분 녹음 파일은 N분에 가까운 변환 시간이 필요할 수 있다. 회의 녹음이 30분, 60분으로 늘어나면 사용자는 앱이 너무 느리다고 느낄 가능성이 높다.

두 번째는 모델 용량이다.

음성 인식 모델만 약 375 MB다. 여기에 Qwen 회의록 모델까지 받으면 저장소 부담은 더 커진다. Wi-Fi 권장 안내, 다운로드 취소, 이어받기, 저장소 사용량 표시 같은 UX가 필요하다.

세 번째는 모델 선택 전략이다.

Whisper small 단일 모델은 단순하지만 무겁다. 모든 녹음에 항상 정확한 모델을 쓰는 것이 좋은 제품 경험은 아닐 수 있다. 일반 회의나 짧은 메모는 빠른 모델로 처리하고, 품질이 중요한 녹음만 Whisper small로 처리하는 2모드 구조가 더 현실적이다.

후보는 다음과 같다.

  • 빠른 변환: SenseVoice 또는 Whisper tiny/base
  • 정확한 변환: Whisper small

네 번째는 노래와 음악 전사의 기대치다.

Whisper small로 바꾸면서 SenseVoice보다 결과는 좋아졌지만, 노래 가사를 완벽하게 전사한다고 말하기는 어렵다. 배경음, 반복 후렴, 늘어진 발음은 일반 회의 음성보다 훨씬 어렵다. 말서랍은 기본적으로 회의와 기록 앱이므로, 노래 전사는 “가능은 하지만 보장하지 않음” 정도로 보는 것이 맞다.

다섯 번째는 작업 중단 상태다.

현재 앱 시작 시 남은 processing 상태를 failed로 되돌리지만, 사용자 입장에서는 “실패”와 “앱이 꺼져서 중단됨”은 다르다. 나중에는 별도 상태를 추가하는 편이 더 명확하다.

앞으로의 방향

지금 가장 현실적인 방향은 단일 모델 고집보다 모델 전략을 나누는 것이다.

정확도만 보면 Whisper small이 낫다. 하지만 속도와 용량까지 보면 모든 사용자 흐름에 항상 Whisper small을 쓰기는 부담스럽다.

그래서 다음 방향은 이렇게 보는 것이 좋다.

  1. 기본 UX는 녹음 후 변환으로 유지한다.
  2. 빠른 변환 모델 후보를 다시 검토한다.
  3. Whisper small은 정확한 변환 모델로 유지한다.
  4. 모델 선택 UI를 설계한다.
  5. 다운로드 취소, 재시도, Wi-Fi 안내를 추가한다.
  6. 1분, 5분, 30분 샘플별 처리 시간을 실제 기기에서 측정한다.
  7. 녹음 중 임시 전사와 저장 후 정식 전사를 함께 쓰는 구조도 검토한다.

말서랍은 개인정보를 우선하는 로컬 처리 앱으로 가고 있다. 이 방향은 좋다. 다만 로컬 처리를 선택한 순간, 서버 API가 대신 해주던 모델 실행 비용과 속도 문제를 앱이 직접 감당해야 한다.

이번 업데이트는 그 현실을 꽤 분명하게 보여줬다.

이번 작업에서 느낀 점

이번 단계는 기능을 붙였다기보다, 앱이 실제 사용자의 손에 가까워지는 과정이었다.

전사가 되고, 회의록이 만들어지는 것만으로는 부족했다. 사용자는 기록을 찾고, 이름을 바꾸고, 중요한 기록을 고정하고, 원본 음성을 공유하고, 녹음 내용과 회의록을 PDF로 보내고 싶어 한다.

그런 면에서 UI 수정과 공유 기능은 모델 작업만큼 중요했다.

반대로 모델 전환은 정확도와 속도 사이의 균형을 다시 생각하게 했다. SenseVoice는 가볍지만 품질 이슈가 있었고, Whisper small은 품질은 좋아졌지만 느리고 크다. 결국 말서랍의 다음 고민은 “가장 좋은 모델 하나”가 아니라 “상황에 맞는 모델 선택”이 될 가능성이 크다.

“정확한 전사는 좋은 기능이지만, 기다릴 수 있는 전사여야 앱 안에 남는다.”

7월 27일 기준 말서랍은 더 많이 할 수 있게 됐다. 이제는 그 기능들이 오래 기다리지 않아도, 헷갈리지 않아도, 실패해도 다시 시도할 수 있게 만드는 단계로 가야 한다.


2026.07.27 정리

  1. UI 수정: 홈 최근 기록 10개 제한, 전체 기록 목록, 고정 기록/최근 기록 분리, 상태 아이콘 추가
  2. 작업 상태: 모델 다운로드와 전사 작업을 전역 job manager로 관리
  3. 공유 처리: 원본 음성 공유, 녹음 내용 PDF 공유, 회의록 PDF 공유, 클립보드 복사 추가
  4. PDF 처리: 한글 깨짐 방지를 위해 NotoSansKR-Regular.ttf asset 추가
  5. 모델 변경: SenseVoice int8에서 Whisper small int8로 전환
  6. 변경 이유: 한글/영어 혼합, 노래/영어 샘플에서 SenseVoice 품질 문제가 커서 Whisper로 이동
  7. 남은 문제: Whisper small은 정확도는 좋지만 무겁고, N분 녹음 전사에 N분 가까운 시간이 필요할 수 있음
  8. 다음 방향: 빠른 변환/정확한 변환 2모드, 다운로드 UX 개선, 실제 기기별 처리 시간 측정