Stretch3の拡張機能「翻訳」を作る

ScratchのAI機能拡張版であるStrech3というScratchがあります。

見た目は、ほぼ同じですね。
通常のScratchにはない拡張機能があるのですが、通常のScratchにもある機能拡張「翻訳」がうまく動かないようなのです。
※Scratchでは、問題なく動作します。Stretch3だと動かない様子(値が帰ってきません)Versionの問題っぽい。
折角、機械学習が使えるのに、英語→日本語が使えないのは、つらい。。。ということで、いろいろ試してできるようになったので、備忘録です。
拡張機能を使わずに、翻訳機能を使いたい!ということでまず
拡張機能のDataToolを使って、翻訳ワードを翻訳エンジンに送って結果を受け取れればいいよね?
じゃあまずは翻訳エンジンを選ぼう。APIも必要だよね。
→ Google翻訳とはDeeplとかあるけど、API使うと有料?
→ 無料で使えるもの。LibreTranslate。。初耳です。が、これ使います。
→ LibreTranslateはローカルで翻訳できるのか。いいね。
→ その代わり、翻訳エンジンをローカルに持つ必要があるね
→ Dockerの中にLibreTranslateを入れて運用しましょう
→ DataToolでリクエスト送ってみるけど反応なし。
→ DataToolはGETリクエストを送っている様子
→ LibreTranslateはPOSTリクエストしか受け付けない様子
→ DataToolのGETリクエストをPOSTリクエストにしてLibreTranslateに送る必要がある。
→ 橋渡しに中継サーバーを噛ませて。。まじか。FlaskにGET→POSTをやってもらいます
構成としてはこんな感じ。

開発&動作環境 Macbook Air M1 OS15.7です
1.DockerでLibreTranslateを起動※DockerDeskTopが必要です。LibreTranslateのダウンロードが必要です
docker run -it -p <公開するポート1>:5000 \ -e LT_LOAD_ONLY=en,ja \ libretranslate/libretranslate \ --update-models
<公開するポート1> の部分は自分で決める番号(例:5001)
この番号は後ほど Scratch と Flask で利用します
モデル更新オプション --update-models により精度が向上します
2.中継サーバー(Flask)の設定
2−1.作業フォルダ
mkdir stretch-translate
cd stretch-translate
2−2.必要ライブラリ
pip install flask requests
2-3.server.pyを作成
nano server.py
中身
from flask import Flask, request, jsonify
import requests
app = Flask(__name__)
# LibreTranslate のURL(例: http://<サーバーのアドレス>:<公開するポート1>/translate )
LIBRE_URL = "http://<翻訳サーバーのアドレス>:<公開するポート1>/translate"
@app.route("/translate")
def translate():
text = request.args.get("q", "")
source = request.args.get("source", "en")
target = request.args.get("target", "ja")
payload = {
"q": text,
"source": source,
"target": target,
"format": "text"
}
try:
r = requests.post(LIBRE_URL, json=payload)
out = r.json().get("translatedText", "")
except:
out = ""
resp = jsonify({"translatedText": out})
resp.headers["Access-Control-Allow-Origin"] = "*"
return resp
if __name__ == "__main__":
# Flask を任意のポートで公開(例:5002)
app.run(host="0.0.0.0", port=<公開するポート2>)
Stretch上では、拡張機能としてDataToolとImageClassifier2Scratchを追加して、以下のブロックを作成すると、カメラ上の認識したものを翻訳して、表示します。

翻訳ブロックが正常に動けば、翻訳ブロック一つで済んでしまうはずなのに。。
同じLAN内にいれば、アクセスして使えそうなので、教室内で運用するには良いかもね。

