Docker

天池Docker提交

2019-03-27  本文已影响0人  FelixCoder

天池竞赛简介

Docker简介

参加天池竞赛不可避免得要碰到一个问题,那就是最基本得提交赛题,本次我遇到的是通过提交阿里容器镜像服务的地址,竞赛刚看完题目后,第一遍提交应该是使用赛题提供的Demo文件提交,这样可以熟悉一遍赛题,熟悉提交流程。所以一定要先对Docker进行一个科普性了解。

Docker是什么?

Docker基本概念

说白了,Docker就是一个能够把你的运行环境也打包的容器,这样才能够让你的提交给赛题方的容器,可以不经过任何修改而直接运行,得出你的成绩。真正使用前还需要了解一些基本概念:镜像、容器、仓库。

名称 打包后大小 运行底层 响应时间(包含修改)
代码打包 MB级别 python+本机操作系统 小时级别
虚拟机 10G级别 虚拟化硬件+虚拟机 开机5分钟
Docker 5G级别 操作系统的Docker引擎 秒级
image
  1. Docker的gitbook地址,有时间的话建议还是把这个全部看完。https://yeasy.gitbooks.io/docker_practice/
  2. 镜像:镜像就像面向对象程序中的类,镜像是静态的定义,镜像可以被修改,增删内容,但是镜像的运行必须通过生成容器实体
  3. 容器:容器就像面向对象程序中的示例,容器是镜像运行时的实体,容器可以被创建、启动、停止、删除、暂停
  4. 仓库:这个仓库就类似git仓库,但是git仓库是储存代码,而docker仓库是储存docker镜像
    • Docker Registry:Docker Registry就像是一个仓库基地,里面可以有很多独立的仓库(Repository)
    • Repository:每个仓库中只能存放一个镜像,同一镜像的不同版本(tag)都放在同一仓库中
    • tag:仓库中镜像的标签(tag)就对应于镜像的版本,取名一般为0.0/2.4等
    • jwilder/nginx-proxy:2.03:表示Docker Registry为jwilder,Repository为nginx-proxy,版本为2.03

如何在天池中提交Docker成功拿到自己的分数(精炼版)

本地准备好代码

按照赛题方要求,写好python代码的输入输出,做好输入参数检查,这里推荐使用argparse,使用demo

import argparse
# 获取参数
parser = argparse.ArgumentParser()
parser.add_argument('--arg1', dest='arg1', type=str, default=None, help='接受--arg1=的参数为变量arg1,类型为str,缺省值为None,参数对应的帮助文档为help的内容')
args = parser.parse_args()
# 执行python **.py --arg1=SSS 后args.arg1的值为'SSS'

编写requirements.txt

检查你的代码中所有的import,然后使用pip list查看你本地使用的版本,在同级目录中添加requirements.txt

Pillow==5.3.0
tqdm==4.19.2
torchnet==0.0.4

编写Docker文件

这一步其实是最难也是最关键的,但是我们是为了使用Docker而使用,所以这一步简化再简化,这里直接提供一个可以使用的制作cuda8.0+pytorch1.0.1镜像的Docker文件,使用该文件可以直接生成cuda8.0+pytorch1.0.1镜像

# Modify from source: https://hub.docker.com/r/nvidia/cuda
# This Docker build is 3.1G
# -----------------------------------------------------------------------------
FROM ubuntu:16.04
LABEL maintainer "NVIDIA CORPORATION <cudatools@nvidia.com>"

RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates apt-transport-https bzip2 gnupg-curl wget && \
    rm -rf /var/lib/apt/lists/* && \
    NVIDIA_GPGKEY_SUM=d1be581509378368edeec8c1eb2958702feedf3bc3d17011adbf24efacce4ab5 && \
    NVIDIA_GPGKEY_FPR=ae09fe4bbd223a84b2ccfce3f60f4b3d7fa2af80 && \
    apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/7fa2af80.pub && \
    apt-key adv --export --no-emit-version -a $NVIDIA_GPGKEY_FPR | tail -n +5 > cudasign.pub && \
    echo "$NVIDIA_GPGKEY_SUM  cudasign.pub" | sha256sum -c --strict - && rm cudasign.pub && \
    echo "deb https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64 /" > /etc/apt/sources.list.d/cuda.list


ENV CUDA_VERSION 8.0.61

ENV CUDA_PKG_VERSION 8-0=$CUDA_VERSION-1
RUN apt-get update && apt-get install -y --no-install-recommends \
        cuda-nvrtc-$CUDA_PKG_VERSION \
        cuda-nvgraph-$CUDA_PKG_VERSION \
        cuda-cusolver-$CUDA_PKG_VERSION \
        cuda-cublas-8-0=8.0.61.2-1 \
        cuda-cufft-$CUDA_PKG_VERSION \
        cuda-curand-$CUDA_PKG_VERSION \
        cuda-cusparse-$CUDA_PKG_VERSION \
        cuda-npp-$CUDA_PKG_VERSION \
        cuda-cudart-$CUDA_PKG_VERSION && \
    ln -s cuda-8.0 /usr/local/cuda && \
    rm -rf /var/lib/apt/lists/*

# nvidia-docker 1.0
LABEL com.nvidia.volumes.needed="nvidia_driver"
LABEL com.nvidia.cuda.version="${CUDA_VERSION}"

RUN echo "/usr/local/nvidia/lib" >> /etc/ld.so.conf.d/nvidia.conf && \
    echo "/usr/local/nvidia/lib64" >> /etc/ld.so.conf.d/nvidia.conf

ENV PATH /usr/local/nvidia/bin:/usr/local/cuda/bin:${PATH}
ENV LD_LIBRARY_PATH /usr/local/nvidia/lib:/usr/local/nvidia/lib64

# nvidia-container-runtime
ENV NVIDIA_VISIBLE_DEVICES all
ENV NVIDIA_DRIVER_CAPABILITIES compute,utility
ENV NVIDIA_REQUIRE_CUDA "cuda>=8.0"
#-----------------------------------------------------------------------------


#MiniConda Install
RUN wget "https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh" && \
    bash ./Miniconda3-latest-Linux-x86_64.sh* -b -p && \
    rm Miniconda3* 
ENV PATH="/root/miniconda3/bin:${PATH}"

#Add Requirement Packages 
RUN conda install pytorch torchvision cudatoolkit=8.0 -c pytorch && \
    conda clean -all --yes

执行完成后,将对应的Docker镜像push到阿里云Docker镜像服务,这样相当于有了一个自己的cuda8+pythch镜像,在这个镜像的基础上,再进行后续操作

#Above image
FROM $你的阿里镜像地址
LABEL maintainer "容器名称"
#设置工作目录
WORKDIR /competition
#添加工作目录下的所有文件
ADD [^p^u]* /competition/

编写run.sh文件

run.sh文件是docker运行的入口,所以你的python执行文件命令必须在run.sh中写完整,$1在脚本中表示脚本接收到的第一个参数(也相当于docker运行的第一个参数),我们需要把这个参数传递给python执行

#!/bin/bash
#
# run.sh is the entry point of the submission.
# nvidia-docker run -v ${INPUT_DIR}:/input_images -v ${OUTPUT_DIR}:/output_data
#       -w /competition ${DOCKER_IMAGE_NAME} sh ./run.sh /input_images /output_data/result.csv
# where:
#   INPUT_DIR - directory with input png images
#   OUTPUT_FILE - the classification result for each image
#

INPUT_DIR=$1
OUTPUT_FILE=$2

python main.py \
  --input_dir="${INPUT_DIR}" \
  --output_file="${OUTPUT_FILE}" \

拉取官方/私有Docker基础镜像,并且制作自己的镜像

做好上述工作后,使用命令sudo docker build -t $docker_name .制作新的docker镜像,这时系统会拉取Docker文件中FROM地址对应的镜像,并且执行后续的修改,并且将其打包成新的镜像,镜像名称为$docker_name

自己的镜像添加改名版本号

使用sudo docker images查看刚才自己制作的docker的ID,并且使用如下命令对docker重命名,为后续的push设置仓库地址和版本号 `sudo docker tagID registry.cn-shenzhen.aliyuncs.com/你的阿里容器仓库地址:版本号`

Push自己的镜像

使用如下命令push自己的本地镜像到阿里云
sudo docker push registry.cn-shenzhen.aliyuncs.com/felix1/$你的阿里容器仓库地址:$版本号
执行完毕后,可以在自己镜像仓库的镜像版本中看到自己推送的镜像,即完成了整个Docker的制作与推送

感想

这也是我本人第一次用Docker,感觉Docker是在纯代码和虚拟机之间的一种折衷,既想方设法得保证所有环境都可以正常迁移到新的环境,又相比于虚拟机减少冗余部分,而只保留了程序运行所必须的部分,而且实测,新制作的Docker拉取到一台陌生的机器上时,可以完美直接运行,性能也基本没有下降,而且支持Docker直接使用本机显卡,这对深度学习使用Docker简直是福音。

上一篇 下一篇

猜你喜欢

热点阅读