当前位置:首页|资讯|Stable Diffusion|Stable Diffusion WebUI

【笔记】尝试构建自己的StableDiffusionWebui-Docker镜像

作者:k7212519发布时间:2023-03-24

1.需求场景

最近在玩AI画图时遇到一个问题,stable-diffusion-webui在Linux底下的ROCm运行环境搭建比较麻烦。由于我是AMD显卡,无法使用Windows下的CUDA环境,导致花了很多时间在环境搭建上。

最开始是直接在Ubuntu本地搭建python,rocm,hip,pytorch环境,虽然最后成功运行,但这些软件的版本依赖性极强,比如pytorch2.0只支持rocm5.4.2,python3.7以上,得去详细地查看每个软件的使用文档,才能成功构建。网上的教程由于大多是直接使用apt命令安装的最新版,相关软件版本一直在更新,导致过一段时间可能教程就失效了。相同的命令最后得到的环境截然不同。而且即使我已经搭建成功了,如果重装了系统,或者换一台配置相似的电脑,就得重头来一遍,可能到时候软件又更新了,之前的命令就跟着失效。

此时Docker就是救星!Docker是一种容器技术,有点类似于虚拟机,但又不完全是。Docker可以把软件以及软件运行所需要环境一起打包成镜像。然后使用该镜像构建一个隔离运行的容器,容器内部与外部宿主机可以近似看作两个单独的系统。容器相比虚拟机最大的优势就是不会过多占用宿主机的性能,容器内部软件的运行性能可以做到基本等同于原生系统运行,IO读写性能上可能会稍有降低,但比虚拟机要好得多。

于是我就想将stable-diffusion-webui运行环境打包成Docker镜像,方便下次使用或者分享给其他人。

2.将软件安装到容器中

其实之前也经常用到Docker,知道它大概是干嘛的,但仅是拉取和使用一些别人镜像,比如nginx,xray之类的,并没有过多的了解。

stable-diffusion-webui的GitHub官方仓库 https://github.com/AUTOMATIC1111/stable-diffusion-webui 中其实有写到如何在Docker下构建环境。首先得保证你的显卡驱动正确地在Linux内进行了安装,而且Docker软件已经安装。这里根据官方文档写了一个在Ubuntu中安装最新Docker和配置相关信息的脚本:

接下来就是从DockerHub拉取rocm/pytorch的镜像,并运行起来:

这里要注意他的 -v 参数指定了将宿主机的 $HOME/dockerx文件夹映射到了容器内部/dockerx目录。通常我们需要将容器内软件的运行数据保存在该映射的卷下,保证数据与容器的隔离。

这里要特别注意:docker run 中的 -v 参数是将宿主机的目录映射到容器中,如果原容器中被映射的文件夹内部有文件,就会自动隐藏掉,实际上数据文件依然在宿主机中。

这里我们能看出Docker的思维是容器只保证软件的运行环境,而软件的数据是在容器之外的,实现了数据与软件本体的分离。这样使得容器打包成的镜像不包含数据,可以被复制,无需担心数据泄露风险。同时可以实现多个容器共用同一份数据,这对于数据库一类的软件是非常重要的,保证了数据的一致性。

因为这个rocm/pytorch只是pytorch的镜像,容器运行起来后,还需要进行一系列的配置才能运行stable-diffusion。首先得升级一下默认的python版本,在容器内部运行:

然后重启容器,运行:

检查一下是否输出了 Python 3.9.5或者更高的版本。再将stable-diffusion-webui项目clone到被映射的 /dockerx目录下,并用新python创建软件所需的虚拟环境:

最后,要运行软件,只需要激活虚拟环境,运行launch.py即可:

这里要注意stable-diffusion官方教程里的rocm为5.1.1,并不支持pytorch2.0。因为pytorch2.0是最近几天才更新,可能作者还没来得及更新文档。这里替换成5.4.2才不会出错。后续新版本需要关注pytorch官网的版本信息。

以后每次运行都需要激活虚拟环境并运行一长串代码,我们可以将其写成sh文件,后续运行脚本文件即可:

3.构建Docker镜像

此时已经能成功运行webui,我们进入webui下载常用的插件,设置好自己的偏好。然后就可以构建自己的镜像了,后续再次部署容器,插件和设置就避免了重复下载和设置。

构建Doker镜像有两种方法:

  1. commit:基于现有的容器,直接打包成镜像。

  2. build:使用Dockerfile精准控制容器打包和运行过程。

我们原本的需求使用commit即可完成,在完成一系列的配置信息后,直接commit将容器打包。然后打包宿主机/home/user/dockerx内的sd软件本体和模型成数据包。数据包可以分发给其他人。也可以直接将软件和数据复制到容器内部打包。我是直接将webui集成到了镜像中。

build是需要使用Dockerfile来操作容器内的修改,一般格式为:

基本思路是FROM开始,从一个基础镜像出发,指定在该镜像的容器中执行哪些命令,添加或是操作哪些文件等。最后CMD是容器运行时执行的命令,只有一条,一般用来指定软件运行的命令。如果在软件运行前还需要执行多条,需要用ENTRYPOINT指定命令。

能看出dockerfile实际上就是在描述新镜像是如何从基础镜像得来的,能对新镜像进行思路清晰地精确控制。完成dockerfile编写后,只需要执行:

即可完成新镜像的构建。docker build本质上其实是多次执行commit操作,每个dockerfile中的代码块为一层,从基础镜像开始,每执行一层,需要一次commit,下一层再基于已经commit的镜像进行构建,直到整个最终的镜像构建完成。

当然,docker 相关命令还有很多,参数和功能也比较多。这里只是记录整个docker镜像构建的思路,需要用到某个功能或者参数时,可以随时看官方的文档,或者问ChatGPT,我们只需要知道基本思路和原理,把握整个流程即可。


Copyright © 2024 aigcdaily.cn  北京智识时代科技有限公司  版权所有  京ICP备2023006237号-1