🤖

본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.

⚠️

본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.

A

AI Generated

2026. 2. 3. · 19 Views

Audio Processing Pipeline 완벽 가이드

오디오 파일을 전처리하는 파이프라인 구축 방법을 다룹니다. librosa와 torchaudio를 활용한 샘플링 레이트 변환부터 노이즈 제거, 볼륨 정규화까지 실무에서 바로 사용할 수 있는 기법을 배웁니다.


목차

  1. 오디오_품질의_중요성
  2. librosa_라이브러리_활용
  3. torchaudio로_샘플링_레이트_변환
  4. 노이즈_제거_기법
  5. 볼륨_정규화
  6. 전처리_파이프라인_구축

1. 오디오 품질의 중요성

김개발 씨는 AI 음성 인식 프로젝트에 투입된 지 일주일 됐습니다. 학습 데이터로 사용할 오디오 파일을 모았는데, 인식률이 형편없이 낮습니다.

분명 같은 모델인데 왜 성능 차이가 이렇게 클까요?

오디오 품질은 음성 처리 시스템의 성패를 좌우하는 핵심 요소입니다. 마치 요리에서 신선한 재료가 맛을 결정짓듯이, 깨끗한 오디오 데이터가 모델 성능을 결정합니다.

노이즈가 섞인 오디오로 학습하면 모델은 잡음까지 패턴으로 인식하게 됩니다.

다음 코드를 살펴봅시다.

import librosa
import numpy as np

# 오디오 파일 로드하여 품질 확인
audio_path = "sample.wav"
y, sr = librosa.load(audio_path, sr=None)

# 기본 품질 지표 계산
duration = len(y) / sr
rms_energy = np.sqrt(np.mean(y**2))
zero_crossings = librosa.zero_crossings(y).sum()

print(f"샘플링 레이트: {sr} Hz")
print(f"길이: {duration:.2f}초")
print(f"RMS 에너지: {rms_energy:.4f}")
print(f"영점 교차 횟수: {zero_crossings}")

김개발 씨는 입사 후 첫 번째 프로젝트로 음성 인식 시스템 개발에 참여하게 됐습니다. 선배가 준 학습 데이터 1만 개를 모델에 넣었는데, 정확도가 60%도 안 나옵니다.

같은 모델로 다른 팀은 95%가 넘는다는데 도대체 뭐가 문제일까요? 박시니어 씨가 데이터를 살펴보더니 한숨을 쉽니다.

"이 오디오 들어봤어요? 노이즈가 장난이 아닌데요." 그렇다면 오디오 품질이란 정확히 무엇을 의미할까요?

쉽게 비유하자면, 오디오 품질은 마치 사진의 해상도와 같습니다. 흐릿한 사진으로는 얼굴을 알아보기 어렵듯이, 품질 낮은 오디오로는 음성을 정확히 인식하기 어렵습니다.

노이즈, 클리핑, 잘못된 샘플링 레이트 등이 오디오 품질을 떨어뜨리는 주범입니다. 오디오 품질을 측정하는 핵심 지표가 몇 가지 있습니다.

첫째, 샘플링 레이트입니다. 1초에 몇 번 소리를 측정했는지를 나타냅니다.

일반적으로 음성 인식에는 16,000Hz가 표준으로 사용됩니다. 음악은 44,100Hz가 일반적입니다.

둘째, RMS 에너지입니다. Root Mean Square의 약자로, 오디오 신호의 평균적인 크기를 나타냅니다.

이 값이 너무 작으면 소리가 작은 것이고, 너무 크면 클리핑이 발생할 수 있습니다. 셋째, 영점 교차율입니다.

신호가 0을 기준으로 양수에서 음수로, 또는 그 반대로 바뀌는 횟수입니다. 이 값이 높으면 고주파 성분이 많다는 의미입니다.

위 코드를 살펴보겠습니다. librosa.load 함수는 오디오 파일을 읽어 numpy 배열로 반환합니다.

sr=None으로 설정하면 원본 샘플링 레이트를 유지합니다. 반환된 y는 오디오 신호 데이터이고, sr은 샘플링 레이트입니다.

실제 현업에서 오디오 품질이 왜 중요할까요? 음성 비서 서비스를 개발한다고 가정해봅시다.

사용자가 "날씨 알려줘"라고 말했는데, 에어컨 소음이 함께 녹음됐습니다. 전처리 없이 이런 데이터로 학습하면, 모델은 에어컨 소음을 특정 단어의 패턴으로 학습할 수 있습니다.

