はじめに
前回までに、ラズパイ5でローカルLLMを使った音声会話を紹介しました。 精度やスピードでやや苦しいところがあるので、今回はラズパイからクラウド上の Groq API を利用する方法を検討しました。
実行方法
まず、Groq API KEY を取得しておきます。
ターミナルで以下を実行しておきます。gsk_xxx のところにKEYを入れます。
# ~/.bashrc に追加
echo 'export GROQ_API_KEY="gsk_xxxxxxxxxxxxxxxxxx"' >> ~/.bashrc
source ~/.bashrc
~ のフォルダに新規テキストファイルを voice_chat_03.sh の名前で作り、以下をコピペして保存します。
#!/bin/bash
VOICE=/usr/share/hts-voice/nitech-jp-atr503-m001/nitech_jp_atr503_m001.htsvoice
DICT=/var/lib/mecab/dic/open-jtalk/naist-jdic
while true
do
echo "Enterで録音開始(終了 Ctrl+C)"
read
arecord -D plughw:2,0 -d 5 -f S16_LE -r 16000 input.wav
# 音声認識(GroqのWhisper API)
TEXT=$(curl -s https://api.groq.com/openai/v1/audio/transcriptions \
-H "Authorization: Bearer $GROQ_API_KEY" \
-F model="whisper-large-v3" \
-F file="@input.wav" \
-F language="ja" \
| python3 -c "import sys,json; print(json.load(sys.stdin)['text'])")
echo "あなた: $TEXT"
# LLM(Groq API)
REPLY=$(curl -s https://api.groq.com/openai/v1/chat/completions \
-H "Authorization: Bearer $GROQ_API_KEY" \
-H "Content-Type: application/json" \
-d "{
\"model\": \"llama-3.3-70b-versatile\",
\"messages\": [
{\"role\": \"system\", \"content\": \"日本語で3文以内で簡潔に返答してください。\"},
{\"role\": \"user\", \"content\": \"${TEXT}\"}
]
}" \
| python3 -c "import sys,json; print(json.load(sys.stdin)['choices'][0]['message']['content'])")
echo "AI: $REPLY"
# 発話(改行を読点に変換して全文発話)
echo "$REPLY" | tr '\n' '、' | open_jtalk \
-x $DICT \
-m $VOICE \
-ow reply.wav
pw-play reply.wav
done
実行前に実行権限付与を忘れずに。
chmod +x voice_chat_03.sh
実行します。
./voice_chat_03.sh
回答文が長い場合には、発話が間延びするようです。気になる場合は、1.2倍速設定して様子を見てください。
echo "$REPLY" | open_jtalk \
-x $DICT \
-m $VOICE \
-r 1.2 \
-ow reply.wav
また、回答文が長くならないように調整してもいいです。
-d "{
\"model\": \"llama-3.3-70b-versatile\",
\"messages\": [{\"role\": \"system\", \"content\": \"日本語で3文以内で簡潔に返答してください。\"}, {\"role\": \"user\", \"content\": \"${TEXT}\"}]
}"
このままだと、一つ前の会話の内容を忘れているので、話が続きません。
そこで、毎回のAPIリクエストに過去の会話履歴をmessages配列に追加して送ることにします。
HISTORY 変数を使って、会話履歴をJSON形式で保持しました。
毎回メッセージに履歴を追加し、AIが文脈を理解できるようにしました。
メッセージ履歴は直近20件(10ターン)だけ保持することにして、トークン数の増えすぎを防止しました。
以下の内容を voice_chat_04.sh にコピペして保存します。
#!/bin/bash
VOICE=/usr/share/hts-voice/nitech-jp-atr503-m001/nitech_jp_atr503_m001.htsvoice
DICT=/var/lib/mecab/dic/open-jtalk/naist-jdic
# 会話履歴初期化
HISTORY='[{"role":"system","content":"あなたは簡潔に返答するアシスタントです。返答は必ず日本語で2文以内にしてください。"}]'
while true
do
echo "Enterで録音開始(終了 Ctrl+C)"
read
arecord -D plughw:2,0 -d 5 -f S16_LE -r 16000 input.wav
# 音声認識
TEXT=$(curl -s https://api.groq.com/openai/v1/audio/transcriptions \
-H "Authorization: Bearer $GROQ_API_KEY" \
-F model="whisper-large-v3" \
-F file="@input.wav" \
-F language="ja" \
| python3 -c "import sys,json; print(json.load(sys.stdin)['text'])")
echo "あなた: $TEXT"
# 会話履歴にユーザー発言を追加
HISTORY=$(python3 -c "
import json
history = json.loads('''$HISTORY''')
history.append({'role': 'user', 'content': '''$TEXT'''})
print(json.dumps(history, ensure_ascii=False))
")
# LLM呼び出し
RESPONSE=$(curl -s https://api.groq.com/openai/v1/chat/completions \
-H "Authorization: Bearer $GROQ_API_KEY" \
-H "Content-Type: application/json" \
-d "$(python3 -c "
import json
history = json.loads('''$HISTORY''')
print(json.dumps({'model': 'llama-3.3-70b-versatile', 'messages': history}))
")")
REPLY=$(echo "$RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin)['choices'][0]['message']['content'])")
echo "AI: $REPLY"
# 会話履歴にAI返答を追加(直近10ターンだけ保持)
HISTORY=$(python3 -c "
import json
history = json.loads('''$HISTORY''')
history.append({'role': 'assistant', 'content': '''$REPLY'''})
if len(history) > 21:
history = history[:1] + history[-20:]
print(json.dumps(history, ensure_ascii=False))
")
# 発話
echo "$REPLY" | tr '\n' '、' | open_jtalk \
-x $DICT \
-m $VOICE \
-ow reply.wav
pw-play reply.wav
done
実行前に実行権限付与を忘れずに。
chmod +x voice_chat_04.sh
実行します。
./voice_chat_04.sh
おわりに
Groq API で精度、スピードが大きく改善されました。ネット環境が使えるなら、こちらの方が楽ですね。