tensorflow-textのインストールに苦戦した話

conda / pip の混在にこだわらなければ、もしくは初めから pipのみで環境を作っていれば何も問題がなかったのですが、
予想外に大苦戦してしまったので tensorflow-text のインストールについてメモしておきます。
(この記事は 2020年5月5日 時点の話です。近い将来のうちに、conda install でさっと入るようになるのを期待します。)

さて、そもそも変な苦労をする羽目になった背景から説明します。
condaの基本的な使い方 という記事で書いたとおり、今使っている環境はできるだけcondaのみで構築しています。
そして、 Tensorflow-Hub にある、 universal-sentence-encoder-multilingual というモデルを試したくなりました。

これを使うのに、 tensorflow_hub と tensorflow_text というライブラリをインポートする必要があります。
tensorflow_hub は 簡単です。
$ conda install tensorflow-hub
で入ります。 (インポート時とインストール時でアンダーバーとハイフンが変わる罠はありますがそれだけです。)

一方、 tensorflow_text ですが、 これが conda の公式リポジトリにも、 conda-forgeにも存在しません。
それだけならいいのですが、 conda skeleton でもエラーが出ます。
(conda skeleton についてはこちら。)


$ conda skeleton pypi tensorflow-text
# ~~ (中略) ~~
Error: No source urls found for tensorflow-text

いろいろ調査しましたが、原因は分からずとりあえず今回は condaでのインストールを諦めることにしました。

これだけ pip で入れることにしたのですが、ドキュメントにあるとおり、
>$ pip install tensorflow-text
すると、1点困ったことになります。
condaで入れていた、tensorflowなどの複数の依存ライブラリをアンインストールしてpipで入れ直してしまうのです。
(僕が確認した範囲だと7つほど影響を受けました。)
これだと、pipとcondaが大きく混在した環境になります。

ということで、pipで入ってしまったライブラリは一旦pipで消して、condaで入れ直します。

そして、次に試みたのが、 依存ライブラリを入れない no-deps オプションです。
$ pip install --no-deps tensorflow-text

これで綺麗にさっと入ったのですが、これでもまだ問題があり、jupyterで動かすとすぐにkernelが死んでしまうようになりました。
エラーを調査すると、ライブラリの依存関係に問題があったようです。(依存関係無視してインストールしたので当然ですね。)
pip check で確認すると、次のように出ました。


$ pip check
tensorflow-text 2.1.1 has requirement tensorflow<2.2,>=2.1.0, but you have tensorflow 2.0.0.

tensorflow のバージョンを上げればいいかと思ったのですが、
$ conda search tensorflow
で調べてみるとまだ condaには2.0.0しかありません。

ということで、次に tensorflow-text の方を古いものに入れ替えることにしました。pip uninstallして消した後、
$ pip install tensorflow-text==1.15.1 --no-deps

今度は tensorflowが新しすぎるからダメだとのことでした。


$ pip check
tensorflow-text 1.15.1 has requirement tensorflow<1.16,>=1.15.0, but you have tensorflow 2.0.0.

最終的に、バージョン2.0.1なら問題ないようでした。


$ pip install tensorflow-text==2.0.1 --no-deps
# ~~ (中略) ~~
Installing collected packages: tensorflow-text
Successfully installed tensorflow-text-2.0.1

$ pip check
No broken requirements found.

本来ならライブラリは新しいバージョンを使っていくべきですし、
condaについてしっかり理解していれば、condaでインストール方法もありそうです。

なので、この記事の内容は全く推奨できず、真似される場合は自己責任でお願いしますとしか言いようがないのですが、
とりあえず自分の環境にはこうやって入れた、というメモとして記録させていただきました。

やってることは最終的に次の1行だけなのに、とても疲れました。
$ pip install tensorflow-text==2.0.1 --no-deps

PyPIのパッケージをcondaでインストールする方法

前回の記事で、condaの公式リポジトリとconda-forgeを探して、それでも見つからなかったパッケージは環境を分けてpipで入れるという話を書きましたが、
一応、PyPIのパッケージをcondaで入れる方法は存在します。

