Skip to content

exphon/kfaligner

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

12 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

KFaligner - Korean Forced Aligner

License Python HTK

KFalignerλŠ” HTK(Hidden Markov Model Toolkit) 기반의 ν•œκ΅­μ–΄ κ°•μ œ μ •λ ¬(Forced Alignment) μ‹œμŠ€ν…œμž…λ‹ˆλ‹€. μŒμ„± 파일과 전사 ν…μŠ€νŠΈλ₯Ό μž…λ ₯λ°›μ•„ μŒμ†Œ(phoneme) 및 단어(word) λ‹¨μœ„μ˜ μ •ν™•ν•œ μ‹œκ°„ μ •λ ¬ 정보λ₯Ό Praat TextGrid ν˜•μ‹μœΌλ‘œ 좜λ ₯ν•©λ‹ˆλ‹€.

πŸ“‹ λͺ©μ°¨

🎯 μ£Όμš” κΈ°λŠ₯

  • μžλ™ μŒμ†Œ μ •λ ¬: ν•œκ΅­μ–΄ μŒμ„±κ³Ό ν…μŠ€νŠΈλ₯Ό μŒμ†Œ λ‹¨μœ„λ‘œ μ •ν™•ν•˜κ²Œ μ •λ ¬
  • 닀쀑 μƒ˜ν”Œλ ˆμ΄νŠΈ 지원: 8kHz, 11.025kHz, 16kHz μŒμ„± 파일 처리
  • μžλ™ λ¦¬μƒ˜ν”Œλ§: Praat 슀크립트λ₯Ό μ΄μš©ν•œ 16kHz μžλ™ λ³€ν™˜
  • TextGrid 좜λ ₯: Praatμ—μ„œ λ°”λ‘œ μ‚¬μš© κ°€λŠ₯ν•œ ν‘œμ€€ ν˜•μ‹
  • 사전 μžλ™ ν™•μž₯: 미등둝 단어에 λŒ€ν•œ 발음 사전 μžλ™ 생성
  • μ›Ή μΈν„°νŽ˜μ΄μŠ€: Flask 기반 μ›Ή μ• ν”Œλ¦¬μΌ€μ΄μ…˜ 제곡
  • Short Pause (sp) 처리: 단어 μ‚¬μ΄μ˜ νœ΄μ§€λ₯Ό 별도 κ΅¬κ°„μœΌλ‘œ 뢄리
  • λ©€ν‹° Tier TextGrid: phone/word/syllable/utterance tier 생성 및 ν•œκΈ€ 라벨 지원

πŸ“– μ‚¬μš©λ²•

κΈ°λ³Έ μ‚¬μš©λ²• (web interface)

http://210.125.93.241:5010/

κΈ°λ³Έ μ‚¬μš©λ²• (μ»€λ§¨λ“œλΌμΈ)

python3 align.py <audio.wav> <transcript.lab> <output.TextGrid>

μ˜ˆμ‹œ:

python3 align.py test/mv01_t01_s01.wav test/mv01_t01_s01.lab test/mv01_t01_s01.TextGrid

μž…λ ₯ 파일 ν˜•μ‹

1. μŒμ„± 파일 (.wav)

  • μƒ˜ν”Œλ ˆμ΄νŠΈ: 16000 Hz (ꢌμž₯)
    • 8000 Hz, 11025 Hz도 지원 (μžλ™ λͺ¨λΈ 선택)
    • λ‹€λ₯Έ μƒ˜ν”Œλ ˆμ΄νŠΈλŠ” μžλ™μœΌλ‘œ 16kHz둜 λ¦¬μƒ˜ν”Œλ§
  • 채널: λͺ¨λ…Έ (Mono)
  • λΉ„νŠΈ 깊이: 16-bit PCM

2. 전사 파일 (.lab)

  • 인코딩: UTF-8
  • ν˜•μ‹: ν•œκ΅­μ–΄ μ² μžλ²• ν…μŠ€νŠΈ (ν•œ 쀄)
  • μ˜ˆμ‹œ: 기차도 정이도 μ—†μ—ˆλ‹€

