Scalene: 一款具有AI驱动优化建议的Python CPU+GPU+内存分析器
作者:Emery Berger、Sam Stern和Juan Altmayer Pizzorno。
(来自Ian Ozsvald的推文,他是《高性能Python》的作者)
Scalene基于网页的用户界面: http://plasma-umass.org/scalene-gui/
关于Scalene
Scalene是一款高性能的Python CPU、GPU和内存分析器,它能够完成其他Python分析器无法做到的多项功能。它的运行速度比许多其他分析器快数个数量级,同时提供更详细的信息。它也是第一个集成AI驱动优化建议的分析器。
AI驱动的优化建议
注意
要启用AI驱动的优化建议,您需要在"高级选项"下的框中输入OpenAI密钥。您的账户需要有正余额才能使用此功能(在https://platform.openai.com/account/usage 查看您的余额)。
输入OpenAI密钥后(见上文),点击任何行旁边的闪电图标(⚡)或整个代码区域的爆炸图标(💥)来生成优化建议。点击建议的优化方案可将其复制到剪贴板。
您可以根据需要多次点击闪电或爆炸图标,它会生成不同的优化建议。效果可能因情况而异,但在某些情况下,建议的改进可能非常显著(例如,数量级的提升)。
快速入门
安装Scalene:
python3 -m pip install -U scalene
或
- Scalene **速度快**。它使用采样而不是插桩或依赖Python的跟踪功能。其开销通常不超过10-20%(通常更少)。
- Scalene **准确性高**。我们测试了CPU分析器的准确性,发现Scalene是最准确的分析器之一,能正确测量所用时间。
![分析器准确性](https://yellow-cdn.veclightyear.com/835a84d5/998bebaa-ca20-4289-925d-30df2d3ed1e2.png)
- Scalene可以**按行**和**按函数**进行分析,指出程序中负责执行时间的具体函数和代码行。
### CPU分析
- Scalene**将Python代码的执行时间与原生代码(包括库)的执行时间分开**。大多数Python程序员不会去优化原生代码的性能(通常是Python实现或外部库中的代码),所以这有助于开发者将优化工作集中在他们实际可以改进的代码上。
- Scalene**用红色突出显示热点**(占用大量CPU时间或内存分配的代码),使它们更容易被发现。
- Scalene还分离出**系统时间**,便于找出I/O瓶颈。
### GPU分析
- Scalene报告**GPU时间**(目前仅限于基于NVIDIA的系统)。
### 内存分析
- Scalene**分析内存使用情况**。除了跟踪CPU使用情况外,Scalene还能指出导致内存增长的具体代码行。它通过包含的专用内存分配器来实现这一点。
- Scalene分离出**Python代码与原生代码消耗的内存百分比**。
- Scalene生成**按行的内存分析**。
- Scalene**识别可能存在内存泄漏的行**。
- Scalene**分析复制量**,便于发现无意中的复制,特别是由于跨越Python/库边界造成的(例如,意外地将`numpy`数组转换为Python数组,反之亦然)。
### 其他特性
- Scalene可以生成**精简的分析报告**(通过`--reduced-profile`),只报告消耗超过1%的CPU或至少执行100次分配的行。
- Scalene支持`@profile`装饰器,只分析特定函数。
- 当Scalene分析在后台启动的程序时(通过`&`),你可以**暂停和恢复分析**。
# 与其他分析器的比较
## 性能和特性
下面是比较各种分析器与Scalene的**性能和特性**的表格。
![性能和特性比较](https://yellow-cdn.veclightyear.com/835a84d5/b562c7a5-ce53-4d97-b3b4-9b6a0cebd58a.png)
- **减速**:运行Pyperformance套件基准测试时的减速程度。绿色表示开销小于2倍。Scalene的开销仅为35%的减速。
Scalene具有以下所有特性,其中许多只有Scalene支持:
- **行或函数**:分析器是只报告整个函数的信息,还是每行的信息 -- Scalene两者都做。
- **未修改代码**:可以在未修改的代码上工作。
- **线程**:支持Python线程。
- **多进程**:支持使用`multiprocessing`库 -- *仅Scalene*
- **Python与C时间**:区分在Python和原生代码(如库)中花费的时间 -- *仅Scalene*
- **系统时间**:区分系统时间(如休眠或执行I/O) -- *仅Scalene*
- **分析内存**:报告每行/每函数的内存消耗
- **GPU**:报告在NVIDIA GPU上花费的时间(如果存在) -- *仅Scalene*
- **内存趋势**:报告每行/每函数随时间的内存使用情况 -- *仅Scalene*
- **复制量**:报告每秒复制的兆字节数 -- *仅Scalene*
- **检测泄漏**:自动定位可能导致内存泄漏的代码行 -- *仅Scalene*
## 输出
如果包含`--cli`选项,Scalene会打印被分析程序的带注释源代码(以文本、JSON(`--json`)或HTML(`--html`)格式)以及同一目录或子目录中使用的任何模块(你可以选择让它`--profile-all`并只包含至少有`--cpu-percent-threshold`时间的文件)。以下是`pystone.py`的一个片段。
![示例分析](https://yellow-cdn.veclightyear.com/835a84d5/d3ffc11b-b742-44ac-b076-791bac36d029.png)
* **顶部的内存使用情况**:通过"迷你图"可视化,显示分析代码运行期间的内存消耗。
* **"Time Python"**:在Python代码中花费的时间。
* **"native"**:在非Python代码(如用C/C++编写的库)中花费的时间。
* **"system"**:在系统中花费的时间(如I/O)。
* **"GPU"**:(此处未显示)如果你的系统安装了NVIDIA GPU,在GPU上花费的时间。
* **"Memory Python"**:Python代码端发生的内存分配量,与非Python代码(如用C/C++编写的库)相对。
* **"net"**:正净内存数表示总内存分配(以兆字节为单位);负净内存数表示内存回收。
* **"timeline / %"**:通过"迷你图"可视化,显示此行在程序运行期间产生的内存消耗,以及此行代表的总内存活动百分比。
* **"Copy (MB/s)"**:每秒复制的兆字节数(参见"关于Scalene")。
## Scalene
以下命令在提供的示例程序上运行Scalene。
```console
scalene test/testme.py
点击查看Scalene的所有选项(通过运行 --help
可获得)
% scalene --help
usage: scalene [-h] [--outfile OUTFILE] [--html] [--reduced-profile]
[--profile-interval PROFILE_INTERVAL] [--cpu-only]
[--profile-all] [--profile-only PROFILE_ONLY]
[--use-virtual-time]
[--cpu-percent-threshold CPU_PERCENT_THRESHOLD]
[--cpu-sampling-rate CPU_SAMPLING_RATE]
[--malloc-threshold MALLOC_THRESHOLD]
Scalene: 高精度CPU和内存分析器。
https://github.com/plasma-umass/scalene
命令行:
% scalene [选项] yourprogram.py
或
% python3 -m scalene [选项] yourprogram.py
在Jupyter中,行模式:
%scrun [选项] 语句
在Jupyter中,单元模式:
%%scalene [选项]
代码...
代码...
可选参数:
-h, --help 显示此帮助信息并退出
--outfile OUTFILE 保存分析器输出的文件(默认:stdout)
--html 输出为HTML(默认:文本)
--reduced-profile 生成精简的分析报告,只包含非零行(默认:False)
--profile-interval PROFILE_INTERVAL
每隔多少秒输出一次分析报告(默认:inf)
--cpu-only 仅分析CPU时间(默认:分析CPU、内存和复制)
--profile-all 分析所有执行的代码,而不仅是目标程序(默认:仅目标程序)
--profile-only PROFILE_ONLY
仅分析文件名中包含给定字符串的代码,用逗号分隔(默认:无限制)
--use-virtual-time 仅测量CPU时间,不包括I/O或阻塞所花费的时间(默认:False)
--cpu-percent-threshold CPU_PERCENT_THRESHOLD
仅报告至少占用此百分比CPU时间的分析(默认:1%)
--cpu-sampling-rate CPU_SAMPLING_RATE
CPU采样率(默认:每0.01秒)
--malloc-threshold MALLOC_THRESHOLD
仅报告至少有这么多分配的分析(默认:100)
当在后台运行Scalene时,你可以为Scalene报告的进程ID暂停/恢复分析。
例如:
% python3 -m scalene [选项] yourprogram.py &
Scalene现在正在分析进程12345
暂停分析:python3 -m scalene.profile --off --pid 12345
恢复分析:python3 -m scalene.profile --on --pid 12345
Scalene与Jupyter一起使用
在Jupyter笔记本中安装和使用Scalene的说明
这个笔记本展示了在Jupyter中使用Scalene的方法。
安装:
!pip install scalene
%load_ext scalene
行模式:
%scrun [选项] 语句
单元模式:
%%scalene [选项]
代码...
代码...
安装
使用 pip
(Mac OS X、Linux、Windows和WSL2)
Scalene作为pip
包分发,适用于Mac OS X、Linux(包括Windows WSL2中的Ubuntu)和(有限制的)Windows平台。
注意
Windows版本目前仅支持CPU和GPU分析,不支持内存或复制分析。
你可以按照以下方式安装:
% pip install -U scalene
或
% python3 -m pip install -U scalene
你可能需要先安装一些包。
有关所有Linux发行版的完整说明,请参见 https://stackoverflow.com/a/19344978/4954434。
对于Ubuntu/Debian:
% sudo apt install git python3-all-dev
使用 conda
(Mac OS X、Linux、Windows 和 WSL2)
% conda install -c conda-forge scalene
Scalene 以 conda
包的形式发布,可在 Mac OS X、Linux(包括 Windows WSL2 中的 Ubuntu)和(有限制地)Windows 平台上运行。
注意
Windows 版本目前仅支持 CPU 和 GPU 分析,不支持内存或复制分析。
在 ArchLinux 上
您可以通过 AUR 包 在 Arch Linux 上安装 Scalene。使用您喜欢的 AUR 助手,或手动下载 PKGBUILD
并运行 makepkg -cirs
进行构建。请注意,这将把 libscalene.so
放在 /usr/lib
中;相应地修改下面的使用说明。
常见问题
我可以将 Scalene 与 PyTest 一起使用吗?
答: 可以!您可以按以下方式运行(例如):
python3 -m scalene --- -m pytest your_test.py
有什么方法可以获得更简短的分析结果或进行更有针对性的分析吗?
答: 是的!有几个选项:
- 使用
--reduced-profile
仅包含有内存/CPU/GPU 活动的行和文件。 - 使用
--profile-only
仅包含包含特定字符串的文件名(例如,--profile-only foo,bar,baz
)。 - 用
@profile
装饰感兴趣的函数,让 Scalene 仅报告这些函数。 - 通过导入 Scalene 分析器(
from scalene import scalene_profiler
)并通过scalene_profiler.start()
和scalene_profiler.stop()
来编程方式开启和关闭分析。默认情况下,Scalene 在分析开启的情况下运行,因此要延迟分析到所需时间,请使用--off
命令行选项(python3 -m scalene --off yourprogram.py
)。
如何在 PyCharm 中运行 Scalene?
答: 在 PyCharm 中,您可以通过在 IDE 底部打开终端并运行 Scalene 命令(例如,python -m scalene <your program>
)来在命令行中运行 Scalene。使用选项 --cli
、--html
和 --outfile <your output.html>
生成 HTML 文件,然后您可以在 IDE 中查看。
如何将 Scalene 与 Django 一起使用?
答: 传入 --noreload
选项(参见 https://github.com/plasma-umass/scalene/issues/178)。
Scalene 可以与 gevent/Greenlets 一起使用吗?
答: 可以!在程序开头放置以下代码,或如下修改对 monkey.patch_all
的调用:
from gevent import monkey
monkey.patch_all(thread=False)
如何在 Mac 上将 Scalene 与 PyTorch 一起使用?
答: Scalene 可以在 Mac OS X 上与 PyTorch 1.5.1 版本一起使用。PyTorch 的较新版本存在一个 bug(https://github.com/pytorch/pytorch/issues/57185),会干扰 Scalene 的运行(讨论见:https://github.com/plasma-umass/scalene/issues/110),但这只影响 Mac。
技术信息
有关 Scalene 工作原理的详细信息,请参阅以下论文,该论文在 OSDI 2023 获得了 Jay Lepreau 最佳论文奖:用 Scalene 三角定位 Python 性能问题。(请注意,此论文不包含有关 AI 驱动的优化建议的信息。)
要在学术论文中引用 Scalene,请使用以下格式:
@inproceedings{288540,
author = {Emery D. Berger and Sam Stern and Juan Altmayer Pizzorno},
title = {Triangulating Python Performance Issues with {S}calene},
booktitle = {{17th USENIX Symposium on Operating Systems Design and Implementation (OSDI 23)}},
year = {2023},
isbn = {978-1-939133-34-2},
address = {Boston, MA},
pages = {51--64},
url = {https://www.usenix.org/conference/osdi23/presentation/berger},
publisher = {USENIX Association},
month = jul
}
成功案例
如果您使用 Scalene 成功调试了性能问题,请在此问题下添加评论!
致谢
标志由 Sophia Berger 创作。
本研究基于美国国家科学基金会 Grant No. 1955610 的资助。本材料中表达的任何观点、发现、结论或建议均为作者的观点,不一定反映美国国家科学基金会的观点。