2020年10月13日 Python3.8 に対応しました
はじめに
形態素解析を行うライブラリ MeCab を用いたアプリケーションをサーバーレスな環境に乗せる機会があり、今後も増えてきそうなので自分用のメモの意味も含めその手順を記載しました。
MeCabをLambda上で実行するためには、Lambdaの実行環境と全く同じ環境でMeCabをビルドし、関数パッケージに含めてデプロイする必要があります。
今回は、DockerとLambdaビルド用のイメージを使って、簡単にMeCabをビルドする方法を紹介します。
※下記のリポジトリよりクローンし、READMEの手順を実行すれば簡単に利用できます。
[GitHub] noyoikw/mecab-python3-lambda
各ファイルの解説
手順の前に、最終的なディレクトリの構成と各ファイルの役割について説明します。
ディレクトリ構成
このサンプルでは、最終的に以下のようなディレクトリ構成になり、 function
配下を Lambda にデプロイすることを目指します。
mecab-python3-lambda
├── docker-compose.yaml
├── function
│ └── lambda_function.py
└── requirements.txt
docker-compose.yaml
DockerComposeを用い、function
配下にMeCabをビルドします。
Lambdaにパッケージをデプロイすると、内部的には /var/task
配下にファイルが置かれるので、それにあわせてビルド先を設定しています。
また、Python3 で MeCab を利用するためのパッケージ mecab-python3
のインストールも含めます。
version: '3'
services:
mecab-python3-lambda:
image: lambci/lambda:build-python3.8
environment:
- AWS_DEFAULT_REGION=ap-northeast-1
- LAMBDA_PACKAGE_DIR=/var/task
- MECAB_SOURCE_URL=https://drive.google.com/uc?export=download&id=0B4y35FiV1wh7cENtOXlicTFaRUE
- IPADIC_SOURCE_URL=https://drive.google.com/uc?export=download&id=0B4y35FiV1wh7MWVlSDBCSXZMTXM
- MECAB_VERSION=0.996
- IPADIC_VERSION=2.7.0-20070801
- LIB_MECAB_DIR_NAME=.mecab
volumes:
- ./function:/var/task
- ./requirements.txt:/requirements.txt
command: >
/bin/sh -c '
cd ~ &&
curl -L $${MECAB_SOURCE_URL} -o mecab.tar.gz &&
curl -L $${IPADIC_SOURCE_URL} -o mecab-ipadic.tar.gz &&
tar -zxvf mecab.tar.gz && tar -zxvf mecab-ipadic.tar.gz &&
cd ~/mecab-$${MECAB_VERSION} &&
./configure --prefix=$${LAMBDA_PACKAGE_DIR}/$${LIB_MECAB_DIR_NAME} --with-charset=utf8 &&
make && make install &&
cd ~/mecab-ipadic-$${IPADIC_VERSION} &&
./configure --prefix=$${LAMBDA_PACKAGE_DIR}/$${LIB_MECAB_DIR_NAME} --with-charset=utf8 --with-mecab-config=$${LAMBDA_PACKAGE_DIR}/$${LIB_MECAB_DIR_NAME}/bin/mecab-config &&
make && make install &&
cd ~ && pip3 install -r /requirements.txt -t $${LAMBDA_PACKAGE_DIR}'
image
dockerhubで、lambciが提供する、 lambci/lambda:build-python3.8
を使用します。
これは、実際のLambda環境を再現したサンドボックス環境のDockerイメージです。
(ランタイムはpython3.8のビルド用のイメージ)
environment
ディレクトリの設定やバージョンを記載します。
MECAB_SOURCE_URL
や IPADIC_SOURCE_URL
はMeCab作者のサイトから削除・変更等があった場合は適宜変更してください。
volumes
function
ディレクトリ配下をパッケージとしてデプロイするので、 /var/task
にマウントします。
requirements.txt
は、コンテナ側で実行するコマンドで使用するためマウントします。
command
やっていることは、 MeCab
と ipadic
をダウンロード、インストールしているだけです。
最後に mecab-python3
をインストールします。
requirements.txt
今回利用するパッケージは mecab-python3
のみですが、Pythonのコード内で他のパッケージを利用する場合は追記してください。
mecab-python3
lambda_function.py
Lambdaにデプロイするファンクションの本体です。
前半部分では、ビルドしたMeCabをライブラリとして使用できるようにロードしています。
import MeCab
は mecab-python3
のパッケージをインポートしています。
今回はサンプルとして、ボディにテキストを付与してリクエストすると、形態素解析の結果をレスポンスとして返する関数を作成しました。
import json
import os
import ctypes
mecabdir = os.path.join(os.getcwd(), '/var/task/.mecab')
libmecab = ctypes.cdll.LoadLibrary(os.path.join(mecabdir, 'lib/libmecab.so'))
import MeCab
output_format_type = 'chasen'
dicdir = os.path.join(mecabdir, 'lib/mecab/dic/ipadic')
rcfile = os.path.join(mecabdir, 'etc/mecabrc')
tagger = MeCab.Tagger('-O{} -d{} -r{}'.format(output_format_type, dicdir, rcfile))
def lambda_handler(event, context):
req_body = json.loads(event['body'])
res_body = {
'morphemes': tagger.parse(req_body['text'])
}
return {
'statusCode': 200,
'headers': {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
},
'body': json.dumps(res_body)
}
ビルドとデプロイ手順
実際に行う手順を解説していきます。
1. ビルド
作業フォルダのルートに移動して、下記コマンドを実行します。
$ docker-compose up
指定したDockerイメージがビルドされ、 docker-compose.yaml
内に記載したコマンドが実行されます。
しばらくすると、 function
配下にMeCabのライブラリとpipでインストールしたパッケージが追加されます。
mecab-python3-lambda
├── docker-compose.yaml
├── function
│ ├── .mecab/
│ ├── bin/
│ ├── MeCab/
│ ├── mecab_python3-1.0.1.dist-info/
│ └── lambda_function.py
└── requirements.txt
2. function配下をzipに圧縮
デプロイ用のパッケージとして、Lambdaにアップロードできる形式(.zip)にします。
下記コマンドを実行すると、 function
配下を圧縮した deploy_package.zip
が生成されます。
$ cd function && zip -r ../deploy_package.zip * .*
3. AWSのコンソールからLambdaにデプロイ
あらかじめLambdaのリソースを作成し、 関数コード
の項目から、
- コード エントリ タイプ →
.zip ファイルをアップロード
- ランタイム →
Python 3.8
- ハンドラ →
lambda_function.lambda_handler
- 関数パッケージ →
アップロード
をクリックしてdeploy_package.zip
を選択
最後に、最上右部の 保存
をクリックして、デプロイ完了です。
4. 動作確認
3.
の Lambda を API Gateway とつなぎ、APIをコールしてみます。
今回は、ステージ名を dev
、リソース名を mecab
としています。
※ 日本語で確認したいため、 jq を利用しています。
curl -X POST -H "Content-Type: application/json" -d '{"text":"この文章は形態素解析のテストです。"}' https://xxxxxx.execute-api.us-west-2.amazonaws.com/dev/mecab | jq .
以下のようなレスポンスが確認できれば成功です!
{
"morphemes": "この\tコノ\tこの\t連体詞\t\t\n文章\tブンショウ\t文章\t名詞-一般\t\t\nは\tハ\tは\t助詞-係助詞\t\t\n形態素\tケイタイソ\t形態素\t名詞-一般\t\t\n解析\tカイセキ\t解析\t名詞-サ変接続\t\t\nの\tノ\tの\t助詞-連体化\t\t\nテスト\tテスト\tテスト\t名詞-サ変接続\t\t\nです\tデス\tです\t助動詞\t特殊・デス\t基本形\n。\t。\t。\t記号-句点\t\t\nEOS\n"
}
最後に
いかがでしたでしょうか。Lambdaの環境を再現しれくれる便利なDockerイメージのおかげで、簡単にMeCabをビルドできました。
今回の環境構築はあくまでMeCabのビルドを行うためのものなので、MeCabを利用したAPIを開発・運用して行く際には、今回ビルドしたMeCabを開発用環境のリポジトリに置いてしまうのが良いかと思います。
参考文献
MeCab
Docker Hub - lambci
[AWS Lambda でMeCabを動かす (2018年9月時点)]
(https://qiita.com/rtaguchi/items/e6cb594196fa8186e9a2)
AWS Lambda x Pythonでのローカル開発環境の再現について