다시 김개발 씨 이야기로 돌아가봅시다. 박시니어 씨는 데이터 전처리의 중요성을 설명했습니다.

"쓰레기가 들어가면 쓰레기가 나온다는 말 알죠? 오디오도 마찬가지예요." 김개발 씨는 고개를 끄덕였습니다.

이제 오디오 전처리 파이프라인을 구축해야 할 때입니다.

실전 팁

💡 - 오디오 품질 문제는 모델 성능 저하의 가장 흔한 원인입니다

  • 전처리 전에 반드시 원본 데이터의 품질 지표를 확인하세요

2. librosa 라이브러리 활용

김개발 씨가 오디오 전처리를 시작하려는데 어디서부터 손대야 할지 막막합니다. 파이썬에서 오디오를 다루는 라이브러리가 여러 개 있다는데, 어떤 걸 써야 할까요?

librosa는 파이썬에서 오디오 분석을 위한 대표적인 라이브러리입니다. 마치 이미지 처리에 OpenCV가 있듯이, 오디오 처리에는 librosa가 있습니다.

오디오 로딩, 스펙트로그램 변환, 특성 추출 등 다양한 기능을 제공합니다.

다음 코드를 살펴봅시다.

import librosa
import librosa.display
import numpy as np

# 오디오 로드 (기본 22050Hz로 리샘플링)
y, sr = librosa.load("sample.wav", sr=22050)

# 멜 스펙트로그램 계산
mel_spec = librosa.feature.melspectrogram(y=y, sr=sr, n_mels=128)
mel_spec_db = librosa.power_to_db(mel_spec, ref=np.max)

# MFCC 특성 추출 (음성 인식에 핵심)
mfccs = librosa.feature.mfcc(y=y, sr=sr, n_mfcc=13)

# 오디오 트리밍 (무음 구간 제거)
y_trimmed, index = librosa.effects.trim(y, top_db=20)
print(f"원본 길이: {len(y)}, 트리밍 후: {len(y_trimmed)}")

박시니어 씨가 김개발 씨에게 librosa를 추천했습니다. "오디오 처리 입문자에게는 librosa가 최고예요.

문서화도 잘 되어 있고, 커뮤니티도 활발하거든요." librosa는 음악 정보 검색 연구에서 시작된 라이브러리입니다. 하지만 지금은 음성 인식, 환경음 분류, 음악 생성 등 오디오와 관련된 거의 모든 분야에서 사용됩니다.

librosa의 가장 큰 장점은 직관적인 API입니다. librosa.load 함수 하나로 오디오 파일을 읽을 수 있습니다.

자동으로 모노 채널로 변환하고, 원하는 샘플링 레이트로 리샘플링까지 해줍니다. 기본값은 22,050Hz인데, 이는 음악 분석에 적합한 값입니다.

멜 스펙트로그램은 오디오를 시각화하는 대표적인 방법입니다. 사람의 귀는 주파수를 선형적으로 인식하지 않습니다.

낮은 주파수 변화에는 민감하고, 높은 주파수 변화에는 둔감합니다. 멜 스케일은 이런 인간의 청각 특성을 반영한 것입니다.

librosa.feature.melspectrogram 함수가 이 복잡한 계산을 한 줄로 처리합니다. MFCC는 음성 인식에서 가장 많이 쓰이는 특성입니다.

Mel-Frequency Cepstral Coefficients의 약자로, 사람이 발음할 때 성대와 입 모양의 특성을 수치화한 것입니다. 일반적으로 13개의 계수를 추출하며, 음성 인식 모델의 입력으로 자주 사용됩니다.

위 코드에서 librosa.effects.trim 함수를 눈여겨보세요. 이 함수는 오디오의 앞뒤 무음 구간을 자동으로 제거합니다.

top_db=20은 20데시벨 이하를 무음으로 간주한다는 의미입니다. 녹음 시작 전후의 불필요한 침묵을 제거하는 데 유용합니다.

실무에서 librosa는 어떻게 활용될까요? 음성 감정 인식 서비스를 예로 들어보겠습니다.

콜센터에서 고객의 감정 상태를 파악하고 싶다면, 먼저 통화 녹음 파일에서 MFCC 특성을 추출합니다. 이 특성을 딥러닝 모델에 입력하면 화남, 기쁨, 슬픔 등의 감정을 분류할 수 있습니다.

