直接回答
Android 构建成功只回答一个范围有限的问题:所选源码和构建配置生成了一个制品。它不能证明制品能装到每个目标设备、包含所有需要的原生库、能打开指定模型、能初始化后端,或能完成用户任务。要更快定位问题,应在更改设置前记录第一处失败。建立阶段清单,包括构建、包检查、安装、进程启动、原生库加载、模型加载、后端初始化、首次推理、输出验证和下一次请求恢复。只有证据支持时,才把故障归到最早阶段;不能把所有安装后崩溃都称为模型错误。首先保存准确的 Gradle 任务、变体、提交、依赖锁、解析后的运行时、构建输出和安装来源。比较实际构建的文件与实际安装的文件;release bundle、设备定向 split 和本地 debug APK 并不能互相代替。Android Studio APK Analyzer 可以查看最终 Manifest、DEX、资源与原生库条目,用它比较制品和预期构建,不要据此断言库一定能加载。若安装阶段失败,保留 Package Manager 结果和设备 ABI;若应用打开后抛出 UnsatisfiedLinkError,就检查所需库名、ABI 目录、原生依赖、加载顺序和异常详情。Android NDK 文档说明,“找不到库”也可能意味着文件存在,但因为依赖缺失而无法打开。请保留首个完整异常和 native log,不要盲目重试。如果原生运行时已打开但模型初始化失败,则记录制品来源、版本、格式、字节长度、路径、运行时修订及初始化阶段。不能仅凭扩展名、文件提供方标签、复制成功或文件长度推断内容完整。Cove 当前 Gemma E2B 配置没有经过验证的 SHA-256 值,因此网站不能把该模型的摘要写成已验证。如果模型能加载但用户任务失败,则保存固定输入样例、提示词修订、配置后端及可观察的实际后端证据、输出、验收规则与回退状态。配置后端的请求不代表请求的加速器实际执行。项目目前没有支持性能或广泛兼容结论的真实设备原始数据;诊断只能针对被记录的组合,不发布速度、最低 RAM 或设备支持结论。进程与生命周期故障也要单独复现:取消任务、离开并返回页面、重建 Activity、在运行时要求时关闭会话,再运行第二次请求。首次成功输出不能证明资源清理或恢复正常。不要同时改 ABI filter、混淆设置、模型文件、后端与生命周期;否则即使转绿也不知道根因。每次只改一项可逆设置,使用同一样例复测,同时保留失败和成功记录。公开日志中不放私人提示词或转写内容;分享支持信息时只提供经过检查的诊断项。实际顺序是:在准确安装制品上复现;保存构建和环境身份;识别最早失败阶段;选择匹配该阶段的工具;一次只改一个有证据的假设;重跑同一任务和恢复流程;说明仍未测试的内容。好的报告会写“APK 已构建、安装成功、在所记录 ABI 上原生加载失败”,而不是“Android 不支持”。把已知事实与待验证猜测分开,并让下一步可以被证伪。这套流程用于定位边界,不证明所有设备、文件、运行时版本或 Android 版本均受支持。
Release 构建成功,但安装后的模型始终未就绪
开发者在一台设备安装 release APK,此前 emulator 上 debug 构建能运行。应用可以启动,但随后显示笼统的模型错误。团队以前一起改过 ABI filter 和后端设置,因此无法判断是包漏了原生库、加载器拒绝依赖、模型路径错误还是初始化失败。
决策
固定已安装 APK、设备和运行时身份,复现一次并捕获第一个失败点,再决定是否改动构建、库或模型设置。
预期结果
下一步对应可验证的故障边界;不能从编译成功或单台设备运行推导普遍兼容、性能或模型支持结论。
需要收集的证据
只有将以下证据与同一模型文件和测试运行关联起来,结论才可复核:
- 已安装制品与构建信息
- 设备 ABI、运行时和第一条错误
- 失败、回退与恢复的同配置记录
发布结论只对所记录的配置和验收集有效;扩大适用范围需要更多记录。
实施流程
- 固定测试制品. 记录提交号、Gradle 变体和任务、解析后的运行时、文件修订与格式、APK 或 bundle 身份、安装来源、Android 构建、设备 ABI,以及这是 debug 还是 release。
- 命名最早失败阶段. 利用 Package Manager 输出、启动结果、首个异常、原生加载日志、模型初始化、后端证据和样例结果,判断执行链最先在哪里中断。
- 检查实际安装的包. 用 APK Analyzer 查看最终 Manifest 和原生库路径,对照 release 与 debug 产物,并确认已安装包就是刚检查的那一个;存在文件不等于文件能被加载。
- 一次验证一个假设. 选与阶段相符的官方文档,每次只改变一个变量,例如打包 ABI、库依赖、运行时修订、模型路径或初始化所有者,并保存原始失败情况。
- 复测任务、清理和恢复. 用同一条非敏感样例再次运行,记录输出和验收,按生命周期约定取消或关闭,然后再次提交任务,确认进程回到已知状态。
让每个阶段的状态都可观察。失败信息应指出阶段、模型、运行时和恢复动作,同时避免记录用户私密内容。
验收标准
- 诊断记录指出构建、已安装制品、设备/系统、ABI、运行时以及最早失败阶段。
- 每项实验只改变一个有说明的因素,并保留修改前后的制品身份和完整错误。
- 运行时或模型结论只覆盖记录的样例和配置;编译或包检查本身不被称为设备兼容证明。
- 公开诊断日志不包含私人提示词、转写、凭证或用户内容。
决策对照表
| 维度 | 选择或证据 | 解读方式 |
|---|---|---|
| Gradle 编译或打包失败 | 构建系统或源码诊断 | 还没有测试安装后的运行行为。 |
| 安装失败或启动即退出 | 包、Manifest、平台或进程启动诊断 | 模型可能还没有打开;保留包管理与首个进程证据。 |
| 原生加载或引擎初始化失败 | ABI、依赖、加载顺序、运行时或制品诊断 | 泛化模型错误不够用,应归类第一条加载或初始化结果。 |
| 模型运行但任务错误或不完整 | 样例、提示词、输出规则、任务或回退诊断 | 这与编译问题不同,也不能推出通用模型质量结论。 |
需要避免的失败模式
- 同时改 ABI、模型与后端
- 只看构建成功或 APK 内文件列表
- 公开提示词或转写作为日志
还要避免静默回退、版本未固定、缺少取消处理,以及把不同配置的结果混在一起下结论。失败运行也应与成功记录一并保存。
最小复现记录
| 层级 | 记录内容 |
|---|---|
| 设备 | 厂商、型号、芯片、内存档位、操作系统版本 |
| 软件 | 应用版本和 Git 提交号 |
| 模型 | 系列、变体、版本、格式、文件长度、摘要、量化方式 |
| 运行时 | 名称、版本、请求后端及实际后端证据 |
| 工作负载 | 样例版本、输入摘要、提示词摘要、输出策略 |
| 结果 | 完成、失败、取消、回退及保护隐私的诊断信息 |
发布检查表
- ☐ 主要搜索问题已回答,且没有未经支持的数字。
- ☐ 所有模型文件和运行时版本均已固定。
- ☐ 代表性任务和失败处理策略均有说明。
- ☐ 生命周期、取消、清理和回退均已测试。
- ☐ 用户内容与网络边界均有说明。
- ☐ 结论只适用于被记录的配置。
- ☐ 新增测试结果时链接到原始方法或证据。
来源与相关证据
- Cove 基准测试方法
- Android Developers — 使用 APK Analyzer 检查构建
- Android NDK — ABI 管理
- Android NDK — JNI tips 与 UnsatisfiedLinkError
- Android Developers — 诊断应用崩溃
- Google AI Edge LiteRT-LM Kotlin 入门
中文部署与排错专题见。奇连 AI 端侧专题。
常见问题
APK 构建成功能证明模型受支持吗?
不能。它只证明所选构建配置生成了包。安装、ABI 原生加载、制品解析、运行时初始化和代表任务都必须单独检查。
UnsatisfiedLinkError 一定是库文件不存在吗?
不一定。Android NDK 文档指出,库文件可能存在但由于某个原生依赖不可用而无法打开。请保留异常详情,并检查 ABI 打包和依赖库。
调试时是否应该马上在 CPU、GPU、NPU 之间切换?
不应该先这样做。先固定执行路径,直到确认失败阶段;后端请求不是实际执行的证据,同时更改多个变量会掩盖原因。
一次设备运行能支持兼容性声明吗?
最多支持对那次构建、制品、运行时、设备、系统、后端证据和任务的窄范围描述。普遍支持需更广泛验证的矩阵,本文没有推导此类结论。