news 2026/2/17 17:41:59

【问题解决】ONNXRuntimeError: Nodes in a graph must be topologically sorted: node ‘attention‘ has input fr

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【问题解决】ONNXRuntimeError: Nodes in a graph must be topologically sorted: node ‘attention‘ has input fr

文章目录

  • 【问题解决】ONNXRuntimeError: Nodes in a graph must be topologically sorted: node 'attention' has input from uninitialized node 'k_proj'
    • 问题描述
    • 问题原因
    • 解决方案
      • 方案 1:重新导出模型
      • 方案 2:检查并修复 ONNX 模型
      • 方案 3:使用正确的 ONNX Runtime 版本
      • 方案 4:检查模型输入输出
      • 方案 5:使用 onnx.shape_inference
      • 方案 6:检查节点依赖关系
    • 示例代码
      • 完整的模型导出和运行示例
    • 常见问题
      • Q: 什么是拓扑排序?
      • Q: 为什么会出现未初始化的节点?
      • Q: 如何选择正确的 opset_version?
      • Q: 模型导出时的 dynamic_axes 参数有什么用?
      • Q: 除了重新导出模型,还有其他方法修复这个问题吗?
    • 总结

【问题解决】ONNXRuntimeError: Nodes in a graph must be topologically sorted: node ‘attention’ has input from uninitialized node ‘k_proj’

问题描述

在使用 ONNX Runtime 运行模型时,遇到以下错误:

ONNXRuntimeError: Nodes in a graph must be topologically sorted: node 'attention' has input from uninitialized node 'k_proj'

问题原因

这个错误通常由以下原因引起:

  1. 模型导出问题:将模型导出为 ONNX 格式时出现问题,导致计算图节点顺序错误
  2. ONNX 版本不兼容:使用的 ONNX 版本与模型不兼容
  3. 模型结构问题:模型中存在循环依赖或节点依赖关系错误
  4. 导出参数问题:导出模型时使用了不正确的参数
  5. ONNX Runtime 版本问题:使用的 ONNX Runtime 版本与模型不兼容
  6. 模型转换问题:在不同框架间转换模型时出现问题

解决方案

方案 1:重新导出模型

确保正确导出模型为 ONNX 格式:

importtorchimporttorch.onnxfromyour_modelimportYourModel# 创建模型实例model=YourModel()model.eval()# 创建示例输入dummy_input=torch.randn(1,3,224,224)# 正确导出模型torch.onnx.export(model,dummy_input,"model.onnx",export_params=True,opset_version=11,do_constant_folding=True,input_names=['input'],output_names=['output'],dynamic_axes={'input':{0:'batch_size'},'output':{0:'batch_size'}})

方案 2:检查并修复 ONNX 模型

importonnx# 加载模型model=onnx.load("model.onnx")# 检查模型onnx.checker.check_model(model)# 优化模型importonnxoptimizer passes=["eliminate_deadend","fuse_bn_into_conv","eliminate_identity"]optimized_model=onnxoptimizer.optimize(model,passes)# 保存优化后的模型onnx.save(optimized_model,"optimized_model.onnx")

方案 3:使用正确的 ONNX Runtime 版本

# 安装兼容的 ONNX Runtime 版本pipinstallonnxruntime==1.15.0# 或安装最新版本pipinstall--upgrade onnxruntime

方案 4:检查模型输入输出

importonnx# 加载模型model=onnx.load("model.onnx")# 查看输入输出print("Inputs:")forinputinmodel.graph.input:print(f"{input.name}:{input.type.tensor_type.shape.dim}")print("\nOutputs:")foroutputinmodel.graph.output:print(f"{output.name}:{output.type.tensor_type.shape.dim}")# 查看节点print("\nNodes:")fori,nodeinenumerate(model.graph.node):print(f" Node{i}:{node.op_type}-{node.name}")print(f" Inputs:{node.input}")print(f" Outputs:{node.output}")

方案 5:使用 onnx.shape_inference

importonnxfromonnx.shape_inferenceimportinfer_shapes# 加载模型model=onnx.load("model.onnx")# 推断形状inferred_model=infer_shapes(model)# 保存推断后的模型onnx.save(inferred_model,"inferred_model.onnx")

方案 6:检查节点依赖关系

importonnxdefcheck_node_dependencies(model):"""检查节点依赖关系"""# 收集所有输出名称all_outputs=set()fornodeinmodel.graph.node:foroutputinnode.output:all_outputs.add(output)# 检查每个节点的输入fori,nodeinenumerate(model.graph.node):forinput_nameinnode.input:# 检查输入是否为图输入或其他节点的输出is_graph_input=any(input_name==graph_input.nameforgraph_inputinmodel.graph.input)is_initializer=any(input_name==initializer.nameforinitializerinmodel.graph.initializer)ifnotis_graph_inputandnotis_initializerandinput_namenotinall_outputs:print(f"Node{i}({node.op_type}) has invalid input:{input_name}")returnFalseprint("All node dependencies are valid")returnTrue# 加载模型model=onnx.load("model.onnx")# 检查依赖关系check_node_dependencies(model)

示例代码

完整的模型导出和运行示例

