Py-spy Speedscope能否导出CSV?如何与Perun能耗分析时间线对齐?
在HPC环境中对齐Perun与Py-spy Speedscope的时间线并导出CSV
问题描述
在HPC环境中分析Transformer深度学习模型的计算能耗,需对比能耗分析器Perun与Py-spy Speedscope的进程时间步:
- Perun可输出CSV格式数据,获取各时间步的能耗信息
- Py-spy Speedscope用于查看进程的精确时间线
- 同时运行两款工具监控
transformer.py的命令如下:
py-spy record --rate 500 --format speedscope --output profile.speedscope.json -- python3.9 transformer.py & ~/.local/bin/perun --format hdf5 --sampling_rate 0.5 monitor transformer.py &
希望将两者统一为CSV格式以对齐时间线,明确代码中高能耗环节(如反向传播梯度计算、权重更新等)的能耗情况,但手动映射时间线难以实现,因此有两个问题:
- 如何对齐两款分析器的时间线进行对比?
- Py-spy Speedscope能否输出CSV格式的结果?
解答
1. 对齐两款分析器的时间线
核心思路是以进程启动或关键代码事件的时间戳为锚点,统一时间基准后匹配数据,具体步骤如下:
- 添加代码级时间锚点:
在transformer.py的启动处、反向传播开始/结束、权重更新等关键节点,用time.time()记录精确到毫秒的时间戳并打印日志。这些锚点可以同时关联Perun的能耗采样和Py-spy的调用栈采样。 - 转换Perun的HDF5数据到CSV:
当前Perun输出的是HDF5格式,先转换为CSV以提取时间戳:
转换后的CSV会包含采样时间戳(通常是相对于进程启动的时间或绝对时间),将这一列作为能耗数据的时间基准。perun convert --from hdf5 --to csv input.hdf5 output_perun.csv - 解析Py-spy的Speedscope JSON生成CSV:
Speedscope的JSON文件中,profiles字段下的samples数组记录了每个采样点的调用栈,timeDeltas数组记录了采样间隔。用Python脚本解析并生成带时间戳的CSV:import json import csv with open('profile.speedscope.json', 'r') as f: data = json.load(f) # 取CPU采样的profile(默认第一个) profile = data['profiles'][0] samples = profile['samples'] time_deltas = profile['timeDeltas'] current_time = 0 output_rows = [['timestamp_ms', 'call_stack']] for idx, sample in enumerate(samples): current_time += time_deltas[idx] # 拼接调用栈路径 call_stack = ' -> '.join([data['shared']['frames'][frame_id]['name'] for frame_id in sample]) output_rows.append([current_time, call_stack]) with open('output_pyspy.csv', 'w', newline='') as csvfile: writer = csv.writer(csvfile) writer.writerows(output_rows) - 时间线匹配与聚合:
现在两个CSV都有了相对于进程启动的时间戳,可按固定时间区间(比如500ms)做数据聚合,将Py-spy的代码调用栈信息与Perun的能耗数据对应。若时间戳精度有差异,可采用线性插值补全能耗数据,匹配Py-spy的采样点。
2. Py-spy输出CSV格式结果
Py-spy没有直接输出CSV的命令行参数,但可通过两种方式生成CSV:
- 解析Speedscope JSON:
用上述Python脚本解析Speedscope格式的JSON文件,提取时间戳和调用栈信息,直接导出为CSV,这是最简便的方式。 - 转换Raw格式采样数据:
先生成原始采样格式文件,再解析转换为CSV:
Raw格式为二进制,可参考Py-spy的内部解析逻辑编写脚本转换,不过相比解析Speedscope JSON复杂度更高。py-spy record --rate 500 --format raw --output profile.raw -- python3.9 transformer.py
内容的提问来源于stack exchange,提问作者Avatar
相关产品推荐
相关产品推荐

