win11环境下docker安装clip模型保姆级流程

近期因为论文项目的原因,需要部署使用clip模型。但是学生那边没有安装这类软件的经验弄不好。我就想着让学生装个docker的clip镜像解决问题。但是我在docker hub和github上找了半天,没有找到独立的clip镜像,都是跟其他模型混搭的版本。浙大博士说clip很好安装,pytorch直接拉取就行了,估计这就是没有独立镜像的原因吧。

虽然理论上可以直接在windows11的电脑上依次安装python、PyTorch、torchvision、cudatoolkit和CLIP达到使用clip模型的目的。但是为了便于学生使用,于是目标改为,先拉取个docker镜像安装个linux子系统,然后在子系统中安装好python、PyTorch、torchvision、cudatoolkit和CLIP,最后再发布出来。这样他们无论是从ubuntu镜像开始从头安装,还是直接拉取我装好的镜像,都可以很快用上。以下是我做的步骤。

windows11安装docker

宿主机环境:win11 64位版本,2060显卡6G显存,除了城市天际线、铁甲雄兵等游戏外什么都没有的神州超级战神笔记本

先安装git,https://git-scm.com/

下载安装docker desktop: Install Docker Desktop on Windows

在win11中默认启用WSL2作为Linux容器。所以还要更新WSL2。 打开powershell,  输入运行以下命令即可:

wsl --update

为了让windows11宿主机中的docker镜像可以使用显卡进行数值计算、模型训练之类的操作,需要先在宿主机安装Nvidia显卡驱动程序和CUDA工具包。显卡驱动可以根据显卡型号到nvidia官网去下载安装。CUDA工具包的最新版下载地址如下:CUDA Toolkit 12.1 Downloads | NVIDIA Developer

下载cuda工具包的时候注意按照自己宿主机的硬件情况选择版本

安装好后,可以在宿主机的终端中,输入nvidia-smi查看当前驱动程序版本。

输入nvidia-smi显示如下界面说明安装成功

然后可以用一个docker示例程序验证docker是否可以访问GPU

docker run --gpus all nvcr.io/nvidia/k8s/cuda-sample:nbody nbody -gpu -benchmark


安装包含clip模型的linux子系统

拉取docker的linux镜像

在 PowerShell 中运行以下命令以下载 Linux ubuntu的最新镜像:

docker pull ubuntu:latest

在 PowerShell 中运行以下格式命令,以启用GPU的方式启动容器:docker run --name [给你的容器起的名字] --gpus all -it [你下载的ubuntu镜像ID或名字] /bin/bash

docker run --name myClipDemo --gpus all -it ubuntu /bin/bash

docker desktop的镜像页面。注意镜像(image)和容器(container)的区别。

需要说明的是,在第一次执行docker run命令启动容器时,就应该加入--gpus all命令启用对宿主机GPU的使用权限。如果忘记使用该命令该怎么办?以下时chatGPT提供给我的答案:

  1. 在当前终端窗口中按 Ctrl + C 终止容器。使用 docker ps 命令查找容器的 ID。
    docker ps
  2. 使用 docker commit 命令将当前容器的状态保存为新的镜像。
    docker commit [CONTAINER ID] new_image_name

    [CONTAINER ID] 替换为第一步中找到的容器 ID,将 new_image_name 替换为新的镜像名称。

  3. 使用 docker run 命令启动一个新的容器,并在其中使用 --gpus all 选项来启用 GPU 支持。使用新的镜像名称来替换原来的镜像名称。
    docker run --gpus all -it new_image_name /bin/bash

接下来更新apt

apt-get update

然后装个wget方便下载其他各种安装包

apt-get install wget

https://github.com/openai/CLIP 的安装说明

必须要说明的是,pytorch的版本与cudatoolkit版本是一一对应的关系,不存在高版本向下兼容一说。因此最好用按照github中openAi/Clip的安装说明,使用conda命令一起安装指定的pytorch版本与cudatoolkit版本。所以先安装个miniconda,以便能使用conda命令。

