java怎么拦截某个对象
244
2022-11-14
RAPIDS cuML中的输入输出可配置性
图 1 :一个优化的 cuML 工作流示例。
最大化兼容性
使用现有 NumPy 、 Scikit-learn 和传统的基于 PyData 库的工作流的用户: cuML 的默认行为,允许尽可能多的格式,以及其基于 Scikit-learn 的 API 设计,允许以最小的工作量和无中断的方式移植这些工作流的一部分。因此,例如,您可以使用 NumPy 数组作为输入,然后返回 NumPy 数组作为输出,正如您所期望的那样,只是速度要快得多。
最大化性能
兼容的输入格式: CUDA 数组接口的奇迹
很大程度上要感谢 cuda_array_interface ,即所谓的 CAI , cuML 接受多种数据格式:
cuDF 对象(数据帧和序列)
pandas 对象(数据帧和序列)
NumPy 阵列
CuPy 和 Numba 设备阵列
任何与 CAI 兼容的对象,如 PyTorch 和 CuPy 数组。这组被称为 CAI 数组。
默认行为: cuML 如何开箱即用?
cuML 的默认行为被设计成尽可能多地镜像输入。因此,例如,如果您在 cuDF 中执行 ETL ,这对于 RAPIDS 用户非常典型,您将看到如下内容:
import cuml
import cudf
df[1] = [1.0, 2.0, 5.0]
df[2] = [4.0, 2.0. 1.0]
df[3] = [4.0, 2.0. 1.0]
kmeans.fit(df)
print(type(kmeans.labels_))
# 《class ‘cudf.core.series.Series’》
镜像 cuML 行为的默认输入格式类型。
使用 cuDF 数据帧时, cuML 会返回 cuDF 对象(在本例中是一个序列)。但是,如前所述, cuML 还允许您在不更改 cuML 调用的情况下使用 NumPy 数组:
import cuml
import numpy as np
ary = np.array([[1.0, 4.0, 4.0], [2.0, 2.0, 2.0], [5.0, 1.0, 1.0]])
kmeans = cuml.KMeans(n_clusters=2)
kmeans.fit(ary)
print(type(kmeans.labels_))
# 《class ‘numpy.ndarray’》
原始视图默认输入格式类型镜像 cuML 镜像 NumPy 数组的行为。
在本例中,现在 cuML 以 NumPy 数组的形式返回结果。镜像输入数据类型格式是 cuML 的默认行为,通常情况下,该行为是:
表 1 :可接受的输入格式和默认输出行为列表。
这个列表在不断增长,所以希望很快能在该表中看到类似 dlpack 兼容库的内容。
可配置性:如何让 cuML 按自己的方式工作?
cuML 允许用户全局配置输出类型。例如,如果您的 ETL 和机器学习工作流基于 GPU ,但依赖于基于 NumPy 的可视化框架,请尝试以下操作:
import cupy as cp
import numpy as np
import cuml
cuml.set_global_output_type(‘numpy’)
ary = cp.array([[1.0, 4.0, 4.0], [2.0, 2.0, 2.0], [5.0, 1.0, 1.0]])
kmeans = cuml.KMeans(n_clusters=2)
kmeans.fit(ary)
print(type(kmeans.labels_))
# 《class ‘numpy.ndarray’》
使用 cuML 的“ set \ u global \ u output \ u type ”`
使用 set_global_output_type 指令会影响对 cuML 的所有后续调用。如果用户需要更细粒度的控制(例如,您的模型由 GPU 库处理,但只有一个模型需要是 NumPy 数组才能进行专门的可视化),则可以使用以下机制:
cuML 的上下文管理器 using_output_type :
import cuml
import cupy as cp
ary = [[1.0, 4.0, 4.0], [2.0, 2.0, 2.0], [5.0, 1.0, 1.0]]
ary = cp.asarray(ary)
with cuml.using_output_type(‘cudf’):
dbscan.fit(ary)
print(type(dbscan_float.labels_))
# 《class ‘cudf.core.Series’》
kmeans = cuml.KMeans(n_clusters=2)
kmeans.fit(ary)
print(type(kmeans.labels_))
# 《class ‘cupy.core.core.ndarray’》
使用 cuML 的上下文管理器` using \ u output \ u type `
设置单个模型的输出类型:
import cupy as cp
import cuml
ary = cp.array([[1.0, 4.0, 4.0], [2.0, 2.0, 2.0], [5.0, 1.0, 1.0]])
kmeans.fit(ary)
print(type(kmeans.labels_))
# 《class ‘numpy.ndarray’》
这种新功能可以自动将数据转换为方便的格式,而无需手动从多种类型转换数据。以下是模型为了解返回内容而遵循的规则:
如果在构建模型时指定了输出类型,例如 cuml.KMeans(n_clusters=2, output_type=’numpy’) ,那么它将给出该类型的结果。
如果模型是使用 cuml.using_output_type 在上下文管理器 with 中构建的,那么模型将使用该上下文的输出类型。
如果 output_type 是使用 set_global_output_type 设置的,那么它将返回该类型的结果。
如果没有指定上述任何一项,则模型将镜像用于输入的对象的类型,如“默认行为”部分中所述。
效率:我应该使用什么格式?
既然您知道了如何使用 cuML 的输入和输出可配置性,那么问题是,最好使用什么格式?这将取决于你的需要和优先级,因为所有的格式都有权衡。让我们考虑一个简单的工作流程:
图 2 :使用 ML 的简单数据科学工作流。
使用基于 NumPy 的对象
在下面的图 3 中,传输(粉色框)限制了 cuML 可以给您的加速量,因为通信使用较慢的系统内存,您必须通过 PCI-Express 总线。每次使用 NumPy 数组作为模型的输入或要求模型返回 NumPy 数组时,主系统内存和 GPU 之间至少有一次内存传输。
乍一看,有人认为这影响不大。然而,将尽可能多的数据保存在 GPU 中,即使不是最大的原因,也是 RAPIDS 实现闪电般速度的原因之一。
图 3 :说明使用 NumPy 数组进行输入或输出时发生什么的工作流。
使用 cuDF 对象
使用 GPU 对象而不是 NumPy 数组具有重要意义。例如,使用 cuDF 对象如下图 4 所示。橙色框表示完全在 fast GPU 内存上发生的转换。不幸的是,这意味着在 cuML 算法处理过程中会有一个额外的数据副本,这会限制在特定 GPU 中可以处理的数据集的大小。
图 4 :说明 GPU 内存中发生的转换的工作流。
DataFrames (和 Series )是非常强大的对象,允许用户以平易近人和熟悉的方式进行 ETL 。但要提供这一点,它们是具有大量复杂性的复杂结构,以实现此功能。
其中有几个例子:
除了数据之外,每一列都可以有一个位掩码数组(基本上是一个由 0 和 1 组成的附加数组),允许用户在数据中有丢失的条目。
由于数据帧在添加/删除行和列时需要提供灵活性,因此每一列 MIG 在内存中应该彼此远离。
当然,还有一些附加的结构,比如索引和列名。
但是,这些限制为某些分析工作流带来了一些困难:
首先,许多算法在所有数据都是连续的情况下工作得更好,例如,所有字节都分组在同一个内存区域中,因为高效地访问内存是快速处理数据的一个重要组成部分(特别是对于 GPU s !)。
内存是一种有限的资源(一般来说,但对于 GPU 和加速器来说更是如此),因此额外的开销会产生非常显著的影响。
使用设备阵列
如前所述,从 cuML 的角度来看,所有 CAI 数组本质上是相同的,因此您的工作流可以组合 Numba 、 CuPy 、 cuML 等功能,而无需执行昂贵的内存复制操作。
图 5 :说明用于输入或输出的 CAI 数组如何在 cuML 中处理数据时具有最低开销的工作流。
选择数据类型的提示
那么您应该使用什么数据类型呢?如前所述,这取决于场景,但这里有一些建议:
如果您有一个现有的 PyData 工作流,那么可以利用 cuML 的 NumPy 功能逐个尝试不同的模型。从加速工作流程中最慢的部分开始。 DBSCAN 和 UMAP 是 cuML 中 modInels 的很好例子,即使它们自己使用,没有完全的 RAPIDS 加速,也能提供巨大的加速和改进。
潜在陷阱:这可能会在主系统内存和 GPU 内存之间造成通信瓶颈。
如果您的工作流程非常依赖 ETL ,需要大量的 cuDF 工作,而大部分处理和开发时间都在数据加载或转换中,请将其作为 cuDF 对象,并让 cuML 管理转换。
潜在的陷阱:这个 MIG ht 限制了 GPU 中单个模型可以容纳的数据量。
如果训练或推理的最终速度是关键,那么调整您的工作流以尽可能多地使用 CUDA rray 接口库。
使用所有这些技巧,您可以配置 cuML 来优化您的需求,并更好地估计工作流的影响和瓶颈。您的新工作流现在可能如下所示:
图 6 :用户在 cuML 中优化的工作流。
下一步是什么?
以下是我们很高兴在接下来的帖子中分享的一些活跃领域:
有关数据及其含义的较低级别详细信息: 许多细节,如数据类型或内存中数据的顺序,都会影响 cuML 。我们将讨论这些细节如何影响 cuML ,以及它与传统 PyData 库的比较和区别。
抽象与设计 :最近在 RAPIDS 软件堆栈中引入的抽象和机制,如 CumlArray ,允许 cuML 提供此功能,同时降低代码复杂性和保证结果所需的测试数量。我们将讨论这个,连同 CAI ,如何让用户能够使用多个库,比如 CuPy , cuDF , cuML ,而不费吹灰之力。
Conclusion
这篇文章讨论了 cuML 的输入和输出可配置能力,支持的不同数据格式,以及 cuML 中每种格式的优缺点。这篇文章展示了在现有工作流中采用 cuML 是多么容易。 cuML 的 sciketlearnapi 和格式输出镜像允许您使用它作为现有库的替代品。为了获得最大的性能,用户应该尽量使用 GPU 特定的格式,以及 CuPy 或 Numba 等 CAI 数组。 RAPIDS 团队正在努力改进 cuML 的功能和支持的数据格式。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~