Files
stgsharp/src/Nitload.RegularAnalysis/NGRA_TENSOR_MEMORY.md
T
2026-09-18 18:28:09 +08:00

20 KiB
Raw Blame History

NGRA-Tensor 设计讨论记忆

更新日期:2026-09-18
目标项目:D:\platform-dev\src\Nitload.RegularAnalysis
来源:关于正则分析、NFA、Transformer、GPU 执行与 NGRA 双算子设计的讨论。

本文件记录设计意图与讨论结果,不代表项目现有代码已经实现这些功能。本次仅检查了目标目录及祖先目录的 AGENTS.md,没有审计源码。下文区分用户已提出的设计决定、辅助建议与待验证问题。

最新设计补充(2026-09-18,详见第 10 节):NGRA 使用持久状态上的增量流输入/输出;以连接占用作为主要容量指标的候选方案;容量不足时丢弃低激活连接。字典本身是结构的一部分,结构是记忆的一部分。 字典与运行时实例的区分属于身份与生命周期管理,不表示字典位于记忆系统之外。

1. 项目目标与讨论方式

NGRA-Tensor 试图结合结构化关系、模糊特征识别、多候选解释及模式预测。出发点包含正则模式分析与 NFA,但不应预设必须逐节点模拟 NFA 的执行方式。

核心工程矛盾:细粒度、动态、自组织的关系网络表达灵活,却容易产生大量小操作、串行依赖、零碎访存和复杂调度,影响 GPU 利用率与训练。

用户希望学习“如何构造能运行且高效的系统”,而不只是阅读既有模型的前向公式或事后解释。后续讨论应说明:需求 → 设计选择 → 数学表达 → 执行方式 → 代价 → 验证方法。不要用 Transformer 也存在串行步骤,来回避 NGRA 的节点过小与调度问题。

“Tr”在不影响理解时作为 Transformer 的简称。

2. 数学符号约定

符号 含义
Scal 标量
Vec_d d 维向量,本文使用列形式表示分量
Covec_d 对向量进行线性求值的余向量
Mat_x_y 每行 x 个元素、每列 y 个元素,即 y 行、x 列;列数在前
Tens_u_v 接收 u 个 Vec 和 v 个 Covec、输出 Scal 的多重线性对象

注意:

  • 数组的存储维数不等于 Tens_u_v 的槽位数。ONNX 等工具中的 tensor 通常只是多维数组的名称。
  • 线性映射 L 可通过 T(x, φ) = φ(Lx) 对应 Tens_1_1;输入向量与输出余向量可以属于不同维度的空间。
  • 点积所对应的度量可视为 Tens_2_0。将向量与余向量识别需要相应的度量约定,不能只凭行列形状混为一谈。
  • 带偏置映射一般为仿射映射;softmax、ReLU、LayerNorm 等不是多重线性运算。完整神经网络不能直接按上述定义称为一个 Tens_u_v。

3. 用户已提出的核心架构决定

3.1 两种组合算子

relation:评估一定数量的 notation 按顺序串接形成的关系。

R = Relation(N1, N2, ..., Np)

port 表达有序关系,交换 port 输入通常会改变含义。此前使用过 R_6 表示 64 口 relation 的约定;64 指串行关系中的输入数量,不是特征向量维数。早期等级与端口数使用过 2^L 的联系,但它与新架构传播层级的准确对应仍须正式定义。

notation(亦讨论为 idea):组织若干并列 relation。

N = Notation{R1, R2, ..., Rk}

这为多种可能结构提供显式位置,避免把并列候选强行塞进 relation 的串行 port。

  • 两者底层数据结构可以形态一致,但必须保留类型及不同的运算语义。
  • 并列候选不自动等于语义独立,也不自动等于互斥。互斥解释与可以同时成立的特征,需要不同的组合规则。
  • 候选评估、候选权重、候选混合是可区分的操作;不必一生成候选就压成一个 Vec。

