背景

今天使用micromamba新建了一个环境来试试latex-ocr+paddle ocr的效果

1
micromamba create -n latex-ocr python=3.8 cudatoolkit=10.2 cudnn

环境创建完成之后切换环境并安装依赖

1
2
micromamba activate latex-ocr
pip install -r requirements.txt

然后开始跑代码

1
python main.py

发现问题

在跑代码的时候发现报了一个库没有找到的问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Error: Can not import paddle core while this file exists: /root/micromamba/envs/latex-ocr/lib/python3.8/site-packages/paddle/fluid/libpaddle.so
Traceback (most recent call last):
File "main.py", line 6, in <module>
import apis.latex_ocr
File "/root/latex-ocr/apis/latex_ocr.py", line 6, in <module>
from paddle_detection.engine import EngineWrapper
File "/root/latex-ocr/paddle_detection/engine.py", line 1, in <module>
from paddleocr import PPStructure
File "/root/micromamba/envs/latex-ocr/lib/python3.8/site-packages/paddleocr/__init__.py", line 14, in <module>
from .paddleocr import *
File "/root/micromamba/envs/latex-ocr/lib/python3.8/site-packages/paddleocr/paddleocr.py", line 21, in <module>
import paddle
File "/root/micromamba/envs/latex-ocr/lib/python3.8/site-packages/paddle/__init__.py", line 25, in <module>
from .framework import monkey_patch_variable
File "/root/micromamba/envs/latex-ocr/lib/python3.8/site-packages/paddle/framework/__init__.py", line 17, in <module>
from . import random # noqa: F401
File "/root/micromamba/envs/latex-ocr/lib/python3.8/site-packages/paddle/framework/random.py", line 16, in <module>
import paddle.fluid as fluid
File "/root/micromamba/envs/latex-ocr/lib/python3.8/site-packages/paddle/fluid/__init__.py", line 36, in <module>
from . import framework
File "/root/micromamba/envs/latex-ocr/lib/python3.8/site-packages/paddle/fluid/framework.py", line 37, in <module>
from . import core
File "/root/micromamba/envs/latex-ocr/lib/python3.8/site-packages/paddle/fluid/core.py", line 338, in <module>
raise e
File "/root/micromamba/envs/latex-ocr/lib/python3.8/site-packages/paddle/fluid/core.py", line 274, in <module>
from . import libpaddle
ImportError: libcudart.so.10.2: cannot open shared object file: No such file or directory

但是这个库是存在lib目录下的

原因

conda共享库隔离的实现原理

Windows上conda隔离共享库的方案与Linux不同

Linux

linux平台上,conda中下载下来的python二进制文件是被修改过的,通过readelf命令可以看到以下内容

Library rpath: [$ORIGIN/../lib]这部分是conda对python二进制文件进行的修改,$ORIGIN代表的意思是文件所在的目录,$ORIGIN/../lib所代表的意思是与文件所在目录同级的lib目录。

在Linux中,动态库的搜索路径优先级为:

  1. rpath
  2. LD_LIBRARY_PATH环境变量指定的目录
  3. runpath
  4. 搜索/etc/ld.so.cache缓存
  5. 默认的系统库目录,/lib或者/usr/lib等

conda中隔离环境中的共享库所安装的目录在env/xxx/lib,python命令所在的目录为env/xxx/bin

所以当使用conda中下载的python解释器时,$ORIGIN/../lib的优先级最高,会优先使用conda安装到隔离环境,也就是env/xxx/lib中的共享库。

Windows

windows中就相对糙快猛了,conda将python命令放在env/xxx/目录下,共享库放在env/xxx/Library/bin下,两个目录都被加入到PATH环境变量中,每次执行conda activate命令时会切换PATH中两个目录的地址,实现切换共享库环境。

问题的原因

当时运行的环境是Linux,上一节中的方案应该是没有问题的才对,为什么还会找不到库呢?

加上LD_DEBUG=libs环境变量再执行一次代码,看看程序是如何寻找缺少的libcudart.so.10.2

1
LD_DEBUG=libs python main.py

从输出中搜索关键字,可以定位到以下内容:

1
2
3
4
5
6
7
8
9
10
87054:	find library=libcudart.so.10.2 [0]; searching
87054: search path=/root/micromamba/envs/latex-ocr/lib/python3.8/site-packages/paddle/fluid/../libs
(RUNPATH from file /root/micromamba/envs/latex-ocr/lib/python3.8/site-packages/paddle/fluid/libpaddle.so)
87054: trying file=/root/micromamba/envs/latex-ocr/lib/python3.8/site-packages/paddle/fluid/../libs/libcudart.so.10.2
87054: search cache=/etc/ld.so.cache
87054: search path=/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu:/lib:/usr/lib (system search path)
87054: trying file=/lib/x86_64-linux-gnu/libcudart.so.10.2
87054: trying file=/usr/lib/x86_64-linux-gnu/libcudart.so.10.2
87054: trying file=/lib/libcudart.so.10.2
87054: trying file=/usr/lib/libcudart.so.10.2

可以看到是libpaddle.so尝试调用libcudart.so.10.2,按顺序尝试了以下目录:

  • RUNPATH所指定的目录/root/micromamba/envs/latex-ocr/lib/python3.8/site-packages/paddle/fluid/../libs
  • 搜索/etc/ld.so.cache缓存
  • /lib/x86_64-linux-gnu
  • /usr/lib/x86_64-linux-gnu
  • /lib
  • /usr/lib

虽然conda安装的python解释器通过rpath的方式进行了修改,但是对于paddle的库中so是不生效的,conda把库安装在/root/micromamba/envs/latex-ocr/lib,所以找不到。

解决方案

解决方法很简单,指定一个变量来运行就好了

1
LD_LIBRARY_PATH=/root/micromamba/envs/latex-ocr/lib python main.py

https://zhuanlan.zhihu.com/p/534778561

https://amir.rachum.com/shared-libraries/#runtime-search-path