기록하는삶

[파이썬/Python] 한국어 STT, kospeech 활용기(3) _ 학습을 위한 코드 수정, configs 변경 본문

AI/kospeech(한국어 STT)

[파이썬/Python] 한국어 STT, kospeech 활용기(3) _ 학습을 위한 코드 수정, configs 변경

mingchin 2021. 12. 28. 16:29
728x90
반응형

지난 글: https://mingchin.tistory.com/221

 

[파이썬/Python] 한국어 STT, kospeech 활용기(2) _ 폴더 위치 변경 및 모듈 설치

지난 글: https://mingchin.tistory.com/201 [파이썬/Python] 한국어 STT, kospeech 활용기(1) _ 단어 사전 및 transcript.txt 생성하기 오늘부터 몇 개로 나누어 작성할 글은 kospeech가 제공하는 모델 중 deepsp..

mingchin.tistory.com

① 데이터 갯수 설정 (+ augmentation 여부 선택)

필요한 모듈들을 모두 설치하고 나니, 학습 실행 과정에서 다음과 같은 오류를 만날 수 있었다.

마찬가지로, 가장 아래 에러의 발생지를 찾아가 코드를 뜯어봐야한다.

이 부분인데, zip(*tmp) 실행 시 tmp가 비어있다는 것이다. 즉, audio_path(음성 파일 이름), transcripts(전사), augment_methods(증강 여부 _ kospeech 안에서는 단순히 데이터를 복제해서 이어 붙인 후 shuffle하여 증강한다.)가 비었다는 말이다. print도 여러 번 찍어보고, 별 짓을 다하다가 돌아돌아 문제 지점을 발견했다.

 

문제는 좀 더 아래의 266번째 줄이다. train/validation에 사용할 데이터의 수가 숫자로 고정되어 있는데, 이것이 맞지 않아 에러가 발생한 것이다. 우리는 총 30만개의 데이터를 사용하는 상황이었기 때문에, 

train_num = 280000, valid_num = 20000 으로 수정해 사용했다. kspon 데이터 대신에 넣어준다고 생각하면 되기 때문에 위쪽만 수정해주면 된다. 각자 데이터 상황에 맞게 비율을 정해 넣어주자.

 

+ 만약 학습 효율 등의 이유로 augmentation을 하고 싶지 않다면, 

92번째 줄을 찾아가 spec_augment 앞에 not을 붙여주거나, 아니면 저 인자 자체를 False로 설정해주면 된다.
(인자 변경 방법은 아래에, 필자도 학습 시간이 부담되어 저 코드 앞에 not을 붙여 데이터 증강을 활용하지 않았다.)

 

② 음성 파일 확장자 지정

 

원 개발자가 사용한 데이터의 음성 파일은 pcm이었던 것으로 보인다. 필자의 경우 wav 파일을 이용했기 때문에, 음성 파일이 pcm으로 설정되어 있는 부분들을 wav로 바꿀 필요가 있었다. (음성 파일 pcm을 사용하는 경우 생략 가능한 부분이다.)

deepspeech2의 경우 음성 파일의 feature 추출 방식으로 fbank를 기본으로 사용한다.따라서 /confids/audio/fbank.yaml에 지정된 인자들을 기본으로 사용하는데, 여기에 있는 audio_extension 혹은 spec_augment 인자를 내가 원하는 값으로 변경하여 사용하면 된다. (pcm -> wav, True -> False)

 

③ 사용하는 글자 사전 변경

사용하는 글자 사전의 이름을 Class에 직접 지정해주어야 한다. main.py에 있는 저 글자 사전의 이름을, 각자 전처리 과정에서 만든 글자 사전의 이름으로 바꾸어주자. 바꾸는 김에 eval.py, inference.py에 있는 모든 파일 명을 바꿔주도록 하자. (이후 모델로 예측을 진행할 때 사용할 글자 사전 지정)

 

④ 학습 옵션 지정(save_result_every, checkpoint_every, resume)

/confids/train/ds2_train.yaml에 있는 인자들을 변경하면 학습 옵션을 내가 원하는 바에 맞게 지정할 수 있다. epoch과 batch_size는 상황에 맞게 지정하면 되고, 

 

save_result_every는 모델이 학습을 진행하면서 발생하는 loss, cer 등의 수치가 저장되는 주기이다. 여기서 time_step의 단위는 원 개발자가 지정한 전체 데이터 길이와 연관되는 수치인데, 

data_loader.py의 276번째 줄에서 그 정의 방법을 확인할 수 있다. 데이터의 크기와 batch_size의 크기로 결정된다. 이 또한 상황에 맞게 지정해주면 된다.

 

checkpoint_every의 역할은 /kospeech/checkpoint/checkpoint.py에서 확인할 수 있다.

학습 도중 model.py와 trainer_states.py(정확한 역할을 모르겠다.)를 저장하는 주기가 checkpoint_every이다. 뒤이어 설명하겠지만 필자는 구글 colab을 활용하며 런타임이 자주 끊기는 상황에서, 모델을 저장하고 가장 최신의 모델을 불러와 이어 학습하는 것을 반복하는 상황이었기 때문에 save_result_every, heckpoint_every를 모두 100으로 짧게 가져가고, 로그를 많이 찍어가면서 계속해서 확인하고, 런타임이 끊기면 model.pt를 불러와 이어 학습하도록 했다.

 

resume 인자로 이어서 학습 여부를 선택할 수 있다. 다만 필자의 상황에 맞게 자주 resume 조건을 활용하고, resume=True로 설정한 상태에서 동일한 코드를 실행했을 때 알아서 가장 최신의 파일을 가져오게 하고 싶었기 때문에 /kospeech/checkpoint/checkpoint.py의 맨 마지막 함수에 변화를 줬다.

 # 원래 것
    def get_latest_checkpoint(self):
        """
        returns the path to the last saved checkpoint's subdirectory.
        Precondition: at least one checkpoint has been made (i.e., latest checkpoint subdirectory exists).
        """
        checkpoints_path = sorted(os.listdir(self.LOAD_PATH), reverse=True)[0]
        sorted_listdir = sorted(os.listdir(os.path.join(self.LOAD_PATH, checkpoints_path)), reverse=True)
        return os.path.join(checkpoints_path, sorted_listdir[0])

    # 변경한 것
    def get_latest_checkpoint(self):
        """
        returns the path to the last saved checkpoint's subdirectory.
        Precondition: at least one checkpoint has been made (i.e., latest checkpoint subdirectory exists).
        """
        sorted_listdir = []
        for (path, dir, files) in os.walk(self.LOAD_PATH):
            if 'model.pt' in files and 'trainer_states.pt' in files:
                sorted_listdir.append(path)

        return sorted(sorted_listdir)[-1]

 

이제 정말 학습을 위한 준비가 끝났다. 실제 학습 과정을 공유하기는 어렵지만, 다음 글에서는 어떠한 환경에서 어떻게 학습을 진행하였고 무슨 문제가 발생하였으며, 어떻게 해결해나갔는지 등을 최대한 공유해보도록 하겠다.

728x90
반응형