Anaconda是一个开源的Python包管理工具,其包含了conda、Python等180多个科学包及其依赖项。因为包含了大量的科学包,Anaconda 的下载文件比较大(约 531 MB),如果只需要某些包,或者需要节省带宽或存储空间,也可以使用Miniconda这个较小的发行版。安装好miniconda以后可以使用conda命令安装pytorch等软件。
需要注意的是下载安装miniconda的版本,与python版本也是一一对应的关系。为了匹配pytorch=1.7.1  cudatoolkit=11.0的版本,miniconda需要安装python3.7的版本。我也是安装最新版以后执行“conda install --yes -c pytorch pytorch=1.7.1 torchvision cudatoolkit=11.0”命令失败后才发现的。

所以我们应该下载如下的安装脚本

wget https://repo.anaconda.com/miniconda/Miniconda3-py37_23.1.0-1-Linux-x86_64.sh

miniconda安装脚本的官网截图,应下载红色框处的安装脚本,或者直接执行我们的安装命令

运行安装脚本

bash Miniconda3-py37_23.1.0-1-Linux-x86_64.sh

接下来按照安装程序的提示操作,一路输入回车或yes来完成安装。

然后关闭当前终端,重新打开一个新终端,miniconda才能生效。打开新终端,输入以下命令即可

docker exec -it [你的容器名称] /bin/bash

此时可以查看版本号命令来查看miniconda是否已经正确安装。

conda --version

python --version

 如果以上命令执行无误,则可以删除之前的miniconda安装脚本

rm Miniconda3-py37_23.1.0-1-Linux-x86_64.sh

更新miniconda

conda install --channel defaults conda python=3.7 --yes
conda update --channel defaults --all --yes

有了conda,就可以按照github上clip的安装流程来搞定clip了:

$ conda install --yes -c pytorch pytorch=1.7.1 torchvision cudatoolkit=11.0
$ pip install ftfy regex tqdm
$ pip install git+https://github.com/openai/CLIP.git

执行conda install --yes -c pytorch pytorch=1.7.1 torchvision cudatoolkit=11.0命令的结果
pip install ftfy regex tqdm 命令执行结果
pip install git+https://github.com/openai/CLIP.git 命令执行结果

注意最后一个命令执行失败,说git版本找不到。可以先使用apt给Linux子系统安装好git,或者先更新pip然后再执行命令。我的操作是两个都做了:

apt安装git

apt-get update

apt-get install git

更新pip

pip install --upgrade pip

最后再执行

pip install git+https://github.com/openai/CLIP.git

成功安装clip

Clip模型的使用测试

在宿主机创建一个名为test_clip.py的文件,其中包含代码如下:

import torch
import clip
from PIL import Image

# 加载预训练模型
device = "cuda" if torch.cuda.is_available() else "cpu"
model, preprocess = clip.load("ViT-B/32", device=device)

# 定义图像路径和标签
image_path = "example.jpg"
labels = ["cat", "dog", "bird"]

# 加载图像
image = preprocess(Image.open(image_path)).unsqueeze(0).to(device)

# 将图像编码为特征向量
with torch.no_grad():
image_features = model.encode_image(image)

# 加载标签,并将其编码为特征向量
with torch.no_grad():
text_features = model.encode_text(clip.tokenize(labels).to(device))

# 计算图像和标签之间的相似度得分,并打印结果
with torch.no_grad():
similarity_scores = (100.0 * image_features @ text_features.T).softmax(dim=-1)[0]
for i, label in enumerate(labels):
print(f"{label}: {similarity_scores[i]:.2f}%")

然后再找个图片,重命名为example.jpg,比如这个:

然后把test_clip.py和example.jpg都放到一个test文件夹里,然后import到我的linux子系统中。具体的说,我上传到了opt目录下。

在file处可以上传文件,右键菜单中选择import文件夹即可

然后回到linux子系统的终端,进入该目录,并运行python文件

cd opt/test

python test_clip.py

返回结果如下:

clip判断输入的图像100%属于是bird。搞怪的话可以试试输入一个人的图像,再自定义一堆标签,看看它能返回什么结果。