3.2 双向分层与反复传播

用户提出的方向:

relation 方向:L0 → L1 → ... → L6
notation 方向:N6 → N5 → ... → N0
一次推理可能经历多轮上述传播。

这是当前设计意图,尚不是完整的状态更新规范。L/N 等级的含义、跨级连接是否合法、上下两个方向如何连接,都需要进一步明确。

讨论中提出的一种解释(待落实):

  • 上行:由局部证据评估更大的组合与解释。
  • 下行:较高层的解释、约束和关注影响局部候选的保留与活跃程度。
  • notation 的候选评估仍须汇集,才能为高层提供依据;“notation 向下传播”不能遗漏候选证据如何上传。
  • 区分来自输入的证据与来自上层的反馈,防止反馈被反复当成独立证据累加,产生自我强化。

3.3 统一机器字典与索引空间

用户决定让 token、relation、notation 位于同一个字典和索引空间。“字”本身也是一种原子理念。

  • token 使用预存字典提供初始表示。
  • relation、notation 的实例“词义”通过节点计算特征向量得到。
  • 字典可以保存结构定义、参数及引用;运行时计算得到本次语境中的实例特征。
  • 预存 token 特征不必永久固定为运行时最终特征,可以接受上下文更新。

建议明确区分两层身份:

层面 内容
字典条目 token/关系/概念的定义、类型、结构与参数
运行时实例 引用哪个条目、出现在何处、连接哪些实例、本轮状态与得分

同一个字在文本中出现两次,可以共享字典 ID,但不能因此共享同一份位置相关状态。可采用“实例 ID + 字典引用”的实现,不要求推翻统一字典。

4. 每轮输出:面向下一轮的规范形

用户提出:一次“小 node → 大 node → 小 node”的传播后,输出一种较工整、供下一轮继续处理的状态。

示例:

输入:吃饭了吗,您?
初步规范表达:我,提问,你,吃饭,状态

各状态同时具有特征向量,用于表达语气等细节。

这里建议把“规范形”理解为结构统一的语义中间表示,暂不要求第一轮得到唯一、最终正确的解释。

4.1 必须保留角色绑定

仅有上述扁平序列,不能明确区分“我问你是否吃饭”和“我问你我是否吃饭”。一个可参考的结构为:

提问
├─ 发起者:当前说话者(来自会话上下文)
├─ 接收者:您所指的人
└─ 内容:进食事件是否已经发生
   ├─ 行为者:您所指的人
   ├─ 行为:吃饭
   └─ 发生状态:待确认

这是讨论中的建议示例,不是已决定的 IR 格式。

  • “我”没有直接出现在原句,应记录其上下文来源。
  • 被询问的事件状态不能在规范化时变成已成立的事实。
  • 敬称、语气等细节可通过特征表示;关键角色关系应有明确结构。
  • 返回小节点时,单位可以是实体引用、行为、状态变量或关系实例,不必恢复成原始字符。

4.2 保留候选与来源

“询问进食情况”和“以此寒暄”可能是候选解释,也可能兼有。notation 应能保留候选身份、得分与结构,而不是强制提前选唯一结果。

建议保留输入片段或上下文依据,区分:显式内容、上下文补足、模型推断、待确认状态。

4.3 轮次与稳定性

可用以下关系描述一次传播,但具体更新函数尚未确定:

S(t) → 组合与解释评估 → H(t) → 角色绑定、反馈与整理 → S(t+1)

建议每轮读取上一轮状态并集中形成下一轮状态,避免执行顺序无意改变语义。最终应定义最大轮数、变化阈值或其他停止条件。

期望已稳定的表示在没有新证据时满足 F(S*) ≈ S*;这只是验证目标,不代表目前已证明收敛。

5. 构建、剪枝与训练:尚未完成的设计

用户明确指出,当前“葫芦形”传播还不够明确,需要剪枝和额外构建规则。

