Python 减少pyomo模型的内存需求

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(

我正在构建一个大的pyomo模型,其中包含超过100万个约束和200万个变量

我正在寻找减少我正在构建的模型的内存需求的建议

目前,它需要超过20gb的RAM

我该如何减少这个

我从未测试过在=pyomo.nonnegativerelals中使用/不使用
定义变量。但我假设它会减少给定变量所需的内存量。在不减少变量或约束的情况下,我还可以做其他事情吗

例如:

以下
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吗