谷歌云(GCP)平台命令行应用实践

谷歌云(GCP)平台命令行应用实践

本文来自社区投稿与征集,作者:段嘉铭,蚂蚁金服算法工程师;胡旭华,谷歌开发者专家(机器学习)

简介

算法平台硬件的运算能力是推动人工智能发展的一个关键因素。一些规模较大的企业会为算法研发人员配备完善的的服务器集群,甚至自主研发相应的云计算服务平台。然而,这对很多初创团队或个人开发者而言并不现实,不仅成本高昂,而且维护工作还相当繁琐。因此,一个既能按需收费也能一键式调度控制云算力资源的解决方案呼之欲出。谷歌云平台 (Google Cloud Platform,GCP) 提供的命令行控制服务就是一个同时满足按需收费与一键式脚本调度云计算资源的解决办法。我们将介绍如何应用这个服务完成实战任务,至于 GCP 的相关架构与原理介绍网上有很多,我们不再赘述。

GCP 命令行控制

我们在学习 GCP 命令行控制前,需要完成以下两个工作准备:

  • 拥有绑定 GCP 的 Google 账号。
  • 获得在 GCP 平台申请的 GPU 配额。

当大家完成这两个准备以后,我将在这部分重点与大家一起学习如何使用纯命令行方式控制 GCP 实例 (Instance) 的操作。或许,有小伙伴会问:“为什么我们不直接使用 Web 端的图形化界面操作实例呢?”。原因是命令行方式有以下两大优点:

  1. 命令行的操作简单、成本低。
  2. 命令行方便编写脚本一键配置 GCP 实例。

因为 GCP 的所有方案都是按秒级收费的,所以我们希望通过设计规则自动创建和删除 GCP 实例,实现 GCP 计算资源的高效利用。比如,我们打算训练 T5 大型自然语言模型,但不希望宝贵的 GCP 计算时间被浪费在繁琐的代码准备阶段。此时,我们可以在自己的代码中配置脚本自动地创建或继续运行实例完成大模型的训练。在模型训练完成或发生异常时,它能自动暂停 GCP 实例以避免计算资源的白白浪费。

下面,我们开始 GCP 命令行控制之旅。

GCloud 安装方法

首先,我们需要从 官网 下载适合我们电脑系统的开发工具包,比如我现在的系统是普通 64 位 MacOS,那么我便点击图示的 google-cloud-sdk-361.0.0-darwin-x86_64.tar.gz 下载压缩包即可。

下载完成后,我们将压缩文件移动到工作区目录,比如 /Users/ShuaiGe666/workspace,并解压它就能得到一个 google-cloud-sdk 目录,这个目录的内部结构如下:

.
└── google-cloud-sdk
   ├── LICENSE
   ├── README
   ├── RELEASE_NOTES
   ├── VERSION
   ├── bin
   ├── completion.bash.inc
   ├── completion.zsh.inc
   ├── data
   ├── deb
   ├── install.bat
   ├── install.sh
   ├── lib
   ├── path.bash.inc
   ├── path.fish.inc
   ├── path.zsh.inc
   ├── platform
   ├── properties
   └── rpm

然后,我们只需将这上面 bin 目录添加到系统的环境变量即可使用这个 GCP 命令行工具。比如我要为 MacOS 的 zsh 终端添加这个工具,仅需运行下面这行命令:

$ echo 'export PATH="/Users/ShuaiGe666/workspace/google-cloud-sdk/bin:$PATH"' >> ~/.zshrc

如果您使用的是 Linux 系统常用的 bash 终端,只需将命令中的 ~/.zshrc 替换成 ~/.bashrc即可。

最后,我们执行下面命令并按照提示完成 GCloud 环境的初始化。至此,我们便完成了 GCloud 命令行工具包的安装任务。值得注意的是,GCloud SDK 需要依赖 Python 环境(推荐使用 Python3.7), Python -V 指令可以帮助我们检查运行环境是否符合要求。更多关于 Python 解释器选型的内容,请移步到 官网相关介绍

$ gcloud init --skip-diagnostics

GCloud 常用操作

完成 GCloud 命令行工具的安装后,我们了解一下它的几个常用操作指令。对于 GCP 实例,我们的主要操作有创建、查看、连接与“启停删”(即启动、暂停、删除)这四种。接下来,我将分别对这四种操作进行具体介绍。

创建实例

下面是实例创建的命令格式,其中,VM_NAME 表示我们实例虚拟机的名字。

MACHINE_TYPE 是指 Compute Engine 的虚拟机类型,不同类型的虚拟机对应不同的价格与计算性能,我们可以参考 官方文档 进行选择。另外,我们还可以通过 gcloud compute machine-types list 显示所有可选的虚拟机类型。

