docs: add tensor-parser-network.md - human-readable tensor debugging tool
- Tensor Parser Network converts standard tensors to human-readable text - Not a runtime component; purely a training/debugging/verification tool - Dedicated parsers for each tensor type (ref, memory, reasoning, expression, control) - Three data generation methods: from subnet training, synthetic via LLM, end-to-end collection - MVP approach: rule-based template parser (zero training, usable immediately) - Iterative roadmap: rules → learned parsers → unified LLM-based generator - Training dataset construction, evaluation metrics, and usage scenarios
This commit is contained in:
404
docs/tensor-parser-network.md
Normal file
404
docs/tensor-parser-network.md
Normal file
@ -0,0 +1,404 @@
|
||||
# 张量解析网络 (Tensor Parser Network)
|
||||
|
||||
## 为什么需要张量解析网络
|
||||
|
||||
NextAgent 的所有子网间通过**标准张量协议**通信。这些张量是高维数值结构(向量、特征图、注意力权重),对人类来说完全是黑箱。
|
||||
|
||||
### 调试黑箱问题
|
||||
|
||||
```
|
||||
手动验证子网输出时:
|
||||
|
||||
┌────────────┐ ┌──────────────┐
|
||||
│ 路由子网输出 │ ───→ 张量 [0.12, │
|
||||
│ 标准张量 │ -0.34, 0.67, │
|
||||
│ │ 0.01, ...] │ ← 完全看不懂
|
||||
└────────────┘ └──────────────┘
|
||||
人类:???
|
||||
```
|
||||
|
||||
### 张量解析网络的定位
|
||||
|
||||
**张量解析网络不是运行时组件**——它不参与任何子网的推理流程。它是一个**训练/调试/验证工具**,在整个训练流程中充当"可读性桥接层":
|
||||
|
||||
```
|
||||
训练时:
|
||||
┌──────────┐ 标准张量 ┌──────────────────┐ 人类可读文本
|
||||
│ 子网输出 │ ───────→ │ 张量解析网络 │ ──────────→ 人类验证
|
||||
└──────────┘ │ (调试模式) │
|
||||
└──────────────────┘
|
||||
|
||||
运行时(不参与):
|
||||
┌──────────┐ 标准张量 ┌──────────┐ 标准张量 ┌──────────┐
|
||||
│ 路由子网 │ ───────→ │ Core │ ───────→ │ 推理子网 │
|
||||
└──────────┘ └──────────┘ └──────────┘
|
||||
↑
|
||||
张量解析网络不在此路径中
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 核心设计
|
||||
|
||||
### 解析目标
|
||||
|
||||
| 张量类型 | 输入 | 人类可读输出 |
|
||||
|----------|------|-------------|
|
||||
| `ref_tensor` | 路由子网的压缩特征向量 | "用户输入了一张北京故宫的照片,标签: ['建筑', '故宫', '北京'],置信度: 0.92" |
|
||||
| `memory_result` | 记忆子网的检索结果 | "找到 3 条相关记忆: (1) 用户上次去北京是 2025年3月, (2) 用户偏好空气质量信息, (3) 用户关注pm2.5指数" |
|
||||
| `reasoning_path` | 推理路径与验证结果 | "推理链: 步骤1(提取实体)→步骤2(查天气数据)→步骤3(推理结论: 北京今天晴, 22°C), 置信度: 0.95, 已验证: true" |
|
||||
| `expression_verify` | LLM 表达验证张量 | "表达验证: 语义对齐度 0.96, 情感正向, 关键实体保留: [天气,北京,今天], 遗漏检测: 无" |
|
||||
| `memory_update` | 记忆更新信息 | "新信息: {实体: [用户_张三], 关系: [HAS_PERSONA 喜欢_摇滚], 置信度: 0.9}" |
|
||||
| `control` | 控制信号 | "控制信号: Core→路由子网, 类型: [从滑动窗口提取详细信息], 参数: {depth: 2}" |
|
||||
|
||||
### 输入/输出
|
||||
|
||||
| 项目 | 说明 |
|
||||
|------|------|
|
||||
| **输入** | 标准张量(任意类型) |
|
||||
| **输出** | 结构化人类可读文本(Markdown / JSON / 自然语言) |
|
||||
| **不参与运行时** | 纯训练/调试工具,不加入推理链路 |
|
||||
| **延迟要求** | 无(仅离线使用) |
|
||||
|
||||
---
|
||||
|
||||
## 网络架构
|
||||
|
||||
### 架构总览
|
||||
|
||||
```
|
||||
标准张量 (任意类型)
|
||||
│
|
||||
▼
|
||||
┌──────────────────────────────────────────────┐
|
||||
│ 张量解析网络 (Tensor Parser) │
|
||||
│ │
|
||||
│ ┌──────────────────────────────────────────┐│
|
||||
│ │ 张量类型分类器 (Tensor Type Classifier) ││
|
||||
│ │ 识别张量类型 → 路由到对应解析器 ││
|
||||
│ │ 输出: ref / memory_result / reasoning / ││
|
||||
│ │ expression / update / control ││
|
||||
│ └──────────────────┬───────────────────────┘│
|
||||
│ │ │
|
||||
│ ┌────────────────┼────────────────────┐ │
|
||||
│ │ │ │ │
|
||||
│ ▼ ▼ ▼ │
|
||||
│ ┌────────┐ ┌────────────┐ ┌────────┐│
|
||||
│ │ 引用 │ │ 记忆结果 │ ... │ 控制 ││
|
||||
│ │ 解析器 │ │ 解析器 │ │ 解析器 ││
|
||||
│ └───┬────┘ └─────┬──────┘ └───┬────┘│
|
||||
│ │ │ │ │
|
||||
│ └──────────────┼────────────────────┘ │
|
||||
│ ▼ │
|
||||
│ ┌──────────────────────────────────────────┐│
|
||||
│ │ 文本生成器 (Text Generator) ││
|
||||
│ │ 将结构化解析结果转换为人类可读文本 ││
|
||||
│ │ 支持: 自然语言 / 结构化表格 / JSON ││
|
||||
│ └──────────────────────────────────────────┘│
|
||||
│ │
|
||||
└──────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
人类可读输出文本
|
||||
```
|
||||
|
||||
### 类型分类器
|
||||
|
||||
一个轻量级分类器,从张量 header 中提取 `tensor_type` 字段并路由到对应解析器。
|
||||
|
||||
```python
|
||||
class TensorTypeClassifier:
|
||||
def classify(self, tensor: StandardTensor) -> str:
|
||||
# 直接从 header 读取(运行时信息) + 向量特征校验
|
||||
expected_type = tensor.header.tensor_type
|
||||
payload_hash = hash(tensor.payload.data[:16])
|
||||
|
||||
# 可选:用小网络验证类型与负载内容一致
|
||||
if self.verification_enabled:
|
||||
type_logits = self.small_classifier(tensor.payload.data)
|
||||
predicted_type = self.type_names[type_logits.argmax()]
|
||||
if predicted_type != expected_type:
|
||||
logger.warning(f"类型不一致: header={expected_type}, payload特征={predicted_type}")
|
||||
|
||||
return expected_type
|
||||
```
|
||||
|
||||
### 专用解析器
|
||||
|
||||
#### 引用解析器 (Ref Parser)
|
||||
|
||||
将路由子网的压缩特征向量解码为标签信息:
|
||||
|
||||
```python
|
||||
class RefParser(nn.Module):
|
||||
"""引用张量解析器"""
|
||||
|
||||
def __init__(self, latent_dim=768, label_vocab_size=10000):
|
||||
super().__init__()
|
||||
self.encoder = nn.Linear(latent_dim, 512)
|
||||
self.label_predictor = nn.Linear(512, label_vocab_size) # 标签分类
|
||||
self.confidence_head = nn.Linear(512, 1) # 置信度估计
|
||||
self.category_head = nn.Linear(512, 50) # 类别预测
|
||||
|
||||
def forward(self, ref_tensor):
|
||||
h = self.encoder(ref_tensor)
|
||||
label_logits = self.label_predictor(h) # 预测标签
|
||||
confidence = torch.sigmoid(self.confidence_head(h)) # 置信度
|
||||
category = self.category_head(h) # 类别
|
||||
return {
|
||||
"predicted_labels": label_logits.topk(5).indices,
|
||||
"confidence": confidence.item(),
|
||||
"category": category.argmax().item()
|
||||
}
|
||||
```
|
||||
|
||||
#### 推理路径解析器 (Reasoning Parser)
|
||||
|
||||
```python
|
||||
class ReasoningParser(nn.Module):
|
||||
"""推理路径张量→推理链文本"""
|
||||
|
||||
def __init__(self, hidden_dim=768, max_steps=20):
|
||||
super().__init__()
|
||||
self.step_encoder = nn.Linear(hidden_dim, 256)
|
||||
self.step_decoder = nn.TransformerDecoderLayer(
|
||||
d_model=256, nhead=4
|
||||
)
|
||||
# 将每一步解码为文本 token
|
||||
self.text_head = nn.Linear(256, vocab_size)
|
||||
|
||||
def forward(self, reasoning_tensor):
|
||||
steps = reasoning_tensor["reasoning_steps"]
|
||||
decoded = []
|
||||
for step_emb in steps:
|
||||
h = self.step_encoder(step_emb)
|
||||
# 自回归解码为文本
|
||||
step_text = self.decode_step(h)
|
||||
decoded.append(step_text)
|
||||
return "\n".join(decoded)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 训练
|
||||
|
||||
### 训练数据构建
|
||||
|
||||
核心思路:**构造"标准张量 → 人类标注文本"的配对数据集**。
|
||||
|
||||
#### 方法一:从子网训练过程自然生成
|
||||
|
||||
在子网训练过程中,每条训练样本天然包含:
|
||||
- 输入(原始数据/问题)
|
||||
- 子网计算的中间张量
|
||||
- 输出(正确结果)
|
||||
|
||||
自动构建配对:
|
||||
|
||||
```
|
||||
子网训练样本 → 记录中间张量 + 记录对应的人类标注 → 构建配对数据
|
||||
```
|
||||
|
||||
#### 方法二:合成数据
|
||||
|
||||
对于无法自然获得标注的场景,使用 LLM 生成合成数据:
|
||||
|
||||
```python
|
||||
def synthesize_training_pair(tensor_type: str) -> tuple:
|
||||
"""生成 (标准张量, 人类可读文本) 配对"""
|
||||
|
||||
# 1. 随机生成或从真实数据采样标准张量
|
||||
tensor = sample_tensor(tensor_type)
|
||||
|
||||
# 2. 使用 LLM 将张量转为人类可读描述
|
||||
metadata_json = json.dumps(tensor.header, ensure_ascii=False)
|
||||
payload_preview = summarize_payload(tensor.payload.data)
|
||||
|
||||
llm_prompt = f"""
|
||||
你是一个张量解析专家。以下是一个 {tensor_type} 类型的标准张量:
|
||||
|
||||
头: {metadata_json}
|
||||
负载摘要: {payload_preview}
|
||||
维度: {tensor.metadata.dimensions}
|
||||
置信度: {tensor.metadata.confidence}
|
||||
|
||||
请用自然语言描述这个张量代表什么。
|
||||
例如,如果是 ref_tensor,描述"用户输入了关于XXX的查询,提取到的关键标签是..."
|
||||
如果是 reasoning_path,描述推理链的每一步和最终结论。
|
||||
"""
|
||||
|
||||
human_readable = llm.generate(llm_prompt)
|
||||
|
||||
return (tensor, human_readable)
|
||||
```
|
||||
|
||||
#### 方法三:端到端采集
|
||||
|
||||
在系统运行过程中,记录所有子网间的张量通信日志,同时记录最终的输入和输出,由人工标注中间张量对应的语义。
|
||||
|
||||
### 训练计划
|
||||
|
||||
#### 阶段 1:张量类型分类器
|
||||
|
||||
| 项目 | 说明 |
|
||||
|------|------|
|
||||
| **数据** | 各类型张量各 2000 条(header 字段即可完成) |
|
||||
| **模型** | 小 MLP (输入: header + payload 前 16 个浮点数) |
|
||||
| **准确率目标** | ≥ 99% |
|
||||
| **训练时间** | ~30 分钟 |
|
||||
|
||||
#### 阶段 2:专用解析器训练
|
||||
|
||||
| 解析器 | 训练数据 | 模型大小 | 目标准确率 |
|
||||
|--------|---------|---------|-----------|
|
||||
| 引用解析器 | 5K 对 (路由中间层输出, 文本标签) | 2 层 MLP | 标签预测 ≥ 85% |
|
||||
| 记忆结果解析器 | 3K 对 (查询结果, 记忆内容描述) | 小型 Transformer | 实体名称 ≥ 90% |
|
||||
| 推理路径解析器 | 5K 对 (推理轨迹, 步骤描述) | 4 层 Transformer | 步骤描述 ≥ 80% |
|
||||
| 表达验证解析器 | 2K 对 (验证张量, 验证报告) | 2 层 MLP | 分类准确率 ≥ 95% |
|
||||
| 控制信号解析器 | 1K 对 (控制信号, 决策描述) | 规则+小MLP | 100% 可规则化 |
|
||||
|
||||
#### 阶段 3:文本生成器微调
|
||||
|
||||
使用轻量 LLM(如 Qwen 2.5-0.5B)进行微调:
|
||||
|
||||
```
|
||||
输入: [TYPE] ref_tensor [HEADER] 源: 路由, 目标: Core, ...
|
||||
[PAYLOAD] 标签预测: [故宫, 建筑, 北京], 置信度: 0.92, ...
|
||||
|
||||
输出: "路由子网将用户输入的图像解析为标签 [故宫, 建筑, 北京],置信度 0.92"
|
||||
```
|
||||
|
||||
微调数据:5K 条配对,LoRA rank=16, 2 epochs
|
||||
|
||||
---
|
||||
|
||||
## 使用场景
|
||||
|
||||
### 场景 1:训练期间验证子网输出
|
||||
|
||||
```
|
||||
训练路由子网时,每个 batch 后:
|
||||
|
||||
batch_output = routing_subnet(batch_input)
|
||||
tensor = encode_to_standard(batch_output)
|
||||
|
||||
# 调用解析网络验证
|
||||
human_text = tensor_parser.parse(tensor)
|
||||
print(human_text)
|
||||
# → "第 127 batch: 成功提取标签 [猫, 动物, 宠物],置信度 0.89"
|
||||
# → "警告:第 128 batch 标签 [交通工具] 置信度仅 0.32,可能是误检"
|
||||
|
||||
# 如果置信度偏低,暂停训练并检查
|
||||
if confidence < 0.5:
|
||||
logger.warning(f"Batch {i}: 低置信度输出,建议检查训练数据")
|
||||
```
|
||||
|
||||
### 场景 2:调试子网间通信
|
||||
|
||||
```python
|
||||
# 拦截子网间通信,通过解析网络查看内容
|
||||
from tensor_parser import TensorParser
|
||||
|
||||
parser = TensorParser(verbose=True)
|
||||
|
||||
# Core 发送给记忆子网的查询张量
|
||||
query_tensor = create_memory_query("用户上次提到过什么音乐偏好?")
|
||||
print(parser.parse(query_tensor))
|
||||
# → "Core 向记忆子网查询: '用户上次提到过什么音乐偏好?',查询模式: 语义检索"
|
||||
|
||||
# 记忆子网返回的结果
|
||||
memory_result = memory_subnet.retrieve(query_tensor)
|
||||
print(parser.parse(memory_result))
|
||||
# → "找到 2 条相关记忆: [用户喜欢摇滚] (置信度 0.95), [用户提过五月天] (置信度 0.78)"
|
||||
```
|
||||
|
||||
### 场景 3:标注训练数据
|
||||
|
||||
```python
|
||||
# 对未标注的张量,由解析网络生成初始描述,人工修正
|
||||
tensor = sample_from_production()
|
||||
draft = parser.parse(tensor)
|
||||
# draft: "推理路径: 步骤1→步骤2→步骤3, 结论: 北京明天有雨"
|
||||
# 人工修正后作为标注数据
|
||||
|
||||
corrected = "推理路径: 步骤1(实体提取: 北京/明天)→步骤2(天气查询: 预报有雨)→步骤3(推理: 北京明天有雨), 置信度 0.92"
|
||||
training_pairs.append((tensor, corrected))
|
||||
```
|
||||
|
||||
### 场景 4:端到端回归测试
|
||||
|
||||
```python
|
||||
def regression_test(subnet, test_cases):
|
||||
"""使用解析网络验证子网输出是否正确"""
|
||||
for input_data, expected_text in test_cases:
|
||||
output = subnet(input_data)
|
||||
output_tensor = encode_to_standard(output)
|
||||
parsed_text = parser.parse(output_tensor)
|
||||
|
||||
# 计算语义相似度
|
||||
similarity = compute_similarity(parsed_text, expected_text)
|
||||
assert similarity > 0.8, f"解析结果与预期不符: {parsed_text} vs {expected_text}"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 评估体系
|
||||
|
||||
| 指标 | 计算方式 | 目标 |
|
||||
|------|----------|------|
|
||||
| 标签预测准确率 | 解析器输出的标签与人工标注的一致率 | ≥ 85% |
|
||||
| BLEU (描述文本) | 生成文本与参考文本的 BLEU 分数 | ≥ 40 |
|
||||
| 语义相似度 | 解析文本与参考文本的余弦相似度 | ≥ 0.85 |
|
||||
| 实体名称准确率 | 提取的实体名称正确率 | ≥ 90% |
|
||||
| 置信度校准 | 解析器自报置信度与实际准确率一致性 | ECE ≤ 0.1 |
|
||||
| 解析延迟 | 单次解析时间(离线使用,宽松) | ≤ 500ms |
|
||||
|
||||
---
|
||||
|
||||
## 实现建议
|
||||
|
||||
### 最小可行产品 (MVP)
|
||||
|
||||
如果不想一开始就训练复杂的解析网络,可以先做一个**规则+模板驱动的轻量版本**:
|
||||
|
||||
```python
|
||||
class RuleBasedParser:
|
||||
"""基于规则的张量解析器(MVP)"""
|
||||
|
||||
def parse(self, tensor: StandardTensor) -> str:
|
||||
tensor_type = tensor.header.tensor_type
|
||||
|
||||
if tensor_type == "control":
|
||||
return self.parse_control(tensor)
|
||||
elif tensor_type == "memory_result":
|
||||
return self.parse_memory(tensor)
|
||||
else:
|
||||
# 其他类型走模板
|
||||
return f"[{tensor_type}] 源={tensor.header.source}, 目标={tensor.header.target}, " \
|
||||
f"置信度={tensor.metadata.confidence:.2f}, " \
|
||||
f"维度={tensor.metadata.dimensions}"
|
||||
|
||||
def parse_control(self, tensor):
|
||||
params = tensor.payload.metadata_map
|
||||
return f"Core 发往 {tensor.header.target}: " \
|
||||
f"控制类型={params.get('control_type', 'unknown')}, " \
|
||||
f"参数={params}"
|
||||
|
||||
def parse_memory(self, tensor):
|
||||
entities = tensor.payload.metadata_map.get('entities', [])
|
||||
rels = tensor.payload.metadata_map.get('relations', [])
|
||||
text = f"记忆检索结果: 找到 {len(entities)} 个实体, {len(rels)} 条关系\n"
|
||||
for r in rels[:3]:
|
||||
text += f" · {r['subject']} -[{r['type']}]-> {r['object']} (置信度 {r.get('confidence', 1.0)})\n"
|
||||
return text
|
||||
```
|
||||
|
||||
规则版不需要训练,可以立即使用。随着需求积累,逐步加入可学习的解析器替换规则路径。
|
||||
|
||||
### 推荐迭代路线
|
||||
|
||||
1. **第 0 天**:规则+模板解析器(零训练,直接可用)
|
||||
2. **第 1~3 天**:训练引用解析器和记忆结果解析器(标签分类,数据易得)
|
||||
3. **第 3~5 天**:训练推理路径解析器和表达验证解析器
|
||||
4. **第 5~7 天**:微调轻量 LLM 作为统一文本生成器
|
||||
5. **持续**:随系统运行积累真实张量数据,持续提升解析质量
|
||||
Reference in New Issue
Block a user