본문 바로가기
딥러닝으로 하루하루 씹어먹기

딥러닝 STT 모델 - ESPNet (2 - 톺아보기)

by Yoo Sung Hyun 2021. 5. 24.
728x90

ESPNet 논문은, 분명히 기술적인 내용들이었지만, 서술형일 뿐이었고, 상세 기술들은 하나하나 조사하다보니 너무 복잡한 느낌이 들었다.

 

2021.05.14 - [논문으로 현업 씹어먹기] - 딥러닝 STT 모델 - ESPNet (1)

 

딥러닝 STT 모델 - ESPNet (1)

BERT부터 설명을 하려고 하긴 했는데, 이제 곧 업무가 시작되기도 할 것이며, 최근에 논문을 읽어본 ESPNet에 대해서 먼저 정리해보겠다. 서론 사실 이전 회사에서, 크롤링 -> Text Analysis(TA) -> Power BI

shyu0522.tistory.com

 

그럼 이 복잡하다면 복잡한 상세 알고리즘들을 어떻게 ESPNet처럼 합쳐서 수려하게 개발할 수 있었을까?

 

ESPNet 자체를 톺아보려고 했지만, 설치부터 Data Download, Loading등 전단위 기술이 패키지화 되어있었고, 심지어 도커를 사용할 것이냐, 안할 것이냐에 따라서도 봐야되는 구성이 완전히 달라졌기에, (파이썬 소스를 보기도 전에 쉘 스크립트부터 전부 이해해야 진행할 수 있을 것 같았음.)

 

비슷한 사상으로, 논문을 낸 다른사람이 없을까 찾아보다가, 운도 좋게 한국인이 논문과 소스를 전부 작성해서 올려놓은 레퍼런스를 보게되었다.

 

http://koreascience.or.kr/article/JAKO201919341608252.page

대단하신 서울대 통계학과 멤버 행님덜....ㄷㄷ

 

End-To-End의 아이디어만 가지고, ESPNet과는 살짝 결이 다르지만, ESPNet에서 자부하는 기술들은 전부 활용하여 개발해놓으셨더라.

단점은, TensorFlow 1.대 버전이어야하며, 필자는 RTX 3090을 사용하는데, 해당 CUDA에서는 이제 TensorFlow 1.대를 수정없이는 지원하지 않아서, 실제로 소스는 돌려보지 못하였고, 논문과 비교를 해가며, 추상적인 이론을 실제 소스 구체화로 어떻게 이어나갔는지를 파악해보기로 했다.

 

https://github.com/dltnwl/KoSR

 

dltnwl/KoSR

Contribute to dltnwl/KoSR development by creating an account on GitHub.

github.com

논문 가장 첫번째에 계시는 (Suji Lee)님의 git이다.

(DataSet까지 공개해주시다니 정말 감사할 다름이다. 심지어 본인이 스크래피로 크롤링 하신 것 같던데... 무한 감사합니다....)

 

ESPNet vs KoSR

언어

Torch vs TensorFlow 1.x

    - 심지어 Keras도 아니다.

 

전처리

Kaldi vs MFCC

    - Kaldi가 설정이 번거롭긴 하던데, (Linux만 지원 잘 되는 등.) 그래서 MFCC를 사용하신건지, 여튼 그렇다

X vs 자체자모분리

    - 자모분리 소스를 직접 구현해놓았고, CTC의 관측을 위한 BeamSearch역시 단어단위가 아닌, 자모단위로 되어야하므로 C소스로 구현되어있다.

 

알고리즘

CTCAtt vs CTCAtt

    - CTC/Att/CTCAtt를 전부 똑같이 짜놓았다.

    - Att는 KoSR쪽이 '바다나우모노토닉 어텐션'만 구현해놓았다. (아마 경험상 가장 잘 맞는거였겠지.)

    - CTC는 BeamSearch로 ESPNet과 동일하나, 단어가 아닌 자모로 Score를 낼 수 있도록 수정해놨다.

    - CTCAtt를 사용하면, tensorflow.nn.ctc_loss()와 바다나우모노토닉 어텐션의 결과로 나온 문자의 유사도를 Loss로 삼아서, 그 둘의 loss를 최소화 시킬 수 있는, Seq2Seq기반 BeamsearchDecoder를 학습시킬 수 있도록 Layer가 구성되게 된다.

 

학습 데이터 구성 방식

데이터는, ESPNet은 리눅스 환경이 없어서 테스트 못해보고, KoSR의 소스 톺아보기를 기본으로한 설명만 덧붙힌다.

KoSR의 학습 순서 자체가,

