百度aistudio 安装 pycorrecotor
背景
百度aistudio提供的notebook juypter 免费提供CPU/GPU 资源,可以比较方便的做算法测试。同时提供了aistudio 提供了直接访问服务器的terminal,可以直接登录到虚拟机上安装相关依赖,这个操作比Google的colab只能在notebook上操作要方便不少。但是百度为了推广自家的paddle(飞桨框架),禁止了TensorFlow/pytorch等DeepLearning框架。 虚拟机的shell也禁用了root权限,那么就不能直接执行sudo apt-get install 之类的需要root权限的命令了。
实验
现在有一个在notebook jupyter上安装pycorrector的需求,直接pip install pycorrector
但是在自动安装依赖kenlm时报错,kenlm是c++扩展,在gcc 编译时,出现gcc: error trying to exec 'cc1plus': execvp: No such file or directory
这样的错误提示。(By the way, 在Google的colab上可以直接安装)
查看gcc的版本
aistudio@jupyter-104673-1192555:~$ gcc --version
gcc (Ubuntu 7.5.0-3ubuntu1~16.04) 7.5.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
aistudio@jupyter-104673-1192555:~$ g++ --version
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
发现gcc 跟 g++的版本不一致,这里简单解释一下cc1plus
的用途:
The g++ is a compiler driver. It knows how to invoke the actual compiler (cc1plus), assembler and linker. It does not know how to parse or compile the sources.
g++只是编译器的驱动,它只知道如何去调用实际的编译器(cc1plus)、汇编器以及链接器。但是不知道如何去编译源代码。
参考:https://stackoverflow.com/questions/19899750/what-is-the-difference-between-gcc-g-and-cc1-cc1plus
想到把g++升级到7.5.0,网上很多使用apt-get命名去升级的方案,在这里都不能使用,因为没有root权限。:)
那么只能手动源码安装了,下面说一下步骤:
- 下载gcc-7.5.0源码
http://mirrors.ustc.edu.cn/gnu/gcc/gcc-7.5.0/gcc-7.5.0.tar.gz
这里使用了中科大的镜像源,比国外的源要快很多,后面也会用到
- 解压编译源码
tar xvf gcc-7.5.0.tar.gz
cd gcc-7.5.0
# 下载依赖
./contrib/download_prerequisites
发下基本不动,因为使用了国外的额源,下载依赖包的速度太慢了。
看一下download_prequisites
源码,
gmp='gmp-6.1.0.tar.bz2'
mpfr='mpfr-3.1.4.tar.bz2'
mpc='mpc-1.0.3.tar.gz'
isl='isl-0.16.1.tar.bz2'
base_url='ftp://gcc.gnu.org/pub/gcc/infrastructure/'
echo_archives() {
echo "${gmp}"
echo "${mpfr}"
echo "${mpc}"
if [ ${graphite} -gt 0 ]; then echo "${isl}"; fi
}
重点是上面的几个文件,可以先下载到当前gcc-7.5.0
目录。
可以使用上面提到的中科大镜像源wget先下载,镜像站没有的包,可以到源站wget下载。再执行./contrib/dowload_prerequisites
,有如下提示:
gmp-6.1.0.tar.bz2: OK
mpfr-3.1.4.tar.bz2: OK
mpc-1.0.3.tar.gz: OK
isl-0.16.1.tar.bz2: OK
All prerequisites downloaded successfully.
说明依赖已经安装好了,接下来就行configure跟编译了。
首先创建一个用于存放编译文件的目录build, 进入build目录,执行上级目录的configure命令。
这里需要注意一点,在configure的时候,一定要用--prefix指定有权限install相关可执行文件以及lib文件的目录。 比如:在aistudio中的work/gcc-install, 笔者就没有指定,结果是默认的目录/usr,可想而知,肯定没有权限install。结果后面要用很多trick来解决后面用到各种依赖的问题,在下面会说到。
# 完整命令
mdir build
cd build
../configure --prefix ~/work/gcc-install -enable-checking=release -enable-languages=c,c++ -disable-multilib
- 接下来就是编译安装了
make -j 30
make install
正常情况install
目录有权限的话,make install
应该就结束了。
但是笔者之前没有配置prefix,结果要install到一个没有权限的默认/usr
目录。所以现在没法make install
。因为编译过的过程太慢长了,所以不想重新configure,重新编译。
好在,源码已经编译好了。配置环境变量:
# gcc、g++在这个目录
export PATH=/home/aistudio/gcc-7.5.0/build/gcc/:$PATH
# 看一下是否生效
which gcc
which g++
# 查看版本
aistudio@jupyter-104673-1192555:~/kenlm-master$ g++ --version
g++ (GCC) 7.5.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- 手动安装pycorrector的依赖kenlm
wget https://github.com/kpu/kenlm/archive/master.zip
unzip master.zip
cd kenlm-master
python setup install
不再提示找不到cc1plus
,出现了各种找不到头文件的错误信息,说明cc1plus
已经能找到了,进入准备编译的阶段了。
根据提示信息,find gcc-7.5.0 -name "xx.hh"
查找到各个头文件的目录,这里也有很多坑,因为一个文件所在的目录不一样,虽然文件名一样,但是代码可能是不一样的。笔者在这里踩了不少坑,不断尝试终于找到所有头文件的目录。
gcc 在编译的时候可以用 gcc -I your_headers_dir
,指定include
的查找路径。
修改 setup.py
# 踩坑之后,找到了所有以来的定义目录
ss = '-I ../gcc-7.5.0/build/gcc/include/ -I ../gcc-7.5.0/libstdc++-v3/include/std/ -I ../gcc-7.5.0/libstdc++-v3/include -I ../gcc-7.5.0/libstdc++-v3/libsupc++/ -I ../gcc-7.5.0/build/x86_64-pc-linux-gnu/libstdc++-v3/include/x86_64-pc-linux-gnu/ -I ../gcc-7.5.0/libstdc++-v3/libsupc++/ -I ../gcc-7.5.0/build/x86_64-pc-linux-gnu/libstdc++-v3/include -I ../gcc-7.5.0/build/gcc/include-fixed/ -L ../gcc-7.5.0/build/gcc/'
#print(ss.split(' '))
ss = ss.split(' ')
s1 = []
for i in range(0,len(ss),2):
#print(i)
s1.append(ss[i]+ss[i+1])
#print(s1)
#s1 = []
ARGS = ['-O3', '-DNDEBUG', '-DKENLM_MAX_ORDER='+max_order, '-std=c++11']
# 通过ARGS参数传递给gcc命令
ARGS += s1
print(ARGS)
再次执行python setup.py install
,正常编译了一小会,但是抛出错误提示:
gcc: fatal error: -fuse-linker-plugin, but liblto_plugin.so not found
看来是没后找到liblto_plugin.so
这个库,find 了一下,发现有这个文件./build/gcc/liblto_plugin.so
。无论用 gcc -L ./build/gcc/
,增加一个链接库的查找路径,还是把路径增加到PATH
变量,都并不起作用。
aistudio@jupyter-104673-1192555:~/gcc-7.5.0$ /usr/bin/gcc -print-file-name=liblto_plugin.so
/usr/lib/gcc/x86_64-linux-gnu/7/liblto_plugin.so
用系统默认的/usr/bin/gcc
能够查找到liblto_plugin.so
,但用刚编译的gcc确找不到此文件。
使用gcc -print-serach-dirs
,发现有搜索类似这样的路径:
libraries =/home/aistudio/gcc-7.5.0/build/gcc/../lib/gcc/x86_64-pc-linux-gnu/7.5.0//home/aistudio/gcc-7.5.0/build/gcc/../lib/gcc/x86_64-linux-gnu//home/aistudio/gcc-7.5.0/build/gcc/../lib/gcc//home/aistudio/gcc-7.5.0/build/gcc/../lib/gcc/
所以,直接在gcc下创建了lib目录,把gcc目录拷贝到lib目下。 再执行gcc -print-file-name=liblto_plugin.so
aistudio@jupyter-104673-1192555:~/gcc-7.5.0$ gcc -print-file-name=liblto_plugin.so
/home/aistudio/gcc-7.5.0/build/gcc/../lib/gcc/liblto_plugin.so
可以正常找到liblto_plugin.so
, 再次python setup.py install
, 可以正常编译安装kenlm了。
另外,笔者在发现默认的/usr/bin/gcc 可以找到liblto_plugin.so
的时候,尝试把编译好的gcc改为gcc_bak,让gcc命令使用的是/usr/bin/gcc,也可以正常编译kenlm。
然后就可以在notebook上, !pip install pycorrector
了
到此,整个踩坑结束。