Spoken Language Processing

Fairseq - Wav2vec 2.0 Pretraining (2) Preprocess 전처리하기

햇농nongnong 2022. 6. 14. 19:56

CLI 툴킷을 사용해 새 모델 학습시켜보기


2. Preprocess - vocabulary 파일 생성하기

  • fairseq에 내장된 fairseq-preprocess 명령어 또는  'libri_labels.py' 파이썬 파일을 통해 전처리 할 수 있음
  • 4개의 파일 : 'dict.ltr.txt', 'train.tsv', 'train.wrd', 'train.ltr'
  • fairseq 장점 : 메모리가 넉넉해서 훈련 잘 됨 (huggingface 에서 했을 때 잘 안되었던 것 fairseq 로 잘됨)
    - huggingface 는 캐시메모리 폴더를 만들고 거기에 저장 - 용량 차지 많이 함 - 따라서 하드 메모리 부족하기도 함
    --> cuda out of memory... 에러메세지 많이 뜸
    --> huggingface 는 소규모 데이터셋으로 돌릴 때 좋음
    - fairseq 는 대규모 데이터셋으로 돌릴 때 좋음

(아래의 예시는 KsponSpeech 데이터의 예시임)

 

1) dict.ltr.txt
- dictionary
- 'vim dict.ltr.txt' - ':set nu' 를 통해 단어 사전 개수 확인 (영어의 경우 26개) (한국어의 경우 2600..개)

 

 

 

2) train.tsv
- 파일명(path)와 프레임 개수

 

 

3) train.wrd
- 아래 예시는 전처리 끝난 것
- 데이터들 전문가가 해서 다 맞다고 생각하지만 실수가 있을 수 있으니 다시 다 고쳐야함 

 

 

4) train.ltr
- word 단위, 스페이스 단위로 만든 것

 

 

 

  • examples/wav2vec 에 있는 "libri_labels.py" 를 통해 character 단위의 ltr, wrd 파일 생성가능

 

libri_labels.py
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("tsv")
    parser.add_argument("--output-dir", required=True)
    parser.add_argument("--output-name", required=True)
    args = parser.parse_args()

    os.makedirs(args.output_dir, exist_ok=True)

    transcriptions = {}

    with open(args.tsv, "r") as tsv, open(
        os.path.join(args.output_dir, args.output_name + ".ltr"), "w"
    ) as ltr_out, open(
        os.path.join(args.output_dir, args.output_name + ".wrd"), "w"
    ) as wrd_out:
        root = next(tsv).strip()
        for line in tsv:
            line = line.strip()
            dir = os.path.dirname(line)
            if dir not in transcriptions:
                parts = dir.split(os.path.sep)
                trans_path = f"{parts[-2]}-{parts[-1]}.trans.txt"
                path = os.path.join(root, dir, trans_path)
                assert os.path.exists(path)
                texts = {}
                with open(path, "r") as trans_f:
                    for tline in trans_f:
                        items = tline.strip().split()
                        texts[items[0]] = " ".join(items[1:])
                transcriptions[dir] = texts
            part = os.path.basename(line).split(".")[0]
            assert part in transcriptions[dir]
            print(transcriptions[dir][part], file=wrd_out)
            print(
                " ".join(list(transcriptions[dir][part].replace(" ", "|"))) + " |",
                file=ltr_out,
            )

 

  • 파일을 가져올 때 string 형식으로 가져오기 위해 libri_labels.py 에서 37번째 줄, 'trans_path = f"{parts[-2]-{parts[-1]}.trans.txt' 부분을 수정해준다.

trans_path = "{0}-{1}.trans.txt".format(parts[-2], parts[-1])

 

 vocabulary file 생성하기 

sudo python3 libri_labels.py /data2/haeyoung/wav2vec_example/manifest/train.tsv --output-dir /data2/haeyoung/wav2vec_example --output-name train
  • valid 도 똑같이 진행해준다.
sudo python3 libri_labels.py /data2/haeyoung/wav2vec_example/manifest/valid.tsv --output-dir /data2/haeyoung/wav2vec_example --output-name valid

 

  • 스페이스(공백문자)는 |(vertical bar) 로 바꿔준다.
  • {train|valid}.ltr = | 를 포함한 character 단위로 나눠진 transcription
  • {train|valid}.wrd = ltr 로 변환하기 전 raw transcription 을 저장

 

train data 맨 앞 10개 샘플 예시

train.wrd

train.ltr

 

 

 dictionary 생성하기 

  • 이제 마지막 dictionary 를 만들기
  • finetune_dir/dict.ltr.txt 에 character 단위 글자를 저장한다.
  • 형식은 [글자] [빈도] 형식으로 

 

 

 phoneme recognition 일 때
- phoneme recognition 일 때는 wav2vec_manifest.py 를 통해 train.tsv, dev.tsv 가 아닌 traih.phn, dev.phn 생성
- "dict.phn.txt" 의 사전 만들기 : 각 줄마다 고유의 phoneme 하나씩 적은 파일 필요
- examples/wav2vec 에 있는 "libri_labels.py" 를 통해 character 단위의 ltr, wrd 파일 생성가능

 

 

 Reference