Engineering

멀티모달 음성 인식: 보이는 것을 보는 리스너 만들기

실제 워크플로에서 오디오 전용 ASR이 여전히 실패하는 이유, 그리고 Loqua가 로컬 화면 컨텍스트로 의도의 모호함을 풀어내는 방법.

TL;DR

멀티모달 음성 인식은 전사와 유용한 받아쓰기 사이의 빠진 레이어예요. Loqua는 맥 네이티브 음성 입력 도구로, 오디오와 로컬 화면 컨텍스트, 활성 앱 메타데이터, 커서 주변 정보를 결합해요. 덕분에 같은 소리가 목적지 앱에서 적절한 식별자, 지시, 포맷된 텍스트가 되도록 해줘요.

오디오 전용 음성 인식은 충분히 잘 동작해서 남아 있는 실패가 과소평가되기 쉬워요. 깔끔한 음성 벤치마크는 실제 제품 문제를 가려요. 사용자는 앱 안에서, 보이는 코드 주변에서, 혼합 언어로, "이 함수"나 "위 항목" 같은 부분 참조와 함께 받아쓰거든요.

ASR이 여전히 실패하는 지점

고전적인 예시는 동음이의어예요. "From foo import bar"와 from foo import bar는 비슷하게 들리지만 다른 세계에 속해요. 모델이 커서가 TypeScript 파일에 있다는 걸 모르면 "cache the auth client"와 "cash the auth client"도 마찬가지죠. 오디오만으로는 목적지를 안정적으로 추론할 수 없어요.

코드 식별자는 이 문제를 더 날카롭게 만들어요. 사용자가 "fetch profile"이라고 말했어도, 보이는 함수는 fetchProfile일 수 있죠. 전사 모델은 단어를 듣지만, 받아쓰기 모델은 식별자를 보존해야 해요. 멀티모달 음성 인식은 보이는 텍스트를 장식이 아닌 증거로 다뤄요.

지시 표현(deixis)이 세 번째 날카로운 경계예요. 사용자가 "replace this with a guard clause"라고 말하면 발화된 텍스트는 기술적으론 완전한 요청이지만, 그 의미는 전적으로 "this"가 가리키는 것에 달려 있어요. 선택 인식이나 안정적인 커서 참조가 없으면 시스템은 추측해야 하고, 잘못된 추측은 다시 타이핑하는 것보다 더 많은 시간을 낭비해요. 오디오 전용 ASR은 지시 표현을 전혀 해결할 수 없어요. 그 지시사를 전사하고, 다운스트림 도구가 어떻게든 풀어주길 바랄 뿐이죠.

  • 동음이의어: 평범한 영어 vs 코드 문법.
  • 엔티티: 패키지 이름, 클래스 이름, 파일 경로, 명령어 플래그.
  • 지시 표현: "이거", "저거", "위에 있는 것", "선택한 부분".
  • 포맷: 산문, 항목, 코드 주석, 커밋 메시지, 또는 프롬프트.

멀티모달 리스너 아키텍처

Loqua의 리스너에는 세 가지 로컬 입력이 있어요. 스트리밍 오디오 특성, 화면에서 추출한 컨텍스트, 그리고 앱 메타데이터예요. 오디오 경로는 무엇이 말해졌는지를 제안해요. 컨텍스트 경로는 텍스트가 어디에 들어갈지를 요약해요. 앱, 필드 타입, 선택된 텍스트, 근처 토큰, 보이는 구조적 단서들이죠. 앱 경로는 줄바꿈, 마크다운, 코드 문법이 적절한지 같은 제약을 더해요.

리스너는 사람처럼 화면 전체를 이해할 필요가 없어요. 받아쓰기에 필요한 최소한의 유용한 증거만 있으면 돼요. VS Code에서는 보이는 식별자, 언어 모드, 선택된 코드일 수 있고요. Slack에서는 스레드 주제와 최근 톤일 수 있어요. Notes에서는 헤딩 레벨과 리스트 컨텍스트일 수 있죠.

의도적으로 하지 않는 것들

의도적으로 범위 밖에 둔 기능들이 있어요. 리스너는 원격 콘텐츠 스크린샷에 OCR을 수행하지 않고, 사용자가 적극적으로 타이핑하지 않는 윈도우를 요약하지 않고, 영구적인 시각 기록을 만들지 않아요. 이미지에서 세밀한 의도를 추론하려고도 하지 않고요. 그래프, 비디오 프레임, 디자인 캔버스는 해석하지 않고 주변 텍스트만 해석해요. 각각의 제거는 예측 가능성과 더 깔끔한 프라이버시 경계를 위해 기능을 맞바꾸는 의도적인 제품 결정이에요.

