ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

LiteRT-LM Android Demo 应用推理合规审计清单:从 EngineConfig 到多模态降级的全项核查实战

2026/9/17 14:36:39 拓冰建站 浏览量
LiteRT-LM Android Demo 应用推理合规审计清单:从 EngineConfig 到多模态降级的全项核查实战 LiteRT-LM Android Demo 应用推理合规审计清单从 EngineConfig 到多模态降级的全项核查实战【免费下载链接】LiteRT-LMLiteRT-LM is Googles production-ready, high-performance, open-source inference framework for deploying Large Language Models on edge devices.项目地址: https://gitcode.com/GitHub_Trending/li/LiteRT-LM导读本文围绕 LiteRT-LM 仓库中面向 Android Demo 应用开发的推理合规清单compliance_checklist_inference.md展开系统讲解在 Bazel 9 Bzlmod 环境下交付一个 LiteRT-LM Android 推理 Demo 前必须逐项通过的 Setup Build、Inference API Optimization、Multi-modal API 三大类核查项。读完本文你将掌握 GPU OpenCL 权限配置、APK 内 .so 验证、Kotlin 数据类配置语法、显式初始化、Conversation 路由、GPU 投机解码MTP以及三级级联降级的完整实现与审计证据规范并能直接对照仓库 Kotlin 源码Config.kt、Engine.kt、Conversation.kt验证每一项。一、合规审计的定位与执行机制该清单是create-litert-lm-android-demo-app技能SKILL.md第 5 步Full Implementation with LiteRT-LM Integration的强制产物实现推理逻辑后需把本清单复制为compliance_review_inference.md初始化所有状态为Pending逐项审计并回填Status与Evidence。它要求开发者在声明任务完成之前必须对照本文件执行一次全面合规审计并使用本表报告合规结果任何检查项失败都必须修复代码并完整重跑审计。1.1 审计状态重置约束只要审计开始后代码库发生任何变更合规报告中的所有状态必须全部重置为Pending或留空以保证所有条目都被干净地重新验证。这避免了改了一行代码但只复验局部的漏网之鱼。1.2 证据质量约束所有处于激活状态的检查项Evidence列必须包含具体的代码引用文件名 行号或精确的命令输出。模糊的、描述性的概括例如 verified、supported、manual scroll不被接受作为证据。这一约束与 SKILL.md 中每项Pass必须直接给出工作区文件的 Markdown 链接和精确起止行号或打印精确的终端日志块的硬性门禁一脉相承。1.3 报告表格模板RequirementStatusEvidenceSetup BuildGPU OpenCL Permissions (AndroidManifest.xml)APK Verification (zipinfo)Inference API OptimizationData Classes vs Builders UsedExplicitinitialize()CalledConversation Class Used (not Session)MTP Enabled for GPUMulti-modal APIInitialize Fallback Try-Catch BlockMulti-modal Executors (CPU Audio)Content Order (Text before Media)Real Inference Used其中Status取值固定为Pass / Fail / SkippedEvidence取值为命令输出或代码片段。二、Setup BuildGPU 权限与 APK 产物核查2.1 GPU OpenCL 权限AndroidManifest.xml针对 Adreno GPU 在 Android 上可能出现的崩溃问题清单要求必须确认AndroidManifest.xml的application标签内存在如下声明uses-native-library android:namelibOpenCL.so android:requiredfalse /关键点有两个一是libOpenCL.so的库名必须精确二是android:requiredfalse——它声明该原生库不是应用运行的必需依赖设备缺少 OpenCL 时仍可安装运行从而允许应用在运行时通过级联降级见第四节回退到 CPU 后端。这与仓库中 GPU 加速相关预编译产物如 prebuilt/android_arm64/libLiteRtOpenClAccelerator.so的存在相互印证GPU 路径由 OpenCL accelerator 驱动而权限声明保证了缺失时应用的优雅降级。2.2 APK 产物验证zipinfo编译完成后清单强制要求执行zipinfo bazel-bin/app_name.apk lib/*目的是验证编译进 APK 的.so原生库被正确放置在lib/abi/目录下Bazel Android 二进制默认按lib/arm64-v8a/、lib/x86_64/等 ABI 目录组织。这是对 Bazel 输出产物的静态核查能在无真机/模拟器的无头环境下确认依赖链路LiteRT-LM 共享库、OpenCL accelerator、TopK sampler 等确实被打包而不仅是编译成功。对应场景中 Bazel 平台标志固定为--android_platformsrules_android//:arm64-v8a见 compliance_checklist_ui.md因此zipinfo输出中应能看到lib/arm64-v8a/下的目标库。三、Inference API Optimization配置语法、初始化与路由核查3.1 Data Classes vs Builders必须使用命名参数直接构造清单要求核验EngineConfig、SessionConfig、ConversationConfig、SamplerConfig这四类配置使用带命名参数的直接构造器禁止使用.builder()构建器模式。这一点在仓库源码中有直接依据Config.kt 中EngineConfig是 data class其参数包括modelPath模型文件路径、backend默认Backend.CPU()、visionBackend/audioBackend默认null为 null 时对应执行器不会被初始化、maxNumTokens、maxNumImages、cacheDir且init块强制maxNumTokens、maxNumImages为正数或 nullConversationConfig含systemInstruction、initialMessages、tools、samplerConfig、automaticToolCalling、channels、loraConfig、prefillPrefaceOnInit、maxOutputToken、thinkingConfig、enableResponseFormat、enableSpeculativeDecoding、chatTemplate等同样全部通过构造器参数传入SamplerConfig要求topK 0、0 topP 1、temperature 0否则require直接抛异常。此外Backend.CPU与Backend.GPU都是 class/data class必须显式实例化Backend.CPU()、Backend.GPU()而不能传类型引用。典型用法val config EngineConfig( modelPath path, backend Backend.GPU(), // 或 Backend.CPU(threadCount 4) visionBackend Backend.GPU(), // 视觉执行器后端 audioBackend Backend.CPU(), // 音频执行器严格锁定 CPU cacheDir cachePath, )从源码看EngineConfig的这些字段最终在 Engine.kt 的initialize()中被逐一映射为 JNI 调用LiteRtLmJni.nativeCreateEngine的参数visionBackend?.name ?: 、audioBackend?.name ?: 、maxNumTokens ?: -1、cacheDir ?: 等null 被转换为空串或 -1 以避免 JNI 层传递可空对象——这就是null 表示不初始化对应执行器的底层机制。3.2 显式 initialize()必须先初始化再创建会话清单要求核验在创建任何 conversation 或 session 之前必须显式调用engine.initialize()。仓库源码对此有强约束Engine.kt 中initialize()通过check(!isInitialized())防止重复初始化成功后设置原生句柄handlecreateConversation()与createSession()内部都先调用checkInitialized()check(isInitialized()) { Engine is not initialized. }未初始化直接抛IllegalStateExceptioninitialize()的 KDoc 明确提示该操作可能耗时约 10 秒取决于模型与设备强烈建议在后台线程调用与 SKILL.md 中所有原生引擎创建/初始化与文件拷贝操作必须放在后台线程如withContext(Dispatchers.IO)的规则一致。正确顺序示例val engine Engine(engineConfig) engine.initialize() // 显式初始化耗时操作放后台线程 val conversation engine.createConversation(conversationConfig) // ... 推理 engine.close() // 释放原生资源3.3 Conversation 路由sendMessageAsync 挂在 Conversation 上而非 Session清单要求核验sendMessageAsync必须调用在通过engine.createConversation()创建的Conversation实例上。这是因为高层消息 API 位于Conversation类而非Session类Engine.kt 的createConversation()会组装 system instruction、初始消息、通道channels等 JSON调用LiteRtLmJni.nativeCreateConversation并返回Conversation对象Conversation.kt 提供三组sendMessage/sendMessageAsync重载String、Contents、Message其中sendMessageAsync支持回调MessageCallbackonMessage/onDone/onError与 KotlinFlow两种消费方式流式返回模型分块响应相比之下SessionEngine.kt只承载samplerConfig、loraConfig、enableSpeculativeDecoding等底层配置不提供sendMessageAsync高层接口。val conversation engine.createConversation() conversation.sendMessageAsync( contents, object : MessageCallback { override fun onMessage(message: Message) { /* 流式分块 */ } override fun onDone() { /* 完成 */ } override fun onError(error: Throwable) { /* 处理错误 */ } }, )清单中Conversation Class Used (not Session)一项正是用来防止误把sendMessageAsync路由到Session的常见实现错误。3.4 MTP Enabled for GPU投机解码配置核查清单要求核验 MTP Enabled for GPU。MTPMulti-Token Prediction即投机解码的 draft 模型机制在 Kotlin API 中通过投机解码配置体现ExperimentalFlags.kt 中的enableSpeculativeDecoding: Boolean? null——null使用模型默认值true显式启用模型不支持则抛错false显式禁用该标志仅在创建新Engine时读取Config.kt 的ConversationConfig.enableSpeculativeDecoding与SessionConfig.enableSpeculativeDecoding文档明确写道若为true且引擎初始化时未开启投机解码则会在首次使用时惰性初始化投机解码 drafter例如 MTP清单对应的审计目标是GPU 后端推理路径中投机解码/MTP 应当处于启用状态ExperimentalFlags.enableSpeculativeDecoding true或在引擎/会话配置中开启以充分利用 GPU 并行算力换取解码加速。四、Multi-modal API三级级联降级与多模态输入核查4.1 三级级联降级 Try-Catch 块清单要求核验引擎初始化代码实现三级级联降级的 try-catch 块这也是推理实现指南inference_implementation.md中级联降级策略的核心部分Try Multi-modal on Selected Backend按用户所选通用后端如 GPU配置并初始化多模态引擎其中audioBackend锁定 CPU、visionBackend与通用后端一致随后调用engine.initialize()Fallback to Multi-modal on CPU若第 1 步抛异常捕获并记录警告改用纯 CPU 多模态配置backend Backend.CPU()、visionBackend Backend.CPU()、audioBackend Backend.CPU()重新初始化并以编程方式将 UI 的 Backend Selector 切换为 CPU保证 UI 与真实执行后端一致Fallback to Text-only Engine (CPU-locked)若第 2 步仍抛异常捕获并记录关键告警改为完全省略visionBackend与audioBackend的纯文本 CPU 配置EngineConfig只含modelPath与backend Backend.CPU()再次初始化并确保 UI Backend Selector 显示/保持为 CPU若该步也失败则将错误冒泡到 UI 层。该策略与 Config.kt 的语义完全对应visionBackend/audioBackend为null时对应执行器不初始化因此文本-only 引擎在源码层面就是省略这两个字段。第 3 步虽然模型可能是文本-only但 SKILL.md 明确要求不得在编译期删除多模态代码路径所有多模态 UI 与 API 集成必须编译通过文本降级只能在运行时通过上述级联 try-catch 动态发生。4.2 初始化结果与 UI 状态机的映射初始化结束后必须把引擎状态直接映射到 UI 加载态见 ui_layout_and_state.md若第 1 或第 2 步成功UI 进入Multi-modal Model状态图片、音频、文本输入与 Send 全部启用若仅第 3 步成功UI 进入Text-only Model状态只启用文本输入与 SendImage 与 Audio 按钮严格置灰。这一映射与 compliance_checklist_ui.md 中的 Text-only Fallback Buttons Disabling 检查项互为表里多模态按钮始终在布局中完整声明、绝不动态隐藏仅通过代码设置 disabled。4.3 多模态执行器visionBackend 与 CPU 锁定的 audioBackend清单要求核验EngineConfig中显式初始化visionBackend与audioBackend且audioBackend严格设置为Backend.CPU()。原因从 Engine.kt 的initialize()可见端倪音频执行器相关线程数audioBackendNumThreads在 JNI 层独立传递音频管线对实时性/兼容性要求更高CPU 锁定可规避 GPU 音频路径在边缘设备上的不稳定因素同时只有显式传入非 null时nativeCreateEngine才会真正初始化对应执行器。4.4 多模态输入组装Content 对象、显式传参与顺序清单对多模态输入的核查分三层Content 包装选中的媒体数据必须包装为Content对象并传入推理调用。仓库 Message.kt 定义了 sealed classContent的多种形态Content.Text、Content.ImageBytes原始字节 Base64 编码为blob、Content.ImageFile绝对路径、Content.AudioBytes、Content.AudioFile、Content.ToolResponse全部支持经Contents列表组装显式传参检查核验sendMessageAsync或等价方法确实传入了构造好的Content对象列表文本 媒体而不是只传单个文本字符串——即调用sendMessageAsync(contents, callback)而非sendMessageAsync(文本, callback)Content 顺序检查确保Content.Text先于任何媒体内容如Content.ImageFile/Content.AudioFile加入 contents 列表以匹配模型对 prompt 结构的预期val contents Contents.of( listOf( Content.Text(prompt), // 文本必须在前 Content.ImageFile(imagePath), // 媒体在后 Content.AudioFile(audioPath), ), ) conversation.sendMessageAsync(contents, callback)4.5 真实推理禁止 Mock 响应清单最后要求核验应用使用 LiteRT-LM 引擎执行真实推理不得使用 mock 响应。这与 SKILL.md 的 No Mock Inference 约束一致应用必须以干净、未初始化的状态启动模型选择器不使用硬编码路径响应必须来自 Conversation.kt 中nativeSendMessageAsync等 JNI 调用返回的真实模型输出。在无头环境下无设备/模拟器审计结果可标记为Pass (Static/Build Only)但实现层面必须走真实引擎链路。五、审计执行顺序与最终门禁结合 SKILL.md 的完整流程该推理合规清单在交付链路中的位置如下第 5.2 步复制本清单为compliance_review_inference.md所有状态初始化为Pending第 5.3 步立即集成 LiteRT-LM 推理读取 inference_implementation.md 后严格按其规则实现第 5.4 步就地审计并回填详细结果与证据引用带行号的文件链接第 6.1 步依次重载三份合规报告UI、Dependency、Inference完整复验防止后续改动破坏先前 Pass 项第 6.2 步门禁校验——任何报告不得残留Pending或Fail项所有适用的块必须以Pass签署、复选框勾选[x]且每项Pass都必须携带精确到行号的代码引用或终端日志否则视为合规失败。六、源码与文档导航本文涉及的核查项均可在以下仓库路径中交叉验证推理合规清单compliance_checklist_inference.md推理实现规则inference_implementation.md技能编排与门禁SKILL.md配置数据类与 Backendkotlin/java/com/google/ai/edge/litertlm/Config.kt引擎生命周期与初始化kotlin/java/com/google/ai/edge/litertlm/Engine.kt会话与流式推理 APIkotlin/java/com/google/ai/edge/litertlm/Conversation.kt消息与多模态 Content 模型kotlin/java/com/google/ai/edge/litertlm/Message.kt投机解码MTP实验开关kotlin/java/com/google/ai/edge/litertlm/ExperimentalFlags.ktUI 状态与降级按钮核查compliance_checklist_ui.md【免费下载链接】LiteRT-LMLiteRT-LM is Googles production-ready, high-performance, open-source inference framework for deploying Large Language Models on edge devices.项目地址: https://gitcode.com/GitHub_Trending/li/LiteRT-LM创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考