news 2026/9/7 9:03:04

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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通用计算核心(X60)
core_arch_x1000x5064X100
core_arch_x2000x50C8X200
core_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_IME1
  • IME2:需要vmadot ... , i4(4-bit 点积累加)同时支持vpack.vvvnspack.vv(打包/解包指令)才定义RISCV64_SPACEMIT_IME2
  • 若编译器为 GCC ≥ 15,march 字符串还会追加_xsmtvdotii(见 ggml/src/ggml-cpu/CMakeLists.txt)。

检测出的规格以宏的形式注入编译,见 CMakeLists.txt:target_compile_definitions(... GGML_USE_CPU_RISCV64_SPACEMIT ${RISCV64_SPACEMIT_IME_SPEC}),随后加入spacemit/目录下的全部内核源文件(ime.cppime1_kernels.cppime2_kernels.cpprvv_kernels.cppspine_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_PROCESSORriscv开头),则走本机原生编译分支,不再需要交叉工具链;
  • 否则从RISCV_ROOT_PATH环境变量读取编译器路径,未设置时直接FATAL_ERROR(第 9–13 行),并配置riscv64-unknown-linux-gnu-gcc/g++/strip与 sysroot;
  • 统一追加编译标志(第 27–29 行):
set(CMAKE_C_FLAGS "-march=rv64gcv_zfh_zvfh_zba_zicbop -mabi=lp64d -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_TYPE=Release \ -DGGML_CPU_RISCV64_SPACEMIT=ON \ -DGGML_CPU_REPACK=OFF \ -DLLAMA_OPENSSL=OFF \ -DGGML_RVV=ON \ -DGGML_RV_ZVFH=ON \ -DGGML_RV_ZFH=ON \ -DGGML_RV_ZICBOP=ON \ -DGGML_RV_ZIHINTPAUSE=ON \ -DGGML_RV_ZBA=ON \ -DCMAKE_TOOLCHAIN_FILE=${PWD}/cmake/riscv64-spacemit-linux-gnu-gcc.cmake \ -DCMAKE_INSTALL_PREFIX=build/installed cmake --build build --parallel $(nproc) --config Release pushd build make install popd

各选项的作用(结合源码逐一说明):

选项作用与依据
GGML_CPU_RISCV64_SPACEMIT=ON总开关。开启后 CMake 引入FindSMTIME.cmake做 IME 能力探测,并把ggml-cpu/spacemit/下 12 个源文件加入编译(见 CMakeLists.txt)
GGML_RVV=ON启用标准 RISC-V 向量扩展(V 扩展)基线路径。march 字符串在rv64gc基础上追加v(CMakeLists.txt)
GGML_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_REPACK=OFF关闭通用的 repack 后端缓冲区。从源码结构看,SpacemiT 自带专用的 repack 缓冲与张量布局重排(spacemit/repack.cpp),关闭通用 repack 避免两条路径冲突
LLAMA_OPENSSL=OFF交叉编译环境下关闭 OpenSSL 依赖,减少目标平台库的查找负担
CMAKE_TOOLCHAIN_FILE=...riscv64-spacemit-linux-gnu-gcc.cmake指定上文分析的 SpacemiT 专用工具链文件
CMAKE_INSTALL_PREFIX=build/installed安装输出目录,供make install使用

构建产物为build/bin/下的llama-clillama-server等可执行文件。

第三步:QEMU 仿真验证(无 RISC-V 硬件时)

原文档提供了在 x86 等架构上用 QEMU 仿真运行构建产物的方法:

  1. 下载 SpacemiT 定制版 QEMU:
wget https://archive.spacemit.com/spacemit-ai/qemu/jdsk-qemu-v0.0.14.tar.gz
  1. 运行仿真(以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,vlen=256,elen=64,vext_spec=v1.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,vlen=256,elen=64,vext_spec=v1.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_ARCH=A064模拟 A100 的 IME2 路径)。

量化类型支持矩阵:X60 与 A100

原文档给出了矩阵乘法量化支持表:

量化类型X60A100
Q2_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 == 0):Q2_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.cpp:perfer_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不符会直接 abort
SPACEMIT_MEM_BACKENDNONE/POSIX/HPAGE/HPAGE1GB内部内存池分配后端:默认HPAGE(透明大页),可切换posix_memalign、1GB 大页或关闭内存池
SPACEMIT_DISABLE_TCM0即禁用关闭 TCM(片上计算存储)相关优化;未禁用时自动探测 TCM 可用性并记录块大小(调试日志输出tcm is available, blk_size: ...

这些变量在模型加载初始化阶段一次性读取并缓存于全局global_spine_env_info(ime_env.h),配合-v详细日志可以看到核心的解析结果(num_coresnum_perfer_coresuse_ime1/use_ime2mem_backendcpu_mask等)。

官方性能参考数据

以下为原文档给出的真机llama-bench风格基准(均为 CPU 后端,n_ubatch=128、启用 Flash Attention),引用时请注意测试条件与模型规模:

Spacemit(R) X60marchid: 0x8000000058000001,4 线程,RVV 宽度 256 位):

