Eli의 여백

바쁜 나날들 사이에서 생각났던 이런저런 것들을 적어봅니다.

IT/새로운 시도

라즈베리파이 구글 어시스턴트 음성인식 세팅

Eli♪ 2021. 4. 21. 23:33

이전 글에서 이어짐.

 

기본적으로 여기에 나와 있는 대로 진행했다.

developers.google.com/assistant/sdk/guides/service/python/embed/audio

 

연결상태

라즈베리파이에 마이크랑 이어폰 꽂은거

마이크: USB 마이크 (shure MV5) 를 USB 3.0 슬롯에 꽂음

스피커: 아날로그 3.5파이 잭 이어폰 (Shure SE215) 를 오디오 잭에 꽂음

 

이어폰을 꽂자마자 화이트노이즈는 심하게 존재한다. 다음의 명령어들을 통해 재생기기의 카드번호와 디바이스 번호를 알 수 있다. 숫자 1이 아니라 list의 l이다.

arecord -l
aplay -l

 

사운드 세팅 만들기

먼저 홈/pi 에 새 파일로 .asoundrc를 만들어준다. 참고로 파일탐색기에서 hidden파일 보기를 눌러줘야 .asoundrc가 보인다.

이렇게 했는데도 잘 안나와서 다른 글을 참고해서 다음과 같이 설정했다.

sudo raspi-config

System options - Audio - Headphones 셀렉 및 finish

 

소리 재생 테스트

이렇게 하고 나서 터미널에 다음과 같이 입력하여 speaker-test 앱을 구동했다. 띄어쓰기에 주의한다.

speaker-test -t wav

Front left를 반복적으로 말하는 여자 목소리가 나온다. Ctrl + C를 누르면 그만한다.

 

소리 녹음 테스트

arecord --format=S16_LE --duration=5 --rate=16000 --file-type=raw out.raw

이렇게 입력하면 5초간 마이크로 녹음한다.

 

aplay --format=S16_LE --rate=16000 out.raw

이렇게 입력하면 위에서 녹음했던 파일을 재생한다. 화이트노이즈가 꽤 있게 재생됐다. 녹음단에서 노이즈가 낀건지 재생단에서 낀건지는 불확실했다. 같은 마이크 이어폰이라도 컴퓨터에서 쓸때와는 퀄리티가 너무 다른...

 

구글 디벨로퍼 액션 콘솔 세팅

구글 어시스턴트를 쓰기 위해 본격적으로 구글 디벨로퍼 세팅을 한다. 먼저 다음의 액션 콘솔 페이지에 들어간다.

console.actions.google.com/

 

적절한 이름으로 프로젝트를 생성한다. 이 때 다음과 같이 existing project에 action을 추가하게 할 수도 있다. 언어설정도 여기서 한다.

 

액션 콘솔 페이지가 뜨는데 처음 만들었다면 스크롤 맨 아래에 아래와 같은 디바이스 등록하기가 있을 것이다.

 

혹시 지나쳤다면 화면 상단의 develop 탭을 눌러 device registration을 한다. 디바이스 타입은 적당한게 없어서 TV로 골랐고, trait는 하나도 안골랐다.

만약 device registration이 안보인다면 다음의 형식으로 접근 가능하다. 힌트는 이 페이지에서 얻었다.

https://console.actions.google.com/u/0/project/{your-project-name}/deviceregistration/

 

다음으로 구글 어시스턴트 api를 활성화해준다.

console.developers.google.com/apis/api/embeddedassistant.googleapis.com/overview

 

그리고 구글 계정과 연동하면서 권한 동의하는 화면을 다음 링크에서 세팅해준다. 사용자 유형은 외부로 만들어주면 된다. 그리고 

console.developers.google.com/apis/credentials/consent

 

다음으로 구글 어카운트에 들어가서 웹 및 앱 활동을 켜준다.

support.google.com/accounts/answer/27441

 

그리고 그 아래있는 어쩌고 포함이라고 써있는 체크박스도 꼭 켜라고 공식 문서에서 말하고 있다.

 

디바이스 모델 등록

다음 링크를 참고했다.

developers.google.com/assistant/sdk/guides/service/python/embed/register-device

 

