GMTC全球大前端技术大会(北京站)门票9折特惠截至本周五,点击立减¥480 了解详情
写点什么

在阿里云容器服务中体验 RAPIDS 加速数据科学

2019 年 12 月 15 日

在阿里云容器服务中体验RAPIDS加速数据科学

摘要

算法、数据和算力称为人工智能的三大要素,如果没有算力的支撑,人工智能难以落地。而 Nvidia GPU 的强劲算力是 AI 模型训练加速的首选,但是它的价格也确实不菲。如何能够简单,有效同时低成本的使用 Nvidia GPU 的算力,使用阿里云容器服务+ECI+Arena 的方案是一个可以参考的选项。


而一谈起 Nvidia GPU,大家首先会想到的就是深度学习,传统的机器学习和数据分析的方法对 GPU 的利用却很少,实际上 Nvidia 有一个非常优秀的项目 RAPIDS,全称 Real-time Acceleration Platform for Integrated Data Science,是 NVIDIA 针对数据科学和机器学习推出的 GPU 加速库。更多 RAPIDS 信息请参见官方网站。这是一个致力于将 GPU 加速带给传统算法的项目,并且提供了与 Pandas 和 scikit-learn 一致的用法和体验。实际上 RAPIDS 有三个模块:cuDF 相当于 Pandas,cuML 相当于 scikit-learn,cuGraph 则是处理图数据的。由于它的兼容性很好,我们可以把 RAPIDS 与深度学习框架结合,用 cuDF 来利用 GPU 加速处理数据,然后使用 TensorFlow 和 PyTorch 的深度学习模型框架处理任务。



在本文中,我们将介绍如何利用 TensorFlow 和 Rapids 实现在阿里云容器服务上以图搜图的功能;同时通过 ECI 实现 GPU 资源的使用即申请,秒级的 GPU 资源准备速度,完成即释放,用户无需提前准备 GPU 实例;而站在使用者的角度,他并不需要和 Kubernetes 的基础设施打交道,通过 arena 的命令行,就可以实现包含 GPU 的 RAPIDS 环境的构建和运行,并且完成对 GPU 基础设施的管理。


执行步骤

步骤 1:准备集群

准备托管 k8s 的集群,所谓托管 k8s 的集群就是这个 k8s 的管控节点由阿里云承担资源和运维成本,并且创建了虚拟的 Kubelet 节点


需要您已创建好容器服务 Kubernetes 集群。 您可以选择管版的 Kubernetes 集群。


由于需要运行系统组件容器,节点中至少有一个 Worker 节点。


  1. 安装虚拟节点,具体可以参考虚拟节点

  2. 配置 virtual-kubelet-autoscaler,当集群内的 GPU 资源不足的时候,通过 virtual-kubelet-autoscaler 将弹出使用 GPU 的 ECI 实例。具体参考文档


步骤 2:从无到有运行 arena 创建 RAPIDS 服务

1.安装 arena


$ wget http://kubeflow.oss-cn-beijing.aliyuncs.com/arena-installer-0.3.1-b96e1ac-linux-amd64.tar.gz$ tar -xvf arena*.tar.gz$ cd arena-installer$ ./install.sh
复制代码


2.先运行一下 arena 命令查看集群的 GPU 资源, 可以看到在该用户集群下,有一个真实节点并没有包含 GPU 资源,同时存在了一个虚拟节点,该节点并不真实存在,无需付费,同时它提供了无限的 GPU 资源可以扩展。


$ arena top nodearena top nodeNAME                       IPADDRESS      ROLE    STATUS  GPU(Total)  GPU(Allocated)cn-shanghai.192.168.1.248  192.168.1.248  <none>  ready   0           0virtual-kubelet            172.20.2.18    agent   ready   1000        0-----------------------------------------------------------------------------------------Allocated/Total GPUs In Cluster:0/1000 (0%)
复制代码


3.再提交 rapids 任务前,我们需要做一些准备。准备的目的是加速创建过程和简化访问操作。


3.1.设置访问方式。将访问方式设置为 LoadBalancer(该方法只是为了示例简单,并不推荐您在生产环境开放外网 ip 方访问)


$ find /charts/ -name "*.yaml" | xargs sed -i "s/NodePort/LoadBalancer/g"
复制代码


3.2.加速启动速度


3.2.1.GPU 的容器镜像通常很大,以本实验要使用的 rapids 容器镜像为例,它的容量为 14.7GB.通常启动时间会在 10 分钟左右。而通过镜像缓存的能力可以将这个从无到有的过程缩短到 20s 左右。


docker images | grep rapidsregistry.cn-shanghai.aliyuncs.com/tensorflow-samples/rapids-samples                0.8.2-cuda10.0-runtime-ubuntu16.04   4597a0334d41        12 days ago         14.7GB
复制代码


