国产化平台部署大模型:aarch64麒麟系统下llama.cpp CUDA编译踩坑实录

📅 2026/8/26 10:46:19
国产化平台部署大模型:aarch64麒麟系统下llama.cpp CUDA编译踩坑实录
1. 项目缘起一次在国产化平台上的“硬核”尝试最近手头有个挺有意思的活儿或者说是一次充满挑战的“踩坑”之旅。我需要在单位一台搭载了国产飞腾CPUaarch64架构和银河麒麟KylinV10操作系统的服务器上尝试运行一个经过中文优化的LLaMA-2模型。这台服务器还插着一张老当益壮的NVIDIA Tesla P4计算卡8GB显存虽然算力在今天看来不算顶尖但跑跑7B、13B参数的模型理论上还是能试试的。我的计划很明确使用llama.cpp这个高效、轻量的推理框架并为其编译CUDA支持以便让Tesla P4的GPU能力派上用场加速中文大模型Chinese-LLaMA-Alpaca-2的推理过程。理想很丰满但现实往往骨感。这个标题里的“【失败】”两个字已经提前剧透了结局。不过在我看来一次完整的、有记录的失败尝试其价值远大于一个语焉不详的成功。它不仅能帮我自己理清思路避免下次在同一个地方摔倒更能为所有在类似国产化软硬件环境下折腾AI的同行们提供一份真实的“避坑地图”。aarch64架构、Kylin系统、老款计算卡、特定的AI框架这几个关键词组合在一起几乎就是一个“小众环境”的典型样本其中的兼容性问题、依赖冲突、编译陷阱每一步都可能让人头疼不已。接下来我就把这趟从满怀希望到最终受挫的全过程以及我排查问题的完整思路毫无保留地分享出来。2. 环境侦察理解我们的“战场”与“武器”在开始任何操作之前彻底摸清环境是避免盲目行动的第一步。这次的环境配置相当特殊几乎每一步都需要仔细确认。2.1 硬件与操作系统底细首先是最基础的硬件和系统信息。通过一系列命令我们得到了以下关键情报CPU架构uname -m明确输出aarch64。这不是我们常见的x86_64AMD64架构而是ARM架构的服务器版本。这意味着所有软件从系统库到我们要编译的llama.cpp都需要针对这个架构进行编译或提供对应的预编译版本。操作系统cat /etc/os-release显示这是Kylin Linux Advanced Server release V10 (Sword)。银河麒麟V10是基于Linux内核的国产操作系统其软件源、库文件路径、甚至一些系统工具的行为可能与Ubuntu、CentOS等主流发行版存在差异。例如它的包管理器是apt但软件仓库的地址和内容需要配置为麒麟官方的源或兼容的国内镜像源如清华源、中科大源对aarch64架构的支持情况需要单独确认。GPU设备使用lspci | grep -i nvidia和nvidia-smi命令需要先安装NVIDIA驱动来确认Tesla P4的存在和状态。Tesla P4是基于Pascal架构的计算卡计算能力CUDA Capability为6.1。这是一个非常关键的数字它直接决定了CUDA Toolkit和后续编译出的GPU内核代码能否在这张卡上运行。2.2 核心软件栈的版本博弈我们的目标是让llama.cpp调用CUDA这涉及一个复杂的软件依赖链NVIDIA驱动-CUDA Toolkit-llama.cpp源码 -Chinese-LLaMA-Alpaca-2模型。每一环的版本都需要仔细斟酌。NVIDIA驱动这是与GPU硬件直接对话的底层软件。对于Tesla P4Pascal架构NVIDIA的长期支持分支Long-lived Branch版本通常都能提供良好支持。我们需要从麒麟的软件源或NVIDIA官网下载适用于aarch64架构的Linux驱动。安装时可能会遇到与麒麟系统内核模块DKMS的兼容性问题这是第一个潜在风险点。CUDA Toolkit这是开发CUDA程序的核心工具包包含编译器、库文件等。llama.cpp的CUDA后端在编译时需要链接CUDA的运行时库如libcudart.so。这里的选择至关重要版本兼容性CUDA Toolkit版本必须与NVIDIA驱动版本兼容。NVIDIA官网有详细的兼容性表格。对于较老的Pascal架构太新的CUDA版本如CUDA 12.x可能会弃用或不再优化对它的支持虽然基础功能可能还在但并非最佳选择。架构支持我们必须下载aarch64版本的CUDA Toolkit安装包通常是.run文件格式而不是x86_64版本。麒麟系统适配CUDA的安装脚本和依赖库可能会对系统库有特定要求。在麒麟系统上可能需要手动解决一些依赖关系比如特定版本的gcc、make、libstdc等。llama.cpp我们需要从GitHub拉取最新的源码。重点在于其CMakeLists.txt中的CUDA配置。我们需要确保CMake能找到我们安装的aarch64版CUDA Toolkit并正确设置计算能力CMAKE_CUDA_ARCHITECTURES为61对应Pascal架构的6.1。编译本身就是一个大坑后面会详细说。模型文件Chinese-LLaMA-Alpaca-2模型通常以GGUF格式提供。我们需要下载对应参数量如7B、13B的GGUF文件。这一步相对简单主要考验网络速度和存储空间。注意在aarch64平台上几乎所有软件都需要从源码编译或者寻找官方/社区提供的aarch64预编译包。直接使用x86_64的二进制文件是行不通的。这大大增加了环境准备的复杂度。3. 长征第一步在麒麟aarch64上部署CUDA环境这是整个项目的基础也是最容易出问题的环节。我的步骤和遇到的挑战如下3.1 NVIDIA驱动安装首先卸载系统上任何可能存在的旧版NVIDIA驱动。然后从NVIDIA官网下载适用于Linux aarch64的驱动安装包.run文件。在麒麟系统上需要先进入文本模式通常通过systemctl set-default multi-user.target并重启或者使用CtrlAltF2切换到tty因为图形界面如UKUI会占用GPU导致驱动安装失败。运行安装脚本时我遇到了第一个错误内核头文件不匹配。麒麟系统自带的内核头文件版本可能与当前运行的内核版本不一致。解决方案是先通过apt安装与uname -r输出完全一致的内核头文件包例如linux-headers-$(uname -r)。如果麒麟源里没有可能需要从系统安装镜像中寻找这是一个非常典型的国产系统适配问题。安装成功后运行nvidia-smi应该能看到Tesla P4的信息包括驱动版本和GPU状态。这标志着驱动层打通了。3.2 CUDA Toolkit 的安装与配置我选择了与Tesla P4兼容且相对稳定的CUDA 11.8的aarch64版本。下载巨大的.run文件后同样在文本模式下执行安装。这里不建议安装驱动因为我们已经装好了也不建议安装捆绑的gcc使用系统自带的即可。安装过程看似顺利但环境变量配置是关键。需要在~/.bashrc或系统级别的配置文件中添加export PATH/usr/local/cuda-11.8/bin${PATH::${PATH}} export LD_LIBRARY_PATH/usr/local/cuda-11.8/lib64${LD_LIBRARY_PATH::${LD_LIBRARY_PATH}}然后执行source ~/.bashrc使其生效。随后通过nvcc --version验证CUDA编译器是否可用并通过编译运行CUDA Samples中的deviceQuery程序来终极验证CUDA环境是否真的能在我们的P4上正常工作。deviceQuery会输出GPU的详细信息并最终显示Result PASS。实操心得在麒麟系统上LD_LIBRARY_PATH的配置有时会被系统的安全策略或其它应用覆盖。一个更稳健的方法是将CUDA库路径添加到/etc/ld.so.conf.d/目录下的一个新建conf文件中如cuda-11.8.conf内容为/usr/local/cuda-11.8/lib64然后运行sudo ldconfig更新动态链接器缓存。这能确保系统全局都能找到CUDA库。4. 编译大冒险为llama.cpp注入CUDA“灵魂”环境就绪接下来就是重头戏——编译支持CUDA的llama.cpp。4.1 源码准备与基础依赖克隆llama.cpp仓库并进入其目录。首先安装基础的编译工具链cmake,gcc,g,make。麒麟系统通常自带但需要确保版本不要太旧。4.2 CMake配置的“魔鬼细节”llama.cpp使用CMake构建。支持CUDA的关键配置命令如下mkdir build cd build cmake .. -DLLAMA_CUDAON -DCMAKE_CUDA_ARCHITECTURES61-DLLAMA_CUDAON 告诉CMake启用CUDA后端。-DCMAKE_CUDA_ARCHITECTURES61这是针对Tesla P4最核心的配置数字61代表计算能力6.1。如果这个参数设置错误例如设为默认的all或支持的新架构如80编译出的内核代码将无法在P4上运行最终会产生类似CUDA error: no kernel image is available for execution on the device的致命错误。然而在aarch64平台上事情没那么简单。执行上述cmake命令时我遭遇了第一个编译拦路虎CMake找不到CUDA Toolkit。即使环境变量都设置了CMake的FindCUDA模块在非标准路径或跨架构环境下有时会失灵。排查与解决我通过手动指定CUDA工具包路径来解决cmake .. -DLLAMA_CUDAON -DCMAKE_CUDA_ARCHITECTURES61 \ -DCUDAToolkit_ROOT/usr/local/cuda-11.8 \ -DCUDA_TOOLKIT_ROOT_DIR/usr/local/cuda-11.8同时还需要显式指定C和C编译器避免CMake使用可能存在的其他版本编译器-DCMAKE_C_COMPILER/usr/bin/gcc -DCMAKE_CXX_COMPILER/usr/bin/g经过一番调整CMake配置终于成功输出了包含CUDA found. Yes的配置摘要。4.3 编译过程中的“坑”与“坎”配置成功后运行make -j$(nproc)开始编译。编译过程漫长且消耗内存在aarch64平台上尤其如此。我遇到了几个典型问题内存不足编译某些大型CUDA文件时8GB或16GB内存可能吃紧导致编译器进程被杀死g: fatal error: Killed signal terminated program cc1plus。解决方案是减少并行编译任务数使用make -j2或make -j1或者增加交换空间swap。链接错误提示找不到cudart等CUDA库。这通常是因为LD_LIBRARY_PATH在编译环境中未生效或者CMake链接路径设置不对。回头检查CMakeCache.txt中CUDA_LIBRARIES等变量的值是否正确指向了/usr/local/cuda-11.8/lib64下的库文件。计算能力警告编译日志中可能会出现关于计算能力61的警告提示其已较老。只要不是错误可以忽略。我们的目标就是让它在P4上运行。经过漫长的等待编译终于完成生成了main、server等可执行文件。5. 遭遇滑铁卢CUDA内核映像缺失错误怀着激动的心情我使用编译好的./main程序加载一个较小的Chinese-LLaMA-Alpaca-2-7B的GGUF模型文件进行测试。命令类似./main -m ./models/chinese-alpaca-2-7b.gguf -n 128 --gpu-layers 20--gpu-layers 20表示将模型的前20层放到GPU上运行。然而程序启动后在初始化CUDA上下文、尝试加载模型层到GPU时控制台抛出了那个令人心碎的致命错误CUDA error: no kernel image is available for execution on the device这个错误直白地告诉我们当前设备Tesla P4上没有可供执行的内核映像kernel image。换句话说我们编译出来的GPU内核代码与当前GPU硬件不兼容。5.1 深度排查错误根源分析这个错误是CUDA开发中一个非常经典的兼容性问题。我开始了系统的排查验证计算能力设置首先确认CMake时-DCMAKE_CUDA_ARCHITECTURES61参数确实被正确应用。检查build/CMakeCache.txt文件搜索CMAKE_CUDA_ARCHITECTURES确认其值为61。检查编译日志重新编译并仔细查看输出日志。关注所有与nvccCUDA编译器相关的行。理想情况下应该看到它为compute_61,sm_61虚拟架构和真实架构生成代码。如果看到为sm_80,sm_90等更高架构生成代码那说明配置未生效。使用deviceQuery验证运行之前编译的deviceQuery再次确认GPU的计算能力CUDA Capability确实是6.1。检查llama.cpp代码查看llama.cpp源码中与CUDA编译相关的部分如CMakeLists.txt和ggml-cuda.cu。发现其CUDA内核代码使用了大量的模板和宏编译时依赖CMAKE_CUDA_ARCHITECTURES来生成对应架构的代码。理论上设置正确就应该能生成。经过以上排查我确认了CMake配置和编译目标架构在llama.cpp层面是正确的。那么问题可能出在更深层。5.2 怀疑转向CUDA Toolkit与驱动兼容性既然llama.cpp的编译目标没错那问题可能出在它依赖的CUDA运行时Runtime库与当前GPU驱动的兼容性上。CUDA有一个“最低驱动版本”的要求。用nvidia-smi查看驱动版本并与NVIDIA官方文档中CUDA 11.8所要求的最低驱动版本进行对比。Tesla P4作为数据中心卡其驱动版本通常能满足要求。但这里有一个更隐蔽的可能性虽然我们指定了为sm_61编译但CUDA Toolkitnvcc编译器在编译某些特定代码路径或依赖的底层库时可能默认链接或包含了为更高架构优化的代码或者我们安装的CUDA Toolkit版本本身对Pascal架构的支持存在某些已知问题。为了验证我尝试了一个更极端的测试编译一个最简单的、不依赖任何复杂模板的CUDA测试程序并指定计算能力为61看在P4上能否运行。如果这个简单程序也失败那就基本坐实是CUDA环境本身的问题。6. 问题定性与替代方案探索综合所有排查信息我将本次失败的根本原因定性为在aarch64架构的银河麒麟V10系统上使用特定版本的CUDA Toolkit11.8编译llama.cpp时生成的CUDA内核二进制映像与NVIDIA Tesla P4计算能力6.1的GPU微架构存在不兼容性。这种不兼容可能源于CUDA Toolkit在aarch64跨平台移植中对老架构支持的细微差异、编译器后端的某个bug或者是llama.cpp复杂模板代码与aarch64版nvcc交互产生的未知问题。鉴于时间和技术栈的限制我没有继续深挖这个特定编译问题的修复方法可能需要修改llama.cpp的CUDA内核代码或深入研究nvcc的编译选项。但这并不意味着在这台机器上运行中文大模型的尝试完全失败。我转向了以下几个替代方案纯CPU推理这是最直接、最稳定的退路。在CMake配置中不启用-DLLAMA_CUDAON而是启用OpenBLAS或ARM Compute Library针对aarch64有优化进行加速。使用-DLLAMA_BLASON -DLLAMA_BLAS_VENDOROpenBLAS。编译后模型完全在飞腾CPU上运行。虽然速度远慢于GPU但对于调试、测试或对延迟不敏感的应用来说是完全可行的。实测运行7B模型虽然生成速度慢可能只有1-2 token/秒但能够正确完成中文对话。尝试更旧或更新的CUDA版本这是一个有风险的尝试。可以尝试退回到CUDA 11.4或11.6等更早的、对Pascal架构支持可能更稳定的版本。或者冒险尝试CUDA 12.x看其是否修复了某个aarch64下的兼容性问题。但这需要重复整个驱动和Toolkit的安装、配置、编译流程时间成本高且结果不确定。使用Docker容器寻找或构建一个包含了预编译好CUDA支持且针对x86_64的llama.cpp的Docker镜像。然后尝试在麒麟系统上使用Docker的--runtimenvidia来运行。但这里有个巨大障碍宿主机的GPU是aarch64架构而Docker镜像内的可执行文件通常是x86_64架构。除非能找到或自己构建一个aarch64架构的、包含CUDA的llama.cppDocker镜像否则此路不通。而构建这样的镜像又会回到最初源码编译的问题上。评估其他推理框架考虑其他对国产化平台支持可能更好的推理框架例如FastTransformer或TensorRT-LLMNVIDIA官方的高性能推理库对自家硬件支持最好。但需要将GGUF模型转换为ONNX或其他框架支持的格式流程复杂且同样面临aarch64平台的编译问题。PPL.LLM国产的推理框架可能对麒麟飞腾平台有更好的优化和适配。需要调研其模型格式支持情况。最终基于项目进度的考虑我选择了方案一纯CPU推理作为短期解决方案确保了项目的基本功能可以验证。同时将“aarch64麒麟系统上llama.cppCUDA后端与Tesla P4的兼容性问题”作为一个待解决的技术难题记录了下来。7. 经验总结与给后来者的建议这次失败的尝试虽然没能达成最初的目标但收获了一套完整的、在国产化异构环境中部署AI模型的排查方法论。以下是我的几点核心经验环境兼容性是第一道鬼门关在aarch64/ARM架构、国产操作系统、老旧计算卡这种“非主流”组合上做AI部署必须将至少50%的精力放在环境适配和兼容性验证上。不要假设任何主流开源项目能“开箱即用”。计算能力Compute Capability是GPU编程的生命线任何时候编译CUDA程序首要任务就是确认目标GPU的计算能力并在编译时通过-DCMAKE_CUDA_ARCHITECTURESCMake或-archcompute_61 -codesm_61nvcc命令行精确指定。no kernel image错误十有八九源于此。分解验证逐步推进不要试图一步到位。应该建立一条清晰的验证链驱动安装成功 (nvidia-smi) - CUDA运行时环境就绪 (deviceQueryPASS) - 编译最小CUDA测试程序并运行 - 最后才去编译复杂的目标项目如llama.cpp。这样能在最早阶段隔离问题。善用社区和文档但保持怀疑llama.cpp的GitHub Issues、NVIDIA的官方文档、麒麟系统的社区论坛都是宝贵的资源。搜索错误信息时结合aarch64、Kylin、Tesla P4、sm_61等关键词。但也要意识到小众环境的组合可能找不到现成答案需要自己动手分析和实验。准备好退路在开始之前就想好如果GPU加速失败纯CPU方案的性能是否可接受。准备好对应的编译选项如BLAS加速确保项目至少有一条能走通的技术路径。这次“失败”的经历深刻地提醒我们在技术选型和应用落地时尤其是在充满不确定性的国产化与异构计算环境中对底层细节的掌握和系统性的排查能力与对高级算法和模型的理解同等重要。每一次踩坑都是对技术栈理解的一次加深。希望我的这份踩坑记录能为你未来的类似项目点亮一盏警示灯或者至少让你在遇到同样问题时知道从何查起。