Files
digital-drosophila/docs/progress/phase4ag-design-and-limits.md
2026-09-30 09:26:21 +08:00

92 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Phase 4AG:设计、证据范围与限制
本文是独立于已登记模型和实验文件的解释性文档,不是预注册协议的修订,也不是最终实验报告。状态快照日期:2026-09-30。
在本说明对应的检查节点,r2 的 8 个固定小型测试场景已完成每场景 3 次 GPU 运行及 1 次 Brian 对照,数值门禁通过;两个预先指定的全图 100 ms Brian 对照也已通过。后续 60 次 CAL 基础运行和 12 次重复检查仍在进行中。本文不宣布 CAL 通过或失败,更不宣布学习成功。正式状态应以各阶段原始审计记录及最终封存报告为准。
## 本阶段到底测试什么
Phase 4AG 测试一个明确的新组合:在 MaleCNS 原有全图上,将已经核对过作者语义的 float64 LIF 动力学,与项目旧版 float32 graded APL 模块连接起来,先检查实现是否符合声明,再检查固定旧 CAL 输入下的嗅觉表征是否满足完整原门槛。
全图仍为 166,700 个神经元、25,582,938 条规范化有向边。原始连接计数、递质符号、W_syn、旧 APL 参数以及 eligibility-v2 的 14,232 边掩码不修改。本阶段不训练,不搜索增益、阈值、刺激强度或时间窗,不新增连接,不做行为、奖励或游戏演示。
作者语义来源是已归档的 Shiu 等人代码,而不是重新选取的最新版本:GitHub commit `91bdd1e7dcf193f3e7ca5a8933497fcef63b7960`,归档 `model.py` 的 SHA-256 为 `fc45837d7122c6ce2a7f3f2f23c515992e4b232aadb919efabb72337fac88e4e`。[固定提交的作者代码](https://github.com/philshiu/Drosophila_brain_model/blob/91bdd1e7dcf193f3e7ca5a8933497fcef63b7960/model.py) 对应 Shiu 等人的论文 [A Drosophila computational brain model reveals sensorimotor processing](https://www.nature.com/articles/s41586-024-07763-9)(Nature,2024)。本项目使用不同的连接组及额外的旧 APL 工程模块,因此不能称为该论文或作者完整模型的严格复现。
## 混合精度与每一步的明确顺序
LIF 的 `v`、`g` 和解剖边权使用 float64、SI 伏特;这里的 `g` 是作者方程中以伏特表示的状态量,不应仅凭变量名解释成电导。LIF 核心复用已封存的 CUDA 运算,不修改数学语义。固定步长为 0.1 ms,解剖传递延迟为 18 步,不应期为 22 步。
APL 则保留旧环境中的 float32 矩阵、状态和运算序列。输入矩阵始终是 `2 × 166700`,输出矩阵始终是 `2 × 4064`;即使测试小型诱导子图,也不裁剪矩阵或重算归一化。每次独立运行从零 APL 状态开始。APL 输入是本步实际产生的二值放电,而不是外部请求:被不应期拒绝的请求不能被当作放电反馈。
每步先完成 LIF 核心、请求处理、真实延迟到达和复位的声明调度,再在 `end` 执行旧 APL。APL 衰减与增加保持分开的 eager 操作:
```text
s32.mul_(float(float32(exp(-0.1 / 20.0))))
drive32 = torch.mv(I32, actual_spikes32)
s32.add_(drive32)
h32 = torch.matmul(s32, O32) * float32(0.01)
delta64 = h32.to(float64) * float64(0.001)
g64[KC] = g64[KC] - delta64
```
其中 `h32` 沿用旧模块的 mV 语义。必须先拓宽为 float64,再乘 0.001 转成伏特,最后单独减去;不能先在 float32 中乘 0.001,也不能将 `mul_`、`add_` 或最后的转换与减法融合成另一条运算路径。tau=20 ms、gain=0.01、normalization=1 均不调整,也不额外加入 APL 延迟、裁剪或 `dt/tau` 缩放。
APL 不改变原环境的默认 TF32/矩阵乘精度/CuBLAS 设置,而是记录实际设置、版本和设备,并核对组件输出。保留“数学上等价”的表达式并不足以保证逐位相同;PyTorch 官方说明明确指出,浮点运算顺序、后端和版本都可能影响结果。[PyTorch 数值精度说明](https://docs.pytorch.org/docs/2.14/notes/numerical_accuracy.html)、[可复现性说明](https://docs.pytorch.org/docs/2.14/notes/randomness.html) 在此用于解释工程风险,不作为改变冻结环境的理由;文档不能替代实验记录中的实际安装版本和设备信息。
## 不应期中的 APL 写入是被检验的假设
本组合在复位后的 `end` 阶段,无条件向所有对应 KC 的 `g` 写入 APL 抑制,包括刚放电或仍处于不应期的 KC。这里没有补加 `ref == 0` 条件。
这必须与作者核心的普通解剖输入区分:作者方程中带有 `unless refractory` 的状态在不应期冻结,普通突触更新受相应保护;本分支的 APL 是显式的末尾直接状态写入,不是把它伪装成普通受保护突触。[Brian 2.5.1 不应期文档](https://brian2.readthedocs.io/en/2.5.1/user/refractoriness.html) 解释了不应期和状态冻结的区别;具体执行依据仍是已归档作者代码及本项目保存的实际生成代码。
由这套代码顺序可以推得:APL 写入的负 `g` 可能在不应期内继续累积,而该期间作者核心不会按通常的 `g` 方程衰减它。这个组合效应是此次被检验的显式工程假设,不是已确认的生理机制,也不是作者原模型的主张。若改成不应期屏蔽、写入后再次清零或更换写入阶段,就已经是另一项假设,不能作为此次结果不好时的即时“修复”。
## 5,845 条 fast APL 掩码及 1,212 条未替换边
旧 APL 模块的兼容规则是:将全部 5,845 条原始 APL fast 出边的有效权重置零,然后仅向 KC 提供 graded 替代。置零只发生在新运行时的内存副本中;磁盘上的原始图、计数、符号和基础权重不改写,边身份也不删除。
其中 1,212 条出边的目标不是 KC,因此其 fast 作用被关闭后,没有获得本模块的 graded 替代。这是已知且保留的覆盖缺口。不能把该组合描述成“所有 APL 输出均被等价替换”,也不能为了得到更好的结果悄悄恢复这些边或新增非 KC 的 graded 通路。这两个数字描述的是本项目图中的有向边计数,不是新增的生物学结论。
## 三类数值证据分别能说明什么
| 检查 | 能支持的结论 | 不能支持的结论 |
| --- | --- | --- |
| Brian 闭环对照 | Brian 自己推进 LIF、产生实际放电,独立进程中的 APL 状态据此更新;与 GPU 比较逐步状态、事件、请求、队列顺序与接受掩码、APL drive/state/h | APL 算法本身完全独立实现,或所有输入下的普遍等价 |
| 原代码 AST 影子重放 | 从冻结旧初始化代码重建矩阵,并提取旧更新语句;用已记录的真实放电重放,检查组件字节是否保持一致 | 新的独立全脑闭环证明,或摆脱共同 Torch/CUDA 底层原语的验证 |
| float64 算术测量与误差界 | 在明确的非负矩阵、正常有限运算等前提下,量化 float32 组件相对独立 float64 测量的偏差,检查预先定义的误差界 | 用 float64 替换 APL、事后放宽容差,或用误差界替代逐位旧组件一致性 |
Brian 的 APL worker 不接收候选 GPU 的抑制轨迹,而只接收 Brian 自己产生的实际放电;它有独立的零初始状态,并通过握手核对矩阵哈希与运行环境。但候选与 worker 共享 APL 组件实现,所以准确名称是“共享 APL 组件的闭环 Brian 对照”,不能写成“全部组件独立的 CPU oracle”。
AST 影子又提供一层不同的代码来源检查,但仍使用相同的 Torch/CUDA 原语。float64 测量不反馈到任一脑模型,其误差界不根据观测误差拟合。各证据应并列阅读,不能互相替代。
8 个固定小型场景检验零输入、真实 PN/KC 输入、不应期边界、自然放电与请求重合、延迟到达、APL mask 和高 fan-in 等情形;每场景 3 次 GPU 运行检查精确重复。两个全图 probe 是预先指定的第一个旧 CAL 气味、首个原始 seed、两种编码模式,各 100 ms。通过这些检查只说明已测试场景符合本组合的声明,不证明所有气味、时间尺度或后续学习任务都有效。同步、IPC、逐步哈希和诊断保存的耗时也不是性能基准。
## CAL 必须通过完整原 4L 门槛
CAL 设计固定为原 6 个校准气味 × 5 个原始 seed(51101–51105)× 2 种模式(`physiological`、`matched_energy`),共 60 次基础运行,每次 100 ms;每个气味/模式的首个 seed 再运行一次,共 12 次重复。它们不是额外的训练 seed。
输入在任何轨迹运行前保存,保留旧 PN 编码、目标/随机数列顺序。matched-energy 的参考值仍取原冻结 12 气味 panel 的中位数,不能换成 6 CAL 的中位数,也不能换成后续其他 panel。读取这份静态参考数据不等于读取 heldout 动态结果。
每种模式都必须同时满足以下原始条件,两种模式都通过才满足表征门槛:
- KC 活跃比例的平均值在闭区间 3%–9%。
- 单次运行的最小活跃比例严格大于 0,最大值严格小于 50%。
- 同气味跨 seed 的平均活跃集 Jaccard,严格大于不同气味同 seed 的平均 Jaccard。
- 不同气味同 seed 的平均欧氏距离,严格大于同气味跨 seed 的平均欧氏距离。
- 至少 3 对气味通过成对分离检查:该对气味在相同 seed 下的 5 个距离均值,严格大于这两个气味各自全部 10 个跨 seed 距离合并后的 20 项均值。
距离来自原始 KC spike-count 向量,欧氏距离先转 float64,不另做向量归一化;Jaccard 使用是否放电的布尔活跃集。6 CAL 每种模式有 15 对气味、60 项 within 距离和 75 项 between 距离。成对比较的基线不是全部气味混在一起的平均 within 距离;只检查平均稀疏率与“至少 3 对”的旧简化 `r4` 不能代替完整原 4L 门槛。
本阶段另加输出完整性、有限值和 12 次精确重复要求;缺失文件、失败运行、NaN 或全静默都不能当成通过。原 4L 虽记录 finite,但没有将它写进原最终 gate,因此这里应明确称为新增的完整性前置检查,而非改写历史。
即使最终 CAL 通过,含义也仅限于这组固定校准输入下的表征检查。它不等于 heldout 泛化、刺激特异性信用分配、记忆、条件化或可用学习;本阶段没有训练或生成新的候选模型结论。后续学习验证仍需在授权范围内另行登记并通过专门门槛,不能由本阶段的数值一致性推导出来。
## 为什么保留 v1,并单独运行 r2
第一次登记的 v1 在启动 APL worker 时,对科学虚拟环境的 Python 路径调用了 `resolve()`,跟随符号链接到了系统解释器,丢失预期包环境。异常发生在首个 Brian tick 之前,错误记录的 `last_complete_tick` 为 -1;v1 已保留源代码、部分输出和故障记录,并以 `INCOMPLETE-NUMERICAL-EXECUTION` 封存。
这不是已观测到的动力学或科学假设失败,也不能反过来称作数值通过。r2 使用新模型目录 `author-apl-lab-v2` 和新实验目录 `phase4ag-author-apl-r2`,保留虚拟环境的调用入口路径,只修执行入口及相应记录/检查,不更改方程、运算精度、掩码、刺激、门槛、参数或测试选择。全部声明流程从新状态重跑,不覆盖或挑选性省略 v1 的记录。
本文所述已通过的 r2 数值门禁与仍在进行的 CAL 是两件事。是否完成、是否通过,以及允许得出的结论,最终都必须回到对应原始证据和封存状态,而不是依据本解释文档升级。