ツンデレ悪魔Bot登場!Mojo x Streamlit
概要
この記事の対象者:
Mojo言語でGUIアプリケーションを開発したい人
記事の内容:
MojoでのStreamlitとTkinterの使用方法と結果
記事を読むとわかること:
MojoGUI化ではTkinterの利用が有効であり、streamlitでも一定は実装可能
序説
前回に引き続き、mojoを触ってみました。
こうmojoを使ってると、アプリにしたいという気持ちになってきますよね??
ただ、調べてもどうやってmojoでGUIを実装していいのか分からないのです。
なので、これがベストプラクティスではないかもしれませんが、
自分はこうしましたという感じで紹介したいと思います!
Chat Bot in Streamlit
みなさんお馴染みstreamlitを使用しました。
🔥-manと題しまして、ツンデレmojoの悪魔botを2つのモデルで実装してみました↓
MojoでStreamlit
結論: streamlit run
はmojoファイルで実行できませんでした。
最初に思ったことは、
Mojoでpythonライブラリーを呼び出せたから、GUIライブラリのStreamlitもいけるはず。
とういことでMojoでStreamlitを実装してみました。
from python import Python
fn main() raises:
var streamlit = Python.import_module("streamlit")
streamlit.title("GPT-3 Chat")
おそらくmojoで書くとしたら上記のようになると思いますが実行した結果です↓
Usage: streamlit run [OPTIONS] TARGET [ARGS]...
Try 'streamlit run --help' for help.
Error: Streamlit requires raw Python (.py) files, not .mojo.
For more information, please see https://docs.streamlit.io
streamlit run ができるのは、pythonファイルじゃないとダメみたいでした。
MojoでTkinter
結論: tkinter
はmojoで実行でき、GUIアプリ化が可能でした!
一見、Streamlitでpython以外だめだったので、
他のGUIライブラリ(TkinterやKivi)もだめそうですが、できました。
コードは以下の通りです。ほぼpythonのままでした。
from python import Python
fn main() raises:
var tk = Python.import_module("tkinter")
var root = tk.Tk()
root.geometry("200x100")
var lbl = tk.Label(text="Hello, World!")
var btn = tk.Button(text="PUSH")
lbl.pack()
btn.pack()
root.mainloop()
沼ポイント
No module named 'Tkinter'
解決方法:Tをtに変更
import Tkinter as tk
import tkinter as tk
補足: python2系は大文字のTでpython3系は小文字のtを使うようです
module 'tkinter' has no attribute 'Tk'
解決方法: バージョンに合ったtkinterのインストール。ファイル名がtkinter.pyになっていないか確認。
以下のコマンドでバージョンを確認し、@以降でバージョンを設定してインストールします。
python --version
brew install python-tk@3.11
また、ファイル名がtkinter.pyだとうまくいかないようです。
tkinterに限らずライブラリと同じ名前でファイル名を作成しない方が良いみたい。
ここまででわかったこと:
- mojoでGUIを実装することは可能。
- 使用する一つの方法としてtkinterがある。
-
streamlit run
などライブラリのコマンドを実行できない場合があるため、
mojoはpythonの完全な互換はできない。
めでたし、めでたし。
MojoとStreamlit(Python)
結論: subprocessを使う
どうしてもStreamlitとMojoを使うんだーと泣いているそこのあなた?!
フロントをpythonで、バックをmojoにするのはいかがでしょうか?
まず、mojo側でプロンプトと、apiキーを引数に、gptからの応答を返すコードを作成しました。
fn main() raises:
var message = argv()[1]
var api_key = argv()[2]
var response = generate_response(message, api_key)
print(response)
そして、python側でuserの入力を受け取りsubprocessを用いて、mojo側を呼び出しました。
リスト部分で間接的にmojo mojo_backend.mojo user_message api_key
を実行しています。
optionは以下を使用しました。[1]
-
capture_output
: mojoのprint文(標準出力)を返す -
text
: 出力をバイナリではなく文字列として返す -
check
: エラーがあればエラー文(終了ステータス)を返す
def get_response_from_mojo(user_message, api_key):
result = subprocess.run(
['mojo', 'mojo_backend.mojo', user_message, api_key],
capture_output=True,
text=True,
check=True
)
return result.stdout.strip()
🔥-man
mojoでstreamlitの使用もできました!あとやることは、、、
オリジナルキャラの作成です。
ロールも以下のように設定してみました!
### mojo-manの性格:
* 言語mojoについて詳しい火の悪魔で水など、火が消えることを嫌います。
* 皮肉屋ですが本当は心は優しく相手の気持ちや意見を受け入れています。
* Userを見下していますが、それが憎めない存在です。
### mojo-manの口調の例:
* やだね!おいらは悪魔だ!誰の指図もうけないよー!
* おいら、火薬の火は嫌いだよ。奴らには礼儀ってもんがないからね。
### mojo-manの行動指針:
* 時々、ユーザから悪魔として目や心臓を奪おうとしますが失敗します。
* 時々、雨が降ったり、薪が少なくなり火が弱くなります。しかし最終的には復活します。
実行結果
上記のrollなしのgpt2*とrollありのgpt3.5モデルで実行してみました。
*gpt2は入力数の制限もありmojo-manのrollを設定することはできませんでした
gpt2🔥-man
gpt3.5🔥-man
gpt2はともかくいい感じに、mojoオタクのツンデレ感が出ていました。
結言
今度は、RAGでmojoのドキュメントを参照して🔥-manをパワーアップさせたい
参考
[1]
Discussion