見出し画像

ローカルで動く自然言語処理AIとUnityをAPI連携させる

皆さん美少女AI作っていますか?私は作っています。
美少女AIを作っているとね。Unityと連携させたくなることってあると思うんですよ、
最初はPythonが動くbatファイルをUnityから起動してテキストファイルに書き込み。
テキストファイルをUnityが読み込んで自然言語処理AIと美少女が連携する仕組みを作っていたのですが、このやり方だと毎回、ジュネレーターが初期化されてしまい、時間的ロスが発生します。
というわけで調べましたよ。ローカルネットワーク内で動くアプリケーション鯖の立て方を。では早速立てていきましょう。

【参考記事】

https://qiita.com/MuAuan/items/ce45f26b961e39c68d32

①仮想環境を作成し、立ち上げる

cd C:\
mkdir convogpt_API
cd C:\convogpt_API
python -m venv env
env\Scripts\activate.bat

②flaskをインストール。

python -m pip install --upgrade pip
pip install flask

③convogpt環境を作る(下記参照の為)

https://github.com/harubaru/convogptからconvogpt-main.zipをDLして解凍。
convogpt-mainの内容をC:\convogptに丸ごとコピー
各種ライブラリをインストール。

cd C:\convogpt_API\models
mkdir rinna
cd rinna
git lfs install
git clone https://huggingface.co/rinna/japanese-gpt-1b
cd C:\convogpt_API

python -m pip install -r requirements.txt
python -m pip install --upgrade pip setuptools
pip install transformers
pip install sentencepiece
pip install pandas
pip install ja-sentence-segmenter

https://note.com/tori29umai/n/n3cd8c5b32f7a
の①の手順を実行した後、以下を実行。

python -m pip install -U pip setuptools 
pip3 install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu117

④以下のスクリプトを作成
C:\convogpt_API\API.py"

from flask import Flask, request
import local_llm
import Textformat

llm = local_llm.GPTGenerator()
app = Flask("__init__")

@app.route("/", methods=['POST'])
def post():
    inputtext =  request.form['inputtext']
    res1 = llm.generate(inputtext)
    res2 = Textformat.Textformat(res1)
    res = res2.encode('utf-8')
    return res

app.run(host="127.0.0.1", port=5000)

"C:\convogpt_API\local_llm.py"

import functools
from ja_sentence_segmenter.common.pipeline import make_pipeline
from ja_sentence_segmenter.concatenate.simple_concatenator import concatenate_matching
from ja_sentence_segmenter.normalize.neologd_normalizer import normalize
from ja_sentence_segmenter.split.simple_splitter import split_newline, split_punctuation

split_punc2 = functools.partial(split_punctuation, punctuations=r"。!?")
concat_tail_te = functools.partial(concatenate_matching, former_matching_rule=r"^(?P<result>.+)(て)$", remove_former_matched=False)
segmenter = make_pipeline(normalize, split_newline, concat_tail_te, split_punc2)

def Textformat(text):
    res1 = "\n".join(text)
    res2 = list(segmenter(res1))
    res3 = res2[0]
    res = ''.join(res3)
    return res

"C:\convogpt_API\Textformat.py"(これはテキスト整形の為の処理なので不別の手段使うなら不要です)

import functools
from ja_sentence_segmenter.common.pipeline import make_pipeline
from ja_sentence_segmenter.concatenate.simple_concatenator import concatenate_matching
from ja_sentence_segmenter.normalize.neologd_normalizer import normalize
from ja_sentence_segmenter.split.simple_splitter import split_newline, split_punctuation

split_punc2 = functools.partial(split_punctuation, punctuations=r"。!?")
concat_tail_te = functools.partial(concatenate_matching, former_matching_rule=r"^(?P<result>.+)(て)$", remove_former_matched=False)
segmenter = make_pipeline(normalize, split_newline, concat_tail_te, split_punc2)

def Textformat(text):
    res1 = "\n".join(text)
    res2 = list(segmenter(res1))
    res3 = res2[0]
    res = ''.join(res3)
    return res

Unity側(プロジェクトは適当に作っておいてください)
EditorRunTerminal.cs

using UnityEngine;
using TMPro;
using UnityEngine.Networking;
using System.Collections;

public class EditorRunTerminal : MonoBehaviour
{
    private const string URL = "http://127.0.0.1:5000/";
    public TMP_InputField inputField;
    public static string Message;

    public void RunTerminal()
    {
        UImanager.thinking = true;
        StartCoroutine("OnSend", URL);
    }

    IEnumerator OnSend(string url)
    {
        WWWForm form = new WWWForm();
        form.AddField("generate_check", "on");
        form.AddField("inputtext", inputField.text);

        using UnityWebRequest webRequest = UnityWebRequest.Post(url, form);
        webRequest.downloadHandler = new DownloadHandlerBuffer();
        yield return webRequest.SendWebRequest();
        UnityEngine.Debug.Log(webRequest.downloadHandler.text);
        Message = webRequest.downloadHandler.text;
        LoadModel.CallVoice.Speak();
    }
}

④鯖を有効にしてUnity側で受け取る

python API.py

Unity
Edit→ProjectSetting→Player→Allow downloads over HTTP
をAlways Allowedにする。

んでなんか動きましたやったー!!!

これだけだとなんなので自分のハマリどころを。

こちらの記事を参照にメモリリークを解決しました。
UnityWebRequest webRequest = UnityWebRequest.Post(url, form);

using UnityWebRequest webRequest = UnityWebRequest.Post(url, form);

よくわからんが動いたのでヨシ!!!!

この記事が気に入ったらサポートをしてみませんか?