whisper
텍스트 데이터 수집
데이터가 파일로 있지 않은 경우에는 우리가 외부에서 텍스트 데이터를 수집해야 한다.
보통 수집하는 방법은 세 가지인데, 이미지에서 읽어오거나, 음성에서 읽어오거나, 인터넷에서 긁어오는 것이다. 이미지에서 긁어오는 것은 무료로 된 도구가 잘 없다. 이것은 구글이나 아마존 같은 곳에서 제공하는 외부 API를 쓰면 된다.
음성 인식이나 웹 스크래핑은 우리가 오픈 소스를 이용해서 쉽게 할 수 있다.
멜 스텍트로그램
요즘 음성 인식은 매우 잘 되어서, 간단한 경우에는 API나 스마트폰의 기본 기능을 사용해도 된다. 하지만 긴 음성의 경우에는 별도의 도구를 써야 한다.
음성 인식의 원리는 다음과 같다. 말은 공기의 진동을 통해 전달되는데, 이 진동이 우리의 고막을 때린다. 이 진동을 주파수별로 나누면 이미지로 만들 수 있는데, 이를 스펙트로그램이라고 한다.
사람의 귀는 모든 주파수를 똑같이 처리하지 않는다. 어떤 주파수에는 더 예민하고, 어떤 주파수에는 덜 민감하다. 예를 들어, 나이가 들면 고주파 영역을 잘 듣지 못하게 된다. 이런 특성을 이용해 가게 앞에서 어른들은 듣지 못하고 아이들만 들을 수 있는 고주파를 틀어 아이들을 쫓아내기도 한다.
우리 귀의 이런 특성을 반영해 스펙트로그램을 변형한 것이 멜 스펙트로그램이다. 음성 파일을 멜 스펙트로그램으로 변환하면 일종의 이미지가 되는데, 이를 딥러닝 모델에 입력하면 텍스트로 바꿀 수 있다.
휘스퍼
ChatGPT를 만든 OpenAI에서, Whisper라는 모델을 만들어서 공개했다. 이 모델은 무료로 사용할 수 있어서, ChatGPT처럼 돈을 내고 쓸 수도 있고 그냥 다운받아서 써도 된다.
아직 완벽하지는 않지만 무료로 쓸 수 있는 것 치고는 꽤 괜찮다. 정확도를 보면, 그래프에서 빨간색으로 표시된 것이 한국어인데, 이 막대가 짧을수록 정확한 것이다. 이는 에러율을 나타낸다. 영어나 스페인어는 굉장히 정확하고, 한국어는 중간 정도의 정확도를 보인다. 대체로 영어나 독일어 같은 언어들이 잘 되는 편이다. 한국어도 해보면 그럭저럭 잘 된다.
colab에서 휘스퍼 사용하기
설치
pip install --ignore-installed openai-whisper
이 명령어로 설치를 하면 된다.
사용
import unicodedata
import tqdm.auto
import whisper
from kiwipiepy import Kiwi
model = whisper.load_model("small")
kiwi = Kiwi()
모델을 다운로드하는데 small 모델을 쓸 것이다. 큰 모델은 다운로드하는 데 시간도 오래 걸리고 돌아가는 데 시간도 오래 걸린다. 모델이 크면 클수록 성능은 좋다. 실제로 사용할 때는 큰 모델을 쓰고, 우리 실습은 small 모델로 해볼 것이다.
import glob
filelist = glob.glob('*.mp3')
glob.glob('*.mp3')는 mp3 파일을 모두 찾으라는 명령이다.
for filename in tqdm.auto.tqdm(filelist):
result = model.transcribe(filename, language='ko') # 음성 인식
sents = kiwi.split_into_sents(result['text']) # 문장 단위로 자르기
text = '\n\n'.join(sent.text for sent in sents) # 하나로 합치기
txt_name = filename.replace('.mp3', '.txt') # 저장할 파일명
txt_name = unicodedata.normalize('NFC', txt_name) # NFC로 정규화
with open(txt_name, "w") as f:
f.write(text)
이 코드는 간단한데, mp3 파일을 하나씩 돌면서 한국어로 음성 인식을 한다. 이게 Whisper를 쓰는 전부다. model.transcribe가 받아쓰기라는 뜻이다. 이 파일 내용을 한국어로 받아쓰라는 것이다. 사실 'language'는 'ko'를 안 써도 알아서 음성 인식을 한다. 어느 나라 말인지 자기가 분석까지 한다. 하지만 한국어라고 얘기를 해주면 그 분석 과정이 필요 없으니까 조금이라도 빨리 돌 것이다.
이걸 좀 보기 좋게 저장하려고 한다. 말이 계속 이어지니까 Kiwi의 split_into_sents 함수를 써서 문장별로 자른다. 이 함수는 마침표 같은 게 없어도 문법을 보고 적당히 문장을 잘라준다. 그래서 이걸 잘라서 문장 하나 끝날 때마다 엔터를 두 번 쳐주라는 것이다. 그러면 좀 보기가 좋을 것이다.
colab에서 이 코드를 돌릴 경우 colab은 NFD 방식으로 파일 이름을 저장한다. 그래서 파일을 윈도에 다운 받으면 파일 이름이 깨져 보인다. 이를 위해 unicodedata.normalize('NFC', txt_name)로 NFC 방식으로 파일 이름을 바꿔준다.
끝으로 파일 이름에서 mp3를 txt로 바꿔서 저장한다. tqdm은 진행 막대기를 표시하려고 쓴다. 파일이 여러 개면 이게 좀 오래 걸리니까, 얼마나 남았는지 보여주려고 하는 것이다.