Vect0rdecay/GraphSurgeon

GitHub: Vect0rdecay/GraphSurgeon

一款用于 ONNX 计算图逆向工程的工具,支持架构参数推断、结构 Motif 检测、反事实图编辑与 3D 可视化。

Stars: 0 | Forks: 0

# GraphSurgeon GraphSurgeon 可以从命令行或 Python 对 ONNX 计算图进行逆向工程。它能总结输入和算子,映射深度和执行顺序,检测 DAG 中的结构 Motif,交叉引用对抗性机器学习(AML)文献,叙述数据流,并支持带有验证和 diff 的反事实编辑。 ### 最近更新 - **架构推断**(2026 年 6 月)— `inspect` 现在可以直接从 ONNX 图中推断隐藏维度、词表大小、MLP 中间层大小、最大位置嵌入、RoPE theta、绑定嵌入、卷积分组(conv groups)和量化格式。使用 `--json` 获取结构化输出。参见[架构推断](#architecture-inference)。 - **外部数据回退** — 解析器现在通过回退到仅解析图结构的方式,加载缺失或不完整的外部权重数据的模型。损坏或存根(stub)ONNX 文件会收到清晰的错误消息,而不是 traceback。 - **3D 查看器** — 交互式太空主题可视化,支持 WASD 飞行穿梭、Motif 区域高亮、ShadowLogic 叠加层、每个节点的结构概况、反事实编辑以及可折叠的侧边栏。参见 [3D 可视化](#3d-visualization)。 该工具仅支持 ONNX。它不需要 PyTorch 或 CUDA 工具包。 ## 功能说明 | 命令 | 作用 | |---------|------| | `inspect` | 模型摘要:I/O 张量、算子组合以及推断的架构(隐藏维度、词表大小、MLP 大小、RoPE theta、绑定嵌入、最大位置、卷积分组、量化) | | `topology` | 图深度、前部/中部/后部层桶(buckets)、执行顺序 | | `patterns` | 粗粒度结构块(conv 堆栈、attention、normalization 链) | | `motifs` | 注册表支持的结构 Motif:图拓扑在架构上使得哪些攻击类别变得合理 | | `flow` | 纯英文的执行叙述 | | `catalog` | 查找 Gadgets、复合链、文献技术以及打包的论文笔记 | | `operators` | 以安全相关行为为键的 ONNX 算子参考 | | `edit` | 反事实图手术(`remove-node`),支持结构、可加载或可运行级别的验证 | | `diff` | 在编辑后比较两个 ONNX 文件 | | `export-scene` | 为 3D 查看器导出 SceneGraph JSON | | `serve` | 启动一个支持反事实编辑的实时 3D 可视化服务器 | Motif 命中描述的是攻击面概况(即该架构允许的攻击类型),而不是确认的可利用性。该工具不会分配风险评分或严重性等级。 ## 架构推断 `inspect` 自动从 ONNX 图结构推断模型架构参数 — 无需配置文件或模型卡片。它仅报告它能确定的字段;未知的字段会被省略。 | 字段 | 推断方式 | |-------|-------------------| | 隐藏维度 | Normalization 节点(LayerNormalization, SimplifiedLayerNormalization, SkipSimplifiedLayerNormalization, SkipLayerNormalization, RMSNormalization)中一维权重形状的众数。回退到最常见的 MatMul/MatMulNBits 权重维度,然后是 Conv 输出通道数。 | | 词表大小 | 嵌入权重(Gather/GatherBlockQuantized 节点)的第一维度,结合来自最终 MatMul/MatMulNBits/Gemm 的 LM head 输出维度。当多个信号一致时,返回频率最高的候选值。 | | MLP 中间层大小 | 通过节点名称识别(gate_proj, up_proj, fc1, c_fc, wi)的 gate/up 投影权重的输出维度。回退到后接 Mul/Sigmoid 模式的 MatMul 节点。 | | 最大位置嵌入 | 名称包含 cos_cache, sin_cache, cos_cached, sin_cached, pos_embed, position_embed 或 wpe 的 initializer 的第一维度。 | | RoPE theta | 从预计算的 cos_cache 张量值逆向工程得出;回退到名称包含 inv_freq, freqs 或 rope_freq 的 initializer 张量,然后是 RotaryEmbedding 节点属性。在 1% 容差范围内吸附到常见的 theta 值(10000, 500000, 1000000 等)。 | | 绑定嵌入 | 检测同时被嵌入节点(Gather/GatherBlockQuantized/Embedding)和图后部或 lm_head 节点(MatMul/MatMulNBits/Gemm/Transpose)消费的 initializer。也会检查在剥离量化后缀后是否共享基础权重名称。 | | 卷积分组(Conv groups) | Conv 节点的 group 属性(仅在 > 1 时报告) | | 量化格式 | 从 MatMulNBits 位宽属性或 DequantizeLinear 的存在中检测 | 已在 Liquid AI LFM2.5 模型(混合门控 conv + GQA + RoPE + SwiGLU)上跨 fp32、fp16、Q4 和 Q8 量化格式进行了测试。隐藏维度和 MLP 大小的回退路径涵盖了标准的基于 MatMul 和基于 Conv 的架构,但尚未在纯 CNN 或标准仅 Transformer 模型上进行验证。当外部权重数据不可用时,基于形状的字段仍然可以解析 — 只有 RoPE theta 需要实际的张量字节(所有三个恢复路径 — cos_cache, inv_freq 和节点属性 — 都依赖于加载的数据或非零属性)。 示例输出: ``` Architecture: Hidden dimension: 2048 Vocab size: 65536 MLP intermediate size: 8192 Max position embeddings: 128000 RoPE theta: 1000000 Tied embeddings: True Tied initializers: ['model_embed_tokens_weight_scales', 'model_embed_tokens_weight_zp'] Conv groups: 2048 Quantization: Q4 ``` 使用 `--json` 获取适合脚本编写和跨模型比较的结构化输出。 ## 安装说明 ``` cd graph-surgeon python3 -m venv .venv .venv/bin/python -m pip install -e ".[dev]" ``` | 包 | 用途 | |---------|---------| | `onnx`, `numpy` | 核心图解析、Motif、拓扑(始终安装) | | `onnxruntime` | `edit validate --level loadable/runnable`(通过 `[dev]`) | | `pytest` | 测试套件(通过 `[dev]`) | | `fastapi`, `uvicorn` | 用于实时 3D 可视化的 `serve` 命令(通过 `[viz]`) | 最小化安装(无运行时验证或测试): ``` .venv/bin/python -m pip install -e . ``` ## CLI 在 `pip install -e .` 之后,使用项目 venv(除非你激活 venv,否则 `graph-surgeon` 命令不在你的系统 PATH 中): ``` source .venv/bin/activate # optional; then graph-surgeon works on PATH # 或者总是: .venv/bin/graph-surgeon --help .venv/bin/python -m graph_surgeon catalog --coverage ``` ``` graph-surgeon inspect model.onnx # human-readable summary + architecture graph-surgeon inspect model.onnx --json # full report as JSON graph-surgeon topology model.onnx graph-surgeon patterns model.onnx graph-surgeon motifs model.onnx -o report.json graph-surgeon flow model.onnx graph-surgeon catalog --gadget GAP_FC_HEAD graph-surgeon catalog --chain CHAIN-PATCH-ATTACK-SURFACE graph-surgeon catalog --coverage graph-surgeon operators --op Conv graph-surgeon edit validate edited.onnx --level runnable graph-surgeon edit remove-node model.onnx NODE_NAME -o edited.onnx graph-surgeon diff baseline.onnx edited.onnx graph-surgeon export-scene model.onnx -o scene.json graph-surgeon serve model.onnx --port 9095 ``` 当检测到 Motif 或链时,使用 `catalog --gadget` 或 `catalog --chain` 获取注册表元数据、检测逻辑和论文综述。显示标题使用注册表 ID(例如 `GAP_FC_HEAD — Global Average Pool → FC Head`)。 反事实编辑(`edit`)目前暴露了一个手术子命令:`remove-node`。在编辑之前,使用 `inspect` 或 `topology` 发现确切的 ONNX 节点名称。 ## 研究语料库 GraphSurgeon 在 `graph_surgeon/taxonomy/data/`(特别是 `attack_research_notes.md`)下提供了按论文分类的分析。该语料库为丰富的目录输出提供了动力:当你查找 Gadget 或链时,你会获得链接的 AML 文献、ONNX 图指标和攻击类映射,而无需获取外部文档。 正常使用不需要触碰这些文件。要查看完成状态: ``` .venv/bin/graph-surgeon catalog --coverage ``` ## Python API GraphSurgeon 主要是一个 CLI 工具,但同样的分析和手术路径也可以从 Python 中使用。包级别的导出(`from graph_surgeon import ...`):`GraphSurgeon`, `GraphTopology`, `GraphTopologyConfig`, `LayerPosition`, `NodeTopology`, `GraphValidationLevel`, `GraphValidationResult`。 ### 分析(Motif、模式、流) 这些镜像了 `motifs`、`patterns` 和 `flow`: ``` from graph_surgeon.parsers.onnx_parser import analyze_onnx_graph, analyze_onnx_patterns, quick_scan motif_report = analyze_onnx_graph("model.onnx", output_path="report.json") print(len(motif_report.structural_findings), motif_report.model_flow_description) pattern_report = analyze_onnx_patterns("model.onnx") print(quick_scan("model.onnx")) ``` 从 Motif 导出的 JSON 使用与 CLI 输出相同的清理器(内部评分字段已被剥离)。 ### 拓扑和图检查 ``` from graph_surgeon import GraphSurgeon, LayerPosition surgeon = GraphSurgeon(verbose=False) model = surgeon.load_model("model.onnx") topo = surgeon.get_graph_topology(model.graph) print(topo.total_nodes, topo.max_depth) print(topo.by_position[LayerPosition.EARLY][:5]) print(topo.by_position[LayerPosition.LATE][:5]) print(surgeon.find_nodes_by_type(model.graph, "Conv")) ``` ### 目录和分类体系 这些镜像了 `catalog` 查找: ``` from graph_surgeon.taxonomy.display import format_catalog_gadget, format_catalog_chain from graph_surgeon.taxonomy.research_coverage import format_coverage_report from graph_surgeon.taxonomy import motif_catalog print(format_catalog_gadget("LINEAR_HEAD")) print(format_catalog_chain("CHAIN-SKIP-HIGHWAY")) print(format_coverage_report()) technique = motif_catalog.get_technique_by_id("AML-ADV-002") ``` ### 反事实编辑 CLI 对等物:`remove_node` 匹配 `edit remove-node`。所有手术方法都会就地改变已加载的 `ModelProto`,并返回一个 `SurgeryResult`(`success`, `graph`, `message`, `nodes_added`, `nodes_removed`, `nodes_modified`, `edges_rewired`)。 ``` from graph_surgeon import GraphSurgeon, GraphValidationLevel surgeon = GraphSurgeon(verbose=False) baseline = surgeon.load_model("model.onnx") edited = surgeon.clone_model(baseline) result = surgeon.remove_node(edited, "node_relu_23") if not result.success: raise RuntimeError(result.message) surgeon.save_model(edited, "edited.onnx") check = surgeon.validate(edited, level=GraphValidationLevel.STRUCTURAL) print(check.valid, check.errors) diff = surgeon.compare_graphs(baseline, edited) print(diff["summary"], diff["nodes_removed"]) ``` `GraphValidationLevel.LOADABLE` 和 `.RUNNABLE` 需要 `onnxruntime`(通过 `pip install -e ".[dev]"` 安装)。在最小化安装时,验证会回退并伴有警告。 其他图手术原语(`remove_subgraph`, `insert_node_before`, `insert_node_after`, `replace_node`, `modify_node_attribute`, `add_initializer`, `add_metadata`)目前仅支持 Python。完整的 `GraphSurgeon` 参考请参见 [docs/PYTHON_API.md](docs/PYTHON_API.md)。 ### 架构推断 ``` from graph_surgeon.parsers.onnx_parser import ONNXGraphParser from graph_surgeon.analysis.architecture import infer_architecture parser = ONNXGraphParser() graph = parser.parse_file("model.onnx") arch = infer_architecture(graph) print(arch.hidden_dim) # e.g. 2048 print(arch.vocab_size) # e.g. 65536 print(arch.rope_theta) # e.g. 1000000.0, or None print(arch.tied_embeddings) # True, or None if not detected print(arch.to_dict()) # dict of non-None fields only ``` ### 可选的权重统计 启发式权重分布分析(仅需核心依赖;无需 `onnxruntime`): ``` from graph_surgeon.behavior.weight_signature import analyze_onnx_weights stats = analyze_onnx_weights("model.onnx") print(stats.summary()) ``` ## 文档 | 文档 | 内容 | |-----|----------| | [docs/PYTHON_API.md](docs/PYTHON_API.md) | 完整的 `GraphSurgeon` 方法参考、验证级别、手术结果字段 | ## 3D 可视化 GraphSurgeon 包含一个交互式 3D 查看器,将 ONNX 模型图渲染为可导航的场景,带有太空星云背景、受 Superluminal 启发的排版以及结构分析叠加层。 ### 快速开始 ``` pip install -e ".[viz]" source .venv/bin/activate graph-surgeon serve model.onnx --port 9095 # 在浏览器中打开 http://127.0.0.1:9095 ``` 或者使用 Vite 导出静态场景并提供服务(用于开发): ``` graph-surgeon export-scene model.onnx -o viewer/sample_scene.json cd viewer && npm install && ./node_modules/.bin/vite --port 5173 ``` ### 导航 | 控制 | 动作 | |---------|--------| | WASD | 飞行穿梭图(前/后/平移) | | Q / Space | 向上飞 | | E / Shift | 向下飞 | | 鼠标拖拽 | 环绕相机 | | 滚轮 | 放大/缩小 | | 点击节点 | 打开节点详情面板 | | 右键点击节点 | 反事实编辑菜单 | | START / END(按钮) | 飞到图的开头或结尾 | ### Motif 和链可视化 检测到的对抗性 Motif 和复合链列在左侧边栏中。点击 Motif 会: - **高亮** 3D 图中参与的节点(其他节点变暗) - **在其节点周围显示一个半透明的边界区域**,按结构重要性进行颜色编码(红色 = EXCEPTIONAL,琥珀色 = PRIMARY,青色 = SECONDARY,绿色 = TERTIARY/MITIGATING) - **打开详情面板**(右下角),显示: - 结构重要性和置信度徽章 - 模式的技术描述 - 该架构允许的攻击类型 - 检测逻辑(GraphSurgeon 是如何发现它的) - 来自内置 AML 语料库的研究论文参考文献 - 可点击的节点 ID,可使相机飞至每个节点 使用 "SHOW ALL REGIONS" 可一次性点亮每个 Motif 区域,以全面了解攻击面概况。重复的发现(例如 50 多个 BatchNorm 统计信息泄露实例)被分组为一个带有计数的单独侧边栏条目。 ### 布局 查看器使布局适应图的形状: - **宽图**(如 Inception 等分支架构):节点按父级连接性排序,并在每个深度水平分布 - **窄图**(如 ResNet 等序列模型):螺旋/螺线路布局,防止形成单条垂直线 - **仅参数节点**(仅消费 initializer 的 Unsqueeze, Reshape 操作):重新定位到其消费者节点旁边,而不是堆积在深度 0 处 ### 附加功能 - **搜索**:在搜索栏中输入以按名称或操作类型过滤节点 - **流遍历(Flow walk)**:"WALK FLOW" 按执行顺序逐级遍历,并带有显示每个级别节点的详情面板 - **模型流描述**:"VIEW MODEL FLOW" 打开全屏的可读叙述 - **ShadowLogic 叠加层**(用于识别潜在逻辑注入点的项目定义启发式方法):在 3D 图上显示注入点标记,支持飞至导航和每个点的详情弹出窗口 - **结构模式**:切换高亮以显示梯度瓶颈、融合点、放大层和防御点 - **每节点的结构概况**:点击节点会显示拓扑衍生的结构代理指标(梯度敏感度、Lipschitz 估计、扰动放大、ShadowLogic 容量、提取泄露)的仪表条指标;这些是基于图结构的启发式估计,而不是运行时计算的值 - **可折叠侧边栏**:所有部分(流、导航、ShadowLogic、模式、Motif 和链)均可独立折叠 - **拖放**:将 `scene.json` 文件拖放到查看器上即可加载 - **反事实编辑**:右键点击节点将其移;服务器会重新分析并且视图会实时更新 ## 与 Netron 的比较 Netron 是一个图查看器:在屏幕上显示节点、张量和形状。 GraphSurgeon 是在相同 ONNX 文件之上的分析和实验层: - 位置拓扑(stem 对 middle 对 head)和有序执行,而不仅仅是邻接关系 - 带有类型化注册表和文献交叉引用的自动化 Motif 和模式检测 - 可搜索的 Gadget、链、技术和打包论文笔记目录 - 反事实编辑(移除节点、重新连线、验证、与基线进行 diff) - 用于脚本编写和跨模型变体批量比较的 JSON 导出 使用 Netron 查看图;使用 GraphSurgeon 解释结构,将其与已发布的攻击类别相关联,测试当你改变 DAG 时会发生什么变化,并以 3D 方式可视化对抗性攻击面。 ## 测试 单元测试(无外部 ONNX 文件): ``` .venv/bin/python -m pytest tests/ -v ``` 需要不在本仓库中的 ONNX fixtures 的集成测试已被 gitignore 忽略,并在 `tests/README.md` 中有说明。 ## 许可证 MIT
标签:CNCF毕业项目, ONNX, 人工智能, 可视化工具, 模型结构分析, 模型逆向分析, 用户模式Hook绕过, 计算图, 逆向工具