Django + KoNLPy + MeCabアプリをHerokuにデプロイ

Django, Python初心者のため不適切な箇所がありましたらご指摘くださいm( )m

筆者が使用しているのはmecab-koですが、mecabと概ね同じ手順になると思います。

ローカルでのKoNLPyとMeCabのセットアップ手順はこちらの記事に書いています

pythonで韓国語の形態素解析 - mnlog

ローカル開発環境

Python 3.6.3
pip 20.0.2
仮想環境にvenv使用
Django 3.0.5

Herokuのセットアップ

しばらくはこちらの2記事を参考に進めていきます。

DjangoアプリをHerokuにデプロイする方法 - Qiita

Herokuでpython+mecab+ffmpegを使う - Qiita

※ Heroku CLIは導入済みとする

HerokuでDjangoを動かすための準備

#### gunicorn, django-heroku, dj-database-url インストール

$ pip install gunicorn django-heroku dj-database-url

requirements.txt 作成

$ pip freeze > requirements.txt

Procfile 作成

$ echo web: gunicorn プロジェクトフォルダー名.wsgi --log-file - > Procfile

HerokuにMeCabをインストールするための準備

buildpackのセットアップ

$ heroku create --buildpack https://github.com/heroku/heroku-buildpack-multi

.buildpacks ファイルに使用するbuildpackを記載します。

一つ目がMeCabのインストールに使用するlinuxbrewのbuildpack、

二つ目がPythonの環境セットアップとpip installに使用するbuildpackです。

記載した順に実行される点に注意です。

https://github.com/sunny4381/heroku-buildpack-linuxbrew.git
https://github.com/heroku/heroku-buildpack-python.git

環境変数の設定

$ heroku config:add LD_LIBRARY_PATH=/app/.linuxbrew/lib
$ heroku config:set MECAB_PATH=/app/.linuxbrew/lib/libmecab.so

デプロイ

$ git push heroku master

あとはherokuにデプロイするだけ...のはずですが、mecab-pythonがインストールできないとエラーが出てしまいました。

remote:        ERROR: Could not find a version that satisfies the requirement mecab-python===0.996-ko-0.9.2 (from -r /tmp/build_1e762344b37986e0579cf1ef71b4961c/requirements.txt (line 16)) (from versions: 0.993, 0.996, 1.0.0rc1, 1.0.0rc2, 1.0.0)
remote:        ERROR: No matching distribution found for mecab-python===0.996-ko-0.9.2 (from -r /tmp/build_1e762344b37986e0579cf1ef71b4961c/requirements.txt (line 16))
remote:  !     Push rejected, failed to compile Multipack app.
remote: 
remote:  !     Push failed

Herokuではmecab-pythonがインストールできないようなので、mecab-python3に書き換えます。 韓国語専用パッケージではありませんがローカルでは問題なく動作しました。

$ pip uninstall mecab-python
$ pip install mecab-python3
$ pip freeze > requirements.txt

heroku pushしたところ、今度はビルドに成功したものの、Slug Sizeが上限の500MBを超えてしまいました...😭

-----> Compressing...
 !     Compiled slug size: 529.5M is too large (max is 500M).
 !     See: http://devcenter.heroku.com/articles/slug-size
 !     Push failed

デプロイ後にpip installを行う設定

pip installをデプロイ後に行うことでSlug Sizeを節約します。

丸ごと後回しにしたいところですが、heroku-buildpack-pythonによる周辺環境セットアップでエラーを発生させないよう、今回はrequirements.txtからmecab-python3とkonlpyを削除して後からインストールする形にします。

次にProcfileの中身を書き換えシェルスクリプトを実行するようにします。

web: bash run.sh
python3 -m pip install mecab-python3 konlpy
gunicorn analysisapi.wsgi --log-file -
$ git push heroku master

試行錯誤の結果、デプロイに成功しました! これでもSlug Sizeがギリギリ(494.8M)なので、herokuでMeCabを使う限界を感じます...。

またデプロイに成功したものの、アプリの実行時に辞書のロケーションでエラーが発生してしまいました。

The MeCab dictionary does not exist at "/usr/local/lib/mecab/dic/mecab-ko-dic". Is the dictionary correctly installed?
You can also try entering the dictionary path when initializing the Mecab class: "Mecab('/some/dic/path')"
dicdir = /app/.linuxbrew/lib/mecab/dic/mecab-ko-dic

エラーメッセージの通り、辞書のパスをクラスの初期化時に渡してあげるといいようです。

pythonで韓国語の形態素解析

pythonで韓国語の形態素解析をするため、KoNLPyを導入してみます。

インストール

$ pip install konlpy

MeCabのインストール

taggerMeCabを使用する場合は、別途MeCabのインストールが必要です。 taggerは数種類をサポートしていますが、今回は実行速度が圧倒的に速いMeCabを導入します。

読み込み時間(クラスと辞書)

  • Kkma: 5.6988 secs
  • Komoran: 5.4866 secs
  • Hannanum: 0.6591 secs
  • Okt (previous Twitter): 1.4870 secs
  • Mecab: 0.0007 secs

実行時間(100K characters)

  • Kkma: 35.7163 secs
  • Komoran: 25.6008 secs
  • Hannanum: 8.8251 secs
  • Okt (previous Twitter): 2.4714 secs
  • Mecab: 0.2838 secs

Morphological analysis and POS tagging — KoNLPy 0.5.2 documentation より