3.2.2.而在 serverless kubernetes 中,你只需要创建一个 ImageCache CRD,就可以直接使用镜像缓存的能力。


$ cat > imagecache.yaml << EOFapiVersion: eci.alibabacloud.com/v1kind: ImageCachemetadata:  name: imagecache-rapidsspec:  images:  - registry.cn-shanghai.aliyuncs.com/tensorflow-samples/rapids-samples:0.8.2-cuda10.0-runtime-ubuntu16.04  imageCacheSize:   50EOF
$ kubectl create -f imagecache.yaml
复制代码


3.2.3.提交后稍等片刻。查看 ImageCache 状态,其中 CACHID 可以做后面提交任务时指定的 snapshot-id


$ kubectl get imagecacheNAME                AGE    CACHEID                    PHASE   PROGRESSimagecache-rapids   3d9h   imc-uf6dxdji7txxxxx        Ready   100%
复制代码


具体操作可以参考文档


4.提交 rapids 的开发环境


$ arena serve custom \     --name=rapids \     --selector=type=virtual-kubelet \     --toleration=all \     --annotation=k8s.aliyun.com/eci-image-snapshot-id=imc-uf6dxdji7txxxxx \     --annotation=k8s.aliyun.com/eci-instance-type=ecs.gn5i-c8g1.2xlarge \     --gpus=1 \     -e=PASSWORD=mypassw0rd \     --restful-port=80 \     --image=registry.cn-shanghai.aliyuncs.com/tensorflow-samples/rapids-samples:0.8.2-cuda10.0-runtime-ubuntu16.04configmap/rapids-201912011815-custom-serving createdconfigmap/rapids-201912011815-custom-serving labeledservice/rapids-201912011815 createddeployment.extensions/rapids-201912011815-custom-serving created
复制代码


--selector=type=virtual-kubelet表示通过Virtual Node启动 Pod

--annotation=k8s.aliyun.com/eci-instance-type=ecs.gn5i-c8g1.2xlarge表示指定使用 ECI 的实例类型,ecs.gn5i-c8g1.2xlarge 代表阿里云 P4 机型。具体规格可以查看文档

--annotation=k8s.aliyun.com/eci-image-snapshot-id=imc-uf6dxdji7txxxxx指定 3.2.3 步中的 CACHEID

-e=PASSWORD=mypassw0rd就是通过环境变量 PASSWORD 设置访问 RAPIDS notebook

--gpus=1表示申请的 GPU 数目


4.查看访问地址,这里是 ENDPOINT_ADDRESS 和 PORTS 的组合, 在本示例中它是106.15.173.2:80。同时发现该任务在 32 秒的时候就可以变成 Running 状态


$ arena serve listNAME    TYPE    VERSION       DESIRED  AVAILABLE  ENDPOINT_ADDRESS  PORTSrapids  CUSTOM  201911181827  1        1          105.13.58.3      restful:80
$ arena serve get rapids arena serve get rapidsNAME: rapidsNAMESPACE: defaultVERSION: 201912011815DESIRED: 1AVAILABLE: 1SERVING TYPE: CUSTOMENDPOINT ADDRESS: 106.15.173.2ENDPOINT PORTS: restful:80AGE: 32s
INSTANCE STATUS AGE READY RESTARTS NODErapids-201912011815-custom-serving-6b54d5cd-swcwz Running 32s 1/1 0 N/A
复制代码


5.再次查看集群的 GPU 使用情况,发现已经有一个 GPU 资源被占用了


$ arena top nodeNAME                       IPADDRESS      ROLE    STATUS  GPU(Total)  GPU(Allocated)cn-shanghai.192.168.1.248  192.168.1.248  <none>  ready   0           0virtual-kubelet            172.20.2.20    agent   ready   1000        1-----------------------------------------------------------------------------------------Allocated/Total GPUs In Cluster:1/1000 (0%)
复制代码


6.如果想查询是哪个 Pod 占用了这个 GPU, 可以在原有命令中加一个-d 就可以看到具体的 Pod 名称。


$ arena top node -d

NAME: cn-shanghai.192.168.1.248IPADDRESS: 192.168.1.248ROLE: <none>
Total GPUs In Node cn-shanghai.192.168.1.248: 0Allocated GPUs In Node cn-shanghai.192.168.1.248: 0 (0%)-----------------------------------------------------------------------------------------
NAME: virtual-kubeletIPADDRESS: 172.20.2.20ROLE: agent
NAMESPACE NAME GPU REQUESTSdefault rapids-201912011815-custom-serving-6b54d5cd-swcwz 1
Total GPUs In Node virtual-kubelet: 1000Allocated GPUs In Node virtual-kubelet: 1 (0%)-----------------------------------------------------------------------------------------

Allocated/Total GPUs In Cluster: 1/1000 (0%)
复制代码


