ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

ONNX Runtime RISC-V RVV 调优实战:MLAS 独立基准测试与 RVV/标量对比工具指南

ONNX Runtime RISC-V RVV 调优实战:MLAS 独立基准测试与 RVV/标量对比工具指南 ONNX Runtime RISC-V RVV 调优实战MLAS 独立基准测试与 RVV/标量对比工具指南【免费下载链接】onnxruntimeONNX Runtime: cross-platform, high performance ML inferencing and training accelerator项目地址: https://gitcode.com/GitHub_Trending/on/onnxruntime本文基于 ONNX Runtime 仓库中 RISC-V MLAS 基准测试目录说明 展开系统讲解该目录下独立于 Google Benchmark 套件的 RVV 调优工具如何在 riscv64 环境构建onnxruntime_mlas_sgemm_riscv_bench与onnxruntime_mlas_softmax_riscv_compare两个可执行文件如何使用它们对 SGEMM 与 Softmax 关键路径做 RVV 对比标量的性能与正确性验证并深入到 MLAS 平台分派层源码说明ORT_MLAS_RISCV_FORCE_SCALAR环境变量与 VLEN 无关VLEN-agnostic设计的实现原理。一、背景MLAS 的 RVV 路径与独立基准工具的定位MLASMachine Learning Acceleration library是 ONNX Runtime 的 CPU 底层算数加速库位于 onnxruntime/core/mlas 目录。对于 RISC-V 目标MLAS 通过 RVVRISC-V Vector Extension提供了 SGEMM、Softmax、量化 GEMM、卷积、RoPE、LayerNorm 等内核的向量化实现内核源码清单见 cmake/onnxruntime_mlas.cmake 中${MLAS_SRC_DIR}/riscv64/下的sgemm_kernel_rvv.cpp、softmax_kernel_rvv.cpp、qgemm_kernel_rvv.cpp等文件。在 RVV 路径的调试与调优bringing up and tuning过程中标准基准套件往往不够用。按照 onnxruntime/test/mlas/bench/riscv64/README.md 的定位说明该目录存放用于在 MLAS 中搭建并调优 RVV 路径时的独立基准与对比工具。这些工具刻意与onnxruntime_mlas_benchmark分离每个源文件拥有自己的main()作为独立 CMake target 构建。这一设计的工程价值在于可单独计时与校验标准套件面向 Google Benchmark 框架而独立工具可以直接打印 pack 时间、计算时间、校验和checksum并支持 RVV 与标量两种执行路径的 A/B 对比不污染主基准普通onnxruntime_mlas_benchmark的源码收集会显式排除 riscv64 子目录见 cmake/onnxruntime_unittests.cmake 中list(FILTER MLAS_BENCH_SOURCE_FILES EXCLUDE REGEX ${MLAS_BENCH_DIR}/riscv64/.*)平台门禁清晰riscv64 专属 target 仅在CMAKE_SYSTEM_PROCESSOR MATCHES ^riscv64.*时注册cmake/onnxruntime_unittests.cmake非 RISC-V 平台不会误构建。二、目录中的工具全集onnxruntime/test/mlas/bench/riscv64/ 目录当前包含六个源文件。README 明确说明其中两个源文件说明摘自 READMEsgemm_riscv_bench.cpp独立 SGEMM 计时 harness带 checksum 输出用于 RVV 与标量的对比softmax_rvv_compare.cppSoftmax 关键路径的标量 vs RVV 验证与计时工具此外从 CMake 构建脚本 cmake/onnxruntime_unittests.cmake 看同一目录下的另外四个源文件也被注册为独立 riscv64 基准 target覆盖了更多 LLM 推理关键算子CMake target源文件onnxruntime_mlas_sgemm_riscv_benchsgemm_riscv_bench.cpponnxruntime_mlas_softmax_riscv_comparesoftmax_rvv_compare.cpponnxruntime_mlas_halfgemm_rvv_benchhalfgemm_rvv_bench.cpponnxruntime_mlas_cast_rvv_benchcast_rvv_bench.cpponnxruntime_mlas_rope_rvv_benchrope_rvv_bench.cpponnxruntime_mlas_rmsnorm_rvv_benchrmsnorm_rvv_bench.cpp这些 target 统一链接${ONNXRUNTIME_MLAS_LIBS} onnxruntime_common并注入mlas_private_compile_definitions编译宏保证与 MLAS 库使用完全一致的平台定义。三、构建流程重新生成构建树并编译独立工具3.1 适用前提构建必须在 riscv64 架构上进行且 MLAS 以 RVV 支持启用。README 给出的完整流程分两步先用build.py重新生成构建树再用 CMake 只构建两个独立工具 target。如需交叉编译仓库提供了 cmake/riscv64.toolchain.cmake它通过RISCV_TOOLCHAIN_ROOT定位riscv64-unknown-linux-gnu-gcc/g工具链。3.2 第一步重新生成构建树python3 tools/ci_build/build.py \ --config Release \ --build_dir build/k1_rvv_resync \ --update \ --skip_tests \ --skip_pip_install \ --skip_submodule_sync \ --no_sve \ --enable_rvv各参数作用--config Release以 Release 配置构建基准计时才有意义--build_dir build/k1_rvv_resync独立构建目录避免污染其他构建--update重新运行 configure 生成构建树--skip_tests --skip_pip_install --skip_submodule_sync跳过测试构建、pip 安装与子模块同步加速纯 CMake 配置流程--enable_rvv启用 MLAS 的 RVV 内核对应MLAS_USE_RVV宏这是本目录所有工具工作的前提--no_sve在 ARM 相关配置上关闭 SVE对 RISC-V 目标属于无害的配置显式化。3.3 第二步直接以 CMake 构建两个工具cmake --build build/k1_rvv_resync/Release \ --config Release \ --target onnxruntime_mlas_sgemm_riscv_bench onnxruntime_mlas_softmax_riscv_compare \ -- -j8生成的二进制通常位于build/k1_rvv_resync/Release/onnxruntime_mlas_sgemm_riscv_bench build/k1_rvv_resync/Release/onnxruntime_mlas_softmax_riscv_compare由于每个源文件自带main()且是独立 target--target方式只编译这两个工具无需构建整个 onnxruntime 测试体系这在 RISC-V 设备上编译资源有限尤其重要。四、SGEMM 基准工具参数、用法与源码细节4.1 README 给出的两条核心命令RVV 路径packed-Btaskset -c 0 build/k1_rvv_resync/Release/onnxruntime_mlas_sgemm_riscv_bench \ --m128 --n3072 --k768 --iters10 --warmup3 --pack_b1 --trans_a0 --trans_b0同一二进制上的标量基线通过环境变量切换无需重新构建ORT_MLAS_RISCV_FORCE_SCALAR1 taskset -c 0 \ build/k1_rvv_resync/Release/onnxruntime_mlas_sgemm_riscv_bench \ --m128 --n3072 --k768 --iters10 --warmup3 --pack_b1 --trans_a0 --trans_b0taskset -c 0将进程绑定到单核消除多核调度噪声使 GFLOPS 数字可复现。示例形状m128, n3072, k768是典型的 LLM 场景小批量128 个 token乘以宽权重矩阵。4.2 完整参数表结合源码解析从 sgemm_riscv_bench.cpp 的Options结构与ParseArgs实现看工具支持全部参数及其默认值如下参数默认值说明--mN128输出矩阵行数--nN3072输出矩阵列数同时是 B 的列数--kN768收缩维度--itersN20计时迭代次数必须 0否则报错退出--warmupN3预热迭代次数--pack_b0\|10false是否走 packed-B 路径接受1/true/on/yes--trans_a0\|10A 是否转置映射到CblasTrans/CblasNoTrans--trans_b0\|10B 是否转置--alphaF1.0GEMM 缩放因子 alpha--betaF0.0GEMM 缩放因子 betabeta0时每次迭代先把 C 清零4.3 执行流程与输出指标从 sgemm_riscv_bench.cpp 的main()看工具的执行流程是确定性数据生成MakeValue()用整数混合哈希index * 747796405u 2891336453u后再做雪崩置换生成[-1.0, 1.0)区间的浮点序列保证 A/B 矩阵在任意运行中完全一致——这是 checksum 可跨 RVV/标量两次运行对比的前提Packed-B 路径--pack_b1先调用MlasGemmPackBSize计算打包缓冲大小再对MlasGemmPackB计时得到 pack 耗时最后用打包后的 B 调用无trans_b的MlasGemm重载若该配置不支持打包返回 0工具直接报错退出计时与校验warmup 之后计时iters次MlasGemm调用输出如下指标pack_total_ms/pack_avg_ms仅 pack_b 时compute_total_ms/compute_avg_msgflops按2*m*n*k / (avg_compute_ms * 1e6)计算checksumC 矩阵全部元素之和用于快速比对 RVV 与标量结果是否一致。RVV 与标量对比时比较两组checksum是否相同、两组gflops的比值即为加速比。五、Softmax 对比工具RVV 分派验证与回归用例5.1 运行方式README 给出的调用方式非常简单——无需任何命令行参数taskset -c 0 build/k1_rvv_resync/Release/onnxruntime_mlas_softmax_riscv_compare工具入口有编译期门禁若不是MLAS_TARGET_RISCV64目标或未定义MLAS_USE_RVVmain()直接打印提示并退出见 softmax_rvv_compare.cpp这解释了为什么它必须搭配--enable_rvv的 riscv64 构建使用。5.2 输出内容解析从 softmax_rvv_compare.cpp 的main()看输出分三部分分派自检4 行布尔值打印dispatch_is_rvv_reduce、dispatch_is_rvv_sumexp、dispatch_is_rvv_softmax、dispatch_is_rvv_logsoftmax通过比较GetMlasPlatform()中各内核指针是否等于MlasReduceMaximumF32KernelRvv、MlasComputeSumExpF32KernelRvv等 RVV 符号来确认运行时真的走了 RVV 分派。这是排错利器——若某项为false说明 RVV 分派未生效例如 CPU 不支持 V 扩展。正确性回归用例PrintCompareCase内置 4 个固定用例逐行调用标量版本直接使用MlasReduceMaximumF32Kernel等内核与 RVV 版本走平台分派在宽输入范围uniform_real_distributionfloat(-150, 190)特意覆盖大负值/大正值以暴露 exp 溢出问题下计算并打印max_abs_diff/max_rel_diff相对误差分母取max(|scalar|, 1e-12)checksum_scalar/checksum_rvv以 12 位精度打印。内置用例包括3x128带 smooth 的 softmax 与 logsoftmax、63x95、16x211——其中 63 与 211 是非 16 对齐的形状专门检验 RVV 尾部处理tail handling。性能用例PrintTimingCase两个 attention 形态的形状4096x128100 次重复与1024x102420 次重复打印scalar_ms、rvv_ms与speedupscalar_ms/rvv_ms。Softmax 是 attention 的热路径该工具验证的三个底层内核ReduceMax、SumExp、SoftmaxOutput正是 Softmax 的三段式实现求行最大值数值稳定化→ 求 exp 之和 → 归一化输出同时覆盖log_softmax变体。六、源码纵深RVV 分派、运行时探测与 VLEN 无关设计6.1 RVV 分派的建立过程MLAS 的分派逻辑集中在 onnxruntime/core/mlas/lib/platform.cpp。在MLAS_TARGET_RISCV64分支中平台结构体先全部指向标量基线MlasReduceMaximumF32Kernel、MlasComputeSumExpF32Kernel等随后在MLAS_USE_RVV编译块内做运行时 RVV 探测#if defined(MLAS_USE_RVV) bool has_rvv true; #if defined(__linux__) has_rvv (getauxval(AT_HWCAP) COMPAT_HWCAP_ISA_V) ! 0; #endif if (MlasShouldForceScalarRiscv(std::getenv(ORT_MLAS_RISCV_FORCE_SCALAR))) { has_rvv false; } if (has_rvv) { this-GemmFloatKernel MlasGemmFloatKernelRvv; ... this-ReduceMaximumF32Kernel MlasReduceMaximumF32KernelRvv; this-ComputeSumExpF32Kernel MlasComputeSumExpF32KernelRvv; this-ComputeSoftmaxOutputF32Kernel MlasComputeSoftmaxOutputF32KernelRvv; ...这揭示了两个关键事实同一个二进制可以在无 V 扩展的 CPU 上安全运行Linux 下通过getauxval(AT_HWCAP)检查COMPAT_HWCAP_ISA_V位没有 V 扩展就整体回退标量路径ORT_MLAS_RISCV_FORCE_SCALAR1的作用点它在平台初始化时直接把has_rvv置为 false使全部分派回退到标量内核。这正是 README 推荐从同一构建中采集标量基线的原因——两次运行除内核实现外完全同码同参checksum与gflops具有严格可比性。6.2 VLEN 无关VLEN-agnostic的 SGEMM 实现README 的 Notes 指出RVV SGEMM 路径被设计为 VLEN 无关——MLAS 的打包格式仍为 16 列宽但每个 tile 使用运行时vsetvl分块消费因此同一二进制可跨 VLEN 128 与 256 等不同配置工作。这与 platform.cpp 中的注释互相印证// The V extension implies VLEN128, which holds the sixteen-float block. this-NchwcBlockSize 16;即打包格式packing format固定为 16 个 float 一列RVV 规范的 VLEN 下限 128 位恰好容纳 16 个 F32而计算时按当前 VLEN 用vsetvl动态决定每次向量化指令处理的元素数。带来的工程收益是在 VLEN128 设备上构建/调优过的二进制迁移到 VLEN256 设备无需重新编译只需保证构建时启用了 RVV 即可。6.3 ZVFH 半精度加速的条件分派从 platform.cpp 看MLAS_USE_RVV_ZVFHZvfh 半精度向量扩展块内还有二次运行探测HasFp16VectorAcceleration()仅在 CPU 实际支持时才挂接MlasCastF16ToF32KernelRvv/MlasCastF32ToF16KernelRvv。CMake 侧与之对应cmake/onnxruntime_mlas.cmake 中halfgemm_kernel_rvv.cpp、cast_kernel_rvv.cpp、hqnbitgemm_kernel_rvv.cpp属于额外的可选内核集合。做 FP16 性能对比时应先确认构建配置与 CPU 能力。七、实践建议与边界说明结合文档与源码使用这套工具时建议构建与测量分离build.py步骤只在配置或 CMake 文件变化后重新执行日常测量直接cmake --build ... --target增量编译即可同一形状、同一数据下成对测量SGEMM 工具的数据生成与参数完全由命令行决定RVV/标量两次运行务必保持除环境变量外所有参数一致用checksum一致性作为正确性门槛再比较gflops先看分派自检再看性能Softmax 工具开头 4 行dispatch_is_rvv_*若出现false后续 speedup 数据没有意义形状选择覆盖尾部路径参考 Softmax 工具内置的 63x95、16x211 用例调优 SGEMM 时除 16 倍数形状外也应测非对齐形状以暴露vsetvl尾块问题适用前提整套流程要求 riscv64 架构 --enable_rvv构建非 RISC-V 平台不会注册这些 targetSoftmax 工具在缺少 RVV 构建时会直接提示退出。README 中--no_sve与k1_rvv_resync构建目录是作者当时的具体工作流可按需替换为自己的构建目录名。八、小结onnxruntime/test/mlas/bench/riscv64/ 目录为 ONNX Runtime 的 RISC-V RVV 调优提供了一套小而锋利的工具链sgemm_riscv_bench用确定性数据 checksum 可选 packed-B把 SGEMM 的 RVV/标量对比压缩成两条命令softmax_rvv_compare用分派自检 固定回归用例 attention 形态计时验证 Softmax 关键路径的正确性与加速比。二者共同依托 MLAS 平台层platform.cpp的运行时 V 扩展探测与ORT_MLAS_RISCV_FORCE_SCALAR强制标量开关实现同一二进制、双路径、零重编译的对比测量而 16 列固定打包 运行时vsetvl分块的设计则让二进制在 VLEN 128/256 之间通用。这套独立 harness 平台分派自检的模式对任何需要为特定 ISA 内核做 A/B 验证的场景都有参考价值。【免费下载链接】onnxruntimeONNX Runtime: cross-platform, high performance ML inferencing and training accelerator项目地址: https://gitcode.com/GitHub_Trending/on/onnxruntime创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表