주의할 점이 있습니다. librosa는 분석에는 강하지만, 실시간 처리에는 적합하지 않습니다.

파일을 메모리에 전부 로드하는 방식이기 때문입니다. 실시간 스트리밍이 필요하다면 다른 라이브러리를 고려해야 합니다.

김개발 씨가 librosa로 데이터를 분석해보니, 샘플링 레이트가 제각각인 파일이 많았습니다. 어떤 건 8,000Hz이고 어떤 건 44,100Hz입니다.

이걸 통일해야 할 것 같은데, 어떻게 해야 할까요?

실전 팁

💡 - pip install librosa로 간단히 설치할 수 있습니다

  • sr=None으로 설정하면 원본 샘플링 레이트를 유지합니다

3. torchaudio로 샘플링 레이트 변환

김개발 씨가 수집한 오디오 파일들의 샘플링 레이트가 제각각입니다. 8,000Hz부터 48,000Hz까지 다양합니다.

모델에 넣으려면 통일해야 하는데, 단순히 숫자만 바꾸면 되는 걸까요?

torchaudio는 PyTorch 기반의 오디오 처리 라이브러리입니다. GPU 가속을 지원하여 대용량 데이터 처리에 유리합니다.

특히 리샘플링 기능이 뛰어나서 샘플링 레이트 변환에 많이 사용됩니다. librosa와 함께 사용하면 강력한 전처리 파이프라인을 구축할 수 있습니다.

다음 코드를 살펴봅시다.

import torchaudio
import torch

# 오디오 파일 로드
waveform, original_sr = torchaudio.load("sample.wav")
print(f"원본: {original_sr}Hz, shape: {waveform.shape}")

# 16000Hz로 리샘플링 (음성 인식 표준)
target_sr = 16000
resampler = torchaudio.transforms.Resample(
    orig_freq=original_sr,
    new_freq=target_sr,
    resampling_method="sinc_interp_hann"
)
resampled = resampler(waveform)

# 스테레오를 모노로 변환
if resampled.shape[0] > 1:
    resampled = torch.mean(resampled, dim=0, keepdim=True)

# 저장
torchaudio.save("output_16k.wav", resampled, target_sr)
print(f"변환 후: {target_sr}Hz, shape: {resampled.shape}")

박시니어 씨가 김개발 씨에게 중요한 사실을 알려줬습니다. "샘플링 레이트 변환은 그냥 숫자 바꾸는 게 아니에요.

잘못하면 음질이 심하게 손상됩니다." 샘플링 레이트는 1초에 몇 번 소리를 측정했는지를 나타냅니다. 쉽게 비유하자면, 초당 몇 장의 사진을 찍었는지와 같습니다.

영화는 보통 초당 24프레임인데, 이보다 적으면 뚝뚝 끊겨 보입니다. 오디오도 마찬가지입니다.

샘플링 레이트가 낮으면 고주파 성분이 손실되어 뭉개진 소리가 됩니다. 나이퀴스트 정리에 따르면, 특정 주파수를 재현하려면 그 두 배 이상의 샘플링 레이트가 필요합니다.

인간의 가청 주파수는 20Hz에서 20,000Hz입니다. 따라서 CD 음질인 44,100Hz는 22,050Hz까지의 주파수를 재현할 수 있습니다.

음성 인식에서 자주 쓰는 16,000Hz는 8,000Hz까지 재현 가능한데, 사람 목소리의 핵심 주파수 대역을 충분히 커버합니다. torchaudio의 Resample 변환기를 살펴보겠습니다.

resampling_method 파라미터가 핵심입니다. sinc_interp_hann은 싱크 보간법과 한 윈도우를 조합한 방식으로, 고품질 리샘플링을 보장합니다.

단순히 샘플을 건너뛰거나 반복하는 것이 아니라, 수학적으로 정밀하게 새 샘플값을 계산합니다. 왜 torchaudio를 사용할까요?

librosa도 리샘플링을 지원하는데요. 첫째, GPU 가속입니다.

수만 개의 오디오 파일을 처리해야 한다면 GPU를 활용하는 것이 훨씬 빠릅니다. torchaudio는 PyTorch 텐서를 사용하므로 .cuda()만 호출하면 GPU에서 처리됩니다.

둘째, 일관성입니다. 모델 학습에 PyTorch를 사용한다면, 전처리도 torchaudio로 통일하는 것이 관리하기 편합니다.