좜λ ₯ 파일 ν˜•μ‹

TextGrid 파일 (Praat ν˜Έν™˜):

  • phone tier: μŒμ†Œ λ‹¨μœ„ μ •λ ¬ (gg, i, c, a, d, o, ...)
  • syllable tier: ν•œκ΅­μ–΄ 음절 κ·œμΉ™(CV(C)) 기반의 μžλ™ 음절 경계
  • word tier: 단어 λ‹¨μœ„ μ •λ ¬ 및 (ν•œκΈ€ μž…λ ₯ μ‹œ) 원문 라벨 ν‘œμ‹œ
  • utterance tier: sil 사이 ꡬ간을 λ¬Έμž₯ λ‹¨μœ„λ‘œ ν•©μΉ˜λ©° ν•œκΈ€ 라벨 ν‘œμ‹œ
  • 경계 ν‘œμ‹œ: sil (silence), sp (short pause)

KFaligner TextGrid output

πŸ’» μ‹œμŠ€ν…œ μš”κ΅¬μ‚¬ν•­

ν•„μˆ˜ μš”κ΅¬μ‚¬ν•­

  • Python: 3.6 이상
  • HTK: 3.4.1 (Hidden Markov Model Toolkit)
  • Praat: μŒμ„± 뢄석 및 λ¦¬μƒ˜ν”Œλ§μš© (선택사항)
  • OS: Linux (Ubuntu 20.04+ ꢌμž₯)

Python νŒ¨ν‚€μ§€

flask>=2.0.0
gunicorn>=20.0.0
numpy

πŸš€ μ„€μΉ˜

1. μ €μž₯μ†Œ 클둠

git clone https://github.com/exphon/kfaligner.git
cd kfaligner

2. HTK μ„€μΉ˜

HTKλŠ” λΌμ΄μ„ μŠ€ μ œμ•½μœΌλ‘œ 직접 λ‹€μš΄λ‘œλ“œκ°€ ν•„μš”ν•©λ‹ˆλ‹€:

  1. HTK 곡식 μ‚¬μ΄νŠΈμ—μ„œ HTK-3.4.1 λ‹€μš΄λ‘œλ“œ
  2. μ••μΆ• ν•΄μ œ 및 컴파일:
tar -xvf HTK-3.4.1.tar.gz
cd htk
./configure --prefix=/usr/local
make all
sudo make install

3. Python ν™˜κ²½ μ„€μ •

# κ°€μƒν™˜κ²½ 생성 (ꢌμž₯)
python3 -m venv venv
source venv/bin/activate

# νŒ¨ν‚€μ§€ μ„€μΉ˜
pip install -r requirements.txt  # requirements.txtκ°€ μžˆλŠ” 경우
# λ˜λŠ”
pip install flask gunicorn numpy

πŸ“– μ‚¬μš©λ²•

κΈ°λ³Έ μ‚¬μš©λ²• (μ»€λ§¨λ“œλΌμΈ)

python3 align.py <audio.wav> <transcript.lab> <output.TextGrid>

μ˜ˆμ‹œ:

python3 align.py test/mv01_t01_s01.wav test/mv01_t01_s01.lab output.TextGrid

μž…λ ₯ 파일 ν˜•μ‹

1. μŒμ„± 파일 (.wav)

  • μƒ˜ν”Œλ ˆμ΄νŠΈ: 16000 Hz (ꢌμž₯)
    • 8000 Hz, 11025 Hz도 지원 (μžλ™ λͺ¨λΈ 선택)
    • λ‹€λ₯Έ μƒ˜ν”Œλ ˆμ΄νŠΈλŠ” μžλ™μœΌλ‘œ 16kHz둜 λ¦¬μƒ˜ν”Œλ§
  • 채널: λͺ¨λ…Έ (Mono)
  • λΉ„νŠΈ 깊이: 16-bit PCM

2. 전사 파일 (.lab)

  • 인코딩: UTF-8
  • ν˜•μ‹: ν•œκ΅­μ–΄ μ² μžλ²• ν…μŠ€νŠΈ (ν•œ 쀄)
  • μ˜ˆμ‹œ: 기차도 정이도 μ—†μ—ˆλ‹€