$ bash <(curl -s https://raw.githubusercontent.com/konlpy/konlpy/master/scripts/mecab.sh)

内部ではmecab-koとmecab-ko-dic、mecab-pythonのインストールが行われています。(私はすでに前者2つはインストール済みでした。)

$ bash <(curl -s https://raw.githubusercontent.com/konlpy/konlpy/master/scripts/mecab.sh)  
Installing automake (A dependency for mecab-ko)
==> Downloading https://homebrew.bintray.com/bottles/automake-1.16.2.mojave.bottle.tar.gz
==> Downloading from https://akamai.bintray.com/fe/fe26d4df57481b6a7ca0a6915c37c53648c27ffb41926b3570c45f80fdd8888e?__gda__=exp=1587821736~h
######################################################################## 100.0%
==> Pouring automake-1.16.2.mojave.bottle.tar.gz
🍺  /usr/local/Cellar/automake/1.16.2: 131 files, 3.4MB
mecab-ko is already installed
mecab-ko-dic is already installed
Install mecab-python
/tmp ~/api-env/python-analysis-api
Cloning into 'mecab-python-0.996'...
remote: Counting objects: 17, done.
remote: Compressing objects: 100% (16/16), done.
remote: Total 17 (delta 3), reused 0 (delta 0)
Unpacking objects: 100% (17/17), done.
~/api-env/python-analysis-api
Processing /tmp/mecab-python-0.996
Installing collected packages: mecab-python
  Running setup.py install for mecab-python ... done
Successfully installed mecab-python-0.996-ko-0.9.2
You are using pip version 9.0.1, however version 20.0.2 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
Done.

動作確認

$ python
>>> from konlpy.tag import Mecab
>>> from konlpy.utils import pprint
>>> mecab = Mecab()
>>> pprint(mecab.pos("빨리 가자."))
[('빨리', 'MAG'), ('가', 'VV'), ('자', 'EF'), ('.', 'SF')]

rake db:migrateでmigrationファイルのパス指定

config/application.rb(全環境向け)か、config/environments/#{environment}.rbに以下の行を追加する。

config.paths['db/migrate'] = ['your_migrate_path']

デフォルトのdb/migrateと両方読み込みたい場合は

config.paths['db/migrate'] << 'your_migrate_path'

と言うのも、redmineプラグイン開発で個別プラグインマイグレーションはどうするんだろうと思って調べました。 正しくは

rake redmine:plugins:migrate

でよかった。。

macOS High Sierraにしたらhomebrewが使えなくなった

環境

macOS High Sierra 10.13.1

事象

正確に言うと以下のようなメッセージが表示されてbrew installが使えなくなりました。

xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun

解決法

上記のエラーメッセージで検索すると、gitが使えない!という内容の記事がたくさん見つかりました。

Mac OS Sierraにしたらgitコマンド、ターミナル上にエラーが出てしまった。 - Qiita

El Capitanにしたらgitコマンド(CUI)が動かなくなった。 - Qiita

上記の記事を参考に、xcode-selectコマンドを実行することで無事解決できました。

$ xcode-select --install

上のコマンドは何?

Xcode Command Line Toolsをインストールするもの。 このツールがあることでgitgccmakeといったコマンドが使えるようになります。

Xcode本体に付属していますが、iOSアプリ開発をしないならCLIを単体で入れた方が数GB容量を節約できます。

OSがアップデートされるたびにCLIも入れ直す必要があるみたいですね。

なぜbrew installが使えなくなったのか?

brewコマンド自体は自分でバイナリインストールしたはずなのでCLIは一見関係なさそうなのが心に引っかかりました。

homebrewの仕組みを調べて見たところ、installの内部ではmake installを実行しているようでCLIに入っているmakeが使えないことが原因だったみたいです。

Homebrew — macOS 用パッケージマネージャー

Homebrew の formula はシンプルな Ruby スクリプトです:

class Wget < Formula
  homepage "https://www.gnu.org/software/wget/"
  url "https://ftp.gnu.org/gnu/wget/wget-1.15.tar.gz"
  sha256 "52126be8cf1bddd7536886e74c053ad7d0ed2aa89b4b630f76785bac21695fcd"

  def install
    system "./configure", "--prefix=#{prefix}"
    system "make", "install"
  end
end

最後に:CLIのバージョンを確認する方法

brew --config出力結果のCLIを参照します。

$ brew --config
HOMEBREW_VERSION: 1.3.9
ORIGIN: https://github.com/Homebrew/brew
HEAD: 4f5e938a5dbe049e05dea19495b6547acc5c5b5b
Last commit: 4 days ago
Core tap ORIGIN: https://github.com/Homebrew/homebrew-core
Core tap HEAD: 2dfcf690f03253ad124dc1c8dae46ef0e82c98c6
Core tap last commit: 5 hours ago
HOMEBREW_PREFIX: /usr/local
CPU: quad-core 64-bit broadwell
Homebrew Ruby: 2.3.3 => /usr/local/Homebrew/Library/Homebrew/vendor/portable-ruby/2.3.3/bin/ruby
Clang: 9.0 build 900
Git: 2.13.6 => /Library/Developer/CommandLineTools/usr/bin/git
Curl: 7.54.0 => /usr/bin/curl
Perl: /usr/bin/perl
Python: /usr/local/opt/python/libexec/bin/python => /usr/local/Cellar/python/2.7.14/Frameworks/Python.framework/Versions/2.7/bin/python2.7
Ruby: /Users/manami/.rbenv/shims/ruby => /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/bin/ruby
Java: 1.8.0_121
macOS: 10.13.1-x86_64
Xcode: 9.1
CLT: 9.1.0.0.1.1508540944
X11: N/A

このトラブルを通じてGNU Makeに興味が出てきたのでさらに勉強してみようー