액션 콘솔의 developer 탭에 들어가서 아까 생성한 디바이스 오른쪽에 점 세개짜리를 눌러서 download OAuth 2.0 credential을 눌러준다.

console.actions.google.com/

 

이름이 긴 json  파일이 받아진다. 이 파일을 VNC뷰어에서 가운데 위쪽에 숨어있던 transfer files 기능을 이용해 /home/pi로 전송한다. 공식문서에서처럼 ssh를 이용하는 scp를 써도 된다.

 

라즈베리파이에 sdk 설치

먼저 다음의 명령어들을 통해 라즈베리파이에서 파이썬 3 환경을 설정한다. 공식문서에도 나와있다.

sudo apt-get update
sudo apt-get install python3-dev python3-venv # Use python3.4-venv if the package cannot be found.
python3 -m venv env
env/bin/python -m pip install --upgrade pip setuptools wheel
source env/bin/activate

 

그리고 구글 어시스턴트에 필요한 패키지들을 다운받는다.

sudo apt-get install portaudio19-dev libffi-dev libssl-dev

 

다음으로 구글 어시스턴트 최신 패키지로 업데이트한다. 시간이 좀 걸린다.

python -m pip install --upgrade google-assistant-sdk[samples]

 

디바이스 credential을 라즈베리파이에 등록

라즈베리파이 터미널에서 구글 authorization tool을 설치한다. 역시나 공식문서에 있는 내용이다.

python -m pip install --upgrade google-auth-oauthlib[tool]

 

다음으로 아까 다운받아놨던 파일을 인식시켜 준다. 여기에서 맨 마지막 /path/to 어쩌고.json 부분을 해당 파일로 바꿔준다.

google-oauthlib-tool --scope https://www.googleapis.com/auth/assistant-sdk-prototype \
      --save --headless --client-secrets /path/to/client_secret_client-id.json

그러면 터미널에 긴 URL이 표시되는데 이것을 복사해서 아무 기기의 웹브라우저에서 켠다. 참고로 터미널에서 Ctrl + C를 누르면 복사가 아니라 명령이 abort되므로 Ctrl + Shift + C를 누르거나 URL에 마우스를 올리고 살포시 copy URL만 눌러준다. 광범위 권한 허용이 끝나면 아래처럼 화면이 뜨면서 복잡한 코드를 보여준다.

 

해당 코드를 복사해서 라즈베리파이에 붙여넣으면 된다. 그러면 다음과 같은 메시지를 볼 수 있다.

credentials saved: /home/pi/.config/google-oauthlib-tool/credentials.json

여기까지 하면 기본적인 연동은 끝난 것이다.

 

인식 테스트

공식 문서에 있는 방법대로 다음과 같이 입력하면 영어로 인식을 한다.

googlesamples-assistant-pushtotalk --project-id my-dev-project --device-model-id my-model

그런데 다른사람 글을 참고하면 한글도 된다. 단순히 -lang 옵션만 추가해주면 된다.

googlesamples-assistant-pushtotalk -lang ko-KR --project-id my-dev-project --device-model-id my-model

 

엔터를 치고 하고싶은 말을 하면 구글 어시스턴트가 대답을 해준다.

 

그런데 인식되는 글자가 다 깨져서 나왔다.

 

이 문제를 해결하기 위해 다른사람 글을 참고하여 다음과 같이 한글을 설치했다. locale은 미국으로 되어있어야 한다고 한다. 나는 원래부터 그렇게 되어있었다.

sudo apt install -y fonts-unfonts-core

설치 후에 터미널을 껐다가 새로 켜줘야 한다.

 

참고로 python env가 활성화가 되어야 하므로 명령어 입력 전에 env를 activate해주는 것을 잊으면 안된다.

이제 아까의 긴 명령어를 다시 입력하고 엔터 친 후 말을 해보면 다음과 같이 잘 나오는 것을 알 수 있다.

대답도 한글로 잘 한다. 접속한 아이피 기반으로 위치정보도 잘 파악하고 있는 것을 확인할 수 있었다.

 

단점

