使用 GPU-Docker-API 管理 GPU 模型容器版本 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
mayooot
V2EX    Docker

使用 GPU-Docker-API 管理 GPU 模型容器版本

  •  1
     
      mayooot 2024-01-23 17:22:22 +08:00 1257 次点击
    这是一个创建于 705 天前的主题,其中的信息可能已经有所发展或是发生改变。

    前言

    在之前的帖子中我用 Go 实现了一个简单的项目,它可以代替你创建 GPU 容器,Volume ,以及方便地更新容器的 GPU 配置、Volume 的存储容量等(在不关闭 Docker 进程的情况下)。

    如果你还不熟悉,可以查看Docker 二次开发 | NVIDIA Docker + Docker Client 调度 GPU 容器项目

    项目一开始的名称叫 GPU-Docker-Demo ,我想通过直接调用 Docker Client 的方式来创建容器,并提供 HTTP 接口,更方便的使用 Docker 。然后尝试如何实现更新一个已存在容器的 GPU 数量,已存在 Volume 的存储容量等,最终通过拷贝 Overlay2 下容器的 merged layer 到新创建的容器中来实现,这样要比将容器提交为镜像再启动快的多。

    最初我想这个项目应该是面向熟悉 Golang 语言的开发者,仅仅只是为你提供一个思路,并不想写一个完整的项目。所以提供的接口大多都比较抽象,需要了解项目的原理后才能更好的使用。

    后来发现有不少只会 Python 的小伙伴 star 了我的项目,并且给我提了一些 issues ,他们往往不熟悉 Golang 语言,并且对构建项目、配置项目以及出错后的日志很陌生,并且对接口的使用也很迷茫,所以我更改了大部分代码,简化了操作。

    比如你可以直接从 release 下载二进制文件然后直接运行,配置通过参数的形式传递;通过导入 json 到 apifox 或者直接通过我分享的在线网站来查看 api 的定义信息。

    新的功能

    通过和 iomgaa-ycz 讨论,我发现学习 AI 的研究生可能会有版本控制的需求,比如我先创建一个容器,调整一些参数,然后获取到最后的结果。如果结果不太理解,我可能需要再次调整一些参数,但是之前的容器我也不想删除,方便我再次启动这个容器用于对比。

    之前的做法可能是,将旧容器提交为镜像,然后创建一个新容器,最后通过 docker cp 将代码拷贝进新容器,如果旧容器里安装了一些软件,例如 vim 、python ,那么只能在新容器里再安装一遍了,管理起来很繁琐。

    所以我试着解决这个问题,并提供了一个回滚的接口,就像 K8s 的回滚到指定版本一样。同时提供了查询历史版本接口,更方便查看容器的创建信息(类似于 K8s 中关于资源描述的 Yaml )。

    下面我为你简单的演示一下这个功能。

    我们先通过 创建 ReplicaSet 接口生成了一个版本为 1 的 foo 容器并且使用了 3 张卡。( ReplicaSet 只是一个抽象的概念,它并没有具体实现,只是代表了具有历史版本的、可回滚的容器而已。)

    image-20240123164937295

    比如我们要在这个容器安装 Python3 ,然后写一些代码。

    通过 GPU-Docker-API 创建或者更新后的容器,都会在环境变量 CONTAINER_VERSION 里保存当前版本号,方便使用。

    $ cat main.py import os print("CONTAINER_VERSION: ", os.environ['CONTAINER_VERSION']) $ python3 main.py CONTAINER_VERSION: 1 

    然后我们先在这个容器的基础上,直接复制一个容器出来,然后旧的容器停止。

    所以我们调用 patch 接口更新它,只不过我们只想要复制,所以 Boyd 传递一个空即可。

    可以看到 foo-2 容器被创建了。我们跳过实际使用它的步骤。

    image-20240123170203206

    foo-1 ,foo-2 都是使用了 3 张 gpu ,我们改变一下 gpu 数量,然后尝试回滚到最初的 foo-1 版本。

    image-20240123170404077

    先调用获取 ReplicaSet 历史版本的接口,看看它都有哪些版本。

    image-20240123170515392

    然后回滚到 foo-1 的版本,可以看到 foo-4 被创建了(这里规定了版本号是递增的)。在前面的操作中,foo-1 ,foo-2 是使用了 3 张卡的,foo-3 是使用了 1 张卡;并且 foo-1 里面还安装了 Python3 ,编写了 main.py

    image-20240123170603796

    我们来验证一下。很酷,保存在非挂载目录的文件和安装的软件都在。我想这会让你炼丹的过程稍微轻松一点,不过浪费时间在提交镜像、拷贝数据上了。

    $ docker exec -it foo-4 bash $ ls -al | grep main.py -rw-r--r-- 1 root root 76 Jan 23 08:55 main.py $ python3 main.py CONTAINER_VERSION: 4 

    项目地址

    gpu-docker-api

    更多的功能可以参考: https://github.com/mayooot/gpu-docker-api/blob/main/README.md

    写在最后

    因为实现这些功能,代码数量会急剧增加,一个人维护也有点困难,所以可能会有一些 bug ,欢迎你随时到 GitHub 上提交 issues 。

    如果对你有帮助,欢迎点一个 ,这对我很重要哦。

    目前尚无回复
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3262 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 04:55 PVG 12:55 LAX 20:55 JFK 23:55
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86