Pytorch CPU OOM 杀死 linux 上的 ssh 服务器

Pytorch CPU OOM kills ssh server on linux

提问人:Daniel Redder 提问时间:11/1/2023 更新时间:11/4/2023 访问量:115

问:

我遇到了一个问题,即 pytorch(使用 2.0.1+cu117 测试)在发生 CPU OOM 时不会正常失败。具体来说,我失去了所有 ssh 连接和对 VM 或裸机的 Xserver 访问权限。

我还没有测试过这是否发生在任何其他操作系统上。

我找到的唯一解决方案是直接重新启动计算机(通过 vSphere 或只是一个电源按钮)。

我考虑过将 python 别名(考虑 conda 环境切换)以将每个进程添加到直接限制内存使用的 cgroup 中,但我被告知弄乱 cgroups 通常是一个坏主意。

很难判断一个模型将占用多少内存,我需要一种优雅的方式来杀死它,而不会杀死我的 ssh-server。

一些注意事项: 我已经在两台设备上尝试过,一台 VM,一台裸机,都是 Ubuntu 22.04,我相信两者都启用了操作系统级别的 OOM 杀手。这在 GPU OOM 中是不可重现的,因为这实际上会终止进程并返回典型的 GPU OOM 错误,但仅限于 RAM。

我尝试按照此处所述设置 RLIMIT:https://www.geeksforgeeks.org/python-how-to-put-limits-on-memory-and-cpu-usage/。虽然这并没有解决我的问题。

我还考虑过在我的训练中添加一个条件来检查可用内存和中断,但这似乎是一个不干净的解决方案。

我没有尝试过cgroups,因为如上所述。我也只是对操作系统的东西非常熟悉,我不愿用它做任何事情,以免我破坏了我无法修复的东西。

pytorch cpu 内存 oom

评论

0赞 Andrew Henle 11/1/2023
TLDR:禁用 OOM 杀手:“一家飞机公司发现,在机上使用更少的燃料驾驶飞机更便宜。飞机会更轻,使用更少的燃料,节省资金。然而,在极少数情况下,燃料量不足,飞机会坠毁。该公司的工程师通过开发一种特殊的OOF(燃料耗尽)机制解决了这个问题。在紧急情况下,一名乘客被选中并被扔出飞机。当进程可能像这样被扼杀时,就不可能有一个可靠的系统。
0赞 Daniel Redder 11/1/2023
禁用 OOM 杀手可能会防止 SSH 服务器死亡,但它并不能解决整体问题。“飞机仍然崩溃”,所以 ssh-server 仍然会崩溃,但只是因为机器崩溃了,而不是 ssh-server 被弹出。
0赞 Andrew Henle 11/1/2023
不,它不会崩溃。只要你投入了足够的“燃料”(足够的内存...),禁用 OOM 杀手和内存过量使用意味着进程将无法请求内存,然后导致对系统可靠性至关重要的其他进程被杀死。你最终会得到一个系统,它不会对进程撒谎,而是告诉他们他们不能有那么多内存。换句话说,一个可靠的系统。
0赞 Andrew Henle 11/1/2023
你不能基于不准确的信息来构建任何类型的可靠系统,而 Linux 对内存过量的使用意味着进程拥有关于可用内存的不准确信息。很难比这更从根本上说更不可靠。

答:

1赞 maxy 11/2/2023 #1

您可以尝试使用以下命令进行调整:oom_score_adjchoom

choom -n 1000 -- python yourscript.py

引用:man proc/proc/<pid>/oom_score_adj

[..]调整用于选择在内存不足情况下终止的进程的不良启发式方法。[坏值]的范围从 0(从不终止)到 1000(始终终止),以确定目标进程。

如果您不确定 OOM 杀手是否处于活动状态,可以使用 检查内核日志中发生了什么。(如果必须重新启动,请添加 。它看起来像这样:journalctl -ke--boot -1

内存不足:终止进程 68412 (python3) total-vm:70398288kB, anon-rss:61052944kB, file-rss:2304kB, shmem-rss:0kB, UID:1000 pgtables:119712kB oom_score_adj:1000

延伸阅读:

评论

0赞 Daniel Redder 11/2/2023
我正在尝试一下。显然,我可以做一些特定于程序的事情来监视和管理 RAM,但我正在寻找的是这样的方法,以确保 python 脚本在 ssh-server 之前被杀死,而不考虑 python 脚本是什么。应用后,我将用我的结果更新此评论。
1赞 maxy 11/3/2023
实际上,我的 sshd 的oom_score_adj为 -1000,这意味着它永远不会被杀死。也许你的问题实际上是你的系统正在交换,没有做太多其他事情。使用 检查交换设置。也许您的交换空间过多,或者正在交换到一个非常慢的磁盘。也许试试.cat /proc/swapsswapoff -a
0赞 Daniel Redder 11/3/2023
cat /proc/swaps /swapfile 文件 2097148 0 -2
1赞 maxy 11/4/2023
2GB 交换听起来很合理。保持永远不会从 RAM 中跑出的程序很有用。不过,如果您读取的 RAM 多于循环中的 RAM,交换可能会大大减慢您的系统速度,以至于看起来它崩溃了。
0赞 Daniel Redder 11/3/2023 #2

#https://www.geeksforgeeks.org/python-how-to-put-limits-on-memory-and-cpu-usage/

^ 我之前错误地实现了这一点(限制属性的拼写错误),但这实际上确实解决了问题并防止了RAM的过度使用。

https://github.com/daniel-redder/mem_restrict/blob/main/mem_restrict.py ^ import 约束

import psutil
import resource


#https://www.geeksforgeeks.org/python-how-to-put-limits-on-memory-and-cpu-usage/

PERCENTAGE_MEMORY_ALLOWED = 0.8

# Calculate the maximum memory limit (80% of available memory)
virtual_memory = psutil.virtual_memory()
available_memory = virtual_memory.available
memory_limit = int(available_memory * PERCENTAGE_MEMORY_ALLOWED)

print(f'{memory_limit} memory limit, available: {available_memory}')

# Set the memory limit
resource.setrlimit(resource.RLIMIT_AS, (memory_limit, memory_limit))

(我将继续在这里讨论 OOM 杀手级的东西,因为它很有趣,但我想提出一个简单的解决方案)

评论

1赞 maxy 11/4/2023
听起来是一个很好的解决方案。还请将最重要的关键字或小代码片段直接添加到答案中。链接可能会失效,答案也应该是独立的。