NVIDIA Nsight Python Tutorial: How to Profile GPU Kernels

2026年10月22日 03:59
站內 AI 整理稿

In this tutorial, we implement on Nsight Python, NVIDIA’s open-source Python interface to its kernel profilers.Instead of running a script under the Nsight Compute command line and digging through a report afterward, we mark the code we care about with nsight.

annotate, decorate a benchmark function with nsight.analyze.kernel, and get back a pandas DataFrame of hardware metrics per annotated region, per configuration, and per run.Since version 1.

0, the library attaches Nsight Compute to the running Python process, making it usable in Jupyter and Colab, and the upcoming 1.1 release adds an experimental CUPTI backend, explicit tool management, and custom information collectors.

We run everything on a free Colab T4: we install a current Nsight Compute next to the one Colab ships, profile a first kernel, decide how many runs a measurement needs, measure what cache and clock control do to the same kernel, sweep matrix sizes in fp32 and fp16 with a derived TFLOP/s metric, use hardware counters to tell compute-bound from memory-bound work, measure kernel fusion in bytes moved, record clocks and temperature per run, compare the CUPTI backend with Nsight Compute, and keep the raw report for deeper analysis.

Copy CodeCopiedUse a different Browserimport os import sys import glob import json import time import shutil import textwrap import traceback import subprocess RESULTS = {} def banner(title): print("\n" + "=" 78) print(title) print("=" 78) def section(name): def wrap(fn): def run(a, kw): banner(name) try: out = fn(a, kw) RESULTS[name] = out if isinstance(out, str) else "ok" return out except Exception as e: RESULTS[name] = f"SKIPPED / FAILED -> {type(e).

