본문 바로가기
AI

STT) Google Cloud STT 기술 검토

by 박채니 2024. 11. 27.
SMALL

안녕하세요, 코린이의 코딩 학습기 채니 입니다.

개인 포스팅용으로 내용에 오류 및 잘못된 정보가 있을 수 있습니다.

 

 

STT (Speech-To-Text) 기술을 사용해야하는 프로젝트가 생겨서 Google, Naver, Azure가 제공하는 STT 서비스를 기술 검토해보았다.

 

검토사항은 아래와 같다.

  1. 스트리밍 처리가 가능한가
  2. 한국어를 가장 잘 인식할 수 있는가
  3. 가격은 저렴한가

Google Cloud

  • 125개 언어 지원
  • 스트리밍의 경우, 기본적으로 최대 5분까지 스트림을 열어둘 수 있음
    • 무한 스트리밍 처리도 가능
  • Google Cloud 공식 홈페이지

가격

출처: Google Cloud 공식 홈페이지
출처: Google Cloud 공식 홈페이지

 

표준 동적 일괄 인식은 낮은 긴급도로 오디오를 처리하는 기능으로 현재는 굳이 필요 없다고 판단하였다.

따라서 표준 인식 모델 & 인식(로깅) 서비스를 이용한다고 가정했을 때 (한 달에 0~500,000분까지 사용했을 경우) 가격은 아래와 같다.

  • 1분: $0.016 (약 22.14원)
  • 1시간: $0.96 (약 1,328원)

 

리소스 한도

출처: Google Cloud STT 공식 홈페이지
출처: Google Cloud STT 공식 홈페이지

서비스 이용해보기 (v2)

나는 Python과 친하지 않아서.. 가상환경 생성하는 것부터 예제코드 적용까지를 정리해보도록 하겠다.

 

Anaconda 설치 및 설정 (이미 설치되어 있는 경우 생략 가능)

$ brew install --cask anaconda
$ /opt/homebrew/anaconda3/bin/conda init zsh
$ source ~/.zshrc

 

가상환경 생성

$ conda create -n googleCloudSttSample python=3.11

 

⭐️ 반드시 python 버전을 3.11로 설치 ⭐️

 

Google Cloud STT 서비스는 ADC (ADC란) 로만 인증 처리가 가능하다.

 

따라서 gcloud (gcloud 설치 가이드) 라는 것을 설치하고 gcloud를 통해 인증 처리를 해주는데, 이 때 지원되는 Python 버전이 3.8~3.12이기 때문에 반드시 Python 버전을 3.11로 설치해준다.

(3.12도 가능하겠지만 "기본 설치 스크립트는 CPython의 Python 3.11을 설치하도록 제공" 한다는 구글 가이드에 따라 3.11로 설치)

 

패키지 설치

$ brew install portaudio

 

requirements.txt 파일 생성

cachetools==5.5.0
certifi==2024.8.30
charset-normalizer==3.4.0
google-api-core==2.22.0
google-auth==2.35.0
google-cloud-speech==2.28.0
googleapis-common-protos==1.65.0
grpcio==1.67.1
grpcio-status==1.67.1
idna==3.10
proto-plus==1.25.0
protobuf==5.28.3
pyasn1==0.6.1
pyasn1_modules==0.4.1
PyAudio==0.2.14
requests==2.32.3
rsa==4.9
urllib3==2.2.3
$ pip install -r requirements.txt

 

gcloud CLI 설치 (Mac)

(Google Cloud 프로젝트를 모두 생성했다고 가정 - 프로젝트 생성부터 해야한다면 stt 서비스 가이드 를 참조하자)

  1. 명령줄에서 다음 명령어 실행
    $ curl https://sdk.cloud.google.com | bash
  2. 메시지가 표시되면 파일 시스템에서 위치(일반적으로 홈 디렉터리)를 선택하여 google-cloud-sdk 하위 디렉터리 생성
  3. gcloud CLI 개선을 위해 익명 사용 통계를 보내려면 메시지가 표시될 때 Y로 응답
  4. PATH에 glcoud CLI 명령줄 도구 추가하고, 명령어 완성을 사용 설정하려면 메시지가 표시될 때 Y로 응답
    1. 업데이트할 rc 파일 경로를 묻는 경우 → Enter
  5. 셸 재실행
    $ exec -l $SHELL
  6. Google Cloud CLI 환경 초기화
    $ gcloud init
  7. 구글 계정 로그인
  8. default로 사용할 프로젝트 선택 (없는 경우 새로 생성)
  9. 로컬 셸 사용 시, 사용자 계정에 대한 로컬 인증 자격 증명 생성
    $ gcloud auth application-default login

 

예제코드

from google.cloud.speech_v2 import SpeechClient
from google.cloud.speech_v2.types import cloud_speech as cloud_speech_types
import pyaudio
import time
import threading

PROJECT_ID = "PROJECT_ID"
RATE = 16000
CHUNK_SIZE = 12800

def print_every_second():
    current_time = time.strftime("%H:%M:%S", time.localtime())
    print(f"1초마다 출력됩니다. 현재 시간: {current_time}")
    threading.Timer(1, print_every_second).start()

