https://ysg2997.tistory.com/51
[음성 인식 모델 프로젝트] 음성 데이터 시각화 및 특성 추출
본 포스팅에서는 실제 데이터를 바탕으로 음성 데이터 시각화와 음성 특징을 추출하는 방법을 알아보겠습니다.데이터활용하는 데이터는 AIHub에서 제공하는 '구음장애 음성인식 데이터'입니다(h
ysg2997.tistory.com
AI에 대해서 심도있는 학습 경험이 없는 나는, 위 티스토리에서 정말 많은 도움을 받았다. 감사합니다~!!
들어가며
음성을 통해 대화를 시도하고자 하는 청각장애인의 발화를 텍스트로 변환하기 위해서, 한국어 음성 인식 모델을 파인튜닝해보기로 했다.
활용 데이터
AI-Hub에 구음장애 음성인식 데이터를 활용하였다. 파인튜닝을 위해서는 청각장애인의 음성 녹음 데이터가 필요했으며, 본 데이터에서는 구음 장애 환자(뇌신경장애, 언어청각장애, 후두장애)들의 한국어 음성 녹음과 정보를 담고 있어 파인튜닝에 적합하다고 판단했다.
EDA
일단 샘플 데이터를 활용하여 EDA를 진행하여 제공되는 데이터의 형태를 파악했다.
데이터 전처리
1) 음성 데이터 발화-비발화 구간 분리하기
EDA를 통해서는 발화 구간과 비발화 구간이 존재한다는 것을 알 수 있었다. 그리고 나는 이 오디오 파일에서 발화와 비발화 구간을 분리하여 저장하는 작업을 수행해야 했다.
1) 침묵 구간 탐지
오디오 세그먼트에서 특정 길이 이상이며 특정 볼륨 이하인 침묵 구간의 시작점과 끝점을 밀리초 단위로 찾아내는 작업을 진행했다.
def detect_silence(audio_segment, min_silence_len=1000, silence_thresh=-40, seek_step=1):
# 중략
for i in slice_starts:
audio_slice = audio_segment[i:i + min_silence_len]
if audio_slice.dBFS < silence_thresh:
silence_starts.append(i)
# 후략
return silence_ranges
- min_silence_len(1000ms)과 silence_thresh(-40dB)는 침묵을 정의하는 매개변수이다.
2) 발화 구간 탐지
앞서 찾은 침묵 구간을 기반으로 나머지 구간을 발화 구간으로 지정했다.
def detect_nonsilent(audio_segment, min_silence_len=1000, silence_thresh=-40, seek_step=1):
# 침묵 구간 찾기
silent_ranges = detect_silence(audio_segment, min_silence_len, silence_thresh, seek_step)
seg_len = len(audio_segment)
nonsilent_ranges = []
last_end = 0
# 침묵 구간 사이를 발화 구간으로 지정
for start, end in silent_ranges:
if start > last_end:
nonsilent_ranges.append([last_end, start])
last_end = end
# 후략
return nonsilent_ranges
그리고 다음과 같이 정의된 함수들을 실제 파일에 적용하여 오디오를 분할하고 저장했다.
2) 분리된 음성 파일에 대응하는 텍스트 분리
주어진 오디오 파일에 대응하는 텍스트 데이터가 문장 단위로 제공되지 않았다. 그래서 이를 문장 단위로 분리하여 개별 .txt 파일로 저장하는 작업이 필요했다.
그래서 전체 전사 스크립트를 문장 단위로 나누는 정규 표현식을 작성하여 파일에 적용시켰다.
sentences = re.findall(r'[^.!?]+[.!?]', transcript)
다음 2가지 방법으로 데이터 전처리를 진행하였으며, 전처리된 음성 파일 세그먼트와 정규화된 텍스트 파일을 쌍을 맞추어 DataFrame으로 매핑시켰다. 따라서 파인튜닝에 적용할 수 있는 음성-텍스트 쌍 데이터가 완성된 것이다. 약 15,000개의 발화쌍을 생성했다.
베이스 모델
학습에는 OpenAI의 사전 학습된 Whisper 모델을 선정했다. Whisper는 대규모의 다양한 오디오 데이터로 학습되어, 여러 언어와 잡음 환경에서 강력한 일반화 성능을 보이는 SOTA 모델이다. 다양한 Whisper 모델 중 `whisper-small` 모델을 사용했다.