λ¦¬μƒ˜ν”Œλ§ (μ˜΅μ…˜)

16kHzκ°€ μ•„λ‹Œ μŒμ„± νŒŒμΌμ€ Praat 슀크립트둜 λ³€ν™˜:

# Praat 슀크립트 μ‹€ν–‰
praat --run resampleTo16000.praat input.wav output_16k.wav

사전에 μ—†λŠ” 단어 μΆ”κ°€

# λ¬Έμž₯ 리슀트 파일 μ€€λΉ„ (flist.txt)
echo "μƒˆλ‘œμš΄ λ¬Έμž₯λ“€" > flist.txt

# 사전 생성 및 μΆ”κ°€
./make_dict.sh flist.txt

이 μŠ€ν¬λ¦½νŠΈλŠ” bin/ λ””λ ‰ν† λ¦¬μ˜ 도ꡬλ₯Ό μ‚¬μš©ν•˜μ—¬:

  1. ν•œκΈ€μ„ μœ λ‹ˆμ½”λ“œλ‘œ λ³€ν™˜
  2. μŒμ†Œ μ‹œν€€μŠ€ 생성
  3. κΈ°μ‘΄ 사전에 병합

πŸ“ ν”„λ‘œμ νŠΈ ꡬ쑰

kfaligner/
β”œβ”€β”€ align.py                    # 메인 μ •λ ¬ 슀크립트
β”œβ”€β”€ __init__.py                 # Python νŒ¨ν‚€μ§€ μ΄ˆκΈ°ν™”
β”œβ”€β”€ restart.sh                  # μ„œλ²„ 관리 슀크립트
β”œβ”€β”€ make_dict.sh               # 사전 생성 슀크립트
β”œβ”€β”€ resampleTo16000.praat      # λ¦¬μƒ˜ν”Œλ§ Praat 슀크립트
β”œβ”€β”€ check_alignment.praat      # μ •λ ¬ κ²°κ³Ό 검증 슀크립트
β”‚
β”œβ”€β”€ bin/                        # μœ ν‹Έλ¦¬ν‹° 슀크립트
β”‚   β”œβ”€β”€ make_kdict.py          # ν•œκ΅­μ–΄ 사전 생성기
β”‚   β”œβ”€β”€ add_dict.py            # 사전 μΆ”κ°€ 도ꡬ
β”‚   β”œβ”€β”€ kdictmap.py            # μŒμ†Œ λ§€ν•‘
β”‚   β”œβ”€β”€ han2uniconversion.py   # ν•œκΈ€-μœ λ‹ˆμ½”λ“œ λ³€ν™˜
β”‚   β”œβ”€β”€ convert_sentences_unicode.py
β”‚   β”œβ”€β”€ dict                   # 발음 사전
β”‚   β”œβ”€β”€ kdict0.txt             # κΈ°λ³Έ ν•œκ΅­μ–΄ 사전
β”‚   └── kdict1.txt             # ν™•μž₯ 사전
β”‚
β”œβ”€β”€ model/                      # HTK 음ν–₯ λͺ¨λΈ
β”‚   β”œβ”€β”€ dict                   # 메인 발음 사전 (5,589+ 단어)
β”‚   β”œβ”€β”€ monophones             # μŒμ†Œ λͺ©λ‘
β”‚   └── 16000/                 # 16kHz λͺ¨λΈ
β”‚       β”œβ”€β”€ hmmdefs            # HMM μ •μ˜
β”‚       β”œβ”€β”€ macros             # 맀크둜 μ •μ˜
β”‚       └── config             # HTK μ„€μ •
β”‚
β”œβ”€β”€ test/                       # ν…ŒμŠ€νŠΈ 파일
β”‚   β”œβ”€β”€ *.wav                  # μƒ˜ν”Œ μŒμ„± 파일
β”‚   β”œβ”€β”€ *.lab                  # μƒ˜ν”Œ 전사 파일
β”‚   └── *.TextGrid             # 좜λ ₯ μ˜ˆμ‹œ
β”‚
β”œβ”€β”€ webapp/                     # Flask μ›Ή μ• ν”Œλ¦¬μΌ€μ΄μ…˜
β”‚   β”œβ”€β”€ app.py                 # 메인 μ• ν”Œλ¦¬μΌ€μ΄μ…˜
β”‚   β”œβ”€β”€ forms.py               # μ›Ή 폼 μ •μ˜
β”‚   β”œβ”€β”€ models.py              # λ°μ΄ν„°λ² μ΄μŠ€ λͺ¨λΈ
β”‚   β”œβ”€β”€ templates/             # HTML ν…œν”Œλ¦Ώ
β”‚   β”‚   β”œβ”€β”€ index.html
β”‚   β”‚   β”œβ”€β”€ login.html
β”‚   β”‚   β”œβ”€β”€ signup.html
β”‚   β”‚   └── results.html
β”‚   └── data/                  # μ—…λ‘œλ“œ 및 μž‘μ—… 데이터
β”‚       β”œβ”€β”€ users.db           # μ‚¬μš©μž λ°μ΄ν„°λ² μ΄μŠ€
β”‚       β”œβ”€β”€ uploads/           # μ—…λ‘œλ“œλœ 파일
β”‚       └── jobs/              # 처리 μž‘μ—… 디렉토리
β”‚
β”œβ”€β”€ tmp/                        # μž„μ‹œ 처리 파일
β”‚   β”œβ”€β”€ tmp.mlf                # μž…λ ₯ MLF
β”‚   β”œβ”€β”€ aligned.mlf            # HVite 좜λ ₯
β”‚   └── *.mfc                  # MFCC νŠΉμ§• 파일
β”‚
└── examples/                   # 예제 파일
    └── code.scp               # 파일 리슀트 μ˜ˆμ‹œ

