共计 9176 个字符,预计需要花费 23 分钟才能阅读完成。
本篇文章将分享如何通过 Docker 来在本地疾速运行 Hugging Face 上的乏味模型。用比原我的项目更少的代码,和更短的工夫老本将模型跑起来。
如果你相熟 Python,那么绝大多数的模型我的项目,都能够用 10 分钟左右的工夫,实现本地的部署和运行。
写在后面
为了不便展现,我抉择了一个图像处理模型。在聊细节之前,让咱们来一起看看这个模型我的项目的理论运行成果吧。
下面的图片解决所应用的 AI 模型,是我在 Hugging Face 上找到的。随着 Hugging Face 的爆火,平台上呈现了越来越多的乏味的模型和数据集,目前仅模型数量就高达 4 万 5 千多个。
这些模型 有一个乏味的特点,在云平台上跑的好好的,然而一旦想在本地跑起来就得各种“吃力”折腾,我的项目关联的 GitHub 中总是能看到用户反馈:这个模型和代码,我本地跑不起来,运行环境和调用代码搞起来太麻烦了。
其实在日常的工作和学习中,咱们也会常常遇到相似下面 Hugging Face 的状况:许多模型在“云上”跑的好好的,然而一到本地就跑不起来了,这或者是因为“操作系统环境、设施 CPU 架构(x86/ ARM)差别”、或者是因为“Python 运行时版本过高或过低”、或者是因为“某个 PIP 装置的软件包版本不对”、“简短的示例代码中写死了一堆货色”…
那么,有没有什么偷懒的办法,能够让咱们绕开这些浪费时间的问题呢?
在通过了一番折腾之后,我摸索出了一个绝对靠谱的计划:用 Docker 容器搭配 Towhee,制作模型的 一键运行环境。
譬如本文结尾提到的这个模型,如果咱们想进行疾速调用,针对咱们的图片进行一个疾速修复解决,真的并不难:只须要一条 docker run
命令,搭配二、三十来行 Python 代码即可。
接下来,我就以腾讯 ARC 实验室开源的 GFPGAN 模型为例,来聊聊如何疾速的把网上凋谢的模型疾速的跑起来。
因为该模型基于 PyTorch,所以本篇文章里,咱们先聊聊如何制作基于 PyTorch 的模型应用的通用 Docker 根底镜像。如果同学们有需要,我就再聊聊其余模型框架。
制作 PyTorch 模型应用的通用 Docker 根底镜像
本章节的残缺示例代码,我曾经上传到了 GitHub:https://github.com/soulteary/docker-pytorch-playground,感兴趣的同学能够自取。如果你想进一步省事,还能够间接应用我曾经构建好的镜像,来作为根底镜像应用:https://hub.docker.com/r/soulteary/docker-pytorch-playground。
如果你对如何封装根底镜像感兴趣,能够持续浏览本章节,如果你只关怀如何疾速跑模型,能够间接浏览下一章节内容。
言归正传,出于上面三个起因,我倡议想在本地疾速复现模型的同学采纳容器计划:
- 想要防止不同我的项目之间的环境造成烦扰(净化)
- 想要确保我的项目依赖清晰,任何人都可能在任何设施上复现后果
- 想要复现模型的工夫老本更低一些,不喜爱折腾 80% 反复的模型调优之外的工作内容(尤其是环境、根底配置)
在理解到容器计划的劣势之后。接下来,咱们来聊聊如何编写这类根底镜像的 Dockerfile,以及编写过程中的思考:
思考到模型可能须要在 x86 和 ARM 两类设施上运行,举荐应用 miniconda3
这个基于 debian
内置了 conda
工具包的根底镜像。
FROM continuumio/miniconda3:4.11.0
对于根底环境镜像的应用,我举荐大家应用具体版本号,而不是 latest
,这样能够让你的容器在须要反复构建的时候,也能放弃“稳固”,缩小“意外的惊喜”。如果你有非凡的版本需要,能够在这里找到更适宜你的镜像版本。对于 conda
和 mini conda
相干的内容,本篇文章暂不赘述,感兴趣的同学能够从官网仓库中取得更多的信息。如果有需要的话,我会写一篇更具体的文章来聊聊它。
因为咱们会频繁应用 OpenGL 的 API,所以咱们须要在根底镜像中装置 libgl1-mesa-glx
软件包,如果你想理解这个软件包的详情,能够浏览 debian 官网软件仓库的文档,为了让安装时间更少,这里我调整了软件源为国内的“清华源”。
RUN sed -i -e "s/deb.debian.org/mirrors.tuna.tsinghua.edu.cn/" /etc/apt/sources.list && \
sed -i -e "s/security.debian.org/mirrors.tuna.tsinghua.edu.cn/" /etc/apt/sources.list && \
apt update
RUN apt install -y libgl1-mesa-glx
当咱们实现了根底零碎依赖库的装置之后,就能够开始筹备模型运行环境了,以 PyTorch 装置为例:
RUN pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
RUN conda install -y pytorch
同样为了节约 Python PyPi 软件包的下载工夫,我同样将下载源切换到了国内的“清华源”。当 conda install -y pytorch
命令执行结束之后,咱们的根底的运行环境也就 OK 了。
思考到大家的网络环境不雷同,这里列出一些国内其余的罕用镜像源。你能够依据你本人的状况,调整软件包下载源,来获取更快的软件包下载速度。
# 清华源
https://pypi.tuna.tsinghua.edu.cn/simple
# 阿里云
http://mirrors.aliyun.com/pypi/simple
# 百度
https://mirror.baidu.com/pypi/simple
# 中科大
https://pypi.mirrors.ustc.edu.cn/simple
# 豆瓣
http://pypi.douban.com/simple
在下面的步骤中,咱们大略须要下载靠近 200MB 的软件包(conda
14MB、pytorch
44MB、mkl
140MB),须要有一些急躁。
为了让咱们的根底镜像环境可能兼容 x86 和 ARM,在实现下面的根底环境装置之外,咱们还须要指定 torch
和 torchvision
版本,对于这点在 PyTorch 社区里曾有过 一些探讨。
RUN pip3 install --upgrade torch==1.9.0 torchvision==0.10.0
在下面的命令中,咱们会将 torch
替换为指定版本。理论构建镜像的过程中,大略须要额定下载 800MB 的数据。即便咱们应用了国内的软件源,工夫可能也会比拟漫长,能够思考去冰箱里拿一罐冰可乐,缓解期待焦虑。🥤
在解决完下面的各种依赖之后,咱们就来到了构建镜像的最初一步。为了后续运行各种 PyTorch 模型可能更省事,举荐间接在根底镜像中装置 Towhee:
# https://docs.towhee.io/Getting%20Started/quick-start/
RUN pip install towhee
至此,一个基于 PyTorch 的模型应用的通用 Docker 根底镜像的 Dockerfile 就编写结束啦,为了不便浏览,我在这里贴出残缺文件内容:
FROM continuumio/miniconda3:4.11.0
RUN sed -i -e "s/deb.debian.org/mirrors.tuna.tsinghua.edu.cn/" /etc/apt/sources.list && \
sed -i -e "s/security.debian.org/mirrors.tuna.tsinghua.edu.cn/" /etc/apt/sources.list && \
apt update
RUN apt install -y libgl1-mesa-glx
RUN pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
RUN conda install -y pytorch
RUN pip3 install --upgrade torch==1.9.0 torchvision==0.10.0
RUN pip install towhee
将下面的内容保留为 Dockerfile 后,执行 docker build -t soulteary/docker-pytorch-playground .
,等到命令执行结束,咱们的 PyTorch 根底镜像就构建实现了。
如果你不想浪费时间构建,也能够间接应用我曾经构建好的根底镜像(反对主动辨别 x86 / ARM 架构设施),间接从 DockerHub 下载即可:
# 能够间接下载最新版本
docker pull soulteary/docker-pytorch-playground
# 也能够应用带有具体版本的镜像
docker pull soulteary/docker-pytorch-playground:2022.05.19
搞定根底镜像之后,咱们就能够持续折腾前文提到的具体模型的运行环境和程序啦。
应用 Python 编写模型调用程序
咱们在 GFPGAN 我的项目中能够找到官网的模型应用示例:https://github.com/TencentARC/GFPGAN/blob/master/inference\_gfpgan.py,原始文件比拟长,大略有 155 行,这里我就不贴了。
我在上一大节中提到过,咱们能够应用 Towhee 来“偷懒”,比方能够将示例代码的行数缩短到 30 来行,并且额定实现一个小性能:扫描工作目录的所有图片,而后将他们别离交给模型去解决,最初生成一个动态页面,来将解决前后的图片进行比照展现。
import warnings
warnings.warn('The unoptimized RealESRGAN is very slow on CPU. We do not use it.'
'If you really want to use it, please modify the corresponding codes.')
from gfpgan import GFPGANer
import towhee
@towhee.register
class GFPGANerOp:
def __init__(self,
model_path='/GFPGAN.pth',
upscale=2,
arch='clean',
channel_multiplier=2,
bg_upsampler=None) -> None:
self._restorer = GFPGANer(model_path, upscale, arch, channel_multiplier, bg_upsampler)
def __call__(self, img):
cropped_faces, restored_faces, restored_img = self._restorer.enhance(img, has_aligned=False, only_center_face=False, paste_back=True)
return restored_faces[0][:, :, ::-1]
(towhee.glob['path']('*.jpg')
.image_load['path', 'img']()
.GFPGANerOp['img','face']()
.show(formatter=dict(img='image', face='image'))
)
如果将下面为了放弃“原汁原味”的 warnings
剔除掉,其实还能够取得更短的行数。将下面的内容保留为 app.py
,咱们稍后应用。
搞定了调用模型所须要的程序之后,咱们持续来聊聊,如何制作具体模型(GFPGAN)运行所须要的利用容器镜像。
制作具体模型应用的利用镜像
这部分的残缺代码,我同样上传到了 GitHub,不便大家“偷懒”:https://github.com/soulteary/docker-gfpgan。配套的预构建镜像在这里 https://hub.docker.com/r/soulteary/docker-gfpgan。
言归正传,有了上文中的根底镜像之后,咱们在日常游玩的过程中,就只须要针对每个不同的模型做一些镜像依赖微调即可。
上面就来看看如何针对上文中提到的 GFPGAN 我的项目做利用镜像定制吧。
同样是以编写 Dockerfile
为例,先来申明咱们正在构建的利用镜像是基于下面的根底镜像。
FROM soulteary/docker-pytorch-playground:2022.05.19
这样做的益处是,在后续的日常应用中,咱们能够节约大量的镜像构建工夫,以及本地磁盘空间。不得不说,模型类大容器特地可能享受 Docker 个性带来的便当。
接下来,咱们须要在要制作的利用镜像中搁置咱们要应用的模型文件,以及实现相干 Python 依赖的补充下载。
思考到国内网络下载 Hugging Face 和 GitHub 模型比较慢,还容易呈现网络中断。我举荐大家在做利用模型构建的时候,能够思考提前进行依赖模型的下载,在构建镜像的过程中,将模型搁置到适合的目录地位即可。至于具体的模型应用形式,不论是打包到镜像里,或者抉择在应用的过程中动静的挂载,其实都是能够的。
在 GFPGAN 我的项目中,咱们一共依赖俩模型文件,一个是 https://github.com/xinntao/facexlib 我的项目中基于 ResNet50
的人脸检测模型,另一个是用于图片修复的 GFPGAN 反抗网络模型,也就是传统意义上的“配角”。
第一个模型文件 detection_Resnet50_Final.pth
,咱们能够在 https://github.com/xinntao/facexlib/releases/tag/v0.1.0 中获取;第二个模型则须要咱们依据本人的设施情况,来做具体抉择:
- 如果你须要应用 CPU 来跑模型,能够在 https://github.com/TencentARC/GFPGAN/releases/tag/v0.2.0 中下载
GFPGANCleanv1-NoCE-C2.pth
;或者在 https://github.com/TencentARC/GFPGAN/releases/tag/v1.3.0 中下载GFPGANv1.3.pth
,这类模型能够实现黑白人像图片的解决。 - 如果你能够应用 GPU 来跑模型,能够在 https://github.com/TencentARC/GFPGAN/releases/tag/v0.1.0 中下载
GFPGANv1.pth
;或者在 https://share.weiyun.com/ShYoCCoc 中进行模型文件下载,这类模型能够解决带色彩的人像图片。 - 除了 GitHub 之外,咱们也能够抉择间接从 Hugging Face 下载模型(只是可选版本不像下面那么多):https://huggingface.co/TencentARC/GFPGANv1/tree/main/experiments/pretrained\_models。
将下载好的模型文件和新的 Dockerfile
文件搁置于雷同目录之后,咱们来持续欠缺 Dockerfile 的内容,实现我的项目依赖的装置,并将模型搁置在容器内适合的目录地位:
# 装置模型相干代码库
RUN pip install gfpgan realesrgan
# 将提前下载好的模型复制到指定地位,防止构建镜像过程中的意外
COPY detection_Resnet50_Final.pth /opt/conda/lib/python3.9/site-packages/facexlib/weights/detection_Resnet50_Final.pth
# 依据你下载的模型版本做抉择,选一个模型文件就行
COPY GFPGANCleanv1-NoCE-C2.pth /GFPGAN.pth
# COPY GFPGANCleanv1-NoCE-C2_original.pth /GFPGAN.pth
# COPY GFPGANv1.pth /GFPGAN.pth
# COPY GFPGANv1.3.pth /GFPGAN.pth
下面除了 gfpgan
之外,我还装置了 realesrgan
,这个软件包能够让处理完毕的图片中的人脸之外的背景也显得更好看、更天然一些。
实现了根底依赖、模型的配置之后,最初就是一些简略的收尾工作了:
# 将上一步保留的调用模型的程序拷贝到镜像中
COPY app.py /entrypoint.py
# 申明一个洁净的工作目录
WORKDIR /data
# 这里能够思考间接将咱们要测试的数据集扔到容器里
# 也能够思考在运行过程中动静的挂载进去
# COPY imgs/*.jpg ./
# 补充装置一些我的项目须要的其余依赖
RUN pip install IPython pandas
# 因为 Towhee 目前只反对间接展现模型后果
# 临时还不反对将展现后果保留为文件
# 所以这里须要打个小补丁,让它反对这个性能
RUN sed -i -e "s/display(HTML(table))/with open('result.html','w') as file:\n file.write(HTML(table).data)/" /opt/conda/lib/python3.9/site-packages/towhee/functional/mixins/display.py
CMD ["python3", "/entrypoint.py"]
下面的代码中,我增加了不少正文来解释每一步要做什么,就不多赘述啦。额定解释一下这里的设计和思考,把上文中的 app.py
挪到 /
根目录,而不是扔到工作目录能够让咱们的程序在应用过程中更简略,因为我打算将工作目录作为图片的读取和处理结果的保留目录。容器最初应用 CMD
而不是 ENTRYPOINT
来执行默认命令,也更不便用户间接调用命令,或者进入容器调试。
同样的,为了不便浏览,我将下面的 Dockerfile 内容合并到一起:
FROM soulteary/docker-pytorch-playground:2022.05.19
RUN pip install gfpgan realesrgan
COPY detection_Resnet50_Final.pth /opt/conda/lib/python3.9/site-packages/facexlib/weights/detection_Resnet50_Final.pth
# 尺寸大一些的模型文件,能够抉择应用挂载的形式
# 而不在此处间接 COPY 到容器外部
COPY GFPGANCleanv1-NoCE-C2.pth /GFPGAN.pth
COPY app.py /entrypoint.py
WORKDIR /data
RUN pip install IPython pandas
RUN sed -i -e "s/display(HTML(table))/with open('result.html','w') as file:\n file.write(HTML(table).data)/" /opt/conda/lib/python3.9/site-packages/towhee/functional/mixins/display.py
CMD ["python3", "/entrypoint.py"]
将下面的内容保留为 Dockerfile
之后,咱们执行命令,来实现利用镜像的构建:
docker build -t pytorch-playground-gfpgan -f Dockerfile .
片刻之后,咱们就失去一个蕴含了模型和模型运行程序的利用镜像啦。
接下来,咱们来看看如何应用这个镜像,来失去文章一开始时的模型运行后果。
模型利用镜像的应用
如果上一步你曾经下载了模型文件,并将模型文件打包到了镜像中,那么咱们只须要下载一些黑白或者黑白的蕴含人像的图片(依据模型来抉择),将它们放在一个目录中(比方 data
目录),而后执行一行命令就可能实现模型的调用啦:
docker run --rm -it -v `pwd`/data:/data soulteary/docker-gfpgan
如果你不违心麻烦找图片,也能够间接应用我在我的项目中筹备的示例图片:https://github.com/soulteary/docker-gfpgan/tree/main/data。
下面是针对利用镜像中蕴含模型的状况,上面咱们来看看如果利用镜像中不蕴含模型要怎么解决。
如果在上文构建利用模型镜像时,没有抉择将 GFPGAN 模型打包到镜像中,那么咱们就须要应用文件挂载的形式,来运行模型了。为了我的项目构造的清晰,我在我的项目中创立了一个名为 model
的目录,来寄存上文中提到的模型文件。
残缺的目录构造相似上面这样:
.
├── data
│ ├── Audrey\ Hepburn.jpg
│ ├── Bruce\ Lee.jpg
│ ├── Edison.jpg
│ ├── Einstein.jpg
│ └── Lu\ Xun.jpg
└── model
└── GFPGANCleanv1-NoCE-C2.pth
当筹备好模型和要解决的图片之后,咱们还是执行一条简略的命令,来将文件挂载到容器中,让模型施展“魔力”:
docker run --rm -it -v `pwd`/model/GFPGANCleanv1-NoCE-C2.pth:/GFPGAN.pth -v `pwd`/data:/data soulteary/docker-gfpgan
当命令执行结束之后,在 data
目录中,会多出一个 result.html
文件,外面记录了模型解决前后的图片后果。应用浏览器间接关上,能够看到相似上面的后果:
写到这里,如何封装 PyTorch 容器根底镜像、如何封装具体模型的利用镜像、如何疾速的调用模型就都介绍完啦。如果前面有机会,我会聊聊如何基于这些镜像做进一步的性能调优,以及聊聊 PyTorch 之外的镜像封装。
最初
本篇内容的实现,须要感激两位好敌人、Towhee 我的项目的外围开发者 @侯杰、@郭人通 的帮忙。解决了对于我这个 Python 菜鸟来说,尽管行数不多,然而十分麻烦的模型调用的内容。
下一篇相干的内容中,我打算聊聊如何在 M1 设施上进行模型训练和推理,以及持续实际一些更乏味的 AI 我的项目。
–EOF
本文应用「署名 4.0 国内 (CC BY 4.0)」许可协定,欢送转载、或从新批改应用,但须要注明起源。署名 4.0 国内 (CC BY 4.0)
本文作者: 苏洋
创立工夫: 2022 年 05 月 20 日
统计字数: 10723 字
浏览工夫: 22 分钟浏览
本文链接: https://soulteary.com/2022/05…