importtorchimporttorch.nnasnnimportonnximportonnxruntimeasortimportnumpyasnpclassSimpleModel(nn.Module):"""简单的模型类"""def__init__(self):super(SimpleModel,self).__init__()self.conv=nn.Conv2d(3,16,3,padding=1)self.relu=nn.ReLU()self.fc=nn.Linear(16*224*224,10)defforward(self,x):x=self.conv(x)x=self.relu(x)x=x.view(x.size(0),-1)x=self.fc(x)returnxdefexport_model():"""导出模型为 ONNX 格式"""print("Exporting model...")# 创建模型实例model=SimpleModel()model.eval()# 创建示例输入dummy_input=torch.randn(1,3,224,224)# 导出模型torch.onnx.export(model,dummy_input,"simple_model.onnx",export_params=True,opset_version=11,do_constant_folding=True,input_names=['input'],output_names=['output'],dynamic_axes={'input':{0:'batch_size'},'output':{0:'batch_size'}})print("Model exported successfully")defcheck_model():"""检查 ONNX 模型"""print("\nChecking model...")# 加载模型model=onnx.load("simple_model.onnx")# 检查模型try:onnx.checker.check_model(model)print("Model check passed")returnTrueexceptExceptionase:print(f"Model check failed:{e}")returnFalsedefrun_model():"""使用 ONNX Runtime 运行模型"""print("\nRunning model with ONNX Runtime...")# 加载模型session=ort.InferenceSession("simple_model.onnx")# 创建输入数据input_data=np.random.randn(1,3,224,224).astype(np.float32)# 运行模型inputs={session.get_inputs()[0].name:input_data}outputs=session.run(None,inputs)print(f"Model output shape:{outputs[0].shape}")print("Model run successfully")# 使用示例if__name__=="__main__":# 导出模型export_model()# 检查模型ifcheck_model():# 运行模型run_model()else:print("Model check failed, cannot run")

常见问题

Q: 什么是拓扑排序?

A: 拓扑排序是一种对有向无环图 (DAG) 中节点的排序,使得对于每条有向边 u → v,u 都排在 v 之前。在 ONNX 模型中,这意味着每个节点的输入必须在该节点之前被计算。

Q: 为什么会出现未初始化的节点?

A: 未初始化的节点通常是因为节点顺序错误,导致某个节点在其依赖的节点之前被处理。

Q: 如何选择正确的 opset_version?

A: opset_version 应该根据你的 PyTorch 版本和 ONNX Runtime 版本来选择。一般来说,使用较新的 opset_version 会支持更多的操作,但可能与旧版本的 ONNX Runtime 不兼容。

Q: 模型导出时的 dynamic_axes 参数有什么用?

A: dynamic_axes 参数允许你指定哪些维度是动态的,这样模型就可以处理不同大小的输入。

Q: 除了重新导出模型,还有其他方法修复这个问题吗?

A: 可以使用 ONNX 的工具来优化和修复模型,如 onnxoptimizer 和 onnx.shape_inference。

总结

遇到ONNXRuntimeError: Nodes in a graph must be topologically sorted: node 'attention' has input from uninitialized node 'k_proj'错误时,主要需要:

  1. 重新导出模型,确保正确设置导出参数
  2. 检查并修复 ONNX 模型
  3. 使用兼容的 ONNX 和 ONNX Runtime 版本
  4. 检查模型结构和节点依赖关系
  5. 使用 ONNX 工具优化和修复模型

通过以上解决方案,大部分情况下都能成功解决计算图节点顺序错误的问题,顺利运行 ONNX 模型。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/13 11:10:47

用ms-swift合并LoRA权重,部署前必看技巧

用ms-swift合并LoRA权重,部署前必看技巧 你刚跑完一轮LoRA微调,模型在验证集上表现亮眼,心里正盘算着怎么上线——结果一试推理,发现每次都要加载原始大模型LoRA适配器,响应慢、显存占用高、服务不稳定。更糟的是&…

作者头像 李华
网站建设 2026/2/14 15:25:16

GPEN一键美颜:5分钟学会AI老照片修复神器

GPEN一键美颜:5分钟学会AI老照片修复神器 你有没有翻出抽屉里那张泛黄的全家福?爷爷年轻时的军装照、父母结婚时的黑白合影、自己小学毕业照上模糊的笑脸……它们承载着温度,却困在了低分辨率里。现在,不用找专业修图师&#xff…

作者头像 李华
网站建设 2026/2/13 4:48:11

C++ STL set与map深度解析

好的,我们来全面解析 C 标准模板库 (STL) 中的 set 和 map 容器。它们都是关联容器,核心功能是基于键高效地存储和检索数据。一、 共同基础:有序性与底层结构有序性 (Sorted):set 和 map 中的元素(对于 set 是整个元素&#xff0c…

作者头像 李华
网站建设 2026/2/13 9:39:14

SeqGPT-560M轻量高效部署:1.1GB模型在消费级RTX 3090上流畅运行

SeqGPT-560M轻量高效部署:1.1GB模型在消费级RTX 3090上流畅运行 你是不是也遇到过这样的问题:想快速验证一个文本理解任务,却要花半天搭环境、下载模型、写推理脚本?训练数据还没凑齐,显存已经爆了。今天要聊的这个模…

作者头像 李华
网站建设 2026/2/11 16:02:23

小白必看!灵毓秀-牧神-造相Z-Turbo文生图模型保姆级使用指南

小白必看!灵毓秀-牧神-造相Z-Turbo文生图模型保姆级使用指南 前言: 最近在AI绘画圈里刷到一个特别有意思的小众模型——灵毓秀-牧神-造相Z-Turbo。它不是泛泛而谈的“古风美女”,而是专为《牧神记》原著粉丝打造的定制化文生图模型&#xff…

作者头像 李华
网站建设 2026/2/7 16:20:53

[工业自动化-33]:什么是线性自动控制系统与非线性自动控制系统?

我们用通俗易懂、生活化的方式来解释线性自动控制系统 和非线性自动控制系统 的区别。 🌟 一句话总结: 线性系统:输入加倍,输出也加倍,行为“规矩”、可预测。 非线性系统:输入加倍,输出可能翻倍…

作者头像 李华