def get_microphone_stream():
    audio = pyaudio.PyAudio()

    try:
        return audio.open(
            format=pyaudio.paInt16, 
            channels=1, 
            rate=RATE, 
            input=True, 
            frames_per_buffer=CHUNK_SIZE
        )  
    except OSError as error:
        print(f"[WARNING]: Unable to access microphone. {error}")   

def save_text_to_file(text):
    if text.strip():
        with open("transcription_output.txt", "a", encoding="utf-8") as file:
            file.write(f"{text}\n")

def transcribe_streaming_v2() -> cloud_speech_types.StreamingRecognizeResponse:
    # Instantiates a client
    client = SpeechClient()

    stream = get_microphone_stream()

    # 인식 요청 처리에 대한 정보를 저장해준다.
    recognition_config = cloud_speech_types.RecognitionConfig(
        explicit_decoding_config=cloud_speech_types.ExplicitDecodingConfig(
            sample_rate_hertz=RATE,
            encoding=cloud_speech_types.ExplicitDecodingConfig.AudioEncoding.LINEAR16,
            audio_channel_count=1
        ),
        language_codes=["ko-KR"],
        model="long",
        features=cloud_speech_types.RecognitionFeatures(
            # 구두점 추가
            enable_automatic_punctuation=True,
            # 욕설 걸러내기 (fuck -> f***)
            profanity_filter=True,
        ),
        # 모델을 chirp or chirp_2 이용해야하는데 해당 모델은 비스트리밍에서만 지원
        # translation_config=cloud_speech_types.TranslationConfig(
        #     target_language="en-US"
        # )
    )
    # 스트리밍 요청에 대한 구성 정보를 제공해준다.
    streaming_config = cloud_speech_types.StreamingRecognitionConfig(
        config=recognition_config,
        streaming_features=cloud_speech_types.StreamingRecognitionFeatures(
            # 중간 결과가 클라이언트에 스트리밍 되지 않도록 함
            # "여러분 안녕하세요"를 말했다고 가정했을 때 클라이언트에 아래와 같이 전달됨
            # True -> 여러분. 안녕하세요. 여러분 안녕하세요.
            # False -> 여러분 안녕하세요.
            interim_results=True,
            enable_voice_activity_events=True,
            # voice_activity_timeout=cloud_speech_types.StreamingRecognitionFeatures.VoiceActivityTimeout(
            #     # 스피치가 시작하고 5초 동안 아무 말이 없으면 스트림을 닫음
            #     speech_start_timeout=duration_pb2.Duration(seconds=5),
            #     # 스피치를 감지하고 10초 동안 아무 말이 없으면 스트림을 닫음
            #     speech_end_timeout=duration_pb2.Duration(seconds=10)
            # )
        )        
    )

    # 인식기와 스트리밍 유형을 지정해준다. (음성을 실시간으로 인식하기 위한 준비 단계)
    config_request = cloud_speech_types.StreamingRecognizeRequest(
        recognizer=f"projects/{PROJECT_ID}/locations/global/recognizers/_",
        streaming_config=streaming_config,
    )

    def requests():
        yield config_request

        print_every_second()

        while True:
            try:
                audio_chunk = stream.read(CHUNK_SIZE)
                yield cloud_speech_types.StreamingRecognizeRequest(audio=audio_chunk)
            except Exception:
                pass

    # Transcribes the audio into text
    responses_iterator = client.streaming_recognize(requests=requests())

    for response in responses_iterator:
        if not response.results:
            continue

        result = response.results[0]

        if not result.alternatives:
            continue

        if hasattr(result, "is_final") and result.is_final:
            transcript = result.alternatives[0].transcript
            print(f"Transcript: {transcript}")
            save_text_to_file(transcript)

try:
    transcribe_streaming_v2()
except Exception as error:
    print(f"[ERROR]: {error}")

 

공식 홈페이지의 오디오 스트리밍 예제 코드를 참고하여 마이크로 말하는 음성에 대해 텍스트로 변환하는 python 코드를 짜보았다.

pyaudio로 마이크 스트림을 만들고 예제코드와 Cloud STT V2 documentiation를 참고하여 필요한 설정을 하였다.

 

위 코드는 5분 이상 스트림을 열어두는 경우

10 ABORTED: Max duration of 5 minutes reached for stream. 오류가 발생한다.

 

만일 무한 스트리밍을 구현하고 싶다면, Python 무한 스트리밍 예제 코드를 참고해보자.

(구글에서 제공하는 예제 코드인데.. 오류 발생하긴 함..;)

 

성능 테스트

샘플동영상을 10분 정도 틀어놓고 얼마나 잘 인식하는지 테스트 해보았다.

결과 값은 아래 파일을 참고하자!

구글이 가장.. 성능이 별로였다. (내가 코드를 잘못 짰나? 싶을 정도로 별로였는데 똑같은 음성으로 구글 테스트 페이지에서 테스트해봤는데 똑같았음)

음성 인식을 잘 못하고 소음이 조금이라도 섞이면 정신을 못차리더라..ㅠ (한국어 기준)

stt_google_result.txt
0.01MB

 

LIST

'AI' 카테고리의 다른 글

STT) Azure STT 기술 검토  (0) 2024.12.10
STT) Naver Cloud(Clova) STT 기술 검토  (1) 2024.12.10