텐서 변환 없이 바로 모델에 입력할 수 있습니다. 위 코드에서 스테레오를 모노로 변환하는 부분도 중요합니다.

음성 인식에서는 보통 모노 채널을 사용합니다. torch.mean으로 두 채널의 평균을 구하면 자연스럽게 모노로 변환됩니다.

주의할 점이 있습니다. 업샘플링과 다운샘플링의 차이를 이해해야 합니다.

8,000Hz를 16,000Hz로 올리는 업샘플링은 이미 손실된 고주파를 복원하지 못합니다. 없는 정보를 만들어낼 수는 없으니까요.

반면 44,100Hz를 16,000Hz로 내리는 다운샘플링은 고주파 정보를 버리는 것입니다. 따라서 가능하면 원본 샘플링 레이트가 높은 데이터를 수집하는 것이 좋습니다.

김개발 씨는 모든 파일을 16,000Hz로 통일했습니다. 이제 노이즈를 제거할 차례입니다.

실전 팁

💡 - 음성 인식에는 16,000Hz가 표준이고, 음악에는 44,100Hz가 표준입니다

  • 업샘플링으로는 손실된 정보를 복원할 수 없습니다

4. 노이즈 제거 기법

김개발 씨가 샘플링 레이트를 통일했는데, 여전히 문제가 있습니다. 에어컨 소음, 키보드 타이핑 소리, 멀리서 들리는 대화 소리까지.

깨끗한 음성만 남기려면 어떻게 해야 할까요?

노이즈 제거는 원하지 않는 소리를 걸러내는 과정입니다. 마치 사진에서 잡티를 지우는 것처럼, 오디오에서도 불필요한 소음을 제거할 수 있습니다.

스펙트럼 감산법, 위너 필터, 딥러닝 기반 방법 등 다양한 기법이 있습니다.

다음 코드를 살펴봅시다.

import noisereduce as nr
import librosa
import numpy as np
import soundfile as sf

# 오디오 로드
y, sr = librosa.load("noisy_audio.wav", sr=16000)

# 방법 1: noisereduce 라이브러리 사용
# 첫 0.5초를 노이즈 프로파일로 사용
noise_sample = y[:int(sr * 0.5)]
y_denoised = nr.reduce_noise(
    y=y,
    sr=sr,
    y_noise=noise_sample,
    prop_decrease=0.8  # 노이즈 감소 비율
)

# 방법 2: 스펙트럼 게이팅 (간단한 방식)
def spectral_gate(audio, sr, threshold_db=-40):
    stft = librosa.stft(audio)
    magnitude = np.abs(stft)
    threshold = librosa.db_to_amplitude(threshold_db)
    mask = magnitude > threshold
    return librosa.istft(stft * mask)

y_gated = spectral_gate(y, sr, threshold_db=-35)
sf.write("denoised_output.wav", y_denoised, sr)

박시니어 씨가 노이즈 제거에 대해 설명을 시작했습니다. "노이즈 제거는 오디오 전처리에서 가장 어려운 부분이에요.

너무 세게 하면 음성도 같이 뭉개지거든요." 노이즈 제거의 기본 원리는 무엇일까요? 쉽게 비유하자면, 노이즈 제거는 마치 시끄러운 카페에서 대화하는 것과 같습니다.

뇌가 주변 소음의 패턴을 파악하고, 그 소음을 무시하면서 대화 상대의 목소리에만 집중하는 것처럼요. 컴퓨터도 비슷한 방식으로 노이즈를 학습하고 제거합니다.

스펙트럼 감산법은 가장 전통적인 노이즈 제거 방식입니다. 먼저 노이즈만 있는 구간을 찾습니다.

녹음 시작 전 무음 구간이나, 말하지 않는 순간을 활용합니다. 이 구간의 스펙트럼을 노이즈 프로파일로 저장합니다.

그 다음 전체 오디오 스펙트럼에서 노이즈 프로파일을 빼면 됩니다. noisereduce 라이브러리는 이 과정을 자동화합니다.

y_noise 파라미터에 노이즈 샘플을 넣으면, 라이브러리가 알아서 노이즈 프로파일을 분석합니다. prop_decrease는 노이즈를 얼마나 줄일지 결정합니다.

0.8이면 80% 감소를 의미합니다. 이 값이 너무 높으면 음성도 손상될 수 있습니다.