ZONE 表示计算引擎实体资源所在地区,官网文档 上可以查到所有资源的地区分布信息。ACCELERATOR_TYPE 是 GPU 计算资源的类型,具体可选择的资源请查阅 相关资料ACCELERATOR_COUNT即是 GPU 资源的数量。IMAGE/IMAGE_FAMILY/IMAGE_PROJECT 是虚拟实例的操作系统参数,有 CentOS、Ubuntu 等 常用操作系统。“--maintenance-policy TERMINATE --restart-on-failure” 最后的这部分表示我们希望实例创建后处于 TERMINATE 状态,并且遇到错误自动重启虚拟机。

gcloud compute instances create VM_NAME \
--machine-type MACHINE_TYPE \
--zone ZONE \
--accelerator type=ACCELERATOR_TYPE, count=ACCELERATOR_COUNT \ #这里选 GPU
[--image IMAGE | --image-family IMAGE_FAMILY] \
--image-project IMAGE_PROJECT \
--maintenance-policy TERMINATE --restart-on-failure \
[--preemptible] # 这个是是否抢占式的机器

下面展示我们在 us-central1-a 区基于 deeplearning-platform-release/pytorch-latest-cpu镜创建一个拥有 GPU 资源的虚拟机实例。其中,Deep Learning VM Image 拥有很多预装深度学习常用工具的 GCP 镜像,这些镜像有利于我们快速搭建自己需要的运行环境,具体深度学习可选镜像都在 这里,请自行查看。

# 这是一个 GPU 相关的例子。
export IMAGE_FAMILY="tf-1-14-cu100"
export IMAGE_PROJECT="deeplearning-platform-release"
export ZONE="us-central1-a"
export INSTANCE_NAME="hello-gpu-example"
export MACHINE_TYPE=n1-standard-4
export ACCELERATOR_TYPE=nvidia-tesla-v100
export GPU_NUM=1

gcloud compute instances create $INSTANCE_NAME \
 --zone=$ZONE \
 --machine-type $MACHINE_TYPE \
 --image-family=$IMAGE_FAMILY \
 --image-project=$IMAGE_PROJECT \
 --accelerator type=$ACCELERATOR_TYPE,count=$GPU_NUM \
 --boot-disk-size=120GB \ 
 --maintenance-policy TERMINATE --restart-on-failure

查看实例

我们可以用以下命令查看实例的当前状态,如果 STATUS 的值是 RUNNING 表示实例正在运行,可以连接登陆运行自己任务。如果这个值 TERMINATED 就是虚拟机已停止不计费了。

# 查看虚拟机实例当前状态的例子。
$ gcloud compute instances list

连接运行实例

连接登陆实例的命令格式如下所示,我们通常使用 ssh 协议连接到对应项目与地区的虚拟机实例。

$ gcloud compute ssh --project=PROJECT_ID --zone=ZONE VM_NAME

而且,我们在首次连接新创建的 GCP 实例时,系统会帮进行一些驱动安装的操作。具体请看我们的下面操作示范。因为当前的 project 的是 edge-brain,创建的虚拟机实例区域在 us-central1-a,所以我们将 PROJECT_IDZONE 替换为对应值,VM_NAME 替换为 hello-gpu-example

# 通过 ssh 连接登陆我们刚创建的 edge-brain 项目下 us-central1-a 区的 GPU 实例。
$ gcloud compute ssh --project=edge-brain --zone=us-central1-a hello-gpu-example

实例的启动/停止/删除

当我们开始在 GCP 的运行任务前,我们都需要确保虚拟机实例在 RUNNING(已启动)状态。有时,我们需要进行实例启动操作。反过来,每当我们结束在 GCP 的工作任务时,都应该确保虚拟机实例在 TERMINATE (已停止)状态,以防不必要的机时浪费,也就需要进行实例停止操作。下面是相关操作的命令格式。

$ gcloud compute instances start/stop/delete VM_NAME

下面,我们展示一个停止并删除虚拟机 hello-gpu-example 的例子。

# 停止运行我们在 us-central1-a 区的虚拟机
$ gcloud compute instances stop --zone us-central1-a hello-gpu-example

# 运行结果
Stopping instance(s) hello-gpu-example...done.

