Python 减少pyomo模型的内存需求
我正在构建一个大的pyomo模型,其中包含超过100万个约束和200万个变量 我正在寻找减少我正在构建的模型的内存需求的建议 目前,它需要超过20gb的RAM 我该如何减少这个 我从未测试过在=pyomo.nonnegativerelals中使用/不使用Python 减少pyomo模型的内存需求,python,memory,pyomo,reducing,Python,Memory,Pyomo,Reducing,我正在构建一个大的pyomo模型,其中包含超过100万个约束和200万个变量 我正在寻找减少我正在构建的模型的内存需求的建议 目前,它需要超过20gb的RAM 我该如何减少这个 我从未测试过在=pyomo.nonnegativerelals中使用/不使用定义变量。但我假设它会减少给定变量所需的内存量。在不减少变量或约束的情况下,我还可以做其他事情吗 例如: 以下var将需要X字节的内存 m.var = pyomo.Var( m.index) m.var = pyomo.Var(
定义变量。但我假设它会减少给定变量所需的内存量。在不减少变量或约束的情况下,我还可以做其他事情吗
例如:
以下var
将需要X
字节的内存
m.var = pyomo.Var(
m.index)
m.var = pyomo.Var(
m.index,
within=pyomo.NonNegativeReals)
下面可能需要X-1
字节的内存
m.var = pyomo.Var(
m.index)
m.var = pyomo.Var(
m.index,
within=pyomo.NonNegativeReals)
当然,这是一种猜测。如果不进行测试,就无法确定这一点。但是,如果有人对这个问题有想法或有更多的经验,我愿意尝试任何事情
有什么想法吗
一些测试:
请记住,这不是真实的模型,而是使用其他数据构建的示例。但还是一样的剧本
index=1000 // Full Consts // 347580 KB (commit) // 370652 KB (working set)
0 Const Full Rules // 282416 KB (commit) // 305252 KB (working set)
0 Const 0 Rule // 282404 KB (commit) // 305200 KB (working set)
1 Const 1 Rule // 290408 KB (commit) // 313136 KB (working set)
index=8760 // Full Consts // 1675860 KB (commit) // 1695676 KB (working set)
我使用了pympler
来分析您指给我的测试用例。以下是我的发现:
在pyomo\u model\u prep
之后(加载数据并将其放置到空的ConcreteModel
):
内存使用率为13.2MB
添加所有Set
和Param
对象后:
内存使用率为13.3 MB
添加所有Var
对象后:
内存使用率为14.3 MB
添加所有约束后
对象:
内存使用率为15.0 MB
当我将timesteps设置为60时,结果是
内存使用率为13.2MB(数据)
内存使用率为13.3MB(在集合之后,参数)
内存使用率为19.6MB(vars之后)
内存使用率为23.6 MB(在限制之后)
因此,当有大量的时间步时,变量确实对模型内存有很大的影响。我所能看到的减少内存使用的唯一明显的地方是不将所有数据存储在模型上(或者在不再需要数据后将其从模型中删除),那么可能未使用的数据将被垃圾收集器清除
不幸的是,没有任何简单的方法来减少变量声明的内存
更新1:仅供参考,几乎所有变量声明的内存使用都是e_pro_in
和e_pro_out
索引变量的结果
更新2:如果模型中未使用大量e_pro_in
和e_pro_out
变量的索引,则可以通过为每个变量建立一个简化的索引集来减少内存需求。下面是可能的情况:
e_pro_in_index = []
for t in m.tm:
for i,j in m.pro_tuples:
for c in m.com:
if ...:
e_pro_in_index.append((t,i,j,c))
m.e_pro_in_index = Set(dimen=4, initialize=e_pro_in_index)
m.e_pro_in = pyomo.Var(
m.e_pro_in_index,
within=pyomo.NonNegativeReals,
doc='Power flow of commodity into process (MW) per timestep')
您需要从约束规则中提取逻辑,以确定哪些索引是不需要的。我使用了pympler
来分析您指给我的测试用例。以下是我的发现:
在pyomo\u model\u prep
之后(加载数据并将其放置到空的ConcreteModel
):
内存使用率为13.2MB
添加所有Set
和Param
对象后:
内存使用率为13.3 MB
添加所有Var
对象后:
内存使用率为14.3 MB
添加所有约束后
对象:
内存使用率为15.0 MB
当我将timesteps设置为60时,结果是
内存使用率为13.2MB(数据)
内存使用率为13.3MB(在集合之后,参数)
内存使用率为19.6MB(vars之后)
内存使用率为23.6 MB(在限制之后)
因此,当有大量的时间步时,变量确实对模型内存有很大的影响。我所能看到的减少内存使用的唯一明显的地方是不将所有数据存储在模型上(或者在不再需要数据后将其从模型中删除),那么可能未使用的数据将被垃圾收集器清除
不幸的是,没有任何简单的方法来减少变量声明的内存
更新1:仅供参考,几乎所有变量声明的内存使用都是e_pro_in
和e_pro_out
索引变量的结果
更新2:如果模型中未使用大量e_pro_in
和e_pro_out
变量的索引,则可以通过为每个变量建立一个简化的索引集来减少内存需求。下面是可能的情况:
e_pro_in_index = []
for t in m.tm:
for i,j in m.pro_tuples:
for c in m.com:
if ...:
e_pro_in_index.append((t,i,j,c))
m.e_pro_in_index = Set(dimen=4, initialize=e_pro_in_index)
m.e_pro_in = pyomo.Var(
m.e_pro_in_index,
within=pyomo.NonNegativeReals,
doc='Power flow of commodity into process (MW) per timestep')
您需要从约束规则中提取逻辑,以确定哪些索引是不需要的。您的模型是平面的(即,它只包含顶级的具体模型
或抽象模型
),还是由许多块
对象组成?@GabeHackebeil它只包含具体模型
,它实际上是在为给定的m.index
构建相同的变量,如果优化1h,则索引将为1。但是,如果您优化一年,索引将为1到8760,ofc将增加变量和约束的数量…我可以向您指出另一种接口,该接口可以使用较少的内存来表示线性约束,但首先我要确保,当约束行可以稀疏时,您不会将其表示为密集表达式。你能把内存使用的范围缩小到一个特定的索引约束吗(通过注释掉所有其他约束)?不是每个约束都有相同的索引,但是在很多情况下,约束包括时间索引,这使得模型更胖。。。我将尝试缩小模型的范围,并尝试获得1约束(带索引)的mem用法,并将其添加到这里。。。顺便问一下,有没有一种简单的方法来检查所创建模型的内存?比检查任务管理器更好您可以查看类似于pympler
的包,但任务管理器可能是更快的途径。您的型号是fl吗