연구노트

R&E 연구노트 ⑧ Whisper로 실시간 음성 인식 만들기

3마지막 수정
R&E 연구노트 ⑧ Whisper로 실시간 음성 인식 만들기

연구노트 시리즈.

목표: 저사양에서도 실시간으로

앞 글에서 시각 기반 화자 분리는 실시간의 벽에 막혔다. 그래서 1년 차에는 잡음 환경에서도 견고한 실시간 음성 인식에 집중했다. 목표는 분명했다. 저사양 ARM 환경(라즈베리파이)에서도 음성 입력 후 2~3초 내에 주문이 완료되는 것.

키오스크 본체(라즈베리파이)는 가볍게 두고 무거운 음성 인식 연산은 별도 서버에서 처리하는 구조를 택했다. 클라이언트(브라우저)가 음성을 WebSocket으로 서버에 스트리밍하면, 서버(Ubuntu 노트북, Flask 호스팅)가 Whisper로 인식해 결과를 즉시 UI에 돌려준다. 인식 결과를 곧바로 되돌려주는 구조라 네트워크 지연을 최소화할 수 있었다.

WebSocket 스트리밍과 메타데이터

클라이언트에서 오는 각 오디오 메시지는 메타데이터와 실제 음성 데이터가 결합된 바이너리 형태다. 메타데이터에는 샘플링 레이트 같은 정보가 담긴다.

서버는 앞부분 메타데이터로 원본 샘플링 레이트를 먼저 확인한다. 음성 인식 엔진은 16kHz 입력을 기준으로 동작하므로 다른 샘플링 레이트로 들어오면 16kHz로 리샘플링한다. PCM 16-bit 오디오를 수치 배열로 변환한 뒤 처리하는 식이다. 이렇게 하면 브라우저나 장치마다 다른 입력 조건을 서버가 흡수해, 입력 환경 차이로 인한 인식 성능 저하를 막는다.

전처리된 오디오는 일정 크기의 청크 단위로 STT 엔진에 연속 입력된다. 덕분에 발화가 끝나기 전에도 부분 인식이 가능해 실시간 자막처럼 빠른 응답을 줄 수 있다. 오디오 수신·전송은 비동기로, 음성 인식 연산은 별도 실행 흐름에서 수행해 둘이 서로의 지연에 영향을 주지 않게 했다.

이중 모델 구조

저사양 환경에서 반응성과 정확도를 함께 잡기 위해 Whisper 모델 두 개를 역할에 따라 나눴다.

발화 중 실시간 부분 인식에는 경량 tiny 모델을 쓰고, 지연을 최소화하기 위해 인위적인 대기 시간을 두지 않았다. 발화가 끝난 뒤 최종 인식에는 더 정확한 medium 모델로 문장 단위 결과를 생성했다. 빠르게 보여주되 마지막엔 정확하게 처리하는 셈이다. 인식 언어는 한국어로 고정해 언어 자동 판별 과정에서 생길 오류를 줄였다.

VAD 튜닝

발화 구간 검출(VAD)에는 두 엔진을 함께 썼다.

  • Silero VAD. 민감도를 0.4로 설정해 배경 소음에 의한 오검출을 줄였다.
  • WebRTC VAD. 민감도를 2로 설정해 발화 시작과 종료를 비교적 빠르게 검출했다.
  • 발화 종료 판단. 음성이 감지되지 않는 상태가 0.7초 이상 지속되면 발화가 끝난 것으로 봤다. 짧은 침묵이나 말 중간의 멈춤이 문장 분리로 오인되지 않게 하려는 것이다.

엔진은 RealtimeSTT를 기반으로 세부 파라미터를 조정해 썼다. 음성은 외부 클라이언트의 WebSocket으로만 받으므로 로컬 마이크 입력은 비활성화했고, 서버의 불필요한 콘솔 출력도 꺼 뒀다.

Whisper에 대해

Whisper는 OpenAI의 자동 음성 인식(ASR) 모델로, Transformer 인코더-디코더 구조를 쓴다. 입력 오디오를 로그-멜 스펙트로그램으로 변환해 처리하며, 약 68만 시간의 다국어 음성으로 학습되어 다양한 억양·소음·방언 조건에서도 비교적 견고하다. 음향 모델과 언어 모델을 따로 설계하던 과거 방식과 달리 음성에서 텍스트까지 엔드투엔드로 처리한다. 이 모델을 PyTorch로 노트북에서 직접 실행했다.

결과

단순한 주문뿐 아니라 여러 옵션을 포함한 여러 음식을 한 번에 주문하는 복잡한 명령도 정확하게 처리할 수 있었다. 이제 인식된 텍스트가 주문이라는 행동으로 바뀌어야 하는데, 그 과정은 ⑩에서 다룰 n8n과 LLM 파이프라인에서 이어진다.

변경 이력 (2건)
  1. gitprogam 수정feat(binaryhub-blog): tetris 위키 + SEO 정비 + hero 이미지 + 글 다수
  2. gitprogam 최초 작성init: monorepo (nsgh-tools + binaryhub-blog)

관련 글