Scikit-learn: ImportError: dlopen: Mit statischem TLS kann kein Objekt mehr geladen werden, wenn eine Taschenlampe mit gcc 5.5 . erstellt wurde

Erstellt am 26. Juli 2019  ·  12Kommentare  ·  Quelle: scikit-learn/scikit-learn

Ich bin mir nicht sicher, ob dies ein PyTorch-Fehler, ein scikit-learn-Fehler oder ein Numba ist, aber das funktionierte früher in scikit-learn 0.20.3 und funktionierte in der 0.21.0-Serie nicht mehr, also werde ich es jetzt wagen eine Vermutung, dass es sich um eine Regression im Scikit-Lernen handelt.

Wenn ich die folgende Reihe von Importen durchführe (minimiert aus dem ursprünglichen Import, der import librosa ), schlägt das Laden des folgenden Programms fehl:

import torch
import soundfile
import scipy.signal
import numba
import sklearn

mit

Traceback (most recent call last):
  File "/opt/conda/lib/python3.6/site-packages/sklearn/__check_build/__init__.py", line 44, in <module>
    from ._check_build import check_build  # noqa
ImportError: dlopen: cannot load any more object with static TLS

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "test_torch.py", line 5, in <module>
    import sklearn
  File "/opt/conda/lib/python3.6/site-packages/sklearn/__init__.py", line 75, in <module>
    from . import __check_build
  File "/opt/conda/lib/python3.6/site-packages/sklearn/__check_build/__init__.py", line 46, in <module>
    raise_build_error(e)
  File "/opt/conda/lib/python3.6/site-packages/sklearn/__check_build/__init__.py", line 41, in raise_build_error
    %s""" % (e, local_dir, ''.join(dir_content).strip(), msg))
ImportError: dlopen: cannot load any more object with static TLS
___________________________________________________________________________
Contents of /opt/conda/lib/python3.6/site-packages/sklearn/__check_build:
_check_build.cpython-36m-x86_64-linux-gnu.so__pycache__               __init__.py
setup.py
___________________________________________________________________________
It seems that scikit-learn has not been built correctly.

If you have installed scikit-learn from source, please do not forget
to build the package before using it: run `python setup.py install` or
`make` in the source directory.

If you have used an installer, please check that it is suited for your
Python version, your operating system and your platform.

Ein Downgrade auf scikit-learn 0.20.3 lässt das Problem verschwinden.

Versionen

jenkins<strong i="15">@260bf77532d0</strong>:~/workspace/test$ python
Python 3.6.8 |Anaconda, Inc.| (default, Dec 30 2018, 01:22:34) 
[GCC 7.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sklearn; sklearn.show_versions()

System:
    python: 3.6.8 |Anaconda, Inc.| (default, Dec 30 2018, 01:22:34)  [GCC 7.3.0]
executable: /opt/conda/bin/python
   machine: Linux-4.15.0-29-generic-x86_64-with-debian-jessie-sid

BLAS:
    macros: SCIPY_MKL_H=None, HAVE_CBLAS=None
  lib_dirs: /opt/conda/lib
cblas_libs: mkl_rt, pthread

Python deps:
       pip: 19.1.1
setuptools: 41.0.1
   sklearn: 0.21.2
     numpy: 1.16.4
     scipy: 1.1.0
    Cython: None
    pandas: None

Sie könnten auch interessiert sein an:

jenkins<strong i="19">@260bf77532d0</strong>:~/workspace/test$ pip list | grep numba
numba                  0.43.1         
jenkins<strong i="20">@260bf77532d0</strong>:~/workspace/test$ pip list | grep torch
torch                  1.2.0a0+ab800ad

Der Build von Fackel muss mit gcc 5.5.0 durchgeführt werden, um dieses Problem zu verursachen; andere Versionen von gcc sind dafür bekannt, dieses Problem nicht zu verursachen.

Zur Vereinfachung der Reproduktion können Sie das folgende Docker-Image ezyang/scikit-learn-tls-repro:1 https://cloud.docker.com/repository/registry-1.docker.io/ezyang/scikit-learn-tls-repro verwenden . Folgen Sie den Reproduktionsanweisungen wie oben beschrieben. (BEARBEITEN Zum Zeitpunkt des Schreibens wird das Docker-Image noch hochgeladen. Sollte in Kürze erfolgen.)

Hilfreichster Kommentar

Ich habe es gelöst, indem ich sklearn importiere und dann tensorflow importiere. Die Importreihenfolge führt zu diesem Fehler.

Alle 12 Kommentare

Danke für den Bericht. Wie hast du sklearn gebaut/installiert?

pip install scikit-learn

Hast du das Log dazu? Wurde es aus der Quelle gebaut oder hast du ein Rad installiert?

Collecting scikit-learn                                                                           
  Using cached https://files.pythonhosted.org/packages/85/04/49633f490f726da6e454fddc8e938bbb5bfed
2001681118d3814c219b723/scikit_learn-0.21.2-cp36-cp36m-manylinux1_x86_64.whl    

@ezyang Sie möchten vielleicht die Dockerfile teilen, wenn dies möglich ist.

Wenn jemand daran interessiert ist, diesen Fehler zu reproduzieren, ist die richtige Docker-Beschwörung etwa so:

docker run -it ezyang/scikit-learn-tls-repro:1 bash

Beachten Sie, dass Sie das Tag 1 explizit angeben müssen, sonst erhalten Sie eine kryptische Fehlermeldung (das 'neueste' Tag existiert nicht):

Unable to find image 'ezyang/scikit-learn-tls-repro:latest' locally
docker: Error response from daemon: manifest for ezyang/scikit-learn-tls-repro:latest not found.

Ich habe keine Ahnung, warum dies passieren sollte, aber ich habe anscheinend zahlreiche Fehlerberichte dazu, zB mit pytorch und OpenCV https://github.com/pytorch/pytorch/issues/2083 oder OpenCV und Tensorflow https://github.com /tensorflow/models/issues/523. Alles in allem würde ich vermuten, dass dies kein Scikit-Learn-Bug ist.

Die Tatsache, dass es von der Importreihenfolge abhängt, ist faul, zum Beispiel funktioniert dies in Ihrem Docker-Image:

python -c 'import torch; import sklearn; import soundfile; import scipy.signal; import numba'

Beachten Sie, dass ich versucht habe, in einer Conda-Umgebung zu reproduzieren (in Ihrem Docker-Image für ein gutes Maß) und konnte dies nicht ( scikit-learn 0.21.2 und pytorch 1.1.0 ), also könnte dies mit einigen Änderungen in pytorch dev zusammenhängen Ausführung.

conda create -n test -c pytorch pytorch scikit-learn scipy numba scikit-learn -y
conda activate test
pip install soundfile
python -c 'import torch; import soundfile; import scipy.signal; import numba; import sklearn'
$ conda list
# packages in environment at /opt/conda/envs/test:
#
# Name                    Version                   Build  Channel
_libgcc_mutex             0.1                        main  
blas                      1.0                         mkl  
ca-certificates           2019.5.15                     0  
certifi                   2019.6.16                py37_1  
cffi                      1.12.3           py37h2e261b9_0  
cudatoolkit               10.0.130                      0  
intel-openmp              2019.4                      243  
joblib                    0.13.2                   py37_0  
libedit                   3.1.20181209         hc058e9b_0  
libffi                    3.2.1                hd88cf55_4  
libgcc-ng                 9.1.0                hdf63c60_0  
libgfortran-ng            7.3.0                hdf63c60_0  
libstdcxx-ng              9.1.0                hdf63c60_0  
llvmlite                  0.29.0           py37hd408876_0  
mkl                       2019.4                      243  
mkl-service               2.0.2            py37h7b6447c_0  
mkl_fft                   1.0.12           py37ha843d7b_0  
mkl_random                1.0.2            py37hd81dba3_0  
ncurses                   6.1                  he6710b0_1  
ninja                     1.9.0            py37hfd86e86_0  
numba                     0.45.0           py37h962f231_0  
numpy                     1.16.4           py37h7e9f1db_0  
numpy-base                1.16.4           py37hde5b4d6_0  
openssl                   1.1.1c               h7b6447c_1  
pip                       19.1.1                   py37_0  
pycparser                 2.19                     py37_0  
python                    3.7.3                h0371630_0  
pytorch                   1.1.0           py3.7_cuda10.0.130_cudnn7.5.1_0    pytorch
readline                  7.0                  h7b6447c_5  
scikit-learn              0.21.2           py37hd81dba3_0  
scipy                     1.3.0            py37h7c811a0_0  
setuptools                41.0.1                   py37_0  
six                       1.12.0                   py37_0  
soundfile                 0.10.2                   pypi_0    pypi
sqlite                    3.29.0               h7b6447c_0  
tk                        8.6.8                hbc83047_0  
wheel                     0.33.4                   py37_0  
xz                        5.2.4                h14c3975_4  
zlib                      1.2.11               h7b6447c_3  

Ich denke, es wäre nützlich und hilfreich, Scikit-Learn zu halbieren, wenn sich das Problem in einem Dev-Build reproduziert.

Generell habe ich das Gefühl, dass die Expertise zu dieser Art von Problemen auf der PyTorch-Seite liegt. Persönlich habe ich noch nie von statischem TLS gehört und ich würde vermuten, dass dies bei vielen anderen Scikit-Learn-Entwicklern der Fall ist, obwohl ich mich bei der letzten Aussage irren könnte.

IIUC Sie haben das Problem ursprünglich mit scikit-learn 0.21.2 und einer pytorch-Entwicklerversion gesehen. Ich kann das Problem auf scikit-learn 0.21.2 und pytorch 1.1.0 nicht reproduzieren, wie in https://github.com/scikit-learn/scikit-learn/issues/14485#issuecomment -517195977 angegeben. Wenn ich versuchen würde, dies genauer zu verstehen, würde ich PyTorch halbieren.

Das verlinkte Problem @ezyang enthält eine Reihe von Informationen zu diesem TLS-Problem (Thread Local Store).
Hier sind einige Informationen, die ich zuvor ausgegraben habe: https://github.com/pytorch/pytorch/issues/2575#issuecomment -369892859

;TLDR: Etwas in der Importkette war nicht C/C++ kompiliert mit -gPIC Flag. Das Importieren dieser Bibliothek verursacht ein Problem, das alle Importe in "statisches TLS" umwandelt. Es gibt eine maximale Anzahl solcher "statischer TLS"-Slots (Namen, die ich hier verwende, sind sicherlich falsch). Genaue N Slots hängen vom Betriebssystem ab und davon, wie es kompiliert wurde.

In der verlinkten pytorch-Ausgabe 2575 wird erwähnt, dass es sich um OpenMP handelt, das ohne das Flag kompiliert wurde, das die Kaskade verursacht.
Dieses scikit-learn-Problem kann auf die Einführung einer neuen Bibliothek oder eine Änderung zurückzuführen sein, die nur wenige statische TLS-Slots mehr verbraucht.

Hinweis: Kein echter Experte. Möglicherweise gibt es andere Quellen für diesen Fehler als "eine/einige Lib fehlt das Flag `-gPIC', als sie kompiliert wurde". Habe aber keinen gefunden.

Gab es hierzu Updates? Ich treffe dieses Problem auch, auch beim Importieren von Librosa.

Ich habe es gelöst, indem ich sklearn importiere und dann tensorflow importiere. Die Importreihenfolge führt zu diesem Fehler.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen