gpt4 book ai didi

memory-leaks - IPython.parallel 模块中的内存泄漏?

转载 作者:行者123 更新时间:2023-12-05 00:01:49 25 4
gpt4 key购买 nike

我正在使用 IPython.parallel 处理集群上的大量数据。我运行的远程功能如下所示:

def evalPoint(point, theta):
# do some complex calculation
return (cost, grad)

由该函数调用:
def eval(theta, client, lview, data):
async_results = []
for point in data:
# evaluate current data point
ar = lview.apply_async(evalPoint, point, theta)
async_results.append(ar)

# wait for all results to come back
client.wait(async_results)

# and retrieve their values
values = [ar.get() for ar in async_results]

# unzip data from original tuple
totalCost, totalGrad = zip(*values)

avgGrad = np.mean(totalGrad, axis=0)
avgCost = np.mean(totalCost, axis=0)

return (avgCost, avgGrad)

如果我运行代码:
client = Client(profile="ssh")
client[:].execute("import numpy as np")

lview = client.load_balanced_view()

for i in xrange(100):
eval(theta, client, lview, data)

内存使用量不断增长,直到我最终用完(76GB 内存)。我已经简化了 evalPoint什么都不做,以确保它不是罪魁祸首。
eval的第一部分是从 IPython 的关于如何使用负载均衡器的文档中复制的。第二部分(解压缩和平均)相当简单,所以我认为这不是内存泄漏的原因。此外,我尝试手动删除 eval 中的对象。并调用 gc.collect()没有运气。

我希望有 IPython.parallel 经验的人可以指出我做错了一些明显的事情,或者能够确认这实际上是内存泄漏。

一些额外的事实:
  • 我在 Ubuntu 11.10
  • 上使用 Python 2.7.2
  • 我正在使用 IPython 版本 0.12
  • 我的引擎在服务器 1-3 上运行,客户端和集线器在服务器 1 上运行。如果我将所有内容都保留在服务器 1 上,我会得到类似的结果。
  • 我发现的唯一与 IPython 的内存泄漏类似的事情与 %run 有关。 ,我相信在这个版本的 IPython 中已修复(另外,我没有使用 %run )

  • 更新

    此外,我尝试将日志记录从内存切换到 SQLiteDB,以防出现问题,但仍然存在同样的问题。

    响应(1)

    内存消耗肯定在 Controller 中(我可以通过以下方式验证这一点:(a)在另一台机器上运行客户端,以及(b)观察顶部)。我没有意识到非 SQLiteDB 仍然会消耗内存,所以我没有费心清理。

    如果我使用 DictDB 并清除,我仍然会看到内存消耗增加,但速度要慢得多。对于 eval() 的 20 次调用,它徘徊在 2GB 左右。

    如果我使用 MongoDB 并清除,看起来 mongod 占用了大约 4.5GB 的内存和 ipcluster 大约 2.5GB。

    如果我使用 SQLite 并尝试清除,则会收到以下错误:
    File "/usr/local/lib/python2.7/dist-packages/IPython/parallel/controller/hub.py", line 1076, in purge_results
    self.db.drop_matching_records(dict(completed={'$ne':None}))
    File "/usr/local/lib/python2.7/dist-packages/IPython/parallel/controller/sqlitedb.py", line 359, in drop_matching_records
    expr,args = self._render_expression(check)
    File "/usr/local/lib/python2.7/dist-packages/IPython/parallel/controller/sqlitedb.py", line 296, in _render_expression
    expr = "%s %s"%null_operators[op]
    TypeError: not enough arguments for format string

    所以,我想如果我使用 DictDB,我可能会没事(我今晚要试试运行)。我不确定是否仍然需要一些内存消耗(我也像你建议的那样在客户端中清除)。

    最佳答案

    是 Controller 进程在增长,还是客户端,或两者兼而有之?

    Controller 会记住所有请求和所有结果,因此将这些信息存储在简单 dict 中的默认行为将导致持续增长。使用数据库后端(sqlite 或者最好是 mongodb,如果可用)应该可以解决这个问题,或者 client.purge_results()方法可用于指示 Controller 丢弃任何/所有结果历史记录(如果您正在使用,这将从数据库中删除它们)。

    客户端本身将所有自己的结果缓存在其results 中。 dict,所以这也将导致随着时间的推移而增长。不幸的是,这有点难以处理,因为引用可以在各种方向上传播,并且不受 Controller 的数据库后端的影响。

    这是 known issue在 IPython 中,但是现在,您应该能够通过删除客户端结果/元数据字典中的条目来手动清除引用,如果您的 View 仍然存在,它有自己的结果字典:

    # ...
    # and retrieve their values
    values = [ar.get() for ar in async_results]

    # clear references to the local cache of results:
    for ar in async_results:
    for msg_id in ar.msg_ids:
    del lview.results[msg_id]
    del client.results[msg_id]
    del client.metadata[msg_id]

    或者,您可以使用简单的 dict.clear() 清除整个客户端缓存。 :
    view.results.clear()
    client.results.clear()
    client.metadata.clear()

    边注:

    View 有自己的 wait() 方法,因此您根本不需要将 Client 传递给您的函数。一切都应该可以通过 View 访问,如果你真的需要客户端(例如清除缓存),你可以将它作为 view.client .

    关于memory-leaks - IPython.parallel 模块中的内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8814583/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com