1. 변환음성 전체 특징화

2. 이미지+시계열 특징추출

3. 전체 추출값에 대한 실제 문장값 CTCAtt

4. CTCAtt Loss를 최소화하도록 Seq2Seq학습

이므로,

Encoder-Decoder 데이터를 따로 구성해줄 필요가 없다. SIMPLE!!!

(전체의 데이터를 음성을 바라보냐, 텍스트를 바라보냐의 차이로만 접근하기에.)

ESPNet에서 가장 자부하던 바가, 많은 설정 선택값과 CTCAtt의 사용이었는데,

 

 

해당 논문도 설정값이 조금 제한적일뿐 (덕분에 소스 이해는 훨씬 쉬웠다.), 로직 자체는 동일하다고 볼 수 있었다.

(심지어 자모분리 및 자모 BeamSearch에 대한 부분은 벤치마크해서 사용할 수도 있을 정도다.)

 

결과적으로는,

한 음성데이터의 전체를 MFCC로 이미지처럼 치환하고, 그것을 CNN-LSTM으로 마치 과거의 OCR 인식을 하듯이 Feature Extraction을 진행한 후, 해당 시계열의 MFCC이미지 특징에 대한, 단어의 순서와 위치 매핑을 CTC+Att로 채점하며, 그 채점점수가 가장 높게 될때까지 BeamSearch로 결정해나가면서, Seq2Seq의 W값을 학습시키게 된다.

(음성을 마치, OCR 처럼 생각해서, 해당 그림순서에 해당 단어가 최대한 잘 나오도록 학습시키는 기법처럼)

 

이번 소스 분석을 통해 느낀점,

  • CTC와 Att를 같이 이용하는 것은, 딱히 둘이 '상호보완'적인 관계라기보다는, '2가지의 관점'이 있으니, 둘 중에 현재 우리의 문제에 더 적합한 문제를 가중선택하여 활용하라. 라는 의미가 명확하게 와닿았다. (실제로 소스를 보면, 서로 보완적인 부분은 없으며, 완전히 개발자 가중치 선택에 맡긴다.)
  • ESPNet도 이런 스팩토그램 방식으로 접근하여 해결했을까? 그렇다면, 구현하기 크게 어려움이 없을 것 같은데...

아! 그리고 여기 논문에서는 베이즈 딥러닝을 자랑으로 꼽던데, 정작 중요한건 Dropout과 특성이 동일하다는 사실이고, 실제로 소스에도 DropoutWrapper의 variational_recurrent=True로만 사용되고, 딱히 특이사항은 없다는 점이다. (내가 소스를 잘못 이해한 것일까?)

이게 맞다면, 그냥 lstm 레이어별로 BatchNorm을 적용시키거나 하는 방식으로 또 고도화를 꿰차볼 수도 있겠다.

 

기발하면서도 좋은 접근이었던것 같다. CNN도 무겁게 사용하지 않으며, BeamSearch를 사용함으로써, 긴 문장에 대한 Attention 계산 속도문제도 해결되었다. CTC에서도 속도문제가 동일하게 해결되지 싶다.

 

ESPNet을 한번 예제로라도 돌려본다면, 슬슬 내가 구현해볼 수도 있을것 같은데, 리눅스 서버가 현재 가용한게 없어서 아쉽다....!! (Kaldi가 리눅스에서 잘 적용됨.)

 

ETC. 소스에서 4로 나누어떨어지는 정수로 xs를 이용하는 이유는 명확히는 잘 모르겠다. 아마 배열에 넣어서 bi-lstm을 2면으로 돌리니, 2(bi)*2면 = 4여서 결국 1만 따지고 볼라면 4로 나누어야 되지 않음일까? 라고 짐작해본다.

 또한, bi를 쓰더라도 말을 거꾸로 하는 경우는 없으므로, backward는 사용할 일이 없어 hidden_state는 forward만 활용하는 것으로 보이며, x는 그냥 결과 예측값에 해당하는 Feature 추출값이므로, 2개를 전부 합쳐서 활용하는 걸로 판단된다.

소스읽다가 이게 뭐지? 싶으면 참고들 하시길...

 


실제로 ESPNet을 구성하기위한 ctc_loss라던가 Attention이라던가, 변분 베이즈 딥러닝 구성 방식이 전부 torch 혹은 keras 모듈로 제공되기 때문에, 이 녀석들에 파라미터를 어떻게 집어넣고, 어느 위치에 집어넣느냐가 ESPNet을 구성할 줄 알고, 모르고의 차이정도나 되겠다.

728x90

댓글