Speaker Diarization 오픈소스 프레임워크 소개

Judy·2024년 1월 6일
0

Speaker Diarization (화자 분할)
두 사람 이상이 대화를 하는 경우 각 화자를 구분하는 기술로,
'화자가 다르다는 것을 인식'하기 위한 기술입니다.

이번 포스팅에서는 오픈소스 화자분할 프레임워크 3가지를 소개합니다.

Pyannote (pyannote.audio)

https://github.com/pyannote/pyannote-audio
https://huggingface.co/pyannote/speaker-diarization-3.1

화자 분할 모델로 가장 유명할 Pyannote 를 가장 먼저 소개합니다.
PyTorch 머신러닝 프레임워크를 기반으로 하며,
Pyannote 는 화자 분할 이외에도 화자 인식(speaker recognition), 화자 분리(speaker segmentation),
음성 활동 검출(voice activity detection) 등의 모델을 지원합니다.

Huggingface 에 모델이 배포되어 있으므로 빠르게 추론 결과를 볼 수 있습니다.

from pyannote.audio import Pipeline
pipeline = Pipeline.from_pretrained(
    "pyannote/speaker-diarization-3.1",
    use_auth_token="HUGGINGFACE_ACCESS_TOKEN_GOES_HERE")

# send pipeline to GPU (when available)
import torch
pipeline.to(torch.device("cuda"))

# apply pretrained pipeline
diarization = pipeline("audio.wav")

# print the result
for turn, _, speaker in diarization.itertracks(yield_label=True):
    print(f"start={turn.start:.1f}s stop={turn.end:.1f}s speaker_{speaker}")

Simple-Diarizer

https://github.com/cvqluu/simple_diarizer

이름에 걸맞게 코드가 매우 심플하고, 그만큼 추론 속도가 빠른 프레임워크입니다.

Embedding Model

  • speechbrain.pretrained model (xvec or ecapa)
    • speechbrain/spkrec-xvect-voxceleb
    • speechbrain/spkrec-ecapa-voxceleb

Cluster

  • AHC (Agglomerative Hierarchical Clustering)
  • SC (Spectral Clustering)

Simple Diarizer 는 CPU 에서 다른 오픈소스와 비교하여 빠른 속도를 보이는데요,
그 비결은 wav 파일을 컨버팅하여 이용하기 때문입니다.
(조금 더 자세히 설명하면 오디오 파일을 single channel wav 로 변환하여 이용합니다.)

print("Converting audio file to single channel WAV using ffmpeg...")
            converted_wavfile = os.path.join(
                os.path.dirname(wav_file), "{}_converted.wav".format(recname)
            )

컨버팅하지 않을 경우 VAD 소요 시간은 3~4배 가량의 차이를 보입니다.

  • 일반 wav : VAD 26~33.8 초
  • 컨버팅 wav : VAD 8.9초

개인적으로 코드리뷰 후 느낀 점은 다른 프레임워크에 비해 구조가 간결하고,
최소한의 기능을 제공하여 코드 리뷰 및 커스터마이징이 수월하다는 점이었습니다.

import soundfile as sf
import matplotlib.pyplot as plt

from simple_diarizer.diarizer import Diarizer
from simple_diarizer.utils import combined_waveplot

diar = Diarizer(
                  embed_model='xvec', # 'xvec' and 'ecapa' supported
                  cluster_method='sc' # 'ahc' and 'sc' supported
               )

segments = diar.diarize(WAV_FILE, num_speakers=NUM_SPEAKERS)

Diart

https://github.com/juanmc2005/diart

화자분할 프레임워크 중 유일하게 실시간 화자 분할을 지원하는 프레임워크입니다.
(RxPY 비동기 프레임워크를 사용하여 실시간 추론을 지원)

버전이 자주 업데이트되므로 수시로 최신 버전을 체크하여 업데이트된 기능을 빠르게 이용해 볼 수 있습니다.

🎙️ Stream audio
diart 설치 후 터미널 창에 다음과 같이 명령어를 입력하여 실시간 화자 분할을 이용할 수 있습니다.

(오디오 파일 화자 분할) diart.stream /path/to/audio.wav
(마이크에 음성을 입력하여 실시간 화자 분할) diart.stream microphone

파이썬 코드를 이용할 경우 다음 코드를 사용합니다.

from diart import SpeakerDiarization
from diart.sources import MicrophoneAudioSource
from diart.inference import StreamingInference
from diart.sinks import RTTMWriter

pipeline = SpeakerDiarization()
mic = MicrophoneAudioSource()
inference = StreamingInference(pipeline, mic, do_plot=True)
inference.attach_observers(RTTMWriter(mic.uri, "/output/file.rttm"))
prediction = inference()

🧠 Models
Diart 는 기본적으로 pyannote 모델(pretrained) 을 이용하며, speechbrain 모델 또한 지원합니다.
Huggingface 의 모델 이름을 model_name 자리에 입력하여 간단하게 사용할 수 있습니다.
(자세한 모델 소개는 Diart GitHub 의 Readme 참고)

import diart.models as m

segmentation = m.SegmentationModel.from_pretrained("model_name")
embedding = m.EmbeddingModel.from_pretrained("model_name")

📈 Tune hyper-parameters
추가 학습 또한 지원하는데, 저는 아직 이 기능을 이용해 보지 않아서 소개는 생략하겠습니다.

🌐 WebSockets
웹소켓을 이용하면 실시간 화자 분할 서버 - 클라이언트 또한 간편하게 구현할 수 있습니다.
2개의 터미널 창을 켜고, 각각의 명령어를 입력하면 서버와 클라이언트가 각각 구동됩니다.

(서버) diart.serve --host 0.0.0.0 --port 7007
(클라이언트) diart.client microphone --host <server-address> --port 7007

클라이언트의 마이크를 통해 음성을 입력받아 서버로 전송하면
서버에서는 0.5 초 단위로 화자 분할을 수행하고 실시간으로 RTTM 포맷의 화자 분할 결과값을 클라이언트로 전송합니다.

Tip

  • Pyannote, Diart 의 경우 버전에 따라 코드가 바뀌는 경우가 있음. 최신 버전 확인하기.
profile
NLP Researcher

0개의 댓글