화자 임베딩

WeSpeaker ResNet34-LM을 사용해 L2 정규화된 256차원 화자 벡터를 추출합니다. 이러한 임베딩은 화자의 고유한 음성 특성을 포착하며 식별, 검증, 음성 검색에 사용할 수 있습니다.

아키텍처

WeSpeaker ResNet34-LM은 화자 표현 학습을 위해 훈련된 심층 residual 네트워크입니다.

단계세부 내용
입력Conv2d (1 → 32 채널)
ResNet34[3, 4, 6, 3] residual 블록
Stats Pooling시간에 대한 평균 + 표준편차
ProjectionLinear (5120 → 256)
출력L2 정규화된 256차원 임베딩

모델 크기: 약 6.6M 파라미터, 디스크에서 약 25 MB.

멜 특징

이 모델은 Hamming 창으로 계산된 80차원 멜 주파수 특징을 사용합니다. 로그 스케일링은 추가 정규화 없이 단순한 log(max(mel, 1e-10)) 공식을 사용합니다. 배치 정규화는 추론 효율성을 위해 변환 시 Conv2d 레이어에 융합됩니다.

CLI 사용법

# 화자 임베딩 추출
.build/release/audio embed-speaker voice.wav

# JSON 출력 (256차원 벡터 포함)
.build/release/audio embed-speaker voice.wav --json

# 추론 엔진 선택
.build/release/audio embed-speaker voice.wav --engine coreml

옵션

옵션설명
--engine추론 엔진: mlx 또는 coreml
--json전체 임베딩 벡터를 포함한 JSON 출력 형식

사용 사례

화자 검증

두 개의 오디오 샘플을 비교하여 동일한 화자인지 판단합니다. 두 샘플에서 임베딩을 추출하고 코사인 유사도를 계산합니다. 유사도 점수가 높을수록 동일 화자일 확률이 높습니다.

import SpeechVAD

let model = try await WeSpeaker.loadFromHub()
let embedding1 = try await model.embed(audioFile: "sample1.wav")
let embedding2 = try await model.embed(audioFile: "sample2.wav")

let similarity = cosineSimilarity(embedding1, embedding2)
print("Similarity: \(similarity)")  // > 0.7이면 일반적으로 동일 화자

화자 식별

미지의 오디오 샘플을 등록된 화자 임베딩 데이터베이스와 매칭합니다. 가장 높은 코사인 유사도를 가진 등록 화자가 예측된 식별자입니다.

음성 검색

오디오 녹음 컬렉션을 화자 임베딩으로 인덱싱한 후, 새 오디오 샘플로 쿼리해 동일 화자의 모든 녹음을 찾습니다.

중요

화자 임베딩은 최소 2-3초의 깨끗한 음성에서 가장 잘 동작합니다. 매우 짧은 클립이나 잡음 녹음은 덜 신뢰할 수 있는 임베딩을 생성할 수 있습니다. 잡음 오디오의 경우 먼저 음성 향상을 적용해 보세요.

모델 다운로드

모델백엔드크기HuggingFace
WeSpeaker-ResNet34-LMMLX약 25 MBaufklarer/WeSpeaker-ResNet34-LM-MLX
WeSpeaker-ResNet34-LMCoreML약 25 MBaufklarer/WeSpeaker-ResNet34-LM-CoreML

Swift API

import SpeechVAD

let model = try await WeSpeaker.loadFromHub()

// 파일에서 임베딩 추출
let embedding = try await model.embed(audioFile: "voice.wav")
print("Embedding dimensions: \(embedding.count)")  // 256

// 오디오 샘플에서 임베딩 추출
let samples: [Float] = loadAudio("voice.wav")
let embedding = try await model.embed(samples: samples, sampleRate: 16000)