本記事の目的
Azure Data Factoryの前処理で、MeCabを利用した簡単な自然言語処理(形態素解析+α程度)をしたい。
関数として実装して、後々LogicAppsとか色々なサービスから呼び出せれば便利そう。ということで2つの実装方法を検討した。
- Azure Functions(本記事)
- Azure DataBricks(Azure DatabricksでPythonとMeCabを使う)
機械学習のように重たい処理を行うわけではないのでAzure Functionsで十分だろう、ということで実装してみた。
先に結論を書くと
・Azure FunctionsのHTTP Requestをトリガーとする関数は以下のURLを参考にすれば実装できる
Visual Studio Code を使用して Azure Functions プロジェクトを作成する
https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-create-first-function-vs-code?pivots=programming-language-csharp
・Mecabは.vscodeのrequirements.txtに「mecab-python3」を追記すればFunctions側でも使える
・Azure Functionsの毎月の無料枠がわりと太っ腹なので、しばらくは無料で試せそう
あとはいくつか躓いた点の備忘録です。
理解不足の点も多々あるので、間違いなどあればご指摘下さい。
Azure Functions概要
イベントドリブン型のサーバーレスコンピューティングプラットフォーム。設定したトリガーで起動し、関数の実行中のみコンピューティングリソースを消費するので無駄なコストを削減できる。
課金体系
Functionsのホスティングプランには次の3つがあるが、一番左の「従量課金プラン」がいわゆる通常のサーバーレス。今回はこれを選択した。
Azure Functions - 料金設定
https://azure.microsoft.com/ja-jp/services/functions/#pricing
なお、課金は実行数、実行時間、およびメモリの使用量で決まる。毎月リセットされる無料枠があり、「100万実行回数」「400,000GB秒」までは無償らしい。
ランタイムスタック(言語)
.Net Core, Node.js, Python, Java, Powershell Coreから選択できる。
1つ注意する点だが、ランタイムスタックにPythonを選択した場合、OSはLinuxのみ対応となる。Linuxの従量課金プランは現状、日本の両リージョンでは未対応とのことで、別のリージョンを選択する必要がある。(2020年5月現在)
※東日本リージョンでは、2020年の第2QにGA予定
対応リージョンは「リージョン別の利用可能な製品」から確認できる。
トリガー
Functionsを起動するためのトリガーには、HTTP Request, Timer, BLOB, eventhubなどがある。今回は使い勝手が良さそうなのでとりあえずHTTP Requestで実装。BLOBファイルが作成されたら実行、というのも使いやすそう。
Azure PortalからFunctions Appsを作成
従量課金プランでPythonを使いたかったので、今回はとりあえずリージョンをEast Asiaで作成。(従量課金プラン Linuxに対応していれば別にどこでも良い。地理的にはソウルのKorea Centralの方が近かった。)
これでLinuxの従量課金が選択できるようになった。
またFunctionsからリンクするストレージアカウントも用意する必要があるので、今回は新規作成。
監視のためのApplication Insightもこのタイミングで作成しておく。
これで実行のログが確認できるようになる。
これで作成すると4つのリソースが作成される。
- 関数アプリ(Functionsのこと)
- Application Insights
- ストレージアカウント
- App Serviceプラン
料金プランで消費量(サーバーレス)を選択したのに、なぜApp Serviceプランというリソースが作成されるのかは不明。
ローカルでの開発とFunctionsへのデプロイ
.NETの場合はAzure Portalの画面上で関数を作成できるのだが、Pythonの場合には残念ながら対応していない。したがってローカルで開発とテストを実行した後、Functionsにデプロイする、という手順になる。
具体的な手順は以下の記事を参照して進めた。
Visual Studio Code を使用して Azure Functions プロジェクトを作成する
https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-create-first-function-vs-code?pivots=programming-language-csharp
ローカルに以下の環境が必要になるので、インストールしておく。
・Node.js
・Python 3.8、Python 3.7、Python 3.6のいずれか
・Visual Studio Code
・Visual Studio Code 用の Python 拡張機能
・Visual Studio Code 用 Azure Functions 拡張機能
・Azure Functions Core Tools
躓いた点
1. ローカル環境でのAzure Functions実行時のエラー1
FunctionsをLocalで実行する際に権限エラー。
エラーメッセージ
このシステムではスクリプトの実行が無効になっているため、ファイルを読み込むことができません。
PowerShellのExecution Policyを変更する必要があった。
初回だけExecutionPlicyをRemoteSignedにあげて実行すると、その後はRestrictedに戻してもエラーは解消された。
About Execution Policies
https://docs.microsoft.com/ja-jp/powershell/module/microsoft.powershell.core/about/about_execution_policies?view=powershell-7
2. ローカル環境でのAzure Functions実行時のエラー2
__init__.py上での以下のコードでエラー
import azure.functions as func
エラーメッセージ
Unable to import 'azure.functions' pylint(import-error) [3, 1]
ローカルに複数のPythonバージョンが混在していることによる問題だったようで、他のランタイムに切り替えることによって解決。
3. FunctionsへのMeCabの追加
.vscodeのrequirements.txtに対してライブラリを追記をするとFunctions側でpip installしてくれるっぽい。
ということで以下を追記。
・mecab-python3
あとはいつも通り。
import MeCab
mecab = MeCab.Tagger("-Ochasen")
parsedsentence = mecab.parse(sentence)
まとめ
FunctionsにおけるMeCab利用は意外にもすぐできた。今回の目的に合致するものはFunctionsで十分。
(ただしmecabの辞書本体がどこにあるのか含め、なぜ動くのかいまいち理解できてません...)
従量課金プランは最大のタイムアウトまでの時間が10分になっているので、あくまでも軽量の実行用。もう少し手の込んだものを実行する場合は、Functionsでも別のホスティングプランを利用するか、いっそDataBricksを採用するのが良さそう。
Azure Functions のスケールとホスティング
https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-scale#service-limits
費用の確認
Azure PortalからMetricを呼び出すことによって、かかった費用が分かる。
「入力の1文に対してMecabで形態素解析した結果を返す」というシンプルな関数を1回実行した結果が以下の通り。
単位はFunction Execution Unitを選択すればよい。Function Execution Unitの単位は【MB milliseconds】なので、これを課金の単位である【GB seconds】に変換する。
今回は163.58 k = 163,580 MB millisecondsなので、
163,580 / 1,024,000 = 0.15974609375 【GB seconds】
毎月「100万実行回数」「400,000GB秒」までは無償ということで、多少テストするくらいなら全然無償枠で収まりそう。
もちろん、同時に作成しているBLOBなどの課金は発生するので注意。