それが、自分でcondaバッケージをビルドする方法で、(スムーズに進めば)具体的には次の手順でできます。
(前回の記事の反省を踏まえてさっさとコマンドを載せておきます。)


conda skeleton pypi [パッケージ名]
conda build [パッケージ名]
conda install --use-local [パッケージ名]

ドキュメントはこちら:Conda-build documentation

試しにこのブログを書くのに欠かせない pycodestyle_magic を入れてみます。これはcondaの公式リポジトリにもconda-forgeにも今日時点では存在しません。
準備として、必要なパッケージである、次の3つをcondaで入れておきます。
これがconda install の場合との大きな違いで、依存するライブラリは事前自分で入れておかないとエラーになります。
flit はこれが何かよく理解していないのですが、入れておかないとビルドする時に、 No module named ‘flit’ というエラーが出ました。


conda install pycodestyle
conda install flake8
conda install flit

さて、準備できたら次のコマンドを順番に実行します。


conda skeleton pypi pycodestyle_magic
conda build pycodestyle_magic
conda install --use-local pycodestyle_magic

conda skelton を実行した段階で、カレントディレクトリ直下に、meta.yamlファイルを含むディレクトリが出来上がります。


$ ls
pycodestyle_magic
$ ls pycodestyle_magic/
meta.yaml

次のconda build も成功するはずだったのですが、結局エラーが出たので対応します。
(3行目の conda installはまだ実行できず。)

出たエラーはこれ。


ModuleNotFoundError: No module named 'flit'

事前にインストールしているのに見つけられていないようです。
meta.yamlファイルを開いて、追記してみます。
(numpyで似たようなことをして解決している人がいたので真似しました。結果的に成功したようです。)


vim pycodestyle_magic/meta.yaml

#requirements の host: と run: に - flit を追記して保存。

requirements:
  host:
    - pip
    - python
    - flit
  run:
    - python
    - flit

さて、もう一回、conda build pycodestyle_magicすると成功しました。


####################################################################################
Resource usage summary:

Total time: 0:00:23.6
CPU usage: sys=0:00:00.3, user=0:00:00.6
Maximum memory usage observed: 75.1M
Total disk usage observed (not including envs): 264B


####################################################################################
Source and build intermediates have been left in /Users/[ユーザー名]/.pyenv/versions/[インストールしたAnacondaのディレクトリ]/conda-bld.
There are currently 1 accumulated.
To remove them, you can run the ```conda build purge``` command

メッセージにある通り、Anacondaのインストールフォルダ配下にビルドのアウトプットは移動しており、
さっきのmeta.yamlファイルがあった所の中身はそのままです。

conda-bld/ の下には、 pycodestyle_magic_1582538942427 というディレクトリができていて、よくわからないファイルがあります。

さて、buildが成功したので最後にインストールです。
(紛らわしい書き方して済みませんが、Anacondaのディレクトリではなく、skeletonやbuildしたのと同じディレクトリでそのまま)


# 今度は成功する。
conda install --use-local pycodestyle_magic

# インストール結果の確認
$ conda list | grep pycodestyle
pycodestyle               2.5.0                    py37_0
pycodestyle_magic         0.5                      py37_0    local

結果確認は、わかりやすいように普通にcondaで入れたpycodestyleも表示しましたが、
このskeletonを使う方法で入れたパッケージは local マークがつきます。

最後に後片付けです。
カレントディfレクトリに、skeletonでできた meta.yamlファイルが入ったディレクトリがあると思いますが、
インストールが終わったら不要なので消してよいと思います。
また、
conda build purge コマンドで、
[Anacondaのインストールディレクトリ]/conda-bld
にできていた一次ファイルたちを消せます。


rm -r [パッケージ名]
conda build purge

あとは入れたパッケージを使うだけです。
今回はjupyterのmagicコマンドだったので、
%load_ext pycodestyle_magic

%%pycodestyle
をそれぞれ試しました。

これで、conda-forgeにもないパッケージもPyPIからインストールできました。

condaの基本的な使い方

PyCon JP 2019 に参加して、
Anaconda環境運用TIPS 〜Anacondaの環境構築について知る・質問に答えられるようになる〜
という講演を聞いてから、自分の環境がcondaとpipの混在状態で結構リスキーだったことが懸念でした。
参考: 資料のページ