name}: {str(e).splitlines()[0][:160]}" print(f"\n[!] {name} did not complete: {type(e).name}: {e}") traceback.printexc(limit=3) return None return run return wrap def sh(cmd): """Run a shell command and return its stdout, stripped.""" return subprocess.

run(cmd, shell=True, captureoutput=True, text=True).stdout.strip() banner("1.Install a current Nsight Compute next to Colab's, then import nsight before CUDA") print(f" GPU: {sh('nvidia-smi --query-gpu=name,driverversion,memory.total,computecap --format=csv,noheader')}") preinstalled = shutil.

which("ncu") print(f" ncu already on PATH: {preinstalled} -> {sh('ncu --version | tail -1') if preinstalled else 'none'}") # nsight-python needs Nsight Compute 2026.2.1 or newer.

Colab ships an older ncu, but its image already # carries NVIDIA's CUDA apt repository, so a current release is one apt-get away.It installs into # /opt/nvidia/nsight-compute// and leaves the preinstalled one untouched.subprocess.run("apt-get update -qq > /tmp/ncuinstall.

log 2>&1", shell=True) for NCUVERSION in ("2026.3.1", "2026.2.1"): if subprocess.run(f"apt-get install -y -qq nsight-compute-{NCUVERSION} >> /tmp/ncuinstall.log 2>&1", shell=True).returncode == 0: break else: print(sh("tail -5 /tmp/ncuinstall.

log")) raise RuntimeError("could not install Nsight Compute 2026.2.1+ from NVIDIA's apt repository") # ask dpkg where the package put the ncu launcher rather than assuming /opt/nvidia/nsight-compute// ncupaths = sh(f"dpkg -L nsight-compute-{NCUVERSION} | grep -E '/ncu$'").

split() if not ncupaths: raise RuntimeError(f"dpkg lists no ncu executable in nsight-compute-{NCUVERSION}") NCUDIR = os.path.dirname(min(ncupaths, key=len)) # the top-level launcher, not a per-platform copy os.environ["PATH"] = NCUDIR + os.pathsep + os.

environ["PATH"] # nsight-python looks ncu up on PATH print(f" installed: {shutil.which('ncu')} -> {sh('ncu --version | tail -1')}") # nsight-python 1.1.0 (CUPTI backend, tool APIs, info collectors) is tagged but not yet on PyPI; # pin the commit this notebook was written against.

The [cupti] extra is used in step 9.NSIGHTCOMMIT = "bb96db4260b1823d86ecab9acfed0646d7af79ad" subprocess.run([sys.executable, "-m", "pip", "install", "-q", f"nsight-python @ git+https://github.com/NVIDIA/nsight-python@{NSIGHTCOMMIT}"], check=True) # The CUPTI backend needs cupti-python 13.

4, which wants a newer libcupti than Colab's torch is pinned to.# Install it into a separate directory that only step 9's child process puts on its path.CUPTIDIR = "/content/cuptienv" CUPTIEXTRA = subprocess.run([sys.

executable, "-m", "pip", "install", "-q", "--target", CUPTIDIR, "--no-deps", "cupti-python>=13.4.0", "nvidia-cuda-cupti~=13.4", "pyelftools"]).returncode == 0 import nsight # activates Nsight Compute's injection library: must come before anything initializes CUDA from nsight.

collection import ncu as ncubackend import numpy as np import pandas as pd import torch SILENT = nsight.VerbosityLevel.SILENT pd.setoption("display.width", 200) pd.setoption("display.maxcolumns", 30) print(f" nsight-python {nsight.version} | active tool: {nsight.

getactivetool()}" f" | injection error at import: {ncubackend.injectionloaderror}") print(f" torch {torch.version} (CUDA {torch.version.cuda}) | {torch.cuda.

getdevicename(0)}" f" | cupti-python installed: {CUPTIEXTRA}") print("\n Order matters: import nsight loads Nsight Compute into this Python process, and it can only") print(" attach to CUDA work started after that.

Every profiled function below runs in this same") print(" process; nsight-python starts ncu --mode attach on its own PID for each one.") We start by checking the GPU and the profiler.Nsight Python requires the Nsight Compute command-line tool, ncu, at version 2026.2.

1 or later, and finds it by looking it up on the PATH.Colab’s GPU image ships an older Nsight Compute.Still, it already has NVIDIA’s CUDA package repository configured, so we install Nsight Compute 2026.3.

1 with apt-get, ask dpkg where the ncu launcher landed, and put that directory first on the PATH.We then install Nsight Python, pinned to the commit of the 1.1.

0 pre-release this notebook was written against, and the cupti-python package into a separate directory, because it needs a newer CUPTI library than the one Colab’s PyTorch is pinned to.

The import order matters: import nsight loads Nsight Compute’s injection library into the Python process, and it can only attach to CUDA work started after that, so nsight must be imported before torch touches the GPU.

Copy CodeCopiedUse a different BrowserADD = lambda x, y: x + y # sums a metric if cuBLAS splits one matmul into several kernels @nsight.analyze.kernel(thermalmode="off", combinekernelmetrics=ADD) def firstmatmul(n: int) -> None: a = torch.randn(n, n, device="cuda") b = torch.

randn(n, n, device="cuda") with nsight.annotate("matmul"): = a @ b @section("2.Profile one kernel: what a ProfileResults row contains") def firstprofile(): df = firstmatmul(2048).todataframe() print(f"\n todataframe() columns: {list(df.columns)}\n") r = df.

iloc[0] t = float(r["AvgValue"]) print(f" annotation {r['Annotation']!r}, n = {r['n']}, kernel {r['Kernel']}") print(f" {r['Metric']} = {t:,.

0f} {r['Unit']} (runs {r['NumRuns']}, stable: {r['StableMeasurement']})") print(f" GPU {r['GPU']}, ComputeClock {r['ComputeClock']}, MemoryClock {r['MemoryClock']}") print(f" -> {2 2048 3 / (t 1e-9) / 1e12:.2f} TFLOP/s for a 2048 x 2048 fp32 matmul") print("\n Only the kernel launched inside nsight.

annotate() is profiled; torch.randn above it is not.") print(" With a single run, StableMeasurement is : one sample has no spread to judge.") return f"fp32 2048 matmul {t / 1e6:.3f} ms ({2 2048 3 / (t 1e-9) / 1e12:.

2f} TFLOP/s)" firstprofile() The first profile is a single fp32 matrix multiplication.The benchmark function creates its inputs, then wraps only the multiplication in nsight.annotate, so the random-number kernels that build the inputs are not measured.

Calling the decorated function starts ncu in attach mode on the notebook’s own process, runs the function, and returns a ProfileResults object whose to_dataframe method gives one row per annotation, configuration, and metric.We print the columns and rea

Related

相關文章

榮耀掀桌電競手機!國補價2251元起,全系2K+185Hz、1萬mAh大電池

作者 | ZeR0 編輯 | 漠影 10月21日報道,今日,榮耀端出電競全家桶,一口氣發佈手機、平板、耳機、手柄、配件等多款電競新品。 榮耀WIN2和榮耀WIN RT2採用同款全新戰鬥美學設計,提供“指定贏”、“快開黑”、“紅藍Buff”三款配色,配備2K 185Hz雙芯綠洲屏與天王星超大風扇、LPDDR5X Ultra旗艦高速內存與UFS 4.1旗艦高速閃存。 該系列手機正面採用0.

20 小時前

人機跨界同框!破全馬記錄名將薩維、越野跑冠軍趙家駒與榮耀人形機器人“閃電”同臺競速

破全馬記錄名將薩維、越野跑冠軍趙家駒與榮耀人形機器人“閃電”同臺競速發布於AI新閒資訊時間 :Oct 20, 2026閱讀 :1分鐘10月20日,一場跨越人類極限與智能科技的特殊競速在線下震撼上演。榮耀全球首席跑步官、肯尼亞馬拉松名將薩巴斯蒂安·薩維,榮耀極限探索官、中國越野跑領軍人物趙家駒,與榮耀自研人形機器人“閃電”迎來了首次線下同框,並現場展開了同臺競速互動與跨賽道對話。

1 天前

一張臉就能算出生死?AI 憑面部照片預測癌症患者存活率

AI 憑面部照片預測癌症患者存活率發布於AI新閒資訊時間 :Oct 20, 2026閱讀 :1分鐘據媒體報道,一支國際研究團隊近日拋出一款堪稱"讀臉斷生死"的 AI 工具——僅憑一張面部照片,就能推算癌症患者的生存機率。它並非要取代醫生,而是給臨床經驗當補充:在醫療資料匱乏、難以做全面評估的場景裡,尤顯價值。

2 天前6900

全球首發:萬拿NOVA21靈巧手,拓展靈巧操作研究邊界

10月15日,在2026香港秋季電子產品展上,萬拿機器人全球首發NOVA21靈巧手。面向機器人科研與開發團隊,萬拿NOVA21採用21自由度全主動旋轉直驅設計,集靈巧、力量、精準與觸覺感知於一體,為多指協同、物品姿態調整與複雜操作策略研究提供執行與感知能力。21自由度全主動旋轉直驅,支持多指協同NOVA21採用擬人化佈局,整手尺寸為195×105×71mm,接近人手大小。拇指擁有5個主動自由度,其餘四指各擁有4個主動自由度。NOVA21的21個主動自由度均採用旋轉直驅,支持全手各指的主動控制與姿態調整。

6 天前

首款韜定律邏輯摺疊芯片量產,麒麟9050讓華為旗艦手機玩出什麼新花樣?

電路折起來,旗艦手機的創新空間也被打開。三年前,麒麟芯片迴歸。三年後,問題已經變成回來之後,還能走多遠?全新基於韜定律的麒麟9050系列給出了一個新的工程答案。作為華為首款採用邏輯摺疊技術的麒麟芯片,麒麟9050 Pro通過跨層重新設計電路,縮短數據傳輸距離,尋找芯片持續升級的空間,也為搭載韜定律芯片的華為手機提供了更強大的算力基礎。

1 週前

賓大茅佳源:從單次演示到 83% 真機泛化,破解具身智能數據困局|IROS 2026

剖析視覺與動作脫節,引入 TR 指標與自適應引導,重構具身泛化機制。作者丨張璐 編輯丨岑峰 在機械臂的實機測試中,不少團隊都遇到過類似的困擾:為了讓機器人學會抓取某個馬克杯,往往需要人類抓著機械臂錄入上百條示範軌跡。然而只要把杯子換成未見過的款式,或者稍微改變物體的擺放位置,策略的成功率就會急劇下降。

1 週前