资讯详情

资讯详情

Moonshine 项目 Android ONNX Runtime 最小化构建指南:从源码编译、操作符裁剪与安装体积实测

Moonshine 项目 Android ONNX Runtime 最小化构建指南从源码编译、操作符裁剪与安装体积实测【免费下载链接】moonshineVery low latency speech to text, intent recognition, and text to speech, for building voice agents and interfaces项目地址: https://gitcode.com/GitHub_Trending/moonshine3/moonshine本指南面向 Moonshine 的开发者与维护者讲解 Android 平台上 ONNX RuntimeORT运行库的供应链管理方案为什么仓库内core/third-party/onnxruntime/lib/android/下的三个.so必须由源码构建而非直接下载官方 AAR最小化构建对模型格式与执行提供程序Execution Provider产生了哪些硬性约束以及如何在提交前验证裁剪与 strip 结果。读完本文你将掌握scripts/build-ort-android.sh的完整用法、各 ABI 的体积收益数据以及用scripts/measure-mobile-size.sh实测真实安装成本的流程。目录这些.so从哪来源码构建而非下载最小化构建的两条硬性约束每个 ABI 的实测体积收益构建脚本用法与参数详解构建流程中的关键工程细节跨平台版本锁ort-build-common.sh提交前的验证与真实安装体积测量一、这些.so从哪来源码构建而非下载关联文档 core/third-party/onnxruntime/lib/android/README.md 开宗明义仓库内android/目录下按 ABI 分目录存放的libonnxruntime.so当前包含arm64/、armeabi-v7a/、x86_64/三个变体不是从官方发布渠道下载的预编译产物而是由scripts/build-ort-android.sh从源码构建后 vendor 进仓库的。这一点至关重要原因有三版本被固定构建脚本将 ONNX Runtime 钉在特定版本当前为1.23.2避免官方 AAR 升级引入行为漂移构建被裁剪整个构建被限制到 core/third-party/onnxruntime/moonshine-required-operators.config 所列的操作符集合只编译 Moonshine 模型真正用到的算子产物被 stripvendor 前会剥离符号与调试信息否则仓库体积会失控。因此文档明确警告不要向这个目录投放标准的 ONNX Runtime AAR。上层所有代码都假设底层是一个最小化构建minimal build放入完整版库虽然能跑但会破坏体积预算并在行为上与其它平台不一致。二、最小化构建的两条硬性约束最小化构建--minimal_build会丢弃 ONNX 解析器与部分图优化器由此产生两条在会话创建session creation时报错、而非编译时报错的约束任何使用该库的调用方都必须遵守1. 只加载 ORT 格式模型.ort最小化构建中根本没有编译进 ONNX 解析器因此.onnx文件在 Android以及 WebAssembly、iOS上永远无法被读取无论调用代码怎么写。为消除桌面端能用、移动端报晦涩解析错误的双格式分裂Moonshine 在所有平台统一只接受 ORT flatbuffer 编码的.ort模型。详细背景见 docs/ort-only-models.md。对使用方的影响是自行提供的自定义模型文件必须先用转换工具迁移python scripts/convert-models-to-ort.py path/to/model.onnx转换后.onnx会在启动时报出指明文件名与本命令的错误信息而不再是难以定位的解析异常。ONNX external datamodel.onnx.data/model.onnx_data支持也随之移除因为.ort是自包含单文件。2. 没有 NNAPI 执行提供程序Android 库在默认构建中不包含 NNAPI execution provider。这不是疏漏而是一个被量化过的工程决策——详见 docs/execution-providers.mdNNAPI 是编译型 provider它把图中自己能识别的节点成组摘出、编译成自己的图其余留给 CPU每个编译组与 CPU 之间的边界都要付出同步甚至跨内存拷贝代价。因此决定它是否有用的关键指标不是支持多少节点而是图被切成了几块。Moonshine 的模型以全优化方式转换为.ort优化会把整段区域融合为com.microsoft域算子FusedConv、MultiHeadAttention、MatMulNBits、SkipLayerNormalization等这些是 CPU 内核任何编译型 provider 都不认识反而把其余节点切成碎片。实测数据由scripts/check-ep-partitioning.py复现Piperen_US-amy-low被切成220 个分区Piperen_US-saikat被切成141 个分区Kokoro 148 个分区没有一个模型能达到每分区 7 个节点的门槛。NNAPI 本身的成本是 0.55 MB约占 6.5 MB 库的 9%换来的却是上述碎片化执行——边界开销大于加速收益所以默认剔除。ort_providers选项仍接受CoreML与NNAPI但任何已发布库中都不包含它们请求会返回指向 docs/execution-providers.md 的错误而不是静默降速。三、每个 ABI 的实测体积收益文档给出了最小化构建替换 stock 1.23.2 mobile 库后的按 ABI 体积对比单位 MBABIStock mobileMinimalSavedarm64-v8a18.56.012.5armeabi-v7a13.33.79.6x86_6422.16.415.7一个设备只安装一个 ABI因此一台 arm64 手机实际节省的是12.5 MB。操作符裁剪约砍掉了 ORT 约三分之二的代码——这是从源码 scripts/build-ort-android.sh 头部注释中明确记载的数字。裁剪的核心机制是--include_ops_by_config构建被限制到 moonshine-required-operators.config 列出的算子。该文件由 scripts/generate-ort-op-config.py 自动生成文件头注明Generated by ... do not edit by hand覆盖了仓库内全部 TTS 音色、转写模型、VAD、拼写模型等ai.onnx各版本段与com.microsoft扩展域算子如FusedConv、MultiHeadAttention、MatMulNBits、RotaryEmbedding等。由于配置按模型清单生成每当模型变更时都需重新生成CI 中的check-ort-op-config测试负责强制这一点防止构建出的库缺失新模型所需算子而在运行时失败。四、构建脚本用法与参数详解构建入口为 scripts/build-ort-android.sh其用法签名如下scripts/build-ort-android.sh [force] [with-nnapi] [abi ...]参数作用force即使对应 ABI 的.so已存在也强制重建并重新 vendorwith-nnapi把 NNAPI 执行提供程序编回库中默认剔除见上文第二部分abiarm64-v8a、armeabi-v7a、x86_64中的若干项缺省时构建全部三个支持的受控环境变量环境变量默认值说明ANDROID_SDK_ROOT/ANDROID_HOME~/Library/Android/sdkAndroid SDK 路径ANDROID_NDK_VERSION28.2.13676358构建所用 NDK 版本需与 language-bindings/android/build.gradle.kts 中minSdk 26匹配的应用保持一致ANDROID_API26目标 API 级别高于应用 minSdk 的 API 会导致库引用旧设备上不存在的符号ORT_ANDROID_CONFIGRelease构建配置可选MinSizeRelMOONSHINE_ORT_ROOT~/moonshine-ort或 wasm 构建遗留的~/moonshine-ort-wasmORT 源码检出与各平台构建树所在位置关于构建配置脚本注释特别提醒MinSizeRel能把 arm64 从 Release 的 6.0 MB 压到 5.3 MB省下约 0.7 MB占 arm64 安装量的 3%但它是靠-Os编译换来的速度折损而 TTS 是实时性预算最紧的场景模拟器计时又说明不了真机问题因此该配置保持 opt-in上真机测过再发布。脚本还内置了智能跳过如果请求的每个 ABI 都已在core/third-party/onnxruntime/lib/android/下存在则直接退出并提示加force重建。五、构建流程中的关键工程细节深入 scripts/build-ort-android.sh 源码可以看到几个不读源码就难以发现的工程细节ABI 目录名映射ORT 构建体系内部把arm64-v8a称为arm64因此 vendor 目录做了映射见脚本dest_dir_for_abi()arm64-v8a→lib/android/arm64/其余两个与 ABI 名一致。这就是为什么仓库里是arm64/而非arm64-v8a/。用 NDK 自带的llvm-strip剥离ORT 构建默认留下调试信息未 strip 的 arm64 库约675 MB其中约636 MB是.debug*段Gradle 打包时虽会丢弃但仓库会通过 Git LFS 永久背着它每个 clone 都受害。脚本用 NDK 工具链自带的llvm-strip --strip-unneeded完成剥离——只有它才理解自己工具链的输出。同时脚本按宿主系统选择HOST_TAGmacOS 为darwin-x86_64Linux 为linux-x86_64。KleidiAI 的交叉编译陷阱ORT 1.23 只要宿主机是 arm64如 Apple Silicon就会为所有目标启用 KleidiAI而不检查交叉编译目标导致armeabi-v7a与x86_64的源码被排除、代码路径却被启用链接时因未定义ArmKleidiAI::Mlas*符号而失败。脚本对非 arm64 目标显式传--no_kleidiai规避。强制重建时的陈旧缓存清理ORT 的build.py只会向 CMakeCache 中添加-D关闭某特性时不会移除旧的开关因此force重建必须从空构建目录开始脚本对已存在的构建目录执行清理否则上次遗留的ON会让关闭标志静默失效——这是陈旧状态真正的来源。六、跨平台版本锁ort-build-common.sh关联文档最后强调保持每个 ABI 使用同一个 ORT 版本并且与其它平台版本一致。这一约束由 scripts/ort-build-common.sh 落实它被三个构建脚本build-ort-android.sh、build-ort-wasm.sh、build-ort-ios.sh共同 source确保三者不会漂移统一版本ORT_VERSION默认1.23.2并须与 core/third-party/onnxruntime/find-ort-library-path.cmake 以及各平台未从源码构建的预编译库core/third-party/onnxruntime/lib/*/README.md保持一致。头文件在所有平台共享库版本不一致可能在会话创建时才以诡异方式失败。共享检出一个约 1 GB 的递归 ORT checkout 供所有平台复用MOONSHINE_ORT_ROOT因为算子裁剪写入构建目录而非源码树。共享最小化标志ort_minimal_flags()输出四组标志并附注释解释其必要性--minimal_build extended custom_ops丢弃 ONNX 解析器与不可用的图优化器extended保留运行时优化器NNAPI/CoreML 这类加载期编译内核的 provider 必需custom_ops保留自定义算子注册ZipVoice 需要--include_ops_by_config OP_CONFIG按算子配置文件裁剪--disable_ml_ops去掉无模型使用的经典 MLai.onnx.ml内核--compile_no_warning_as_error绕开 ORT 1.23 最小化构建中-Werror,-Wunused-const-variable的编译失败待上游修复后可移除。脚本还提供ort_require_op_config()守护算子配置文件缺失时直接报错并提示先运行scripts/generate-ort-op-config.py防止无配置构建出完整体积的库。七、提交前的验证与真实安装体积测量验证库确实被 strip替换任何.so之前用文档给出的两条命令确认file abi/libonnxruntime.so # expect stripped strings -a abi/libonnxruntime.so | grep -o VERS_1\.[0-9.]* | sort -u第一条确认符号已被剥离输出应含stripped第二条确认版本符号符合预期如VERS_1.23。因为 Git LFS 会乐意永久携带调试信息所以这一检查是提交前的硬性门槛。测量真实安装成本仓库磁盘上的.so大小并不能直接代表用户支付的成本Android 的.so是整体随 AAR 发布的但 AAR 里装着所有 ABI而设备只下载一个。因此文档强调要用 scripts/measure-mobile-size.sh 读取构建出的 AAR而非这些源码文件来测量scripts/build-android.sh local scripts/measure-mobile-size.sh android从 scripts/measure-mobile-size.sh 源码看measure_android()会自动在 Gradle 输出目录、发布目录与本地 Maven 缓存中选取最近修改的 AAR支持MOONSHINE_AAR覆盖用unzip -l逐 ABI 统计libonnxruntime.so与 AAR 内全部.so的总和并明确输出AAR total没人下载这个与各 ABI 的真实下载量。脚本注释还点明了另一个反直觉事实Gradle 会在打包时对原生库做 strip中间产物intermediates约 98 MB而实际发布约 18 MB因此必须从 AAR 测量。该脚本同样支持 iOS 侧measure_ios()通过真实链接最小二进制并报告__TEXT段大小ios/all参数可对照使用——这也呼应了关联文档与其它平台保持同版本、同思路的跨平台一致性原则。小结core/third-party/onnxruntime/lib/android/下的三个.so是 Moonshine 移动端体积与延迟预算的核心支柱。它由 scripts/build-ort-android.sh 从源码构建、按 moonshine-required-operators.config 裁剪算子、用 NDKllvm-strip剥离后 vendor 进仓库换来 arm64 上每设备 12.5 MB 的安装节省代价是只支持.ort模型且默认无 NNAPI。任何替换都必须遵守同版本、同配置、验证 strip、从 AAR 实测四条纪律。【免费下载链接】moonshineVery low latency speech to text, intent recognition, and text to speech, for building voice agents and interfaces项目地址: https://gitcode.com/GitHub_Trending/moonshine3/moonshine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
觉得有用,分享给同行:

为您的企业打造数字门面

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

立即咨询 →