资讯详情

资讯详情

llama.cpp RISC-V 64 交叉编译实战:面向 SpacemiT SoC 的 IME 矩阵加速构建与 QEMU 仿真验证

llama.cpp RISC-V 64 交叉编译实战面向 SpacemiT SoC 的 IME 矩阵加速构建与 QEMU 仿真验证【免费下载链接】llama.cppLLM inference in C/C项目地址: https://gitcode.com/GitHub_Trending/ll/llama.cpp本文基于仓库内 docs/build-riscv64-spacemit.md 展开完整覆盖在 x86 主机上交叉编译 llama.cpp 以运行于 SpacemiT香山/X60、A100 等RISC-V 64 位 SoC 的全流程工具链准备、CMake 构建选项、QEMU 仿真运行、矩阵量化类型支持矩阵并结合ggml/src/ggml-cpu/spacemit/源码深入解释 IME1/IME2 两套矩阵扩展的自动检测与量化内核分发机制。读完后你可以独立完成一次可部署的 riscv64 构建、在无 RISC-V 硬件的主机上仿真验证并理解不同量化格式在不同芯片上的加速路径选择。适用范围与硬件背景该构建文档仅针对 SpacemiT 的 RISC-V SoC原文档开头即以 IMPORTANT 注明。从运行时源码看llama.cpp 支持的 SpacemiT 核心架构定义在 ggml/src/ggml-cpu/spacemit/ime_env.h 中架构 ID枚举值说明core_arch_x600x503C通用计算核心X60core_arch_x1000x5064X100core_arch_x2000x50C8X200core_arch_a600xA03CAI 矩阵核心IME1 能力core_arch_a1000xA064AI 矩阵核心IME2 能力core_arch_a2000xA0C8A200运行时的核心识别逻辑在 ime_env.cpp解析/proc/cpuinfo中每个 processor 的marchid并与内置映射表比对。文档性能章节给出的marchid如 X60 为0x8000000058000001、A100 为0x8000000041000002与映射表一致可印证芯片型号识别方式。两套加速能力在 ggml/src/ggml-cpu/cmake/FindSMTIME.cmake 中定义IME1通过尝试编译内联汇编vmadot v2, v0, v1检测能力齐备则定义RISCV64_SPACEMIT_IME1IME2需要vmadot ... , i44-bit 点积累加同时支持vpack.vv与vnspack.vv打包/解包指令才定义RISCV64_SPACEMIT_IME2若编译器为 GCC ≥ 15march 字符串还会追加_xsmtvdotii见 ggml/src/ggml-cpu/CMakeLists.txt。检测出的规格以宏的形式注入编译见 CMakeLists.txttarget_compile_definitions(... GGML_USE_CPU_RISCV64_SPACEMIT ${RISCV64_SPACEMIT_IME_SPEC})随后加入spacemit/目录下的全部内核源文件ime.cpp、ime1_kernels.cpp、ime2_kernels.cpp、rvv_kernels.cpp、spine_mem_pool.cpp等。第一步准备 RISC-V 交叉工具链在 x86_64 主机上交叉编译先下载 SpacemiT 官方工具链来自原文档wget https://github.com/spacemit-com/toolchain/releases/download/v1.2.4/spacemit-toolchain-linux-glibc-x86_64-v1.2.4.tar.xz解压后必须导出根目录环境变量这是构建的硬性前提export RISCV_ROOT_PATH{your_compiler_path}工具链文件 cmake/riscv64-spacemit-linux-gnu-gcc.cmake 的机制值得注意若主机本身就是 riscv 架构CMAKE_HOST_SYSTEM_PROCESSOR以riscv开头则走本机原生编译分支不再需要交叉工具链否则从RISCV_ROOT_PATH环境变量读取编译器路径未设置时直接FATAL_ERROR第 9–13 行并配置riscv64-unknown-linux-gnu-gcc/g/strip与 sysroot统一追加编译标志第 27–29 行set(CMAKE_C_FLAGS -marchrv64gcv_zfh_zvfh_zba_zicbop -mabilp64d -fno-tree-vectorize -fno-tree-loop-vectorize ${CMAKE_C_FLAGS})其中-fno-tree-vectorize系列标志用于关闭 GCC 的自动向量化因为 SpacemiT 内核使用的是显式 RVV/IME 汇编自动向量化反而可能干扰链接阶段追加-latomic。此外CMAKE_FIND_ROOT_PATH_MODE_*设置为ONLY/NEVER确保交叉链接只使用目标 sysroot 中的库与头文件。第二步CMake 配置与构建原文档给出的完整构建脚本如下需启用GGML_CPU_RISCV64_SPACEMIT并配合 RISC-V 向量扩展选项cmake -B build \ -DCMAKE_BUILD_TYPERelease \ -DGGML_CPU_RISCV64_SPACEMITON \ -DGGML_CPU_REPACKOFF \ -DLLAMA_OPENSSLOFF \ -DGGML_RVVON \ -DGGML_RV_ZVFHON \ -DGGML_RV_ZFHON \ -DGGML_RV_ZICBOPON \ -DGGML_RV_ZIHINTPAUSEON \ -DGGML_RV_ZBAON \ -DCMAKE_TOOLCHAIN_FILE${PWD}/cmake/riscv64-spacemit-linux-gnu-gcc.cmake \ -DCMAKE_INSTALL_PREFIXbuild/installed cmake --build build --parallel $(nproc) --config Release pushd build make install popd各选项的作用结合源码逐一说明选项作用与依据GGML_CPU_RISCV64_SPACEMITON总开关。开启后 CMake 引入FindSMTIME.cmake做 IME 能力探测并把ggml-cpu/spacemit/下 12 个源文件加入编译见 CMakeLists.txtGGML_RVVON启用标准 RISC-V 向量扩展V 扩展基线路径。march 字符串在rv64gc基础上追加vCMakeLists.txtGGML_RV_ZFH/GGML_RV_ZVFH单精度浮点压缩zfh与向量浮点压缩zvfh。ime.cpp 中显式检查__riscv_zfh与__riscv_zvfh宏缺失则直接#error中断编译所以这两项是硬依赖GGML_RV_ZBAbitmanip 扩展同样是 ime.cpp 强制检查项GGML_RV_ZICBOP/GGML_RV_ZIHINTPAUSE缓存预取与线程暂停提示指令用于多线程内核同步的优化属可选增强GGML_CPU_REPACKOFF关闭通用的 repack 后端缓冲区。从源码结构看SpacemiT 自带专用的 repack 缓冲与张量布局重排spacemit/repack.cpp关闭通用 repack 避免两条路径冲突LLAMA_OPENSSLOFF交叉编译环境下关闭 OpenSSL 依赖减少目标平台库的查找负担CMAKE_TOOLCHAIN_FILE...riscv64-spacemit-linux-gnu-gcc.cmake指定上文分析的 SpacemiT 专用工具链文件CMAKE_INSTALL_PREFIXbuild/installed安装输出目录供make install使用构建产物为build/bin/下的llama-cli、llama-server等可执行文件。第三步QEMU 仿真验证无 RISC-V 硬件时原文档提供了在 x86 等架构上用 QEMU 仿真运行构建产物的方法下载 SpacemiT 定制版 QEMUwget https://archive.spacemit.com/spacemit-ai/qemu/jdsk-qemu-v0.0.14.tar.gz运行仿真以llama-cli加载 Qwen2.5-0.5B 模型为例export QEMU_ROOT_PATH{your QEMU file path} export RISCV_ROOT_PATH_IME1{your RISC-V compiler path} ${QEMU_ROOT_PATH}/bin/qemu-riscv64 -L ${RISCV_ROOT_PATH_IME1}/sysroot \ -cpu max,vlen256,elen64,vext_specv1.0 \ ${PWD}/build/bin/llama-cli -m ${PWD}/models/Qwen2.5-0.5B-Instruct-Q4_0.gguf -t 1要点解析-L ${RISCV_ROOT_PATH_IME1}/sysroot指定 guest 的库搜索根目录即交叉工具链自带的 glibc sysroot保证动态链接可解析-cpu max,vlen256,elen64,vext_specv1.0选择 QEMU 最完整的 CPU 模型向量寄存器长度设为 256 位与 X60 的 RVV 宽度匹配向量扩展规范锁定为 v1.0仿真主要用于功能验证指令正确性、模型加载、推理链路不代表真实性能性能数据以真机运行为准。另外仿真环境还有一个特殊处理QEMU 下/proc/cpuinfo拿不到真实的marchidspine_core_info::get_spine_core_info()会返回空列表此时 ime_env.cpp 会回退到读取SPACEMIT_CORE_ARCH环境变量十六进制架构 ID来伪造核心架构信息若两者都拿不到构造函数会直接抛出 Failed to get SPACEMIT_CORE_ARCH from environment or failed to parse it from /proc/cpuinfo 异常。因此仿真 SpacemiT 后端时建议按目标芯片设置该变量例如SPACEMIT_CORE_ARCHA064模拟 A100 的 IME2 路径。量化类型支持矩阵X60 与 A100原文档给出了矩阵乘法量化支持表量化类型X60A100Q2_K✅Q3_K✅Q4_0✅✅Q4_1✅✅Q4_K✅✅Q5_0✅Q5_1✅Q5_K✅Q6_K✅Q8_0✅这张表与源码中的 repack 类型分发表完全对应。ggml_riscv64_spacemit_get_optimal_repack_type 按张量类型选择专用矩阵内核其选择逻辑同时受编译宏RISCV64_SPACEMIT_IME1/IME2与运行时核心架构use_ime1/use_ime2双重约束IME1 路径X60/A60、X100 核心要求行维度ne[1] % 16 0仅 Q4_0、Q4_1、Q4_K 三种类型有 16×32 形状的 IME1 内核——与表中 X60 一列严格一致IME2 路径A100 核心要求ne[1] % 32 0Q2_K、Q3_K、Q4_0另有ne[0] % 256 0时的 32×256 变体、Q4_1、Q4_K、Q5_0、Q5_1、Q5_K、Q6_K、Q8_0 全部具备 32×32 形状的 IME2 内核——与表中 A100 一列严格一致未命中任何专用内核的张量会回退到通用 RVV 基线实现rvv_impl保证可运行但吞吐较低GGML_TYPE_MXFP4在 ime.cpp 中尚为 TODO 注释状态暂未启用。值得注意的一个细节IME1 与 IME2 的选择由运行时核心架构自动决定ime_env.cppperfer_core_arch_id为 A60/X100 时置use_ime1为 A100 时置use_ime2。X60 SoC 的混合核心通用核 少量 AI 核在初始化时有专门处理8 核且前 4 核为 x60 架构时会把前 4 核按 a60 对待ime_env.cpp这正是 X60 只支持 Q4_0/Q4_1/Q4_K 的硬件根源。运行时调优环境变量除构建期选项外SpacemiT 运行时还提供一组环境变量全部解析逻辑位于 ggml/src/ggml-cpu/spacemit/ime_env.cpp原文档未展开此处补充环境变量取值作用SPACEMIT_CORE_ARCH十六进制架构 ID如A064核心列表为空时典型场景QEMU 仿真伪造核心架构取值见上文架构 ID 表SPACEMIT_PERFER_CORE_ARCH十六进制架构 ID指定优先使用的核心架构未设置时默认自动挑选架构号高字节为0xA的 AI 核心A 系列核SPACEMIT_PERFER_CORE_ID逗号分隔的核心 ID 列表如4,5,6,7精确指定优先核心列表中任何核心架构与SPACEMIT_PERFER_CORE_ARCH不符会直接 abortSPACEMIT_MEM_BACKENDNONE/POSIX/HPAGE/HPAGE1GB内部内存池分配后端默认HPAGE透明大页可切换posix_memalign、1GB 大页或关闭内存池SPACEMIT_DISABLE_TCM非0即禁用关闭 TCM片上计算存储相关优化未禁用时自动探测 TCM 可用性并记录块大小调试日志输出tcm is available, blk_size: ...这些变量在模型加载初始化阶段一次性读取并缓存于全局global_spine_env_infoime_env.h配合-v详细日志可以看到核心的解析结果num_cores、num_perfer_cores、use_ime1/use_ime2、mem_backend、cpu_mask等。官方性能参考数据以下为原文档给出的真机llama-bench风格基准均为 CPU 后端n_ubatch128、启用 Flash Attention引用时请注意测试条件与模型规模Spacemit(R) X60marchid: 0x80000000580000014 线程RVV 宽度 256 位modelsizeparamsthreadstestt/sqwen35 2B Q4_11.19 GiB1.88 B4pp12810.32 ± 0.02qwen35 2B Q4_11.19 GiB1.88 B4tg1283.07 ± 0.01qwen3 0.6B Q4_0358.78 MiB596.05 M4pp12849.15 ± 0.25qwen3 0.6B Q4_0358.78 MiB596.05 M4tg12811.73 ± 0.02Spacemit(R) A100marchid: 0x80000000410000028 线程modelsizeparamsthreadstestt/sqwen3 0.6B Q4_0358.78 MiB596.05 M8pp128565.83 ± 0.31qwen3 0.6B Q4_0358.78 MiB596.05 M8tg12855.77 ± 0.02qwen3 4B Q4_02.21 GiB4.02 B8pp12879.74 ± 0.04qwen3 4B Q4_02.21 GiB4.02 B8tg12811.29 ± 0.00qwen3moe 30B.A3B Q4_016.18 GiB30.53 B8pp12857.88 ± 0.31qwen3moe 30B.A3B Q4_016.18 GiB30.53 B8tg12812.79 ± 0.00qwen35 2B Q4_11.19 GiB1.88 B8pp128115.23 ± 0.04qwen35 2B Q4_11.19 GiB1.88 B8tg12816.49 ± 0.01gemma4 E4B Q4_K - Medium4.76 GiB7.52 B8pp12821.13 ± 0.01gemma4 E4B Q4_K - Medium4.76 GiB7.52 B8tg1285.66 ± 0.00从数据可以看出两点A100 的 IME2 矩阵核心在 0.6B 小模型上的 prompt 处理吞吐565 t/s显著高于 X6049 t/s印证了 IME2 更宽的矩阵单元而 X60 上测试的模型均为 Q4_1/Q4_0 量化正好落在 IME1 支持矩阵内——若给 X60 使用 Q2_K/Q5_K 等量化则会退回 RVV 基线路径。小结关键路径速查阶段关键命令 / 文件工具链设置RISCV_ROOT_PATH工具链文件 cmake/riscv64-spacemit-linux-gnu-gcc.cmakeIME 能力探测ggml/src/ggml-cpu/cmake/FindSMTIME.cmake编译宏RISCV64_SPACEMIT_IME1/IME2构建cmake -B build -DGGML_CPU_RISCV64_SPACEMITON ...完整脚本见上文第二步仿真qemu-riscv64 -L sysroot -cpu max,vlen256,elen64,vext_specv1.0 ...必要时设SPACEMIT_CORE_ARCH内核分发ggml/src/ggml-cpu/spacemit/ime.cpp量化类型 → IME1/IME2/RVV 内核选择运行调优SPACEMIT_PERFER_CORE_ARCH、SPACEMIT_PERFER_CORE_ID、SPACEMIT_MEM_BACKEND、SPACEMIT_DISABLE_TCM解析于 ime_env.cpp需要强调的是该路径只适用于 SpacemiT SoC其他 RISC-V 64 平台如通用 RVV 芯片应走不带GGML_CPU_RISCV64_SPACEMIT的标准GGML_RVV构建。所有性能数字仅反映文档所列机型与量化组合换用其他硬件或量化类型前应先自行基准测试。【免费下载链接】llama.cppLLM inference in C/C项目地址: https://gitcode.com/GitHub_Trending/ll/llama.cpp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →