Repository navigation
Releases: Neocher/self-evolving-hypergraph-memory
Release list
v6.28.0 LoadShedding
版本
v6.27.0 (LockFairness) → v6.28.0 (LoadShedding) — 检索性能总纲(19 个提交合并发布)
成果
| 指标 | 基线 | v6.28.0 | 改善 |
|---|---|---|---|
| 检索中位(稳态) | 15.40s | 1.6~3.0s | 5~9x |
| 重启后首条 | 12.7s | ~2.5s | 5x |
| 超时率(稳态) | ~11% | 0% | 归零 |
| 并发 8 超时 | 8/8 | 0/8 | 归零 |
| 并发 12 超时 | 12/12 | 0/12 | 归零 |
| 503 峰值 | 78/h | 0 | 归零 |
并发场景下所有请求返回完整 20 条结果(不再退化为 9–10 条兜底)。
关键改动
- 社区成员 sidecar 索引 — 取成员 7,719ms → 3ms(2,166x);构建 1,449s → 16.4s(88x)
(目标侧分批 + keyset 游标分页,绕开引擎 1 万行上限与 max_skip 限制) - 社区索引 100% 覆盖 + 按社区门控 — 社区扩展熔断误触 55% → 0
- reranker 长度分桶 — 2.08x,排序逐位一致(bit 级等价);
max_length保持 512 - 本体同步前移到启动期 — 首条 6.87s → 2.51s
(根因:路由层 lazy sync 是预热盲区,预热直连QueryRouter.retrieve绕过api/routes/) - reranker 进程级并发闸门 — Semaphore + 有界 acquire + 优雅降级,无死锁
- 高并发显式卸载 — in-flight ≥ 4 时跳过社区扩展,超载请求快速返回未扩展的完整结果
(严格优于原「超时 6s → Cypher 兜底只给 9–10 条」);低并发逐字节不变 - 社区相关性 TF-IDF 拟合缓存 — bit 级等价,固定语料 89x
关键依赖(版本要求 / 下载地址)
| 依赖 | 版本要求 | 说明 |
|---|---|---|
| Python | 3.11+ | |
| overgraph | >=0.17.0 | 存储引擎(纯 Rust 嵌入式图数据库,v6.0.0 起唯一后端)· https://overgraph.io |
| torch | 2.12.1+cpu(实测) | CPU 构建即可(本机无 GPU;CUDA 可选) |
| sentence-transformers | >=2.2.0(实测 2.7.0) | 重排模型加载 |
| scikit-learn | >=1.3.0 | 社区相关性 / BM25 |
| mcp | >=2.0.0 | MCP 协议支持 |
| 嵌入模型 | EmbeddedLLM/bge-m3-onnx-o2-cpu |
ONNX,MRL 截断 512 保 HNSW 契约;国内镜像 https://hf-mirror.com |
| 重排模型 | BAAI/bge-reranker-base |
CPU 推理(需本地 HF 缓存,离线加载) |
⚠️ graphlite_sdk不在 PyPI(仅迁移旧库时需要源码构建);v6.0.0 起后端已是 OverGraph。
验证
- 全量测试 1783 passed / 1 skipped / 0 failed
- 生产实测(重启后):稳态 0 超时、0 503;并发 4/8/12 全部 0 超时且返回完整 20 条
- 等价性:长度分桶排序逐位一致;缓存与原实现差
0.000e+00;卸载在低并发逐字节不变
已知结构性成本(未消除,已由卸载兜住)
- 每请求社区相关性 char-ngram 向量化 ~530ms(摘要集随查询变化,553–1509 条)
- reranker 单次 ~0.94s(CPU 串行)
方法论
本轮用 py-spy 抓栈替代猜测定位瓶颈;3 个假设被实测证伪(ONNX 加速 1.04x /
后台任务抢 CPU / 「93% 是词表拟合」),1 个方案被实测否决(全局词表:1.0x 且语义偏离 84.4%)。
过程与数字均有记录。
v6.27.0 LockFairness — OverGraph 锁公平:消除写队列 503 与 /health 劣化
v6.27.0 LockFairness — 消除 OverGraph 全局锁饿死
根因
OverGraphStore._session_lock 是单把全局互斥锁,串行化所有图操作。检索侧
_community_expansion 为每个相关社区各调一次 get_community_members,每次都取锁 →
持锁时间长 → 写线程 _persist_entities(梦境管道)取不到锁 → 写队列积压至上限 →
WriteQueueFullError → HTTP 503;/health 自身也要查图,同样排队 → 19~23 秒。
py-spy 5 次采样实证:检索线程持锁 active / 写线程反复 blocked。
修复
| 文件 | 改动 |
|---|---|
graph/overgraph_store.py |
threading.RLock → _WriterPriorityLock(写线程优先;同线程可重入 + 跨线程互斥);新增 bind_writer_thread() 与有界 health_probe(timeout=0.5) |
retrieval/query_router.py |
N 次 get_community_members → 1 次批量取回;无批量原语的 store 回落逐社区查询,检索语义不变 |
api/app.py |
把 WriteQueue 的 worker_ident 绑给写优先锁 |
api/routes/system.py |
/health 连通性探测改用有界 health_probe,超时降级 degraded |
core/write_queue.py |
新增只读 worker_ident property(不动背压/看门狗) |
验证
| 项 | 结果 |
|---|---|
| 新增验收测试 | tests/test_overgraph_lock_fairness.py(6 用例 / 21 断言 / 真并发) |
| RED→GREEN | 暂存实现 → 6 failed;恢复 → 6 passed |
| 全量回归 | 1544 passed / 2 skipped / 5 deselected / 0 failed |
| 压测(8 读者 + 50 写) | 写队列 503 = 0 次;/health P95 = 0.301s(基线 23.2s) |
| 生产实测(重启后) | 503 = 0 次;/health 0.12~0.30s |
备注
- 交付方:太极 / DSH(Hermes 负责诊断 + 验收标准 + 独立核验)
- 既有测试
tests/test_v529_concurrency_fixes.py的锁断言同步升级为行为等价
(同线程可重入 + 跨线程互斥),断言强度不减 scripts/stress_overgraph_lock_fairness.py:AC2/AC3 压测脚本
v6.23.0 StateSemantics — AtomicFact bi-temporal supersession
P3: AtomicFact 事实 supersession (bi-temporal 作废)
- 写侧: create_atomic_fact 落库前查同 (subject, predicate) 的 active fact, object 不同 → 旧 fact 打 superseded_at + superseded_by, 新 fact 记 supersedes 血缘 (多条旧 fact 记 created_at 最近一条)
- 读侧: get_atomic_facts_by_subject 默认 active-only (排除已作废) + 新增 get_active_facts_by_sp 精确查
- 检索: _fact_retrieve 仲裁改基于 supersession (同 S+P 去重), 不再依赖 valid_time 非空
- 开关: SHM_FACT_SUPERSEDE=0 一键关 (默认开)
- 设计: 复用 PropertyVersion bi-temporal 思路 (supersedes/superseded_by 双挂链) 独立实现; 纯 GQL 层不碰向量/FAISS; 标记作废非删节点, 血缘可回溯
- 门: 10 新用例 + 全量 1467 passed 零回归; 生产探针: REST 写端口 1080→2080, active-only 只回新值, 三向血缘核验一致
同期 (v6.22.7 → v6.22.9)
- v6.22.7 CJK 兜底分词 + 判别打分 (char 2-gram + 匹配度打分)
- v6.22.8 兜底同步到 REST 主路径 (双副本陷阱)
- v6.22.9 P1 生产写路径懒抽取 SPO 事实落库 (AtomicFact 从 0 累积)
v6.22.6 谓词论元抽取与类型锚定检索 — StateSemantics 系列收官
SHM v6.22.6
自演化超图记忆系统 — 检索与证据装配层升级 (v6.21.0 → v6.22.6, 13 commits)
核心能力新增
状态语义 (StateSemantics, v6.20.0 基座)
- E1' 状态时点裁决 / E3 实例 key / E2 模态五值 / E4 槽位检索 (QueryRouter.retrieve_slot, env R8_CTX/R8_SLOT 控制)
谓词论元抽取 (v6.21.x)
- 触发词词边界 + 屈折匹配, 宾语 NP 抽取 (跳限定词/停在介词连词代词助动词时间状语)
- P1 类型化值校验: 题面推断期望类型 + 封闭词表类型门 + 引号抽取
- 注入块 precision 0.032 → 0.071 (2.2x), 段长 -72%, 垃圾值归零
类型锚定抽取 (v6.22.x)
- 集合题走类型扫描通道: us_state / us_country / us_city / activity / work_book / family_member / event / music_genre / game_title 九类端到端 (题面识别 + 扫描 + 类型校验)
- gold 覆盖 0.249 → 0.494, 闭包 recall 0.205 → 0.334 (+63%)
- 类型通道放开说话人归属: 集合/枚举题证据常由对话伙伴提供, 类型过滤作为精度守门 (us_state 精度保持 1.00)
计数题路径 (v6.22.0-6.22.1)
- core/instance_dedup.py 实例去重/计数基础件
- count_anchor_terms / extract_anchor_mentions / count_instances / route_count_question + [SLOT COUNT] 渲染
- 路由零候选 6/20 → 0/20
装配预算与选择/过滤 (v6.22.3-6.22.5)
- 注入块上限 80 → 15 (实测零 gold 损失), 候选均值 30.1 → 7.7, 段均字符 1279 → 716
- 五种排序键实测固化负结果 (题面同域加权与 gold 反相关, 已回退)
性能
- 启动直接加载已落库向量 (SHM_INDEX_LOAD): 重启就绪 9.2s (原 2.5min), 零重编码
- 编码器 fp16 + 分块 (SHM_ENC_BATCH), 重建后归还 CUDA 缓存 (常驻 5.3G → 1.5G)
- 全量 pytest 1406 passed
兼容性
- 默认全 off 时与 v6.20.0 逐字节等价; 新通道由 env 开关控制
- 依赖 OverGraph 0.17.0 (pip/GitHub 最新)
修复
- R8-SLOT-SCOPE-1: 装配链路静默零注入 (int session_id 前缀裁剪恒空 → 回落调用方已裁剪消息), T1~T5 回归
v6.20.0 (StateSemantics) — 引擎语义不变量 E1'~E4
v6.20.0 StateSemantics (2026-09-09)
引擎语义不变量四件套 (R8, 评测只当探照灯 — 引擎能力真升级, 判卷/judge/prompt V1/数据面零改动):
- E1' 状态时点裁决 core/state_projection.py — latest-wins + 否定行 + timeline 全链掩码 (与 _property_temporal_retrieve 同构)
- E3 实例身份 key core/instance_key.py — sha1(entity|type|iso_week|obj|obj_desc), obj_desc 修饰语维 (双吉他异实例), 别名归一
- E2 模态五值闭域 core/modality_rules.py — actual/planned/wish/inferred/in_talks, 谓词语义门 did/plan/offer
- E4 槽位确定性检索 retrieval/slot_facts.py (SlotIndex 全集+值去重) + slot_extract.py (原文抽取) + QueryRouter.retrieve_slot (R8_CTX=1)
- 评测装配 scripts/slot_assembly.py [SLOT EVIDENCE] (R8_SLOT=1, bench 3 点位追加式)
默认全 off 与 v6.19.0 逐字节等价; 全量 pytest 1320 零回归。
Benchmark: 官方口径仍 v6.19.0 83.14% (cat1 68.5/ cat2 81.6/ cat3 77.9/ cat4 88.0) — G4 全量评测延后 11 号后更新至 v6.20.0。
v6.19.0 MultiModalCaption — LoCoMo-Refined 83.14% 超 SOTA 82.65%
v6.19.0 — MultiModalCaption: 精卫超 SOTA 收官 🎉
评测结果 (2026-09-08, LoCoMo-Refined 官方判卷 qwen3-14b refined / 1382 题)
全量 83.14% (1149/1382) > MemoraX SOTA 82.65% (+0.49pp)
| 类别 | 正确率 | vs 上轮 (76.48%) |
|---|---|---|
| cat1 多证据聚合 | 68.5% | ▲ +9.8pp |
| cat2 时间/日期 | 81.6% | ▲ +13.4pp |
| cat3 推断/偏好 | 77.9% | ▲ +1.4pp |
| cat4 跨会话综合 | 88.0% | ▲ +3.7pp |
精卫演化循环收官 (67.29% → 83.14%, +15.85pp)
- qwen3.8-max reader — 击穿 14B 系硬顶 72.7%
- P0-a 会话作用域 (QueryRouter.retrieve(scope=)) — 引擎级跨会话隔离
- P0-b 确定性时间层 (time_anchors 零 LLM 日历算术)
- R7-3 多模态证据通道 (本版核心) — 图像消息 blip_caption 附加进灌库, 910/5882 消息, 强化检索 + 修复图像承载答案题
关键改动
load_messages含图消息附加[img: caption](commit f47f37b)- 评测工程降噪: 温度 0.2→0.0, CTX_DUMP 分臂 (0c05314)
- NEG_CLEAN 断言模态极性守卫 (ee7c6b1, 默认 off)
- eval_db_p2 新评测库 (caption 数据面, blocks=393)
纪律合规
- judge 全程 qwen3-14b refined 官方规范不变 · 1382 题 · 固定灌库口径
- 全部提升来自 SHM 技术范式 (记忆表示/证据组织/检索/时间建模)
v6.15.0 R4OracleDb — 精卫循环: oracle DB 同形注入 + 数据面重建 (r1 72.43%)
SHM v6.15.0 — R4OracleDb (精卫循环 R4A)
达摩院 R4A oracle DB 同形注入 — 精卫演化循环 round2b 决策 §3 R4 行。
本次推送内容 (v6.13.0 → v6.15.0, 精卫循环 16 commits)
v6.13.0 DataPlaneRestore (R1A 评测数据面重建):
- REBUILD_SHADOW_ONLY=1 补跑 LLM 影子段 (blocks=393/entity/ontology) 落 pkl — 修复第 0 轮 65.05% pkl 缺失消融
- bge-reranker CUDA OOM 显式化; CTX_DUMP 评测 ctx 落盘
- 实测: LoCoMo-Refined 72.43% (r1, +5.14pp vs 67.29 基线)
v6.14.0/v6.14.1 R2OutputProtocol:
- R2-0: llm_generate 瞬态重试 (300/600/900s) + 预测失败落盘 + CTX_DUMP 默认开
- R2c: 输出协议 prompt v2 (日期锚/粒度/计数/范围纪律) — A/B FAIL (v6.14.1 默认翻转回 v1)
v6.15.0 R4OracleDb:
- ORACLE_INJECT DB 同形注入: evidence dia_id → 灌库 content (带 [date:] 前缀), ORACLE_MODE=db|legacy
- R4 oracle 上限复核: 300 题裁决 — 14B 证据侧饱和 (oracle = 生产 72.7%), 四层责任表完成
验证
- pytest 1195 passed (0 failed)
- R4 oracle: 297/297 = 100% DB 同形映射
精卫演化循环: 67.29 → 65.05 (消融) → 72.43 (数据面) → oracle 裁决证据饱和。目标 SOTA 82.65% 进行中。
v6.11.0 FUSION 通道深度参数化 — 修复 top-40 证据截断流失
根因: _fusion_retrieve 三通道各取 top-20, 证据 rank 21-40 候选阶段截断 (fusion hit@40=76.0% 劣于纯向量 80.4%)。
修复: fusion_*_topk 独立参数化(默认100) + bigram Jaccard 近重复去重; 级联 L1/L2/L3 零回归; 15 新回归用例, pytest 1173 passed。
验证: hitk N=300 修复后检索责任 20.3%→5.0%, hit@1 44.7%(向量 20.3%)。
配套: bench INGEST_LOADED OverGraph 直连恢复(去 pkl 依赖) + ORACLE_INJECT falsification 开关; scripts/hitk_overgraph.py 责任分层工具。
v6.10.1 CudaAccel — 本机 embedding 强制 CUDA, rebuild 提速 25x
v6.10.1 — CudaAccel
- 本机 embedding 强制 CUDA(config device: cuda),ST bge-m3 占 ~2.2G 显存
- device=cuda 时跳过 ONNX(ONNX 为 CPU 版);auto 解析回 cpu 仍走 ONNX 省显存
- 实测:rebuild 6020 节点 3 分 22 秒(ONNX CPU 84 分钟+ 未完成)
- 测试 15/15,索引 6020 全量,检索冒烟命中
v6.10.0 FullIndex — 向量索引社区节点全覆盖 + label_filter 修复
v6.10.0 — FullIndex
向量索引退化根治
根因:梦境 CommunityNode 占 94.5%(5947/6289)从不参与索引重建,仅 37 个 EpisodeNode 有 dense_vector,向量检索长期 degraded(vector_index_size=37)。叠加 OverGraph label_filter 为 AND 语义,多 label 查询恒空。
修复:
_rebuild_index_overgraph同时索引 EpisodeNode + CommunityNode(summary 为文本源)batch_upsert_embeddingslabel-aware- 主检索通道按 label 分次查询、按 score 合并去重
- Hebbian 边仍仅 Episode-Episode(语义保留)
验证:
- 回归测试
tests/test_vector_index_degradation.py5/5 - 全量 1157 passed
- 重启 rebuild:37 → 6020 节点全量入索引,检索冒烟命中 5 条
- 补 ONNX CPU 快照(EmbeddedLLM/bge-m3-onnx-o2-cpu, 2.2G)消除 CUDA OOM 隐患