当前位置:   article > 正文

stable-diffusion-webui RAM内存泄漏问题_stable diffusion内存溢出

stable diffusion内存溢出

问题说明

近日工作中遇到了stable-diffusion-webui在频繁切换模型时,发生内存OOM问题。平时用GUI界面验证效果时,切换模型多了也会遇到这个问题。

复现操作

step1

配置文件或webui-setting中设置sd_checkpoints_limit:4 & sd_checkpoints_keep_in_cpu:true|勾选 ,作用:内存中缓存4个模型,显存中只存放当前推理使用的模型。

step2

开发机使用GUI模式启动,频繁切换模型。
线上在k8s环境中启动api模式启动实例,并发请求,每次请求模型都不同,并发数量2个请求或2个以上即可复现。

现象:

webui在切换模型时,会先check内存中是否有加载过此模型,如果有则直接从内存中读取,没有就去磁盘中加载,并且判断已加载模型数量是否大于checkpoint_limit,不满足则会在下次切换其他模型时将此模型权重加载到内存中(send_to_cpu())。
所以正常内存中缓存 4个sd-xl模型,单个模型占用6G左右,最终模型缓存占用内存大小应为24G,总内存占用应不超过30G。且在模型切换时,模型从内存中加载到显存中的操作为copy,所以在已经预先加载完成4个模型后,再次切换模型内存应保持不变。
但结果是内存概率性一路飙升,导致开发机经常性会宕机,线上服务也不稳定,经常性oom自动重启。

环境描述

开发环境:CentOS Linux8
线上环境:
- k8s集群
- docker镜像系统环境:pytorch:2.0.1-py3.10.11-cuda11.8.0-ubuntu22.04
显卡型号:
- NVIDIA-A10
- 驱动版本:550.54.14

解决方式:

先执行以下命令,找一下系统中有无此文件

whereis libtcmalloc.so.4
显示如下图就是没有
在这里插入图片描述
显示如图为文件存在,红框内为文件路虎路径在这里插入图片描述

  • libtcmalloc.so.4 是 Google 的 Tcmalloc(Thread-Caching Malloc)库的动态链接库文件。这个文件通常用于在运行时加载并替代系统默认的内存分配库,以提供更高效的内存管理和优化性能。

如果不存在
则运行如下命令,安装Google PerfTools

centos系统:
yum install gperftools
ubuntu:
apt-get update && apt-get install -y google-perftools

如果文件存在,则将此文件添加到环境变量中,地址替换为自己查找到的地址

export LD_PRELOAD=“/usr/lib64/libtcmalloc.so.4”

  • Google PerfTools(Google Performance Tools)是一组由Google提供的开源库和工具,用于提高C++应用程序的性能。这些工具主要包括四部分:Tcmalloc,HeapChecker,HeapProfiler 和 CPUProfiler。这些工具帮助开发者优化内存分配、跟踪和分析内存使用情况以及分析CPU使用情况。

再次启动webui,随便怎么切换模型,内存占用都十分稳定。

后记(问题原因,解决方案解析)

从理论上讲,如果一个应用程序设计良好,它应该在没有 Tcmalloc 等优化工具的情况下正常运行。然而,实际上许多编程语言和库默认的内存分配器可能在某些复杂的应用场景下表现不足,尤其是在处理大量数据和频繁分配/释放内存的情境下。

以下是几个 Stable Diffusion WebUI 在没有 Tcmalloc 的情况下可能会发生内存泄漏问题的原因:

  1. 默认分配器问题
    默认的内存分配器如 glibc malloc,在非常高频的内存分配和释放操作中,可能会引发内存碎片化。这种碎片化会降低内存使用效率,最后表现为内存泄漏或者近似的内存问题。

  2. 高负载场景下的锁争用
    标准的内存分配器在多线程环境下可能会出现显著的锁争用问题,这影响了性能并可能导致内存管理异常。而 Tcmalloc 由于其线程缓存机制,能够高效地处理多线程环境中的内存争用问题,避免潜在的内存泄漏。

  3. 未优化的内存释放
    在一些复杂的应用中,在代码路径的某些地方可能没有正确释放内存。这些问题在使用 Tcmalloc 的情景下可能不足以引发严重的内存泄漏,因为 Tcmalloc 能够更好地管理内存碎片化和加速内存释放过程。而在未使用 Tcmalloc 时,这些释放不当的内存就表现为内存泄漏。

  4. GNU Allocator 和 Tcmalloc 的处理差异
    Tcmalloc 实际上可能会在多线程环境中自动处理掉一些原本会被认为是“泄漏”的内存,因为它设计用于避免内存碎片化,并且能更高效地将未使用的内存返回操作系统。而一些标准的分配器在高压力环境下表现不如 Tcmalloc。

  5. 程序的依赖性
    有些程序可能会被所编写的依赖库以及本身的运行环境所限制,而这些程序设计时就假设会使用像 Tcmalloc 这样的高效内存分配器,因此没有进行额外的内存管理优化。

一句话总结就是,webui在切换模型时,工程师偷懒了,并没有考虑在内存频繁读取和分配时做好垃圾回收和释放,导致重复向内存中写入模型权重,他们估计也发现了这个问题,怎么解决呢?直接引入Tcmalloc来管理不再引用的模型权重和其他碎片化内存文件

为什么选择 Tcmalloc

Tcmalloc(Thread-Caching Malloc) 是 Google 开发的高效内存分配器,被设计用于减少锁争用和内存碎片化问题。以下是它的几个优点:

  • 线程缓存:每个线程有自己的缓存,因此内存分配和释放操作几乎是无锁的。
  • 减少内存碎片:采用更好的内存管理策略来减少碎片。
  • 性能优化:在多线程和高并发环境下具有更好的性能。
为什么 WebUI 选择 Tcmalloc

在 Stable Diffusion WebUI 这样高负载并且需要频繁内存分配和释放的场景中,默认的 glibc malloc 可能会带来性能问题和内存碎片化,进而可能导致内存泄漏。而 Tcmalloc 通过其高效的内存管理策略和线程缓存,可以有效减少这些问题。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/煮酒与君饮/article/detail/986590
推荐阅读
相关标签
  

闽ICP备14008679号