性能分析#

性能分析是诊断性能、内存不足、挂起或其他应用程序问题的最重要调试工具之一。以下是您在调试 Ray 应用程序时可能使用的常见性能分析工具列表。

  • CPU 性能分析

    • py-spy

  • 内存性能分析

    • memray

  • GPU 性能分析

    • PyTorch Profiler

    • Nsight System

  • Ray 任务 / Actor 时间线

如果 Ray 与某些性能分析工具无法正常工作,请尝试在不使用 Ray 的情况下运行它们来调试问题。

CPU 性能分析#

分析 Driver 和 Worker 进程的 CPU 使用率。这有助于您了解不同进程的 CPU 使用情况,并调试意外的高或低使用率。

py-spy#

py-spy 是一个用于 Python 程序的采样分析器。Ray Dashboard 与 pyspy 原生集成。

  • 它允许您在不重新启动程序或以任何方式修改代码的情况下,可视化您的 Python 程序在做什么。

  • 它会转储运行进程的堆栈跟踪,以便您可以看到进程在特定时间正在做什么。当程序挂起时很有用。

注意

在使用 docker 容器中的 py-spy 时,您可能会遇到权限错误。要解决此问题:

  • 如果您在 Docker 容器中手动启动 Ray,请遵循 py-spy 文档_ 来解决。

  • 如果您是 KubeRay 用户,请遵循 配置 KubeRay 的指南 来解决。

以下是 在 Ray 和 Ray Dashboard 中使用 py-spy 的步骤

cProfile#

cProfile 是 Python 原生性能分析模块,用于分析 Ray 应用程序的性能。

以下是 使用 cProfile 的步骤

内存性能分析#

分析 Driver 和 Worker 进程的内存使用情况。这有助于您分析应用程序中的内存分配,跟踪内存泄漏,并调试高/低内存或内存不足问题。

memray#

memray 是一个 Python 内存分析器。它可以跟踪 Python 代码、原生扩展模块以及 Python 解释器本身的内存分配。

以下是 分析 Ray 任务和 Actor 内存使用情况的步骤

Ray Dashboard 视图#

您现在可以在 Ray Dashboard 中对 Ray Driver 或 Worker 进程进行内存分析,方法是点击活动 Worker 进程、任务、Actor 以及作业的驱动程序进程的“内存分析”操作。

memory profiling action

此外,您还可以从仪表板视图指定以下 Memray 分析参数:

  • 格式: 分析结果的格式。值可以是“flamegraph”或“table”。

  • 持续时间: 要跟踪的持续时间(以秒为单位)。

  • 泄漏: 启用内存泄漏视图,该视图显示 Ray 未释放的内存,而不是峰值内存使用量。

  • 原生: 跟踪原生(C/C++)堆栈帧(仅在 Linux 上受支持)。

  • Python 分配器跟踪: 记录 pymalloc 分配器进行的分配。

GPU 性能分析#

为您的 GPU 工作负载(如分布式训练)进行 GPU 和 GRAM 性能分析。这有助于您分析性能并调试内存问题。

  • 与 Ray Train 一起使用时,PyTorch Profiler 已开箱即用。

  • NVIDIA Nsight System 在 Ray 上得到原生支持。

PyTorch Profiler#

PyTorch Profiler 是一个允许在训练和推理过程中收集性能指标(尤其是 GPU 指标)的工具。

以下是 在 Ray Train 或 Ray Data 中使用 PyTorch Profiler 的步骤

Nsight System Profiler#

安装#

首先,请按照 Nsight 用户指南 安装 Nsight System CLI。

确认您已正确安装 Nsight。

$ nsys --version

# NVIDIA Nsight Systems version 2022.4.1.21-0db2c85

在 Ray 上运行 Nsight#

要启用 GPU 性能分析,请在 runtime_env 中按如下方式指定配置:

import torch
import ray

ray.init()

@ray.remote(num_gpus=1, runtime_env={ "nsight": "default"})
class RayActor:
    def run(self):
        a = torch.tensor([1.0, 2.0, 3.0]).cuda()
        b = torch.tensor([4.0, 5.0, 6.0]).cuda()
        c = a * b

        print("Result on GPU:", c)

ray_actor = RayActor.remote()
# The Actor or Task process runs with : "nsys profile [default options] ..."
ray.get(ray_actor.run.remote())

您可以在 nsight.py 中找到 "default" 配置。

自定义选项#

您还可以通过指定一个选项值字典来为 Nsight System Profiler 添加 自定义选项,该字典会覆盖 default 配置,但 Ray 保留了默认配置的 --output 选项。

import torch
import ray

ray.init()

@ray.remote(
num_gpus=1, 
runtime_env={ "nsight": {
    "t": "cuda,cudnn,cublas",
    "cuda-memory-usage": "true",
    "cuda-graph-trace": "graph",
}})
class RayActor:
    def run(self):
        a = torch.tensor([1.0, 2.0, 3.0]).cuda()
        b = torch.tensor([4.0, 5.0, 6.0]).cuda()
        c = a * b

        print("Result on GPU:", c)

ray_actor = RayActor.remote()

# The Actor or Task process runs with :
# "nsys profile -t cuda,cudnn,cublas --cuda-memory-usage=True --cuda-graph-trace=graph ..."
ray.get(ray_actor.run.remote())

注意: 默认报告文件名(-o, --output)在日志目录中是 worker_process_{pid}.nsys-rep

性能分析结果#

/tmp/ray/session_*/logs/{profiler_name} 目录下查找性能分析结果。此特定目录位置将来可能会更改。您可以从 Ray Dashboard 下载性能分析报告。

Nsight System Profiler folder

要可视化结果,请在笔记本电脑上安装 Nsight System GUI,将其作为主机。将 .nsys-rep 文件传输到您的主机并使用 GUI 打开它。您现在可以看到可视化的性能分析信息。

注意: Nsight System Profiler 的 output (-o, --output) 选项允许您设置文件名路径。Ray 使用日志目录作为基础,并向其附加 output 选项。例如:

--output job_name/ray_worker -> /tmp/ray/session_*/logs/nsight/job_name/ray_worker

--output /Users/Desktop/job_name/ray_worker -> /Users/Desktop/job_name/ray_worker

最佳实践是仅在 output 选项中指定文件名。

Ray 任务或 Actor 时间线#

Ray Timeline 分析 Ray 任务和 Actor 的执行时间。这有助于您分析性能,识别慢速任务,并了解工作负载的分布。

在 Ray Dashboard 中打开您的 Ray 作业,然后按照 说明下载和可视化 Ray Timeline 生成的跟踪文件