Updated [https://compute.googleapis.com/compute/v1/projects/edge-brain/zones/us-central1-a/instances/hello-gpu-example].

# 删除我们在 us-central1-a 区的虚拟机
$ gcloud compute instances delete --zone us-central1-a hello-gpu-example

# 运行结果
The following instances will be deleted. Any attached disks configured
 to be auto-deleted will be deleted unless they are attached to any 
other instances or the `--keep-disks` flag is given and specifies them
 for keeping. Deleting a disk is irreversible and any data on the disk
 will be lost.
 - [hello-gpu-example] in [us-central1-a]

Do you want to continue (Y/n)?  Y

Deleted [https://www.googleapis.com/compute/v1/projects/edge-brain/zones/us-central1-a/instances/hello-gpu-example].

基于 Bert4Keras CMNLI 任务的实战示例

学习完 GCP 的命令行用法后,我们试着参考《bert4keras 在手,baseline 我有:CLUE 基准代码》做些关于中文自然语言处理评价基准 (CLUE,Chinese GLUE) 的实验。这里我们将以 BERT 模型运行 CMNLI (Chinese Multi-Genre NLI) 自然语言推理任务作为实战示例进行介绍。我们的整体思路相当简单,仅需把代码在本地调通后上传到 GCP 虚拟机实例运行即可。

本地代码准备

为了节约训练机时,我们应该在本地完成代码准备并尽量避免在云虚拟机调试代码。我们下载相应的 开源代码,根据 README 我们可以轻易地得到预训练模型参数,同时在 CLUE 官方 Github 仓库 中搜索 cmnli 还能找到对应数据集的下载地址。在准备好数据后,我们配置好 snippets.py 文件中的通用参数和预训练模型路径,即可调试并完成本地代码的准备工作。

GPU 虚拟机创建

1. 建立并执行内容如下的 Shell 脚本。

# 创建 GPU 虚拟机实例的脚本内容
export IMAGE_FAMILY="tf-1-14-cu100"
export ZONE="us-central1-a"
export INSTANCE_NAME="clue-bert4keras-show"
export GPU_NUM=1

gcloud compute instances create $INSTANCE_NAME \
--zone=$ZONE \
--machine-type n1-standard-4 \
--image-family=$IMAGE_FAMILY \
--image-project=deeplearning-platform-release \
--accelerator type=nvidia-tesla-v100,count=$GPU_NUM \
--boot-disk-size=120GB \ # 扩容虚拟实例的启动硬盘大小,避免数据存储空间不足。
--metadata="install-nvidia-driver=True"# Nvidia 显卡驱动自动安装选项。

运行结果如下图所示

同时,如果有想查看申请 VM Instance 更多细节配置的同学可以在这个 官方文档 中找到对应的说明,关于它的生命周期在 VM instance life cycle 文档中介绍。

2. 登陆到该虚拟机并按照提示安装相应的显卡驱动。一般情况下,这个镜像会帮我们预先准备显卡驱动的安装脚本,我们直接运行即可。

# 登陆连接虚拟机
$ gcloud compute ssh --project=edge-brain --zone=us-central1-c clue-bert4keras-show
# 查看显卡工作情况
$ nvidia-smi

至此我们含有显卡实例就创建好了,注意该步骤只需要一次,之后只要不删除实例就可以直接启动它直接运行我们的实验。

实验程序运行

上传代码

由于单文件上传方式的流程繁琐且效率较低,我们先将 src 目录压缩打包成 src.zip 进行上传。然后,我们使用 gcloud 中提供的 gcloud compute scp 命令上传即可。

# 代码上传
$ gcloud compute scp ./src.zip clue-bert4keras-show:~/src.zip

在 100M 带宽的网络环境下,我们的上传速度是相对客观的 2.0MB/s。

运行程序

为了达到最佳的 bert4keras 的使用体验,我们除了镜像自带的 TensorFlow 以外,还需要安装 wheel,版本为 2.3.1 的 Keras 以及 bert4keras。这些运行环境准备完成后,我们直接运行 cmnli.py 即可开始训练。另外,如果读者还希望训练程序常驻后台,方便查看程序出现异常中断状况的日志,我们推荐使用类似 screen,tmux 等后台监控工具。

# 安装依赖
$ pip3 install wheel keras==2.3.1 bert4keras
# 开始训练
$ python3 cmnli.py

实验结果如下图所示,我们可以看到程序跑得很顺畅,相比本地 CPU 环境有数倍的提升。

停止/删除实验

若我们想暂停实验,只要 stop 虚拟机实例就立刻停止计算资源的付费了。取而代之,我们只需要支付很少的存储费用保留实验环境。而当我们完成实验后,直接 delete 虚拟机实例就彻底删除虚拟机实例付费了。

# 停止虚拟实例
$ gcloud compute instances stop/delete clue-bert4keras-show

# delete 该虚拟机实例结果
$ Deleted [https://www.googleapis.com/compute/v1/projects/edge-brain/zones/us-central1-a/instances/clue-bert4keras-show]

结束语

至此,谷歌云平台的命令行应用与案例实践的介绍便结束了。我们十分感谢谷歌开发者专家计划(Google Developer Expert)与谷歌云平台提供宝贵的云计算服务。未来我们打算将富裕的机时投入到更多有趣的开源项目里面。同时,我们还发起了一项开源项目互助活动,尽可能帮助有需要的同学完成他们自己的开源项目。有意加入开源互助小组的同学,可以微信联系我们的管理员大佬。(hi_vincent_duan)

中文:TensorFlow 公众号