AI/機械学習の技術がすごく進んでいて、その中に文書要約があります。長い文書を短く要約すると目を通す時間を短縮できて便利です。
この技術を導入したいと考えましたが、外部サービスへデータを流し込むのはためらわれます。BERTやGPT-2を使った文書要約の記事も多々ありますが、これらは単純化されていて(とても参考になります)、次々と要約をしていきたい場合には初期化処理が長くなりすぎてさすがに待てません。
そこで試行としてローカルで動作する要約化するサーバーを作ってみることにしました。普段Pythonでコーディングをしないので、そのトライアルを兼ねています。
使用環境
ここでは以下を用いました。
- Python(3.9.0) Windows版
- Django : Webアプリケーション用フレームワーク
- TransformerSummarizer : 文書要約(gpt2-mediumを用いました)
- Excel & VBA : 呼び出し側
最初は標準のhttp.serverで実現しようとしましたが、私に理解する範囲では処理の重い初期化を外出しできませんでした。
仕様
ここではHTTP/POSTでtargetTextパラメータに変換したい元の文書を入れて送ると、要約文が返信されることとしました。手動で利用するものとプログラムからコールするものの2種類を作成しました。
当初GETで作っていましたが対象の文が長くなったときに問題が生じました。調べてみるとURLには長さ制限があるようです。長いから要約したいので2000文字程度で制限があるのは本末転倒です。
コード
特徴のある部分だけ抜き出しています。これら以外にDjangoで動作するために幾つかの設定が必要です。
view.pyは以下の通りとしました。modelの初期化を変更するとBERTを使うなどの変更が可能です。
from django.shortcuts import render
from django.http import HttpResponse
from summarizer import Summarizer,TransformerSummarizer
from django.views.decorators.csrf import csrf_exempt
#model = Summarizer()
model = TransformerSummarizer(transformer_type="GPT2",transformer_model_key="gpt2-medium")
@csrf_exempt
def index(request):
targetText = request.POST.get("targetText")
targetAbst = 'empty'
if targetText is not None:
targetAbst = ''.join(model(targetText, min_length=20))
content = {
'target_text':targetText,
'target_abst':targetAbst,
}
return render(request, 'call/index.html', content)
@csrf_exempt
def api(request):
targetText = request.POST.get("targetText", None)
targetAbst = 'empty'
if targetText is not None:
targetAbst = ''.join(model(targetText, min_length=20))
content = {
'target_text':targetText,
'target_abst':targetAbst,
}
return HttpResponse(targetAbst)
#return render(request, 'call/api.html', content)
index.htmlは以下の通りとしました。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<h1>form</h1>
<p>text : {{target_text}}</p>
<p>abst : <div id="abstract">{{target_abst}}</div></p>
<form action="http://127.0.0.1:8000/call/" method="POST">
<textarea rows="10" cols="60" name="targetText"></textarea>
<input type="submit"/>
</form>
</body>
</html>
api.htmlは以下の通りとしました。
Excel(に特に限りませんが)のVBAから呼び出すプログラムは以下のようになります。
{{target_abst}}
ここで文字列をUTF-8に変換する関数( encodeString2UTF8 )を別に必要とします。
Function getAbstract(targetText As String) As String
Dim httpRequest As XMLHTTP60
Set httpRequest = New XMLHTTP60
utfText = encodeString2UTF8(targetText)
postUrl = "http://127.0.0.1:8000/call/api/"
postParams = "targetText=" & utfText
httpRequest.Open "POST", postUrl, False
httpRequest.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
httpRequest.send (postParams)
Do While httpRequest.readyState < 4
DoEvents
Loop
getAbstract = httpRequest.responseText
Set httpRequest = Nothing
End Function