1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

今週は夏休みをいただいています。なので、夏休みの宿題的に。

ずっと前に買ったRaspberry Pi(Zero W)をしばらく放置していたのですが、何かに使えないかなと思っていたら、最近流行りのLLMと組み合わせるのはどうだと。

DatabricksならREST API経由で簡単にLLMを呼び出せるので、そちらを使わせてもらいます。エッジデバイスを使えるということで入出力の幅が広がっているということで、まずはLLMに喋ってもらうことにしました。OpenAIにもすでに同様のインタフェース(音声によるやりとり)は実装されていますが、オープンソースLLMでもそういうことができたらいいなと思いまして。

モデルサービングエンドポイントの確認

DBRX InstructのURLを確認し、パーソナルアクセストークンを作成しておきます。LLMの呼び出しに必要になります。

Screenshot 2024-09-02 at 20.50.05.png

RaspberryPIの設定

IMG_0799.jpg

久々に起動したので、色々忘れてました。

  • ネットワークの準備(2.4Hzでないとダメなの忘れてました)
  • イメージのインストール
    • この際に、WiFiやsshの設定をします
  • スピーカーの接続

Python環境の準備

pipが入っていないので、

sudo apt install pip

pip installをそのまま実行するとエラーになるので仮想環境を作って、そこでインストールしていきます。

python3 -m venv ~/Documents/dbx

必要なライブラリをインストールしていきます。仮想環境のpippythonを使います。

./bin/pip install openai

今回、Raspberry Piに喋らせたいので、こちらを参考にライブラリを追加します。pyopenjtalkという便利なものが。

sudo apt install cmake
sudo apt-get install libopenblas-dev
./bin/pip install scipy
./bin/pip install pyopenjtalk

ロジックの実装

流れはシンプルです。

  1. モデルサービングエンドポイントをRaspberry Piから呼び出してレスポンスを取得
  2. pyopenjtalkでテキストを読み上げ
from openai import OpenAI
import os

import pyopenjtalk
from scipy.io import wavfile
import numpy as np

import subprocess

# レスポンスの読み上げを格納する音声ファイル
wave_file = "/home/yayoi/Documents/dbx/talk.wav"

def synthesize_voice(text):
    x, sr = pyopenjtalk.tts(text)
    wavfile.write(wave_file, sr, x.astype(np.int16))

    cmd = f'/usr/bin/aplay {wave_file}'
    process = (subprocess.Popen(cmd, stdout=subprocess.PIPE,
                           shell=True).communicate()[0]).decode('utf-8')

# How to get your Databricks token: https://docs.databricks.com/en/dev-tools/auth/pat.html
DATABRICKS_TOKEN = os.environ.get('DATABRICKS_TOKEN')
# Alternatively in a Databricks notebook you can use this:
# DATABRICKS_TOKEN = dbutils.notebook.entry_point.getDbutils().notebook().getContext().apiToken().get()

client = OpenAI(
  api_key=DATABRICKS_TOKEN,
  base_url="<エンドポイントのURL>"
)

chat_completion = client.chat.completions.create(
  messages=[
  {
    "role": "system",
    "content": "あなたは好奇心旺盛な日本人の学生です。AIアシスタントに対して日本語を用いて様々な質問をします。"
  },
  {
    "role": "user",
    "content": "思いついた質問を英語の翻訳を含めず日本語で簡潔に教えてください"
  }
  ],
  model="databricks-dbrx-instruct",
  max_tokens=256
)

question = chat_completion.choices[0].message.content
print(question)
synthesize_voice(question)

chat_completion = client.chat.completions.create(
  messages=[
  {
    "role": "system",
    "content": "あなたはAIアシスタントです。質問に対して英語の翻訳を含めず日本語で簡潔に回答してください。"
  },
  {
    "role": "user",
    "content": question
  }
  ],
  model="databricks-dbrx-instruct",
  max_tokens=256
)

response = chat_completion.choices[0].message.content
print(response)
synthesize_voice(response)

環境変数DATABRICKS_TOKENにパーソナルアクセストークンを設定しています。

~/.profile
export DATABRICKS_TOKEN=<パーソナルアクセストークン>

今回、質問文もLLMに考えてもらうようにしました。結構、英語が混じるのでプロンプトで調整しています。このように動作します。

これ、ずっと会話させておくこともできるんですよね。でも、単に1ターンのやりとりだけですとだと味気ないので、コンテキスト持たせた方が良さそうです。

他にもデバイスはあるので、色々試してみます。

はじめてのDatabricks

はじめてのDatabricks

Databricks無料トライアル

Databricks無料トライアル

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?