89·工程化与部署进阶

Docker 容器化部署机器学习模型

deploymentdocker

第89课:Docker 容器化部署机器学习模型

课程标签:deployment, docker
所属模块:工程化与部署
难度:中级
上一课:FastAPI 高性能模型服务
下一课:模型监控与数据漂移检测


1. 学习目标

完成本课学习后,你将能够:

  • 理解容器化(Containerization)的基本概念及其在机器学习部署中的核心优势。
  • 编写一个有效的 Dockerfile 来打包一个机器学习模型及其服务(如 FastAPI)。
  • 使用 docker builddocker run 命令构建镜像并运行容器。
  • 理解卷(Volume)挂载在本地开发与调试中的重要作用。
  • 了解如何将构建好的镜像推送到容器仓库(如 Docker Hub),为后续的集群部署做准备。

2. 核心概念

容器化就像为你的应用程序(包括代码、运行时、库和依赖)创建一个标准化的“集装箱”。无论这个“集装箱”被运到哪里(开发机、测试服务器、生产云环境),内部环境都完全一致,彻底解决了“在我机器上能运行”的经典难题。

Docker 是当前最流行的容器化工具。它的核心概念是:

  • 镜像 (Image):一个只读的模板,包含了运行应用所需的一切。你可以把它看作是容器的“源代码”或“安装盘”。
  • 容器 (Container):镜像的一个运行实例。你可以从一个镜像创建多个相互隔离的容器。
  • Dockerfile:一个文本文件,包含了一系列构建镜像的指令(如“安装Python”、“复制代码”、“暴露端口”)。它是构建镜像的“说明书”。

对于机器学习模型部署,Docker 的优势在于:

  1. 环境一致性:打包特定版本的 Python、PyTorch/TensorFlow、scikit-learn 以及模型文件,确保从训练到推理的环境无缝衔接。
  2. 简化部署:一个容器就是一个完整的、可运行的服务单元,无需在服务器上手动安装一堆依赖。
  3. 易于扩展:容器可以被快速复制和启动,是构建微服务和自动化扩缩容的基础。

3. 代码示例

让我们基于上一课的 FastAPI 模型服务,创建一个可部署的 Docker 容器。

第一步:准备项目结构 假设你的项目目录如下:

ml-project/
├── app/
│   ├── __init__.py
│   ├── main.py          # FastAPI 服务代码
│   ├── model.py         # 模型加载和预测逻辑
│   └── schemas.py       # 数据模型定义
├── model/
│   └── model.joblib     # 训练好的模型文件
├── requirements.txt     # Python 依赖列表
└── Dockerfile           # 我们将要创建的文件

第二步:创建 requirements.txt

fastapi==0.104.1
uvicorn[standard]==0.24.0
scikit-learn==1.3.2
joblib==1.3.2
pandas==2.1.4

第三步:编写 Dockerfile 在项目根目录下创建一个名为 Dockerfile 的文件(没有后缀名),并写入以下内容:

# 1. 使用官方 Python 基础镜像
FROM python:3.10-slim

# 2. 设置工作目录(容器内的路径)
WORKDIR /app

# 3. 先复制依赖文件,利用 Docker 的层缓存机制优化构建速度
COPY requirements.txt .

# 4. 安装 Python 依赖
RUN pip install --no-cache-dir -r requirements.txt

# 5. 将项目代码和模型文件复制到工作目录
COPY ./app ./app
COPY ./model ./model

# 6. 声明容器运行时将监听的端口(仅文档作用)
EXPOSE 8000

# 7. 定义容器启动时运行的命令
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]

指令解读

  • FROM:选择基础镜像。python:3.10-slim 是一个包含 Python 3.10 的轻量级镜像。
  • WORKDIR:设置后续指令的工作目录,类似于 cd
  • COPY:将本地文件/目录复制到镜像中。注意:COPY 的第一个路径是相对于 Dockerfile 所在目录的构建上下文(Build Context)。
  • RUN:在镜像构建过程中执行命令(如安装软件)。
  • EXPOSE:声明容器监听的端口,方便使用者了解。
  • CMD:指定容器启动时默认执行的命令。这里我们启动了 Uvicorn 服务器。

