mayooot
V2EX  ›  Docker

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

  •  1
     
  •   mayooot · Jan 23, 2024 · 1539 views
    This topic created in 889 days ago, the information mentioned may be changed or developed.

    前言

    在之前的帖子中我用 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 。

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

    No Comments Yet
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   1127 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 41ms · UTC 23:07 · PVG 07:07 · LAX 16:07 · JFK 19:07
    ♥ Do have faith in what you're doing.