前一篇文章那种方法虽然当前运行没有什么问题,但潜在风险很大,在生产环境断然是无法适用的,所以还是老老实实按照别人的建议,通过conda的方式来安装。可能有人已经非常熟悉这些流程和操作了,这里主要是为了记录一下,方便初次接触的人快速上手。
接触conda还是因为python虚拟环境,比如在python2的机器上想运行python3的工程和应用,conda就是一个非常不错的选择。docker非常庞大;virtialenv用起来非常繁琐,需要自己安装各种依赖库;conda则通过交互命令让环境隔离这一过程非常顺滑。现在通过能在隔离环境中使用gcc、ninja、cmake这些强大的编译工具,conda已经变得异常强大,不仅仅限于python包管理和部署了,还没有使用过的人可以赶紧体验一下。
conda是一系列工具的总称,常用的有Anaconda,相对比较庞大,但做环境移植相对比较方便,因为依赖库比较全面;Miniconda,可以说是精简后的anaconda;Miniforge,不同编译参数下的Miniconda,有些机器Miniconda安装不了,只有Miniforge才能成功!
基本使用
可以说非常简单明了,不过最好带上国内的channel地址,这个channel就是仓库镜像:
conda install gcc -c https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge
安装python依赖包的时候,一般通过:
pip install mumpy -i https://pypi.tuna.tsinghua.edu.cn/simple
这两个仓库地址是不同的!pypi一般是python包仓库地址,有些包两个仓库都有,有些只有一方才有, 比如cmake
、ninja
通过pip就能安装,但gcc
就只能通过conda安装。
指定版本
默认安装gcc是最新版本的gcc-12.1,相当高的版本了,可能不是我们需要的,安装指定版本的gcc自然就是我们的需要了,要安装指定版本先得罗列所有可安装版本:
$ conda search gcc
Loading channels: done
# Name Version Build Channel
gcc 8.5.0 h85e6f30_1 conda-forge
gcc 8.5.0 h85e6f30_1 anaconda/cloud/conda-forge
gcc 8.5.0 h85e6f30_10 conda-forge
gcc 8.5.0 h85e6f30_10 anaconda/cloud/conda-forge
gcc 8.5.0 h85e6f30_2 conda-forge
gcc 8.5.0 h85e6f30_2 anaconda/cloud/conda-forge
gcc 8.5.0 h85e6f30_3 conda-forge
gcc 8.5.0 h85e6f30_3 anaconda/cloud/conda-forge
...
比如要安装8.5.9,仓库中没有那就安装不了,所以一定要写对版本号:
$ conda install 'gxx=9.5.0' -c https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge
写成conda install 'gxx=9.5'
可是安装不了的。版本指定还有不少花哨的用法,可以参照这篇帖子。c++的编译工具的名字和熟悉的gcc-c++
不同,而是叫gxx
。
问题解决
1. cmake生成错误
cmake ..
-- The CXX compiler identification is GNU 9.5.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - failed
-- Check for working CXX compiler: /home/zhouwenyuan/.conda/envs/gcc9.5/bin/c++
-- Check for working CXX compiler: /home/zhouwenyuan/.conda/envs/gcc9.5/bin/c++ - broken
CMake Error at /usr/share/cmake/Modules/CMakeTestCXXCompiler.cmake:59 (message):
The C++ compiler
"/home/zhouwenyuan/.conda/envs/gcc9.5/bin/c++"
is not able to compile a simple test program.
It fails with the following output:
Change Dir: /home/zhouwenyuan/llama.cpp/build/CMakeFiles/CMakeTmp
Run Build Command(s):/usr/bin/gmake -f Makefile cmTC_d422e/fast && /usr/bin/gmake -f CMakeFiles/cmTC_d422e.dir/build.make CMakeFiles/cmTC_d422e.dir/build
gmake[1]: Entering directory '/home/zhouwenyuan/llama.cpp/build/CMakeFiles/CMakeTmp'
Building CXX object CMakeFiles/cmTC_d422e.dir/testCXXCompiler.cxx.o
/home/zhouwenyuan/.conda/envs/gcc9.5/bin/c++ -o CMakeFiles/cmTC_d422e.dir/testCXXCompiler.cxx.o -c /home/zhouwenyuan/llama.cpp/build/CMakeFiles/CMakeTmp/testCXXCompiler.cxx
Linking CXX executable cmTC_d422e
/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_d422e.dir/link.txt --verbose=1
/home/zhouwenyuan/.conda/envs/gcc9.5/bin/c++ CMakeFiles/cmTC_d422e.dir/testCXXCompiler.cxx.o -o cmTC_d422e
/home/zhouwenyuan/.conda/envs/gcc9.5/bin/../lib/gcc/x86_64-conda-linux-gnu/9.5.0/../../../../x86_64-conda-linux-gnu/bin/ld: /home/zhouwenyuan/.conda/envs/gcc9.5/bin/../lib/gcc/x86_64-conda-linux-gnu/9.5.0/libstdc++.so: undefined reference to `memcpy@GLIBC_2.14'
/home/zhouwenyuan/.conda/envs/gcc9.5/bin/../lib/gcc/x86_64-conda-linux-gnu/9.5.0/../../../../x86_64-conda-linux-gnu/bin/ld: /home/zhouwenyuan/.conda/envs/gcc9.5/bin/../lib/gcc/x86_64-conda-linux-gnu/9.5.0/libstdc++.so: undefined reference to `aligned_alloc@GLIBC_2.16'
/home/zhouwenyuan/.conda/envs/gcc9.5/bin/../lib/gcc/x86_64-conda-linux-gnu/9.5.0/../../../../x86_64-conda-linux-gnu/bin/ld: /home/zhouwenyuan/.conda/envs/gcc9.5/bin/../lib/gcc/x86_64-conda-linux-gnu/9.5.0/libstdc++.so: undefined reference to `clock_gettime@GLIBC_2.17'
collect2: error: ld returned 1 exit status
gmake[1]: *** [CMakeFiles/cmTC_d422e.dir/build.make:99: cmTC_d422e] Error 1
gmake[1]: Leaving directory '/home/zhouwenyuan/llama.cpp/build/CMakeFiles/CMakeTmp'
gmake: *** [Makefile:127: cmTC_d422e/fast] Error 2
这是一个可忽略的错误,解决办法:
cmake .. -DCMAKE_CXX_COMPILER_WORKS=TRUE
2. 编译错误
$ make -j8
[ 2%] Built target BUILD_INFO
[ 5%] Building C object CMakeFiles/ggml.dir/ggml.c.o
[ 7%] Building C object CMakeFiles/ggml.dir/k_quants.c.o
In file included from /home/zhouwenyuan/abc.c:7:
/home/zhouwenyuan/abc.h:26:15: error: expected declaration specifiers or '...' before 'sizeof'
26 | static_assert(sizeof(block_q2_K) == 2*sizeof(ggml_fp16_t) + QK_K/16 + QK_K/4, "wrong q2_K block size/padding");
| ^~~~~~
In file included from /home/zhouwenyuan/llama.cpp/k_quants.c:1:
/home/zhouwenyuan/llama.cpp/k_quants.h:26:15: error: expected declaration specifiers or '...' before 'sizeof'
26 | static_assert(sizeof(block_q2_K) == 2*sizeof(ggml_fp16_t) + QK_K/16 + QK_K/4, "wrong q2_K block size/padding");
解决办法:
替换static_assert
为_Static_assert
3. 链接错误
在编译过程中的链接阶段:
~/.conda/envs/gcc9.5/bin/../lib/gcc/x86_64-conda-linux-gnu/9.5.0/../../../../x86_64-conda-linux-gnu/bin/ld: ~/.conda/envs/gcc9.5/bin/../lib/gcc/x86_64-conda-linux-gnu/9.5.0/libstdc++.so: undefined reference to `memcpy@GLIBC_2.14'
~/.conda/envs/gcc9.5/bin/../lib/gcc/x86_64-conda-linux-gnu/9.5.0/../../../../x86_64-conda-linux-gnu/bin/ld: ~/.conda/envs/gcc9.5/bin/../lib/gcc/x86_64-conda-linux-gnu/9.5.0/libstdc++.so: undefined reference to `aligned_alloc@GLIBC_2.16'
~/.conda/envs/gcc9.5/bin/../lib/gcc/x86_64-conda-linux-gnu/9.5.0/../../../../x86_64-conda-linux-gnu/bin/ld: ~/.conda/envs/gcc9.5/bin/../lib/gcc/x86_64-conda-linux-gnu/9.5.0/libstdc++.so: undefined reference to `clock_gettime@GLIBC_2.17'
通过一番艰苦搜索,终于在这篇帖子找到了办法,原来是因为安装的glibc版本太低(2.12),但链接符号的库版本过高(2.14,2.16,2.17)导致了这个问题,所以只需安装高版本的glibc库即可。
解决办法:
conda install 'sysroot_linux-64=2.17' -c https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge
这一问题也让我突然明白,前面的两个错误应该也是引用了低版本的sysroot导致的,把代码和参数调回去,果然问题没有再出现。
另外这篇帖子也给人启发,原来Miniforge中那么多的发布版本,其中的那个Mamba能够更快地解析远程仓库信息,难怪conda每次运行install都那么慢!而且miniconda和miniforge的解析也容易出现问题,比如上面的错误,安装gxx-9.5.0并竟然没有自动引用高版本的sysroot
。