第四步:构建并运行容器 在终端中,进入项目根目录(Dockerfile 所在目录),执行以下命令:

# 1. 构建镜像(-t 用于给镜像命名)
docker build -t my-ml-api .

# 2. 运行容器(-p 将本地端口映射到容器端口)
docker run -p 8000:8000 my-ml-api

现在,你可以在浏览器中访问 http://localhost:8000/docs,应该能看到 FastAPI 自动生成的交互式文档,说明你的模型服务已经在一个隔离的容器中成功运行了!

进阶:使用卷挂载进行本地开发 在开发阶段,每次修改代码都要重新构建镜像很不方便。可以使用卷(Volume)将本地代码目录映射到容器中,实现热重载。

# 将当前目录的 `app` 文件夹挂载到容器内的 `/app/app`,并运行带热重载的 uvicorn
docker run -p 8000:8000 -v $(pwd)/app:/app/app my-ml-api uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload

现在,你在本地修改 app/ 下的任何代码,容器内的服务都会自动重启。

4. 实践练习

练习一:基础 - 创建自己的 Dockerfile 你有一个简单的脚本 train.py,它需要 numpypandas。请编写一个 Dockerfile,使其能在容器中执行这个脚本。

  • 要求:基础镜像使用 python:3.9-slim,工作目录为 /workspace
  • 预期:构建镜像后,通过 docker run <image_name> python train.py 可以成功执行。

练习二:中级 - 容器内运行模型预测 基于课程示例的 ml-project 结构,完成以下任务:

  1. app/main.py 中添加一个简单的预测端点 /predict
  2. 使用提供的 Dockerfile 构建并运行容器。
  3. 使用 curl 或浏览器向容器内的服务发送一个预测请求。
  • 要求:记录你的构建命令、运行命令和测试请求的 curl 命令。
  • 预期:容器能正确返回预测结果。

练习三:挑战 - 多阶段构建优化 研究多阶段构建(Multi-stage Build)。目标是创建一个更小的生产镜像,其中不包含 pip 等构建工具。

  • 提示:在一个阶段安装依赖并复制代码,在另一个更精简的运行时镜像中,只复制必要的代码和安装的库。
  • 预期:最终镜像大小相比单阶段构建显著减小。

5. 常见错误

  1. 路径错误COPYADD 指令中的源路径是相对于构建上下文的,而不是 Dockerfile 文件本身。通常你需要在包含 Dockerfile 和项目代码的根目录运行 docker build .
  2. 忽略 .dockerignore:创建一个 .dockerignore 文件(语法类似 .gitignore),排除 .git__pycache__.venv、模型大型数据文件等,可以加快构建速度并减小镜像体积。
  3. 未暴露端口:虽然 EXPOSE 指令主要是文档作用,但忘记在 docker run 时使用 -p 参数映射端口,会导致无法从容器外部访问服务。
  4. 依赖安装问题requirements.txt 中指定的库版本与基础镜像中的系统环境不兼容(如某些 C 库版本)。使用 slimalpine 镜像时可能需要额外安装系统依赖。
  5. 工作目录设置错误:后续的 COPYCMD 命令都基于 WORKDIR 的设置,确保文件复制到了正确的位置。

6. 小结

在本课中,我们学习了使用 Docker 容器化部署机器学习模型的核心流程:

  • 容器化的核心是打包应用及其完整运行环境,确保一致性可移植性
  • Dockerfile 是定义镜像构建步骤的蓝图,通过 FROM, COPY, RUN, CMD 等指令描述应用环境。
  • 通过 docker build 构建镜像,docker run 启动容器,并使用 -p 参数暴露端口。
  • 在开发阶段,善用卷挂载(Volume Mount) 可以极大地提升调试效率。
  • 将镜像推送到 Docker Hub 或其他仓库(docker push),是迈向自动化部署(如 Kubernetes)的关键一步。

掌握 Docker 部署,意味着你能够将“可运行的代码”转变为“可交付的产品”,这是成为一名成熟机器学习工程师的重要里程碑。

练习编辑器

rust
Loading...

继续学习

完成本课后,建议继续学习下一课「模型监控与数据漂移检测」 以巩固所学知识。