分析#

分析是诊断性能、内存溢出、挂起或其他应用问题最重要的调试工具之一。以下是调试 Ray 应用时可能用到的一些常用分析工具列表。

  • CPU 分析

    • py-spy

  • 内存分析

    • memray

  • GPU 分析

    • PyTorch Profiler

    • Nsight System

  • Ray Task / Actor 时间线

如果 Ray 不与某些分析工具配合使用,请尝试在不使用 Ray 的情况下运行它们以调试问题。

CPU 分析#

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

py-spy#

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

  • 它允许您可视化 Python 程序将时间花费在哪里,而无需重启程序或修改任何代码。

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

注意

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

  • 如果您在 Docker 容器中手动启动 Ray,请遵循 py-spy documentation_ 进行解决。

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

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

cProfile#

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

以下是使用 cProfile 的步骤

内存分析#

分析 Driver 和 Worker 进程的内存使用率。这有助于您分析应用中的内存分配、跟踪内存泄漏以及调试高/低内存或内存溢出问题。

memray#

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

以下是分析 Ray Tasks 和 Actors 内存使用率的步骤

Ray Dashboard 视图#

您现在可以在 Ray Dashboard 中对 Ray Driver 或 Worker 进程进行内存分析,只需点击针对活跃 Worker 进程、Tasks、Actors 和 Job Driver 进程的“内存分析”操作即可。

memory profiling action

此外,您可以在 dashboard 视图中指定以下 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 User Guide 安装 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():
    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 会保留 default 配置的 --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():
    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) 是 logs 目录中的 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 输出 (-o, –output) 选项允许您设置文件名路径。Ray 使用 logs 目录作为基础,并在其后附加输出选项。例如

--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

最佳实践是在输出选项中只指定文件名。

Ray Task 或 Actor 时间线#

Ray Timeline 分析 Ray Tasks 和 Actors 的执行时间。这有助于您分析性能、识别拖慢进度的任务并了解工作负载的分布。

在 Ray Dashboard 中打开您的 Ray Job,并按照下载和可视化 Ray Timeline 生成的跟踪文件的说明进行操作。