01开始之前
三个硬条件,缺一条都跑不起来:
- 联发科天玑芯片。整条链路直接调用 MediaTek Neuron(APU / MDLA)接口,不是通用推理框架。高通骁龙、三星 Exynos、海思麒麟一律跑不了,装上去也只会在装载时报错。
- Android 12 或更高。用到的 Neuron Adapter 与
TENSOR_FLOAT16需要较新的系统层。 - 足够的存储和内存。第一档要占约 4.9 GB 存储;出图时还需要 3.7–4.8 GB 的可用内存(按档位不同,见首页表格)。8 GB 运存的机器只能跑 512²,12 GB 以上才谈得上 768×1024。
不确定自己是哪颗,装上 App 后左上角进设置页,第一行就是识别结果。也可以用任意一个硬件信息 App 看 ro.soc.model。
02安装
从下载区取 APK 安装即可。几点说明:
- 包是自签名的,不走应用商店,系统会提示「来源未知」,允许一次即可。
- 签名密钥不会更换。以后升级都是覆盖安装,已下的模型和历史图不会丢。
- 如果提示「应用未安装」或「安装包已损坏」,多半是旧版本残留的下载文件被续传接坏了 —— 卸载后重装即可,或者换备用源重下一遍。
03第一次出图
挑一档
打开 App 进「模型库」。列表里是已上架的五档,按分辨率排。第一次建议选 512²:它资产最小、内存门槛最低(3.7 GB 可用)、最容易一次成功。
列表顶部会显示你这颗芯片的状态。如果显示「这颗芯片还没人验证过」,不代表跑不了 —— 只是没人报过,图会在你的机器上现场编译,第一次装载会慢很多。
下模型
点下载。第一档大约 4.9 GB:模型资产 3.3 GB + 预编译缓存 1.6 GB。下载在前台服务里跑,可以息屏,通知栏有进度。断了会续传。
主源是魔搭(ModelScope),实测单连接 18.8 MB/s;失败会自动换到备用源。下载地址内置,不用手填。
有 adb 的话可以把资产直接推进去,跳过下载:
adb push <资产文件> /sdcard/Android/data/com.anima.npu/files/models/miaomiao8/
注意五档共用同一个目录 miaomiao8(1.46 GB 的文本编码器权重因此只存一份)。
装载与出图
进「画图工作台」,写提示词,点生成。第一次会弹「正在装载模型」——它在把计算图搬进 NPU。缓存全部命中时实测在 9–82 秒之间(512² 档,跨度几乎全来自当时的可用内存,内存越紧越慢);没命中就是现场编译,可能要几分钟到十几分钟。
装载完成后连续出图不会重复装载。切换档位或分辨率会重新装。
04预编译缓存
这是整个项目里最反直觉、也最必要的一环,值得单独讲清楚。
.npug 文件只是计算图的描述,不是可执行的 NPU 指令。真正的 MDLA 二进制要由 Neuron 编译器在设备上生成。实测在天玑 9400 上:
| 单张图耗时 | 起跑需要的可用内存 | |
|---|---|---|
| 冷编译(没缓存) | 249 s | 约 6 GB |
| 命中缓存 | 0.51 s | 无额外要求 |
四张图冷编就是 17 分钟,而且全程要压着 6 GB 可用内存 —— 没 root 的人清不干净后台,中途基本会被系统杀掉。所以每一档都把已经编好的产物一起下发,装载时直接命中。
为什么缓存要按档分
缓存文件名是 Neuron 自己编的不透明串,从外面推不出来,所以每个档位目录里带一份 manifest.txt(文件名 + 大小)。分档是实测确定的:把某一簇缓存单独放进干净目录、跑对应档的图,命中约 600 ms、不命中直接超时,四档十六张图全验过。
试过两条更省事的路子,都不成立:按文件大小配对(四档的图全挤在 443.5–443.9 MB,判据退化),按 atime 判断哪些被读过(/data 是 f2fs 且挂了 noatime,根本不更新)。
为什么换颗芯片就命不中
缓存 token 由「文件名哈希 ^ 文件大小 ^ 编译旋钮」算出,不含芯片型号。而编译产物是绑定某一代 MDLA 的二进制。异构机型硬套会命中错误的产物并返回 rc=6 UNMAPPABLE。所以非 9400 家族的机器不会下载 9400 编的缓存,会在本地现编。
05芯片兼容与自检
App 读 ro.soc.model 判断芯片,并与云端的芯片表求并集 —— 新增机型和状态更新不需要发新版。
- 已验证:有人在这颗芯片的真机上完整跑通过。界面不会有任何额外提示。
- 其它联发科:模型库顶部出现说明条,可以试。建议从 512² 开始。
- 非联发科:明确提示跑不了,不要浪费流量。
装载失败了怎么办
装载对话框里有「复制错误详情」。复制出来的内容包含:芯片型号、机型、系统版本、Android 版本、App 构建号、选的哪一档、编到第几张图、本地缓存文件数,以及错误原文。发到群里就能判断这颗芯片卡在哪。
另外还有个「后台继续」——装载很慢时可以退出对话框让它接着编,不用一直盯着。
兼容性自检
设置页里有一项自检,会实打实地探测这颗 NPU:系统里有哪些 Neuron 库(扫目录,不猜名字)、APU 设备节点存不存在及能否打开(区分「没有」和「没权限」)、关键符号齐不齐、各种张量类型逐个探针、特性位、磁盘剩余。有些机型的问题只有跑完这个才看得出来 —— 天玑 9500 当初就是靠它发现系统里存在两个 adapter、而 App 一直加载了错的那个。
这个错误码在早期版本里被当成「芯片不支持」,其实绝大多数情况是编译时内存不够。0.2.x 已经把装载拆成两趟(先逐张编译并立刻释放,再统一装载),把冷编峰值从「各图之和」压到「单张最大」,并在 rc=6 时整张放掉、等 1.5 秒重试两次。
06分享你的编译缓存
如果你的芯片没有现成缓存,第一次装载会花上十几分钟现场编译。但这份产物对同款芯片的所有人都有效。
设置页里可以看到:本机是哪颗芯片、本机哪些档位已经有缓存、云端哪些「芯片 × 档位」组合已经有人传过。编成之后点一下上传,下一个同款芯片的人就能直接命中,省掉每张图约 4 分钟。
缓存按「芯片 × 档位」两维归档,因为不同分辨率和不同量化各是一套。
07出图参数
提示词
模型吃的是 danbooru 标签风格的提示词,支持 1.2::标签:: 这样的加权写法。例如:
masterpiece, best quality, very aesthetic, absurdres,
1girl, solo, silver hair, long hair, 1.2::red eyes::,
kimono, night, cherry blossoms, depth of field
交叉注意力的条件长度在编译时就固定了:多数档位是 256 个 token,768×1024 W8A16 那档是 512。超长会被截断。
负面提示词为什么不生效
这是 CFG=1.0 的蒸馏模型,原理上就没有无分类器引导的负分支 —— 没有那一路计算,负面词无处可去。输入框保留着只是为了完整复现历史记录里的条件。想去掉某个元素,用正向标签描述你想要的东西,比写负面词有效。
步数
滑块范围 6–12,一端标「快」一端标「稳」。模型原生是 8 步。步数基本线性地决定耗时,实测(768×1024 W8A16、引擎已装载、只算采样到存图):6 步 42.0–42.6 秒,12 步 77.3–79.4 秒。512² 那档 6 步是 9.4 秒。
每个步数对应一张预先导出的调制表,下载时会把 6–12 全部拉下来(七张合计约 65 MB)。所以滑块应该是能拖满的 —— 只有一个刻度是 0.1.x 的老 bug,升级即可。
分辨率与种子
分辨率由档位决定,同一档里可选的比例已经列在界面上。种子可以随机,也可以手填复现。工作台支持「存配置 / 取配置」,把提示词、步数、种子整套存下来复用。
历史
每张出图都带完整参数存进历史,可以放大看、保存到相册,也能从历史里把当时的配置读回工作台。
08内存与后台
能不能出图,很大程度取决于点下去那一刻系统还剩多少可用内存。App 每一档都有实测定出的门槛,不够会直接拦下并提示清后台 —— 这是刻意的,跑到一半被系统杀掉比一开始就拒绝要糟糕得多(严重时会连带整机重启)。
提高成功率的常规做法:关掉后台大应用、别在下载的同时出图、把 768×1024 留到刚重启完的时候跑。
Root 模式(可选)
有 root 的话,设置页里有一键释放内存:对候选应用逐个 am force-stop(杀现在的)并 pm suspend(防以后自启)。解冻是向系统查真实的 suspended 状态再全部解开,不依赖 App 自己记的名单 —— 就算 App 中途被杀,也不会有应用永远解不开。
要有心理预期:ION、GPU、Slab、PageTables 这些内核和驱动占用(实测合计约 2.5 GB)是清不掉的。
09版本更新
启动时会静默检查一次云端版本,比本机新就弹框,可以「下载并安装」或「以后再说」(同一版本不再打扰)。检查失败一律沉默 —— 没网不该弹错误框。
升级是覆盖安装,已下的模型和历史图都保留。
10常见问题
为什么要下这么大?
因为模型权重本来就在手机上,不是在服务器上。一档 = DiT 计算图 1.8 GB + 文本编码器权重 1.46 GB + VAE 与调制表约 90 MB + 预编译缓存 1.4–1.7 GB。文本编码器和 VAE 各档共用,只下一次,所以加第二档只多约 1.9 GB。
能不能不下预编译缓存?
技术上可以,但基本不现实:冷编译要 249 秒一张、四张 17 分钟,全程压着 6 GB 可用内存。没 root 的机器很难撑到结束。
下载速度慢
主源是魔搭 CDN,国内直连通常能跑满宽带。如果卡住,去设置页换到备用源重试;下载支持断点续传,不会从头开始。
装载时报 rc=6 / UNMAPPABLE
绝大多数是编译时内存不足,不是芯片不支持。清后台重试,或换到内存门槛更低的 512² 档。仍然不行就复制错误详情发群里。
出来一张纯色平图 / 一团糊
说明资产配错了(比如 RoPE 表与计算图精度不匹配)。这类问题的特点是日志一切正常,只有看图才发现。遇到请连提示词、种子、档位一起发群里。
能用我自己的模型吗?
暂时不能。App 跑的是已经转好并编译过的 .npug 计算图,原始 safetensors 无法在手机上转换 —— 转换链路在 PC 上,涉及量化标定、分段、调制表导出等一整套流程。
会上传我的提示词或图片吗?
不会。出图全程离线。联网只发生在三件事上:检查版本、下载模型资产、以及你主动点「上传本机编译缓存」(传的是 NPU 二进制,不含任何出图内容)。
11已知限制
- 负面提示词不参与计算。见上面 07 的说明,这是模型本身的性质,不是 bug。
- 768×1024 吃内存。W8A16 那档装载约 4.6 GB,后台满的时候可能装不上。App 会先拦住并提示,不会跑一半被杀。
- 机型覆盖有限。绝大部分调优在一台天玑 9400(ColorOS)上完成,其它机型的支持来自群里的反馈,一颗一颗加。
- 只有一个模型。目前上架的都是同一个底模的不同分辨率与精度切分。
- 还是测试版。版本号 0.2.x,界面、档位、参数都可能变。
12名词表
| NPU / APU | 手机 SoC 里的神经网络加速单元。联发科这一代的执行单元叫 MDLA。 |
| Neuron | 联发科的 NPU 运行时与编译器。App 通过它的 Adapter 接口把计算图编译并执行在 MDLA 上。 |
| .npug | 本项目的计算图格式。只是图的描述,真正的 NPU 指令要在设备上编译出来。 |
| DiT | Diffusion Transformer。这里是 2B 参数、28 层、隐藏维 2048 的结构,被切成 4 张图分别编译。 |
| VAE | 把采样出来的隐空间张量解码成像素图的那一步。 |
| W8A16 / W8A8 | 量化配置。前者 int8 权重 × int16 激活,后者激活也是 int8 —— 更快更省内存,但注意力概率会被清零,画质有可见损失。 |
| 调制表 | 每个步数对应一张预先算好的表。步数不同表不同,且与图的量化标定绑定,混用会静默降画质。 |
| RoPE 表 | 旋转位置编码表。它是唯一编码二维位置的东西,所以同一套 DiT 图换张表就能换长宽比。 |
| 蒸馏 / CFG=1.0 | 把多步采样蒸馏成 8 步的模型。代价是没有无分类器引导,负面提示词失效。 |
文档跟着 App 走,有出入以 App 内的提示为准。发现写错了或者讲不清楚的地方,欢迎在 QQ 群 1106566586 里指出来。