TVM/Relay 的 PartitionGraph()(mod) 函数讨论整理

本文档详细讨论了TVM/Relay中的PartitionGraph()函数,通过示例展示了该函数在图形分区中的作用,包括错误处理、图形处理流程和期望的输出结果。同时,提到了在处理条件分支时可能出现的问题,以及如何解决这些问题。最后,通过成功案例验证了修复后的代码功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

TVM/Relay 的 PartitionGraph()(mod) 函数讨论整理
TVM/Relay 的图形分区功能。以下简单示例,错误信息。
PartitionGraph() 函数指定图形是用带有 AnnotateTarget([“target”]) 函数的目标注释的。编写了以下示例,以便能够将“add”运算符划分为一个单独的功能函数(使用relay模式语言,或遍历 AST,将add划分为一个单独的relay函数),试图了解 PartitionGraph() 如何在简单情况下工作。
这是代码:
graph_type =1
def _register_external_op_helper(op_name, supported=True):

@tvm.ir.register_op_attr(op_name, "target.special")
def _func_wrapper(attrs, args):
    return supported

return _func_wrapper

_register_external_op_helper(“add”)
_register_external_op_helper(“subtract”)

if graph_type == 1:
# this is test case for graph type 1
print(“Graph type 1”)

# graph 1: true branch
x1 = relay.var('x', shape=(10, 1))
y1 = relay.var('y', shape=(10, 1))

# graph 2: false branch
x2 = relay.var('x', shape=(10, 1))
y2 = relay.var('y', shape=(10, 1))

f1 = relay.op.add(x1, y1)

f2 = relay.op.multiply(x2, y2)

cond = relay.var('c')
result = relay.If(cond, true_branch=f1, false_branch=f2)
f = relay.Function([], result)

mod = tvm.IRModule({"main": f})

mod = relay.transform.AnnotateTarget(["special"])(mod)  # ==> It GIVES ERROR here
mod = relay.transform.PartitionGraph()(mod)  # 

这是错误信息。
Graph type 1
Traceback (most recent call last):
File “C:\Program Files\JetBrains\PyCharm 2020.1.2\plugins\python\helpers\pydev\pydevd.py”, line 1438, in _exec
pydev_imports.execfile(file, globals, locals) # execute the script
File “C:\Program Files\JetBrains\PyCharm 2020.1.2\plugins\python\helpers\pydev_pydev_imps_pydev_execfile.py”, line 18, in execfile
exec(compile(contents+"\n", file, ‘exec’), glob, loc)
File “C:/repos/tvm23/tvm/graph_opt/subgraph/PartitionGraphTry.py”, line 48, in
mod = relay.transform.AnnotateTarget([“special”])(mod) # Output: Figure 2
File “C:\repos\tvm23\tvm\python\tvm\ir\transform.py”, line 127, in call
return _ffi_transform_api.RunPass(self, mod)
File “C:\repos\tvm23\tvm\python\tvm_ffi_ctypes\packed_func.py”, line 237, in call
raise get_last_ffi_error()
tvm._ffi.base.TVMError: Traceback (most recent call last):
File “C:\repos\tvm23\tvm\src\ir\module.cc”, line 192
TVMError: Check failed: fv.size() == 0 (5 vs. 0) : There are free variables: [Var(c, ty=TensorType([], bool)), Var(x, ty=TensorType([10, 1], float32)), Var(y, ty=TensorType([10, 1], float32)), Var(x, ty=TensorType([10, 1], float32)), Var(y, ty=TensorType([10, 1], float32))] in function: #[version = “0.0.5”]
fn () -> Tensor[(10, 1), float32] {
free_var %c: bool;
if (%c) {
free_var %x: Tensor[(10, 1), float32];
free_var %y: Tensor[(10, 1), float32];
add(%x, %y) /* ty=Tensor[(10, 1), float32] /
} else {
free_var %x1: Tensor[(10, 1), float32];
free_var %y1: Tensor[(10, 1), float32];
multiply(%x1, %y1) /
ty=Tensor[(10, 1), float32] */
}
}

可能的错误原因
1) the if/else handling in this pass might not be correct.
2) apache/incubator-tvm/blob/main/tests/python/relay/test_pass_annotate_target.py
f = relay.Function([x], out)
mod = tvm.IRModule.from_expr(f)
return mod

mod = transform.AnnotateTarget("A")(before())
mod = transform.AnnotateTarget("B")(mod)
expected = transform.AnnotateTarget(["A", "B"])(before())
assert tvm.ir.structural_equal(expected, mod)

def test_if_else():
target = “test_if_else”
@tvm.ir.register_op_attr(“equal”, “target.” + target)
def relu(attrs, args): # pylint: disable=unused-variable
return True
@tvm.ir.register_op_attr(“tanh”, “target.” + target)
def tanh(attrs, args): # pylint: disable=unused-variable
return True
3) Isn’t it simply a problem of free variables? I suggest replacing
f = relay.Function([], result)
with
f = relay.Function(relay.

@@ [17:26:42][INFO]<quantize model fp16 cmd>: python3 -m dl quantize 1_handle.onnx.rlym --downcast --output-model 1_handle.onnx.fp16.rlym Traceback (most recent call last): File "/tfjz_auto/miniconda3/envs/TFDS_ARM/lib/python3.8/runpy.py", line 194, in _run_module_as_main return _run_code(code, main_globals, None, File "/tfjz_auto/miniconda3/envs/TFDS_ARM/lib/python3.8/runpy.py", line 87, in _run_code exec(code, run_globals) File "/dl/sdk/python/tvm/dl/python/dl/__main__.py", line 7, in <module> main() File "/dl/sdk/python/tvm/dl/python/dl/main.py", line 72, in main sys.exit(_main(sys.argv[1:])) File "/dl/sdk/python/tvm/dl/python/dl/main.py", line 68, in _main return args.func(args) File "/dl/sdk/python/tvm/dl/python/dl/driver/quantize.py", line 150, in drive_quantize from dl.quantize.quantize import quantize, qconfig File "/dl/sdk/python/tvm/dl/python/dl/quantize/quantize.py", line 49, in <module> from dl.quantize.analysis import ( File "/dl/sdk/python/tvm/dl/python/dl/quantize/analysis.py", line 16, in <module> from dl.quantize.quantization_lib import calibration File "/dl/sdk/python/tvm/dl/python/dl/quantize/quantization_lib.py", line 3, in <module> import tensorflow as tf File "/tfjz_auto/miniconda3/envs/TFDS_ARM/lib/python3.8/site-packages/tensorflow/__init__.py", line 37, in <module> from tensorflow.python.tools import module_util as _module_util File "/tfjz_auto/miniconda3/envs/TFDS_ARM/lib/python3.8/site-packages/tensorflow/python/__init__.py", line 45, in <module> from tensorflow.python.feature_column import feature_column_lib as feature_column File "/tfjz_auto/miniconda3/envs/TFDS_ARM/lib/python3.8/site-packages/tensorflow/python/feature_column/feature_column_lib.py", line 18, in <module> from tensorflow.python.feature_column.feature_column import * File "/tfjz_auto/miniconda3/envs/TFDS_ARM/lib/python3.8/site-packages/tensorflow/python/feature_column/feature_column.py", line 143, in <module> from tensorflow.python.layers import base File "/tfjz_auto/miniconda3/envs/TFDS_ARM/lib/python3.8/site-packages/tensorflow/python/layers/base.py", line 16, in <module> from tensorflow.python.keras.legacy_tf_layers import base File "/tfjz_auto/miniconda3/envs/TFDS_ARM/lib/python3.8/site-packages/tensorflow/python/keras/__init__.py", line 25, in <module> from tensorflow.python.keras import models File "/tfjz_auto/miniconda3/envs/TFDS_ARM/lib/python3.8/site-packages/tensorflow/python/keras/models.py", line 22, in <module> from tensorflow.python.keras.engine import functional File "/tfjz_auto/miniconda3/envs/TFDS_ARM/lib/python3.8/site-packages/tensorflow/python/keras/engine/functional.py", line 32, in <module> from tensorflow.python.keras.engine import training as training_lib File "/tfjz_auto/miniconda3/envs/TFDS_ARM/lib/python3.8/site-packages/tensorflow/python/keras/engine/training.py", line 54, in <module> from tensorflow.python.keras.saving import hdf5_format ImportError: cannot import name 'hdf5_format' from 'tensorflow.python.keras.saving' (/tfjz_auto/miniconda3/envs/TFDS_ARM/lib/python3.8/site-packages/tensorflow/python/keras/saving/__init__.py) @@ [17:26:52][INFO]<nne execute>: static build [NNE]python3 -m dl convert --optimize 1_handle.onnx.fp16.rlym --output-model /tmp/.330450//temp_i9x3MV.rlym --outputs "output onnx::Sigmoid_741 onnx::Sigmoid_927 onnx::Sigmoid_1111 " load dlnne_plugin.so && libdlnne_tvm_plugin.so success Traceback (most recent call last): File "/tfjz_auto/miniconda3/envs/TFDS_ARM/lib/python3.8/runpy.py", line 194, in _run_module_as_main return _run_code(code, main_globals, None, File "/tfjz_auto/miniconda3/envs/TFDS_ARM/lib/python3.8/runpy.py", line 87, in _run_code exec(code, run_globals) File "/dl/sdk/python/tvm/dl/python/dl/__main__.py", line 7, in <module> main() File "/dl/sdk/python/tvm/dl/python/dl/main.py", line 72, in main sys.exit(_main(sys.argv[1:])) File "/dl/sdk/python/tvm/dl/python/dl/main.py", line 68, in _main return args.func(args) File "/dl/sdk/python/tvm/dl/python/dl/driver/convert.py", line 231, in drive_convert tvmc_model = load_model(model, shape_dict=args.input_shapes, **kwargs) File "/dl/sdk/python/tvm/python/tvm/driver/tvmc/frontends.py", line 412, in load_model mod, params = frontend.load(path, shape_dict, **kwargs) File "/dl/sdk/python/tvm/dl/python/dl/relay/frontend/frontends.py", line 185, in load assert os.path.exists(path), "{} doesn't exist".format(path) AssertionError: 1_handle.onnx.fp16.rlym doesn't exist terminate called after throwing an instance of 'std::logic_error' what(): basic_string::_M_construct null not valid
最新发布
08-01
<think>我们正在处理两个独立但可能相关的问题: 1. ImportError: cannot import name 'hdf5_format' from 'tensorflow.python.keras.saving' 2. 在模型转换时遇到文件不存在的 AssertionError 首先,我们针对第一个问题:无法导入 'hdf5_format' 根据之前的分析,这个错误通常是因为代码中尝试导入了一个在较新版本TensorFlow中已经被移除或重构的模块。在TensorFlow 2.x的早期版本中,`hdf5_format`模块确实存在,但在后续版本中被移除了。 解决方案: 1. 避免直接导入内部模块。应该使用Keras提供的高级API来保存和加载模型。 2. 检查代码中是否有类似以下导入语句: ```python from tensorflow.python.keras.saving import hdf5_format ``` 如果有,请删除它,并改用标准的模型保存和加载方法。 标准保存和加载模型的方法: ```python # 保存模型为HDF5格式 model.save('my_model.h5') # 加载模型 from tensorflow.keras.models import load_model model = load_model('my_model.h5') ``` 另外,如果用户使用的是自定义对象(如自定义损失函数),在加载模型时需要传递`custom_objects`参数: ```python model = load_model('my_model.h5', custom_objects={'dice_loss': dice_loss}) ``` 第二个问题:模型转换时提示文件不存在 这个错误可能是由于文件路径错误或文件确实不存在导致的。需要检查以下几点: 1. 确认文件路径是否正确,包括文件名和扩展名。 2. 确认在转换之前模型已经成功保存,即保存模型的文件确实存在。 3. 如果使用的是相对路径,注意当前工作目录是否与预期一致。 例如,在转换模型之前,我们通常需要先保存模型: ```python model.save('model.h5') # 保存为HDF5格式 ``` 然后,在转换脚本中,确保加载这个文件: ```python # 假设使用TensorFlow Lite转换 converter = tf.lite.TFLiteConverter.from_keras_model('model.h5') ``` 但是,请注意:`TFLiteConverter.from_keras_model`方法期望的是一个Keras模型对象,而不是文件路径。正确的方法是先加载模型,或者直接使用已经存在于内存中的模型。或者,也可以使用保存的HDF5文件来转换: 方法1:从已保存的HDF5文件转换(使用`from_keras_model`需要先加载模型,这样会占用内存,另一种方法是使用`from_saved_model`,但这里我们讨论HDF5): ```python # 先加载模型 model = tf.keras.models.load_model('model.h5') converter = tf.lite.TFLiteConverter.from_keras_model(model) ``` 方法2:使用`from_saved_model`函数,但要求模型必须是以SavedModel格式保存的(TensorFlow默认的保存格式): ```python # 保存为SavedModel格式(目录) model.save('saved_model') # 这会创建一个目录 # 然后转换 converter = tf.lite.TFLiteConverter.from_saved_model('saved_model') ``` 因此,如果遇到文件不存在的错误,请检查: - 文件路径是否正确 - 文件是否已经成功保存 另外,如果用户使用的是HDF5格式,确保在保存时没有出现错误,并且文件已经完整写入。 总结步骤: 1. 修复导入错误:移除对`hdf5_format`的直接导入,改用标准API保存模型。 2. 确保模型保存成功:使用`model.save`保存模型后,检查文件是否存在。 3. 在转换模型时,使用正确的转换方法,并确保提供的文件路径正确。 如果用户正在尝试将模型转换为其他格式(如TFLite),并且遇到了文件不存在的问题,请确保在转换之前已经正确保存了模型,并且在转换代码中引用了正确的路径。 注意:在TensorFlow 2.x中,推荐使用SavedModel格式进行保存,因为这是TensorFlow的标准格式,而HDF5格式在Keras中也被支持,但在某些情况下(如自定义层)可能不如SavedModel稳定。 最后,如果用户的问题是在一个脚本中同时遇到这两个问题,那么修改后的代码流程应该是: 原始错误代码可能类似于: ```python from tensorflow.python.keras.saving import hdf5_format # 这行会导致ImportError # ... 构建模型 ... # 保存模型(可能使用hdf5_format内部函数) hdf5_format.save_model_to_hdf5(model, 'model.h5') # 然后转换模型 converter = tf.lite.TFLiteConverter.from_keras_model_file('model.h5') # 假设这个函数存在(实际上可能不存在) ``` 修改后: ```python # 移除有问题的导入 # ... 构建模型 ... # 使用标准方法保存模型 model.save('model.h5') # 或者使用 model.save('saved_model') 保存为SavedModel格式 # 转换模型 # 注意:TFLiteConverter的API可能会变化,以下为2.x版本的常用方法 # 方法1:从HDF5文件加载模型然后转换(需要先加载模型) model = tf.keras.models.load_model('model.h5') converter = tf.lite.TFLiteConverter.from_keras_model(model) # 或者方法2:如果保存为SavedModel格式,则可以直接从目录转换 # converter = tf.lite.TFLiteConverter.from_saved_model('saved_model') tflite_model = converter.convert() with open('model.tflite', 'wb') as f: f.write(tflite_model) ``` 这样,两个问题应该都能解决。 注意:在转换模型时,如果模型包含自定义层或自定义损失函数(如Dice loss),需要在加载模型时通过`custom_objects`参数传入,否则会报错。 例如,在加载模型时: ```python model = tf.keras.models.load_model('model.h5', custom_objects={'dice_loss': dice_loss}) ``` 其中`dice_loss`是用户定义的损失函数,需要在当前作用域可访问。 如果用户没有定义这个函数,则需要先定义它,或者使用一个等效的字符串(如果Keras内置支持的话,但Dice loss通常需要自定义)。 因此,用户需要确保在加载模型之前已经定义了所有自定义对象。 综上所述,我们通过以下步骤解决问题: 1. 移除对`hdf5_format`的导入,使用标准API保存模型。 2. 确保保存模型的文件存在,并在转换时使用正确的路径和API。 3. 处理自定义对象(如自定义损失函数)以确保模型正确加载。 如果用户按照这些步骤操作,应该能够解决这两个问题。 生成相关问题: 1. 如何在TensorFlow 2.x中正确保存和加载包含自定义层的模型? 2. 如何将Keras模型转换为TensorFlow Lite格式? 3. 在模型转换过程中遇到自定义损失函数错误怎么办? 4. TensorFlow中SavedModel格式和HDF5格式有什么区别?</think>### 解决 TensorFlow 无法导入 `hdf5_format` 的问题 #### 原因分析 `hdf5_format` 是 TensorFlow 的内部模块,在 2.6+ 版本中已被移除或重构。直接导入该模块会导致 `ImportError`[^2]。 #### 解决方案 1. **使用标准 API 替代** 避免直接调用内部模块,改用 Keras 的标准保存/加载方法: ```python # 保存模型(HDF5格式) model.save('model.h5') # 加载模型 from tensorflow.keras.models import load_model loaded_model = load_model('model.h5', custom_objects={'dice_loss': dice_loss}) # 包含自定义损失函数 ``` 2. **检查版本兼容性** 若必须使用旧版 API: ```bash pip install tensorflow==2.5.0 # 降级到包含该模块的版本 ``` 3. **处理自定义损失函数** 确保 Dice loss 等自定义函数已正确定义并在加载时传入: ```python # 定义Dice loss函数 def dice_loss(y_true, y_pred): # 实现代码... return loss ``` --- ### 解决模型转换时的文件不存在错误 #### 原因分析 `AssertionError` 通常由以下原因导致: 1. 文件路径错误或未生成 2. 模型未正确保存 3. 文件权限问题 #### 解决方案 1. **验证文件路径** 添加路径检查代码: ```python import os model_path = 'model.h5' assert os.path.exists(model_path), f"文件不存在: {model_path}" ``` 2. **确保模型正确保存** 检查保存操作是否成功执行: ```python try: model.save(model_path) print(f"模型已保存至: {os.path.abspath(model_path)}") except Exception as e: print(f"保存失败: {str(e)}") ``` 3. **转换模型时的完整流程** 使用标准转换 API: ```python # 保存模型 model.save(model_path) # 转换为TFLite格式 converter = tf.lite.TFLiteConverter.from_keras_model(model) tflite_model = converter.convert() with open('model.tflite', 'wb') as f: f.write(tflite_model) ``` 4. **处理路径规范** 使用绝对路径避免歧义: ```python import pathlib model_path = pathlib.Path('model.h5').resolve() ``` --- ### 完整修复流程 ```python import tensorflow as tf from pathlib import Path # 1. 定义自定义损失函数 def dice_loss(y_true, y_pred): # Dice loss实现代码 return loss_value # 2. 构建并保存模型 model = build_your_model() # 替换为实际模型构建函数 model_path = Path("model.h5").resolve() try: model.save(str(model_path)) print(f"✅ 模型保存成功: {model_path}") except Exception as e: print(f"❌ 保存失败: {str(e)}") # 3. 验证文件存在 assert model_path.exists(), f"文件不存在: {model_path}" # 4. 加载模型 try: loaded_model = tf.keras.models.load_model( str(model_path), custom_objects={'dice_loss': dice_loss} ) print("✅ 模型加载成功") except Exception as e: print(f"❌ 加载失败: {str(e)}") # 5. 模型转换 converter = tf.lite.TFLiteConverter.from_keras_model(loaded_model) tflite_model = converter.convert() output_path = Path("model.tflite").resolve() with open(output_path, 'wb') as f: f.write(tflite_model) print(f"✅ TFLite模型保存至: {output_path}") ``` ### 关键预防措施 1. **避免内部 API**:不再使用 `from tensorflow.python.keras.saving import hdf5_format` 2. **路径处理**:使用 `pathlib` 处理路径,避免字符串拼接错误 3. **版本控制**:保持 TensorFlow 和依赖库版本一致 4. **错误处理**:添加 try-except 块捕获具体错误信息[^2]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值