(実際何度も環境壊れていますし。)
会社で使っている端末では環境を極力condaのみで作り直していたのですが、実は自宅の端末では相変わらず混在していました。
そんな時に先日、SSDが壊れてMBPを修理に出す機会があり、完全に初期化されたので今回はできる限りpipを使わないように作り直しました。

まず、Anaconda入れるところまでは昔の記事の通りです。
参考: Macにpyenvとanacondaをインストールする

これまではこの後pip install [ライブラリ名]で、どんどんライブラリを入れていましたが、これはとても危険な行為です。
condaとpipの仕組みには互換性がないからです。

condaのドキュメントにも Using pip in an environment というセクションで注意事項が書かれています。
要約すると、pipを使うなら環境を分けることと、condaでできるだけ多くのライブラリをインストールした後に残りをpipで入れるべきということです。

免責事項
さて、ここからcondaの説明など書いていきますが、僕自身がパッケージの開発者でもなく、環境構築等を専門にするエンジニアでもないただのユーザーなので、
とりあえず自分はこういう理解で使っています、というレベルの内容になります。
厳密には各自公式のドキュメントを確認の上、自己責任でご利用お願いします。
(どちらかというと、他の記事の pip install 〜と書いてるところにこそ、この免責事項が必要ですね。)

さて、 pip と conda ですが、どちらもパッケージマネージャー(パッケージを管理するツール)です。
そして管理の方法が違い、互換性がないので混ぜると二重管理になって競合し、環境の破壊等が発生しえます。

インターネット上のリポジトリで管理されているパッケージを手元の端末に追加したりアップデートしたりできるのですが、
その大元になるリポジトリが違います。
pip は PyPI 、で、 condaはrepo.anaconda.comです。

condaの最大のデメリットが、PyPIに比べてrepo.anaconda.comで配布されているパッケージの少なさだと思います。
この点を補うために、condaでは別の場所(チャンネル)からもパッケージを追加できます。
特に conda-forge は比較的充実しているのでオススメです。
ドキュメントの中でも紹介されているので安心して使えるかと思います。
参考: Conda channels

余談ですが、Python初心者の頃、-c conda-forgeの意味がわからなかったのもcondaを敬遠した理由でした。
要はconda公式リポジトリにそのパッケージはないけど、ユーザーグループが管理している conda-forge にはある時にこれを使います。

さて、チートシートに主なコマンドはまとまっているので、詳しいことはそちらを見てもらうとして、自分がいつもやっている手順を紹介します。

最初にインストールしたいパッケージの名前を確認しておきます。


# インストール済みのパッケージの中に、該当のパッケージがないことを確認する。(必要に応じてgrep)
conda list
# 公式リポジトリ内に存在するかどうか確認
conda search [パッケージ名]
# 公式リポジトリにあったらそこからインストール
conda install [パッケージ名]
# 公式リポジトリになかったら conda-forge 内を検索
conda search -c conda-forge [パッケージ名]
# conda-forgeに存在したらそこからインストール
conda install -c conda-forge [パッケージ名]
# バージョンを指定したいときは==の後ろにバージョン番号を指定
conda install [パッケージ名]==[バージョン番号]

また、インストール済みのパッケージのアップデートとアンインストールは次です。


# アップデート
conda update [パッケージ名]
# アンインストール
conda uninstall [パッケージ名]

前置きが長くなって、記事が冗長になってしまったので一旦ここまで。
次はconda-forgeでも見つからないライブラリをPyPIからcondaで入れることのできる、
conda buildや conda skeletonについて紹介したいです。

Mac に LightGBMをインストールする

手順のメモです。

公式ドキュメントにイストールガイドがありますが、実は使うのはこちらではありません。
Installation Guide

僕はpythonから使う予定なので、Githubのリポジトリの方を読んで作業します。
LightGBM Python-package

次のコマンドを順番に実行します。


brew install libomp
pip install wheel
pip install lightgbm

自分の環境では wheel はすでにインストールされているという趣旨のメッセージが出ました。


