Continuous Integration (CI)
持续集成(CI)会频繁合并代码更改,并自动测试每项更改;ML 流水线还会加入数据检查和模型质量门禁。
持续集成(CI)是指频繁将每位开发者的更改合并到共享主分支(至少每天一次),并自动构建和测试每次更改,从而在几分钟内发现集成问题,而不是等到发布时才发现。Grady Booch 于 1991 年提出这一术语;Kent Beck 在 20 世纪 90 年代末将其确立为极限编程的核心实践;Martin Fowler 的文章持续集成介绍了大多数团队至今仍采用的工作流。在机器学习(ML)中,CI 还会检查数据、训练代码和模型行为,因为某项更改可能在所有单元测试通过的同时降低模型的准确率。
CI 流水线的工作原理#
开发者推送分支或创建拉取请求时,GitHub Actions、GitLab CI/CD 或 Jenkins 等 CI 服务会启动一个全新的运行器,检出代码、安装依赖项,并运行由多个作业组成的流水线:代码检查器和类型检查器、单元测试、集成测试,以及软件包或容器镜像构建。每个作业都会向拉取请求报告状态;分支保护规则可以阻止合并,直到所有必需的检查都通过。流水线通常会针对不同操作系统和 Python 版本的矩阵重复运行相同的测试,并在每次合并后于主分支上重新运行完整测试套件。速度也是这项实践的一部分:Beck 的极限编程将构建整个系统并运行所有测试的目标时间设为 10 分钟,因为构建越慢,运行频率就越低。
机器学习项目中的 CI#
ML 项目还需要进行专门检查。数据测试会确认新的训练数据符合预期架构、每个标签文件都能解析,并确保同一图像不会同时出现在训练集和验证集中,否则会造成数据泄漏。冒烟测试会在小型数据集上训练一个轮次,以便在几分钟内发现形状错误和崩溃。比较模型输出的测试会固定随机种子并允许较小的数值误差,因为 GPU 内核和数据加载顺序可能导致不同运行产生不同的浮点结果。质量门会在固定验证集上为模型评分;如果平均精度均值(mAP)等指标低于底线,构建就会失败。导出测试则会检查 ONNX 或 TensorRT 版本的模型能否正常加载,并取得与原始模型相近的分数。完整训练耗时较长,GPU运行器也很昂贵,因此团队通常会在每个拉取请求上运行快速检查,并将完整重训练和模型部署留给定时运行或主分支运行;DVC 等版本管理工具则能让每个作业获取所需的确切数据集版本。
Ultralytics YOLO 的基准测试模式可以作为这样的质量门:将 verbose 设为 0.216 等浮点数时,如果导出失败,或任何导出格式的 mAP50-95 未超过该底线,系统就会报错;Ultralytics 仓库自己的 CI会使用此功能,在 Linux、macOS 和 ARM 运行器上测试 YOLO26 的导出结果。下面是一个将单元测试与该质量门结合起来的最简 GitHub Actions 工作流:
name: CI
on:
pull_request:
push:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v6
with:
python-version: "3.13"
- run: pip install ultralytics pytest
- run: pytest tests/
# Fail if the ONNX export breaks or its mAP50-95 is not above the 0.216 floor
- run: yolo benchmark model=yolo26n.pt format=onnx imgsz=160 verbose=0.216每个拉取请求以及每次推送到 main 的操作,都会在全新的 Ubuntu 运行器上运行该作业。如果单元测试失败,或 ONNX 模型在小型 COCO8 数据集上的评分未超过底线,检查就会显示红色,阻止更改合并。
CI 与 CD、MLOps 和持续训练#
- 持续交付(CD):将通过 CI 的构建成果保持在可发布状态,通常会自动将其部署到预发布环境。持续部署则更进一步,会将每项通过检查的更改直接发布到生产环境。
- MLOps:更广泛的实践领域,涵盖 ML 生命周期中的 CI 和 CD、数据版本管理、模型部署、监控和重新训练。
- 持续训练(CT):在有新数据到来或监控检测到漂移时,自动重新训练并重新部署模型。Google 的 MLOps 成熟度等级将自动重新训练列为 1 级,将训练流水线本身的自动化 CI/CD 列为 2 级。