modelsizeparamsthreadstestt/s
qwen35 2B Q4_11.19 GiB1.88 B4pp12810.32 ± 0.02
qwen35 2B Q4_11.19 GiB1.88 B4tg1283.07 ± 0.01
qwen3 0.6B Q4_0358.78 MiB596.05 M4pp12849.15 ± 0.25
qwen3 0.6B Q4_0358.78 MiB596.05 M4tg12811.73 ± 0.02

Spacemit(R) A100marchid: 0x8000000041000002,8 线程):

modelsizeparamsthreadstestt/s
qwen3 0.6B Q4_0358.78 MiB596.05 M8pp128565.83 ± 0.31
qwen3 0.6B Q4_0358.78 MiB596.05 M8tg12855.77 ± 0.02
qwen3 4B Q4_02.21 GiB4.02 B8pp12879.74 ± 0.04
qwen3 4B Q4_02.21 GiB4.02 B8tg12811.29 ± 0.00
qwen3moe 30B.A3B Q4_016.18 GiB30.53 B8pp12857.88 ± 0.31
qwen3moe 30B.A3B Q4_016.18 GiB30.53 B8tg12812.79 ± 0.00
qwen35 2B Q4_11.19 GiB1.88 B8pp128115.23 ± 0.04
qwen35 2B Q4_11.19 GiB1.88 B8tg12816.49 ± 0.01
gemma4 E4B Q4_K - Medium4.76 GiB7.52 B8pp12821.13 ± 0.01
gemma4 E4B Q4_K - Medium4.76 GiB7.52 B8tg1285.66 ± 0.00

从数据可以看出两点:A100 的 IME2 矩阵核心在 0.6B 小模型上的 prompt 处理吞吐(565 t/s)显著高于 X60(49 t/s),印证了 IME2 更宽的矩阵单元;而 X60 上测试的模型均为 Q4_1/Q4_0 量化,正好落在 IME1 支持矩阵内——若给 X60 使用 Q2_K/Q5_K 等量化则会退回 RVV 基线路径。

小结:关键路径速查

阶段关键命令 / 文件
工具链设置RISCV_ROOT_PATH;工具链文件 cmake/riscv64-spacemit-linux-gnu-gcc.cmake
IME 能力探测ggml/src/ggml-cpu/cmake/FindSMTIME.cmake(编译宏RISCV64_SPACEMIT_IME1/IME2
构建cmake -B build -DGGML_CPU_RISCV64_SPACEMIT=ON ...(完整脚本见上文第二步)
仿真qemu-riscv64 -L <sysroot> -cpu max,vlen=256,elen=64,vext_spec=v1.0 ...;必要时设SPACEMIT_CORE_ARCH
内核分发ggml/src/ggml-cpu/spacemit/ime.cpp(量化类型 → IME1/IME2/RVV 内核选择)
运行调优SPACEMIT_PERFER_CORE_ARCHSPACEMIT_PERFER_CORE_IDSPACEMIT_MEM_BACKENDSPACEMIT_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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/7 9:00:05

谢三枪开荒指南:萌新如何用复盘思维击败三连击机制敌人

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/7 8:58:47

C#上位机集成libNFC:NFC读卡器封装实战与工业应用

简介&#xff1a;面向需要在C#中调用libNFC实现近场通信&#xff08;NFC&#xff09;功能的.NET开发者&#xff0c;提供了一套可直接参考的多项目解决方案&#xff0c;围绕P/Invoke跨平台调用、设备发现与连接、标签读写、NDEF消息处理、事件驱动和资源释放等核心环节展开&…

作者头像 李华
网站建设 2026/9/7 8:58:22

湖南单招学考成绩重要吗,考差了怎么办?湘楚有才单招官方深度解析

湘楚有才单招全国咨询热线:400‑893‑7001,湘楚有才单招官方咨询专线:13203104897前言每年湖南单招备考季,家长问得最多的核心问题就是:孩子学考成绩一般、甚至考得比较差,还能不能走单招上岸公办大专?湖南单招学考成绩到底重不重要?学考低分有没有补救办法、翻盘机会?绝大多…

作者头像 李华
网站建设 2026/9/7 8:57:22

DeepSeek Harness实战:API接入、Agent边界与多模态识图方案

很多人第一次接触 DeepSeek&#xff0c;是从网页对话开始的。输入一段提示词&#xff0c;模型给你一段回答&#xff0c;体验不错&#xff0c;但真把它放进自己的工作流里&#xff0c;立刻会遇到几种尴尬&#xff1a;页面之外没法用、图片传进去没反应、想让它操作本地代码或文档…

作者头像 李华