🌐 μ›Ή μ• ν”Œλ¦¬μΌ€μ΄μ…˜

μ„œλ²„ μ‹œμž‘

# 개발 μ„œλ²„ (5010 포트)
cd webapp
python3 app.py

# ν”„λ‘œλ•μ…˜ μ„œλ²„ (Gunicorn + Systemd)
sudo systemctl start kfaligner
sudo systemctl enable kfaligner

# μ„œλ²„ 관리 슀크립트 μ‚¬μš©
./restart.sh start|stop|restart|reload|status

μ›Ή μΈν„°νŽ˜μ΄μŠ€ μ ‘κ·Ό

http://localhost:5010

μ£Όμš” κΈ°λŠ₯

  • 파일 μ—…λ‘œλ“œ: WAV + LAB 파일 λ™μ‹œ μ—…λ‘œλ“œ
  • 배치 처리: μ—¬λŸ¬ 파일 λ™μ‹œ μ •λ ¬
  • κ²°κ³Ό λ‹€μš΄λ‘œλ“œ: TextGrid 파일 λ‹€μš΄λ‘œλ“œ
  • μ‚¬μš©μž 관리: νšŒμ›κ°€μž…/둜그인 μ‹œμŠ€ν…œ
  • μž‘μ—… νžˆμŠ€ν† λ¦¬: κ³Όκ±° μ •λ ¬ κ²°κ³Ό 쑰회

ν™˜κ²½ λ³€μˆ˜ μ„€μ •

# webapp/app.py λ˜λŠ” systemd μ„œλΉ„μŠ€μ—μ„œ
export MAX_CONTENT_LENGTH_MB=64        # μ΅œλŒ€ μ—…λ‘œλ“œ 크기
export MAX_FILES_PER_REQUEST=100       # μ΅œλŒ€ 파일 수
export ENABLE_CLAMAV_SCAN=1            # λ°”μ΄λŸ¬μŠ€ μŠ€μΊ” ν™œμ„±ν™”

πŸ”§ 기술 세뢀사항

HTK 기반 κ°•μ œ μ •λ ¬