스펙트럼 게이팅은 더 단순한 방식입니다. 특정 임계값 이하의 신호를 모두 0으로 만듭니다.

노이즈는 보통 에너지가 낮으므로 이렇게 해도 어느 정도 효과가 있습니다. 하지만 음성의 약한 부분도 함께 잘릴 수 있어서 주의가 필요합니다.

위 코드에서 librosa.stft는 오디오를 주파수 영역으로 변환합니다. STFT는 Short-Time Fourier Transform의 약자로, 시간에 따른 주파수 변화를 분석합니다.

처리 후 librosa.istft로 다시 시간 영역으로 변환합니다. 실무에서는 어떤 방법을 써야 할까요?

녹음 환경이 일정하다면 스펙트럼 감산법이 효과적입니다. 사무실 에어컨 소음처럼 일정한 노이즈는 잘 제거됩니다.

반면 불규칙한 노이즈, 예를 들어 지나가는 자동차 소리나 갑자기 짖는 개 소리는 딥러닝 기반 방법이 더 효과적입니다. 주의할 점이 있습니다.

노이즈 제거는 항상 트레이드오프가 있습니다. 노이즈를 많이 제거하면 음성 품질도 저하됩니다.

특히 자음 발음은 노이즈와 비슷한 주파수 대역을 가져서 쉽게 손상됩니다. 따라서 적절한 균형점을 찾는 것이 중요합니다.

김개발 씨가 노이즈 제거를 적용했더니 훨씬 깨끗해졌습니다. 하지만 파일마다 소리 크기가 다릅니다.

어떤 건 귀가 찢어질 듯 크고, 어떤 건 거의 안 들립니다.

실전 팁

💡 - pip install noisereduce로 쉽게 설치할 수 있습니다

  • 노이즈 샘플은 최소 0.5초 이상 확보하는 것이 좋습니다

5. 볼륨 정규화

김개발 씨가 노이즈를 제거했는데, 새로운 문제가 생겼습니다. 어떤 파일은 소리가 너무 크고, 어떤 파일은 너무 작습니다.

모델이 일관된 볼륨의 데이터를 기대하는데, 이대로 괜찮을까요?

볼륨 정규화는 오디오 신호의 크기를 일정하게 맞추는 과정입니다. 마치 사진의 밝기를 조정하는 것처럼, 오디오의 음량을 표준 범위로 맞춥니다.

피크 정규화와 RMS 정규화가 가장 많이 사용되며, 방송에서는 라우드니스 정규화(LUFS)를 사용합니다.

다음 코드를 살펴봅시다.

import numpy as np
import librosa
import soundfile as sf

def peak_normalize(audio, target_peak=0.95):
    """피크 정규화: 최대값을 기준으로 정규화"""
    peak = np.max(np.abs(audio))
    if peak > 0:
        return audio * (target_peak / peak)
    return audio

def rms_normalize(audio, target_rms=0.1):
    """RMS 정규화: 평균 에너지를 기준으로 정규화"""
    current_rms = np.sqrt(np.mean(audio**2))
    if current_rms > 0:
        return audio * (target_rms / current_rms)
    return audio

# 오디오 로드
y, sr = librosa.load("audio.wav", sr=16000)

# 피크 정규화 적용
y_peak_norm = peak_normalize(y, target_peak=0.9)

# RMS 정규화 적용 (더 일관된 음량)
y_rms_norm = rms_normalize(y, target_rms=0.1)

# 클리핑 방지
y_rms_norm = np.clip(y_rms_norm, -1.0, 1.0)
sf.write("normalized.wav", y_rms_norm, sr)

박시니어 씨가 김개발 씨의 데이터를 들어보더니 미간을 찌푸렸습니다. "이렇게 볼륨이 들쭉날쭉하면 모델이 제대로 학습할 수 없어요.

정규화가 필수입니다." 볼륨 정규화가 왜 필요할까요? 쉽게 비유하자면, 시험지 채점과 같습니다.

어떤 학생은 연필로 흐리게 썼고, 어떤 학생은 볼펜으로 진하게 썼습니다. 채점자는 글씨 진하기가 아니라 내용을 봐야 합니다.

마찬가지로 음성 인식 모델은 볼륨이 아니라 발음 패턴을 봐야 합니다. 피크 정규화는 가장 간단한 방식입니다.

