| --- |
| license: other |
| tags: |
| - private |
| - android |
| - on-device-llm |
| - llama.cpp |
| - offline |
| --- |
| |
| # 团智宝(TrainAI)— 离线端侧心理训练方案生成 APP |
|
|
| > ⚠️ **私有仓库 · 仅供代码备份与同步。** |
| > 本软件著作权与知识产权归委托方所有;仓库内不含委托方业务资料(知识库/模板/图片/音频)、 |
| > 不含合同与任何身份信息、不含模型权重。请勿转为公开可见,勿对外分发。 |
|
|
| Android(适配鸿蒙 NEXT + 卓易通容器)平板端**完全离线**运行的训练方案生成工具: |
| 输入训练主题 → 端侧大模型分章节生成完整"指导语"方案 → 自动匹配示意图与背景音乐 → 导出 PDF。 |
| 不申请 `INTERNET` 权限,全部数据留在本机。 |
|
|
| ## 仓库内容 |
|
|
| | 路径 | 说明 | |
| |---|---| |
| | `app/` | Android 工程源码(Kotlin + Jetpack Compose + Hilt + Room;JNI/C++ 推理桥) | |
| | `docs/` | 使用手册、维护手册、交付说明 | |
| | `tools/` | 资源包制作、向量离线预计算、生成质量回归测试(Python) | |
| | `fetch_llama_cpp.sh` | 拉取并固定第三方推理引擎版本(未随仓库分发) | |
|
|
| **不在仓库内**(体积或权属原因):`llama.cpp` 源码(脚本拉取)、GGUF 模型权重、 |
| bge 向量模型、出厂资源包 `library.zip`、编译产物、APK。 |
|
|
| ## 快速开始 |
|
|
| ```bash |
| ./fetch_llama_cpp.sh # 拉取推理引擎(固定 commit) |
| cd app && echo "sdk.dir=/path/to/Android/sdk" > local.properties |
| ./gradlew assembleDebug # 需要 JDK17 / SDK34 / NDK r26+ / CMake / ninja |
| ``` |
|
|
| ## 架构 |
|
|
| ``` |
| UI (Compose) chat 对话生成 / browse 方案库卡片 / knowledge 学习空间 / library 资料库 |
| │ |
| 业务层 PromptBuilder(分章节引导生成)· StylePrefs(生成偏好)· Summarizer(AI 总结) |
| MediaMatcher(示意图/音乐语义匹配)· TemplateExtractor(模板骨架) |
| │ |
| 数据层 Room(文档/切片/媒体/会话)· RagPipeline(切片→bge 向量→余弦检索) |
| │ |
| 推理层 LlamaCpp(Kotlin)──JNI──► llama_jni.cpp ──► llama.cpp(CPU, arm64-v8a) |
| crash_handler.cpp:native 崩溃黑匣子(信号捕获 + 回溯落盘) |
| ``` |
|
|
| ## 端侧工程要点(踩坑记录,改代码前必读) |
|
|
| 1. **容器内存上限**:鸿蒙 NEXT 的 Android 容器单应用仅约 3–4 GB 可用 → 模型必须 ≤3B(7B 必被 OOM 强杀);代码对 >3GB 的模型直接拒绝加载并给出说明。 |
| 2. **JNI 字符串不能用 `NewStringUTF`**:它要求 Modified UTF-8,模型输出 emoji(4 字节 UTF-8)会让 ART `abort` → 崩溃。token 回调与 prompt 传参一律走 `byte[]`。 |
| 3. **中文跨 token 边界**:一个汉字可能被拆到两个 token,需在 native 侧缓冲不完整的 UTF-8 尾字节,否则显示成 `?`。 |
| 4. **native 必须 Release 构建**:Debug 的 ggml 断言会因 ARM FP16 累加溢出(`isnan/isinf`)直接 abort;同时禁用 CPU flash-attention(该路径数值不稳)。 |
| 5. **生命周期**:`Session` 析构负责释放 model/ctx/sampler;卸载/换模型前先置停止标志并等生成线程退出,否则重复加载泄漏 GB 级内存或 use-after-free。 |
| 6. **流式背压**:`trySend` 在缓冲满时会静默丢 token(输出缺字),改 `trySendBlocking`;UI 侧节流刷新(每 token 全量刷新是 O(n²) 拷贝)。 |
| 7. **容器文件沙箱**:文件管理器放入的文件应用不可见,大文件必须走 SAF 导入,并分段 `fsync` 防页缓存计入应用内存被强杀。 |
| 8. **小模型的长文本策略**:整篇一次生成会残缺;改为逐章节引导(每章独立 prompt + 结构要求 + few-shot),并对与范例的 n-gram 重合率超阈值的章节自动重写。 |
|
|
| ## 许可与合规 |
|
|
| 第三方组件依其原许可(llama.cpp、ONNX Runtime、PdfBox-Android 等)。 |
| 本项目自身代码的著作权归委托方所有,未获书面授权不得公开分发或商用。 |
|
|