![images](../img/imgtop_sub_b.png)
感情分析のエンジンと、そのサーバ〜クライアントを作ってみます。
関連
- ◯
- サーバ証明書を取得〜更新する(ワイルドカード証明書、ネームサーバ経由):Let's Encrypt
検証
- ・
- クラウド:GCP
- ・
- コンテナ:Docker
- ・
- ゲストOS:Ubuntu 22.04
- ・
- ウェブブラウザ:Chrome
- ・
- 画像生成アプリ:ComfyUI
概要
- ◯
- 背景
いまは感情分析のモデルを、ローカル環境で動かすことができます。
- ◯
- 対応
ここでは、感情分析のエンジンと、そのサーバ〜クライアントの、かんたんな実装を試みます。
- ◯
- 構成
言語モデルに LUKE 、データセットに愛媛大学のもの(プルチックの「感情の輪」にもとづく)を使用した感情分析のモデルを使います:[※1]
- ・
- https://huggingface.co/Mizuiro-sakura/luke-japanese-large-sentiment-analysis-wrime
- ※1
- エクマンもそうですが、感情を分類できるという主張は、すでに否定されていますーーとはいえ、生成モデルとの組み合わせでは使い勝手がいいので、テキストから8コの感情を抽出するプルチックのモデルを採用します(XML にもエクマンの感情分類をもとにした仕様があり、表現という点から一定の需要はあるのかもしれませんね)。
設置
環境は、音声認識エンジン向けに作ったコンテナ/ライブラリを流用します:
- ◯
- 音声認識のエンジン/サーバ/クライアントを作る:Python (Transformers, aiohttp), Javascript (MediaRecorder)
実装
- ◯
- バックエンド:エンジン
- ・
- appsen/bin/senprc.py
import torch from transformers import AutoTokenizer, AutoModelForSequenceClassification, LukeConfig class SenPrc: def __init__(self, lenmax, nmodel): self.lenmax = lenmax cnfluk = LukeConfig.from_pretrained( nmodel, output_hidden_states=True) self.omodel = AutoModelForSequenceClassification.from_pretrained( nmodel, config=cnfluk) self.tokenz = AutoTokenizer.from_pretrained( nmodel) def getsen(self, txtreq): inputs = self.tokenz( txtreq, truncation=True, max_length=self.lenmax, padding="max_length") output = self.omodel( torch.tensor(inputs["input_ids"]).unsqueeze(0), torch.tensor(inputs["attention_mask"]).unsqueeze(0)) maxsen = torch.argmax( torch.tensor(output.logits)) numsen = maxsen.item() return numsen
- ◯
- バックエンド:サーバ
- ・
- appsen/bin/sensrv.py
import json from aiohttp import web from senprc import SenPrc async def res001(datreq): dicreq = await datreq.json() txtreq = dicreq["txtreq"] numres = senprc.getsen(txtreq) return web.Response( text=json.dumps({"numres": numres}), content_type="application/json", ) prttgt = 8081 adr001 = "/" lenmax = 512 nmodel = "Mizuiro-sakura/luke-japanese-large-sentiment-analysis-wrime" senprc = SenPrc(lenmax, nmodel) appweb = web.Application() appweb.add_routes([web.post(adr001, res001)]) web.run_app(appweb, port=prttgt)
- ◯
- フロントエンド:クライアント
- ・
- appsen/bin/senclt.py
import sys import asyncio import aiohttp async def req001(dicreq): async with aiohttp.ClientSession() as sssweb: async with sssweb.post(adr001, json=dicreq) as datres: dicres = await datres.json() return dicres txtreq = sys.argv[1] adr001 = "http://localhost:8081/" dicreq = {"txtreq": txtreq} dicres = asyncio.run(req001(dicreq)) print(dicres["numres"])
利用
コンテナ上で、サーバを起動し〜クライアントを実行します:
# サーバ $ python /system/vol104/bin/sensrv.py & # クライアント $ python /system/vol104/bin/senclt.py 'きょうは楽しい一日だった'