수달이네 기술 블로그

4. VAD(Voice Activity Detection) 본문

프로젝트

4. VAD(Voice Activity Detection)

슬픈 수달이 2026. 4. 15. 15:47

VAD(Voice Activity Detection)

지금 들어오는 소리가 사람의 음성인지 소음인지 판별하는 모듈이다.

무음구간, 소음구간을 모두 전사시키면

  • 불필요한 GPU연산
  • 소음이 엉뚱한 텍스트로 전사
  • 발화 단위 조정이 힘들어 LLM에 넘길 타이밍을 잡지 못함.

EnergyVAD(에너지 기반)

RMS를 통해 신호의 평균적인 에너지를 측정한다.

class EnergyVAD:
	def is_speech(self, pcm_float32: np.ndarray) -> bool:
		rms = np.sqrt(np.mean(pcm_float32 ** 2))
		return rms > self.threshold
  • pcm_float32 값을 받음 → 해당 값이 0.2(기본 임계점)이 넘으면 출력하도록 설정
신호: [-0.1, 0.3, -0.2, 0.4]
         ↓
각 값을 제곱:  [0.01, 0.09, 0.04, 0.16]
         ↓
평균:  0.075
         ↓
루트:  0.274  →  0.02 초과 → 발화!
장점 단점
속도가 빠르고, 연산량이 적음 큰 박수소리, 문닫는 소리에 오반응함.
구현이 단순함 발화 소리가 작으면 묵음으로 판단
실시간 처리에 최적화 마이크 환경에 따라 threshold튜닝 필요

SileroVAD(딥러닝 기반)

신경망이 직접 이 소리가 사람 목소리일 확률을 0~1의 확률로 출력

  • 똑같이 pcm_float32를 받음 → 값을 모델에 넣어 판단 → 확률 출력 
    장점 단점
    소음에 강건함 초기 모델 로딩 시간 필요
    소리가 작아도 감지 무거움
    음악/잡음/목소리 모두 구분 PyTorch의존성 추가
30ms 청크 하나 도착
      ↓
EnergyVAD.is_speech(chunk)
      ↓
  True (발화)          False (묵음)
      ↓                    ↓
버퍼에 추가          이미 발화 중이면
_is_speaking=True    silence_count += 1
                     (0.8초치 = 약 27청크 쌓이면)
                           ↓
                     → 버퍼 flush → Whisper 전송

딥러닝 모델

Silero VAD

https://github.com/snakers4/silero-vad

  • SileroVAD는 6000개 이상의 언어 코퍼스로 학습됨.
  • 다양한 도메인의 오디오, 다양한 배경 소음에서 잘 동작한다는 특성이 있음
  • 위 다른 모델과 비교해봐도 높은 Precision/Recall을 보여줌
  • 해당 모델은 Fine-tuning은 불가하다.
    • Pytorch JIT과 ONNX파일만 제공하기 때문
  • 가중치 threshold만 수정 가능
# 현재 코드의 SileroVAD
class SileroVAD:
    def __init__(self, sample_rate: int = 16000, threshold: float = 0.5):
        ...
        self.threshold = threshold  # ← 이게 유일한 튜닝 포인트