베이스라인 성능 평가
파인튜닝의 효과를 측정하기 위해, 파인튜닝을 전혀 하지 않은 원본 whisper-small 모델이 구음장애 데이터에 어느 정도의 성능을 보이는지 측정해보았다.
측정 지표
음성 인식을 평가하는 표준 지표인 `WER(Word Error Rate, 단어 오류율`과 `CER (Character Error Rate, 글자 오류율)`을 평가 지표로 잡았다. 두 지표 모두 값이 낮을 수록 인식 정확도가 높음을 의미한다.
평가 결과
데이터 처리에서 분리한 검증 데이터셋을 원본 모델로 추론한 결과, WER 78.97%, CER 73.62%로 매우 높은 오류율을 보였다. 이는 Whisper 모델이 특수한 발화를 전혀 이해하지 못함을 의미하며, 해당 도메인에 특화된 파인튜닝이 필요함을 시사한다.
파인튜닝 모델 설계

1) Full Fine-Tuning
Full Fine-Tuning은 말 그대로 모든 파라미터를 업데이트하는 방식이다. 이 기법은 모델의 모든 가중치를 조정하여 특정 작업에 맞게 성능을 개선한다. 전체 모델을 조정하기 때문에 메모리와 계산 자원이 많이 요구된다. 일반적인 딥러닝 모델을 학습하는 방법을 Full Fine-Tuning이라고 이해하면 된다.
2) Parameter-Efficient Fine-Tuning (PEFT)
PEFT는 모델의 모든 파라미터를 조정하지 않고, 특정 파라미터 집합만을 업데이트하여 모델을 튜닝하는 방법이다. 이는 계산 자원과 메모리 사용을 줄이면서도 효과적인 성능 개선을 제공한다. PEFT는 기존의 LLM 파라미터를 freeze 하고 선택된 부분만을 조정하여 훈련의 효율성을 높인다.
LoRA (Low-Rank Adaptation)

LoRA는 PEFT의 한 형태로, 모델의 특정 층에서 저 차원 행렬을 사용하여 파라미터를 조정한다. LoRA는 전체 모델을 업데이트하지 않고, 일부 파라미터만을 조정하여 효율적인 튜닝을 가능하게 한다.

위 그림에서 보는 것처럼, LoRA는 전체 weight는 고정해 두고, 대신 아래쪽에서 아주 적은 연산량을 필요로 하는 행렬만 학습한다. 그리고 최종 업데이트 되는 레이어는 두 개의 연산 결과를 합쳐서 구성한다.
QLoRA (Quantized LoRA)

