もりはやメモφ(・ω・ )

インフラなエンジニアからSREへ

pyenvのpython環境で'_lzma'が存在しなかった時の対応メモ

pyenvのpython環境で'_lzma'が存在しなかった時の対応メモです。分析チームメンバの一人から「 _lzma が無いよ助けてー」と言われて対応しました。

対象環境

  • Amazon Linux1
  • pyenvでpython3.6.5
  • 開発メンバはJupyterを使用してた(けれどこれは関係なかった)

対応方法

最初に対応方法を記しておきます

解決に到るまでの経緯メモ

解決に至るまでの試行錯誤をメモメモ

CIrcleCIのフォーラムに目を通したけど

No python lzmaというドンピシャなタイトルでCircleCIのフォーラムに議題が上がっており、一通り読むも特に解決に至らず。 「version: 3.6.0b3 指定でカスタムビルドを使うんだ」みたいなことが書いてありますが、こちらの環境はCircleCIでは無いので参考になりませんでした。

流石の もみじあめ さんのサイトで解決への道が

Python本も出版されているもみじあめさんのブログより「ソースコードから Python をインストールするときにビルドされないモジュールを確認する」の記事のおかげで解決への道が開かれました。

具体的には「例えば Python のインストールマネージャの pyenv では、各環境用に必要なパッケージを示している。」とpyenvのwikiへのリンクが提示されていました。

実際にWikiのコマンドを打つが改善されない

そうして以下のコマンドを実際に打ち、パッケージを導入するも改善はしませんでした。

yum install gcc zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel tk-devel libffi-devel

上記コマンドで導入されたパッケージは以下

Dependencies Resolved

======================================================
 Package                                        Arch
======================================================
Installing:
 libffi-devel                                   x86_64
 tk-devel                                       x86_64
Updating:
 openssl-devel                                  x86_64
Installing for dependencies:
 fontconfig-devel                               x86_64
 freetype-devel                                 x86_64
 libXft                                         x86_64
 libXft-devel                                   x86_64
 libXrender-devel                               x86_64
 tcl                                            x86_64
 tcl-devel                                      x86_64
 tk                                             x86_64
Updating for dependencies:
 openssl                                        x86_64

Transaction Summary
======================================================
Install  2 Packages (+8 Dependent packages)
Upgrade  1 Package  (+1 Dependent package)

それもやはり_lzmaは存在しないと怒られました...

>>> import lzma
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/bin/.pyenv/versions/3.6.5/lib/python3.6/lzma.py", line 27, in <module>
    from _lzma import *
ModuleNotFoundError: No module named '_lzma'
>>>

改めてWikiのドキュメントを読む

改めて見直すとWikiに次の文言を見つけます FIXME: you may need to install xz to build some CPython version 。 それならと rpm -qa | grep xz を確認すると、既にインストールされていました。

勘でxz-develも入れてみる

pyenvがソースからビルドすると言うのを何となく理解したおかげか勘が冴えます。ビルドといえば devel が必要だったりします。 よって yum install xz-devel を試したところ、新たにパッケージがインストールされました。(未導入だったと言うこと)

pyenvで再インストールしてlzmaのimportに成功!

この状態で改めてpyenvで指定バージョンを入れ直したところ、無事に import lzma に成功しました。

~]# python
Python 3.6.5 (default, Feb  4 2019, 12:37:53)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-28)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>>
>>> import lzma
>>>

余談、stanfordnlp をimportするためPythonを3.5.6 -> 3.6.8 へアップ

これは余談ですが、冒頭で「 _lzma が無いよ助けてー」と言ってきた分析チームメンバが、lzmaをクリアしても「今度は import stanfordnlp が通らないよ助けてー」と追加ヘルプを求めてきました。

これはPythonのバージョンを3.5.6からstanfordnlpが推奨する3.6.8に上げることで解決することができました。 なお3.5.6時点で発生したエラーは以下になります。

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-104-5d3e57dcfa26> in <module>()
----> 1 import stanfordnlp

/usr/bin/.pyenv/versions/3.6.5/lib/python3.6/site-packages/stanfordnlp/__init__.py in <module>()
----> 1 from stanfordnlp.pipeline.core import Pipeline
      2 from stanfordnlp.pipeline.doc import Document
      3 from stanfordnlp.utils.resources import download
      4 
      5 __version__='0.1.0'

/usr/bin/.pyenv/versions/3.6.5/lib/python3.6/site-packages/stanfordnlp/pipeline/core.py in <module>()
      9 from stanfordnlp.pipeline.mwt_processor import MWTProcessor
     10 from stanfordnlp.pipeline.pos_processor import POSProcessor
---> 11 from stanfordnlp.pipeline.lemma_processor import LemmaProcessor
     12 from stanfordnlp.pipeline.depparse_processor import DepparseProcessor
     13 from stanfordnlp.utils.resources import DEFAULT_MODEL_DIR, default_treebanks, mwt_languages, build_default_config

/usr/bin/.pyenv/versions/3.6.5/lib/python3.6/site-packages/stanfordnlp/pipeline/lemma_processor.py in <module>()
      1 from stanfordnlp.models.common.conll import FIELD_TO_IDX
----> 2 from stanfordnlp.models.lemma.data import DataLoader
      3 from stanfordnlp.models.lemma.trainer import Trainer
      4 from stanfordnlp.pipeline.processor import UDProcessor
      5 

/usr/bin/.pyenv/versions/3.6.5/lib/python3.6/site-packages/stanfordnlp/models/lemma/data.py in <module>()
      5 import torch
      6 
----> 7 import stanfordnlp.models.common.seq2seq_constant as constant
      8 from stanfordnlp.models.common.data import map_to_ids, get_long_tensor, get_float_tensor, sort_all
      9 from stanfordnlp.models.common import conll

AttributeError: module 'stanfordnlp' has no attribute 'models'

ただ、なぜか手打ちすると3.5.6でも通りました。Jupyter経由なのが問題なのか、それとも別の何かなのか、バージョンアップで解決してしまったので詳細は不明ですが、一応のメモとして残しておきます。

~]# python
Python 3.6.5 (default, Feb  4 2019, 12:37:53)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-28)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import stanfordnlp
>>> import stanfordnlp.models.common.seq2seq_constant as constant
>>>

また、JuptyerからでもPython3.6.5の段階でfrom stanfordnlp.models import * は通ったとのことです、うーむ....