오디오에서 가장 큰 값을 찾아서, 그 값이 목표치가 되도록 전체를 스케일링합니다. target_peak=0.95는 최대값이 0.95가 되도록 맞춘다는 의미입니다.

1.0으로 하지 않는 이유는 클리핑 여유를 남겨두기 위함입니다. 하지만 피크 정규화에는 한계가 있습니다.

순간적으로 큰 소리가 하나 있으면, 전체 볼륨이 낮아집니다. 예를 들어 녹음 중 책상을 탁 치는 소리가 있으면, 그 한 순간 때문에 전체 음성이 작아지는 것입니다.

RMS 정규화가 이 문제를 해결합니다. RMS는 Root Mean Square의 약자로, 신호의 평균적인 에너지를 의미합니다.

순간적인 피크가 아니라 전체적인 음량을 기준으로 정규화하므로, 더 일관된 청취 경험을 제공합니다. 위 코드를 살펴보겠습니다.

np.sqrt(np.mean(audio**2))가 RMS를 계산하는 공식입니다. 각 샘플을 제곱하고, 평균을 구한 뒤, 제곱근을 취합니다.

이 값을 목표 RMS로 나눈 비율만큼 전체 신호를 곱합니다. np.clip 함수는 중요합니다.

RMS 정규화 후 일부 피크가 -1.0에서 1.0 범위를 벗어날 수 있습니다. 이를 강제로 범위 안에 맞추는 것이 클리핑입니다.

클리핑이 많이 발생하면 음질이 저하되므로, target_rms를 적절히 조정해야 합니다. 실무에서는 어떤 값을 사용할까요?

음성 인식에서는 target_rms를 0.05에서 0.15 사이로 설정하는 것이 일반적입니다. 너무 높으면 클리핑이 발생하고, 너무 낮으면 노이즈 대비 신호가 약해집니다.

방송 업계에서는 LUFS라는 더 정교한 측정 방법을 사용합니다. Loudness Units relative to Full Scale의 약자로, 인간의 청각 특성을 반영한 음량 측정 단위입니다.

pyloudnorm 라이브러리로 파이썬에서도 사용할 수 있습니다. 김개발 씨가 RMS 정규화를 적용했습니다.

이제 모든 파일이 일관된 볼륨을 가집니다. 지금까지 배운 것들을 하나로 합칠 차례입니다.

실전 팁

💡 - 음성 인식에는 RMS 정규화가 피크 정규화보다 적합합니다

  • 클리핑 발생 시 target_rms 값을 낮추세요

6. 전처리 파이프라인 구축

김개발 씨가 지금까지 배운 모든 것을 정리했습니다. 샘플링 레이트 변환, 노이즈 제거, 볼륨 정규화.

이제 이 과정을 자동화해서 수만 개의 파일에 적용해야 합니다. 어떻게 효율적으로 처리할 수 있을까요?

전처리 파이프라인은 여러 처리 단계를 순서대로 연결한 자동화 시스템입니다. 마치 공장의 컨베이어 벨트처럼, 원본 오디오가 들어가면 정제된 오디오가 나옵니다.

모듈화와 병렬 처리를 통해 대용량 데이터도 효율적으로 처리할 수 있습니다.

다음 코드를 살펴봅시다.

import librosa
import noisereduce as nr
import numpy as np
import soundfile as sf
from pathlib import Path
from concurrent.futures import ProcessPoolExecutor

class AudioPreprocessor:
    def __init__(self, target_sr=16000, target_rms=0.1):
        self.target_sr = target_sr
        self.target_rms = target_rms

    def process(self, input_path, output_path):
        # 1단계: 로드 및 리샘플링
        y, sr = librosa.load(input_path, sr=self.target_sr, mono=True)

        # 2단계: 무음 구간 트리밍
        y, _ = librosa.effects.trim(y, top_db=25)

        # 3단계: 노이즈 제거
        y = nr.reduce_noise(y=y, sr=self.target_sr, prop_decrease=0.7)

        # 4단계: RMS 정규화
        rms = np.sqrt(np.mean(y**2))
        if rms > 0:
            y = y * (self.target_rms / rms)
        y = np.clip(y, -1.0, 1.0)

        # 저장
        sf.write(output_path, y, self.target_sr)
        return output_path