일단 샘플 코드로 위처럼 하는데는 성공했지만, 자동으로 음성을 인식하는 것이 아니라 엔터를 쳐줘야 다음 말을 인식한다는 단점이 있다. 다른 사람의 방법을 보면 무작정 1초 기다리고 다음을 인식하는데 이러면 계속 신호를 보내기 때문에 사생활 침해의 우려가 있을 것으로 생각했다.

 

그리고 오케이 구글 등을 인식할 수 있는 googlesamples-assistant-hotword는 deprecate되었기 때문에 원본 코드를 찾을 수 없다. pip에서 library로 설치해서 구동은 가능하지만 한글은 안되는 것을 확인했다. 이전에는 둘다 설치하면 segmentation fault같은게 떴다는데 나한테는 일어나지 않았다.

 

추가적인 가능성

pushtalk의 경우에는 아래의 링크에서 코드를 확인할 수 있다.

github.com/googlesamples/assistant-sdk-python/blob/master/google-assistant-sdk/googlesamples/assistant/grpc/pushtotalk.py

 

googlesamples/assistant-sdk-python

Samples and bindings for the Google Assistant API. Contribute to googlesamples/assistant-sdk-python development by creating an account on GitHub.

github.com

 

해당 코드의 맨 마지막쯤을 보면 while True로 도는 것을 알 수 있다.

# If no file arguments supplied:
# keep recording voice requests using the microphone
# and playing back assistant response using the speaker.
# When the once flag is set, don't wait for a trigger. Otherwise, wait.
wait_for_user_trigger = not once
while True:
  if wait_for_user_trigger:
  	click.pause(info='Press Enter to send a new request...')
  continue_conversation = assistant.assist()
  # wait for user trigger if there is no follow-up turn in
  # the conversation.
  wait_for_user_trigger = not continue_conversation

  # If we only want one conversation, break.
  if once and (not continue_conversation):
  	break

그리고 이 코드를 잘 수정해서 특정 단어를 말하면 인식되게 할 수 있을 것으로 예상이 된다.

 

참고로 스마트폰에 깔려있는 구글 홈을 켜보면 아래와 같이 구글홈 연동이 가능한 기기로 등록이 되어있는 것을 알 수 있다.

기기가 2개인건 하나는 sdk고 하나는 deprecate된 library에 동시에 등록되어서 그런 것 같다.

이것을 보면 그냥 데탑에도 python 깔고 적당한 라이브러리와 디바이스 등록을 해버리면 데탑도 기기로 쓸수있는거 아닌가 하는 생각이 든다. 위의 모든 내용들은 남을 따라한 결과물인데, 이전 글에서 3rd party 구글 어시스턴트 앱을 확인한 것과 같이 직접 짜면 충분히 구현 가능할 것으로 보인다.

 

결론

Raspberry Pi 4 model B와 USB 마이크, 이어폰을 이용해서 구글 어시스턴트 기본기능을 구현하고 대화를 주고받는데 성공했다. 커스텀 명령을 만드려면 샘플 코드 수정하면 될 것 같다. 부족한 부분도 보였지만 충분히 극복 가능할 것으로 생각한다. 오늘은 여기까지. 끝.

 

이외 참고 자료

[1] swkimtech.tistory.com/entry/Actions-SDK%EB%A1%9C-google-assistant-Action-%EB%A7%8C%EB%93%A4%EA%B8%B0

[2] e3jake.tistory.com/53 

[3] developers.google.com/assistant/sdk/guides/service/python/embed/next-steps

[4] developers.google.com/assistant/sdk/reference/rpc/google.assistant.embedded.v1alpha2

[5] assistant.google.com/explore/c/1/?hl=ko-KR

[6] 다른사람 잘 정리한 자료

[7] 마이크 스피커 연결부분만 따로 뗀 자료

[8] Cortana command 목록(구글 어시스턴트로 구현가능 여부 확인하면 좋을듯)

[9] 구글 어시스턴트 3rd party의 wakeword 설정법(유튜브)

[10] 위에서 wakeword 설정시 사용한 프로그램

[11] 구글 어시스턴트 3rd party app (github)

[12] 위 앱의 auth 설정법

[13] 구글 액션 콘솔

[14] 구글 클라우드 대시보드