🔥알림🔥
① 테디노트 유튜브 -
구경하러 가기!
② LangChain 한국어 튜토리얼
바로가기 👀
③ 랭체인 노트 무료 전자책(wikidocs)
바로가기 🙌
④ RAG 비법노트 LangChain 강의오픈
바로가기 🙌
⑤ 서울대 PyTorch 딥러닝 강의
바로가기 🙌
[2024년 UPDATE] OpenAI Python API 튜토리얼 - Whisper API를 사용하여 TTS, STT 구현하기(3)
이번 튜토리얼은 OpenAI 의 Whisper API 를 사용하여 음성을 텍스트로 변환하는 STT, 그리고 텍스트를 음성으로 변환하는 방법에 대해 알아보겠습니다.
튜토리얼 진행시 참고사항
- openai 버전:
1.6.1
- API KEY 발급방법: OpenAI Python API 키 발급방법, 요금체계 글을 참고해 주세요.
# 토큰 정보로드를 위한 라이브러리
# 설치: pip install python-dotenv
from dotenv import load_dotenv
# 토큰 정보로드
load_dotenv()
True
📍 Client 생성
client
는 OpenAI 모듈로 생성된 인스턴스 입니다.
[주의] 아래의 코드에서 오류가 난다면 API 키의 오류일 가능성이 높습니다.
from openai import OpenAI
client = OpenAI()
① Text To Speech(TTS)
-
TTS는 컴퓨터 프로그램이나 기기가 텍스트를 인간의 음성처럼 들리는 오디오로 변환하는 과정입니다.
-
이 기술은 음성 합성을 통해 텍스트 데이터를 자연스러운 음성으로 바꿉니다.
-
사용 예시: 오디오북, 음성 안내 시스템, 음성 기반 가상 어시스턴트 등.
[참고]
- 공식문서: https://platform.openai.com/docs/guides/text-to-speech
주요 파라미터
-
model
: 사용 가능한 TTS 모델 중 하나를 지정합니다.tts-1
또는tts-1-hd
.- 최신 지원모델 확인: https://platform.openai.com/docs/models/tts
-
input
: 오디오를 생성할 텍스트입니다. 최대 길이는 4096자입니다. -
voice
: 오디오를 생성할 때 사용할 음성입니다. 지원되는 음성은alloy
,echo
,fable
,onyx
,nova
, andshimmer
입니다. 음성의 미리듣기는 여기 에서 확인할 수 있습니다. -
response_format
: 오디오를 입력할 형식입니다. 지원되는 형식은mp3
,opus
,aac
및flac
입니다. -
speed
: 생성된 오디오의 속도입니다.0.25
에서4.0
사이의 값을 선택합니다. 기본값은1.0
입니다.
speech_file_path = "tts_audio.mp3"
response = client.audio.speech.create(
model="tts-1",
input="아~ 오늘 파이썬 배우기 정말 좋은 날이네~",
voice="alloy",
response_format="mp3",
speed=1.1,
)
response.stream_to_file(speech_file_path)
저장한 오디오 파일을 재생합니다.
from IPython.display import Audio
Audio(speech_file_path)
② Speech To Text(STT)
-
STT는 사람의 말소리를 텍스트로 변환하는 기술입니다.
-
이는 음성 인식을 통해 구어체 언어를 캡처하고 이를 기록 가능한 형태의 텍스트로 변환합니다.
-
사용예시: 음성 명령 입력, 자동 회의록 작성, 음성 기반 검색 시스템 등.
[참고]
-
공식문서: https://platform.openai.com/docs/guides/speech-to-text
-
파일 업로드는 현재 25MB로 제한되어 있으며, 지원되는 입력 파일 형식은
mp3
,MP4
,MPEG
,MPGA
,M4A
,WAV
,WEBM
입니다. -
지원언어
- 아프리칸스어, 아랍어, 아르메니아어, 아제르바이잔어, 벨라루스어, 보스니아어, 불가리아어, 카탈로니아어, 중국어, 크로아티아어, 체코어, 덴마크어, 네덜란드어, 영어, 에스토니아어, 핀란드어, 프랑스어, 갈리시아어, 독일어, 그리스어, 히브리어, 힌디어, 헝가리어, 아이슬란드어, 인도네시아어, 이탈리아어, 일본어, 인도네시아어, 칸나다어, 카자흐어, 한국어, 라트비아어, 리투아니아어, 마케도니아어, 말레이어, 마라티어, 마오리어, 네팔어, 노르웨이어, 페르시아어, 폴란드어, 포르투갈어, 루마니아어, 러시아어, 세르비아어, 슬로바키아어, 슬로베니아어, 스페인어, 스와힐리어, 스웨덴어, 타갈로그어, 타밀어, 태국어, 터키어, 우크라이나어, 우르두어, 베트남어 및 웨일스어.
주요 파라미터
-
file
: 변환할 오디오 파일 개체(파일 이름이 아님)로, 다음 형식 중 하나입니다:FLAC
,MP3
,MP4
,MPEG
,MPGA
,M4A
,OGG
,WAV
또는WEBM
. -
model
: 현재는whisper-1
모델만 지정 가능합니다. -
language
: 입력 오디오의 언어입니다. 입력 언어를 ISO-639-1 형식으로 제공하면 정확도와 지연 시간이 개선됩니다. -
prompt
: (선택 사항) 모델의 스타일을 안내하거나 이전 오디오 세그먼트를 계속하기 위한 텍스트입니다. 프롬프트는 오디오 언어와 일치해야 합니다. -
response_format
: 변환된 결과물 출력 형식입니다. 가능한 지정 옵션은json
,text
,srt
,verbose_json
또는vtt
입니다. -
temperature
: 0에서 1 사이의 샘플링temperature
입니다. 0.8과 같이 값이 높을수록 출력은 더 무작위적이고, 0.2와 같이 값이 낮을수록 출력은 더 집중적이고 결정론적입니다. 0으로 설정하면 모델은 로그 확률을 사용하여 특정 임계값에 도달할 때까지 자동으로temperature
을 높입니다.
audio_file = open("data/채용면접_샘플_01.wav", "rb")
transcript = client.audio.transcriptions.create(
file=audio_file,
model="whisper-1",
language="ko",
response_format="text",
temperature=0.0,
)
# 결과물 출력
print(transcript)
③ 더욱 긴 오디오 입력 대한 처리
기본적으로 Whisper API는 25MB 미만의 파일 만 지원합니다.
이보다 긴 오디오 파일이 있는 경우 25MB 이하의 청크로 나누거나 압축된 오디오 형식을 사용 해야 합니다.
최상의 성능을 얻으려면 문장 중간에 오디오를 분할하면 일부 문맥이 손실될 수 있으므로 분할을 피하는 것이 좋습니다.
이를 처리하는 한 가지 방법은 PyDub
오픈 소스 Python 패키지를 사용하여 오디오를 분할 하는 것입니다.
샘플 데이터셋(채용면접 인터뷰 데이터)
- 링크: https://aihub.or.kr/aihubdata/data/view.do?currMenu=115&topMenu=100&aihubDataSe=data&dataSetSn=71592
아래의 코드는 오디오 파일을 정해진 시간에 따라 분절하여 별도의 파일로 저장하는 코드입니다.
from pydub import AudioSegment
filename = "data/채용면접_샘플_02.wav"
myaudio = AudioSegment.from_mp3(filename)
# PyDub 는 밀리초 단위로 시간을 계산합니다.
thirty_seconds = 1 * 30 * 1000 # (1초 * 30) * 1000
total_milliseconds = myaudio.duration_seconds * 1000 # 전체 길이를 밀리초로 변환
# 전체 길이를 30초로 나누어서 반복할 횟수를 계산합니다.
total_iterations = int(total_milliseconds // thirty_seconds + 1)
total_iterations
3
# 생성된 파일명을 저장할 리스트
output_filenames = []
for i in range(total_iterations):
if i < total_iterations - 1:
# 30초 단위로 오디오를 분할합니다.
part_of_audio = myaudio[thirty_seconds * i: thirty_seconds * (i + 1)]
else:
# 마지막은 나머지 전체를 분할합니다.
part_of_audio = myaudio[thirty_seconds * i:]
output_filename = (
# 예시: 채용면접_샘플_02-(1).mp3, 채용면접_샘플_02-(2).mp3 ...
f"{filename[:-4]}-({i+1}).mp3"
)
# 분할된 오디오를 저장합니다.
part_of_audio.export(output_filename, format="mp3")
output_filenames.append(output_filename)
# 결과물(파일명) 출력
output_filenames
['data/채용면접_샘플_02-(1).mp3', 'data/채용면접_샘플_02-(2).mp3', 'data/채용면접_샘플_02-(3).mp3']
transcripts = []
for audio_filename in output_filenames:
audio_file = open(audio_filename, "rb") # audio file 을 읽어옵니다.
# transcript 를 생성합니다.
transcript = client.audio.transcriptions.create(
file=audio_file,
model="whisper-1", # 모델은 whisper-1 을 사용
language="ko", # 한국어를 사용
response_format="text", # 결과물은 text 로 출력
temperature=0.0,
)
# 생성된 transcript 를 리스트에 추가합니다.
transcripts.append(transcript)
# 전체 transcript 출력(리스트를 문자열로 변환)
final_output = "---- 분할 ---- \n".join(transcripts)
print(final_output)
뭐 제가 평소에 제가 생각했던 것 말고 다른 사람들이 주로 저한테 말했던 걸 생각해보면은 일단은 되게 한가지에 꽂히면 그거를 끝을 보는 그런 성격을 장점이라고 해줬던 것 같습니다. 항상 실행을 하는 편이었고 주변에서 저한테 너 항상 행동력이 좋다 이런 말을 들었던 것 같아요. ---- 분할 ---- 제가 하고 싶은 일이 생기고 호기심이 생기면 어쨌든 그거를 실행해봐야 다음으로 넘어갈 수 있다고 생각하고 있어요. 그래서 사실 일적인 부분 말고도 취미적인 부분에서도 되게 많은 것들을 시도했던 경험이 있고요. 단점을 말하자면 좀 주변에서 제가 많이 들었던 게 자기 비하였던 것 같아요. 제가 좀 외적으로 컴플렉스를 스스로 ---- 분할 ---- 느끼고 있는 부분들이 많은데 안 그래야지 라고 생각하면서도 스스로 좀 비하하는 말들을 많이 하게 되더라구요. 그래서 주변에서 그런 것들에 대해서 주의를 좀 많이 줬던 순간들이 있었어요. 그래서 저도 최대한 그런 것들을 좀 지양해야겠다고 스스로 좀 다 지고 있습니다.
example_prompt = """
당신은 채용 담당관입니다.
주어진 내용을 바탕으로, 면접자의 긍정적인 면과 부정적인 면을 나누어서 정리해 주세요.
결과물은 요약된 불렛포인트로 정리해 주세요.
한글로 작성해 주세요.
(예시)
#긍정적인면
-
-
-
#부정정인면
-
-
"""
def generate_HR_opinion(temperature, prompt, transcript):
response = client.chat.completions.create(
model="gpt-4",
temperature=temperature,
messages=[
{"role": "system", "content": prompt},
{"role": "user", "content": transcript},
],
)
return response.choices[0].message.content
hr_opinion = generate_HR_opinion(0, example_prompt, final_output)
print(hr_opinion)
#긍정적인면 - 한 가지 일에 꽂히면 끝을 본다는 집중력 - 행동력이 좋음 - 호기심이 많고, 새로운 것을 시도하는 것을 두려워하지 않음 #부정적인면 - 자기 비하하는 경향이 있음 - 외적인 컴플렉스를 스스로 느끼는 경향이 있음 - 자신에 대한 부정적인 말을 자주 함
댓글남기기