KFalignerλŠ” HViteλ₯Ό μ‚¬μš©ν•œ Viterbi 정렬을 μˆ˜ν–‰ν•©λ‹ˆλ‹€:

HVite -T 1 -a -m \
      -I tmp/tmp.mlf \
      -H model/16000/macros \
      -H model/16000/hmmdefs \
      -S tmp/test.scp \
      model/dict \
      model/monophones \
      > tmp/aligned.mlf

μ£Όμš” μ˜΅μ…˜:

  • -T 1: 트레이슀 레벨 (디버깅)
  • -a: μŒμ†Œ 경계 좜λ ₯
  • -m: λͺ¨λΈ μ‚¬μš©
  • -I: μž…λ ₯ MLF (Master Label File)
  • -H: HMM μ •μ˜ 파일

TextGrid 닀쀑 Tier 생성

  • readAlignedMLF()μ—μ„œ 단어 끝 spλ₯Ό λΆ„λ¦¬ν•œ ν›„, writeTextGrid()μ—μ„œ phone, syllable, word, utterance tierλ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.
  • _build_syllable_intervals()λŠ” 둜마자 μŒμ†Œμ—΄μ„ 기반으둜 ν•œκ΅­μ–΄ 음절 경계λ₯Ό μΆ”μ •ν•©λ‹ˆλ‹€.
  • _build_utterance_intervals()λŠ” sil 사이 ꡬ간을 ν•˜λ‚˜μ˜ λ°œν™”λ‘œ λ¬Άκ³ , ν•œκΈ€ μ „μ‚¬μ—μ„œ λ³€ν™˜λœ 원문 λ¬Έμžμ—΄μ„ 라벨둜 μ‚¬μš©ν•©λ‹ˆλ‹€.
  • ν•œκΈ€ μž…λ ₯ μ‹œ _build_display_map()이 둜마자/ν•œκΈ€ 맀핑을 λ§Œλ“€μ–΄ wordΒ·utterance tierμ—μ„œ ν•œκΈ€ 라벨을 좜λ ₯ν•©λ‹ˆλ‹€.

Short Pause (sp) 처리

문제: HTK의 spλŠ” tee-model (1-state)둜 sil의 쀑간 μƒνƒœλ₯Ό κ³΅μœ ν•©λ‹ˆλ‹€.

ν•΄κ²° 방법 (2025-10-09 μ—…λ°μ΄νŠΈ):

  1. 사전: λͺ¨λ“  단어가 sp둜 끝남 (5,589 단어)
  2. MLF: sp μ‚½μž… μ—†μŒ, sil만 λ¬Έμž₯ μ–‘ 끝에
  3. ν›„μ²˜λ¦¬: readAlignedMLF()μ—μ„œ 단어 끝 spλ₯Ό 별도 ν•­λͺ©μœΌλ‘œ 뢄리
# align.py Line 196-205
for wrd in ret:
    if len(wrd) > 1 and wrd[-1][0] == 'sp':
        sp_entry = wrd.pop()  # spλ₯Ό λ‹¨μ–΄μ—μ„œ 뢄리
        separated_ret.append(wrd)  # λ‹¨μ–΄λ§Œ
        separated_ret.append(['sp', sp_entry])  # sp 별도

κ²°κ³Ό: 단어 μ‚¬μ΄μ˜ pauseκ°€ 별도 κ΅¬κ°„μœΌλ‘œ TextGrid에 ν‘œμ‹œλ©λ‹ˆλ‹€.

μŒμ†Œ 체계

ν•œκ΅­μ–΄ 둜마자 ν‘œκΈ° 기반 μŒμ†Œ:

  • 자음: gg, dd, bb, jj, ss, k, t, p, c, h, g, d, b, j, m, n, ng, r, s
  • λͺ¨μŒ: a, eo, o, u, eu, i, ae, e, wa, weo, wo, we, oe, wi, ui, ya, yeo, yo, yu, yae, ye
  • 특수: sil (silence), sp (short pause)

지원 μƒ˜ν”Œλ ˆμ΄νŠΈ

