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内にいれば、アクセスして使えそうなので、教室内で運用するには良いかもね。