优先需要确定:

  1. relation 各 port 的角色、输入类型、顺序与允许的连接范围。
  2. notation 中哪些候选回答同一个解释问题,是否覆盖相同区间或具有相容的输出类型。
  3. 候选是互斥、可并存还是具有其他依赖;采用何种打分与归一化。
  4. 构建网络、选择路径与更新特征,哪些是离散决策,哪些可微、哪些需要额外训练机制。
  5. 如何限制候选数量,并测量剪枝造成的正确解释丢失。
  6. 如何防止重复证据、自我支持、循环振荡及无上限的关系扩张。
  7. 如何保留原始词序、实体身份、否定、疑问、范围及来源。

简单 regex/NFA 的布尔关系可以用向量、矩阵及相应的逻辑运算表达;转成浮点矩阵后,必须重新定义多路径的组合含义。布尔可达性、概率、模糊兼容度与特征混合不可直接互换。

目前没有得到“任意一组 NFA 能以常数总计算量执行”的结论。并行深度、总工作量、状态规模和存储量必须分别分析。

6. GPU 执行路线

6.1 语义粒度与执行粒度分离

讨论中形成的总体判断:

  • 常规稠密 Tr 从规则的大计算出发,再为硬件分块、融合与安排数据复用。
  • NGRA 从细粒度的关系与候选出发,再把已经就绪、形状相容的操作合并为批次。

不必让每个小 relation 对应一次 GPU 调用,也不必为批处理把语义上的多个 relation 合并成一个大 relation。

方法 收益与限制
批处理独立实例 可保持实例语义,同时提高单次执行规模
融合有依赖的操作 可减少启动及中间搬运;不会自动消除数据依赖
按层级、轮次、形状分组 可以简化调度;具体规则尚待验证
稳定的数据布局与参数分组 有机会提高复用并减少碎片化读取

早期低阶、小 port 关系的串行活动密集,是重点瓶颈。把 L0/L1 放在 CPU、把短模式预筛编译成矩阵运算等,均只是候选方向,尚未通过基准测试决定。

6.2 按需加载模型内容

用户提出的潜在优势:根据激活情况,只加载本次需要的 relation/notation 参数,降低显存工作集。

成立条件与待验证因素:

  • 用廉价、常驻的索引或路由信息判断加载对象,避免必须先读完完整参数才能决定不用它。
  • 测量当前活跃集合、跨轮复用、加载粒度、预取能力及批次内激活集合的并集。
  • 同时核算参数、活跃状态、候选记录、运行缓冲与传输缓冲。
  • 省显存不自动等于提速;零碎且依赖刚完成计算的加载可能使 GPU 等待。
  • 区分 GPU 内部缓存未命中与数据不驻留显存、需要从主存迁入。

Tr 也能参数卸载、逐层加载或使用 MoE,故不能把“必须所有权重常驻显存”当作 Tr 的数学要求。NGRA 的优势仍需在质量相当时实测。

7. Tr 对照:已经澄清的关键概念

7.1 block、上下文与执行分块不是一回事

  • Tr block 通常指深度方向的一层计算,不是固定 4096 口的文本单元。
  • 4096 是本讨论的示例长度,也可能是某个模型的上下文配置;不是 Tr 固有 I/O 宽度。
  • 同一层的投影权重作用于特征轴,通常不含序列长度 n 这个参数维度。
  • 支持长上下文还涉及位置机制、训练与资源,不能据此宣称任意短上下文模型可直接可靠处理 1M。
  • 彼此隔离的文本窗口不会自动互通。共享模型权重不等于保留上一段输入。

7.2 输入与输出

以 512 维、8 个头、每头 64 维的示例来说:

X: Mat_n_512 → 一个完整 Tr block → Y: Mat_n_512

每个输出列仍对应一个位置,但携带上下文整合后的特征。输出通常不是显式 relation 表,也不是 vocabulary 概率。只有第一层直接接收 embedding 与初始位置表示,后续层接收前层输出。

