# Audio-Course

## Docs

- [라이브 세션과 워크샵[[live-sessions-and-workshops]]](https://huggingface.co/learn/audio-course/ko/events/introduction.md)
- [오디오 데이터에 대하여[[introduction-to-audio-data]]](https://huggingface.co/learn/audio-course/ko/chapter1/audio_data.md)
- [오디오 데이터셋 불러오기 및 탐색하기[[load-and-explore-an-audio-dataset]]](https://huggingface.co/learn/audio-course/ko/chapter1/load_and_explore.md)
- [더 알아보기[[learn-more]]](https://huggingface.co/learn/audio-course/ko/chapter1/supplemental_reading.md)
- [오디오 데이터 스트리밍하기[[streaming-audio-data]]](https://huggingface.co/learn/audio-course/ko/chapter1/streaming.md)
- [코스에 대한 이해도를 체크해보세요[[check-your-understanding-of-the-course-material]]](https://huggingface.co/learn/audio-course/ko/chapter1/quiz.md)
- [오디오 데이터셋 전처리하기[[preprocessing-an-audio-dataset]]](https://huggingface.co/learn/audio-course/ko/chapter1/preprocessing.md)
- [1단원. 오디오 데이터 다루기[[unit-1-working-with-audio-data]]](https://huggingface.co/learn/audio-course/ko/chapter1/introduction.md)
- [파이프라인을 이용한 오디오 분류[[audio-classification-with-a-pipeline]]](https://huggingface.co/learn/audio-course/ko/chapter2/audio_classification_pipeline.md)
- [파이프라인을 이용한 자동 음성 인식[[automatic-speech-recognition-with-a-pipeline]]](https://huggingface.co/learn/audio-course/ko/chapter2/asr_pipeline.md)
- [실습 과제[[hands-on-exercise]]](https://huggingface.co/learn/audio-course/ko/chapter2/hands_on.md)
- [2단원. 오디오의 응용에 대한 소개[[unit-2-a-gentle-introduction-to-audio-applications]]](https://huggingface.co/learn/audio-course/ko/chapter2/introduction.md)
- [Seq2Seq 아키텍처[[seq2seq-architectures]]](https://huggingface.co/learn/audio-course/ko/chapter3/seq2seq.md)
- [추가 자료 및 리소스[[supplemental-reading-and-resources]]](https://huggingface.co/learn/audio-course/ko/chapter3/supplemental_reading.md)
- [이번 코스에 대한 이해도를 확인해보세요[[check-your-understanding-of-the-course-material]]](https://huggingface.co/learn/audio-course/ko/chapter3/quiz.md)
- [3단원. 오디오를 위한 트랜스포머 아키텍처[[unit-3-transformer-architectures-for-audio]]](https://huggingface.co/learn/audio-course/ko/chapter3/introduction.md)
- [오디오 분류 아키텍처[[audio-classification-architectures]]](https://huggingface.co/learn/audio-course/ko/chapter3/classification.md)
- [CTC 아키텍처 [[ctc-architectures]]](https://huggingface.co/learn/audio-course/ko/chapter3/ctc.md)
- [허깅페이스 오디오 코스에 오신것을 환영합니다![[welcome-to-the-hugging-face-audio-course]]](https://huggingface.co/learn/audio-course/ko/chapter0/introduction.md)
- [커뮤니티에 참여해보세요![[join-the-community]]](https://huggingface.co/learn/audio-course/ko/chapter0/community.md)
- [코스 준비하기[[get-ready-to-take-the-course]]](https://huggingface.co/learn/audio-course/ko/chapter0/get_ready.md)

### 라이브 세션과 워크샵[[live-sessions-and-workshops]]
https://huggingface.co/learn/audio-course/ko/events/introduction.md

# 라이브 세션과 워크샵[[live-sessions-and-workshops]]

새 오디오 트랜스포머 코스: Paige Bailey(DeepMind), 김석환(Amazon Alexa AI), Brian McFee(Librosa)가 함께하는 라이브 런칭 이벤트

### 오디오 데이터에 대하여[[introduction-to-audio-data]]
https://huggingface.co/learn/audio-course/ko/chapter1/audio_data.md

# 오디오 데이터에 대하여[[introduction-to-audio-data]]

본질적으로 음파(sound wave)는 연속적인 신호입니다. 이는 어떤 주어진 시간에 대해 무한개의 신호 값을 가진다는 뜻입니다.
그런데 디지털 기기들은 유한개의 값들을 요구하기에 문제가 됩니다. 이런 디지털 기기에서의 처리, 저장, 전송을 위해 연속적인 음파들은 일련의 이산적인(discrete) 값, 즉 디지털 표현(digital representation)으로 변환되어야 합니다.

어떤 오디오 데이터셋에서건 텍스트 나레이션이나 음악같은 디지털 음향 파일들을 볼 수 있습니다. 이는 `.wav` (Waveform Audio File), `.flac` (Free Lossless Audio Codec), 그리고 `.mp3` (MPEG-1 Audio Layer 3)같이 다양한 포맷으로 접할 수 있습니다. 이 포맷들은 주로 오디오 신호의 디지털 표현을 압축하는 방식에서 차이가 있습니다.

연속적인 신호로부터 이러한 표현을 얻는 방법에 대해 알아봅시다. 아날로그 신호는 먼저 마이크에 의해 포착되어 음파에서 전기 신호로 변환됩니다. 이 전기 신호는 아날로그-디지털 컨버터(Analog-to-Dogital Converter)를 거치며 샘플링(sampling)을 통해 디지털 표현으로 디지털화됩니다.

## 샘플링과 샘플링 속도(sampling rate)[[sampling-and-sampling-rate]]

샘플링이란 연속적인 신호를 고정된 시간 간격으로 측정하는 과정입니다. 샘플링된 파형(waveform)은 균일한 간격으로 유한개의 신호 값을 가지므로 이산적입니다.

    

*Illustration from Wikipedia article: [Sampling (signal processing)](https://en.wikipedia.org/wiki/Sampling_(signal_processing))*

**샘플링 속도** (샘플링 주파수(sampling frequency)라고도 합니다)는 1초동안 수집된 샘플의 수로, 헤르츠(Hz)단위로 측정됩니다. 예를 들어 CD 품질의 오디오는 44,100 Hz의 샘플링 속도를 가지며 이는 초당 44,100번의 샘플이 수집된다는 뜻입니다. 고해상도 오디오는 192,000 Hz(혹은 192 kHz)의 샘플링 속도를 가집니다. 음성 모델 학습에 주로 쓰이는 샘플링 속도는 16,000 Hz(혹은 16 kHz)입니다.

샘플링 속도의 선택은 신호에서 얼마나 큰 주파수까지 캡처할 수 있는지를 결정하는데 큰 역할을 합니다. 신호에서 캡처가능한 최고 주파수의 한계는 샘플링 속도의 정확히 절반이며 이를 나이퀴스트 한계(Nyquist limit)라고 합니다. 예를 들면 사람의 음성에서 들을 수 있는 주파수는 8 kHz 미만이므로 16 kHz로 음성을 샘플링한다면 충분할 것입니다. 더 높은 샘플링 속도를 사용하여도 얻을 수 있는 추가 정보는 없을것이며 오히려 파일 처리에 대한 계산 비용만 증가시키게 됩니다. 반면, 너무 낮은 샘플링 속도는 정보의 손실로 이어집니다. 8 kHz로 샘플링된 음성은 높은 주파수들을 캡처할 수 없기때문에 흐릿하게 들릴것입니다.

오디오 작업을 할 때는 데이터셋에 있는 모든 오디오 예제가 동일한 샘플링 속도를 가지고 있는지 확인하는것이 중요합니다.
여러분의 커스텀 데이터로 사전 학습된 모델을 파인튜닝할 계획이라면 모델이 사전 학습된 데이터의 샘플링 속도와 여러분의 데이터의 샘플링 속도가 일치해야 합니다. 샘플링 속도는 샘플간의 시간 간격을 결정하며 오디오 데이터의 시간 해상도(time interval)에 영향을 주기 때문입니다. 예를 들어, 16,000 Hz의 샘플링 속도를 가진 5초 길이의 소리는 80,000개의 값으로 표현되지만, 동일한 5초 길이의 소리여도 8,000 Hz의 샘플링 속도를 가진다면 40,000개의 값으로 표현됩니다.
오디오 작업을 처리하는 트랜스포머 모델은 시퀀스를 취급하며 어텐션 메커니즘을 이용해 오디오 또는 멀티모달 표현을 학습합니다. 서로 다른 샘플링 속도를 갖는 오디오 데이터는 다른 시퀀스가 되므로 모델이 샘플링 속도간 일반화를 하기 어렵습니다.
**리샘플링**은 이런 서로 다른 샘플링 속도를 일치시켜주는 작업으로, 오디오 데이터 [전처리](preprocessing#resampling-the-audio-data) 과정 중 하나입니다.

## 진폭(amplitude)과 비트뎁스(bit depth)[[amplitude-and-bit-depth]]

샘플링 속도는 샘플을 얼마나 자주 뽑는지 알려줍니다. 그런데 이 샘플의 값은 정확히 어떤걸 뜻할까요?

소리는 사람이 들을 수 있는 주파수에서 기압의 변화로 만들어집니다. 소리의 **진폭**이란 특정 순간의 소리의 압력 수준을 나타내며 데시벨(dB)로 측정됩니다. 즉, 진폭은 소리의 세기를 뜻합니다.
예를 들어, 일반적인 말소리는 60 dB 미만입니다. 락 콘서트 같은 경우 약 125 dB로 사람의 청각적 한계를 뛰어넘을 수 있습니다.

디지털 오디오에서, 각 오디오 샘플은 특정 시점의 오디오 파동의 진폭을 기록합니다. 샘플의 **비트뎁스**는 이 진폭 값을 얼마나 정밀하게 기록할지를 정합니다. 비트뎁스가 높을수록 디지털 표현이 원래의 연속 음파에 더 가까워 집니다.

가장 일반적인 오디오 비트뎁스는 16비트와 24비트입니다. 이는 이진 용어(binary term)로, 진폭값을 연속값에서 이산값으로 변환할때 양자화(quantized)할 수 있는 수를 나타냅니다. 16비트 오디오의 경우 65,356개, 24비트 오디오의 경우 16,777,216개에 달합니다. 양자화는 연속값을 이산값으로 바꾸는 과정에서 반올림이 일어나므로 샘플링 과정은 노이즈가 발생합니다. 비트뎁스가 높을수록, 이런 양자화 노이즈는 작아집니다.
실무적으론 16비트 정도만 돼도 양자화 노이즈가 이미 들리지 않을 정도로 작아 이를 위해 굳이 더 높은 비트뎁스를 사용할 필요는 없습니다.

여러분은 32비트 오디오를 접할 수도 있습니다. 이는 값을 소수로 저장하기 위함으로, 16비트나 24비트 오디오는 값을 정수로 저장하는 반면 32비트는 샘플을 부동소수점 값으로 저장합니다. 32비트 부동 소수점 값의 정밀도는 24비트이므로 24비트 오디오와 같은 비트뎁스를 가지게 됩니다.
부동 소수점 오디오 샘플은 [-1.0, 1.0] 범위의 값을 가집니다. 머신 러닝 모델은 기본적으로 부동 소수점 데이터에서 작동하므로 학습 전 먼저 오디오를 부동 소수점 형식으로 변환해야 합니다. 이는 다음 [전처리](preprocessing) 섹션에서 살펴보겠습니다.

연속적인 오디오 신호와 마찬가지로 디지털 오디오의 진폭 역시 일반적으로 데시벨(dB)로 표시됩니다. 인간의 청각은 기본적으로 로그함수를 따르므로(우리 귀는 큰 소리보다 조용한 소리의 작은 변동에 더 민감합니다) 진폭이 데시벨(마찬가지로 로그함수를 따릅니다)로 표시되면 소리의 크기를 해석하기 쉽습니다.
실생활에서 쓰이는 오디오 데시벨 단위는 사람이 들을 수 있는 가장 조용한 소리인 0 dB에서 시작하여 소리가 커질수록 값도 커집니다. 그러나 디지털 오디오 신호의 경우, 0 dB이 가장 큰 진폭이며 다른 모든 진폭은 음수값을 가집니다(디지털에서의 데시벨 단위는 dBFS, 실생활에서 주로 쓰이는 데시벨은 dBSPL로 서로 다릅니다). 간단한 규칙으로 -6 dB마다 진폭이 절반으로 줄어들고 -60 dB 미만은 일반적으로 볼륨을 크게 높이지 않는 한 들을 수 없다고 보시면 됩니다.

## 파형(waveform)으로써의 오디오[[audio-as-a-waveform]]

여러분은 아마 소리가 **파형**으로 시각화된것을 본 적이 있으실 겁니다. 이는 시간에 따른 샘플 값들을 그래프로 표현하여 소리의 진폭 변화를 보여줍니다. 이를 소리의 *시간 영역(time domain)* 표현이라고도 합니다.

이러한 유형의 사각화는 특정 사운드 이벤트가 언제 발생했는지, 전체적인 음량은 어떤지, 오디오에 어떤 노이즈나 불규칙성이 있는지 등 오디오 신호의 특징을 식별하는데 유용합니다.

오디오 신호의 파형을 그리기 위해 파이썬 라이브러리 `librosa`를 이용할 수 있습니다:

```bash
pip install librosa
```

라이브러리에서 제공하는 "트럼펫" 소리를 예로 들어 보겠습니다:

```py
import librosa

array, sampling_rate = librosa.load(librosa.ex("trumpet"))
```

이 예제는 오디오 시계열(`array`)과 샘플링 속도(`sampling_rate`) 튜플을 불러옵니다.
이 사운드의 파형을 `librosa`의 `waveshow()` 함수를 통해 살펴보겠습니다:

```py
import matplotlib.pyplot as plt
import librosa.display

plt.figure().set_figwidth(12)
librosa.display.waveshow(array, sr=sampling_rate)
```

    

이 그래프의 X축은 시간을, Y축은 진폭을 나타냅니다. 각 점은 이 소리를 샘플링할때 취한 값에 해당합니다. `librosa`가 이미 오디오를 부동소수점 값으로 변환했으며 진폭값이 [-1.0, 1.0] 범위내에 있다는 점을 유의하세요.

이런 시각화는 오디오를 듣는것과 더불어 작업할 데이터를 이해하는데 유용한 도구가 될 수 있습니다.
이를 통해 신호의 모양, 패턴 관찰, 노이즈나 왜곡을 발견할 수 있습니다. 만약 정규화(normalization), 리샘플링, 필터링 등의 방법을 통해 데이터 전처리를 했다면, 이런 전처리가 제대로 되었는지 시각적으로 확인할 수도 있습니다.
또한 모델의 학습이 완료된 후에 어디서 오류가 발생했는지 디버깅하기위해 샘플을 시각화할 수도 있습니다(예를 들어, 오디오 분류 작업 문제 등에서).

## 주파수 스펙트럼(frequency spectrum)[[the-frequency-spectrum]]

오디오 데이터를 시각화하는 또 다른 방법은 오디오 신호의 **주파수 스펙트럼**을 그리는 것입니다. 이는 *주파수 영역(frequency domain)* 표현이라고도 합니다. 
스펙트럼은 이산 푸리에 변환(DFT)을 사용하여 계산할 수 있습니다. 이를 통해 신호를 구성하고 있는 각각의 주파수들과 그 세기를 알 수 있습니다.

`numpy`의 `rfft()` 함수를 쓰면 DFT를 계산할 수 있습니다. 이를 아까의 트럼펫 소리에 적용시켜 주파수 스펙트럼을 그려봅시다. 전체 소리의 스펙트럼을 그릴 수도 있지만, 그보다는 작은 영역에 집중하는것이 더 낫습니다. 여기서는 첫 4096개의 샘플에 적용시켜보겠습니다. 이는 대략적으로 연주의 첫 음표의 길이에 해당합니다:

```py
import numpy as np

dft_input = array[:4096]

# calculate the DFT
window = np.hanning(len(dft_input))
windowed_input = dft_input * window
dft = np.fft.rfft(windowed_input)

# get the amplitude spectrum in decibels
amplitude = np.abs(dft)
amplitude_db = librosa.amplitude_to_db(amplitude, ref=np.max)

# get the frequency bins
frequency = librosa.fft_frequencies(sr=sampling_rate, n_fft=len(dft_input))

plt.figure().set_figwidth(12)
plt.plot(frequency, amplitude_db)
plt.xlabel("Frequency (Hz)")
plt.ylabel("Amplitude (dB)")
plt.xscale("log")
```

    

이 그래프는 이 오디오 구간에 존재하는 다양한 주파수의 세기를 보여줍니다. 보통 X축에 로그스케일로 주파수를, Y축엔 진폭을 표시합니다.

이 주파수 스펙트럼 그래프는 여러개의 피크를 보여주는데, 이 피크들은 연주중인 음표의 고조파(harmonic)에 해당하며 더 높은 고조파는 더 작은 소리를 나타냅니다. 첫번째 피크가 약 620 Hz에 있으므로 이 스펙트럼은 E♭ 음표의 주파수 스펙트럼인것을 알 수 있습니다.

DFT의 결과값은 복소수 배열입니다. `np.abs(dft)`로 그 크기를 구하면 스펙트로그램의 진폭 정보를 알 수 있습니다. 실수부와 허수부 사이의 각도는 위상 스펙트럼(phase spectrum)을 나타내지만, 머신러닝에선 쓰이지 않는 경우가 종종 있습니다.

`librosa.amplitude_to_db()`는 진폭값을 데시벨 스케일로 변환합니다. 이로 인해 스펙트럼의 더욱 세밀한 부분까지 쉽게 확인이 가능합니다. 때때로는 **파워 스펙트럼(power spectrum)**을 쓸 때도 있습니다. 진폭보다 에너지를 측정하기 위해 쓰는데, 이는 단지 진폭에 제곱을 취한 값으로 나타낸 스펙트럼입니다.

💡 실무에서 사람들이 고속 푸리에 변환(FFT)이라는 용어와 DFT를 혼용해서 쓰는 경우를 볼 수 있을겁니다. 이는 DFT를 계산하는 유일한 효율적인 방법이 FFT를 사용하는것이기 때문입니다.

오디오 신호의 파형과 주파수 스펙트럼은 동일한 정보를 지닙니다. 단지 같은 데이터(여기서는 트럼펫 소리의 첫 4096개의 샘플)를 바라보는 두 가지 방법일 뿐입니다. 파형은 시간에 따른 오디오 신호의 진폭을 표시하며, 스펙트럼은 고정된 시점의 개별 주파수들의 진폭을 시각화합니다.

## 스펙트로그램(spectrogram)[[spectrogram]]

오디오 신호에서 주파수가 어떻게 변화하는지 보려면 무엇을 해야 할까요? 트럼펫 소리는 여러 음으로 구성돼있어서 여러 다른 주파수들로 이뤄져있습니다. 스펙트럼의 문제는 주어진 한 순간만의 주파수들을 보여준다는 것입니다.
이에 대한 해결법은 시간을 작은 구간들로 나누어 DFT를 적용하고, 그 결과인 스펙트럼들을 쌓아 **스펙트로그램**을 만드는 것입니다.

스펙트로그램은 오디오 신호의 주파수를 시간에 따라 변화하는 형태로 그립니다. 이를 통해 시간, 주파수, 진폭을 그래프에서 한눈에 볼 수 있습니다. 이 계산을 수행하는 알고리즘을 STFT(Short Time Fourier Transform)라 합니다.

스펙트로그램은 오디오를 다루는데 가장 유용한 툴 중 하나입니다. 예를 들어, 음악 녹음 작업을 다룰 때 다양한 악기와 보컬 트랙이 어떻게 전체 사운드에 기여하는지 볼 수 있습니다. 음성 작업의 경우, 모음을 발음할 때 각각의 모음들은 고유 주파수가 있기 때문에 서로 다른 모음인것을 식별할 수 있습니다. 

`librosa`의 `stft()`와 `specshow()` 함수를 이용해 트럼펫 소리의 스펙트로그램을 그려보겠습니다:

```py
import numpy as np

D = librosa.stft(array)
S_db = librosa.amplitude_to_db(np.abs(D), ref=np.max)

plt.figure().set_figwidth(12)
librosa.display.specshow(S_db, x_axis="time", y_axis="hz")
plt.colorbar()
```

    

이 그래프에서 X축은 (파형 그래프처럼)시간을 나타내며 Y축은 주파수를 Hz 단위로 나타냅니다. 
색상의 강도는 각 시점의 주파수 성분의 진폭 또는 파워를 데시벨(dB)로 측정하여 나타냅니다.

스펙트로그램은 일반적으로 오디오 신호의 몇 밀리초 정도 되는 짧은 구간에 DFT를 적용하여 주파수 스펙트럼들을 얻어 만들어집니다. 이 스펙트럼들을 시간축으로 쌓은것이 스펙트로그램이기 때문입니다.
이 이미지에서 각각의 수직 조각들은 (아까 위에서 본)주파수 스펙트럼에 해당합니다. 기본적으로, `librosa.stft()`는 오디오 신호를 2048개의 샘플로 나눕니다. 주파수 해상도(frequency resolution)와 시간 해상도(time resolution) 사이의 적절한 절충(trade-off)이기 때문입니다.

스펙트로그램과 파형은 같은 데이터를 다른 방식으로 볼 뿐이므로, 스펙트로그램을 다시 원래의 파형으로 돌리는 역 STFT(inverse STFT)가 가능합니다. 그러나, 이를 위해선 진폭 정보뿐만 아니라 위상(phase) 정보 또한 필요한데, 스펙트로그램이 머신러닝 툴에 의해 생성됐다면 대부분 단순히 진폭만 출력하게 됩니다.
이런 경우, 위상 재구성 알고리즘(phase reconstruction algorithm)인 vocoder라는 신경망이나 고전적인 Griffin-Lim 알고리즘을 사용하여 스펙트로그램에서 파형을 재구성할 수 있습니다.

스펙트로그램은 단순히 시각화를 위해서만 사용되는게 아닙니다. 많은 머신러닝 모델들은 (파형과는 다르게)스펙트로그램 그 자체를 입력으로 받고 출력 또한 스펙트로그램으로 내는 경우도 있습니다.

이제 스펙트로그램이 무엇이고 어떻게 만들어지는지 알았으니, 음성 작업에 사용되는 이 스펙트로그램의 변형에 대해 알아봅시다: 멜 스펙트로그램(mel spectrogram)입니다.

## 멜 스펙트로그램[[mel-spectrogram]]

멜 스펙트로그램은 스펙트로그램의 한 종류로 음성 작업이나 머신러닝 작업에 주로 쓰입니다.
오디오 신호를 시간에 따른 주파수로 보여준다는 점에서 스펙트로그램과 비슷하지만, 다른 주파수 축을 사용합니다.

표준적인 스펙트로그램에선 주파수 축이 선형(linear)이며 헤르츠(Hz)단위로 측정됩니다. 그러나, 사람의 청각 시스템은 고주파보다 저주파에 더 민감하며, 이 민감성은 주파수가 증가함에 따라 로그함수적으로 감소합니다. 멜 스케일(mel scale)은 이런 사람의 비선형 주파수 반응을 근사한(approximate) 지각 스케일(perceptual scale)입니다.

멜 스펙트로그램을 만드려면 전처럼 STFT를 사용하고 오디오를 여러 짧은 구간으로 나눠 일련의 주파수 스펙트럼들을 얻어야 합니다. 그 후 추가적으로, 각 스펙트럼에 mel filterbank라고 불리는 필터들을 적용시켜 주파수를 멜 스케일로 변환합니다. 

이 모든 단계를 대신 해주는 `librosa`의 `melspectrogram()` 함수를 이용하여 멜 스펙트로그램을 그려봅시다:

```py
S = librosa.feature.melspectrogram(y=array, sr=sampling_rate, n_mels=128, fmax=8000)
S_dB = librosa.power_to_db(S, ref=np.max)

plt.figure().set_figwidth(12)
librosa.display.specshow(S_dB, x_axis="time", y_axis="mel", sr=sampling_rate, fmax=8000)
plt.colorbar()
```

    

위의 예에서, `n_mels`는 mel band의 수를 정합니다. mel band는 필터를 이용해 스펙트럼을 지각적으로 의미있는 요소로 나누는 주파수 범위의 집합을 정의합니다. 이 필터들의 모양(shape)과 간격(spacing)은 사람의 귀가 다양한 주파수에 반응하는 방식을 모방하도록 선택됩니다. 흔히 `n_mels`의 값으로 40 또는 80이 선택됩니다. `fmax`는 우리가 관심을 가지는 최고 주파수(Hz 단위)를 나타냅니다.

일반적인 스펙트로그램과 마찬가지로 멜 스펙트로그램의 주파수 성분 역시 세기를 데시벨로 표현하는 것이 일반적입니다. 데시벨로의 변환이 로그 연산을 포함하기 때문에 이를 흔히 **로그-멜 스펙트로그램(log-mel spectrogram)**이라 합니다. 위 예제에선 `librosa.power_to_db()`를 썻는데, 이는 `librosa.feature.melspectrogram()`는 파워 스펙트로그램(power spectrogram)을 만들기 때문입니다.

💡 모든 멜 스펙트로그램이 같은 것은 아닙니다! 일반적으로 사용되는 멜 스케일에는 두가지가 있으며("htk"와 "slaney"), 파워 스펙트로그램 대신 진폭 스펙트로그램(amplitude spectrogram)이 사용될 수도 있습니다. 로그-멜 스펙트로그램으로의 변환은 항상 실제 데시벨을 계산하는 것이 아니며 단순히 로그를 취할 수도 있습니다. 따라서, 머신러닝 모델이 멜 스펙트로그램을 입력으로 받는다면, 같은 방식으로 계산하고 있는지 다시 한번 확인하시길 바랍니다.

멜 스펙트로그램은 신호를 필터링하여 만들기 때문에 정보의 손실이 일어납니다. 따라서 멜 스펙트로그램을 다시 원래의 파형으로 바꾸는 것은 일반적인 스펙트로그램을 다시 되돌리는것보다 힘든 일입니다. 버려진 주파수를 어떻게든 추정해야 하기 때문이죠. 멜 스펙트로그램을 다시 원래의 파형으로 되돌리기 위해 HiFiGAN vocoder같은 머신러닝 모델이 필요한 이유이기도 합니다.

기본적인 스펙트럼과 비교하여, 멜 스펙트로그램은 인간의 지각에 더 의미 있는 오디오 신호의 특성을 포착할 수 있어 음성 인식, 화자 식별, 음악 장르 분류 같은 작업에서 널리 사용됩니다.

이제 오디오 데이터의 시각화 방법을 알았으니 여러분이 좋아하는 소리가 어떻게 보이는지 한번 확인해보세요. :)

### 오디오 데이터셋 불러오기 및 탐색하기[[load-and-explore-an-audio-dataset]]
https://huggingface.co/learn/audio-course/ko/chapter1/load_and_explore.md

# 오디오 데이터셋 불러오기 및 탐색하기[[load-and-explore-an-audio-dataset]]

이 코스에서 우리는 🤗 Datasets 라이브러리를 사용하여 오디오 데이터셋을 다룹니다.🤗 Datasets는 오디오를 포함한 모든 양식의 데이터셋을 다운로드하고 준비할 수 있는 오픈소스 라이브러리입니다.
이 라이브러리는 허깅페이스 허브에서 공개적으로 사용 가능한 머신러닝 데이터셋에 쉽게 접근할 수 있도록 도와줍니다. 무엇보다도, 🤗 Datasets는 연구자와 실무자 모두가 오디오 데이터셋을 쉽게 다룰 수 있도록 만드는 특화 기능들을 여럿 가지고 있습니다.

시작에 앞서, 🤗 Datasets 라이브러리가 설치돼있는지 확인해주세요:

```bash
pip install datasets[audio]
```

🤗 Datasets의 주된 기능 중 하나는 `load_dataset()` 파이썬 코드 한줄로 데이터셋을 다운로드하고 준비할 수 있다는것입니다.

[MINDS-14](https://huggingface.co/datasets/PolyAI/minds14)라고 하는 오디오 데이터셋을 불러와 다뤄봅시다. 이 데이터셋은 여러 언어와 방언으로 사람들이 인터넷뱅킹에 대해 묻는 내용이 녹음돼있습니다.

MINDS-14 데이터셋을 불러오기 위해 허브에서의 데이터셋 식별자인 (`PolyAI/minds14`)를 `load_dataset` 함수로 넘겨줘야 합니다. 또한 데이터셋의 호주 부분(`en-AU`)에만 관심이 있고 학습용 데이터에만 관심이 있음을 명시하겠습니다.:

```py
from datasets import load_dataset

minds = load_dataset("PolyAI/minds14", name="en-AU", split="train")
minds
```

**Output:**
```out
Dataset(
    {
        features: [
            "path",
            "audio",
            "transcription",
            "english_transcription",
            "intent_class",
            "lang_id",
        ],
        num_rows: 654,
    }
)
```

데이터셋은 654개의 오디오 파일로 이뤄져있습니다. 각각의 파일들은 자막, 영어 번역, 그리고 질문자의 의도를 나타내는 레이블(label)이 함께 제공됩니다. 오디오 컬럼(column)에는 원시(raw) 오디오 데이터가 포함되어 있습니다. 예제를 하나 살펴보겠습니다:

```py
example = minds[0]
example
```

**Output:**
```out
{
    "path": "/root/.cache/huggingface/datasets/downloads/extracted/f14948e0e84be638dd7943ac36518a4cf3324e8b7aa331c5ab11541518e9368c/en-AU~PAY_BILL/response_4.wav",
    "audio": {
        "path": "/root/.cache/huggingface/datasets/downloads/extracted/f14948e0e84be638dd7943ac36518a4cf3324e8b7aa331c5ab11541518e9368c/en-AU~PAY_BILL/response_4.wav",
        "array": array(
            [0.0, 0.00024414, -0.00024414, ..., -0.00024414, 0.00024414, 0.0012207],
            dtype=float32,
        ),
        "sampling_rate": 8000,
    },
    "transcription": "I would like to pay my electricity bill using my card can you please assist",
    "english_transcription": "I would like to pay my electricity bill using my card can you please assist",
    "intent_class": 13,
    "lang_id": 2,
}
```

오디오 컬럼에 여러 feature가 있음을 알 수 있습니다. 각각은 다음과 같습니다: 
* `path`: 오디오 파일의 경로(이 예제의 경우 `*.wav`).
* `array`: 1차원 넘파이 배열로 디코딩된 오디오 데이터.
* `sampling_rate`: 오디오 파일의 샘플링 속도(이 예제의 경우 8,000 Hz).

`intent_class`는 오디오 녹음이 어떤 카테고리로 분류되는지 나타냅니다. 이 숫자를 의미있는 문자열로 바꾸려면 `int2str()` 메소드를 사용하세요:

```py
id2label = minds.features["intent_class"].int2str
id2label(example["intent_class"])
```

**Output:**
```out
"pay_bill"
```

`transcription` feature를 보면 누군가가 청구서를 지불하는 것에 대해 질문하는 녹음의 오디오 파일이란것을 알 수 있습니다.

이 데이터의 부분집합에 대해 오디오 분류기(classifier)를 학습시킬 계획이시라면, 이 모든 feature가 필요하진 않을지도 모릅니다. 예를 들어, `lang_id`는 모든 예제에서 같은 값을 지니기 때문에 그다지 쓸모 있지 않을겁니다.  `english_transcription`는 이 호주데이터에선 대부분이 `transcription`과 같을테니 삭제해도 좋을겁니다.

이런 관계없는 feature는 🤗 Datasets의 `remove_columns` 메소드를 사용하면 쉽게 제거할 수 있습니다:

```py
columns_to_remove = ["lang_id", "english_transcription"]
minds = minds.remove_columns(columns_to_remove)
minds
```

**Output:**
```out
Dataset({features: ["path", "audio", "transcription", "intent_class"], num_rows: 654})
```

이제 데이터셋의 원시 컨텐츠들을 불러오고 살펴봤으니, 몇개를 들어봅시다!
`Gradio`의 `Blocks`와 `Audio` 기능을 써서 데이터셋의 샘플 몇개를 무작위로 디코딩해보겠습니다:

```py
import gradio as gr

def generate_audio():
    example = minds.shuffle()[0]
    audio = example["audio"]
    return (
        audio["sampling_rate"],
        audio["array"],
    ), id2label(example["intent_class"])

with gr.Blocks() as demo:
    with gr.Column():
        for _ in range(4):
            audio, label = generate_audio()
            output = gr.Audio(audio, label=label)

demo.launch(debug=True)
```

원하신다면, 예제 몇개를 시각화해보는 것도 좋습니다. 첫번째 예제의 파형을 그려보겠습니다.

```py
import librosa
import matplotlib.pyplot as plt
import librosa.display

array = example["audio"]["array"]
sampling_rate = example["audio"]["sampling_rate"]

plt.figure().set_figwidth(12)
librosa.display.waveshow(array, sr=sampling_rate)
```

    

한번 해보세요! MINDS-14 데이터셋의 다른 언어나 방언을 다운로드하여 듣고 시각화를 해보세요. 전체 데이터셋이 어떨지 대략적인 감을 줄겁니다. [여기](https://huggingface.co/datasets/PolyAI/minds14)서 가능한 언어들이 무엇인지 확인하실 수 있습니다.

### 더 알아보기[[learn-more]]
https://huggingface.co/learn/audio-course/ko/chapter1/supplemental_reading.md

# 더 알아보기[[learn-more]]

이 단원에서는 오디오 데이터와 이를 다루는 데 관련된 많은 기본 개념들을 다루었습니다.
더 알고 싶으신가요? 여기에서 주제에 대한 더 깊은 이해를 돕고 학습 경험을 향상시킬 수 있는 추가 자료들을 찾아보실 수 있습니다.

아래 비디오에서는 xiph.org의 Monty Montgomery가 현대 디지털 분석 장비와 오래된 아날로그 벤치 장비를 이용해 실제 오디오 장비에서의 샘플링, 양자화, 비트뎁스, 디더(dither)를 실시간 시연으로 보여줍니다. 확인해보세요:

디지털 신호 처리에 대해 더 깊게 다뤄보고 싶으시다면 `librosa` 패키지의 주요 메인테이너이자 Assistant Professor of Music Technology and Data Science at New York University인 Brian McFee가 저술한 무료 책 ["Digital Signals Theory"](https://brianmcfee.net/dstbook-site/content/intro.html)를 확인해보세요.

### 오디오 데이터 스트리밍하기[[streaming-audio-data]]
https://huggingface.co/learn/audio-course/ko/chapter1/streaming.md

#  오디오 데이터 스트리밍하기[[streaming-audio-data]]

오디오 데이터셋을 다룰 때 마주치는 가장 큰 문제 중 하나는 바로 그 크기입니다. 1분짜리 압축되지 않은 CD 품질의 오디오(44.1kHz, 16-bit)는 5MB를 조금 넘습니다. 보통 오디오 데이터셋은 몇시간 분량의 녹음을 가지고 있습니다.

이전 섹션에서 우린 MINDS-14 오디오 데이터셋의 아주 작은 부분만을 다뤘습니다. 그러나, 보통의 오디오 데이터셋은 훨씬 큽니다.
예를 들어, [GigaSpeech from SpeechColab](https://huggingface.co/datasets/speechcolab/gigaspeech)의 `xs`(최소) 설정은 10시간의 훈련 데이터만 포함하지만 다운로드와 준비에 13GB의 저장공간이 필요합니다. 더 큰 분할(split)의 경우는 어떨까요? 이 데이터셋의 `xl`(최대) 설정은 10,000 시간의 훈련 데이터를 가지고 있고 이는 1TB의 저장 공간을 차지합니다. 우리 대부분은 이 정도 크기의 하드 디스크 용량을 가지고 있지 않을겁니다. 추가로 저장장치를 구매해야 할까요? 아니면 이런 저장 공간의 제약이 없이 학습할 수 있는 방법이 있을까요?

 🤗 Datasets은 스트리밍 모드를 제공하여 이 문제를 해결합니다. 스트리밍은 데이터셋을 차례로 접근할 때 점진적으로 불러올 수 있도록 해줍니다. 모든 데이터셋을 한번에 다운로드하기보단, 데이터셋을 하나씩 불러오는 것입니다.
 데이터셋을 순회하며 데이터가 필요할 때마다 즉석에서 준비하고 불러옵니다. 이런 방식으로 우린 현재 필요가 없는 데이터가 아닌 당장 필요로 하는 데이터만을 불러올 수 있습니다!
한 샘플이 끝나면 데이터셋에서 다음 데이터를 불러오면 됩니다.

스트리밍 모드는 전체 데이터셋을 한번에 다운로드하는 것에 비해 세가지 특장점이 있습니다:

* 디스크 공간: 데이터는 데이터셋을 순회하며 메모리에 하나씩 불러와집니다. 데이터를 로컬에 다운로드하지 않으므로 저장 공간의 제약없이 임의의 크기의 데이터셋을 다룰 수 있습니다.
* 다운로드시간과 처리 시간: 오디오 데이터셋은 그 크기가 크기때문에 다운로드하고 처리하는데 많은 시간이 소요됩니다. 스트리밍의 경우, 처리와 불러오는것이 즉석에서 이뤄지기 때문에 데이터가 준비되는대로 시작할 수 있습니다.
* 실험의 간편함: 전체 데이터셋을 다운로드받을 필요 없이 몇개의 데이터에 대해 여러분의 스크립트가 잘 작동하는지 실험하기 쉽습니다.

스트리밍 모드에는 한가지 주의사항이 있습니다. 스트리밍이 아닌 전체 데이터셋을 다운로드하는 경우, 원시 데이터와 가공된 데이터(processed data) 모두 로컬 디스크에 저장됩니다. 따라서 추후에 재사용하고 싶다면 다운로드와 처리 단계를 다시 거칠 필요 없이 바로 가공된 데이터를 불러올 수 있습니다. 즉, 한번 다운로드와 처리과정을 거친다면 후에는 준비된 데이터를 다시 사용할 수 있습니다.

스트리밍 모드에서는 데이터가 디스크에 저장되지 않습니다. 따라서 다운로드 데이터와 가공 데이터는 캐시되지 않습니다. 만약 데이터셋을 재사용하길 원한다면 스트리밍 단계를 반복해야 합니다. 즉, 오디오 파일을 불러오고 처리하는 과정을 다시 거쳐야합니다. 이런 이유때문에, 여러번 사용할 데이터셋은 다운로드하는것이 좋습니다.

스트리밍 모드는 어떻게 활성화 시킬까요? 쉽습니다! 데이터셋을 불러올 때 `streaming=True`로 설정만 하면 됩니다. 나머지는 알아서 처리됩니다:

```py
gigaspeech = load_dataset("speechcolab/gigaspeech", "xs", streaming=True)
```

MINDS-14에 전처리 과정을 적용했던것처럼 스트리밍 데이터셋에도 똑같은 방식으로 전처리를 할 수 있습니다.

유일한 차이점은 더 이상 파이썬 인덱싱으로 데이터에 접근하지 못한다는 점입니다(즉, `gigaspeech["train"][sample_idx]`같은 접근은 불가합니다).
대신, 데이터셋을 순회하여 접근해야 합니다. 다음은 데이터셋을 스트리밍할때 어떻게 데이터에 접근하는지를 보여줍니다:

```py
next(iter(gigaspeech["train"]))
```

**Output:**
```out
{
    "segment_id": "YOU0000000315_S0000660",
    "speaker": "N/A",
    "text": "AS THEY'RE LEAVING  CAN KASH PULL ZAHRA ASIDE REALLY QUICKLY ",
    "audio": {
        "path": "xs_chunks_0000/YOU0000000315_S0000660.wav",
        "array": array(
            [0.0005188, 0.00085449, 0.00012207, ..., 0.00125122, 0.00076294, 0.00036621]
        ),
        "sampling_rate": 16000,
    },
    "begin_time": 2941.89,
    "end_time": 2945.07,
    "audio_id": "YOU0000000315",
    "title": "Return to Vasselheim | Critical Role: VOX MACHINA | Episode 43",
    "url": "https://www.youtube.com/watch?v=zr2n1fLVasU",
    "source": 2,
    "category": 24,
    "original_full_path": "audio/youtube/P0004/YOU0000000315.opus",
}
```

만약 큰 데이터셋에서 여러개의 데이터를 보고싶다면 `take()` 함수로 첫 `n`개의 원소를 가져올 수 있습니다. gigaspeech 데이터셋에서 처음 두개의 데이터를 가져와 보겠습니다:

```py
gigaspeech_head = gigaspeech["train"].take(2)
list(gigaspeech_head)
```

**Output:**
```out
[
    {
        "segment_id": "YOU0000000315_S0000660",
        "speaker": "N/A",
        "text": "AS THEY'RE LEAVING  CAN KASH PULL ZAHRA ASIDE REALLY QUICKLY ",
        "audio": {
            "path": "xs_chunks_0000/YOU0000000315_S0000660.wav",
            "array": array(
                [
                    0.0005188,
                    0.00085449,
                    0.00012207,
                    ...,
                    0.00125122,
                    0.00076294,
                    0.00036621,
                ]
            ),
            "sampling_rate": 16000,
        },
        "begin_time": 2941.89,
        "end_time": 2945.07,
        "audio_id": "YOU0000000315",
        "title": "Return to Vasselheim | Critical Role: VOX MACHINA | Episode 43",
        "url": "https://www.youtube.com/watch?v=zr2n1fLVasU",
        "source": 2,
        "category": 24,
        "original_full_path": "audio/youtube/P0004/YOU0000000315.opus",
    },
    {
        "segment_id": "AUD0000001043_S0000775",
        "speaker": "N/A",
        "text": "SIX TOMATOES ",
        "audio": {
            "path": "xs_chunks_0000/AUD0000001043_S0000775.wav",
            "array": array(
                [
                    1.43432617e-03,
                    1.37329102e-03,
                    1.31225586e-03,
                    ...,
                    -6.10351562e-05,
                    -1.22070312e-04,
                    -1.83105469e-04,
                ]
            ),
            "sampling_rate": 16000,
        },
        "begin_time": 3673.96,
        "end_time": 3675.26,
        "audio_id": "AUD0000001043",
        "title": "Asteroid of Fear",
        "url": "http//www.archive.org/download/asteroid_of_fear_1012_librivox/asteroid_of_fear_1012_librivox_64kb_mp3.zip",
        "source": 0,
        "category": 28,
        "original_full_path": "audio/audiobook/P0011/AUD0000001043.opus",
    },
]
```

스티리밍 모드는 여러분의 연구를 한 단계 높은 수준으로 이끌어줄 수 있습니다. 가장 큰 데이터셋에 접근가능할 뿐만 아니라 디스크 공간에 대한 걱정 없이 여러 데이터셋을 이용해 시스템을 한번에 쉽게 평가(evaluate)할 수 있기 때문입니다.
하나의 데이터셋을 평가하는 것과 비교하여 여러 데이터셋에 대한 평가는 음성 인식 시스템의 일반화(generalisation) 능력에 대해 더 나은 지표를 제공합니다(End-to-End Speech Benchmark(ESB)를 참고하세요).

### 코스에 대한 이해도를 체크해보세요[[check-your-understanding-of-the-course-material]]
https://huggingface.co/learn/audio-course/ko/chapter1/quiz.md

# 코스에 대한 이해도를 체크해보세요[[check-your-understanding-of-the-course-material]]

### 1. 샘플링 속도는 어떤 단위를 사용합니까?

### 2. 큰 오디오 데이터셋을 스트리밍한다면 어느 시점부터 이를 사용할 수 있습니까?

### 3. 스펙트로그램이란 무엇인가요?

### 4. 원시 오디오 데이터를 Whisper에 적합한 로그-멜 스펙트로그램으로 변환하는 가장 쉬운 방법은?

A.
```python
librosa.feature.melspectrogram(audio["array"])
```

B.
```python
feature_extractor = WhisperFeatureExtractor.from_pretrained("openai/whisper-small")
feature_extractor(audio["array"])
```

C.
```python
dataset.feature(audio["array"], model="whisper")
```

### 5. 🤗 허브에서 데이터셋을 불러오는 방법은?

A.
```python
from datasets import load_dataset

dataset = load_dataset(DATASET_NAME_ON_HUB)
```

B.
```python
import librosa

dataset = librosa.load(PATH_TO_DATASET)
```

C.
```python
from transformers import load_dataset

dataset = load_dataset(DATASET_NAME_ON_HUB)
```

### 6. 32 kHz의 샘플링 속도를 가진 고품질 오디오 데이터셋으로 16 kHz 샘플링 속도를 요구하는 음성 인식 모델을 학습하고자 합니다. 그렇다면 무엇을 해야합니까?

### 7. 머신러닝 모델에 의해 만들어진 스펙트로그램을 파형으로 바꾸는 방법으로 옳은 것은?

### 오디오 데이터셋 전처리하기[[preprocessing-an-audio-dataset]]
https://huggingface.co/learn/audio-course/ko/chapter1/preprocessing.md

# 오디오 데이터셋 전처리하기[[preprocessing-an-audio-dataset]]

🤗 Datasets을 이용하여 데이터셋을 불러오는건 재미의 반에 불과합니다. 모델을 학습시키거나 추론(inference)을 실행하기 위해선 먼저 데이터를 전처리해야할 것입니다. 일반적으로 이는 다음의 단계를 거칩니다:

* 오디오 데이터 리샘플링
* 데이터셋 필터링 
* 오디오 데이터를 모델의 입력에 맞게 변환

## 오디오 데이터 리샘플링하기[[resampling-the-audio-data]]

`load_dataset` 함수는 오디오 데이터를 게시된(published) 샘플링 속도에 맞춰 다운로드합니다. 이 샘플링 속도는 여러분이 계획한 학습 혹은 추론을 위한 샘플링 속도가 아닐 수 있습니다. 이렇게 샘플링 속도간 불일치가 있다면, 모델이 기대하는 샘플링 속도에 맞춰 리샘플링을 할 수 있습니다.

대부분의 사전 학습된 모델들은 16 kHz의 샘플링 속도를 가진 오디오 데이터셋에 대하여 사전학습이 이뤄져있습니다.
여러분이 MINDS-14 데이터셋을 살펴보신다면 8 kHz로 샘플링된것을 알 수 있을겁니다. 업샘플링이 필요하다는 뜻이죠.

이를 위해, 🤗 Datasets의 `cast_column` 메소드를 써봅시다. 이 연산은 오디오를 in-place로 변경하는 것이 아니라 오디오 데이터들이 불러와질때 즉석에서 리샘플링되도록 데이터셋에 신호를 보냅니다. 다음의 코드는 샘플링 속도를 16 kHz로 설정합니다:

```py
from datasets import Audio

minds = minds.cast_column("audio", Audio(sampling_rate=16_000))
```

MINDS-14 데이터셋의 첫번째 오디오 예제를 다시 불러와 원하는 `sampling_rate`으로 리샘플링 되었는지 확인해 보겠습니다:

```py
minds[0]
```

**Output:**
```out
{
    "path": "/root/.cache/huggingface/datasets/downloads/extracted/f14948e0e84be638dd7943ac36518a4cf3324e8b7aa331c5ab11541518e9368c/en-AU~PAY_BILL/response_4.wav",
    "audio": {
        "path": "/root/.cache/huggingface/datasets/downloads/extracted/f14948e0e84be638dd7943ac36518a4cf3324e8b7aa331c5ab11541518e9368c/en-AU~PAY_BILL/response_4.wav",
        "array": array(
            [
                2.0634243e-05,
                1.9437837e-04,
                2.2419340e-04,
                ...,
                9.3852862e-04,
                1.1302452e-03,
                7.1531429e-04,
            ],
            dtype=float32,
        ),
        "sampling_rate": 16000,
    },
    "transcription": "I would like to pay my electricity bill using my card can you please assist",
    "intent_class": 13,
}
```

여러분은 아마 배열의 값들 역시 달라졌음을 눈치채셨을 겁니다. 이는 기존에 비해 진폭값들의 갯수가 전부 두배로 늘어났기 때문입니다.

💡 리샘플링에 대한 배경 정보: 만약 오디오 신호가 8 kHz로 샘플링 되었다면(즉, 초당 8000개의 샘플이 있다면) 4 kHz보다 높은 주파수는 없음을 알 수 있습니다. 나이퀴스트 샘플링 정리(Nyquist sampling theorem)에 의해서 말이죠. 이 덕분에 우린 샘플링 지점들간의 원래의 연속적인 신호는 항상 부드러운 커브임을 확신할 수 있는 것입니다. 더 높은 샘플링 속도로의 업샘플링은 이 커브를 근사하여 기존 점들 사이의 값을 찾아내면 됩니다. 그러나 다운샘플링 같은 경우, 새로운 샘플을 결정하기전에 새로운 나이퀴스트 한계보다 높은 주파수를 먼저 걸러내는 작업이 필요할 겁니다. 다시 말해, 2배의 다운샘플링 같은 경우 이에 맞춰 단순히 샘플들을 버리는 것으로는 왜곡이 생길 수 있습니다. 이 왜곡을 alias라고 합니다. 이렇듯 리샘플링을 올바르게 하기란 꽤 까다로우므로 librosa나 🤗 Datasets같은 잘 테스트된 라이브러리를 쓰는편이 낫습니다.

## 데이터셋 필터링하기[[filtering-the-dataset]]

여러분은 데이터를 어떤 기준에 맞춰 필터링해야할 때도 있을겁니다. 흔한 경우로는 오디오 데이터를 특정 길이에 맞춰 제한하는 경우가 있을 수 있습니다. 예를 들어, 모델 학습시 out-of-memory 에러를 피하기 위해 20초 보다 긴 모든 데이터를 필터링하길 원할 수도 있습니다.

🤗 Datasets의 `filter` 메소드에 필터링 로직을 짠 함수를 집어넣어 쓴다면 이를 수행할 수 있습니다. 한번 어떤 데이터를 쓸지 또는 버릴지를 알려주는 함수를 작성해 이를 써봅시다. 함수 `is_audio_length_in_range`는 만약 샘플이 20초보다 짧다면 `True`를 그렇지 않다면 `False`를 반환합니다.

```py
MAX_DURATION_IN_SECONDS = 20.0

def is_audio_length_in_range(input_length):
    return input_length 

이제 전처리 후 Whisper 모델에 대한 오디오 입력이 어떻게 보이는지 확인하실 수 있습니다.

모델의 feature extractor 클래스는 원시 데이터를 모델이 원하는 포맷으로 변경하는 작업을 처리합니다. 그러나, 대개의 오디오 작업은(예를 들어, 음성 인식) multimodal입니다. 이런 경우 🤗 Transformers는 텍스트 입력을 처리하기 위해 모델별 토크나이저(tokenizer)를 제공합니다. 토크나이저에 대해 더 자세히 알고 싶으시다면 [NLP 코스](https://huggingface.co/course/chapter2/4)를 참고하세요.

Whisper와 다른 multimodal 모델에 대해 각각의 feature extractor와 토크나이저를 별도로 불러오거나, 이른바 processor를 통해 한번에 불러올 수도 있습니다. 더 간단히 다음의 코드처럼 `AutoProcessor`로 체크포인트에서 모델의 feature extractor와 processor를 불러올 수도 있습니다:

```py
from transformers import AutoProcessor

processor = AutoProcessor.from_pretrained("openai/whisper-small")
```

여기에서는 기본적인 데이터 준비 단계를 설명했습니다. 물론 커스텀 데이터는 더 복잡한 전처리가 필요할 수도 있습니다.
이 경우, 여러분은 어떤 종류의 커스텀 데이터도 변환이 가능하도록 `prepare_dataset` 함수를 확장할 수 있습니다. 🤗 Datasets과 함께라면, 여러분은 파이썬 함수로 작성 할 수만 있다면 여러분의 데이터에 이를 적용시킬 수 있을겁니다!

### 1단원. 오디오 데이터 다루기[[unit-1-working-with-audio-data]]
https://huggingface.co/learn/audio-course/ko/chapter1/introduction.md

# 1단원. 오디오 데이터 다루기[[unit-1-working-with-audio-data]]

## 이 단원에서 배울 내용[[what-youll-learn-in-this-unit]]

모든 오디오작업과 음성 작업은 오디오 파일부터 시작됩니다. 이러한 작업을 해결하기에 앞서, 이 파일들이 실제로 무엇을 담고 있는지, 그리고 어떻게 작업해야할지에 대해 이해하는 것이 중요합니다.

이 단원에선 파형(waveform), 샘플링 속도(sampling rate), 스펙트로그램(spectrogram)과 같은 오디오 데이터와 연관된 기본 용어에 대하여 배웁니다. 또한 오디오 데이터를 불러오고 전처리하는 방법, 큰 데이터셋을 효율적으로 스트리밍하는 방법 등 오디오 데이터셋을 다루는 법도 배우게 됩니다.

이 단원을 마치면 오디오 데이터 용어들에 대한 확실한 이해와 오디오 데이터셋의 다양한 응용작업을 위해 필요한 기술들을 습득하게 될것입니다. 이 단원에서 습득하게 될 지식은 코스의 나머지 과정을 이해하기 위해 필요한 기초가 됩니다.

### 파이프라인을 이용한 오디오 분류[[audio-classification-with-a-pipeline]]
https://huggingface.co/learn/audio-course/ko/chapter2/audio_classification_pipeline.md

# 파이프라인을 이용한 오디오 분류[[audio-classification-with-a-pipeline]]

오디오 분류는 녹음된 오디오 내용에 기반하여 하나 혹은 여러개의 레이블을 할당하는 작업입니다. 이 레이블은 음악, 음성, 노이즈 같은 카테고리에 해당할 수도 있고, 새소리나 차 엔진 소리처럼 더 구체적인 카테고리일 수도 있습니다.

인기 있는 오디오 트랜스포머 모델들이 세부적으로 어떻게 작동하는지, 커스텀 모델을 어떻게 파인튜닝하는지 등을 알아보기 전에 🤗 Transformers를 이용하여 단 몇줄의 코드만으로 사전학습된 모델을 오디오 분류에 쓰는 법을 알아봅시다.

이전 단원에서 사용했던 [MINDS-14](https://huggingface.co/datasets/PolyAI/minds14) 데이터셋을 쓰겠습니다. 기억하시다시피, MINDS-14는 사람들이 인터넷뱅킹 시스템에 대해 전화로 여러 언어와 방언으로 묻는 것이 녹음돼있습니다. 각 녹음에는 `intent_class`가 있으며 이를 이용해 녹음들을 전화의 의도에 따라 분류할 수 있습니다.

파이프라인을 써보기 위해 이전과 마찬가지로 데이터의 `en-AU` 부분을 가져와 모델이 요구하는 16 kHz 샘플링 속도를 가지도록 업샘플링 해봅시다.

```py
from datasets import load_dataset
from datasets import Audio

minds = load_dataset("PolyAI/minds14", name="en-AU", split="train")
minds = minds.cast_column("audio", Audio(sampling_rate=16_000))
```

🤗 Transformers의 `audio-classification` 파이프라인을 사용하면 녹음된 오디오를 클래스 집합으로 분류할 수 있습니다.
우리의 경우, MINDS-14 데이터셋의 의도 분류를 위해 파인튜닝된 모델이 필요합니다. 운좋게도, 바로 그럴때 쓰이는 모델이 허브에 있습니다! `pipeline()` 함수를 써서 이를 불러보겠습니다:

```py
from transformers import pipeline

classifier = pipeline(
    "audio-classification",
    model="anton-l/xtreme_s_xlsr_300m_minds14",
)
```

이 파이프라인은 오디오 데이터로 넘파이 배열을 요구합니다. 원시 오디오 데이터의 모든 전처리는 편리하게도 파이프라인이 해결해줍니다. 한 예를 봅시다:

```py
example = minds[0]
```

데이터셋의 구조를 기억하신다면, 원시 오디오 데이터가 `["audio"]["array"]` 아래에 넘파이 배열로 저장돼있는걸 기억하실겁니다. 그대로 `classifier`에 넘겨봅시다:

```py
classifier(example["audio"]["array"])
```

**Output:**
```out
[
    {"score": 0.9631525278091431, "label": "pay_bill"},
    {"score": 0.02819698303937912, "label": "freeze"},
    {"score": 0.0032787492964416742, "label": "card_issues"},
    {"score": 0.0019414445850998163, "label": "abroad"},
    {"score": 0.0008378693601116538, "label": "high_value_payment"},
]
```

모델은 전화하는 사람이 청구서의 지불 방법에 대해 묻고 있다고 매우 확신하고 있습니다. 실제 레이블은 어떤지 확인해봅시다: 

```py
id2label = minds.features["intent_class"].int2str
id2label(example["intent_class"])
```

**Output:**
```out
"pay_bill"
```

만세! 예측값이 맞았습니다! 운 좋게도 우리는 필요한 레이블을 정확하게 분류할 수 있는 모델을 찾을 수 있었습니다. 그러나 분류 작업을 다루는 많은 경우에는 사전학습된 모델의 클래스가 우리가 바라는 분류 클래스와 일치하지 않습니다. 이와 같은 경우, 여러분은 사전학습된 모델을 "보정(calibrate)"하여 여러분의 클래스 레이블에 맞출 수 있습니다. 이후 단원에서 이를 어떻게 하는지 배우게 됩니다. 이제 음성 처리에서 매우 일반적인 작업인 _자동 음성 인식_에 대해 살펴봅시다.

### 파이프라인을 이용한 자동 음성 인식[[automatic-speech-recognition-with-a-pipeline]]
https://huggingface.co/learn/audio-course/ko/chapter2/asr_pipeline.md

# 파이프라인을 이용한 자동 음성 인식[[automatic-speech-recognition-with-a-pipeline]]

자동 음성 인식(ASR)은 음성 오디오 녹음을 텍스트로 변환하는 작업입니다. 이 작업은 매우 다양하게 실용적으로 쓰일 수가 있습니다. 비디오 자막 생성부터 Siri나 Alexa같은 가상 비서의 음성명령에 이르기까지요.

이번 섹션에선 이전의 MINDS-14 데이터셋의 청구서 지불 방법에 대해 묻는 사람의 음성 녹음을 `automatic-speech-recognition` 파이프라인을 이용해 텍스트로 변환하는 방법을 알아보겠습니다.

시작을 위해 데이터를 준비해야 합니다. 아직 준비하지 않았다면, [Audio classification with a pipeline](introduction.mdx)에서 했던것처럼 데이터셋을 불러오고 16 kHz로 업샘플링을 해주세요.

오디오 녹음을 텍스트로 바꾸기 위해 🤗 Transformers의 `automatic-speech-recognition` 파이프라인을 이용합니다. 파이프라인을 인스턴스화(instantiate) 해보겠습니다:

```py
from transformers import pipeline

asr = pipeline("automatic-speech-recognition")
```

다음으로, 데이터셋에서 원시 데이터를 불러와 파이프라인에 넘겨봅시다:

```py
example = minds[0]
asr(example["audio"]["array"])
```

**Output:**
```out
{"text": "I WOULD LIKE TO PAY MY ELECTRICITY BILL USING MY COD CAN YOU PLEASE ASSIST"}
```

이 출력과 실제값을 비교해보겠습니다:

```py
example["english_transcription"]
```

**Output:**
```out
"I would like to pay my electricity bill using my card can you please assist"
```

모델이 오디오를 텍스트로 바꾸는 일을 꽤 잘 해낸것 같습니다! 실제 텍스트와 비교했을때 한 단어("card")만을 틀렸을 뿐입니다. 화자가 호주식 억양인 것을 고려할 때 꽤 괜찮은 결과로 볼 수 있습니다(호주식 억양에선 "r"이 종종 묵음입니다). 그렇긴 하지만, 전기요금을 물고기("cod"는 영어로 대구를 뜻합니다)로 낼 것을 권장하지는 않습니다!

기본적으로 이 파이프라인은 영어의 자동 음성 인식을 위해 학습된 모델을 씁니다. 이 예제에서는 괜찮지만 여러분이 만약 MINDS-14의 다른 언어에 대해 텍스트 변환을 시도해보고 싶으시다면 [🤗 Hub](https://huggingface.co/models?pipeline_tag=automatic-speech-recognition&language=fr&sort=downloads)에서 사전학습된 ASR 모델을 찾아보실 수 있습니다.
모델 리스트에서 작업순으로 필터링을 먼저하고 언어에 대해 필터링을 할 수 있습니다. 마음에 드는 모델을 찾으셨다면, 파이프라인의 `model` 인수(argument)로 넘겨 쓰면 됩니다.

이를 이용해 MINDS-14의 독일어 부분을 다뤄 보겠습니다. "de-DE" 부분을 불러봅시다:

```py
from datasets import load_dataset
from datasets import Audio

minds = load_dataset("PolyAI/minds14", name="de-DE", split="train")
minds = minds.cast_column("audio", Audio(sampling_rate=16_000))
```

예제를 하나 선택해 텍스트가 어떻게 나와야하는지 확인해봅시다:

```py
example = minds[0]
example["transcription"]
```

**Output:**
```out
"ich möchte gerne Geld auf mein Konto einzahlen"
```

🤗 Hub에서 독일어를 위해 사전학습된 ASR 모델을 찾아 파이프라인을 인스턴스화한 후 이 예제에 적용시켜봅시다:

```py
from transformers import pipeline

asr = pipeline("automatic-speech-recognition", model="maxidl/wav2vec2-large-xlsr-german")
asr(example["audio"]["array"])
```

**Output:**
```out
{"text": "ich möchte gerne geld auf mein konto einzallen"}
```

역시나, stimmt's!

여러분이 작업을 시작할 때, 이번 단원에서 보신것처럼 간단한 파이프라인으로 시작해보는것은 여러 장점이 있습니다:
- 여러분의 문제를 해결할 사전학습된 모델이 이미 있을 수 있습니다. 많은 시간을 아끼실 수 있을겁니다.
- `pipeline()`은 여러분을 위해 전처리 및 후처리를 대신 해줍니다. 따라서 여러분은 데이터 형식을 모델에 맞추는것에 대해 걱정하지 않으셔도 됩니다.
- 결과가 이상적이지 않더라도 하나의 기준점을 빠르게 제시해줍니다.
- 여러분이 커스텀 데이터에 맞춰 모델을 파인튜닝하고 허브에 올린다면 `pipeline()` 메소드를 이용해 모든 커뮤니티가 이를 쉽게 쓸 수 있어 AI를 더욱 사용하기 쉽게 만듭니다.

### 실습 과제[[hands-on-exercise]]
https://huggingface.co/learn/audio-course/ko/chapter2/hands_on.md

# 실습 과제[[hands-on-exercise]]

이 과제는 평가의 대상은 아닙니다. 단지 나머지 코스를 위해 여러분이 라이브러리와 툴에 익숙해지는 것을 목적으로 합니다. 구글 코랩, 🤗 Datasets, librosa, 🤗 Transformers에 이미 익숙하시다면 과제를 건너뛰셔도 좋습니다.

1. [구글 코랩](https://colab.research.google.com) 노트북을 생성해보세요.
2. 🤗 Datasets을 이용해 여러분이 원하시는 언어의 [`facebook/voxpopuli` 데이터셋](https://huggingface.co/datasets/facebook/voxpopuli) 학습 데이터를 스트리밍 모드로 불러와보세요.
3. 데이터셋의 `train` 부분에서 세번째 데이터를 불러와 보세요. 이 데이터의 feature를 고려할 때, 어떤 오디오 작업에 이 데이터셋을 쓸 수 있으실 것 같나요?
4. 이 데이터의 파형과 스펙트로그램을 그려보세요.
5. [🤗 허브](https://huggingface.co/models)에서 사전학습된 모델을 둘러보고 여러분이 고른 언어의 자동 음성 인식 모델을 선택해보세요. 그에 맞는 파이프라인을 인스턴스화 하시고 음성 데이터를 텍스트로 바꿔보세요.
6. 여러분이 파이프라인에서 얻은 출력 텍스트와 실제 데이터의 텍스트를 비교해보세요.

과제를 푸는데 어려움이 있다면 [풀이 예시](https://colab.research.google.com/drive/1NGyo5wFpRj8TMfZOIuPaJHqyyXCITftc?usp=sharing)를 살펴보는 것도 좋습니다. 
뭔가 흥미로운 것을 발견하셨나요? 멋진 모델을 찾으셨나요? 아름다운 스펙트로그램을 얻으셨나요? 트위터에 여러분의 작업 결과와 발견들을 공유해보세요!

다음 챕터에선 여러 오디오 트랜스포머의 구조에 대해 알아보고 여러분만의 모델을 학습해봅시다!

### 2단원. 오디오의 응용에 대한 소개[[unit-2-a-gentle-introduction-to-audio-applications]]
https://huggingface.co/learn/audio-course/ko/chapter2/introduction.md

# 2단원. 오디오의 응용에 대한 소개[[unit-2-a-gentle-introduction-to-audio-applications]]

허깅페이스 오디오 코스의 두번째 단원에 오신것을 환영합니다! 지금까지는 오디오 데이터의 기본 개념을 살펴보고 🤗 Datasets과 🤗 Transformers 라이브러리를 활용해 오디오 데이터셋을 처리하는 방법을 배웠습니다. 또한 샘플링 속도, 진폭, 비트뎁스, 파형, 스펙트로그램, 사전학습된 모델을 위해 데이터를 전처리하는 방법에 관하여도 살펴봤습니다. 

이 시점에서 여러분은 🤗 Transformers로 처리할 수 있는 오디오 작업들에 관해 배우고 싶으실 것이며 이에 필요한 기초 지식은 모두 갖추셨을 것입니다. 몇 가지 놀라운 오디오 작업 예제들을 살펴봅시다:

* **오디오 분류(Audio classification)**: 오디오 클립을 쉽게 다른 카테고리들로 분류합니다. 녹음된 소리가 개가 짖는 소리인지 고양이가 우는 소리인지를 구분한다거나, 노래가 어떤 음악 장르에 속하는지 등을 판별합니다.
* **자동 음성 인식(Automatic speech recognition)**: 오디오 클립에서 자동으로 자막을 만듭니다. "오늘 하루 어때요?"와 같이 누군가가 말하는 녹음 내용을 텍스트로 변환할 수 있습니다. 메모를 할 때 상당히 유용합니다!
* **화자 구분(Speaker diarization)**: 녹음에서 누가 말하고 있는지 궁금했던 적이 있나요? 🤗 Transformers를 사용하면 오디오 클립의 어느 시점에 누가 말하는지를 구분할 수 있습니다. "Alice"와 "Bob" 두 사람의 대화 녹음에서 그들을 구분할 수 있다고 상상해 보세요.
* **텍스트 음성 변환(Text to speech)**: 텍스트의 나레이션을 만들어 오디오북을 만들거나 접근성(accessibility)을 향상시킬 수도 있고 게임의 NPC에게 목소리를 부여할 수도 있습니다. 🤗 Transformers를 사용하면 쉬운 일입니다!

이번 단원에서는 🤗 Transformers의 `pipeline()` 함수를 사용하여 이런 작업들에 사전학습된 모델을 쓰는 법을 알아보겠습니다.
특히, 사전학습된 모델이 오디오 분류와 자동 음성 인식에 어떻게 쓰이는지를 살펴보겠습니다.
시작해봅시다!

### Seq2Seq 아키텍처[[seq2seq-architectures]]
https://huggingface.co/learn/audio-course/ko/chapter3/seq2seq.md

# Seq2Seq 아키텍처[[seq2seq-architectures]]

이전 섹션에서 설명한 CTC 모델은 트랜스포머 아키텍처의 인코더 부분만 사용했습니다. 디코더를 추가하여 인코더-디코더 모델을 생성할 때 이를 **sequence-to-sequence** 모델 또는 줄여서 seq2seq라고 합니다. 이 모델은 한 종류의 데이터 시퀀스를 다른 종류의 데이터 시퀀스에 매핑합니다.

인코더 전용 트랜스포머 모델에서는 인코더가 입력 시퀀스의 각 요소에 대해 예측을 수행합니다. 따라서 입력 및 출력 시퀀스의 길이는 항상 동일합니다. Wav2Vec2와 같은 CTC 모델의 경우 입력 파형이 먼저 다운샘플링되었지만 여전히 오디오 20ms당 하나의 예측이 있었습니다.

seq2seq 모델을 사용하면 이러한 일대일 대응이 없으며 입력 및 출력 시퀀스의 길이가 다를 수 있습니다. 따라서 seq2seq 모델은 텍스트 요약이나 서로 다른 언어 간 번역과 같은 NLP 작업뿐만 아니라 음성 인식과 같은 오디오 작업에도 적합합니다.

디코더 아키텍처는 인코더 아키텍처와 매우 유사하며, 둘 다 셀프 어텐션을 주요 기능으로 하는 유사한 레이어를 사용합니다. 하지만 디코더는 인코더와는 다른 작업을 수행합니다. 이것이 어떻게 작동하는지 알아보기 위해 seq2seq 모델이 어떻게 자동 음성 인식을 수행하는지 살펴봅시다.

## 자동 음성 인식[[automatic-speech-recognition]]

**Whisper**의 아키텍처는 다음과 같습니다([OpenAI Whisper 블로그](https://openai.com/blog/whisper/) 그림 제공):

    

꽤 익숙하게 보일 것입니다. 왼쪽은 **트랜스포머 인코더**입니다. 이것은 로그 멜 스펙트로그램을 입력으로 받아 해당 스펙트로그램을 인코딩하여 음성에서 중요한 특징을 추출하는 인코더의 은닉 상태 시퀀스를 형성합니다. 이 은닉 상태 텐서는 입력 시퀀스를 전체적으로 나타내며 입력 음성의 '의미'를 효과적으로 인코딩합니다.

💡 이러한 seq2seq 모델은 스펙트로그램을 입력으로 사용하는 것이 일반적입니다. 하지만 오디오 파형에서 직접 작동하도록 설계할 수도 있습니다.

그런 다음 인코더의 출력은 **크로스 어텐션**이라는 메커니즘을 사용하여 오른쪽에 표시된 **트랜스포머 디코더**로 전달됩니다. 이는 셀프 어텐션과 비슷하지만 인코더 출력을 통해 이루어집니다. 이 시점부터 인코더는 더 이상 필요하지 않습니다.

디코더는 '시작' 토큰만 있는 초기 시퀀스(위스퍼의 경우 'SOT')부터 시작하여 한 번에 하나의 토큰씩 **자동 회귀** 방식으로 텍스트 토큰의 시퀀스를 예측합니다. 다음 각 타임스텝에서 이전 출력 시퀀스는 새로운 입력 시퀀스로 디코더에 다시 공급됩니다. 이러한 방식으로 디코더는 "종료" 토큰을 예측하거나 최대 타임스텝 수에 도달할 때까지 한 번에 하나의 새 토큰을 방출하여 출력 시퀀스를 꾸준히 증가시킵니다.

디코더의 아키텍처는 인코더의 아키텍처와 대부분 동일하지만 두 가지 큰 차이점이 있습니다:

1. 디코더에는 인코더의 입력 시퀀스 표현을 살펴볼 수 있는 크로스 어텐션 메커니즘이 있습니다.
2. 디코더 어텐션은 인과적이기 때문에 디코더는 미래를 미리 살펴볼 수 없습니다.

이 설계에서 디코더는 **언어 모델**의 역할을 수행하여 인코더의 은닉 상태 표현을 처리하고 해당 텍스트 트랜스크립션을 생성합니다. 이는 CTC 모델을 외부 언어 모델과 결합하더라도 동일한 훈련 데이터와 손실 함수로 seq2seq 시스템을 엔드 투 엔드 훈련할 수 있어 유연성이 뛰어나고 일반적으로 성능이 우수하기 때문에 CTC보다 강력한 접근 방식입니다.

💡 CTC 모델은 개별 문자의 시퀀스를 출력하는 반면, Whisper가 예측하는 토큰은 전체 단어 또는 단어의 일부입니다. GPT-2의 토크나이저를 사용하며 5만 개 이상의 고유 토큰을 보유하고 있습니다. 따라서 seq2seq 모델은 동일한 트랜스크립션에 대해 CTC 모델보다 훨씬 짧은 시퀀스를 출력할 수 있습니다.

모델의 최종 계층이 발생 가능한 토큰에 대한 확률 분포를 예측하기 때문에 seq2seq ASR 모델의 일반적인 손실 함수는 크로스 엔트로피 손실입니다. 이는 일반적으로 [최종 시퀀스 생성을 위한 빔 검색](https://huggingface.co/blog/how-to-generate)과 같은 기술과 결합됩니다. 음성 인식의 지표는 문자 오류율(WER, Word Error Rate)로, 예측된 텍스트를 대상 텍스트로 바꾸는 데 필요한 대체, 삽입, 삭제 횟수를 측정하며, 이 수치가 적을수록 좋은 점수를 받습니다.

## 텍스트 음성 변환[[texttospeech]]

놀랍지 않으실 수도 있습니다: TTS용 seq2seq 모델은 위에서 설명한 것과 본질적으로 동일하게 작동하지만 입력과 출력의 위치가 바뀝니다! 트랜스포머 인코더는 일련의 텍스트 토큰을 받아 입력 텍스트를 나타내는 은닉 상태 시퀀스를 추출합니다. 트랜스포머 디코더는 인코더 출력에 크로스 어텐션을 적용하고 스펙트로그램을 예측합니다.

💡 스펙트로그램은 오디오 파형의 연속적인 시간 조각의 주파수 스펙트럼을 가져와서 함께 쌓아서 만든다는 것을 기억하세요. 즉, 스펙트로그램은 각 타임스텝마다 하나씩의 로그 멜(log-mel) 주파수 스펙트럼이 요소로 구성된 시퀀스입니다.

ASR 모델에서는 특별한 "시작" 토큰이 포함된 시퀀스를 사용하여 디코더를 시작합니다. TTS 모델의 경우, '시작 토큰' 역할을 하는 길이가 1이고 모두 값이 0인 스펙트로그램으로 디코딩을 시작할 수 있습니다. 이 초기 스펙트로그램과 인코더의 은닉 상태 표현에 대한 크로스 어텐션이 주어지면 디코더는 이 스펙트로그램의 다음 타임슬라이스를 예측하여 스펙트로그램을 한 번에 한 타임스텝씩 꾸준히 증가시킵니다.

    

하지만 디코더는 언제 멈춰야 하는지 어떻게 알 수 있을까요? **SpeechT5** 모델에서는 디코더가 두 번째 시퀀스를 예측하도록 함으로써 이 문제를 처리합니다. 여기에는 현재 시간 간격이 마지막 시간 간격일 확률이 포함됩니다. 추론 시간에 오디오를 생성하는 동안 이 확률이 특정 임계값(예: 0.5)을 초과하면 디코더는 스펙트로그램이 완료되었음을 나타내며 생성 루프를 종료해야 합니다.

디코딩이 완료되고 스펙트로그램이 포함된 출력 시퀀스를 얻은 후 SpeechT5는 여러 컨볼루션 레이어로 구성된 소위 **post-net**을 사용하여 스펙트로그램을 개선합니다.

TTS 모델을 훈련하는 동안 목표도 스펙트로그램이며 손실은 L1 또는 MSE(Mean Squared Error)입니다. 추론 시에는 출력 스펙트로그램을 오디오 파형으로 변환하여 실제로 들을 수 있도록 하려고 합니다. 이를 위해 외부 모델인 **보코더(vocoder)**가 사용됩니다. 이 보코더는 seq2seq 아키텍처의 일부가 아니며 별도로 학습됩니다.

TTS를 어렵게 만드는 것은 일대다 매핑이라는 점입니다. 음성 대 텍스트에서는 입력 음성에 해당하는 올바른 출력 텍스트가 하나만 있지만, 텍스트 음성 변환에서는 입력 텍스트를 여러 가지 가능한 음성 소리에 매핑할 수 있습니다. 예를 들어 화자마다 문장의 다른 부분을 강조하도록 선택할 수 있습니다. 이 때문에 TTS 모델을 평가하기가 어렵습니다. 동일한 텍스트를 스펙트로그램으로 표현하는 방법은 여러 가지가 있기 때문에 L1 또는 MSE 손실 값은 실제로 큰 의미가 없습니다. 그렇기 때문에 일반적으로 TTS 모델은 MOS(Mean Opinion Score)라는 메트릭을 사용하여 사람이 직접 평가합니다.

## 결론[[conclusion]]

seq2seq 접근 방식은 인코더 전용 모델보다 더 강력합니다. 입력 시퀀스의 인코딩과 출력 시퀀스의 디코딩을 분리함으로써 오디오와 텍스트의 정렬이 보다 수월해집니다. 

그러나 인코더-디코더 모델은 디코딩 프로세스가 한 번에 한 번에 이루어지는 것이 아니라 한 번에 한 단계씩 이루어지기 때문에 속도가 느립니다. 시퀀스가 길수록 예측 속도가 느려집니다. 또한 자동 회귀 모델은 반복되는 단어에 갇히거나 단어를 건너뛸 수 있습니다. 빔 검색과 같은 기술을 사용하면 예측 품질을 개선하는 데 도움이 될 수 있지만 디코딩 속도가 더 느려질 수도 있습니다.

### 추가 자료 및 리소스[[supplemental-reading-and-resources]]
https://huggingface.co/learn/audio-course/ko/chapter3/supplemental_reading.md

# 추가 자료 및 리소스[[supplemental-reading-and-resources]]

다양한 트랜스포머 아키텍처에 대해 더 자세히 알아보고 음성 처리 분야의 다양한 애플리케이션에 대해 알아보려면 이 백서를 확인하세요:

### 음성 처리를 위한 트랜스포머: 설문 조사[[transformers-in-speech-processing-a-survey]]

작성자:  Siddique Latif, Aun Zaidi, Heriberto Cuayahuitl, Fahad Shamshad, Moazzam Shoukat, Junaid Qadir

"자연어 처리 분야에서 트랜스포머의 놀라운 성공은 음성 처리 커뮤니티의 관심을 불러일으켰고, 음성 시퀀스 내에서 장거리 종속성을 모델링할 수 있는 트랜스포머의 잠재력에 대한 탐구로 이어졌습니다. 최근 트랜스포머는 자동 음성 인식, 음성 합성, 음성 번역, 음성 준언어학, 음성 향상, 음성 대화 시스템 및 수많은 멀티모달 애플리케이션을 포함한 다양한 음성 관련 영역에서 각광받고 있습니다. 이 백서에서는 음성 기술 내 다양한 하위 분야의 연구를 연결하는 것을 목표로 하는 포괄적인 설문조사를 제시합니다. 음성 기술 환경 전반의 연구 결과를 통합함으로써, 이 분야를 발전시키기 위해 트랜스포머의 힘을 활용하는 데 관심이 있는 연구자에게 귀중한 리소스를 제공합니다.
연구자들에게 귀중한 리소스를 제공합니다. 음성 처리에서 랜포머가 직면한 문제를 파악하는 동시에 이러한 문제를 해결할 수 있는 잠재적 솔루션에 대한 통찰력도 제공합니다."

[arxiv.org/abs/2303.11607](https://arxiv.org/abs/2303.11607)

### 이번 코스에 대한 이해도를 확인해보세요[[check-your-understanding-of-the-course-material]]
https://huggingface.co/learn/audio-course/ko/chapter3/quiz.md

# 이번 코스에 대한 이해도를 확인해보세요[[check-your-understanding-of-the-course-material]]

### 1. 보코더(vocoder)는 무엇일까요?

### 2. Wav2Vec2는 어떤 항목에 예제일까요?

### 3. CTC 알고리즘에서 빈 토큰은 어떤 역할을 하나요?

 토큰과 유사합니다.",
			explain: ""
		}
	]}
/>

### 4. 다음 중 CTC 모델에 대한 설명 중 거짓은 무엇입니까?

### 5. Whisper모델은 어떤 항목의 예제일까요?

### 6. 오디오 분류를 수행하는 가장 쉬운 방법은 무엇인가요?

### 7. 참인가요, 거짓인가요? 분류를 위해 스펙트로그램을 이미지로 처리할 때는 항상 이미지 이동, 자르기 또는 크기 조정과 같은 이미지 데이터 증강 기술을 활용할 수 있습니다.

### 3단원. 오디오를 위한 트랜스포머 아키텍처[[unit-3-transformer-architectures-for-audio]]
https://huggingface.co/learn/audio-course/ko/chapter3/introduction.md

# 3단원. 오디오를 위한 트랜스포머 아키텍처[[unit-3-transformer-architectures-for-audio]]

이 강좌에서는 주로 트랜스포머 모델과 이를 오디오 작업에 적용하는 방법을 살펴봅니다. 모델의 내부의 세부 내용을 알 필요는 없지만 모델이 동작하는 주요 개념을 이해하는 것이 중요하기 때문에 간단히 복습하겠습니다. 트랜스포머에 대해 자세히 살펴보고 싶으시다면 [NLP 과정](https://huggingface.co/course/chapter1/1)을 참조하세요.

## 트렌스포머의 작동 원리[[how-does-a-transformer-work]]

원래 트랜스포머 모델은 텍스트를 한 언어에서 다른 언어로 번역하도록 설계되었습니다. 구조는 다음과 같습니다.:

    

왼쪽에는 **인코더(encoder)**가 있고 오른쪽에는 **디코더(decoder)**가 있습니다.

- 인코더는 입력(이 경우 텍스트 토큰 시퀀스)을 수신하고 그 표현(특징)을 구축합니다. 모델의 이 부분은 입력을 통해 이해력을 습득하도록 학습됩니다.

- 디코더는 인코더의 표현(특징)을 다른 입력(이전에 예측된 토큰)과 함께 사용하여 목표 시퀀스를 생성합니다. 모델의 이 부분은 출력을 생성하도록 훈련됩니다. 원래 설계에서 출력 시퀀스는 텍스트 토큰으로 구성되었습니다.

인코더 부분만 사용하는 트랜스포머 기반 모델(분류와 같이 입력에 대한 이해가 필요한 작업에 적합) 또는 디코더 부분만 사용하는 모델(텍스트 생성과 같은 작업에 적합)도 있습니다. 인코더 전용 모델의 예로는 BERT가 있고, 디코더 전용 모델의 예로는 GPT2가 있습니다.

트랜스포머 모델의 핵심 특징은 **어텐션(attention) 레이어**라는 특수 레이어로 구축된다는 점입니다. 이 레이어는 특징 표현을 계산할 때 입력 시퀀스의 특정 요소에 특별히 주의를 기울이고 다른 요소는 무시하도록 모델에 지시합니다.

## 오디오에 트랜스포머 사용하기[[using-transformers-for-audio]]

이 강좌에서 다룰 오디오 모델은 일반적으로 위와 같은 표준 트랜스포머 아키텍처를 사용하지만, 텍스트 대신 오디오 데이터를 사용할 수 있도록 입력 또는 출력 측에서 약간의 수정이 이루어집니다. 이러한 모든 모델은 기본적으로 트랜스포머이므로 대부분의 아키텍처가 공통적이며 주요 차이점은 학습 및 사용 방식에 있습니다.

    

오디오 작업의 경우 입력과 출력 전체 혹은 각각의 시퀀스가 텍스트가 아닌 오디오일 수 있습니다:

- 자동 음성 인식(ASR, Automatic Speech Recognition): 입력은 음성, 출력은 텍스트입니다.

- 음성 합성(TTS): 입력은 텍스트, 출력은 음성입니다.

- 오디오 분류(audio classification): 입력은 오디오이고 출력은 클래스 확률(시퀀스의 각 요소에 대해 하나씩 또는 전체 시퀀스에 대해 단일 클래스 확률)입니다.

- 음성 변환(voice conversion) 또는 음성 향상(speech enhancement): 입력과 출력 모두 오디오입니다.

트랜스포머와 함께 사용할 수 있도록 오디오를 처리하는 방법에는 몇 가지가 있습니다. 주요 고려 사항은 오디오를 원시 형태(파형)로 사용할지, 아니면 스펙트로그램으로 처리할지 여부입니다.

## 모델 입력[[model-inputs]]

오디오 모델에 대한 입력은 텍스트 또는 사운드일 수 있습니다. 목표는 이 입력을 트랜스포머 아키텍처에서 처리할 수 있는 임베딩 벡터로 변환하는 것입니다.

### 텍스트 입력[[text-inputs]]

텍스트 음성 변환 모델은 텍스트를 입력으로 받습니다. 이는 원래의 트랜스포머나 다른 NLP(Natural Language Processing) 모델과 똑같이 작동합니다: 입력 텍스트는 먼저 토큰화되어 일련의 텍스트 토큰을 제공합니다. 이 시퀀스는 입력 임베딩 레이어를 통해 전송되어 토큰을 512차원 벡터로 변환합니다. 그런 다음 이러한 임베딩 벡터는 트랜스포머 인코더로 전달됩니다.

### 파형 입력[[waveform-input]]

자동 음성 인식 모델은 오디오를 입력으로 받습니다. ASR에 트랜스포머를 사용하려면 먼저 오디오를 어떤 식으로든 임베딩 벡터 시퀀스로 변환해야 합니다.

**Wav2Vec2** 및 **HuBERT**와 같은 모델은 오디오 파형을 모델에 대한 입력으로 직접 사용합니다. [오디오 데이터 소개](chapter1/introduction)에서 살펴보았듯이 파형은 부동 소수점 숫자의 1차원 시퀀스이며, 각 숫자는 주어진 시간에 샘플링된 진폭을 나타냅니다. 이 원시 파형은 먼저 평균과 단위 분산이 0으로 정규화되어 다양한 음량(진폭)의 오디오 샘플을 표준화하는 데 도움이 됩니다.

    

정규화 후 오디오 샘플 시퀀스는 특징 인코더(feature encoder)로 알려진 작은 컨볼루션 신경망을 사용하여 임베딩으로 변환됩니다. 이 네트워크의 각 컨볼루션 레이어는 입력 시퀀스를 처리하고 오디오를 서브샘플링하여 시퀀스 길이를 줄인 다음 최종 컨볼루션 레이어가 오디오 25ms마다 임베딩이 포함된 512차원 벡터를 출력할 때까지 처리합니다. 입력 시퀀스가 이러한 임베딩 시퀀스로 변환되면 트랜스포머는 평소와 같이 데이터를 처리합니다.

### 스펙트로그램 입력[[spectrogram-input]]

원시 파형을 입력으로 사용할 때의 한 가지 단점은 시퀀스 길이가 길어지는 경향이 있다는 것입니다. 예를 들어 샘플링 속도가 16kHz인 30초 분량의 오디오는 '30 * 16000 = 480000' 길이의 입력이 됩니다. 시퀀스 길이가 길수록 트랜스포머 모델에서 더 많은 계산이 필요하므로 메모리 사용량이 증가합니다.

이 때문에 원시 오디오 파형은 일반적으로 오디오 입력을 표현하는 가장 효율적인 형태가 아닙니다. 스펙트로그램을 사용하면 동일한 양의 정보를 더 압축된 형태로 얻을 수 있습니다.

    

**Whisper**와 같은 모델은 먼저 파형을 로그 멜 스펙트로그램으로 변환합니다. Whisper는 항상 오디오를 30초 세그먼트로 분할하며, 각 세그먼트의 로그 멜 스펙트로그램은 80, 3000의 형태를 갖습니다. 여기서 80은 멜 빈의 수이고 3000은 시퀀스 길이입니다. 로그 멜 스펙트로그램으로 변환함으로써 입력 데이터의 양을 줄였지만, 더 중요한 것은 원시 파형보다 훨씬 짧은 시퀀스라는 점입니다. 그런 다음 로그 멜 스펙트로그램은 작은 CNN에 의해 임베딩 시퀀스로 처리되어 평소와 같이 트랜스포머로 들어갑니다.

파형과 스펙트로그램 입력 두 경우 모두, 트랜스포머 앞에 작은 네트워크가 있어 입력을 임베딩으로 변환한 다음 트랜스포머가 작업을 수행합니다.

## 모델 출력[[model-outputs]]

트랜스포머 아키텍처는 출력 임베딩이라고도 하는 은닉 상태 벡터의 시퀀스를 출력합니다. 우리의 목표는 이러한 벡터를 텍스트 또는 오디오 출력으로 변환하는 것입니다.

### 텍스트 출력[[text-output]]

자동 음성 인식 모델의 목표는 텍스트 토큰의 시퀀스를 예측하는 것입니다. 이는 언어 모델링 헤드(일반적으로 단일 선형 레이어)를 추가한 다음 트랜스포머의 출력 위에 소프트맥스를 추가하여 수행됩니다. 이렇게 하면 어휘의 텍스트 토큰에 대한 확률을 예측할 수 있습니다

### 스펙트로그램 출력[[spectrogram-output]]

텍스트 음성 변환(TTS) 모델과 같이 오디오를 생성하는 모델의 경우 오디오 시퀀스를 생성할 수 있는 레이어를 추가해야 합니다. 스펙트로그램을 생성한 다음 보코더(vocoder)라고 하는 추가 신경망을 사용하여 이 스펙트로그램을 파형으로 변환하는 것이 매우 일반적입니다.

예를 들어 **SpeechT5** TTS 모델에서 트랜스포머 네트워크의 출력은 768개 요소 벡터의 시퀀스입니다. 선형 레이어는 이 시퀀스를 로그 멜 스펙트로그램으로 투영합니다. 추가 선형 및 컨볼루션 레이어로 구성된 이른바 포스트넷(post-net)은 노이즈를 줄여 스펙트로그램을 개선합니다. 그런 다음 보코더가 최종 오디오 파형을 생성합니다.

    

💡 기존 파형을 가지고 단시간 푸리에 변환(STFT)을 적용하면 역연산인 ISFT를 수행하여 원래의 파형을 다시 얻을 수 있습니다. 이는 STFT로 생성된 스펙트로그램에 진폭과 위상 정보가 모두 포함되어 있고 파형을 재구성하는 데 두 가지 정보가 모두 필요하기 때문에 가능합니다. 그러나 스펙트로그램으로 출력을 생성하는 오디오 모델은 일반적으로 위상이 아닌 진폭 정보만 예측합니다. 이러한 스펙트로그램을 파형으로 변환하려면 어떻게든 위상 정보를 추정해야 합니다. 이것이 바로 보코더가 하는 일입니다.

### 파형 출력[[waveform-output]]

모델이 중간 단계로 스펙트로그램 대신 파형을 직접 출력하는 것도 가능하지만, 현재 🤗 트랜스포머에는 이 기능을 지원하는 모델이 없습니다.

## 결론[[conclusion]]

요약: 대부분의 오디오 트랜스포머 모델은 다른 점보다는 비슷한 점이 더 많은데, 일부 모델은 트랜스포머의 인코더 부분만 사용하고 다른 모델은 인코더와 디코더를 모두 사용하지만 모두 동일한 트랜스포머 아키텍처와 어텐션 레이어를 기반으로 구축됩니다.

또한 트랜스포머 모델에 오디오 데이터를 가져오고 내보내는 방법도 살펴봤습니다. ASR, TTS 등의 다양한 오디오 작업을 수행하려면 입력을 임베딩으로 전처리하는 레이어를 교체하고, 예측된 임베딩을 출력으로 후처리하는 레이어를 교체하면 되며, 트랜스포머 백본(backbone)은 그대로 유지하면 됩니다.

다음으로, 이러한 모델을 자동 음성 인식으로 학습시킬 수 있는 몇 가지 방법을 살펴보겠습니다.

### 오디오 분류 아키텍처[[audio-classification-architectures]]
https://huggingface.co/learn/audio-course/ko/chapter3/classification.md

# 오디오 분류 아키텍처[[audio-classification-architectures]]

오디오 분류의 목표는 오디오 입력에 대한 클래스 레이블을 예측하는 것입니다. 모델은 전체 입력 시퀀스를 포괄하는 단일 클래스 레이블을 예측하거나 모든 오디오 프레임(일반적으로 입력 오디오의 20밀리초마다)에 대한 레이블을 예측할 수 있으며, 이 경우 모델의 출력은 클래스 레이블 확률의 시퀀스입니다. 전자의 예로는 어떤 새가 특정 소리를 내는지 감지하는 것을 들 수 있고, 후자의 예로는 특정 순간에 어떤 화자가 말하는지 예측하는 화자 구분(speaker diarization)을 들 수 있습니다.

## 스펙트로그램을 사용한 분류[[classification-using-spectrograms]]

오디오 분류를 수행하는 가장 쉬운 방법 중 하나는 이미지 분류 문제인 것처럼 가정하는 것입니다!

스펙트로그램은 `(주파수, 시퀀스 길이)` 모양의 2차원 텐서라는 것을 기억하세요. [오디오 데이터 챕터](../chapter1/audio_data)에서 이러한 스펙트로그램을 이미지로 그려보았습니다. 여러분 아시나요? 말 그대로 스펙트로그램을 이미지로 취급하고 ResNet과 같은 일반 CNN 분류기 모델에 전달하면 매우 좋은 예측 결과를 얻을 수 있습니다. 더 좋은 방법은 ViT와 같은 이미지 트랜스포머 모델을 사용하는 것입니다.

이것이 바로 **오디오 스펙트로그램 트랜스포머**가 하는 일입니다. 이 모델은 ViT 또는 비전 트랜스포머 모델을 사용하며, 일반 이미지 대신 스펙트로그램을 입력으로 전달합니다. 트랜스포머의 셀프 어텐션 레이어 덕분에 이 모델은 CNN보다 글로벌 컨텍스트를 더 잘 포착할 수 있습니다.

ViT와 마찬가지로 AST(Audio Spectrogram Transformer) 모델은 오디오 스펙트로그램을 16×16픽셀의 부분적으로 겹치는 이미지 패치 시퀀스로 분할합니다. 그런 다음 이 패치 시퀀스는 일련의 임베딩으로 투영되고, 이 임베딩은 평소와 같이 트랜스포머 인코더에 입력으로 제공됩니다. AST는 인코더 전용 트랜스포머 모델이므로 출력은 16×16 입력 패치마다 하나씩 숨겨진 상태 시퀀스입니다. 여기에는 은닉 상태를 분류 확률에 매핑하기 위해 시그모이드 활성화가 포함된 간단한 분류 계층이 있습니다.

    

논문 [AST: 오디오 스펙트로그램 트랜스포머](https://arxiv.org/pdf/2104.01778.pdf)에서 가져온 이미지

💡 여기서는 스펙트로그램이 이미지와 동일하다고 가정하지만, 중요한 차이점이 있습니다. 예를 들어, 이미지의 내용을 위아래로 이동해도 일반적으로 이미지에 포함된 내용의 의미는 변하지 않습니다. 그러나 스펙트로그램을 위아래로 이동하면 소리에 포함된 주파수가 변경되어 소리의 성격이 완전히 달라집니다. 이미지는 변환 시에도 변하지 않지만 스펙트로그램은 그렇지 않습니다. 스펙트로그램을 이미지로 취급하는 것은 실제로는 매우 잘 작동할 수 있지만 실제로는 같은 것이 아니라는 점을 명심하세요.

## 모든 트랜스포머는 분류기가 될 수 있습니다.[[any-transformer-can-be-a-classifier]]

[이전 섹션](ctc)에서 CTC가 인코더 전용 트랜스포머를 사용하여 자동 음성 인식을 수행하는 데 효율적인 기술이라는 것을 살펴보았습니다.  이러한 CTC 모델은 이미 토큰화 어휘에서 클래스 레이블에 대한 확률을 예측하는 분류기입니다. 라벨을 변경하고 특수한 CTC 손실 대신 크로스 엔트로피 손실 함수로 훈련하면 CTC 모델을 범용 오디오 분류기로 전환할 수 있습니다.

예를 들어, HF 트랜스포머에는 `Wav2Vec2ForCTC` 모델뿐만 아니라 `Wav2Vec2ForSequenceClassification` 및 `Wav2Vec2ForAudioFrameClassification` 모델도 있습니다. 이러한 모델의 아키텍처 간의 유일한 차이점은 분류 계층의 크기와 사용되는 손실 함수입니다.

실제로 모든 인코더 전용 오디오 트랜스포머 모델은 은닉 상태 시퀀스 위에 분류 레이어를 추가하여 오디오 분류기로 전환할 수 있습니다. (분류기에는 일반적으로 트랜스포머 디코더가 필요하지 않습니다.)

전체 시퀀스에 대한 단일 분류 점수를 예측하기 위해 모델(Wav2Vec2ForSequenceClassification)에서는 숨겨진 상태의 평균을 구하여 분류 레이어에 입력합니다. 출력은 단일 확률 분포입니다.

각 오디오 프레임에 대해 별도의 분류를 만들기 위해, 분류기(Wav2Vec2ForAudioFrameClassification)는 은닉 상태의 시퀀스에서 실행되므로 분류기의 출력도 시퀀스입니다.

### CTC 아키텍처 [[ctc-architectures]]
https://huggingface.co/learn/audio-course/ko/chapter3/ctc.md

# CTC 아키텍처 [[ctc-architectures]]

연결주의 시간 분류(CTC, Connectionist Temporal Classification)는 자동 음성 인식을 위한 인코더 전용 트랜스포머 모델에 사용되는 기법입니다. 이러한 모델의 예로는 **Wav2Vec2**, **HuBERT** 및 **M-CTC-T**가 있습니다.

인코더 전용 트랜스포머는 모델의 인코더 부분만 사용하기 때문에 가장 간단한 종류의 트랜스포머입니다. 인코더는 입력 시퀀스(오디오 파형)를 읽고 이를 출력 임베딩이라고도 하는 은닉 상태 시퀀스로 매핑합니다.

CTC 모델을 사용하면 은닉 상태 시퀀스에 추가 선형 매핑을 적용하여 클래스 레이블 예측을 얻습니다. 클래스 레이블은 **알파벳 문자**(a, b, c, ...)입니다. 이렇게 하면 어휘가 26자와 몇 개의 특수 토큰으로만 존재하면 되기 때문에 작은 분류 헤드로 대상 언어의 모든 단어를 예측할 수 있습니다.

    

지금까지는 NLP에서 BERT와 같은 모델을 사용하는 것과 매우 유사합니다. 인코더 전용 트랜스포머 모델이 텍스트 토큰을 인코더 숨겨진 상태 시퀀스에 매핑한 다음 선형 매핑을 적용하여 각 숨겨진 상태에 대해 하나의 클래스 레이블 예측을 얻습니다.

음성에서는 오디오 입력과 텍스트 출력의 '정렬(alignment)'을 알 수 없다는 점이 문제입니다. 음성이 말하는 순서와 텍스트를 필사(transcribe)하는 순서가 같다는 것은 알지만(소위 단조로운 정렬의 경우), 필사하는 텍스트의 문자가 오디오와 어떻게 일치하는지는 알 수 없습니다. 바로 이 부분에서 CTC 알고리즘이 등장합니다.

💡 NLP 모델에서 어휘는 일반적으로 개별 문자뿐만 아니라 단어의 일부 또는 완전한 단어를 설명하는 수천 개의 토큰으로 구성됩니다. 그러나 CTC의 경우 작은 어휘가 가장 효과적이며 일반적으로 50자 미만으로 유지하려고 노력합니다. 트위터에서는 글자의 대소문자를 구분하지 않으므로 대문자(또는 소문자)만 사용해도 충분합니다. 숫자는 철자로 표기합니다(예: `"20"`은 `"twenty"`가 됩니다). 문자 외에도 최소한 단어 구분 토큰(공백)과 패딩 토큰이 필요합니다. 패딩 토큰은 자연어 처리 모델과 마찬가지로 여러 개의 예문을 일괄적으로 결합할 수 있게 해주지만, 모델이 무음을 예측할 때 사용하는 토큰이기도 합니다. 영어에서는 `'` 문자를 유지하는 것도 유용합니다. `it`s`와 `its`는 매우 다른 의미를 갖기 때문입니다.

## 정렬을 어떻게 확인하지?[[dude-wheres-my-alignment]]

자동 음성 인식(ASR)은 오디오를 입력으로 받아 텍스트를 출력으로 생성합니다. 텍스트를 예측하는 방법에는 몇 가지 선택지가 있습니다:

- 개별 문자로 인식
- 음소(phonemes)로 인식
- 단어 토큰으로 인식

자동 음성 인식 모델은 `(오디오, 텍스트)` 쌍으로 구성된 데이터 셋에 대해 학습되며, 텍스트는 오디오 파일의 사람이 만든 필사본입니다. 일반적으로 데이터 셋에는 오디오 파일에서 어떤 단어나 음절이 어디에 나오는지 알려주는 타이밍 정보가 포함되지 않습니다. 훈련 중에 타이밍 정보에 의존할 수 없기 때문에 입력과 출력 순서를 어떻게 정렬해야 하는지 알 수 없습니다.

입력이 1초짜리 오디오 파일이라고 가정해 봅시다. **Wav2Vec2** 모델에서는 먼저 CNN 피처 인코더를 사용하여 오디오 입력을 더 짧은 은닉 상태 시퀀스로 다운샘플링하는데, 여기에는 오디오 20밀리초당 하나의 은닉 상태 벡터가 있습니다. 오디오 1초에 대해 50개의 은닉 상태 시퀀스를 트랜스포머 인코더로 전달합니다.  (입력 시퀀스에서 추출된 오디오 세그먼트는 부분적으로 겹치므로 20밀리초마다 하나의 은닉 상태 벡터가 출력되지만 각 은닉 상태는 실제로 25밀리초의 오디오를 나타냅니다.)

트랜스포머 인코더는 이러한 숨겨진 상태 각각에 대해 하나의 특징 표현을 예측하므로 트랜스포머로부터 50개의 출력 시퀀스를 수신합니다. 이러한 각 출력의 차원은 768입니다. 따라서 이 예제에서 트랜스포머 인코더의 출력 시퀀스는 `(768, 50)` 모양을 갖습니다. 이러한 각 예측은 음소 지속 시간보다 짧은 25ms의 시간을 포함하므로 전체 단어가 아닌 개별 음소 또는 문자를 예측하는 것이 합리적입니다. CTC는 작은 어휘에서 가장 잘 작동하므로 문자를 예측해 보겠습니다.

    

텍스트 예측을 위해 768차원 인코더 출력 각각을 선형 레이어("CTC 헤드")를 사용하여 문자 레이블에 매핑합니다. 그런 다음 모델은 로그를 포함하는 `(50, 32)` 텐서(여기서 32는 어휘의 토큰 수)를 예측합니다. 시퀀스의 각 특징에 대해 하나의 예측을 수행하므로 오디오의 각 초에 대해 총 50개의 문자를 예측하게 됩니다.

그러나 단순히 20ms마다 한 문자를 예측한다면 출력 시퀀스는 다음과 같이 보일 수 있습니다:

```text
BRIIONSAWWSOMEETHINGCLOSETOPANICONHHISOPPONENT'SSFAACEWHENTHEMANNFINALLLYRREECOGGNNIIZEDHHISSERRRRORR ...
```

자세히 보면 영어와 다소 비슷하지만 많은 문자가 중복되어 있습니다. 이는 모델이 입력 시퀀스의 오디오 20밀리초마다 *어떤 것*을 출력해야 하기 때문이며, 한 문자가 20밀리초보다 긴 기간에 걸쳐 분산되어 있으면 출력에 여러 번 나타나게 됩니다. 특히 훈련 중에는 대본의 타이밍을 알 수 없기 때문에 이를 피할 방법이 없습니다. CTC는 이러한 중복을 필터링하는 방법입니다.

(실제로 예측된 시퀀스에는 모델이 소리가 무엇을 나타내는지 잘 모를 때나 문자 사이의 빈 공간을 위한 많은 패딩 토큰도 포함되어 있습니다. 명확성을 위해 예제에서 이러한 패딩 토큰을 제거했습니다. 오디오 세그먼트가 부분적으로 겹치는 것도 출력에서 문자가 중복되는 또 다른 이유입니다.)

## CTC 알고리즘[[the-ctc-algorithm]]

CTC 알고리즘의 핵심은 흔히 **공백 토큰**이라고 불리는 특수 토큰을 사용하는 것입니다. 이것은 모델이 예측하는 또 다른 토큰이며 어휘의 일부입니다. 이 예시에서 빈 토큰은 `_`로 표시됩니다. 이 특수 토큰은 문자 그룹 간의 엄격한 경계 역할을 합니다.

CTC 모델의 전체 출력은 다음과 같을 수 있습니다:

```text
B_R_II_O_N_||_S_AWW_|||||_S_OMEE_TH_ING_||_C_L_O_S_E||TO|_P_A_N_I_C_||_ON||HHI_S||_OP_P_O_N_EN_T_'SS||_F_AA_C_E||_W_H_EN||THE||M_A_NN_||||_F_I_N_AL_LL_Y||||_RREE_C_O_GG_NN_II_Z_ED|||HHISS|||_ER_RRR_ORR||||
```

토큰 `|`는 단어 구분 문자입니다. 이 예에서는 공백 대신 `|`를 사용하여 단어 나누기 위치를 더 쉽게 파악할 수 있도록 했지만 동일한 용도로 사용됩니다.

CTC 공백 문자를 사용하면 중복 문자를 필터링할 수 있습니다. 예를 들어 예측된 시퀀스의 마지막 단어인 `_ER_RRR_ORR`을 살펴봅시다. CTC 공백 토큰이 없으면 이 단어는 다음과 같이 보입니다:

```text
ERRRRORR
```

단순히 중복된 문자를 제거하면 `EROR`이 됩니다. 이는 분명 올바른 철자가 아닙니다. 하지만 CTC 빈 토큰을 사용하면 각 그룹에서 중복을 제거할 수 있습니다. 따라서:

```text
_ER_RRR_ORR
```

는 아래와 같이 변경됩니다.:

```text
_ER_R_OR
```

이제 `_` 빈 토큰을 제거하여 최종 단어를 얻습니다:

```text
ERROR
```

이 논리를 `|`를 포함한 전체 텍스트에 적용하고 남은 `|` 문자를 공백으로 바꾸면 최종 CTC 디코딩된 출력은 다음과 같습니다:

```text
BRION SAW SOMETHING CLOSE TO PANIC ON HIS OPPONENT'S FACE WHEN THE MAN FINALLY RECOGNIZED HIS ERROR
```

요약하자면, 모델은 입력 파형에서 (부분적으로 겹치는) 오디오의 20ms마다 하나의 토큰(문자)을 예측합니다. 이로 인해 많은 중복이 발생합니다. CTC 빈 토큰 덕분에 단어의 올바른 철자를 파괴하지 않고도 이러한 중복을 쉽게 제거할 수 있습니다. 이는 출력 텍스트를 입력 오디오와 정렬하는 문제를 해결하는 매우 간단하고 편리한 방법입니다.

💡 실제 Wav2Vec2 모델에서 CTC 빈 토큰은 패딩 토큰 ``와 동일합니다. 이 모델은 예를 들어 현재 20ms의 오디오에 대해 예측할 명확한 문자가 없는 경우와 같이 이러한 `` 토큰을 많이 예측합니다. 패딩에 CTC 공백(blanking)과 동일한 토큰을 사용하면 디코딩 알고리즘이 단순화되고 어휘를 작게 유지하는 데 도움이 됩니다.

인코더의 출력 시퀀스가 어휘에 음향 특징을 투영하는 선형 레이어로 이동하기 때문에 트랜스포머 인코더 모델에 CTC를 추가하는 것은 간단합니다.모델은 특수한 CTC 손실로 훈련됩니다.

CTC의 한 가지 단점은 '소리'는 정확하지만 '철자'는 정확하지 않은 단어를 출력할 수 있다는 점입니다.결국 CTC 헤드는 완전한 단어가 아닌 개별 문자만 고려하기 때문입니다. 오디오 트랜스크립션의 품질을 개선하는 한 가지 방법은 외부 언어 모델을 사용하는 것입니다. 이 언어 모델은 기본적으로 CTC 출력 위에 맞춤법 검사기 역할을 합니다.

## Wav2Vec2, HuBERT, M-CTC-T, ...의 차이점은 무엇인가요?[[whats-the-difference-between-wav2vec2-hubert-mctct]]

모든 트랜스포머 기반 CTC 모델은 매우 유사한 아키텍처를 가지고 있습니다. 트랜스포머 인코더(디코더는 아님)를 사용하며 그 위에 CTC 헤드가 있습니다. 아키텍처 측면에서 보면 다른 점보다는 비슷한 점이 더 많습니다.

Wav2Vec2와 M-CTC-T의 한 가지 차이점은 전자는 원시 오디오 파형에서 작동하는 반면 후자는 멜 스펙트로그램을 입력으로 사용한다는 점입니다. 또한 두 모델은 서로 다른 목적으로 훈련되었습니다. 예를 들어, M-CTC-T는 다국어 음성 인식을 위해 훈련되었기 때문에 다른 알파벳 외에 한자를 포함하는 비교적 큰 CTC 헤드를 가지고 있습니다.

Wav2Vec2와 HuBERT는 완전히 동일한 아키텍처를 사용하지만 매우 다른 방식으로 학습됩니다. Wav2Vec2는 오디오의 마스크된 부분에 대한 음성 단위를 예측하여 BERT의 마스크된 언어 모델링과 같이 사전 학습됩니다. HuBERT는 BERT에서 한 걸음 더 나아가 텍스트 문장의 토큰과 유사한 '개별 음성 단위'를 예측하는 방법을 학습하여 기존 NLP 기술을 사용하여 음성을 처리할 수 있도록 합니다.

여기서 강조 표시된 모델만 트랜스포머 기반 CTC 모델이 아니라는 점을 분명히 말씀드립니다. 다른 모델도 많이 있지만 모두 비슷한 방식으로 작동한다는 것을 배웠습니다.

### 허깅페이스 오디오 코스에 오신것을 환영합니다![[welcome-to-the-hugging-face-audio-course]]
https://huggingface.co/learn/audio-course/ko/chapter0/introduction.md

# 허깅페이스 오디오 코스에 오신것을 환영합니다![[welcome-to-the-hugging-face-audio-course]]

학습자 여러분,

트랜스포머 모델의 오디오 분야 적용에 대한 코스에 오신것을 환영합니다. 트랜스포머는 자연어 처리, 컴퓨터 비전, 최근에는 오디오 처리에 이르기까지 다양한 작업에서 최고의 성능을 달성하는 가장 강력하고 다재다능한 딥러닝 아키텍처 중 하나입니다.

이 코스에서는 트랜스포머를 오디오 데이터에 적용하는 방법을 살펴볼 것입니다. 여러분은 이를 사용하여 다양한 오디오 작업을 처리하는 방법을 배우게 됩니다. 음성 인식, 오디오 분류, 텍스트에서 음성 생성 같은 문제에 관심이 있다면 트랜스포머와 이 코스를 통해 해결할 수 있을것입니다.

이 모델로 어떤 작업이 가능한지 보여주기 위해 아래 데모를 준비했습니다. 데모에서 짧게 말한 후 실시간으로 받아쓰는 것을 확인해보세요!

코스를 진행하면서 여러분은 오디오 데이터작업의 세부사항들과 다양한 트랜스포머 아키텍처에 대해 배우고, 사전학습된 모델을 활용하여 여러분만의 오디오 트랜스포머를 훈련시킬 것입니다.

이 코스는 딥러닝에 대한 배경지식이 있고 트랜스포머에 대해 어느 정도 친숙한 학습자를 대상으로 설계되었습니다. 오디오 데이터 처리에 대한 전문지식은 필요하지 않습니다. 트랜스포머에 대한 이해가 필요하다면, 트랜스포머의 기초에 대한 저희의 [NLP 코스](https://huggingface.co/course/chapter1/1)를 참고하세요.

## 코스 팀 소개[[meet-the-course-team]]

**Sanchit Gandhi, Machine Learning Research Engineer at Hugging Face**

안녕하세요! 저는 Sanchit이고, 허깅페이스🤗의 오픈 소스 팀에서 오디오 분야의 기계 학습 리서치 엔지니어로 일하고 있습니다.
저의 주요 연구 분야는 자동 음성 인식과 번역으로, 음성 모델을 더 빠르고, 가볍고, 사용하기 쉽게 만드는 것을 목표로 하고 있습니다.

**Matthijs Hollemans, Machine Learning Engineer at Hugging Face**

안녕하세요, 저는 Matthijs입니다. 저는 허깅페이스의 오픈 소스 팀에서 오디오 분야의 기계 학습 엔지니어로 일하고 있습니다. 또한 사운드 신디사이저를 작성하는 방법에 대한 책의 저자이며, 여가 시간에 오디오 플러그인을 만듭니다.

**Maria Khalusova, Documentation & Courses at Hugging Face**

저는 Maria입니다. 트랜스포머와 기타 오픈 소스 도구를 더욱 접근하기 쉽게 만들기 위해 교육 콘텐츠와 문서를 만듭니다. 복잡한 기술 개념을 세분화하여 사람들이 최첨단 기술을 시작하는데 도움을 줍니다.

**Vaibhav Srivastav, ML Developer Advocate Engineer at Hugging Face**

저는 Vaibhav(VB)이고, 허깅페이스의 오픈 소스 팀에서 오디오 분야의 Developer Advocate 엔지니어로 일하고 있습니다. 저자원으로 텍스트를 음성으로 변환하는 연구를 하고 있으며, 최첨단 음성 연구를 대중에게 전달하는데 도움을 주고 있습니다.

## 코스 구성[[course-structure]]

이 코스는 다양한 주제를 심도 있게 다루는 여러 단원으로 구성되어 있습니다:

* 1단원: 오디오 처리 및 데이터 준비 등 오디오 데이터를 다루는 방법을 배웁니다.
* 2단원: 오디오의 응용방법을 알아보고, 오디오 분류 및 음성 인식과 같은 다양한 작업을 위해 🤗 트랜스포머 파이프라인을 사용하는 방법을 배웁니다.
* 3단원: 오디오 트랜스포머 아키텍처를 탐구하고, 그 차이를 배우며, 어떤 작업에 가장 적합한지 알아봅니다.
* 4단원: 여러분만의 음악 장르 분류기를 만듭니다.
* 5단원: 음성 인식에 대해 더 자세히 알아보고, 회의 녹음을 위한 모델을 만듭니다.
* 6단원: 텍스트에서 음성을 생성하는 방법을 배웁니다.
* 7단원: 트랜스포머를 이용하여 오디오에서 다른 오디오로 바꾸는 법을 배웁니다.

각 단원에는 기본 개념과 기술에 대해 깊이 있는 이해를 얻을 수 있는 이론적인 구성 요소가 포함되어 있습니다. 코스 전반에 걸쳐 여러분의 지식을 테스트하고 학습을 도와줄 퀴즈를 제공하며, 일부 장에는 배운 내용을 적용해 볼 수 있는 실습과제들(hands-on exercises)도 포함되어 있습니다.

이 코스를 마치면 여러분은 트랜스포머를 활용한 오디오 데이터 처리에 대한 탄탄한 기초를 갖추게 되며, 다양한 오디오 관련 작업에 이 기술을 적용할 수 있게될 것입니다.

코스의 단원들은 다음과 같은 게시일정에 따라 순차적으로 공개될 예정입니다:

| 단원 | 출시일 |
|---|-----------------|
| 0단원, 1단원, 2단원  | 2023년 6월 14일   |
| 3단원, 4단원  | 2023년 6월 21일   |
| 5단원  | 2023년 6월 28일   |
| 6단원  | 2023년 7월 5일    |
| 7단원, 8단원  | 2023년 7월 12일   |

[//]: # (| Bonus Unit  | TBD             |)

## 학습 경로 및 인증[[learning-paths-and-certification]]

이 코스를 수강하는 데 옳거나 그른 방법은 없습니다. 이 코스의 모든 자료는 100% 무료로 공개되며 오픈 소스입니다.
여러분은 자유롭게 진도를 나갈 수 있지만, 단원 순서대로 진행하는 것을 권장합니다.

코스 완료 시 인증을 받고 싶다면, 두 가지 옵션이 있습니다:

| 인증 유형 | 요구 사항 |
|---|-------------------------------------------------------------------------------------|
| Certificate of completion  | 2023년 7월 말까지 지침에 따라 실습과제의 80%를 완료하세요. |
| Certificate of honors  | 2023년 7월 말까지 지침에 따라 실습과제의 100%를 완료하세요. |

각각의 실습과제들에 완료 기준이 써있습니다. 인증을 받을 수 있을정도로 실습과제들을 충분히 풀었다면, 코스의 마지막 단원을 참조하여 인증서를 취득하는 방법을 알아보세요. 행운을 빕니다!

## 코스 등록하기[[sign-up-to-the-course]]

이 코스의 단원들은 몇 주에 걸쳐 점진적으로 공개될 예정입니다. 새로운 단원이 출시될때 놓치지 않도록 코스 업데이트에 등록하시는 것을 권유드립니다. 코스 업데이트에 등록한 사용자는 저희가 주최예정인 특별한 소셜 이벤트에 대해서도 가장 먼저 알게 됩니다.

[등록하기](http://eepurl.com/insvcI)

즐거운 학습 되세요!

### 커뮤니티에 참여해보세요![[join-the-community]]
https://huggingface.co/learn/audio-course/ko/chapter0/community.md

# 커뮤니티에 참여해보세요![[join-the-community]]

[활발하고 지원이 풍부한 우리의 디스코드 커뮤니티](http://hf.co/join/discord)에 여러분을 초대합니다. 여러분은 이곳에서 같은 생각을 가진 학습자들을 만나고, 아이디어를 교환하며, 실습 과제에 대한 소중한 피드백을 받으실 수 있습니다. 질문을 하고, 자료를 공유하며 다른 사람들과 협력을 해보세요.

우리 팀도 디스코드에서 활동하고 있으며 여러분께 지원과 안내를 해드립니다. 커뮤니티에 가입하는 것은 참여적이고 동기를 부여받을 수 있게 해주며 소통을 유지할 수 있는 훌륭한 방법입니다. 여러분을 커뮤니티에서 만나 뵙기를 기대합니다!

## 디스코드가 뭔가요?[[what-is-discord]]

디스코드는 무료 채팅 플랫폼입니다. 슬랙을 써보신적 있으시다면 그것과 비슷하다고 생각하시면 됩니다. 허깅페이스 디스코드 서버는 18,000명의 AI 전문가, 학습자 및 애호가로 구성된 활발한 커뮤니티로, 여러분도 참여하실 수 있습니다.

## 디스코드 탐색하기[[navigating-discord]]

디스코드 서버에 가입하시면 왼쪽의 `#role-assignment`를 클릭하여 관심있는 주제를 선택하셔야 합니다. 주제는 원하시는 만큼 선택하실 수 있으며 다른 학습자들과 같이하기 위해선 반드시 "ML for Audio and Speech"를 클릭하셔야 합니다.
채널을 살펴보고 `#introduce-yourself`에서 여러분을 소개해보세요.

## 오디오 코스 채널[[audio-course-channels]]

우리의 디스코드 서버에는 다양한 주제의 채널들이 있습니다. 논문에 대한 토론, 이벤트 꾸리기, 프로젝트와 아이디어 공유, 브레인스토밍 등 다양한 활동을 찾아보실 수 있습니다.

다음의 채널들은 오디오 코스 학습을 위해 관련이 있는 채널들입니다:

* `#audio-announcements`: 코스 업데이트, 허깅페이스의 오디오와 관련된 모든 뉴스들, 이벤트 공지 등을 전합니다.
* `#audio-study-group`: 아이디어를 교환하고 코스에 대한 질문과 토론을 합니다.
* `#audio-discuss`: 오디오와 관련된 일반적인 토론을 합니다.

`#audio-study-group` 외에도 자유롭게 자신의 학습 그룹을 만들어보세요. 함께 배우면 더 쉽습니다!

### 코스 준비하기[[get-ready-to-take-the-course]]
https://huggingface.co/learn/audio-course/ko/chapter0/get_ready.md

# 코스 준비하기[[get-ready-to-take-the-course]]

코스에 대한 기대가 크신가요? 이 페이지는 여러분이 바로 시작하실 수 있도록 준비를 도와드립니다.

## 1단계. 등록하기[[step-1-sign-up]]

모든 업데이트와 소셜 이벤트에 대한 최신 소식을 받아보려면 코스에 등록하세요.

[👉 등록하기](http://eepurl.com/insvcI)

## 2단계. Hugging Face 계정 만들기[[step-2-get-a-hugging-face-account]]

아직 허깅페이스 계정이 없다면, 계정을 만드세요(무료입니다). 실습과제 완료, 수료 인증, 사전학습 모델 탐색, 데이터셋에 접근 등을 위해 필요합니다.

[👉 HUGGING FACE 계정 생성](https://huggingface.co/join)

## 3단계. 기초지식 점검하기(필요한 경우)[[step-3-brush-up-on-fundamentals-if-you-need-to]]

우린 여러분이 딥러닝과 트랜스포머에 대해 대략적으로 이해를 하고 있다고 가정합니다. 트랜스포머에 대한 이해가 필요하다면 우리의 [NLP 코스](https://huggingface.co/course/chapter1/1)를 참고하세요.

## 4단계. 설정 확인하기[[step-4-check-your-setup]]

코스 자료를 보기 위해서는 다음이 필요합니다:
- 인터넷 연결이 가능한 컴퓨터
- 실습과제를 위한 [Google Colab](https://colab.research.google.com). 무료버전이면 충분합니다.

Google Colab을 사용해본적이 없으시다면, 이 [공식 소개 노트북](https://colab.research.google.com/notebooks/intro.ipynb)을 참고하세요.

## 5단계. 커뮤니티 참여하기[[step-5-join-the-community]]

동료 수강생들과 아이디어를 공유하고 허깅페이스팀과 연락할 수 있는 디스코드 서버에 가입하세요.

[👉 디스코드 참여](http://hf.co/join/discord)

이 디스코드 커뮤니티에 대해 더 알아보고 싶으시다면 [다음 페이지](community)를 참고하세요.
