14 KiB
NGRA 转型计划
面向本地 Codex / 项目维护者的快速架构说明
项目:Nitload General Regular Analyzer(NGRA)
1. 转型结论
NGRA 不再以“高性能字符串正则表达式引擎”为主要目标。
原先围绕 Span<char>、专用字符串匹配、复杂回溯、Source Generator 等方向继续投入的收益已经明显下降。后续核心工作转向:
- 以 ε-NFA / NFA 为基础执行模型;
- 将输入从
char推广为任意可比较、可判定类别的序列元素; - 面向 Token Stream、语法前端、半上下文模式分析等场景;
- 支持自动机归并、分层自动机、状态/断言/前序引用;
- 在此基础上继续研究 Weighted Automaton / NGRA-Tensor。
因此,Text Regex 从“主架构”降级为“兼容前端 / 参考实现 / 测试子系统”。
2. 当前代码处理原则
2.1 保留现有 Text Regex 半成品
当前 Text Regex Source Generator、COUNT/CONCAT/ALT lowering、生成式 matcher 等代码不删除。
原因:
- 五角星 AST 模型仍然是有效成果;
- AST 搜索、规范化、旋转、合并等代码仍可复用;
- 当前实现记录了 COUNT continuation、group boundary、rollback 等真实工程问题;
- 可作为未来自动机 IR 与旧实现行为的对照;
- 删除会丢失大量探索成果。
建议:
- 将旧生成器移动到
Legacy/Experimental/Archive目录; - 通过
.csproj的Compile Remove或独立非构建项目,使其暂时不参与主编译; - 不再优先修补完整
.NET Regex兼容性。
2.2 五角星 AST 继续保留
现有节点关系:
Parent
↑
Previous ← Node → Next
↙ ↘
Left Right
继续作为通用语法树 / 结构树基础设施。
需要坚持:
- AST 用于表达语法和结构;
- 自动机 / CFG / Relation Graph 用于表达执行与传播;
- 不再要求 AST 本身承担全部 backtracking / continuation 语义。
3. 新主线:ε-NFA
第一阶段优先实现一个简单、正确、无性能野心的 ε-NFA 模拟器。
3.1 基础状态模型
Current Active States
↓
ε-closure
↓
consume(input)
↓
Next Active States
↓
ε-closure
核心状态:
State
Transition
StartState
AcceptStates
ActiveStateSet
Transition 分为:
ε transition
matched transition
输入类型不能写死为 char。
建议:
EpsilonNfa<TInput>
或:
EpsilonNfa<TScalar>
匹配条件可以抽象为:
bool Match(in TInput input)
或者后续升级为更明确的 Predicate / Category Matcher。
3.2 第一阶段支持的 Pattern
第一版只要求:
literal / predicate
concat
alternation
*
+
?
{m,n}
ordinary grouping
暂不追求:
capture rollback
复杂 greedy / lazy 行为
lookaround
backreference
完整 .NET Regex compatibility
其中 {m,n} 可以优先在构造期展开为 NFA 结构,而不是运行时维护复杂 COUNT 控制流。
4. 为什么以 NFA 为主,而不是 DFA
DFA 仍然有价值,但不再是必须经过的阶段。
核心路线:
Pattern
↓
ε-NFA
↓
NFA execution
↓
Weighted NFA
↓
NGRA-Tensor
DFA 只作为可选 specialization:
Boolean
Static
No dynamic relation
No weighted state
满足这些条件的局部子图,可以由编译器确定化为 DFA fast path。
总体原则:
NFA 是主语义模型,DFA 是可选优化后端。
原因:
普通 NFA 的活动状态:
a_i ∈ {0,1}
加权机可自然推广为:
a_i ∈ R
Tensor 版本可以继续推广为:
a_i ∈ R^d
多状态同时活跃不再是需要“消除的非确定性”,而会成为模型本身的状态表示。
5. NGRA 的目标:广义序列分析
NGRA 不再局限于字符串。
典型输入:
char
token
syntax node
semantic node
sensor frame
event
instruction-like object
Pattern 的作用也从:
“这个字符串是不是符合 regex”
扩展为:
“这个序列在当前状态、历史、类别和上下文条件下,
是否满足某个结构化模式”
6. 半上下文 Token Analyzer
NGRA 的近期目标之一,是成为一种介于普通 Regex 与完整 Parser 之间的 Token Stream Analyzer。
可用能力包括:
Token 类别匹配
Token 属性匹配
前序状态引用
局部断言
Pattern 状态
符号绑定
分层子自动机
局部上下文
因此它适合作为:
Lexer 后端
Token Regex
语法前端
编译器预分析器
DSL Parser Frontend
结构化流分析器
“半上下文”的含义不是严格的形式语言分类,而是:
Pattern 不只依赖当前 token,也可以依赖有限的已知状态、绑定、前序结果和结构信息,但不要求一开始就构造完整通用 Parser。
7. 自动机归并
大量 Pattern 应优先在 NFA 层归并,而不是各自独立执行。
例如:
ε → Pattern A
/
GlobalStart ─ε → Pattern B
\
ε → Pattern C
Accepting State 可以附带:
PatternId
MatchKind
Payload
后续目标:
- 合并公共路径;
- 消除冗余 ε 边;
- 状态压缩;
- bitset active state;
- pattern priority;
- 多层自动机组合。
8. 分层自动机
后续重点不是继续增加字符串 Regex 特性,而是建立分层自动机。
示意:
Scalar / Token Layer
↓
Local Pattern Layer
↓
Phrase / Region Layer
↓
Sentence / Structure Layer
↓
Semantic / Relation Layer
低层自动机可以生成高层节点,高层节点继续作为新序列输入。
即:
Input Stream
↓
Automaton L0
↓
Derived Nodes
↓
Automaton L1
↓
Higher-level Nodes
这应成为 NGRA 进入编译器前端、自然语言结构分析和复杂流分析的主路径。
9. Assertion / Context 的重新定义
不再围绕字符串 Regex 的 lookahead / lookbehind 设计核心架构。
通用定义应更接近:
Assert(Context) -> bool
或者:
RelationGate(State, Context, History) -> bool
因此:
- 字符串前瞻/后顾只是特殊情况;
- 前序引用只是状态引用的一种;
- group/capture 不是核心抽象;
- Context / Binding / Region / History 才是可推广概念。
NGRA-Tensor 构想
10. 基本方向
NGRA-Tensor 不是简单地“给 NFA 边加 float”。
它希望把:
Boolean multi-state automaton
推广为:
Weighted / Tensor Relation Network
基础演化:
NFA
a_i ∈ {0,1}
↓ weighted
Weighted Automaton
a_i ∈ R
↓ tensor/state
NGRA-Tensor
a_i ∈ R^d
11. Relation 成为一等对象
不再采用固定 Port4 作为核心语义。
推荐模型:
Source Node
↓
[ Relation ]
↓
Destination Node
Relation 包含:
Source
Destination
Type
Parameters
Weight / Weight Function
Optional State
Eligibility / Gate
语义上:
Relation:
决定一条联系是否生效,
以及它如何把 Source 信息贡献给 Destination。
Node 负责保存状态。
Blend 负责汇合多条 Relation 的贡献。
12. Pull,而不是主动广播
GPU / 执行层优先采用 destination pull:
Destination Node
↓
请求自己依赖的 Relations
↓
读取 Source states
↓
Relation Eval
↓
Blend
而不是:
Source Node
↓
主动向大量 Destination 广播
优点:
- 减少 scatter;
- 减少原子写冲突;
- 减少 readiness 管理;
- 更适合 GPU destination-centric execution。
13. Relation 的三段语义
推荐拆成:
Eligibility
↓
Compatibility
↓
Transfer
即:
- Eligibility:这条 Relation 当前能不能参与;
- Compatibility:参与后有多重要;
- Transfer:真正传递什么信息。
形式上:
gate_ij = G(state, context, relation)
score_ij = F(query, key, relation)
value_ij = T(source_state, relation)
最终:
output_i = Blend(gate_ij * weight_ij * value_ij)
14. 与 Attention / QKV 的关系
QKV 可以作为 Relation 内部算子的第一种 baseline,但不应决定 NGRA-Tensor 的外层拓扑。
标准 Attention:
Q = “我需要什么”
K = “我适不适合被引用”
V = “真正传递的内容”
数学上:
score_ij = q_i · k_j
weight_ij = softmax(score_ij)
output_i = Σ weight_ij * v_j
NGRA-Tensor 的差异:
- Relation 是显式、长期存在、可带类型的;
- 候选关系通常是稀疏的;
- 不一定对全部 node 做 dense attention;
- Relation 可以有自己的参数、状态、类型和 gate;
- Attention 可以只是某种 Relation Eval backend。
15. 稀疏关系,而不是全连接爆破
Transformer 的典型关系空间:
L × L
NGRA-Tensor 的目标:
E << N²
即只计算显式 Relation。
但必须承认:
- 稀疏图带来 gather;
- 不规则访问会伤害 GPU;
- 小算子过多会降低吞吐。
因此不能简单逐 Relation 启动 kernel。
16. Relation Tile / 脑区式分块
后续 GPU backend 应研究:
Semantic Relation Graph
↓
Graph Partition
↓
Relation Tiles
↓
Block-sparse / Dense subgraph execution
目标:
块内允许不规则访问,块间尽量转成规则张量传输。
示意:
Dense / semi-dense local region
↓
少量跨区 Relation
↓
another dense / semi-dense region
类似“脑区”:
- 区内关系较密;
- 区间关系较稀;
- 每个区可以编译成中型 tensor operator;
- 跨区使用显式 Relation。
这可能成为 NGRA-Tensor 与传统 Transformer 之间的重要折中。
17. 语义稀疏 vs 物理稠密
前端语义可以是:
Sparse Relation Graph
GPU backend 可以通过:
node reorder
feature reorder
relation reorder
graph clustering
block detection
tile packing
kernel fusion
shared-memory staging
将其转为:
Dense blocks
+
Block-sparse blocks
+
Irregular sparse tails
原则:
模型的图结构不等于 GPU 必须逐边解释。
18. Node State 可以是高维 Tensor
NGRA-Tensor 不等于“每个 Node 只有一个 scalar”。
Node 可以持有:
x_i = [f0, f1, ..., fN]
但 Relation 不一定读取全部 feature。
因此可能存在两层稀疏:
Topology sparsity
Feature sparsity
Relation 可以只对特定 feature/subspace 感兴趣。
例如:
Relation A:
Q features = [1, 2, 7]
K features = [4, 8]
V features = [16, 17, 18]
语义上只取这些 feature。
物理执行时 GPU compiler 可以为了带宽一次读入更大的连续 block。
19. Tensor 观念
后续 NGRA-Tensor 设计不要把 Tensor 只理解为“算子”。
Tensor 可以同时是:
状态
参数
关系
mask
中间结果
数据集合
算子
“算子”只是某个 Tensor 在某次 contraction 中扮演的角色。
建议以“语义轴”理解 Tensor,例如:
Node × Feature
Destination × Source
Relation × Feature
Time × Node × Feature
优先思考:
- 哪些轴保留;
- 哪些轴被收缩;
- 哪些轴表示关系;
- 哪些轴表示 feature;
- 哪些轴可以 sparse;
- 哪些轴可以 dense。
20. 训练 / 运行时关系发现
NGRA-Tensor 长期设想允许结构学习。
训练阶段:
短程强关系
↓
词 / Token 局部关系
↓
词组 / 短句
↓
长句 / 语义
↓
知识网络 / 长程弱关系
运行时:
当现有网络:
NoActivePath
LowConfidence
HighAmbiguity
Unknown
可进入较慢的 Relation Discovery:
Stable Graph
↓
Unknown
↓
Candidate Relation Search
↓
Candidate Graph
↓
验证
↓
可能固化进入 Stable Graph
不建议运行时每一步都修改主图。
应区分:
Fast inference time
Slow structural learning time
近期开发优先级
Phase 1 — ε-NFA Reference Runtime
实现:
EpsilonNfa<TInput>
StateId
Transition
ε-closure
Consume
Accept
目标:
- 语义简单;
- 正确性优先;
- 不做复杂性能优化;
- 不绑定
char。
Phase 2 — Pattern → NFA Lowering
从现有 AST / Pattern IR 构造 NFA:
literal
predicate
concat
alt
repeat
Phase 3 — NFA Merge
实现:
multi-pattern merge
PatternId
shared start
accept payload
然后测试大量 Pattern 同时运行。
Phase 4 — Token Stream
将输入切换到:
Token
支持:
Token kind
Token value
Token metadata
simple binding
context predicate
目标:作为编译器前端 / Token Regex 原型。
Phase 5 — Hierarchical Automata
允许低层自动机输出高层节点,并再次进入更高层自动机。
Phase 6 — Weighted Automaton
将:
active : bool
推广为:
activation : float
先不要急于引入复杂 Tensor。
Phase 7 — NGRA-Tensor Prototype
研究:
Node state tensor
Typed Relation
Eligibility
Compatibility
Transfer
Blend
Sparse / block-sparse execution
QKV/Attention 可作为 baseline Relation operator。
非目标
近期不要优先投入:
完整 .NET Regex 兼容
极端 Span<char> 优化
复杂 Source Generator matcher
完整 capture rollback
所有 lookaround/backreference
为了 Regex 完整性设计核心 IR
这些功能如确实需要,可以:
System.Text.RegularExpressions
作为字符串兼容层。
这不是架构退让,而是目标调整。
一句话定位
NGRA 的新定位:
以 NFA 为基础的广义序列模式与分层自动机框架,并逐步推广到加权 Relation Network 与 NGRA-Tensor。
Text Regex:
一个兼容前端 / 参考实现,不再定义 NGRA 的核心架构。
NGRA-Tensor:
把 Boolean NFA 的多状态传播推广为显式、稀疏、可加权、可训练、可分块执行的 Relation Network。