{"id":5674,"library":"onnx-graphsurgeon","title":"ONNX GraphSurgeon","description":"ONNX GraphSurgeon is a Python library used for programmatically manipulating ONNX graphs. It provides a high-level API to import, inspect, modify, and export ONNX models, often used in conjunction with NVIDIA TensorRT for optimization and deployment workflows. The current PyPI version is 0.6.1, though its development is closely tied to TensorRT's release cadence, with newer versions often bundled with TensorRT distributions.","status":"active","version":"0.6.1","language":"en","source_language":"en","source_url":"https://github.com/NVIDIA/TensorRT/tree/main/tools/onnx-graphsurgeon","tags":["onnx","tensorrt","neural network","graph manipulation","optimization"],"install":[{"cmd":"pip install onnx-graphsurgeon==0.6.1","lang":"bash","label":"Install specific PyPI version"}],"dependencies":[{"reason":"Required for ONNX model parsing and generation.","package":"onnx","optional":false},{"reason":"Used for internal data serialization.","package":"flatbuffers","optional":false}],"imports":[{"note":"Common alias for convenience.","symbol":"gs","correct":"import onnx_graphsurgeon as gs"},{"note":"While often re-exported, the canonical path is through `ir.graph`.","wrong":"from onnx_graphsurgeon import Graph","symbol":"Graph","correct":"from onnx_graphsurgeon.ir.graph import Graph"},{"note":"While often re-exported, the canonical path is through `ir.node`.","wrong":"from onnx_graphsurgeon import Node","symbol":"Node","correct":"from onnx_graphsurgeon.ir.node import Node"},{"note":"While often re-exported, the canonical path is through `ir.tensor`.","wrong":"from onnx_graphsurgeon import Tensor","symbol":"Tensor","correct":"from onnx_graphsurgeon.ir.tensor import Tensor"}],"quickstart":{"code":"import onnx\nimport onnx_graphsurgeon as gs\nfrom onnx import helper, TensorProto\nimport numpy as np\nimport os\n\n# 1. Create a dummy ONNX model for demonstration\ndef create_dummy_model():\n    X = helper.make_tensor_value_info('X', TensorProto.FLOAT, [1, 3, 16, 16])\n    Y = helper.make_tensor_value_info('Y', TensorProto.FLOAT, [1, 3, 16, 16])\n    \n    const_val_tensor_1 = helper.make_tensor('const_add_val_1', TensorProto.FLOAT, [], [1.0])\n    \n    # Model: X -> Add (with const_add_val_1) -> Add_Output -> Identity -> Y\n    node_add = helper.make_node('Add', ['X', 'const_add_val_1'], ['Add_Output'])\n    node_identity = helper.make_node('Identity', ['Add_Output'], ['Y'])\n\n    graph_def = helper.make_graph(\n        [node_add, node_identity],\n        'simple_graph',\n        [X],\n        [Y],\n        [const_val_tensor_1]\n    )\n    model = helper.make_model(graph_def, producer_name='dummy-model', opset_imports=[helper.make_opsetid(\"\", 13)])\n    return model\n\n# Save the dummy model to a file\ndummy_model = create_dummy_model()\nonnx.save(dummy_model, \"dummy_model.onnx\")\nprint(\"Original model saved to dummy_model.onnx\")\n\n# 2. Load the model with ONNX GraphSurgeon\ngraph = gs.import_onnx(onnx.load(\"dummy_model.onnx\"))\n\n# 3. Modify the graph: Replace the Identity node with a second Add node\nidentity_node = None\nfor node in graph.nodes:\n    if node.op == \"Identity\":\n        identity_node = node\n        break\n\nif identity_node:\n    input_tensor = identity_node.inputs[0]  # Output of the first Add node\n    output_tensor = identity_node.outputs[0] # The graph's final output tensor 'Y'\n\n    # Remove the old Identity node\n    graph.nodes.remove(identity_node)\n\n    # Create a new Constant for the second Add op\n    const_val_tensor_2 = gs.Constant(name=\"const_add_val_2\", values=np.array([2.0], dtype=np.float32))\n\n    # Create a new Add node to replace Identity\n    new_add_node = gs.Node(\n        op=\"Add\",\n        inputs=[input_tensor, const_val_tensor_2], # Input from first Add, plus new constant\n        outputs=[output_tensor] # Re-use the original output tensor 'Y'\n    )\n\n    # Add the new node to the graph\n    graph.nodes.append(new_add_node)\n\n# Always cleanup and topological sort after graph modifications\ngraph.cleanup().toposort()\n\n# 4. Save the modified model\nmodified_model = gs.export_onnx(graph)\nonnx.save(modified_model, \"modified_dummy_model.onnx\")\nprint(\"Modified model saved to modified_dummy_model.onnx (Identity replaced with Add)\")\n\n# Optional: Verify the modified model with ONNX checker\ntry:\n    onnx.checker.check_model(modified_model)\n    print(\"Modified model check successful!\")\nexcept Exception as e:\n    print(f\"Modified model check failed: {e}\")\n\n# Cleanup created files\nos.remove(\"dummy_model.onnx\")\nos.remove(\"modified_dummy_model.onnx\")","lang":"python","description":"This quickstart demonstrates how to load an ONNX model, find a specific node (Identity), remove it, and replace it with a new operation (an 'Add' node with a new constant input), and then save the modified model. It also includes `onnx.checker.check_model` for basic graph validation."},"warnings":[{"fix":"Check TensorRT documentation for recommended installation methods. Consider building from the TensorRT GitHub repository or using the version provided with your TensorRT distribution instead of pip installing.","message":"The PyPI package `onnx-graphsurgeon` (v0.6.1) might be significantly older than the version integrated with current NVIDIA TensorRT releases (e.g., TensorRT 10.x). For optimal compatibility, especially with new ONNX operators or TensorRT features, it is often recommended to use the `onnx-graphsurgeon` version bundled with your specific TensorRT installation or build from source.","severity":"breaking","affected_versions":"PyPI versions vs. bundled TensorRT versions"},{"fix":"Always use `onnx.checker.check_model()` after graph modifications to verify structural integrity. Perform runtime validation (e.g., with ONNX Runtime or TensorRT) to confirm functional correctness.","message":"ONNX GraphSurgeon does not automatically validate the semantic correctness of graph modifications. Incorrect changes can lead to invalid ONNX graphs that fail `onnx.checker.check_model()` or cannot be parsed/optimized by runtimes like TensorRT.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Explicitly manage `gs.Tensor` inputs/outputs when adding/removing nodes. Always call `graph.cleanup().toposort()` to remove disconnected nodes/tensors and ensure a valid topological order.","message":"Careful management of `gs.Tensor` objects (inputs/outputs) is crucial during graph manipulation. Incorrectly linking tensors or failing to update consumer/producer relationships can result in a broken graph. Using `graph.cleanup().toposort()` is essential after modifications.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-13T00:00:00.000Z","next_check":"2026-07-12T00:00:00.000Z"}