그래서 좁은 제품적 의미에서만 오디오 비주얼 받아쓰기라고 불러요. 글쓰기를 위한 오디오 + 시각적 컨텍스트라는 의미죠. 목표는 일반 시각 추론이 아니에요. 목표는 커서 위치에서 잘못된 단어를 줄이는 거예요.

화면 컨텍스트가 모호함을 푸는 방법

화면 컨텍스트 받아쓰기는 가능성을 제한해서 출력을 바꿔요. 커서가 Python 파일 안에 있고 보이는 줄에 이미 from fastapi import가 있다면, 발화된 "router"는 일반 명사보다는 심볼일 가능성이 높아요. 커서가 Gmail에 있다면 같은 문구가 문장이 되어야 하고요.

사용자가 말함
"add a guard before fetch profile if auth client is missing"
Loqua가 작성 (VS Code에서)
if (!authClient) return null;
const profile = await fetchProfile(authClient);
사용자가 말함
"can you take a look at the PR I just pushed and let me know if the retry logic looks right"
Loqua가 작성 (Slack에서)
Could you take a look at the PR I just pushed? Want to make sure the retry logic looks right.

리스너는 선택 인식 편집도 처리해요. 텍스트가 선택되어 있으면, 사용자가 명시적으로 새 산문을 삽입해달라고 하지 않는 한, 받아쓰기는 그 텍스트에 대한 지시로 해석돼요. 이 한 가지 구분만으로도 우발적인 중복 텍스트 한 부류를 통째로 제거할 수 있어요.

컨텍스트 충돌은 가장 강한 증거를 먼저 신뢰하는 방식으로 처리해요. 활성 앱은 운영체제가 구조적으로 보장하는 가장 신뢰할 수 있는 신호예요. 그다음은 선택된 텍스트예요. 보이는 근처 토큰은 가장 부드러운 신호예요. 오래됐거나 우연일 수 있거든요. 두 신호가 충돌하면 리스너는 더 단단한 쪽을 선호하고, 하나를 골라 커밋하기보다는 신뢰도를 낮춰요.

프라이버시: 화면 컨텍스트는 로컬에 머무른다

컨텍스트 인식 음성 인식은 부주의하게 구현하면 프라이버시 비용이 들어요. Loqua의 규칙은 리스너가 필요로 하는 화면 컨텍스트는 기본적으로 로컬에 머무른다는 거예요. 컨텍스트 요약은 기기에서 계산돼요. 현재 발화를 다듬는 데 쓰일 뿐, 일반 화면 로그로 보존되지 않아요.

구체적으로, 온디바이스 리스너에 도달하는 건 짧고 일시적인 컨텍스트 번들이에요. 활성 앱 식별자, 언어와 필드 타입, 선택 범위, 그리고 근처에 보이는 텍스트 수백 자예요. 기본적으로 기기를 떠나지 않는 건 더 넓은 윈도우 콘텐츠, 다른 탭, 다른 앱, 또는 위의 어떤 것이든 영구적인 기록이에요. 사용자가 활성화하는 선택적 클라우드 기능은 저희 하이브리드 프라이버시 노트에서 이미 설명한 경계 아래 받아쓴 오디오나 텍스트를 받지, 원본 컨텍스트 번들은 절대 받지 않아요.

이 경계가 중요한 이유는, 보이는 것을 보는 리스너는 코드, 메시지, 초안을 볼 수도 있기 때문이에요. 저희는 그것들을 민감한 데이터로 다뤄요. 프라이버시 아키텍처는 저희 하이브리드 프라이버시 노트에서 더 자세히 다뤘지만, 짧게 말하면 명확해요. 화면 컨텍스트 경로는 로컬 우선이고, 선택적 클라우드 기능은 원본 주변 화면 콘텐츠를 받지 않아요.

공개 연구 컨텍스트

연구 배경에는 오디오-언어 모델링, 비주얼-언어 프로젝션, 멀티모달 인스트럭션 튜닝이 포함돼요. 유용한 출발점으로는 견고한 ASR의 Whisper, 비주얼 인스트럭션 튜닝 패턴의 LLaVA, 그리고 모달리티 간 정렬의 ImageBind가 있어요.

이 논문들은 문헌 컨텍스트예요. Loqua의 멀티모달 음성 인식 스택은 맥 받아쓰기 표면을 위해 튜닝된 독자적인 작업물이에요. 로컬 컨텍스트, 저지연 스트리밍, 앱 인식 출력에 맞춰져 있죠. 분야의 어휘를 빌려 쓰는 거지, 의존성 체인을 빌려 쓰는 게 아니에요.

로드맵

다음 단계는 더 나은 불확실성 보고예요. 컨텍스트가 두 개의 가능한 식별자를 시사하면, 시스템은 자신감을 지어내기보다 모호함을 보존해야 해요. 또 터미널, 스프레드시트, IDE 채팅 패널, 디자인 도구처럼 유용한 출력의 형태가 크게 다른 곳을 위해 더 세분화된 앱 어댑터를 원해요.

