先看结论与判断条件
- 个人化适配器既是模型执行输入,也是与账号和训练材料相关的受控资产,文件完整性不能代替用户授权。
- 适配器身份应同时包含 adapter 摘要、基础模型摘要、运行时族、匿名用户作用域、生成批次和数据许可版本。
- 基础模型兼容只回答适配器能否按预期装载,用户权益回答谁在什么目的和期限内可以使用,两类门禁必须分开。
- 移动端隐私声明需要覆盖应用与第三方 SDK 的实际数据行为,但声明文件本身不会执行账号隔离、删除或撤销。
- 平台证明可以作为服务端风险信号并绑定请求,不能在客户端单独充当用户身份、许可或绝对设备可信结论。
- 账号切换、退出登录、许可撤销和数据删除都要驱动适配器停用与清理,并保留不含个人内容的审计回执。
个人化适配器不是普通模型附件
通用 LoRA 适配器可以面向一个产品版本或任务分发,个人化适配器则可能由某个用户的选择、内容或行为材料生成。两者即使采用相同文件格式,责任也不同。个人化文件一旦被复制到其他账号、与错误基础模型组合,或者在许可撤销后继续加载,问题不再只是推理兼容,而是资产归属、数据用途和访问控制同时失效。
文件摘要只能回答当前字节是否与登记对象一致,不能回答谁有权使用。基础模型摘要可以排除一部分混搭,却不能证明当前账号仍持有权益。设备本地目录名更不能充当身份,因为目录可以残留、备份恢复或在账号切换时被错误复用。工程上应把适配器视为服务端授权的本地缓存,激活权来自当前会话和许可状态,而不是来自文件已经存在。
发布门禁需要在三个层次分别给出结论。技术层检查适配器、基础模型和运行时是否形成受支持组合;身份层检查适配器是否属于当前匿名用户作用域;许可层检查生成材料的授权版本、使用目的、期限和撤销状态。任一层缺失,候选都只能保持未授权或待确认,不能用另两层的通过结果补齐。
| 门禁 | 核心问题 | 所需证据 | 不能替代 |
|---|---|---|---|
| 技术兼容 | 能否与基础模型执行 | 模型摘要、格式与运行时 | 用户拥有权益 |
| 用户作用域 | 是否属于当前账号 | 服务端主体与本地匿名标识 | 数据许可有效 |
| 数据许可 | 材料能否用于当前目的 | 许可版本、目的与撤销状态 | 文件字节完整 |
| 设备风险 | 请求环境是否满足策略 | 服务端验证的平台信号 | 绝对设备可信 |
| 生命周期 | 何时停用和清理 | 登录、退出、删除和过期事件 | 历史授权永久有效 |
用一组不可拆分的身份字段描述适配器
适配器 manifest 至少应登记 adapterId、adapterDigest、baseModelId、baseModelDigest、runtimeFamily、format、匿名 userScope、generationId、licenseId、licenseVersion、purpose、issuedAt、expiresAt 和 revokedAt。字段不是为了让清单显得完整,而是分别回答字节、兼容对象、运行环境、账号归属、生成来源和授权窗口。清单需要签名或由受信服务返回,客户端自行拼出的 JSON 不能成为权威授权证据。
userScope 应使用服务端生成的稳定匿名作用域,而不是电子邮件、手机号、昵称或其他可识别信息。它可以由租户、账号和服务域共同决定,但不应允许客户端从公开字段自行推导。应用比较本地缓存时只处理作用域标识,服务端才维护其与真实账号的关系。日志可以记录作用域摘要和决策状态,不记录训练内容、完整输入或用户可识别字段。
适配器清单还要绑定生成来源。generationId 可以关联受控训练或个性化任务的内部回执,公开侧只保留任务状态、材料许可版本和产物摘要,不公开原始材料。若同一用户重新授权、重新生成或修改用途,即使 adapter 字节偶然相同,也应形成新的授权记录。字节身份与业务授权身份需要相互引用,但不能被压缩成一个含义模糊的版本号。
| 字段组 | 示例字段 | 回答的问题 | 失败处置 |
|---|---|---|---|
| 产物身份 | adapterId、adapterDigest | 当前文件是哪一件产物 | 摘要不符拒绝 |
| 基础模型 | baseModelId、baseModelDigest | 与哪份模型组合 | 不匹配不装载 |
| 用户作用域 | userScope | 属于哪个匿名账号范围 | 作用域不同停用 |
| 许可状态 | licenseVersion、purpose、expiresAt | 当前用途是否仍获授权 | 过期或撤销拒绝 |
| 生成来源 | generationId、issuedAt | 由哪次受控任务产生 | 来源缺失待确认 |
基础模型兼容与用户授权必须分开判断
Google AI Edge LLM Inference for Android 展示了把基础模型路径和独立 LoRA 路径同时交给运行时的方式,并明确适配器路径受支持模型与 GPU 后端约束。这说明 adapter 不是可脱离基础模型任意使用的文件。该接口已处于 maintenance-only,页面描述只能用于理解这一路实现,不能外推为所有移动 LoRA 运行时的统一兼容标准。
Google AI Edge LLM Inference overview 把基础模型、可选定制权重和运行配置作为相互依赖的执行输入。工程上应先检查 baseModelDigest、模型家族、适配器 rank 或相关格式要求和运行策略,再决定是否进入初始化。即使组合技术上可装载,仍要独立检查当前用户和用途;兼容通过只证明候选组合满足执行前提,不授予任何账号使用权。
LiteRT-LM Android 要求应用显式选择并初始化受支持的模型包与运行时配置。迁移到新的运行时族时,旧适配器不能因为扩展名相同就自动继承兼容或授权结论。发布记录应把 runtimeFamily 纳入组合身份,并为迁移后的候选重新生成技术回执。用户许可可以继续有效,也可能因用途或服务变化需要更新,二者由业务规则决定,不能由运行时迁移文档替代。
| 检查项 | 技术兼容结论 | 授权结论 | 组合规则 |
|---|---|---|---|
| 基础模型摘要 | 确认目标模型一致 | 不说明用户权利 | 必须匹配 manifest |
| 运行时族 | 确认集成路径受支持 | 不说明数据用途 | 迁移后重新验证 |
| 用户作用域 | 不影响格式解析 | 确认账号归属 | 服务端签发 |
| 许可版本 | 不改变模型字节 | 确认用途与期限 | 激活时复核 |
| 撤销状态 | 文件仍可能可装载 | 决定立即停用 | 授权优先于缓存 |
数据许可要绑定来源、目的和生命周期
个性化材料的合法使用不能只记录一次同意按钮。许可记录至少需要说明材料类别、生成目的、适用产品、许可版本、开始时间、到期或撤销条件,以及是否允许继续保存已经生成的 adapter。不同业务可能对撤销后的产物采取立即删除、停止激活后限期清理或保留不可用审计摘要等策略。文章不能替具体法律与业务判断给出统一答案,但技术系统必须能够执行经过批准的规则。
Declare Android app data use 要求 Data safety 声明覆盖应用和第三方 SDK 实际收集与共享的数据。若个性化过程上传内容、特征或诊断数据,商店声明需要与真实行为一致。不过商店声明是面向用户与审核的说明,不会自动限制本地缓存、阻止跨账号读取或执行删除。工程团队仍需实现数据分类、访问控制、保留周期和删除回执。
Apple privacy manifests 要求 App 与第三方 SDK 的数据收集和 required reason API 进入有效 privacy manifest。它同样属于声明与审核材料,不是运行时隔离机制。若 adapter 生成或加载引入新的 SDK、文件访问或数据路径,应更新相关清单并复核真实行为。Android 与 Apple 平台声明可以帮助识别责任范围,但用户作用域和许可决策仍应由业务服务与客户端门禁共同执行。
| 许可字段 | 工程含义 | 触发动作 | 保留边界 |
|---|---|---|---|
| 材料类别 | 识别输入数据责任 | 选择存储和传输策略 | 不记录原始内容到普通日志 |
| 使用目的 | 限制 adapter 的业务场景 | 每次激活比对 purpose | 目的变化需重新授权 |
| 许可版本 | 绑定当时的条款与选择 | 服务端复核版本 | 版本号不代替同意证据 |
| 到期与撤销 | 定义何时失去权益 | 停用并进入清理队列 | 只保留必要审计摘要 |
| 删除策略 | 决定文件和索引处理 | 生成可核对回执 | 声明文件不执行删除 |
服务端权益复核是激活适配器的最终入口
客户端可以检查摘要、基础模型和本地账号作用域,但不能单独作出最终授权。移动应用属于用户可控制环境,本地时间、缓存状态和决策代码都可能失去可信性。激活前应向服务端提交当前会话、adapterId、adapterDigest、baseModelDigest、purpose、许可版本和一次性挑战,服务端核对账号归属、撤销、期限与产品权益,再返回短期且用途受限的决策。
Apple App Attest server validation 说明平台证明需要在服务端验证并绑定请求,而不是只在客户端判断。适配器场景可以把证明作为额外风险信号,并将挑战与本次激活请求关联。平台证明不是用户身份,也不是许可本身,更不是绝对设备可信结论。服务端仍需先完成会话认证、资源所有权和业务授权,再根据风险策略决定是否接受、降级或要求重新验证。
离线场景需要预先定义。若产品允许短时离线使用,可以缓存带签发时间、过期时间、adapter 和基础模型摘要、userScope 与 purpose 的最小权益票据,并在恢复联网后复核。离线窗口、设备时间可信度和撤销传播属于项目策略,需要真实风险评审。无法取得有效权益时,应用应保持通用模型路径或清晰提示,而不是因为本地文件存在就自动激活个人化适配器。
| 校验顺序 | 输入 | 通过条件 | 失败行为 |
|---|---|---|---|
| 会话身份 | 当前登录会话 | 主体有效 | 要求重新登录 |
| 资源所有权 | adapterId 与 userScope | 属于当前主体 | 拒绝跨账号使用 |
| 组合身份 | adapter 与基础模型摘要 | 登记组合一致 | 拒绝激活 |
| 许可状态 | 版本、目的、期限与撤销 | 当前仍有效 | 停用并清理 |
| 风险信号 | 绑定请求的平台证明 | 符合业务策略 | 降级或复核 |
账号切换和退出登录必须驱动停用与清理
账号切换时,应用应先冻结当前个人化会话,等待正在执行的推理结束或安全取消,再清除内存中的 adapter 句柄和用户相关缓存,最后加载新账号的授权状态。不能先修改界面账号再异步清理旧文件,因为短暂窗口内新账号可能继续使用旧作用域。清理顺序需要在状态机中明确,并通过并发测试覆盖前台切换、进程恢复和网络延迟。
退出登录不一定意味着立即删除所有文件,但必须立即失去激活权。具体是否删除 adapter,取决于许可与离线策略;无论采用哪种规则,本地索引都应从活动集合移除,内存会话应关闭,后续调用应返回需要授权的状态。若文件暂存用于快速重新登录,应加密存储并按匿名作用域隔离,同时设置过期和服务端复核,不能靠不可读文件名制造安全感。
用户删除个性化数据时,需要形成从服务端任务、分发对象到设备缓存的清理链。设备离线可能让删除延迟,因此服务端应先撤销权益,使旧文件即使存在也无法重新激活;客户端联网后再执行本地清理并提交不含个人内容的回执。删除失败要可重试且不恢复授权。工程上应分别记录已撤销、待设备清理和已清理,避免一个完成标志掩盖不同状态。
- 账号变化前冻结个人化推理入口
- 等待或安全取消当前 adapter 会话
- 清除内存句柄并移除活动索引
- 服务端撤销优先于设备文件清理
- 删除失败可重试且不恢复授权
- 回执只保存作用域摘要与状态
验收要覆盖错配、撤销和恢复,而不只验证成功装载
正常用例应绑定当前用户、正确 adapter、正确基础模型、受支持运行时、有效许可和允许 purpose,并验证服务端决策与本地激活记录一致。测试材料使用专门的公开安全或脱敏账号,不应把真实个人内容带入通用日志。每条回执至少保存候选身份、适配器和模型摘要、匿名作用域摘要、许可版本、决策状态与时间。
拒绝用例更能证明门禁有效。应覆盖其他用户的 adapter、错误基础模型摘要、未知运行时族、过期许可、已撤销许可、目的不匹配、离线票据超期、服务端挑战不匹配和账号切换中的并发调用。正确结果不是应用一定崩溃,而是在进入个人化推理前得到明确、可审计且不会泄露资源存在性的失败。
恢复用例覆盖进程退出、应用升级、设备离线后重连、缓存文件残留和删除任务重试。历史回执不能自动证明新候选仍保持相同状态机。没有当前应用、adapter、基础模型和服务端决策的组合证据时,只能记录测试方案未执行。本文不提供任何客户案例、兼容率、性能数字或御盾项目通过结论。
| 用例 | 预置状态 | 期望决策 | 关键回执 |
|---|---|---|---|
| 正确组合 | 当前用户与有效许可 | 允许激活 | 组合摘要与服务端决策 |
| 跨账号文件 | adapter 属于其他作用域 | 拒绝且不泄露详情 | 所有权失败类别 |
| 基础模型错配 | 摘要或模型家族不同 | 技术门禁拒绝 | 组合身份不一致 |
| 许可撤销 | 文件仍在设备 | 立即停用 | 撤销与清理状态 |
| 进程恢复 | 缓存和会话状态重建 | 重新复核后决定 | 候选与恢复路径 |
用只读校验器阻止错误作用域和过期许可进入激活流程
下面的 Python 示例读取适配器 manifest 与本次激活上下文,检查匿名用户作用域、adapter 和基础模型摘要、运行时族、许可标识与版本、purpose、到期时间和撤销状态。脚本只读文件,不接触训练内容,也不输出完整作用域;任何字段缺失、摘要格式错误、作用域错配、目的不符、许可过期或被撤销都会返回非零状态。通过结果只表示两份输入在静态规则下相符。
生产系统不应让客户端自签 manifest,也不能把该脚本当作服务端授权替代品。权威清单和激活上下文需要由受信服务生成,并绑定当前会话与请求;客户端静态校验用于尽早发现缓存错配和明显无效状态。服务端仍需独立核对资源所有权、许可、撤销、风险信号和重放,并把短期决策返回当前请求。
申请个人化模型的商业加固评估时,应准备应用候选、adapter 与基础模型摘要、运行时和格式说明、匿名用户作用域设计、数据许可版本、服务端激活协议、退出登录与删除状态机及拒绝用例回执,再通过御盾中央平台提交申请。真实证据齐备前,不宣称资产不可提取、跨账号攻击被阻断或任何设备矩阵已经通过。
- 输入清单来自受信服务而非客户端自签
- adapter 与基础模型摘要同时匹配
- 匿名 userScope 与当前会话一致
- 许可版本、purpose 和期限逐项复核
- 撤销状态优先于本地缓存存在
- 静态通过后仍进入服务端最终授权
from pathlib import Path
from datetime import datetime, timezone
import hashlib
import json
import sys
ALLOWED_RUNTIMES = {"mediapipe-llm", "litert-lm"}
def load_json(path_text):
path = Path(path_text)
if not path.is_file():
raise SystemExit(2)
value = json.loads(path.read_text(encoding="utf-8"))
if not isinstance(value, dict):
raise SystemExit(2)
return value
def valid_digest(value):
return isinstance(value, str) and len(value) == 64 and all(ch in "0123456789abcdef" for ch in value.lower())
def parse_time(value):
if not isinstance(value, str):
raise SystemExit(2)
return datetime.fromisoformat(value.replace("Z", "+00:00")).astimezone(timezone.utc)
if len(sys.argv) != 3:
raise SystemExit(2)
manifest = load_json(sys.argv[1])
context = load_json(sys.argv[2])
required = ["adapterId", "adapterDigest", "baseModelDigest", "runtimeFamily", "userScope", "licenseId", "licenseVersion", "purpose", "expiresAt", "revoked"]
if any(field not in manifest for field in required):
raise SystemExit(2)
if not valid_digest(manifest["adapterDigest"]) or not valid_digest(manifest["baseModelDigest"]):
raise SystemExit(2)
if manifest["runtimeFamily"] not in ALLOWED_RUNTIMES or manifest["revoked"] is not False:
raise SystemExit(2)
for field in ["userScope", "baseModelDigest", "licenseId", "licenseVersion", "purpose"]:
if context.get(field) != manifest[field]:
raise SystemExit(2)
now = parse_time(context.get("checkedAt"))
if parse_time(manifest["expiresAt"]) <= now:
raise SystemExit(2)
scope_digest = hashlib.sha256(manifest["userScope"].encode("utf-8")).hexdigest()
print(json.dumps({"status": "eligible-for-server-review", "adapterId": manifest["adapterId"], "scopeDigest": scope_digest}, ensure_ascii=False))事实依据与适用边界
以下内容区分官方事实、本文工程判断和不能外推的范围,避免把设计建议写成未经验证的产品结论。
| 本文判断 | 事实或工程依据 | 适用限制 |
|---|---|---|
| Android LLM Inference 可以把基础模型路径与独立 LoRA 路径同时交给运行时,并受支持模型和后端约束。 | Google AI Edge LLM Inference for Android 描述 Android 上的基础模型与 LoRA 适配器集成路径。 | 该接口处于 maintenance-only,其模型和后端约束不能外推为所有移动 LoRA 运行时的统一标准。 |
| 基础模型、可选定制权重和运行配置属于相互依赖的执行输入。 | Google AI Edge LLM Inference overview 描述 MediaPipe LLM Inference 的模型与定制权重关系。 | 概览不能证明任意 adapter 与任意基础模型兼容,也不提供用户授权。 |
| LiteRT-LM Android 要求应用显式选择并初始化受支持的模型包与运行时配置。 | LiteRT-LM Android 描述 Android 集成、模型包与运行时配置要求。 | 迁移方向不自动继承旧适配器兼容结论,也不定义业务版本或用户绑定策略。 |
| Android 的数据声明需要覆盖应用和第三方 SDK 实际收集与共享的数据。 | Declare Android app data use 说明 Data safety 声明的开发者责任。 | 商店声明不是运行时隔离、日志脱敏、用户授权或删除控制。 |
| Apple 平台的 App 与第三方 SDK 数据行为和 required reason API 应进入有效隐私清单。 | Apple privacy manifests 描述 App 与第三方 SDK 的 privacy manifest 要求。 | 隐私清单属于声明和审核材料,不会自动执行账号隔离或本地清理。 |
| App Attest 证明应由服务端验证并绑定请求。 | Apple App Attest server validation 说明证明生成后的服务端验证路径。 | 平台证明是风险信号,不是绝对设备可信、用户身份或业务许可。 |
| 个人化 adapter 的激活身份应包含用户作用域、基础模型摘要、许可版本和用途。 | 工程判断:仅验证 adapter 字节无法阻止跨账号、跨模型或跨目的复用。 | 字段齐全提高可追溯性,服务端仍需验证权威签名、所有权与当前状态。 |
| 撤销用户权益应先阻止激活,再异步完成设备缓存清理。 | 工程判断:设备可能离线或清理失败,授权决策必须先于文件物理删除生效。 | 具体保留和删除规则取决于项目许可、隐私与合规评审,本文不提供法律结论。 |
工程常见问题
个人化 LoRA 文件摘要正确,为什么还不能直接加载?
摘要只证明字节对应登记对象,还需要确认基础模型和运行时兼容、文件属于当前匿名用户作用域、许可用途与期限有效,并由服务端完成最终权益复核。
把 adapter 放在每个用户不同的目录是否就完成隔离?
没有。目录可以残留、复制或在账号切换时错误复用。应使用服务端签发的匿名 userScope、受控清单和激活授权,并在内存、索引和文件层共同隔离。
基础模型摘要匹配是否说明 adapter 与当前用户匹配?
不能。基础模型摘要解决组合身份,用户归属由 userScope 和服务端资源所有权决定,数据许可还要独立检查 purpose、版本、期限和撤销状态。
退出登录时是否必须立刻删除 adapter 文件?
必须立即停用个人化权益,但是否同步删除文件取决于批准的离线与保留策略。无论文件是否暂存,活动索引、内存会话和后续调用都要先失效。
App Attest 能否代替用户登录和许可校验?
不能。App Attest 是由服务端验证并绑定请求的平台风险信号,仍需会话认证、资源所有权、数据许可和业务授权共同决定是否激活。
申请个人化模型加固评估前需要哪些材料?
准备应用候选、adapter 与基础模型摘要、运行时说明、匿名作用域设计、许可版本、服务端激活协议、退出与删除状态机及拒绝用例回执,再通过御盾中央平台申请。