7.根据步骤 4 中的访问地址和端口,打开本地浏览器。输入http://{ENDPOINT ADDRESS}:{ENDPOINT PORT},在本例子中是http://105.13.58.3:80


说明: 推荐使用 Chrome 浏览器。


8.输入启动命令中设置的密码,然后单击 Log in。 在本例子中,密码为mypassw0rd



步骤三:执行以图搜图的示例

1.进入示例所在目录 cuml。


2.双击 cuml_knn.ipynb 文件。


3.单击




说明: 单击一次执行一个 cell,请单击至示例执行结束,详细说明请参见示例执行过程



示例执行过程

图像搜索示例的执行过程分为三个步骤:处理数据集、提取图片特征和搜索相似图片。本文示例结果中对比了 GPU 加速的 RAPIDS cuml KNN 与 CPU 实现的 scikit-learn KNN 的性能。


1.处理数据集。


1.1 下载和解压数据集。 本文示例中使用了STL-10数据集,该数据集中包含 10 万张未打标的图片,图片的尺寸均为:96 x 96 x 3, 您可以使用其他数据集,为便于提取图片特征,请确保数据集中图片的尺寸相同。


本文示例提供了download_and_extract(data_dir)方法供您下载和解压 STL-10 数据集。RAPIDS 镜像中已经将数据集下载到./data 目录,您可以执行download_and_extract()方法直接解压数据集。



1.2. 读取图片。 从数据集解压出的数据为二进制格式,执行read_all_images(path_to_data)方法加载数据并转换为 NHWC(batch, height, width, channels)格式,以便用 Tensorflow 提取图片特征。



1.3. 展示图片。 执行show_image(image)方法随机展示一张数据集中的图片。



1.4. 分割数据集。 按照 9:1 的比例把数据集分为两部分,分别用于创建图片索引库和搜索图片。



2.提取图片特征。 使用开源框架 Tensorflow 和 Keras 提取图片特征,其中模型为基于 ImageNet 数据集的 ResNet50(notop)预训练模型。


2.1 设定 Tensorflow 参数。 Tensorflow 默认使用所有 GPU 显存,我们需要留出部分 GPU 显存供 cuML 使用。您可以选择一种方法设置 GPU 显存参数:


  • 方法 1:依据运行需求进行显存分配。


config.gpu_options.allow_growth = True
复制代码


  • 方法 2:设定可以使用的 GPU 显存比例。本示例中使用方法 2,并且 GPU 显存比例默认设置为 0.3,即 Tensorflow 可以使用整块 GPU 显存的 30%,您可以依据应用场景修改比例。


config.gpu_options.per_process_gpu_memory_fraction = 0.3
复制代码



2.2 下载 ResNet50(notop)预训练模型。 连接公网下载模型(大小约 91M),目前该模型已经被保存到/root/.keras/models/目录。


参数名称说明
weights取值范围:
- None:随机初始化权重值。
- imagenet:权重值的初始值设置为通过ImageNet预训练过的模型的权重值。
本示例中设置为imagenet。
include_top取值范围:
- True:包含整个ResNet50网络结构的最后一个全链接层。
- False:不包含整个ResNet50网络结构的最后一个全链接层。
本示例中,使用神经网络模型ResNet50的主要目的是提取图片特征而非分类图片,因此设置为False。
input_shape可选参数,用于设置图片的输入shape,仅在include_top设置为False时生效。
您必须为图片设置3个inputs channels,且宽和高不应低于32。此处设为(96, 96, 3)。
pooling在include_top设置为False时,您需要设置池化层模式,取值范围:
- None:输出为4D tensor。
- avg:平均池化,输出为2D tensor。
- max:最大池化,输出为2D tensor。 本示例中设置为max。



您可以执行model.summary()方法查看模型的网络结构。



2.2 提取图片特征。 对分割得到的两个图片数据集执行model.predict()方法提取图片特征。



  1. 搜索相似图片。


3.1 使用 cuml KNN 搜索相似图片。 通过k=3设置 K 值为 3,即查找最相似的 3 张图片,您可以依据使用场景自定义 K 值。


其中,knn_cuml.fit()方法为创建索引阶段,knn_cuml.kneighbors()为搜索近邻阶段。



KNN 向量检索耗时 791 ms。


3.2 使用 scikit-learn KNN 搜索相似图片。 通过n_neighbors=3设置 K 值为 3,通过n_jobs=-1设置使用所有 CPU 进行近邻搜索。


说明: ecs.gn5i-c8g1.2xlarge 的配置为 8 vCPU。



KNN 向量检索耗时 7 分 34 秒。


3.3 对比 cuml KNN 和 scikit-learn KNN 的搜索结果。 对比两种方式的 KNN 向量检索速度,使用 GPU 加速的 cuml KNN 耗时 791 ms,使用 CPU 的 scikit-learn KNN 耗时 7min 34s。前者为后者的近 600 倍。