터미널 어댑터가 가장 구체적인 단기 작업이에요. 터미널은 구조적으로는 커서 위치의 한 줄이지만, 컨텍스트적으로는 사용자가 곧 입력할 내용을 알려주는 이전 명령과 출력의 긴 기록이에요. 스프레드시트 어댑터는 정반대 형태예요. 작은 가시 컨텍스트 윈도우와 엄격한 열 의미를 가지죠. 두 어댑터 모두 같은 리스너 아키텍처를 재사용해요. 차이는 무엇이 증거로 간주되고, 텍스트 렌더러가 어디서 포매팅 단서를 얻는가에 있어요.

장기 방향은 "모델이 모든 걸 본다"가 아니에요. 더 좁고 안전해요. 리스너가 의도된 곳에 의도된 대로 더 적은 정리로 쓰기 위한 충분한 로컬 컨텍스트만 본다는 거죠. 그게 멀티모달 음성 인식의 제품 약속이에요.

자주 묻는 질문

멀티모달 음성 인식이란 무엇인가요?
멀티모달 음성 인식은 오디오와 화면 컨텍스트, 앱 메타데이터 같은 다른 신호를 결합해서 의도된 출력 텍스트를 추론하는 거예요. Loqua에서는 시스템이 음성을 전사할 뿐 아니라 커서가 어디 있는지, 근처에 어떤 텍스트가 보이는지도 함께 고려한다는 뜻이에요.
왜 오디오 전용 ASR이 코드에서 실패하나요?
코드에는 식별자, 패키지 이름, 대소문자, 구두점, 문법이 있어서 소리만으로는 명확하지 않을 수 있어요. 모델이 'fetch profile'을 정확히 들어도, 보이는 식별자가 fetchProfile이라는 걸 놓칠 수 있죠. 화면 컨텍스트는 인식기에 오디오엔 없는 증거를 줘요.
Loqua는 제 화면을 녹화하나요?
여기서 설명하는 제품의 의미에서는 그렇지 않아요. Loqua는 활성 앱, 선택된 텍스트, 근처에 보이는 텍스트 같은 현재 받아쓰기 이벤트에 필요한 로컬 컨텍스트를 읽어요. 연속 화면 녹화기로 설계되지 않았고, 컨텍스트 경로는 기본적으로 로컬에 머물러요.
개인 사전과는 어떻게 다른가요?
개인 사전은 알려진 문구를 선호하는 철자로 매핑해요. 멀티모달 컨텍스트는 사용자가 미리 등록하지 않은 문구도 보이는 증거를 보고 해결할 수 있어요. 식별자가 커서 옆에 나타나면, Loqua는 수동 사전 등록 없이도 그 식별자를 보존할 수 있죠.
화면 컨텍스트가 실수할 수 있나요?
네. 보이는 컨텍스트가 오래됐거나, 모호하거나, 관련 없는 경우 리스너가 그쪽으로 과적합할 수 있어요. 제품의 과제는 보정이에요. 강할 때만 컨텍스트를 쓰고, 불확실할 때는 원본 음성을 보존하고, 약한 증거로 자신감 있게 재작성하는 건 피해야 해요.
멀티모달 음성 인식이 개발자만을 위한 건가요?
아니에요. 코드가 식별자로 빽빽해서 개발자가 가장 먼저 그 통증을 느끼지만, 같은 아이디어가 이메일, 노트, 스프레드시트, 프로젝트 도구, 채팅에서도 도움이 돼요. 평범한 단어라도 목적지 앱에 따라 발화된 문구가 어떤 텍스트가 되어야 하는지가 달라져요.
리스너가 받는 컨텍스트 번들에는 정확히 뭐가 들어 있나요?
일시적인 페이로드예요. 활성 앱 식별자, 필드 타입과 언어 모드, 현재 선택 범위, 그리고 근처에 보이는 텍스트 — 보통 수백 자 정도의 작은 윈도우예요. 발화마다 만들어지고, 받아쓰는 동안만 쓰이고, 일반 화면 로그로 저장되지 않아요.

지금 Loqua를 사용해보세요

무료로 시작하세요. 맥 네이티브. 매일 직접 사용하는 알고리즘 연구자들이 만들었어요.

Download for Mac

Loqua Blog의 다른 글

engineering
옴니모달 음성 입력: 멀티모달 이해, MoE, 그리고 스트리밍 텍스트 출력
how-to
맥에서 코드를 받아쓰는 방법: Cursor, VS Code, Claude Code를 위한 완벽 가이드
compare
Loqua vs Typeless: 컨텍스트, 코딩, 깊이를 위한 맥 네이티브 Typeless 대안