首页
/ 在 Android / Termux 上运行 MemPalace:基于 Debian PRoot 容器的完整部署指南

在 Android / Termux 上运行 MemPalace:基于 Debian PRoot 容器的完整部署指南

2026-09-07 13:00:07作者:田桥桑Industrious

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_exact backend

从源码看,存储后端通过 mempalace/backends/registry.py 注册为 chromamilvusqdrantsqlite_exactpgvector 五类,其中 chroma 是历史默认。PRoot 容器里特意选用 sqlite_exact 正是为了规避 ChromaDB 在 PRoot 下的内嵌存储运行时开销(后文详述)。

开始前需要知道的前提

  1. 使用较新的 Termux 构建版本,且必须是 64 位 ARM 设备(本指南的 ARM64 包与轮子均针对此架构)。
  2. 预留至少 2 GB 空闲空间:Debian 根文件系统、Python 环境、依赖以及本地 embedding 模型都需要磁盘。
  3. 把 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.pymempalace/embedding.py
MEMPALACE_EMBEDDING_DEVICE cpu ONNX Runtime 执行设备:auto/cpu/cuda/coreml/dmlauto 会优先 CUDA → CoreML → DirectML 并在不可用时回退 CPU;本场景显式 cpu 以规避 PRoot 下的设备访问告警,见 config.pymempalace/embedding.py
MEMPALACE_EMBEDDING_THREADS 1 限制 ONNX Runtime intra-op 线程池。unset/auto 为逻辑核数一半(至少 1);正整数为精确线程数;0 或负数不设上限(默认物理核数)。ChromaDB 的 ONNX embedder 默认不设上限,后台 mine 会钉满所有核并造成发热,故这里显式收紧到 1,见 config.py
OMP_NUM_THREADSTOKENIZERS_PARALLELISM 1false 抑制 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 中对 SQLiteExactBackendpytest.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"
  • 第一次执行 minesearch 时,会下载本地 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.pycmd_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 mempalaceproot-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 兼容层」这一特定约束。遵循本文的升级与备份纪律,即可在手机本地获得与桌面端一致的本地优先记忆索引能力。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.13 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.8 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
529
593
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
915
1.83 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.58 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.35 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.01 K
515
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
388