# 병렬 처리로 대량 파일 처리
def batch_process(input_dir, output_dir, num_workers=4):
    preprocessor = AudioPreprocessor()
    input_files = list(Path(input_dir).glob("*.wav"))
    Path(output_dir).mkdir(exist_ok=True)

    with ProcessPoolExecutor(max_workers=num_workers) as executor:
        futures = []
        for f in input_files:
            out_path = Path(output_dir) / f.name
            futures.append(executor.submit(preprocessor.process, f, out_path))

        for future in futures:
            print(f"완료: {future.result()}")

프로젝트 마감이 다가왔습니다. 김개발 씨에게 남은 파일은 5만 개.

하나씩 처리하면 일주일이 걸릴 것 같습니다. 박시니어 씨가 해결책을 제시했습니다.

"파이프라인을 만들고 병렬로 돌리면 돼요." 전처리 파이프라인이란 무엇일까요? 쉽게 비유하자면, 자동차 세차장과 같습니다.

차가 들어가면 먼저 물로 헹구고, 비누칠하고, 다시 헹구고, 건조합니다. 각 단계가 정해진 순서대로 진행되고, 여러 대의 차가 동시에 다른 단계에서 처리됩니다.

오디오 파이프라인도 마찬가지입니다. 위 코드의 AudioPreprocessor 클래스를 살펴보겠습니다.

process 메서드가 핵심입니다. 한 개의 오디오 파일이 들어오면 네 단계를 거쳐 정제된 파일로 출력됩니다.

각 단계는 이전 단계의 출력을 입력으로 받습니다. 1단계는 로드 및 리샘플링입니다.

librosa.load에 sr=self.target_sr를 지정하면 자동으로 리샘플링됩니다. mono=True는 스테레오를 모노로 변환합니다.

2단계는 무음 트리밍입니다. librosa.effects.trim으로 앞뒤 무음 구간을 제거합니다.

top_db=25는 25데시벨 이하를 무음으로 간주합니다. 3단계는 노이즈 제거입니다.

noisereduce 라이브러리가 자동으로 노이즈 프로파일을 추정합니다. prop_decrease=0.7은 70% 감소를 의미합니다.

4단계는 RMS 정규화입니다. 목표 RMS 값으로 볼륨을 맞추고, 클리핑을 방지합니다.

병렬 처리가 속도를 극적으로 높여줍니다. ProcessPoolExecutor는 여러 개의 파이썬 프로세스를 동시에 실행합니다.

num_workers=4면 4개 파일을 동시에 처리합니다. CPU 코어 수에 맞춰 조정하면 됩니다.

8코어 CPU라면 num_workers=8로 설정하세요. 왜 ThreadPoolExecutor가 아니라 ProcessPoolExecutor일까요?

파이썬의 GIL 때문입니다. CPU 집약적인 작업은 멀티프로세싱이 더 효과적입니다.

오디오 처리는 CPU를 많이 사용하므로 ProcessPoolExecutor가 적합합니다. 실무에서 고려할 점이 더 있습니다.

첫째, 에러 처리입니다. 손상된 파일이 있으면 전체 프로세스가 멈출 수 있습니다.

try-except로 개별 파일 에러를 처리하고 로그를 남기세요. 둘째, 진행 상황 표시입니다.

5만 개 파일을 처리하는데 아무 출력도 없으면 불안합니다. tqdm 라이브러리로 진행률 바를 추가하세요.

셋째, 재시작 지원입니다. 중간에 프로세스가 죽으면 처음부터 다시 하기 싫습니다.

이미 처리된 파일은 건너뛰도록 구현하세요. 김개발 씨가 파이프라인을 완성하고 실행했습니다.

4코어 노트북으로 5만 개 파일을 하룻밤에 처리했습니다. 다음 날 아침, 정제된 데이터로 모델을 다시 학습했더니 정확도가 92%로 뛰어올랐습니다.

박시니어 씨가 웃으며 말했습니다. "봤죠?

좋은 데이터가 좋은 모델을 만드는 겁니다." 김개발 씨의 첫 번째 프로젝트는 성공적으로 마무리됐습니다. 오디오 전처리의 중요성을 몸소 깨달은 소중한 경험이었습니다.

실전 팁

💡 - CPU 코어 수에 맞춰 num_workers를 설정하세요

  • tqdm을 추가하면 진행 상황을 실시간으로 확인할 수 있습니다

이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!

#Python#librosa#torchaudio#AudioProcessing#SignalProcessing#Audio,Python

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.

함께 보면 좋은 카드 뉴스

Audio Processing Pipeline 완벽 가이드 | CodeDeck | CodeDeck