当前位置: 首页 > news >正文

torch.jit.script编译加速推理的尝试

我也不知道有什么意义,但好歹推进了一点

Bug1

RuntimeError: Type ‘<class ‘actor.model.Model’>’ cannot be compiled since it inherits from nn.Module, pass an instance instead Model类前加了@torch.jit.script,请问这是什么原因

GPT
在 PyTorch 中,@torch.jit.script 装饰器用于将 Python 函数或类编译为 TorchScript,这是一种可以在 C++ 环境中运行的中间表示形式。TorchScript 允许你将 PyTorch 模型导出并在没有 Python 解释器的环境中运行。

当你在一个继承自 nn.Module 的类上使用 @torch.jit.script 时,可能会遇到 RuntimeError: Type '<class 'actor.model.Model'>' cannot be compiled since it inherits from nn.Module, pass an instance instead 这个错误。这是因为 @torch.jit.script 期望的是一个函数或类的实例,而不是类本身。

要解决这个问题,你可以使用 @torch.jit.script 装饰器来装饰类中的方法,而不是整个类。以下是一个示例:

import torch
import torch.nn as nnclass MyModel(nn.Module):def __init__(self):super(MyModel, self).__init__()self.linear = nn.Linear(10, 5)@torch.jit.script_methoddef forward(self, x):return self.linear(x)# 创建模型实例
model = MyModel()# 使用 TorchScript 编译模型
scripted_model = torch.jit.script(model)# 现在可以使用 scripted_model
input_tensor = torch.randn(1, 10)
output = scripted_model(input_tensor)
print(output)

在这个示例中,forward 方法被装饰为 @torch.jit.script_method,而不是直接在类上使用 @torch.jit.script。这样可以避免你遇到的错误。

总结一下,确保你在 nn.Module 的实例方法上使用 @torch.jit.script_method,而不是在类定义上使用 @torch.jit.script

方案:

在network.forward()前加@torch.jit.script

Bug2

RuntimeError:
‘Tensor (inferred)’ object has no attribute or method ‘all_hero_feature_dim’.:
File “.\aiarena\process…\code\common\algorithm_torch.py”, line 222
feature_vec_split_list = feature_vec.split(
[
self.all_hero_feature_dim,
~~~~~~~~~~~~~~~~~~~~~~~~~ <— HERE
self.all_soldier_feature_dim,
self.all_organ_feature_dim,

方案:
修改forward中的所有成员变量为具体值

Bug3

RuntimeError:
‘Tensor (inferred)’ object has no attribute or method ‘hero_main_mlp’.:
File “.\aiarena\process…\code\common\algorithm_torch.py”, line 323
“”" real computations"“”
hero_main_result = self.hero_main_mlp(_hero_main)
~~~~~~~~~~~~~~~~~~ <— HERE
hero_emy_mlp_out = self.hero_mlp(_hero_emy)

network.forward()引用成员模块,但这也要手动写,需要把network的所有子模块当作实参传入,

  • 用@torch.jit.script修饰复杂类的成员函数不现实
  • 但可以把torch.nn的实现复制过来,这样不用继承了

Bug4

转投torch.jit.trace

:List inputs to traced functions must have consistent element type. Found Tensor and Tuple[Tensor, Tensor]

torch.jit.trace()只接受 Tuple[Tensor,…,Tensor] or Tensor

Commit 0 = torch.jit.trace()编译成功!

把所有的tensor的组合(集合、列表、字典)全展成Tensor列表,一个个输入,终于编译成功了

  • 但效果未知,因为实际的模型包含了for循环,可能不支持,
  • 但本模块中的所有for均为固定格式的判断,没有if-else路径的切换,理论上是可以的

Q1

torch.jit.trace优化的模型的forward可以包含for循环吗
torch.jit.trace 是PyTorch提供的一种模型优化技术,它主要用于将Python函数式的模型转换为高效的低级张量操作,以便在推理阶段获得更快的速度。在使用trace()对模型进行追踪时,它通常假设输入数据是静态的,并且函数体中的大部分计算应该是可以直接编译的。

关于forward函数是否能包含for循环,这取决于循环内的内容能否被静态地推断出来并且转化为等效的张量操作。如果循环内部的操作是对单个输入元素进行简单变换并累积结果(例如卷积或累加),那么理论上是可以支持的。但是,复杂的条件控制、随机数生成或动态图操作通常不在trace的支持范围内,因为它们难以确定其对输入的所有可能影响。

总的来说,对于那些能够简化为固定序列运算的循环,torch.jit.trace可能会工作,但对于依赖于循环变量状态或不确定性的部分,可能会失败或者效果不佳。

Extension: trace VS script

torch.jit.trace 和 torch.jit.script 都是PyTorch用于将Python函数转换为 TorchScript(高效的低级神经网络中间表示)的方法,但它们的工作原理和性能特点有所不同。

torch.jit.trace 是基于采样(tracing)的方式,它会记录函数在特定输入上运行的路径,并生成对应的执行图。当输入在trace期间发生变化时,trace 的效果可能会受到影响,因为它是针对单个或一组输入进行优化的。如果输入数据集是静态的或者变化不大,trace 可能能提供接近原生性能的速度,因为它避免了完整的静态分析。

相比之下,torch.jit.script 则会对整个函数进行全面的静态分析,然后生成一个通用的执行计划。这种方法通常会产生更高效的代码,但它需要完整地理解和构建函数的结构,所以对于动态操作或复杂控制流,script 有时可能会比较慢,但如果模型结构不变并且可以完全分析,其速度通常优于trace。

总的来说,trace 更适合于轻量级、输入固定或者变化较小的情况,而script 更适合那些可以提前分析并优化的场景。实际性能取决于具体的用例和模型特性。

重要的是,torch.jit.script不能编译继承类!!!

考虑把nn.Module源码搬到要继承的类下面


http://www.mrgr.cn/news/50283.html

相关文章:

  • 读书笔记《PPT演讲力》大树模型
  • 如何优化 Nginx 配置
  • 用Java写一个学生类
  • RA6M5——GPIO
  • React前端框架的描述和使用方法
  • Java开发中知识点整理
  • P1439 【模板】最长公共子序列 Python 题解
  • Redis如何批量删除指定前缀的key
  • 单点登录Apereo CAS 7.1客户端登出配置及免认证页面问题
  • 安装和配置Canal
  • Linux rm命令详解
  • 面对服务器掉包的时刻困扰,如何更好的解决
  • Oracle数据库安装Windows版本
  • C++ 内存分布情况
  • 空间智能技术赋能CIM平台,为数字住建插上翅膀
  • Exporter for Unreal to Unity 2024(Unreal到Unity的导出器)
  • [Linux] 层层深入理解文件系统——(3)磁盘组织存储的文件
  • R语言统计分析——马赛克图
  • 【玩转 JS 函数式编程_013】4.1 JavaScript 纯函数的相关概念(中):函数副作用的几种具体表现
  • Linux 文件系统结构深入解析