From 5030b2f3d003e81021c1177a2cf66b3e19c73fc2 Mon Sep 17 00:00:00 2001 From: hehongzhe <935062458@qq.com> Date: Mon, 30 Jun 2025 11:27:12 +0800 Subject: [PATCH] add profiler mstx --- docs/sample_code/profiler/mstx_profiler.py | 74 ++++++++++++++++++ tutorials/source_en/debug/profiler.md | 23 +++++- .../debug/images/mstx_profiler.png | Bin 0 -> 448636 bytes tutorials/source_zh_cn/debug/profiler.md | 23 +++++- 4 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 docs/sample_code/profiler/mstx_profiler.py create mode 100644 tutorials/source_zh_cn/debug/images/mstx_profiler.png diff --git a/docs/sample_code/profiler/mstx_profiler.py b/docs/sample_code/profiler/mstx_profiler.py new file mode 100644 index 0000000000..20c259d38b --- /dev/null +++ b/docs/sample_code/profiler/mstx_profiler.py @@ -0,0 +1,74 @@ +# Copyright 2025 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ +"""mstx Profiler Example""" +import numpy as np + +import mindspore +import mindspore.dataset as ds +from mindspore import nn +from mindspore.profiler import ProfilerLevel, ProfilerActivity, schedule, tensorboard_trace_handler, mstx + + +class Net(nn.Cell): + def __init__(self): + super(Net, self).__init__() + self.fc = nn.Dense(2, 2) + + def construct(self, x): + return self.fc(x) + + +def generator_net(): + for _ in range(10): + yield np.ones([2, 2]).astype(np.float32), np.ones([2]).astype(np.int32) + + +def forward_fn(data, label): + logits = model(data) + mstx.mark("backward_begin") + loss = loss_fn(logits, label) + return loss, logits + + +def train_step(data, label): + range_id1 = mstx.range_start("forward_and_backward") + (loss, _), grads = grad_fn(data, label) + mstx.range_end(range_id1) + range_id2 = mstx.range_start("optimizer_step") + optimizer(grads) + mstx.range_end(range_id2) + return loss + + +if __name__ == "__main__": + mindspore.set_device("Ascend") + model = Net() + optimizer = nn.Momentum(model.trainable_params(), 1, 0.9) + grad_fn = mindspore.value_and_grad(forward_fn, None, optimizer.parameters, has_aux=True) + loss_fn = nn.SoftmaxCrossEntropyWithLogits(sparse=True) + stream = mindspore.runtime.current_stream() + # pylint: disable=protected-access + experimental_config = mindspore.profiler._ExperimentalConfig( + profiler_level=ProfilerLevel.LevelNone, + mstx=True) + with mindspore.profiler.profile( + activities=[ProfilerActivity.CPU, ProfilerActivity.NPU], + schedule=schedule(wait=0, warmup=1, active=1, repeat=1, skip_first=0), + on_trace_ready=tensorboard_trace_handler("./data"), + experimental_config=experimental_config + ) as profiler: + for step_data, step_label in ds.GeneratorDataset(generator_net(), ["data", "label"]): + train_step(step_data, step_data) + profiler.step() diff --git a/tutorials/source_en/debug/profiler.md b/tutorials/source_en/debug/profiler.md index 8fd491f142..5807116aed 100644 --- a/tutorials/source_en/debug/profiler.md +++ b/tutorials/source_en/debug/profiler.md @@ -18,7 +18,7 @@ This tutorial introduces how to use MindSpore Profiler for performance tuning on ## Usage -There are four ways to collect training performance data, and the following describes how to use Profiler enablement depending on the scenario. +There are five ways to collect training performance data, and the following describes how to use Profiler enablement depending on the scenario. ### Method 1: mindspore.Profiler Interface Enabling @@ -181,6 +181,27 @@ from mindspore.profiler.profiler import analyse analyse("./profiler_data_path") # './profiler_data_path' is the data path ``` +### Method 5: Lightweight Marking + +To address the traditional profiler process being time-consuming and dealing with large amounts of data in large cluster scenarios, MindSpore 2.5 offers a lightweight profiler capability to assist in obtaining performance data for critical model metrics in a lightweight manner for large-scale clusters. As illustrated in the following figure, users can customize marking through the mstx.mark, mstx.range_start, and mstx.range_end interfaces, and also support built-in marking of communication operators. When users enable the lightweight marking function, marking is automatically performed before and after the communication operators. All marking tasks are issued by the runtime to the device side, which can present the time points or time slices of the marking tasks on the host side and the device side. + +![mstx_profiler.png](../../source_zh_cn/debug/images/mstx_profiler.png) + +For details about the mstx interface, please refer to [mstx API](https://www.mindspore.cn/docs/en/master/api_python/mindspore/mindspore.profiler.mstx.html). + +The lightweight marking sample is shown below: + +```python +from mindspore.profiler import mstx + +range_id = mstx.range_start("train") +mstx.mark("start") +# train_step +mstx.range_end(range_id) +``` + +For the complete case, refer to [mstx lightweight marking method case](https://gitee.com/mindspore/docs/blob/master/docs/sample_code/profiler/mstx_profiler.py). + ## Performance Data Users can collect, parse, and analyze performance data through MindSpore Profiler, including raw performance data from the framework side, CANN side, and device side, as well as parsed performance data. diff --git a/tutorials/source_zh_cn/debug/images/mstx_profiler.png b/tutorials/source_zh_cn/debug/images/mstx_profiler.png new file mode 100644 index 0000000000000000000000000000000000000000..08c8e79abf974a2d04be42c75cc36614a1ee0947 GIT binary patch literal 448636 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 z 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 lAP^7;2m}NI0s-R@cxXw)$l}<36S(B