$ pip install wheel
Requirement already satisfied: wheel in ./.pyenv/versions/anaconda3-5.2.0/lib/python3.6/site-packages (0.31.1)

これでインストールできたはずなのですが、インポートしてみると次の警告がでます。


$ python
>>> import lightgbm
/Users/xxxxxx/.pyenv/versions/anaconda3-5.2.0/lib/python3.6/site-packages/lightgbm/__init__.py:46: UserWarning: Starting from version 2.2.1, the library file in distribution wheels for macOS is built by the Apple Clang (Xcode_8.3.3) compiler.
This means that in case of installing LightGBM from PyPI via the ``pip install lightgbm`` command, you don't need to install the gcc compiler anymore.
Instead of that, you need to install the OpenMP library, which is required for running LightGBM on the system with the Apple Clang compiler.
You can install the OpenMP library by the following command: ``brew install libomp``.
  "You can install the OpenMP library by the following command: ``brew install libomp``.", UserWarning)

Warningは出るものの、動作に問題はなさそうなので一旦はこのまま使うおうと思っています。
とはいえ気持ち悪いのでいつか直したいです。
brew install libomp は実行してるし、 brew list すると、libompは出てくるのですけどね。

Xcodeがどうのこうのと書かれているので、以下の記事で行なったcommand Line Toolsのインストールが影響してるような気もします。

Mac(Mojave) に pip で mecab-python3をインストールする時にはまった

pyenvで作成した環境を消す

うまくインストールできないライブラリがあり、
pipで入れたり消したり、condaで入れたり消したりとやっていたら何やら全体的に環境がおかしくなってしまいました。
(またかよという感じですが。)

しかたがないので、その環境は消して作り直すことにしました。
pyenv uninstall で環境は消せます。
参考 : pyenv uninstall


# 確認
$ pyenv versions
  system
* anaconda3-5.2.0 (set by /Users/******/.pyenv/version)

# 利用するpythonの環境をsystemのものに戻す。
$ pyenv global system
$ python --version
Python 2.7.10

# 不要になった環境を消す
$ pyenv uninstall anaconda3-5.2.0
# もう一度入れ直し
$ pyenv install anaconda3-5.2.0
$ pyenv global anaconda3-5.2.0
$ python --version
Python 3.6.5 :: Anaconda, Inc.

あとはこのブログで pip で検索して、うまくインストールできていたものを順に入れていけば元に戻るはず。
そもそも、anacondaで作った環境でcondaではなくpipを使ってるのがトラブルの原因でもあるのですが、
condaとpipの違いとか使い分けとか十分理解できてないので、どうしてもpipの方使っちゃいます。
この辺りはいつかしっかり勉強したい。

mecabの新語辞書をインストールする

非常に便利な形態素解析ソフトMeCabですが、デフォルトの辞書は最近登場した単語に弱いと言う欠点があります。
自分で辞書を改善していけたらいいのですがそれも工数が大きくめんどくさい。

以上の状況において、定期的にメンテナンスされている非常にありがたい辞書があります。
mecab-ipadic-neologd

インストール手順はリポジトリの README.ja.mdにある通りです。


$ cd ~/Downloads
$ git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git
$ cd mecab-ipadic-neologd
# -a をつけると全部入り
$ ./bin/install-mecab-ipadic-neologd -n -a

途中で
Do you want to install mecab-ipadic-NEologd? Type yes or no.
と聞かれるのでこれは yes.

ドキュメントにある通り、インストール先は次のコマンドで確認できます。
(出力は僕の環境の例)


$ echo `mecab-config --dicdir`"/mecab-ipadic-neologd"
/usr/local/lib/mecab/dic/mecab-ipadic-neologd

動作確認してみましょう。
まずデフォルト辞書の場合。