token embedding 提供初始向量,不能把后续位置向量理解成始终只有原始 token 的静态词义。

7.3 本文列向量约定下的主要运算

运算 形状或说明
Q = WQ X, K = WK X, V = WV X W 为 Mat_512_64;Q/K/V 为 Mat_n_64
S = QᵀK / sqrt(64) + M Mat_n_n;行是查询,列是候选
A = softmax_rows(S) 对每个查询的允许候选统一归一化
H = V Aᵀ Mat_n_64,按位置混合内容
8 个 H 沿特征轴拼接 Mat_n_512
输出投影、残差、Norm、FFN、残差、Norm 最终仍为 Mat_n_512;此顺序是原论文 post-norm 示例

参数 WQ/WK/WV 通常分层、分头拥有,并在所有位置复用。ONNX 的图级 initializer 存储位置不代表各层共享同一组参数。Q/K/V/A 是本次输入产生的中间结果,不是查表得到的固定权重。

7.4 混合不等于重排

  • W X:特征投影,不移动 token 列。
  • V Aᵀ:根据输入计算权重,允许多个输出读取同一来源。
  • X Π:用置换矩阵重排位置。
  • 标准注意力不默认执行“聚类相关 token → 打包 → 分组路由”。若需要这种行为,须明确设计路由过程。
  • 两个局部组的输出可以按 [B00h B01h]、[B00l B01l] 重组后交给下一层。若 h/l 表示 token 子集,这属于改变窗口分组;若表示特征通道子集,则是另一种操作。
  • 重组本身不做语义融合,下游计算才融合;需要保留位置身份与因果约束。

7.5 1M 上下文与跨计算块通信

全局注意力可以逻辑上覆盖整个上下文,执行时按块读取 K/V。对于两个分块 A/B,跨块关系直接来自 QAᵀ KB 与 QBᵀ KA;因果掩码限制允许的方向。

一次处理 4096 个查询,不代表这些查询只能访问 4096 个候选。它们可以分批访问全部允许的 K/V,并维护统一的 softmax 累加状态。

不能对各候选块独立 softmax 后简单平均。FlashAttention 使用分块与在线归一化执行精确注意力;跨设备方案如 Ring Attention 可以传递 K/V 块完成跨分片交互。

这不要求先分配完整的巨大注意力矩阵再把它切开。

7.6 成本与能力边界

  • 全局注意力的配对计算为 O(n²d);序列长度翻倍,该部分工作量约四倍,不代表端到端推理时间必然四倍。
  • 固定窗口宽度 w 的局部注意力为 O(nwd);固定层数的间接信息覆盖范围有限。
  • 使用 KV cache 生成一个新 token 时,该 token 对历史的注意力计算随历史长度线性增长,而非重新计算完整历史的所有配对。
  • KV cache 不会自动把上下文容量变成无限,且需要区分缓存、压缩记忆与原始历史可访问性。
  • 普通前馈网络与关闭随机操作的 Tr 都可确定性执行。“DNN”通常表示深度神经网络,不能用来与 Tr 作“确定/非确定”分类。
  • 普通网络通常训练权重与偏置,而非修改固定 ReLU 等激活函数本身。
  • 注意力混合不自动保留完整候选结构,也不等于显式逻辑关系或可解释的置信度。

8. 下一阶段建议产物(尚未执行)

  1. 明确统一字典条目与运行时实例的最小 schema。
  2. 明确 relation/notation 的输入输出类型、候选组合与角色绑定规则。
  3. 写出一个完整传播轮次的状态读取、写入与反馈语义。
  4. 用“吃饭了吗,您?”制作可逐节点检查的示例,包括歧义保留与下一轮稳定性。
  5. 定义候选数量上限、剪枝指标、最大轮数与停止条件。
  6. 先建立语义正确的参考执行,再比较逐节点、批处理、融合和按需加载的性能。
  7. 训练目标、路由学习方式、收敛性质以及相对 Tr 的性能优势均保持待验证状态。