验证两种方式的输出结果是否相同,输出结果为两个数组:


  • distance:最小的 K 个距离值。本示例中搜索了 10000 张图片,K 值为 3,因此distance.shape=(10000,3)

  • indices:对应的图片索引。indices.shape=(10000, 3)

  • 由于本示例所用数据集中存在重复图片,容易出现图片相同但索引不同的情况,因此使用 distances,不使用 indices 对比结果。考虑到计算误差,如果两种方法得出的 10000 张图片中的 3 个最小距离值误差都小于 1,则认为结果相同。



图片搜索结果

本示例从 1 万张搜索图片中随机选择 5 张图片并搜索相似图片,最终展示出 5 行 4 列图片。


第一列为搜索图片,第二列至第四列为图片索引库中的相似图片,且相似性依次递减。每张相似图片的标题为计算的距离,数值越大相似性越低。



步骤 4:清理工作

$ arena serve delete rapidsservice "rapids-201912011815" deleteddeployment.extensions "rapids-201912011815-custom-serving" deletedconfigmap "rapids-201912011815-custom-serving" deletedINFO[0000] The Serving job rapids with version 201912011815 has been deleted successfully
复制代码


总结

本文介绍通过Arena+阿里云Serverless Kubernetes快速,简单,低成本的使用 RAPIDS 加速数据科学。


本文转载自云栖社区。


原文链接


https://yq.aliyun.com/articles/735438?spm=a2c4e.11153959.0.0.715cd55arelKky


2019 年 12 月 15 日 10:002367

评论 3 条评论

发布
用户头像
好棒

2019 年 12 月 17 日 14:55
回复
很有用的内容

2019 年 12 月 17 日 14:55
回复
666
2019 年 12 月 17 日 14:55
回复
没有更多了
发现更多内容

数据挖掘从入门到放弃(一):线性回归和逻辑回归

数据社

机器学习 5月日更

JS中every()和some()的对比使用

三掌柜

5月日更

Flutter开发:Gridview的使用

三掌柜

5月日更

浪潮云“1231”业务战略正式发布 “分布式云+”行动计划首次亮相

浪潮云

云计算

【得物技术】浅谈本地缓存与分布式缓存

得物技术

缓存 测试 质量 本地缓存 分布式缓存

看完了蚂蚁金服年薪180万的大佬扔给我的“Java成长笔记”,差距不止一点点

云流

Java 程序员 架构 面试 计算机

C++ & Linux 后端:进BAT的学习路线

赖猫

c++ Linux 后端 后端开发 服务器端开发

c++的并发操作(多线程)

赖猫

c++ Linux 多线程 服务端 并发

从一线城市回到三四线城市的第一个月

布衣骇客

生活,随想 个人总结

打字员为什么要去看商业模式

ES_her0

5月日更

Netty整体架构学习笔记

风翱

Netty 5月日更

《互联网人的英语私教课》复习

IT蜗壳-Tango

5月日更

今日学习小结

Nydia

学习笔记

【TcaplusDBx王者荣耀】五五开黑节背后的数据存储挑战

tcaplus

数据库

飞书悄然开辟新战线,协同办公之外另有新动作?

ToB行业头条

飞书 协同办公

网络攻防学习笔记 Day14

穿过生命散发芬芳

5月日更 网络攻防

Golang library source file 库源码文件

escray

go 极客时间 学习笔记 5月日更 Go语言核心36讲

「技术分享」Shiro 权限绕过的历史线(下)

Machine Gun

网络安全 信息安全 渗透测试 漏洞 Kail linux

谈谈企业的成本

石云升

创业 职场经验 5月日更

JavaScript 进阶——井字棋游戏智能AI搭建

空城机

JavaScript 前端 5月日更 web游戏

这个世界不会欺负诚实的人,也绝对不会亏待努力的人

小天同学

5月日更 真诚 诚信 努力

不是会员不让复制粘贴?看我“三板斧”!

liuzhen007

使用技巧 5月日更

就这?腾讯云高工熬夜手写'Java微服务学习笔记'也就让我月薪涨3k

云流

Java 编程 程序员 架构 面试

研发知识:MDD、MDF是什么?

paraboy1

为什么突然谁都能造车了?

白洞计划

音视频同步!RTCP协议解析及代码实现

明儿

c++ 音视频 协议 Wireshark 流媒体

小企业面对大数据如何破局,高并发与海量数据技术又如何操作?

读字节

大数据 分布式架构 高并发系统设计 战略思考

API网关关键技术

lenka

5月日更

数据线索梳理

顿晓

数据 5月日更

5G Capital一年,“首都标准”初现

脑极体

5分钟速读之Rust权威指南(二)

码生笔谈

rust

在阿里云容器服务中体验RAPIDS加速数据科学-InfoQ