使用自定义镜像训练模型

最近更新时间:2019-12-12 15:47:34

操作场景

TI 平台预置了 TensorFlow、Pytorch 等流行的机器学习框架,方便用户快速使用 SDK 提交训练任务。除了平台预置的框架和算法外,TI 还允许用户打包自己的算法并上传自定义镜像到平台进行训练。

无论您使用哪种编程语言、系统环境、机器学习框架,及需要安装哪些库依赖,只要您的自定义镜像及训练脚本遵循 TI 的容器规范约束,即可在 TI 平台完成训练。

本文档将向您介绍 TI 自定义镜像需要遵循的一些容器规范约束,再通过几个典型案例向您演示如何制作镜像。

容器规范

启动规范

TI 启动训练容器的方式可以类比为在本地执行 docker run 命令

$ docker run {image_name} train

其中 train 为 TI 传入的启动参数,容器入口(EntryPoint)需遵循以下启动规范:

  • 镜像未指定 EntryPoint 情况
    train 即为启动命令,系统路径$PATH中必须包含 train 的命令
  • 镜像指定 EntryPoint 情况
    train 为传入 EntryPoint 命令的第一个参数,EntryPoint 可以选择解析这个参数或忽略

目录规范

TI 在启动训练容器前,会做一些准备工作,包括

  1. 在容器内/opt/ml/下新建多个工作目录,详见下表
  2. 拉取训练数据到输入数据目录(/opt/ml/input/data/)
  3. 落地训练需要的超级参数配置和资源配置到输入配置目录中(/opt/ml/input/config/)

自定义镜像的训练脚本只需要去这些目录下读取训练数据和配置,训练完后将模型文件写入到模型目录,checkpoint 和训练日志写入到输出目录中,TI 后台会自动将模型和输出目录的文件自动上传到用户指定的 COS 存储桶中。

下表是 TI 自动创建的工作目录和文件

名称 容器内目录 备注
输入目录 /opt/ml/input/ 存放训练输入相关的目录
输入配置目录 /opt/ml/input/config/ 存放训练相关的配置文件
超级参数文件 /opt/ml/input/config/hyperparameters.json 文件为 JSON 格式,读取值是为 string 格式
资源配置文件 /opt/ml/input/config/resourceConfig.json 分布式训练时的网络布局描述
输入数据目录 /opt/ml/input/data/ 存放训练数据的目录
模型目录 /opt/ml/model/ 模型文件将被自动压缩为 tar 包格式上传到 COS
输出目录 /opt/ml/output/ 存放训练过程的 checkpoint 及日志文件,训练失败时将把 FailReason 写进 failure 文件

目录结构:
/opt/ml

├── input

│  ├── config

│  │  ├── hyperparameters.json

│  │  └── resourceConfig.json

│  └── data

│     └── user input data

├── model

│  └── user model files

└── output

   └── failure

典型案例 Scikit-learn 决策树

下面的例子实现了一个 Scikit-learn 决策树的自定义镜像,例子源码可以在 sdk example 中找到。

ti-python-sdk/example/scikit/decision-trees

制作镜像

Dockerfile所在目录结构:

├── Dockerfile

├── build_and_push.sh   // 构建镜像并 push 镜像到镜像仓库的脚本

├── sources.list      // 建议替换成腾讯云 apt 源

├── pip.conf        // 建议替换成腾讯云 pip 源

└── decision_trees

  └── train       // 训练脚本,EntryPoint,此处内容为 Python 的格式

Dockerfile 文件:

FROM ubuntu:16.04

COPY sources.list /etc/apt/

RUN apt-get -y update && apt-get install -y --no-install-recommends \
         wget \
         python \
         nginx \
         ca-certificates \
    && rm -rf /var/lib/apt/lists/*

COPY pip.conf /etc/

RUN wget https://bootstrap.pypa.io/get-pip.py && python get-pip.py && \
    pip install numpy==1.16.2 scipy==1.2.1 scikit-learn==0.20.2 pandas==0.24 flask gevent gunicorn && \
        (cd /usr/local/lib/python2.7/dist-packages/scipy/.libs; rm *; ln ../../numpy/.libs/* .) && \
        rm -rf /root/.cache

# Update PATH so that the train program is found when the container is invoked.

ENV PYTHONUNBUFFERED=TRUE
ENV PYTHONDONTWRITEBYTECODE=TRUE
ENV PATH="/opt/program:${PATH}"

# Set up the program in the image
COPY decision_trees /opt/program
WORKDIR /opt/program

执行 build_and_push.sh 文件制作和上传镜像到腾讯云容器服务镜像仓库。

$ build_and_push.sh decision_trees

提交训练

example.py:

from __future__ import absolute_import, print_function

from ti import session
from ti.estimator import Estimator

def test_scikit_decision_trees_training():
    try:
        print("Set up ti environment")
        ti_session = session.Session()

        role = "TIONE_QCSRole"

        print("Upload the data to a COS bucket")
        inputs = ti_session.upload_data(path="data", key_prefix="data/scikit/decision-trees")
        print(inputs)

        print("Start training on ti")
        tree = Estimator(image_name="ccr.ccs.tencentyun.com/ti_private/decision-trees:latest",
                         role=role,
                         train_instance_count=1,
                         train_instance_type='TI.LARGE8.4core8g')
        tree.fit(inputs)
    except Exception as e:
        print(e)

if __name__ == '__main__':
    test_scikit_decision_trees_training()

运行 example.py 提交训练任务:

$ python example.py

典型案例自定义 Tensorflow 镜像

下面的例子实现了一个自定义 Tensorflow 镜像,使用 cifar10 数据集作为训练集,例子源码可以在 sdk example 中找到

ti-python-sdk/example/cifar10

制作镜像

Dockerfile:

FROM tensorflow/tensorflow:1.8.0-py3

# Update PATH so that the train program is found when the container is invoked.
ENV PATH="/opt/program:${PATH}"

COPY /cifar10 /opt/program

WORKDIR /opt/program

通过执行 build_and_push.sh 文件制作和上传镜像到腾讯云容器服务镜像仓库

$ build_and_push.sh tensorflow1.8-py3-cifar10

制作完的镜像名称为:ccr.ccs.tencentyun.com/ti_private/tensorflow1.8-py3-cifar10:latest

准备 CIFAR-10 数据集

执行以下命令下载 CIFAR-10 数据集到 cifar-10-data 目录,并转换成 TFRecords 格式:

$ python utils/generate_cifar10_tfrecords.py --data-dir=<your workspace>/cifar-10-data

cifar-10-data/

├── eval.tfrecords

├── train.tfrecords

└── validation.tfrecords

提交训练

example.py:

from __future__ import absolute_import, print_function

from ti import session
from ti.estimator import Estimator


def test_cifar10_training():
    try:
        print("Set up ti environment")
        ti_session = session.Session()

        role = "TIONE_QCSRole"

        print("Upload the data to a COS bucket")
        inputs = ti_session.upload_data(path="cifar-10-data/", key_prefix="/data/tensorflow-cifar10")
        print(inputs)

        print("Start training on ti")
        tree = Estimator(image_name="ccr.ccs.tencentyun.com/ti_private/tensorflow1.8-py3-cifar10:latest",
                         role=role,
                         train_instance_count=1,
                         train_instance_type='TI.LARGE8.4core8g',
                         hyperparameters={'train-steps': 100})
        tree.fit(inputs)
    except Exception as e:
        print(e)

if __name__ == '__main__':
    test_cifar10_training()

运行 example.py 提交训练任务:

$ python example.py