在传统软件部署中,开发人员通常只需要关注源代码、依赖库和容器镜像。但进入机器学习和生成式AI系统之后,一个新的问题出现了:模型本身也是一种需要版本控制和生命周期管理的生产制品。一个推理服务到底运行的是哪个模型、使用哪一版代码、依赖什么运行环境、来自哪一次训练以及最终部署到了哪台GPU节点,这些信息如果没有建立清晰的关联,系统运行一段时间后就很容易出现“代码一样、镜像一样,但模型已经不是同一个模型”的情况。
模型注册中心和容器镜像仓库因此经常同时出现在AI部署架构中,但两者解决的并不是同一个问题。模型注册中心主要负责管理模型版本和模型生命周期,例如模型名称、版本号、来源、评估指标、标签、模型状态以及模型文件的位置等;容器镜像仓库则负责保存和分发OCI/Docker镜像,里面通常包含应用程序代码、Python运行环境、系统库以及推理框架等运行时组件。
理解这两个系统最重要的一点,是不要把“模型”和“运行模型的环境”当成同一种制品。一个经过训练的PyTorch模型文件可能存储在对象存储中,而负责加载这个模型的FastAPI、Triton Inference Server或其他推理服务代码,则可以被构建成容器镜像。镜像仓库保存的是这个运行环境,模型注册中心管理的是模型生命周期,两者通过版本和部署元数据建立联系。
因此,一个更加典型的AI部署链路实际上包含至少四个角色:代码仓库、模型注册中心、模型Artifact Store以及容器镜像仓库。训练代码通常来自Git仓库;训练完成后产生的模型权重、Tokenizer、配置文件等Artifact通常存放在对象存储或其他Artifact Store;模型注册中心保存这些Artifact对应的模型版本和元数据;推理服务代码及其依赖则被构建成容器镜像并推送到容器镜像仓库。
例如一次训练产生模型fraud-model:42。模型注册系统可以记录该模型的版本、训练运行ID、评估指标、数据集版本、代码Commit以及模型Artifact URI。与此同时,推理服务代码被构建成类似registry.example.com/fraud-api@sha256:xxxx这样的容器镜像。部署系统随后同时指定模型版本42和这个镜像Digest。容器启动以后,根据部署配置取得模型Artifact,再由推理服务加载模型。
这种设计比“每产生一个模型就重新制作一个巨大的Docker镜像”更加灵活。特别是大型语言模型、视觉模型和多模态模型,权重文件可能非常庞大。如果每次模型更新都重新构建和分发一个包含完整模型权重的容器镜像,不仅会增加镜像体积,也会明显增加CI/CD构建时间、Registry存储压力和节点拉取时间。生产环境因此经常采用“镜像与模型分离”的方式,让容器镜像保持相对稳定,而模型作为独立Artifact进行版本管理。
当然,在某些小型模型或者需要极强部署封装性的场景中,也可以把模型直接放进容器镜像。这种方式能够获得较强的制品不可变性,因为镜像本身就包含了模型和推理代码。但它的代价是模型更新必须重新构建和分发镜像。因此应该根据模型大小、更新频率、部署规模和供应链要求决定,而不是把其中一种方式当成唯一标准。
模型依赖关系同样需要分层处理。Python依赖可以通过requirements.txt、Poetry或其他锁定文件管理;推理框架可能涉及PyTorch、TensorFlow、ONNX Runtime或Triton;GPU环境还涉及CUDA Runtime、cuDNN以及宿主机NVIDIA Driver。这里不能简单地把“模型依赖”全部交给模型注册中心。模型注册中心负责描述模型及其来源,而具体运行环境通常由源码仓库、锁定依赖文件、容器构建文件和基础镜像共同定义。
在Kubernetes环境中,部署对象通常会同时引用容器镜像和模型版本。例如Deployment指定某一个不可变的镜像Digest,环境变量或配置文件指定模型注册中心中的模型名称和版本。Pod启动后,推理服务根据这个版本取得对应Artifact,并加载到本地缓存、Persistent Volume或者节点存储中。对于大型模型,还可以建立模型缓存机制,避免每次Pod重启都从远程对象存储重新下载完整权重。
这里尤其需要注意ConfigMap的使用边界。Kubernetes ConfigMap适合保存配置数据,例如模型名称、服务参数、环境设置等,但并不适合作为大型模型文件的存储方式。大型模型更适合放在对象存储、持久化卷或者专门的模型缓存系统中。这样既可以避免Kubernetes对象本身承担不适合的存储任务,也便于多个推理实例共享或缓存模型。
版本一致性是整个系统最容易被忽略、却最重要的一环。真正需要绑定的通常不只是“模型版本”和“镜像标签”,还包括源代码Commit、容器镜像Digest、模型Artifact版本、配置版本以及必要时的数据版本。例如一次生产部署可以形成这样的完整记录:模型42来自某次训练Run,模型Artifact具有确定的校验值,推理代码来自Git某个Commit,容器使用固定Digest,部署配置则来自某个Git版本。这样出现线上问题时,工程人员才能真正做到可追溯和可复现。
这里也解释了为什么生产环境更推荐使用镜像Digest而不是只使用latest之类的可变标签。标签可以被重新指向其他镜像,而Digest对应的是确定的镜像内容。模型版本同样应该具有不可歧义的身份标识。只有模型Artifact、代码和运行环境都能够被准确定位,所谓的“可复现部署”才真正成立。
CI/CD在这个体系中的作用,是把这些制品按照规定的流程连接起来,而不是让模型注册中心直接负责所有事情。一次新的模型训练完成后,可以由训练流水线执行模型评估,满足质量门槛后注册新模型版本;随后CI流水线构建或验证推理服务镜像;部署系统再把经过批准的模型版本、镜像Digest和配置组合成一次部署。模型更新是否触发镜像重新构建,则应该由具体架构决定。如果推理代码和运行环境没有变化,只更换模型Artifact,完全可以不重新构建整个镜像。
DVC、MLflow等工具也应该放在各自合适的位置理解。DVC可以用于数据和模型Artifact的版本控制,MLflow可以提供实验跟踪、模型管理和Registry等能力,但它们并不等于完整的CI/CD系统,更不会天然决定每一次模型变化之后是否必须重新构建容器。真正的自动触发机制通常来自Git、CI/CD平台、Webhook、工作流引擎或者其他事件驱动系统。
从整体架构来看,比较清晰的AI部署链路可以理解为:代码仓库保存推理代码和构建定义,训练系统产生模型Artifact,模型注册中心记录模型版本和元数据,Artifact Store保存实际模型文件,容器构建系统产生推理镜像,容器镜像仓库存储和分发镜像,Kubernetes或其他运行平台最终把指定的镜像和指定的模型版本组合起来运行。
这也意味着,模型注册中心与容器镜像仓库并不是互相替代的两个系统。一个回答的是“我们正在部署哪个模型以及这个模型从哪里来”,另一个回答的是“运行这个模型的软件环境是什么”。真正成熟的AI工程体系,最终追求的并不是简单地把两个仓库连接起来,而是让模型、代码、运行环境、数据和配置都拥有明确的身份,并且能够在出现模型质量下降、推理错误或环境升级问题时准确回溯到当时运行的完整制品组合。
对于小型AI项目,这套体系不必一开始就堆叠大量平台。一个Git仓库、一个对象存储、一个模型Registry和一个容器Registry已经可以形成基本闭环。随着模型数量、GPU节点和部署环境增加,再逐步加入模型缓存、自动评估、审批、灰度发布、回滚以及监控机制。最终形成的核心原则其实很简单:模型负责版本化,镜像负责环境封装,Artifact Store负责大型文件,部署系统负责把确定版本的制品组合起来。把这几个边界划清楚,AI模型从训练走向生产就不会变成一场“哪个文件到底是哪一版”的考古工作。
模型注册中心与容器镜像仓库有什么区别,AI 模型部署链路如何连接二者
图片说明:示意图 图片来源:Public Domain(公有领域)
喜欢这篇报道?
使用下面的功能,方便以后继续阅读和分享 MNewsTV
关于文章收藏
收藏不需要注册帐号,收藏信息仅保存在当前浏览器中。
删除收藏请进入「我的收藏」进行管理。
捐助(Paypal): https://www.paypal.me/observeccp 订阅中国观察电报 Telegram : https://t.me/s/ObserveCCP