将linux子系统打包为镜像

现在我已经做好了一个通过测试的clip模型linux子系统。我想要把它打包为镜像,然后分享给其他人使用。操作流程如下:

1.先登录到docker hub网站上,注册并登录账号(需科学上网),点击repositories选项卡,点击create repository(创建存储库),创建一个自己的存储库。

这里我创建了一个名为divis的存储库。之后要用到我自己的用户名和这个存储库,也就是zhangdiwaa/divis

2.确保要打包的docker容器在运行,使用下面这个命令检查状态:

docker ps

可以看到我之前安装的ClipDemo正在运行,复制前面的container ID

3. 将容器打包为镜像

然后按照以下格式输入命令:

docker commit <container_id> <image_name>:<tag>

其中,<container_id>是容器的ID,可以使用docker ps命令获取,<image_name>是您要为镜像命名的名称,应与docker hub上你要推送的地址一致,简单的说就是“账号/存储库”,在我这个例子里是“zhangdiwaa/divis”,总之不能随便命名,这也是踩过坑才知道。<tag>是您要为镜像指定的标签,通常为版本号或日期,其用途是区别同一个存储库下的不同镜像,也不能没有。

所以这里我输入的是

docker commit 324268be0b29 zhangdiwaa/divis:1.0

等待较长一段时间后,显示sha256码证明你的镜像已经生成完毕。

4.镜像上传docker hub

按下面格式输入命令:

docker push <dockerHub push地址>:<tag>

其中image_name是你的dockerHub push地址, tag就是之前为镜像指定的标签。所以这里我输入的是:

docker push zhangdiwaa/divis:1.0

然后等待上传完毕即可。


拉取我封装好的镜像,并使用clip模型

先确定你的电脑时win11,安装好了docker,更新了WSL,安装了显卡驱动和cuda。

还记得最开始我们是怎么拉去ubuntu镜像并启动的么?

在 PowerShell 中运行以下命令以下载 Linux ubuntu的最新镜像:

docker pull ubuntu:latest

在 PowerShell 中运行以下格式命令,以启用GPU的方式启动容器:docker run --name [给你的容器起的名字] --gpus all -it [你下载的ubuntu镜像ID或名字] /bin/bash

docker run --name myClipDemo --gpus all -it ubuntu /bin/bash

所以使用我的clip镜像,方法也差不多。先拉取镜像,再以GPU方式启用即可:

docker pull zhangdiwaa/divis:1.0

docker run --name myClipDemo --gpus all -it zhangdiwaa/divis:1.0 /bin/bash

等你的容器运行起来以后,既可以直接跳到本文的“Clip模型的使用测试”一节对clip模型进行测试。


其他需要注意的问题

最大的一个问题是,cuda版本是与pytorch版本严格对应的,不存在高级版本对低级版本的兼容。要查看你的pytorch与哪些cuda版本兼容,可以查看这个站点:https://pytorch.org/get-started/previous-versions/

然后在本人安装流程中,宿主机使用的cuda版本是12.1, 而docker中的linux子系统,pytorch版本是1.7.1 , cudatoolkit版本是11.0,也就是说只有linux子系统中的pytorch版本和cuda版本是对应的。虽然这也可以运行,但前提条件是我不对clip模型本身进行编译。如果要编译clip模型,最好宿主机和linux子系统使用同样的cuda版本11.0, 避免编译出错的情况。

clip对于prompt匹配程度的预测,首先取决于你设置的prompt池的范围。网上很多stable diffusion webui的图生文的案例,都是使用类似DeepDanbooru这样的标签库,让clip预测图与标签库中的标签之间的匹配程度。在本文中,只用了一个非常简单的案例,标签库中只有三个标签,没有更深入的使用。更多可以查看:https://github.com/openai/CLIP

长期不做这种工程工作让我对linux安装软件过程生疏不少,感谢浙大潘波博士对容器启用GPU的说明,和chatGPT对安装过程细节的说明,让我可以及时解决遇到问题。