9. 讨论中核对过的参考资料

上述资料作为对照,不意味着 NGRA 已被证明等价于其中某种架构。

10. 2026-09-18:持久结构、增量流与连接容量

10.1 用户明确提出的设计方向

  • 从正则引擎的流式增量输入思路演进:输入、输出都在上一次运行结果所保留的状态上继续进行。
  • 不以每次重新输入完整历史文本作为基本执行语义;历史对当前的影响由已保留的结构及其状态承接。
  • 容量很可能按连接数量或连接占用评估,而不是按 token 数量评估;具体度量尚未定稿。
  • 容量不足时,通过丢弃低激活连接释放容量。这是已提出的方向,评分、阈值、删除语义与正确性规则尚未确定。
  • 字典本身也是结构,结构本身也是记忆。记忆不只包含特征向量数值,还包括对象身份、连接、组合方式、候选与参数化定义。

10.2 建议的抽象接口(非已实现 API)

(S[t+1], ΔO[t]) = Step(S[t], ΔI[t])
  • S[t]:上次保留的结构、字典相关状态、实例特征、候选、待执行依赖及流位置等。
  • ΔI[t]:新增输入;是否包含撤回、修改和外部反馈,需进一步定义。
  • ΔO[t]:本次新增输出;若允许修订先前解释,需要明确输出更新或撤回协议。
  • S[t+1]:完成必要传播与容量管理后保留的状态。

输入流步 t 与一次输入触发的内部上下传播轮次应分开编号;一次增量输入可能触发多轮关系更新。

10.3 增量失效规则

Roslyn 增量管线与因果 Tr 的缓存复用提供了讨论类比:依赖没有改变的结果可以复用。但 NGRA 必须按自己的依赖图定义失效,而不能只检查原始文字是否变化。

  • 下游输入、上层反馈、候选集合、相关字典结构或参数的变化,都可能使实例状态失效。
  • 新输入可能激活此前尚未选择的连接,因此只记录已经活跃的依赖可能不够;候选发现与再激活机制待设计。
  • 双向反馈可以扩大受影响区域,增量输入不保证只需要少量增量计算。
  • 纯函数结果复用、依赖版本与参数版本是实现候选,不是目前已经确定的数据结构。

10.4 连接预算与遗忘:需要进一步决定的内容

  1. 预算计算活跃连接、全部保留连接、驻留显存的连接,还是三者分别统计?
  2. 不同连接携带的特征、参数、元数据大小可能不同;是否采用连接数量加权或真实字节数作为物理预算?
  3. “丢弃”表示暂停执行、移出显存、删除当前实例边,还是删除可持久化的字典结构?这些行为对记忆的影响不同。
  4. 当前激活低不必然意味着未来无用或结构可删除;角色绑定、串行 port、待完成模式等所需连接应有明确的完整性规则。
  5. 连接移除后,哪些实例需要重新评估?候选如何重新发现?还保留哪些历史依据?
  6. 遗忘顺序不必等同于时间顺序;连接重要性的估计方法和低激活持续时间阈值尚待实验。

这些是辅助建议与待决问题,不覆盖用户已提出的“容量不足时优先丢弃低激活连接”方向。

10.5 容量与智能的关系:待验证假设

用户提出“越智能的模型可能上下文更快耗尽”:在相同连接预算下,若模型为同一输入识别并保留更多关系、候选和依赖,容量可能更快用尽。

这不是已证明的必然关系。更好的抽象、共享、合并与剪枝也可能降低连接需求。后续应测量单位输入的新增连接、保留连接、复用率、候选召回与任务质量,而不是直接把智能程度等同于连接消耗。

补充参考:Roslyn Incremental Generators Cookbook。该资料只支持增量管线类比,不证明 NGRA 的依赖追踪或遗忘方案正确。