在 Android / Termux 上运行 MemPalace:基于 Debian PRoot 容器的完整部署指南
MemPalace 的官方安装方式针对 Linux 桌面与服务器(Python 3.9+、标准 Linux 轮子)设计,而 Android / Termux 使用 Android 的 Python 平台(Bionic libc 与 Android wheel tags),无法直接安装其依赖树。本文给出当前仓库中验证过的兼容路径:在 Termux 内的 Debian 12 PRoot 容器中部署标准 Linux ARM64 包,并在 Android ARM64 设备上完成 mine / search 的完整本地记忆工作流——包括容器安装、launcher 脚本、环境变量语义、升级与备份注意事项。
为什么不能在 Termux 的 Android Python 里直接安装
MemPalace 本身是纯 Python,但它的依赖发布的是 Linux 轮子。Termux 使用的是 Android 的 Bionic libc 与 Android wheel tags,pip 找不到匹配的预编译包,会回退到源码构建(source build)。对 ChromaDB、Maturin 这类包含原生代码的依赖,源码构建在 Termux 环境下往往失败(相关结论与实测环境见 website/guide/termux.md)。
因此,当前仓库认可的方案是:运行 Debian PRoot 容器内的标准 Linux ARM64 包。需要明确两点边界:
- 这不是 Android 原生移植,而是一条「兼容性路线」;
- 实测组合为 Android ARM64 + Termux + Debian 12 + Python 3.11 +
sqlite_exactbackend。
从源码看,存储后端通过 mempalace/backends/registry.py 注册为 chroma、milvus、qdrant、sqlite_exact、pgvector 五类,其中 chroma 是历史默认。PRoot 容器里特意选用 sqlite_exact 正是为了规避 ChromaDB 在 PRoot 下的内嵌存储运行时开销(后文详述)。
开始前需要知道的前提
- 使用较新的 Termux 构建版本,且必须是 64 位 ARM 设备(本指南的 ARM64 包与轮子均针对此架构)。
- 预留至少 2 GB 空闲空间:Debian 根文件系统、Python 环境、依赖以及本地 embedding 模型都需要磁盘。
- 把 palace 放在 PRoot 容器内部,只把 MemPalace 需要读取的 Termux 目录 bind 进容器。
安全边界必须说清楚:PRoot 只是兼容层,不是安全边界。下面的 launcher 使用 --isolated 模式并只暴露 Termux 的 home 目录,但 MemPalace 仍能读取该 bind 下的全部内容。不要把 PRoot 当成沙箱来依赖。
关于 palace 目录的定位,可以在 mempalace/config.py 看到 palace_path 的解析规则:优先取 MEMPALACE_PALACE_PATH(或旧名 MEMPAL_PALACE_PATH)环境变量,其次取 config.json 中的 palace_path,最后回落到默认路径。因此 launcher 里设置 MEMPALACE_PALACE_PATH=/opt/mempalace/palace,就能把全部记忆数据稳定锚定在容器内的专属目录,而不是散落在随机工作目录中。
第一步:安装 PRoot 容器
在 Termux 中依次执行:
pkg update
pkg install proot-distro
proot-distro install -n mempalace debian:12
随后在 Debian 内创建专用虚拟环境并安装 MemPalace:
proot-distro login --isolated mempalace -- /bin/sh -lc '
set -eu
apt-get update
apt-get install -y --no-install-recommends ca-certificates python3 python3-venv
mkdir -p /opt/mempalace/home /opt/mempalace/cache /opt/mempalace/palace
python3 -m venv /opt/mempalace/venv
/opt/mempalace/venv/bin/python -m pip install --upgrade pip
/opt/mempalace/venv/bin/python -m pip install --only-binary=:all: mempalace
'
几个目录的作用分别是:
| 目录 | 用途 |
|---|---|
/opt/mempalace/home |
容器内的 HOME,存放 ~/.mempalace/config.json 等配置 |
/opt/mempalace/cache |
通过 XDG_CACHE_HOME 指向,用于模型与依赖缓存 |
/opt/mempalace/palace |
palace 数据目录(MEMPALACE_PALACE_PATH),含记忆内容 |
/opt/mempalace/venv |
独立 Python 虚拟环境 |
--only-binary=:all: 是这条安装命令的关键:它让安装在缺少 Linux ARM64 轮子时明确失败,而不是悄悄启动一个不被支持的源码构建,从而保证「要么装好、要么立刻报错」,避免在半损坏的环境里继续排错。这与上一节「依赖源码构建会失败」的结论互为印证。
第二步:添加 mempalace-proot launcher
把下面的脚本保存为 Termux 下的 ~/.local/bin/mempalace-proot,然后执行 chmod 700 ~/.local/bin/mempalace-proot:
#!/data/data/com.termux/files/usr/bin/bash
set -euo pipefail
termux_home="${HOME:?}"
case "$termux_home" in
/*) ;;
*) echo "HOME must be an absolute path" >&2; exit 2 ;;
esac
case "$termux_home" in
*:*) echo "HOME containing ':' cannot be bound safely" >&2; exit 2 ;;
esac
case "$PWD" in
"$termux_home"|"$termux_home"/*) work_dir="$PWD" ;;
*) work_dir="$termux_home" ;;
esac
exec "${PREFIX:?}/bin/proot-distro" login \
--isolated \
--bind "$termux_home:$termux_home" \
--work-dir "$work_dir" \
mempalace -- \
env -i \
HOME=/opt/mempalace/home \
PATH=/opt/mempalace/venv/bin:/usr/bin:/bin \
LANG=C.UTF-8 LC_ALL=C.UTF-8 \
XDG_CACHE_HOME=/opt/mempalace/cache \
MEMPALACE_PALACE_PATH=/opt/mempalace/palace \
MEMPALACE_BACKEND=sqlite_exact \
MEMPALACE_EMBEDDING_MODEL=minilm \
MEMPALACE_EMBEDDING_DEVICE=cpu \
MEMPALACE_EMBEDDING_THREADS=1 \
OMP_NUM_THREADS=1 TOKENIZERS_PARALLELISM=false \
/opt/mempalace/venv/bin/mempalace "$@"
这个 wrapper 的设计要点如下:
- 参数透传与工作目录保留:
"$@"把每次调用的命令行参数原样传给mempalace;当当前工作目录位于 Termux home 之下时,--work-dir "$work_dir"保持相对路径语义,否则回退到 home。 - HOME 安全校验:脚本拒绝非绝对路径或包含
:的HOME——冒号路径无法被--bind安全绑定。${PREFIX:?}保证 Termux 前缀已设置。 - 隔离与最小暴露:
--isolated模式配合只 bind Termux home,容器内不继承宿主环境变量(env -i全新环境),随后显式注入一份最小化、确定性的环境。 - 后端选择
sqlite_exact:避免在 PRoot 下依赖 ChromaDB 内嵌存储运行时;同时 embedding 与检索完全留在设备本地。 - 单 embedding 线程:
MEMPALACE_EMBEDDING_THREADS=1是对手机散热的保守默认。
launcher 环境变量的源码语义
这些变量都对应 mempalace/config.py 中真实的配置读取逻辑,全项目配置优先级统一为 env vars > config file(~/.mempalace/config.json)> defaults(模块 docstring 见 mempalace/config.py):
| 变量 | 取值 | 源码语义 |
|---|---|---|
MEMPALACE_PALACE_PATH |
/opt/mempalace/palace |
palace 数据目录,覆盖配置文件中的 palace_path(见 config.py) |
MEMPALACE_BACKEND |
sqlite_exact |
存储后端名。backend 解析优先级为 CLI 显式值 > 每 palace 配置 > MEMPALACE_BACKEND 环境变量 > 磁盘产物自动探测(仅迁移用)> 默认 chroma,见 mempalace/backends/registry.py |
MEMPALACE_EMBEDDING_MODEL |
minilm |
本地 ONNX 模型:all-MiniLM-L6-v2,384 维,英文训练;另有 embeddinggemma(多语言、默认推荐,约 300 MB,首次使用时懒下载)与 openai-compat(走 /v1/embeddings 兼容端点)。模型切换意味着向量空间改变,需 mempalace repair rebuild-index,见 config.py 与 mempalace/embedding.py |
MEMPALACE_EMBEDDING_DEVICE |
cpu |
ONNX Runtime 执行设备:auto/cpu/cuda/coreml/dml。auto 会优先 CUDA → CoreML → DirectML 并在不可用时回退 CPU;本场景显式 cpu 以规避 PRoot 下的设备访问告警,见 config.py 与 mempalace/embedding.py |
MEMPALACE_EMBEDDING_THREADS |
1 |
限制 ONNX Runtime intra-op 线程池。unset/auto 为逻辑核数一半(至少 1);正整数为精确线程数;0 或负数不设上限(默认物理核数)。ChromaDB 的 ONNX embedder 默认不设上限,后台 mine 会钉满所有核并造成发热,故这里显式收紧到 1,见 config.py |
OMP_NUM_THREADS、TOKENIZERS_PARALLELISM |
1、false |
抑制 OpenMP 与 tokenizer 的并行开销,降低小内存设备上的线程竞争 |
注意注释里的一个细节:源码指出 OMP_NUM_THREADS 对 ONNX Runtime 自身的线程池是无效的(ORT 独占自己的池),因此真正的并发上限由 MEMPALACE_EMBEDDING_THREADS 通过 SessionOptions 施加,见 config.py。Launcher 同时设置两者,是「双保险」式的保守配置。
为什么选择 sqlite_exact 后端
从 mempalace/backends/sqlite_exact.py 的模块注释看,该后端「刻意简单、本地优先」,是一个正确性后端而非高吞吐 ANN 后端:向量以 float32 blob 存储,查询在同一集合内做精确 cosine 距离(向量化 numpy),无过滤查询仅按 embedding 列排序、随后再水合 top-k 文档,并缓存矩阵避免每次搜索重读 blob。对一部手机规模的 palace,精确检索完全够用,且比需要嵌入式运行时服务的 ChromaDB 在 PRoot 兼容性上更稳。该后端同样参与 tests/_backend_conformance.py 定义的后端一致性验收(如 tests/test_backend_conformance.py 中对 SQLiteExactBackend 的 pytest.param)。
第三步:验证与日常使用
mempalace-proot --version
# Project files under the Termux home bind
mempalace-proot mine "$HOME/projects/myapp"
# Codex conversations
mempalace-proot mine "$HOME/.codex/sessions" --mode convos
mempalace-proot search "why did we change the authentication flow"
- 第一次执行
mine或search时,会下载本地 MiniLM 模型(约 80 MB)。 - PRoot 下可能出现
denied access to /sys/class/drm之类的告警;只要如上设置了MEMPALACE_EMBEDDING_DEVICE=cpu,该告警无害,可忽略。 - Termux home 之外的路径刻意不可达。想处理 home 外的源码,要么把源复制到
$HOME下,要么自行在 launcher 中追加窄而明确的--bind source:destination——追加前务必想清楚这会暴露什么。
从 CLI 实现看,mine 支持多模式:默认 projects(代码与文档,自动探测房间),--mode convos(会话导出,按问答对分块),并可通过 --extract general 在会话挖掘时把内容分类为决策、偏好、里程碑、问题与情绪上下文;cmd_mine 入口见 mempalace/cli.py。cmd_search 则把查询、可选 wing/room 过滤、结果数、时间窗参数传给 searcher.search,见 mempalace/cli.py。
命令用法速查:
| 命令 | 作用 | 说明 |
|---|---|---|
mempalace-proot --version |
打印版本 | 顺带验证 wrapper 与容器内 CLI 均正常 |
mempalace-proot mine "$HOME/projects/myapp" |
挖掘项目 | projects 模式,代码与文档自动分房 |
mempalace-proot mine "$HOME/.codex/sessions" --mode convos |
挖掘会话 | convos 模式,Codex 会话按问答对切分 |
mempalace-proot search "..." |
语义检索 | 输出 top-k 结果与来源路径 |
关于 palace 背后的组织模型(wing / room / hallway / tunnel),可进一步阅读 website/concepts/the-palace.md;初始化、通用挖掘模式与 MCP 接入的桌面侧细节见 website/guide/getting-started.md。
升级:只升级 Python 环境,别动 palace
升级只作用于 Python 环境,palace 保持在 /opt/mempalace/palace:
proot-distro login --isolated mempalace -- \
/opt/mempalace/venv/bin/python -m pip install \
--upgrade --only-binary=:all: mempalace
--only-binary=:all: 同样保证了未来若某个依赖暂时没有 Linux ARM64 轮子,升级会清晰失败而非启动不被支持的源码构建。
备份与容灾提醒
proot-distro remove mempalace 与 proot-distro reset mempalace 都会销毁存放在容器内的 palace。因为 MEMPALACE_PALACE_PATH=/opt/mempalace/palace 位于 Debian 根文件系统中,重置容器等于清空全部记忆数据。因此:
- 在移除或重置容器之前,先备份整个容器(例如
proot-distro backup或直接归档/opt/mempalace)。 - 若希望 palace 独立于容器生命周期,可考虑在 launcher 中把一个 Termux 目录以
--bind方式挂载为 palace 目录,但正如上文所述,这会把记忆明文暴露在 PRoot 之外,需自行权衡(当前仓库的官方示例默认不这么做)。
小结
在 Termux 上运行 MemPalace 的路径可以概括为三步:装 Debian PRoot 容器 → 在容器内建 venv 并以 --only-binary=:all: 安装 → 通过 mempalace-proot wrapper 统一入口。所有关键环境变量(palace 路径、sqlite_exact 后端、CPU 设备、单线程 embedding)都有对应的源码级读取逻辑支撑,并且每一项都服务于「小内存 ARM 设备 + PRoot 兼容层」这一特定约束。遵循本文的升级与备份纪律,即可在手机本地获得与桌面端一致的本地优先记忆索引能力。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0627
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00