摘要
算法、数据和算力称为人工智能的三大要素,如果没有算力的支撑,人工智能难以落地。而 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 节点。
安装虚拟节点,具体可以参考虚拟节点。
配置 virtual-kubelet-autoscaler,当集群内的 GPU 资源不足的时候,通过 virtual-kubelet-autoscaler 将弹出使用 GPU 的 ECI 实例。具体参考文档
步骤 2:从无到有运行 arena 创建 RAPIDS 服务
1.安装 arena
2.先运行一下 arena 命令查看集群的 GPU 资源, 可以看到在该用户集群下,有一个真实节点并没有包含 GPU 资源,同时存在了一个虚拟节点,该节点并不真实存在,无需付费,同时它提供了无限的 GPU 资源可以扩展。
3.再提交 rapids 任务前,我们需要做一些准备。准备的目的是加速创建过程和简化访问操作。
3.1.设置访问方式。将访问方式设置为 LoadBalancer(该方法只是为了示例简单,并不推荐您在生产环境开放外网 ip 方访问)
3.2.加速启动速度
3.2.1.GPU 的容器镜像通常很大,以本实验要使用的 rapids 容器镜像为例,它的容量为 14.7GB.通常启动时间会在 10 分钟左右。而通过镜像缓存的能力可以将这个从无到有的过程缩短到 20s 左右。
3.2.2.而在 serverless kubernetes 中,你只需要创建一个 ImageCache CRD,就可以直接使用镜像缓存的能力。
3.2.3.提交后稍等片刻。查看 ImageCache 状态,其中 CACHID 可以做后面提交任务时指定的 snapshot-id
具体操作可以参考文档
4.提交 rapids 的开发环境
--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 状态
5.再次查看集群的 GPU 使用情况,发现已经有一个 GPU 资源被占用了
6.如果想查询是哪个 Pod 占用了这个 GPU, 可以在原有命令中加一个-d 就可以看到具体的 Pod 名称。
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:依据运行需求进行显存分配。
方法 2:设定可以使用的 GPU 显存比例。本示例中使用方法 2,并且 GPU 显存比例默认设置为 0.3,即 Tensorflow 可以使用整块 GPU 显存的 30%,您可以依据应用场景修改比例。
2.2 下载 ResNet50(notop)预训练模型。 连接公网下载模型(大小约 91M),目前该模型已经被保存到/root/.keras/models/目录。
您可以执行model.summary()
方法查看模型的网络结构。
2.2 提取图片特征。 对分割得到的两个图片数据集执行model.predict()
方法提取图片特征。
搜索相似图片。
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+阿里云Serverless Kubernetes快速,简单,低成本的使用 RAPIDS 加速数据科学。
本文转载自云栖社区。
原文链接:
https://yq.aliyun.com/articles/735438?spm=a2c4e.11153959.0.0.715cd55arelKky
评论 3 条评论