~$ mecab
志村五郎先生は偉大な数学者でした。
志村	名詞,固有名詞,人名,姓,*,*,志村,シムラ,シムラ
五郎	名詞,固有名詞,人名,名,*,*,五郎,ゴロウ,ゴロー
先生	名詞,一般,*,*,*,*,先生,センセイ,センセイ
は	助詞,係助詞,*,*,*,*,は,ハ,ワ
偉大	名詞,形容動詞語幹,*,*,*,*,偉大,イダイ,イダイ
な	助動詞,*,*,*,特殊・ダ,体言接続,だ,ナ,ナ
数学	名詞,一般,*,*,*,*,数学,スウガク,スーガク
者	名詞,接尾,一般,*,*,*,者,シャ,シャ
でし	助動詞,*,*,*,特殊・デス,連用形,です,デシ,デシ
た	助動詞,*,*,*,特殊・タ,基本形,た,タ,タ
。	記号,句点,*,*,*,*,。,。,。
EOS

neologdの場合


~$ mecab -d /usr/local/lib/mecab/dic/mecab-ipadic-neologd
志村五郎先生は偉大な数学者でした。
志村五郎	名詞,固有名詞,人名,一般,*,*,志村五郎,シムラゴロウ,シムラゴロー
先生	名詞,一般,*,*,*,*,先生,センセイ,センセイ
は	助詞,係助詞,*,*,*,*,は,ハ,ワ
偉大	名詞,形容動詞語幹,*,*,*,*,偉大,イダイ,イダイ
な	助動詞,*,*,*,特殊・ダ,体言接続,だ,ナ,ナ
数学者	名詞,固有名詞,一般,*,*,*,数学者,スウガクシャ,スーガクシャ
でし	助動詞,*,*,*,特殊・デス,連用形,です,デシ,デシ
た	助動詞,*,*,*,特殊・タ,基本形,た,タ,タ
。	記号,句点,*,*,*,*,。,。,。
EOS

志村五郎先生の名前が固有名詞として認識されていますね。
数学者も。

cloneしてきた辞書ファイルの中を見るとこのように登録されていることがわかります。


mecab-ipadic-neologd$ grep 志村五郎 * -r
build/mecab-ipadic-2.7.0-20070801-neologd-20190610/mecab-user-dict-seed.20190610.csv:志村五郎,1289,1289,4757,名詞,固有名詞,人名,一般,*,*,志村五郎,シムラゴロウ,シムラゴロー

ディレクトリやファイルの権限を一括で修正する

職場で使っている端末の調子が悪く、新端末に交換することになったので大量のファイルを移行しました。
その際、一度NASにファイルを移して持って行ったのですが、
なぜかファイルやディレクトリの権限が全部 777 になってしまうと言う面倒な事態になりました。

chmod で一つ一つ直すのが面倒だったので一括で修正するコマンドがわかったので紹介します。

前提として、カレントディレクトリ”.”配下のすべてのファイルとディレクトリを対象に、
ファイルは644、ディレクトリは755に設定するには次のコマンドを実行します。
カレント以外を対象にする場合は、”.” の代わりにそのPathを入力したらできます。


find . -type d -exec chmod 755 {} +
find . -type f -exec chmod 644 {} +

一応解説。
find . -type d
と、
find . -type f
はそれぞれ、カレントディレクトリ配下の ディレクトリとファイルの一覧を取得します。
そして、 -exec はその後ろに書かれたコマンドを{}を find で見つけたpathに置換して実行します。
+ をつけておくと、各ファイル/ディレクトリに対してコマンドを個別に実行するのではなく、
まとめて実行してくれます。

詳細は man find で、マニュアルを読むのが確実です。

Macでlsコマンドの出力結果の文字色を変更する

今回もMacの小ネタ。
Macのターミナルでlsコマンドを使うと、ディレクトリに色を塗ってくれますが、背景色との組み合わせによっては見辛いことがあります。
(具体的に言えば、黒背景で使っている時の通常ディレクトリの青は見辛いです)

これらの色は、 LSCOLORS という環境変数に適切に値を設定することで変更可能です。
設定内容は、 ls コマンドのマニュアル内で検索すると出てきます。

$ man ls
で、マニュアルを開いて、
/LSCOLORS
で検索しましょう。

自分のMacで実行した時の該当部分を載せておきます。

LSCOLORS The value of this variable describes what color to use for which attribute when col-
ors are enabled with CLICOLOR. This string is a concatenation of pairs of the format
fb, where f is the foreground color and b is the background color.

The color designators are as follows:

