背景
Neologdの辞書が重すぎて、Cloud Functionsに乗らない。
でも、サーバ料金を押さえたいので、なんとかして乗せたい。お金ない。
・環境
Mac macOS Mojave(10.14.2)
・Cloud Functions
言語はPython3、トリガーはhttpです。
参考記事
方針
参考記事に書かれているように、neologd辞書を--eliminate-redundant-entry
で縮小し、zip化することで100MB以下に納め、デプロイするという作戦です。
--eliminate-redundant-entry オプションとは
mecab-ipadic-NEologd
"--eliminate-redundant-entry" オプションを指定した場合は、正規化済みの日本語テキストを単語分割するための別称・異表記・表記揺れなどを一切考慮できない辞書を、512MByte 程度の空きメモリ領域があればインストールできます。
Functionのデプロイ方法
- APIのコードとneologd辞書をzip化(mecab.zip)してCloud Storageに配置
- Storageのパスを指定してFunctionを作成します
デプロイコマンドはこんな感じ。
gcloud beta functions deploy mecab \
--source=gs://<バケット名>/mecab.zip \
--stage-bucket=<バケット名> \
--trigger-http \
--memory=512MB \
--runtime=python37 \
--region=asia-northeast1 \
--project=<プロジェクト名>
mecab.zip
mecab.zipは下記ファイルとフォルダを一つのzipにしたものです。
このmecab.zipは、上記デプロイコマンドを打つ前にStorageにデプロイしておきます。
$ tree
.
├── main.py # Functionのコード
├── neologd-light # 辞書
│ ├── char.bin
│ ├── dicrc
│ ├── left-id.def
│ ├── matrix.bin
│ ├── pos-id.def
│ ├── rewrite.def
│ ├── right-id.def
│ ├── sys.dic
│ └── unk.dic
└── requirements.txt
下記コマンドでmecab.zipを作成します。
$ zip -r mecab.zip *
$ tree
.
├── main.py
├── mecab.zip # 作成されたmecab.zip
├── neologd-light
│ ├── char.bin
│ ├── dicrc
│ ├── left-id.def
│ ├── matrix.bin
│ ├── pos-id.def
│ ├── rewrite.def
│ ├── right-id.def
│ ├── sys.dic
│ └── unk.dic
└── requirements.txt
各ファイルの説明
neologd-light(辞書)
Mac上でMeCabとNeologdをインストールし、作られた辞書データを使用します。
環境依存だと思っていたのでダメ元だったのですが、Cloud Functions上でそのまま動作しました。
ここでは、MeCabのインストール方法は割愛させてください。
Neologdを--eliminate-redundant-entry
オプション付きでビルドします。
$ git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git
$ cd mecab-ipadic-neologd/
$ ./bin/install-mecab-ipadic-neologd -y -p $HOME/neologd-light -n --eliminate-redundant-entry
ホームディレクトリにneologd-light
が作成されました。
main.py
import os
import json
import MeCab
# MeCab準備
# リクエスト毎ではなく、インスタンスが立った時にだけ読み込まれる
neologd_path = os.path.join(os.path.abspath(
os.path.dirname(__file__)), "neologd-light")
mcb = MeCab.Tagger('-d ' + neologd_path)
mcb.parse('')
def mecab(request):
if request.method == 'GET':
if request.args and 'text' in request.args:
text = request.args.get('text')
parsed_text = mcb.parse(text)
return json.dumps({'p_text': parsed_text}, ensure_ascii=False)
else:
print('No text.')
return ('Bad Request', 400)
requirements.txt
mecab-python3==0.996.2