μƒ˜ν”Œλ ˆμ΄νŠΈ λͺ¨λΈ 디렉토리 μžλ™ λ³€ν™˜
8000 Hz model/8000/ βœ…
11025 Hz model/11025/ βœ…
16000 Hz model/16000/ -
기타 - β†’ 16000 Hz

πŸ› 문제 ν•΄κ²°

1. "dur<=0" μ—λŸ¬

증상: HViteκ°€ ERROR [+8522] LatFromPaths: Align have dur<=0 좜λ ₯

원인: spκ°€ MLF와 사전 μ–‘μͺ½μ— μžˆμ–΄ tee-model 좩돌

ν•΄κ²°:

  • between_token = None μ„€μ • (MLF에 sp μ‚½μž… μ•ˆ 함)
  • μ‚¬μ „μ—λ§Œ sp μœ μ§€

2. 쀑볡 sil 토큰

증상: λ¬Έμž₯ μ‹œμž‘/끝에 sil sil λ‚˜νƒ€λ‚¨

원인: -b sil μ˜΅μ…˜ + MLF의 sil = 쀑볡

ν•΄κ²°: HViteμ—μ„œ -b μ˜΅μ…˜ 제거

3. 사전에 μ—†λŠ” 단어

증상: νŠΉμ • λ‹¨μ–΄μ—μ„œ μ •λ ¬ μ‹€νŒ¨

ν•΄κ²°:

# μžλ™ 사전 생성
./make_dict.sh flist.txt

# λ˜λŠ” μˆ˜λ™ μΆ”κ°€
python3 bin/make_kdict.py

4. μƒ˜ν”Œλ ˆμ΄νŠΈ 뢈일치

증상: μ •λ ¬ ν’ˆμ§ˆ μ €ν•˜ λ˜λŠ” μ‹€νŒ¨

ν•΄κ²°:

# Praat으둜 λ¦¬μƒ˜ν”Œλ§
praat --run resampleTo16000.praat input.wav output.wav

# λ˜λŠ” sox μ‚¬μš©
sox input.wav -r 16000 output.wav

5. μ›Ήμ•± μ—…λ‘œλ“œ μ‹€νŒ¨

증상: "Maximum file size exceeded"

ν•΄κ²°:

# app.py λ˜λŠ” ν™˜κ²½λ³€μˆ˜ μˆ˜μ •
export MAX_CONTENT_LENGTH_MB=128

# Nginx μ„€μ • (ν”„λ‘μ‹œ μ‚¬μš© μ‹œ)
client_max_body_size 128M;

πŸ™ κ°μ‚¬μ˜ 말

이 ν”„λ‘œμ νŠΈλŠ” λ‹€μŒ κΈ°μˆ μ„ 기반으둜 ν•©λ‹ˆλ‹€:

  • HTK (Hidden Markov Model Toolkit): Cambridge University Engineering Department
  • Praat: Paul Boersma and David Weenink
  • Flask: Pallets Projects

πŸ‘€ μ €μž

Tae-Jin Yoon
Sungshin Women's University Β© January 2016-2025

πŸ“§ 문의

ν”„λ‘œμ νŠΈ κ΄€λ ¨ λ¬Έμ˜μ‚¬ν•­μ΄λ‚˜ 버그 λ¦¬ν¬νŠΈλŠ” GitHub Issuesλ₯Ό μ΄μš©ν•΄μ£Όμ„Έμš”:
https://github.com/exphon/kfaligner/issues

πŸ“„ λΌμ΄μ„ μŠ€

이 ν”„λ‘œμ νŠΈλŠ” MIT λΌμ΄μ„ μŠ€ ν•˜μ— λ°°ν¬λ©λ‹ˆλ‹€. μžμ„Έν•œ λ‚΄μš©μ€ LICENSE νŒŒμΌμ„ μ°Έμ‘°ν•˜μ„Έμš”.


⭐ 이 ν”„λ‘œμ νŠΈκ°€ μœ μš©ν•˜λ‹€λ©΄ Starλ₯Ό λˆŒλŸ¬μ£Όμ„Έμš”!

About

Korean forced aligner

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors