• 文档 >
  • 模块代码 >
  • torch >
  • torch.onnx >
  • torch.onnx._internal.exporter._verification
快捷键

源代码用于 torch.onnx._internal.exporter._verification

来自 未来 导入 注释


__all__ = [
    "验证信息",
    "验证 ONNX 程序",
]

导入 dataclasses
导入 记录日志
导入 数学
来自 打字 导入 任意, 类型检查

导入 火炬
来自 torch.utils 导入 _pytree


如果 类型检查:
    来自 onnxscript 导入 ir

    来自 torch.onnx._internal.exporter 导入 _onnx 程序


日志记录器 = 记录日志.获取日志记录器(__name__)


@dataclasses.数据类
 验证信息:
    验证 ONNX 程序中一个值的验证信息。

这个类包含最大绝对差异、最大相对差异、
预期值与实际值之间的绝对和相对差异直方图
值。它还包括预期和实际的数据类型。

历史图表示为张量的元组,其中第一个张量是历史图计数,第二个张量是边界。
名称:值的名称(输出或中间值)。

属性:
名称:值的名称(输出或中间值)。
最大绝对差:预期值与实际值之间的最大绝对差。
最大相对差:预期值与实际值之间的最大相对差。
绝对差直方图:表示绝对差直方图的张量元组。
第一个张量是直方图计数,第二个张量是箱边。
rel_diff_hist:表示相对差异直方图的张量元组。
第一个张量是直方图计数,第二个张量是箱边。
expected_dtype:预期值的类型。
actual_dtype:实际值的类型。
```python
# 假设输入文本为:
input_text = '"""'

# 翻译函数(此处仅为示例,实际翻译功能需要调用真实的翻译 API)
def translate_to_simplified_chinese(text):
    # 这里应该调用真实的翻译 API 进行翻译
    # 由于示例中不使用真实的 API,以下为模拟翻译结果
    return text

# 输出翻译结果
translated_text = translate_to_simplified_chinese(input_text)
print(translated_text)
```

    名称: 字符串
    最大绝对差: 浮点数
    最大相对差: 浮点数
    绝对差分历史: 元组[火炬.张量, 火炬.张量]
    相对差分历史: 元组[火炬.张量, 火炬.张量]
    预期数据类型: 火炬.dtype
    实际数据类型: 火炬.dtype
    # NOTE: 我们不需要包括形状,因为预期的形状已经已知
    # 并且由运行时检查

[文档] @类方法 def from_tensors( cls, name: str, expected: torch.Tensor | float | int | bool, actual: torch.Tensor | float | int | bool, ) -> VerificationInfo: """从两个张量创建一个 VerificationInfo 对象。 Args: 名称:值的名称。 预期:预期的张量。 实际:实际的张量。 返回值: 验证信息对象:VerificationInfo 对象。 """ 如果 expected 不是 torch.Tensor 类型: expected = torch.tensor(expected) 如果实际不是 torch.Tensor 类型: 实际 = torch.tensor(actual) max_abs_diff, max_rel_diff, abs_diff, rel_diff = _compare_tensors( 预期,实际 ) bins = torch.tensor( [0.0, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1, 1.0, 10, 1000000], dtype=torch.float, ) abs_diff_hist = torch.histogram(abs_diff.float(), bins=bins) rel_diff_hist = torch.histogram(rel_diff.float(), bins=bins) return cls( name=name, max_abs_diff=max_abs_diff, max_rel_diff=max_rel_diff, abs_diff_hist=abs_diff_hist, rel_diff_hist=rel_diff_hist, expected_dtype=expected.dtype, actual_dtype=actual.dtype, )
def 比较张量( 预期
: 火炬.张量, 实际: 火炬.张量, ) -> 元组[float, float, 火炬.张量, 火炬.张量]: 将张量移动到同一设备 预期 = 预期.detach().cpu() 实际的 = 实际.detach().cpu() 如果 预期.元素数量() == 0 实际.元素数量() == 0: 返回 数学.无穷, 数学.无穷, 火炬.张量(数学.无穷), 火炬.张量(数学.无穷) 如果 预期.dtype == 火炬.布尔: 预期 = 预期.(火炬.float32) 实际的 = 实际.(火炬.float32) 如果 火炬.是复杂的(预期): 预期 = 火炬.真实查看(预期) 绝对差 = 火炬.绝对值(预期 - 实际) eps = 1e-7 标准化器 = 火炬.绝对值(预期) + eps 相对差 = 绝对差 / 标准化器 最大绝对差异 = 绝对差.最大值().项目() 最大相对差异 = 相对差异.最大值().项目() 返回 最大绝对差值, 最大相对差值, 绝对差, 相对差 def verify_onnx_program( ONNX 程序: _onnx_program.ONNX 程序, 参数: 元组[任意, ...] | None = , kwargs: 字典[字符串, 任意] | None = , 比较中间变量: 布尔类型 = 错误, ) -> 列表[验证信息]: 验证 ONNX 模型,通过比较与从 ExportedProgram 导出的预期值。 参数: onnx_program: 要验证的 ONNX 程序。 args: 模型的输入参数。 kwargs: 模型的关键字参数。 比较中间值:是否验证中间值。这是否 因此需要更长时间,所以默认情况下已禁用。 返回: 包含每个值验证信息的 VerificationInfo 对象。 ```python # 假设输入文本为: input_text = '"""' # 翻译函数(此处仅为示例,实际翻译功能需要调用真实的翻译 API) def translate_to_simplified_chinese(text): # 这里应该调用真实的翻译 API 进行翻译 # 由于示例中不使用真实的 API,以下为模拟翻译结果 return text # 输出翻译结果 translated_text = translate_to_simplified_chinese(input_text) print(translated_text) ``` 导出程序 = onnx 程序.导出程序 如果 导出程序 : 抛出异常 ValueError( "ONNX 程序不包含导出的程序。" "请提供一个导出的程序以验证 ONNX 程序。" ) 如果 args None kwargs : # 用户未提供示例输入,使用默认示例输入 如果 导出的程序.示例输入 : 抛出异常 ValueError( "未提供示例输入,且 exported_program 不包含示例输入。" "请提供参数以验证 ONNX 程序。" ) 参数, kwargs = 导出的程序.示例输入 如果 args : args = () 如果 kwargs : kwargs = {} # 将 ONNX 程序和 VerificationInterpreter 的参数扁平化 平铺参数, _ = 导出的程序._get_flat_args_with_check(参数, kwargs) 如果 not 比较中间结果: # Compare the output values 火炬输出, _ = _pytree.树扁平化( 导出的程序.模块()(*参数, **kwargs) ) ONNX 输出 = ONNX 程序(*平铺参数) 结果 = [] 火炬输出, ONNX 输出, 输出值 压缩( 火炬输出, ONNX 输出, onnx 程序.模型..输出 ): 结果.追加( 验证信息.从张量中( 名称=字符串(输出值.名称), 预期=torch 输出, 实际=onnx 输出, ) ) 返回 结果 使用 _VerificationInterpreter 获取中间值 按设计输出值也包含在内 解释器 = _VerificationInterpreter(onnx_program) 解释器.run(*平铺参数) 返回 解释器.验证信息 def 创建值映射(: ir.) -> 字典[字符串, ir.]: 返回一个字典,将名称映射到图中的值。 该映射不包括子图中的值。 参数: 图:提取映射的图。 返回: 一个将名称映射到值的字典。 ```python # 假设输入文本为: input_text = '"""' # 翻译函数(此处仅为示例,实际翻译功能需要调用真实的翻译 API) def translate_to_simplified_chinese(text): # 这里应该调用真实的翻译 API 进行翻译 # 由于示例中不使用真实的 API,以下为模拟翻译结果 return text # 输出翻译结果 translated_text = translate_to_simplified_chinese(input_text) print(translated_text) ``` values = {} .更新(.初始化器) 值的名称可以是 None 或 "",我们需要排除这些。 输入 .输入: 如果 not 输入.名称: 继续 [输入.名称] = 输入 节点 : value 节点.输出: 如果 not .名称: 继续 [.名称] = value 返回 values _VerificationInterpreter(火炬.fx.解释器): "用于验证转换后的 ONNX 模型准确性的解释器,通过比较中间值。" 要比较模型,首先使用 ONNX 程序初始化解释器。 然后,使用输入参数调用 :meth:`run` 方法来执行模型。 The :meth:`run` 方法将执行模型并填充每个值的验证信息。 attr:`verification_infos` 属性包含每个值的验证信息。 :: onnx_program = torch.onnx.export(model, args, dynamo=True) interpreter = _VerificationInterpreter(onnx_program) interpreter.run(*args) verification_infos = interpreter.verification_infos for info in verification_infos: print("value name:", info.name, info) 验证信息包括最大绝对差,最大相对差 差异以及预期值之间绝对和相对差异的直方图 实际值。请参阅::class:`VerificationInfo` 以获取更多详细信息。 属性: verification_infos:每个值的验证信息列表。 当调用 `run` 方法时,它会被填充。 ```python # 假设输入文本为: input_text = '"""' # 翻译函数(此处仅为示例,实际翻译功能需要调用真实的翻译 API) def translate_to_simplified_chinese(text): # 这里应该调用真实的翻译 API 进行翻译 # 由于示例中不使用真实的 API,以下为模拟翻译结果 return text # 输出翻译结果 translated_text = translate_to_simplified_chinese(input_text) print(translated_text) ``` def 初始化(自身, onnx_program: 火炬.onnx.ONNX 程序) -> : """使用 ONNX 程序初始化 _VerificationInterpreter。""" 参数: onnx_program: 要验证的 ONNX 程序。 ```python # 假设输入文本为: input_text = '"""' # 翻译函数(此处仅为示例,实际翻译功能需要调用真实的翻译 API) def translate_to_simplified_chinese(text): # 这里应该调用真实的翻译 API 进行翻译 # 由于示例中不使用真实的 API,以下为模拟翻译结果 return text # 输出翻译结果 translated_text = translate_to_simplified_chinese(input_text) print(translated_text) ``` 如果 onnx 程序.导出程序 : 抛出异常 ValueError( "ONNX 程序不包含 exported_program。" "请提供一个 exported_program 以验证 ONNX 程序。" ) 超级().初始化(onnx 程序.导出的程序.模块()) 自身._onnx 程序 = onnx 程序 自身._onnx 值 = _创建值映射(onnx 程序.模型.) 自身._args: 元组[任意, ...] = () 自身.验证信息: 列表[验证信息] = [] def run( 自身, *参数: 任意, 初始环境: 字典[火炬.fx.节点, 任意] | None = , 启用 IO 处理: 布尔类型 = True, ) -> 任意: 使用给定的输入参数运行解释器。 此方法执行模型并填充每个值的验证信息到 :attr:`verification_infos` 属性。 以每个值的验证信息填充 :attr:`verification_infos` 属性。 参数: 输入参数:模型的输入参数。 初始环境:解释器的初始环境。 启用 IO 处理:是否启用 IO 处理。 返回: 任何:执行模型的结果。 ```python # 假设输入文本为: input_text = '"""' # 翻译函数(此处仅为示例,实际翻译功能需要调用真实的翻译 API) def translate_to_simplified_chinese(text): # 这里应该调用真实的翻译 API 进行翻译 # 由于示例中不使用真实的 API,以下为模拟翻译结果 return text # 输出翻译结果 translated_text = translate_to_simplified_chinese(input_text) print(translated_text) ``` 自身.验证信息 = [] 自身._args = args 返回 超级().run( *参数, 初始环境=初始环境, 启用 IO 处理=启用 IO 处理, ) def 运行节点(自身, n: 火炬.fx.节点) -> 任意: 结果 = 超级().运行节点(n) 如果 n.操作符 != 调用函数: 返回 结果 节点名称 = n.名称 如果 节点名称 not 自身._onnx_values: 返回 结果 try: (onnx 结果,) = 自身._onnx_program.计算值([节点名称] 自身._args) 除了 异常 作为 e: 记录器.警告( 无法计算节点值%s: %s", 节点名称, e, ) 返回 结果 信息 = 验证信息.from_tensors( 名称=节点名称, 预期=结果, 实际=onnx_result, ) 自身.verification_infos.追加(信息) 如果 信息.max_abs_diff > 0.01 信息.最大相对差异 > 0.1: 记录器.警告( 节点验证信息%s最大绝对差异:%s,最大相对差异:%s", 节点名称, 信息.最大绝对差, 信息.最大相对差, ) 否则: 记录器.信息( 节点验证信息%s最大绝对差值:%s, 最大相对差值:%s", 节点名称, 信息.最大绝对差, 信息.最大相对差, ) 返回 结果

© 版权所有 PyTorch 贡献者。

使用 Sphinx 构建,并使用 Read the Docs 提供的主题。

文档

查看 PyTorch 的全面开发者文档

查看文档

教程

深入了解初学者和高级开发者的教程

查看教程

资源

查找开发资源,获取您的疑问解答

查看资源