QLoRA는 LoRA 기법의 확장으로, 모델 파라미터를 양자화하여 더 효율적으로 튜닝하는 방법이다. 양자화는 모델 파라미터를 낮은 정밀도로 표현하여 메모리와 계산 자원을 절약할 수 있게 해주는 기법이다.
QLoRA와 LoRA의 차이는 모델의 양자화 하나이다. 그렇기 때문에 학습 코드에 LoRA Tuning 코드에서 양자화하는 부분만 추가하면 된다.
QLoRA 기법 파인튜닝
Whisper-small 모델도 수백만개의 파라미터를 가지며, 전체를 학습하는 Full Fine-Tuning은 높은 GPU 메모리를 요구한다. 따라서 PEFT(Parameter-Efficient Fine-Tuning, 파라미터 효율적 파인튜닝) 기법 중 하나인 QLoRA를 채택하였다.
1) 8비트 양자화 (Quantization)
모델의 가중치를 32비트 부동 소수점에서 8비트 정수로 양자화해서 GPU 메모리 사용량을 획기적으로 줄였다.
2) LoRA (Low-Rank Adaptation) 적용
LoRA는 모델의 모든 가중치를 학습하는 대신, 가중치 행렬 옆에 작은 랭크(r)의 두 행렬을 추가하여 이 두 행렬만 학습하는 기법이다. 이는 학습해야 할 파라미터 수를 극적으로 줄여 학습 시간과 메모리 사용량을 절감하면서도, 모델의 원래 성능을 거의 유지하면서 새로운 데이터에 적응시킬 수 있다.
PEFT 라이브러리를 사용하여 LoRA 의 핵심 설정을 다음과 같이 정의했다.모델의 성능 최적화를 위해 Rank 값을 변경하며 비교 실험을 진행했다.
LoRA 설정
| 매개변수 | 값 | 설명 |
| r | 8, 16 | LoRA의 랭크이다. 이 값이 낮을수록 학습 파라미터가 적다. |
| lora_alpha | 32, 64 | 스케일링 파라미터로 r 값보다 크거나 같게 설정하여 학습 강도를 조절한다. |
| target_modules | ["q_proj", "v_proj"] | LoRA를 적용할 모듈이다. Whisper의 Attention 레이어의 Query와 Value 가중치에만 적용하여 효율을 극대화했다. |
| lora_dropout | 0.05 | 학습 중 과적합을 방지하기 위한 드롭아웃 비율이다. |
Rank를 16으로 설정한 실험 2에서는 Rank가 8인 실험 1에 비해 약 2배 더 많은 LoRA 파라미터를 학습했다.
실험 결과 비교 분석
두 모델을 각 10Epoch 동안 훈련시킨 후, 검증 데이터셋에서 기록된 최고 성능을 비교 분석했다.
| 모델 | Best WER (%) | Best CER (%) |
| 베이스라인 | 98.97 | 93.62 |
| 실험 1 (r = 8, 알파 = 32) | 43.81 | 20.08 |
| 실험 2 (r = 16, 알파 = 64) | 44.85 | 20.61 |
파인튜닝 결과, 베이스라인 모델 대비 많은 성능 개선을 보였다. 이는 LoRA 파인튜닝이 구음장애 음성 데이터셋에 효과적으로 적응했음을 입증한다. 또한, 학습 파라미터수를 2배 늘렸음에도 성능 향상이 크지 않았기에 r=8인 실험 1을 최종 모델로 선정했다.
참고로, 한국어는 WER에 적합한 지표는 아니라고 한다. 한국어는 '밥을 먹었다' 처럼 명사 뒤에 조사가 붙어 하나의 단어를 이루기 때문에 모델이 '밥을' 이라는 것을 '밥 을'로 띄어쓰거나 '이다' 를 '이 다'로 잘못 인식하면 단어 하나가 통째로 틀린 것으로 계산되어 WER이 확 올라간다. 그래서 WER이 높더라도 CER이 낮으면 그 모델은 글자 하나하나의 소리는 잘 듣고 있다고 이해하면 된다.
'프로젝트 > handDoc' 카테고리의 다른 글
| [Spring] 공공데이터 API를 DB에 저장하기 (0) | 2025.10.13 |
|---|---|
| [AI] 수어 동작 인식 모델 만들기 - CNN과 LSTM (0) | 2025.10.01 |
| [Spring] WebRTC 정리 - 시그널링 서버와 STUN/TURN 서버 (0) | 2025.09.08 |
| [Spring] NAVER CLOVA CSR 적용하여 음성을 텍스트로 변환하기 (0) | 2025.08.15 |
| [Spring] MongoDB Atlas 설정하기 (0) | 2025.08.04 |