TunableOp
注意
这是一个原型功能,目前处于早期阶段,主要用于收集反馈和进行测试。其组件可能还会发生变化。
概述
此模块提供了一个 TunableOp 接口。
某些操作,如 GEMM(通用矩阵乘法),可以使用多个库或多种技术来实现。例如,GEMM 可以在 CUDA 或 ROCm 上分别通过 blas 库或 blasLt 库进行实现。此外,ROCm 的 rocblas 和 hipblaslt 库允许用户查询所有可能的算法并选择其中一个。那么如何确定哪种实现方式最快并且应该被选用呢?这就是 TunableOp 提供的功能。
分别启用TunableOp和进行独立调优
TunableOp 特性与启用调优阶段是分开的。启用 TunableOp 意味着 PyTorch 会用其可调版本替换任何标准的操作符。每次调用 TunableOp 时,都会检查是否已经为给定输入进行了优化调整。如果已进行过优化,则直接使用该优化结果;即使启用了调优设置,也不会再进行进一步的调优。相反,如果没有找到之前的优化结果,并且启用了调优功能,TunableOp 将针对给定的一组输入对所有注册的操作符实现进行基准测试并选择最快的。
文件输入与输出
当首次调用任何 TunableOp 时,内部的优化操作数据库将通过尝试从给定文件读取结果来进行初始化。默认的文件名是 ‘tunableop_results.csv’。为了支持在多进程中使用多张 GPU 进行调整,GPU 设备序号会自动插入到文件名中以避免多个进程覆盖同一个文件。
如果启用了调优,并且在工作负载过程中发现了新的调优设置,它会将所有调优设置(包括启动时读取的和运行时发现的新设置)写入同一个文件。例如,可以通过重复使用同一文件来构建跨越多个工作负载的调优文件。输出文件会在应用程序终止时自动创建。此行为可通过 C++ 和 Python API 控制,但不能通过环境变量控制。
如果你指定了一个文件名,最终会生成一个类似的CSV文件,内容如下:
Validator,PT_VERSION,2.2.0 Validator,ROCM_VERSION,6.0.0.0-12969-1544e39 Validator,HIPBLASLT_VERSION,0.6.0-a9c5cc7 Validator,ROCBLAS_VERSION,4.0.0-72e57364-dirty GemmTunableOp_float_NT,nt_25088_4096_64,1219,1.262 GemmTunableOp_float_NT,nt_4096_4096_64,1216,0.033
请注意“Validator”行。如果更改了库版本、ROCm版本或PyTorch版本,TunableOp 会检测到这些变化,并拒绝使用之前的调优文件,因为这些调优结果可能受到了其他软件变更的影响。
剩余的行包含了在执行过程中遇到的每个 TunableOp 的调优解决方案。每一行包含四个用逗号分隔的字段:操作符名称、操作符参数、解决方案名称和平均执行时间(该字段是可选的)。CSV 文件可以编辑,但需谨慎。例如,你可以将第 3 字段中的解决方案名称更改为“Default”,这样会回退到原始未调优的 PyTorch 实现。或者,在使用 ROCm 的 hipBLAS 或 hipBLASLt 库时,如果你知道特定的解决方案索引,则可以通过替换值来覆盖 TunableOp 所选择的解决方案。操作符名称和参数(第 1 和第 2 字段)是内部命名的,不应修改。对于 GemmTunableOp,第 1 字段表示数据类型以及输入是否转置(T 表示转置,N 表示未转置),而第 2 字段则表示 M、N、K 的输入形状。
有一个选项可以启用详细输出,但仅推荐在调试时使用。这将生成大量诊断消息,但如果要确认是否实际使用了TunableOp,则可能会很有用。否则,除非在使用过程中出现警告或错误,否则TunableOp不会产生任何日志信息,除了文件输出之外。要启用详细模式,请设置环境变量 PYTORCH_TUNABLEOP_VERBOSE=1。
关于调整行为的说明
调整一个操作符包括遍历注册的实现列表,并对每个实现进行性能分析。通过在一个循环中多次运行单个实现,然后取其平均执行时间来建立性能指标。
默认情况下,对于给定操作的每个可能的解决方案,将运行100次迭代或在30毫秒内可以完成的最大迭代次数(取较小值),并计算其平均执行时间。从所有成功分析的方案中选择最快的那一个。如果给定的解决方案未能达到与默认实现相同的准确性,或者返回了错误代码,则配置文件可能会失败。
当前可调节的操作符
TunableGemm for ROCm
目前只实现了适用于ROCm的TunableGemm。需要注意的是,虽然PyTorch的CUDA构建版本在使用TunableOp时可以正常工作,但其唯一可用的解决方案是“Default”实现,即通过TunableOp调用的原始cuBLAS默认实现。任何对at::cuda::blas::gemm()或::bgemm()的调用,在启用TunableOp的情况下都将通过TunableOp进行路由。对于给定的一组输入参数(transa, transb, m, n, k),调用gemm()将尝试使用rocblas和hipblaslt中最快的可用实现。
调优 context
TunableOp的行为目前可以通过环境变量、at::cuda::tunable::getTuningContext()的C++接口,或者包装了C++ TuningContext的torch.cuda.tunable Python接口来控制。环境变量的优先级高于通过C++或Python API设置的任何配置。
API参考
- torch.cuda.tunable.enable(val=True)[源代码]
-
这是控制所有可调操作(TunableOp)实现的总开关。
- torch.cuda.tunable.tuning_enable(val=True)[源代码]
-
启用可调操作(TunableOp)实现的调节功能。
启用时,如果没有找到已调优的条目,则执行调优步骤并记录该条目。
- torch.cuda.tunable.set_max_tuning_duration(duration)[源代码]
-
设置调优给定解决方案的最大时间(以毫秒为单位)。
如果同时设置了最大调优时长和迭代次数,则以较小的值为准,并且至少会进行一次调优迭代。
- torch.cuda.tunable.set_max_tuning_iterations(iterations)[源代码]
-
设置调整特定解决方案时的最大迭代次数。
如果同时设置了最大调优时长和迭代次数,则以较小的值为准,并且至少会进行一次调优迭代。
- torch.cuda.tunable.set_filename(filename, insert_device_ordinal=False)[源代码]
-
设置用于输入和输出调优结果的文件名。
如果
insert_device_ordinal
为True
,则当前设备的序号会自动添加到给定的文件名中。这在每个进程对应一个GPU的情况下非常有用,可以确保所有进程写入不同的文件。
- torch.cuda.tunable.write_file_on_exit(val)[源代码]
-
在进行上下文调整销毁时,将文件写入磁盘。
如果应用程序因正常操作或错误而终止,这可以作为将结果最终写入磁盘的有效方式。可以通过手动调用
write_file()
来刷新你的结果。
- torch.cuda.tunable.write_file(filename=None)[源代码]
-
将结果写入CSV文件。
如果没有提供
filename
,则会调用get_filename()
。- 返回类型