使用GitHub Actions实现DeOldify模型的CI/CD:自动测试与镜像构建

张开发
2026/6/29 5:49:34 15 分钟阅读
使用GitHub Actions实现DeOldify模型的CI/CD:自动测试与镜像构建
使用GitHub Actions实现DeOldify模型的CI/CD自动测试与镜像构建最近在折腾一个老照片上色的项目用的是DeOldify这个模型。项目本身挺有意思但每次更新代码、测试模型效果、再打包成Docker镜像这一套流程下来手动操作不仅繁琐还容易出错。团队里有人改了代码忘了跑测试或者打包的镜像版本对不上都是常有的事。后来我们决定得把这一套流程自动化起来。正好GitHub Actions用起来挺方便就在上面搭了一套CI/CD流水线。现在只要代码一提交自动就跑测试打个标签自动就构建镜像推送到仓库。整个过程清晰透明省心不少。今天就来聊聊我们是怎么做的如果你也在做类似的项目或许能给你一些参考。1. 为什么DeOldify项目需要CI/CD你可能用过DeOldify它是一个基于深度学习的老照片、老视频上色工具效果挺惊艳的。但把它用起来尤其是在团队协作或者想要提供稳定服务的时候就会遇到一些工程上的麻烦。首先这个项目依赖不算少环境配置起来需要点耐心。不同人电脑上的环境稍有差异可能我这儿跑得好好的你那儿就报错了。其次模型本身有一些测试用例比如检查颜色渲染是否自然、边界处理是否得当。这些测试如果全靠人工来跑效率低不说还容易遗漏。更关键的是部署。我们最终是要把模型封装成Docker镜像提供API服务。手动构建镜像、打标签、上传步骤多容易手滑。比如忘了更新镜像版本号导致线上服务还是旧的代码这就出问题了。所以引入CI/CD持续集成/持续部署就是为了解决这些痛点让机器代替人工去完成那些重复、易错的工作保证每次代码变更都是可验证、可追溯、可自动部署的。2. 设计我们的自动化流水线在动手写代码之前我们先想清楚这个流水线应该帮我们做什么。核心目标有三个保证代码质量每次提交代码自动运行测试确保新改动不会破坏原有功能。自动化构建与发布当我们需要发布新版本时通过一个简单的动作比如打一个Git标签就能自动打包出Docker镜像并推送到镜像仓库。生成部署文档自动生成或更新相关的部署说明比如镜像的拉取命令、版本信息等。基于GitHub Actions我们设计了两个主要的工作流WorkflowCI流水线持续集成监听每一次代码推送比如推送到main分支触发单元测试和模型精度测试。CD流水线持续部署监听特定的Git标签推送事件比如v1.0.0触发Docker镜像的构建和推送。下面这张图概括了整个流程graph TD A[开发者提交代码到GitHub] -- B{触发事件类型?}; B -- 推送到主分支 -- C[CI流水线: 运行测试]; C -- D[测试结果反馈]; B -- 推送版本标签 -- E[CD流水线: 构建镜像]; E -- F[推送镜像到仓库]; F -- G[生成部署文档]; D -- H[流程结束]; G -- H;接下来我们看看具体怎么实现。3. 搭建CI流水线自动运行测试我们的测试主要分两类一类是传统的单元测试检查工具函数、数据处理逻辑对不对另一类是针对模型的“精度”测试虽然不完全是严格的数值精度更多的是检查模型加载、预处理、推理的基本流程是否通畅输出是否合理。我们在项目根目录下的.github/workflows文件夹里创建了一个叫run-tests.yml的文件。name: Run Tests on Push on: push: branches: [ main, develop ] pull_request: branches: [ main ] jobs: test: runs-on: ubuntu-latest steps: - name: Checkout Code uses: actions/checkoutv4 - name: Set up Python uses: actions/setup-pythonv5 with: python-version: 3.9 - name: Install Dependencies run: | pip install --upgrade pip pip install -r requirements.txt # 安装测试相关的额外包 pip install pytest pytest-cov - name: Run Unit Tests run: | pytest tests/unit/ -v --covdeoldify --cov-reportxml - name: Run Model Sanity Tests run: | python tests/model_sanity_test.py env: # 假设测试需要一个小型测试模型文件 TEST_MODEL_PATH: ./test_models/artistic_model.pth这个配置文件做了几件事触发条件当代码推送到main或develop分支或者向main分支发起拉取请求时这个工作流就会启动。准备环境它会在GitHub提供的最新版Ubuntu系统上拉取我们的代码安装指定版本的Python和项目依赖。执行测试Run Unit Tests使用pytest运行tests/unit/目录下的所有单元测试并生成测试覆盖率报告。Run Model Sanity Tests运行一个我们写的模型完整性测试脚本。这个脚本会尝试加载模型用一张小的测试图片跑一遍上色流程确保核心推理链路没有崩溃输出图片的格式、尺寸是符合预期的。这样每次团队成员提交代码都能立刻看到测试是否通过。如果测试失败了GitHub会发出通知我们就能第一时间定位问题而不是等到要打包发布的时候才发现。4. 搭建CD流水线自动构建与推送镜像当测试都通过我们觉得代码可以发布一个新版本了CD流水线就该上场了。我们约定给代码库打上一个类似v1.2.3的标签就代表要发布。我们在.github/workflows目录下创建另一个文件build-and-push.yml。name: Build and Push Docker Image on: push: tags: - v* # 匹配所有以v开头的标签如 v1.0, v1.0.1 jobs: build-and-push: runs-on: ubuntu-latest permissions: contents: read packages: write steps: - name: Checkout Code uses: actions/checkoutv4 - name: Extract Metadata for Docker id: meta uses: docker/metadata-actionv5 with: images: | your-docker-registry/username/deoldify tags: | typesemver,pattern{{version}} typesemver,pattern{{major}}.{{minor}} typeref,eventtag - name: Set up Docker Buildx uses: docker/setup-buildx-actionv3 - name: Log in to Container Registry uses: docker/login-actionv3 with: registry: your-docker-registry.com # 例如 ghcr.io, docker.io username: ${{ secrets.REGISTRY_USERNAME }} password: ${{ secrets.REGISTRY_TOKEN }} - name: Build and Push Docker Image uses: docker/build-push-actionv5 with: context: . file: ./Dockerfile push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: typegha cache-to: typegha,modemax - name: Generate Deployment Doc run: | IMAGE_TAGS${{ steps.meta.outputs.tags }} echo ## 最新镜像版本 DEPLOYMENT.md echo 以下镜像已自动构建并推送至仓库 DEPLOYMENT.md echo \\\bash DEPLOYMENT.md for TAG in $(echo $IMAGE_TAGS | tr , \n); do echo docker pull $TAG DEPLOYMENT.md done echo \\\ DEPLOYMENT.md echo DEPLOYMENT.md echo **构建时间:** $(date) DEPLOYMENT.md echo **Git 标签:** ${{ github.ref_name }} DEPLOYMENT.md echo **提交哈希:** ${{ github.sha }} DEPLOYMENT.md - name: Commit and Push Deployment Doc uses: stefanzweifel/git-auto-commit-actionv5 with: file_pattern: DEPLOYMENT.md commit_message: docs: update deployment info for ${{ github.ref_name }}这个流程稍微复杂点我解释一下关键步骤触发条件只有推送了符合v*模式的标签时才会运行。镜像元数据使用docker/metadata-action自动根据Git标签生成Docker镜像的标签。比如打了标签v1.2.3它会生成your-registry/deoldify:1.2.3、:1.2和:latest如果是最新等多个标签方便不同场景下拉取。登录与构建使用存储在GitHub Secrets中的凭证登录到你的Docker镜像仓库如Docker Hub、GitHub Container Registry等然后使用Buildx构建镜像并推送。这里还配置了缓存能加速后续的构建过程。生成部署文档这一步非常实用。流水线会自动生成或更新一个DEPLOYMENT.md文件里面包含了刚刚构建的镜像的完整拉取命令、构建时间、对应的Git版本信息。任何人需要部署时看这个文件就一目了然。提交文档最后自动将更新后的部署文档提交回代码仓库确保文档与版本同步。注意你需要提前在GitHub仓库的Settings - Secrets and variables - Actions里配置REGISTRY_USERNAME和REGISTRY_TOKEN这是安全登录镜像仓库所必需的。5. 实际效果与经验分享这套流水线跑起来以后最直接的感受就是“省心”和“靠谱”。以前发布一个版本需要我手动做一系列操作跑测试脚本、构建Docker镜像、打标签、推送、再写更新日志。现在我只需要专注写代码然后打一个Git标签剩下的全部交给GitHub Actions。大概几分钟后镜像就已经在仓库里了DEPLOYMENT.md文件也更新好了。团队其他成员看到新标签就知道可以去拉取新镜像了。在实践过程中我们也积累了一些小经验测试要快且稳定CI流水线里的测试不能太耗时否则会影响开发反馈速度。我们的模型完整性测试用的是特别小的测试图片和简化的流程只做最基本的冒烟测试保证核心流程不挂。善用缓存Docker构建和Python依赖安装都比较耗时。我们按照上面配置了Buildx的缓存以及可以使用actions/cache来缓存Python的pip包能显著缩短流水线运行时间。部署文档是宝藏自动生成的DEPLOYMENT.md成了我们团队内部的部署标准参考。运维同事再也不用跑来问“这次更新用哪个镜像标签”了。分支策略我们通常会在develop分支进行功能开发和CI测试main分支用于稳定版本的发布和CD构建。通过PRPull Request来合并代码确保每次合并前CI都是通过的。6. 总结给DeOldify这类AI模型项目配上CI/CD听起来好像是大工程的专属但其实用GitHub Actions来实现门槛并不高。核心思路就是把那些重复性的、容易出错的步骤用配置文件描述出来让自动化工具去执行。这么做的好处是实实在在的。代码质量有了自动化的守护发布流程变得规范且可追溯团队协作起来摩擦也少了。更重要的是它把开发者从繁琐的运维操作中解放出来能更专注于模型效果的优化和业务逻辑的开发。如果你正在管理一个类似的开源项目或者团队内的AI服务强烈建议花点时间把自动化流水线搭起来。一开始可能会觉得有点麻烦但一旦跑通你会发现它带来的效率和可靠性提升绝对是值得的。从最简单的“提交代码自动跑测试”开始逐步完善你的项目也会显得更专业、更可靠。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。

更多文章