a black
b red
c green
d brown
e blue
f magenta
g cyan
h light grey
A bold black, usually shows up as dark grey
B bold red
C bold green
D bold brown, usually shows up as yellow
E bold blue
F bold magenta
G bold cyan
H bold light grey; looks like bright white
x default foreground or background

Note that the above are standard ANSI colors. The actual display may differ depend-
ing on the color capabilities of the terminal in use.

The order of the attributes are as follows:

1. directory
2. symbolic link
3. socket
4. pipe
5. executable
6. block special
7. character special
8. executable with setuid bit set
9. executable with setgid bit set
10. directory writable to others, with sticky bit
11. directory writable to others, without sticky bit

The default is “exfxcxdxbxegedabagacad”, i.e. blue foreground and default background
for regular directories, black foreground and red background for setuid executables,
etc.

初期設定はこれです。
exfxcxdxbxegedabagacad

この22文字が、2文字ずつ”文字色””背景色”のペアになっていて、マニュアル中の11種類に対応しています。
最初の ex が directory の配色で、 blue の文字と、デフォルトの背景色です。

これが読みにくいので、 g : cyan あたりに変更するには、
gxfxcxdxbxegedabagacad と設定すれば大丈夫です。

.bash_profile に以下のように設定しておきましょう。


export LSCOLORS=gxfxcxdxbxegedabagacad

濃い青が明るい水色になって(僕の環境では)とても読みやすくなります。

Note that the above are standard ANSI colors. The actual display may differ depending on the color capabilities of the terminal in use.
と注意されている通り、環境によって色は違うので設定を変更するときは試しながら行うことをお勧めします。
例えば今の僕の環境では d : brown は黄色いです。

Mac の起動時刻を調べる

先日分け合って、使っているMacを何時に起動したのか調べる必要が発生しました。

結論から言うと、次のコマンドで調べることができます。
rebootなのに再起動だけでなく通常の起動もわかります。


$ last reboot
# --- 略 ---
reboot    ~                         Tue Jan  1 17:13
reboot    ~                         Thu Nov 29 19:28
reboot    ~                         Sun Nov 25 12:47
reboot    ~                         Thu Nov 22 14:51
reboot    ~                         Wed Nov 21 20:18

また、シャットダウン時刻を調べたい時は以下のコマンドです。 (出力略)


$ last shutdown

last とだけ打つと両方同時に表示されます。

もっと細かい使い方はそのうち調べようと想うのですが、
取り急ぎ今回の要件は満たしたのでメモしておきました。

NLTKを使う準備をする

普段、文章の形態素解析にはMeCabを使用しているのですが、
とあるサンプルコードを動かそうとした時に、その中でNLTKが使われており、思ったように動かなかったのでそのメモです。

ちなみに、 Anaconda で環境を作ったので、 nltk自体はインストールされていました。


~$ python --version
Python 3.6.8 :: Anaconda, Inc.
~$ pip freeze | grep nltk
nltk==3.3

サンプルコードを動かした時にデータエラーがこちら


LookupError:
**********************************************************************
  Resource punkt not found.
  Please use the NLTK Downloader to obtain the resource:

  >>> import nltk
  >>> nltk.download('punkt')

ドキュメントを読むと、何かダウンロードをやらないといけないようです。

Installing NLTK Data

こういう、基本的な処理であってもエラーになります。


>>> import nltk
>>> nltk.word_tokenize('hello nltk!')
Traceback (most recent call last):
    (略)
LookupError:
**********************************************************************
  Resource punkt not found.
  Please use the NLTK Downloader to obtain the resource:

  >>> import nltk
  >>> nltk.download('punkt')

  Searched in:
    (略)
**********************************************************************

エラーメッセージを見る限りでは、 ‘punkt’ってのだけで良さそうですが、一気に入れてしまっておきましょう。


~$ python
>>> import nltk
>>> nltk.download()
showing info https://raw.githubusercontent.com/nltk/nltk_data/gh-pages/index.xml

CLI内で完結すると思ったら windowが立ち上がったので少しびっくりしました。

all を選んで Downloadします。
結構時間がかかります。

これで動くようになりました。


>>> import nltk
>>> nltk.word_tokenize("hello nltk!")
['hello', 'nltk', '!']