昨天我們整天泡在會診室,讀片、指認病徵,最後把眼睛的極限講明白了,聯集、佔比、重疊,看得到、算不動,要精確就得回去手寫 SQL。今天把白袍掛回去,跟我去一趟花市,我要給你看一朵花。
先把身分交代清楚。這朵花叫 nsys-ai,開源,我自己也有份一起種,Day 5 掀 sqlite 蓋子的時候就預告過它。自家種的花聞起來當然香,所以今天的規矩比平常更嚴,只講你當場驗證得了的東西,界線跟短處一起講。賣花歸賣花,判準永遠是你的。
第一件要講清楚的事,這朵花不是憑空開的。nsys-ai 不取代 nsys,它從 nsys 的土裡長出來,開在最上面。
土還是同一盆。Day 4 你錄下(好吧,是下載)的那份 .nsys-rep,Day 5 掀開看過的那顆 sqlite,就是這朵花的土。它接受三種土質,.nsys-rep、.sqlite、.parquetdir,全是 Nsight Systems 自家的匯出格式,沒有私有魔法,你 Day 5 學的那套表結構知識一路通用。
依賴的界線一句話講死。錄新檔、轉格式,機器上得有 nsys CLI;分析現成的 .sqlite 或 .parquetdir,純 Python 3.10 以上就跑,不用 CUDA、不用裝 Nsight。育土要 nsys,賞花不用。
所以它跟前面十一天的關係是這樣的。nsys 負責把這盆土錄出來,stats 跟 analyze 是官方發的鏟子跟篩子,GUI 是你的眼睛,前面十一天你都在徒手翻土。nsys-ai 的根扎在同一盆土裡,把你會的動作打包成一鍵,再把 Day 5 那些要繞路手算的(對,就是 idle 聯集)直接算好,開成一朵花端給你。
拿 Day 4 那張工具地圖對位,nvidia-smi 在表象層,Nsight 在量測層,nsys-ai 填的是再上面的解讀層,不量新東西,只把量到的翻成診斷。它跟 Nsight Compute 也不打架,細查單顆 kernel 的戲在更下面那層,Day 21 才開。

種下去一行,開花也一行:
pip install nsys-ai
# 有 nsys 的機器:.nsys-rep 直接餵,第一次自動轉檔、之後吃快取
nsys-ai doctor baseline.t128k.host-fs-mbz-gpu-899.nsys-rep
nsys-ai report baseline.t128k.host-fs-mbz-gpu-899.nsys-rep --gpu 4 --trim 39 42
不用自己動手轉檔。第一次餵 .nsys-rep,它背後呼叫 nsys export 轉成 Parquet 快取放在檔案旁邊,一次性,文件給的參考數字是 634 MB 約 6 秒,之後所有指令直接吃快取,來源檔更新或上次轉到一半斷了才重轉。依賴界線的實際玩法就出來了,訓練機上第一次開完,把快取目錄(或現成的 .sqlite)拖回筆電,整場會診免 nsys。想強制走 sqlite 老路,環境變數 NSYS_AI_INGEST=sqlite;但文件有句話值得抄,兩種儲存是相容路徑、不是完全相同的證據來源,同一場會診別兩邊混著讀。
第一行的 doctor 是驗土,環境跟土一起驗,nsys 在不在、檔案健不健康、該有的資料在不在,一次講清楚。它是 Day 10 第 0 步的自動版,也是 Day 11 那頁 Diagnostics Summary 在命令列上的表親,開工先跑,省得對著殘檔認真半天。
第二行的 report 是病歷首頁的自動版,一頁總覽,卡的佔用、idle、top kernel、NVTX 各段,最後還附一句人話總結;它的 --gpu 跟 --trim 是必填,正好把 example-20 的建議值填進去。
再來是選窗,這家的做法值得學。--trim 收兩個秒數,掛在錄影時鐘上,不是從第一顆 kernel 起算,剪之前先 nsys-ai info 看窗落在哪;剪到窗外不會默默給你空表,直接一個 TRIM_OUT_OF_RANGE 打回來,比 Day 7 圈錯窗白錄一場文明多了。更合本系列胃口的是 --iteration N,以圈選窗,零起算,邊界從 NVTX 標記找,沒標記就用 kernel 空檔猜,跨檔比較特別好用,兩份錄影的絕對時鐘本來就對不上。兩種選窗一次只能用一種,同時給會被直接拒絕。
安裝也有個講究。pip install nsys-ai 裝的是刻意保持輕量的核心,重依賴全部拆成選配,要 agent 加 [agent]、要 MCP server 加 [mcp]、Day 22 的 CUTracer 加 [cutracer],懶得挑就 [all]。核心輕,是為了讓它進得了 CI 跟隨身筆電,這個取捨後面會一直感覺到。
主檔 A 在 HF 上只放了 11 MB 的 .nsys-rep,所以第一次轉檔繞不開一台有 nsys 的機器,這是目前跟課最大的一道門檻,我們正在想辦法把轉好的快取直接補上去。
手邊完全沒有 nsys 的人也有位子。抓一顆預先轉好的公開 sqlite,一樣能把今天所有指令跑一遍:
hf download rich7421/fastvideo-wan-h100-sp1-nsys \
profiles/perf_h100_sp1.sqlite --repo-type dataset --local-dir .
nsys-ai info profiles/perf_h100_sp1.sqlite
這是一份 H100 上跑影片生成模型的推論 profile,Day 27 做優化前後 diff 的主角,今天先借來練手。
進去之後幾個入口先認一認。info 報檔案身家,連整份錄影的時間窗都先告訴你;diagnose 一口氣跑預設的 skill 包、把發現排好名;瀏覽器派有三個介面,web、timeline-web、diff-web,留到 0.3.0 那節細講;終端機黨用 open --viewer tui。同一盆土,看你今天想用哪隻手。
花開了,第一件事我建議是對帳。report 的總覽拿去跟 Day 10 手填的病歷首頁並排,五格一格一格對。最可能出入的是 idle,你手上是粗估,它給的是全 stream 聯集的精確值。差不到幾個百分點,你的眼睛可以信;差超過五個百分點,先別怪花,回 Day 11 檢查是不是把假空白當成洞。用手工驗它,再用它校手工,來回一趟,兩邊都更信得過。
nsys-ai 的核心概念只有一個,skill,也就是花瓣。
一個 skill 回答一個問題。最肥的 kernel 是誰,top_kernels;GPU 發呆的洞在哪、多寬,gpu_idle_gaps;搬運的帳,memory_transfers;通訊拆帳,nccl_breakdown。一瓣管一件事,想問什麼摘哪瓣,全部從命令列跑:
nsys-ai skill list
nsys-ai skill run gpu_idle_gaps baseline.t128k.host-fs-mbz-gpu-899.nsys-rep
nsys-ai skill run profile_health_manifest \
baseline.t128k.host-fs-mbz-gpu-899.nsys-rep --format json
skill list 印的是活目錄,0.3.0 這一版數下來整朵花 38 瓣,但文件講得很直白,registry 才是唯一真相,花瓣會一直長,以你當場印出來的為準。第二行先兌現一筆欠帳。Day 5 講過真 idle 要把所有 stream 的區間做聯集,Day 10 你只能靠 analyze 加目測夾出粗估,Day 11 你拿眼睛一刀一刀垂直切。gpu_idle_gaps 就是把那個聯集寫成程式,洞的清單、每個洞多寬、加總佔比,一次吐給你。三天的手工,一行收掉。
這種把繞路寫成程式的地方,正是花瓣最值錢的部分。Day 10 你要拿 mem_time_sum 跟 mem_size_sum 兩張表同列相除才有有效頻寬,Day 11 你要對著三五個圈一次一次拖選才量得出圈長,前者這類跨表換算 skill 直接內建,後者有一瓣 iteration_timing,專門找重複出現的圈、量它們的長度。官方報表給的是原料,花瓣給的是結論的前一步。
第三行的 profile_health_manifest 是 Day 10 第 0 步的自動版,檢體有沒有貨、量級對不對,先驗再讀。後面掛的 --format json 值得多看一眼,每片花瓣都能吐機器可讀的格式,這代表它可以進腳本、進 CI,Day 29 我們就靠這個讓壞掉的效能亮紅燈。JSON 吐的是一列一列的 rows,配 --max-rows 限行數,被截斷時會多出 _truncated、_total_rows 這類中繼欄位老實交代,寫腳本的人會感謝這種設計。
再來是今天最重要的一個主張,這些花瓣是確定性的(deterministic)。同一盆土,同一片瓣,摘一百次是同一個答案,沒有溫度參數、沒有隨機性、不靠 LLM。為什麼我把這件事看得比功能列表重,因為只有確定性的數字才配當證據,才能寫進報告、才能當 baseline 存起來、才能在 CI 裡當紅綠燈,也才輪得到之後的 agent 引用它。反過來,沒有量測就下結論,人會犯,模型也會犯,Day 10 說過那叫通靈,換成機器來通靈並不會比較高級。

還有一層信任是開源給的。skill 不是黑盒,底下就是對那份快取下查詢,跟 Day 5 你手寫的那句 SQL 同一國,原始碼隨時可以翻,開發文件還有一頁 skill contract,白紙黑字規定每片新瓣都得可攜、確定性、輸出 JSON-safe,把可信寫進工程規範,不是口號。建議你至少做一次,挑一瓣最簡單的,拿 Day 5 那句 GROUP BY 覆算一遍,對得上再收編進工作流。工具要用信的,信要用驗的。
順帶講一句設計,為什麼是三十八片瓣,不是一朵掰不開的大紅花。一瓣一問,輸出結構化,小單元才能自由組合,你可以只摘三瓣、可以整朵摘完、可以串進腳本挑著摘;之後的 agent 也是同一套邏輯,它是繞著這朵花轉的蜜蜂,一次停一瓣,採哪瓣講哪瓣的蜜。
現在把 Day 10 那張分診表拿出來,好戲在這。每一條分診線,都有一片花瓣認領,而且這正好就是接下來一週的課表:
profile_health_manifest
top_kernels
gpu_idle_gaps
kernel_launch_overhead
memory_transfers
region_mfu
nccl_breakdown 跟 overlap_breakdown

會診的玩法從今天起升級。Day 11 你用眼睛在片子上指認病徵,從明天開始,每指認一個,就摘對應的那瓣,讓數字進病歷。眼睛找嫌疑,花瓣給答案,這才是完整的一套。
花瓣裡還藏著一片有意思的,root_cause_matcher,把手上的證據對到可能的病因,等於自動分診的雛形。可以摘,但分診表你還是得自己會,Day 10 講過為什麼,佔比排序、絕對值換算、值不值得動手,這些是判斷,不是查表。
Day 5 預告過的 0.3.0 到位了,挑對這場會診有用的講。
先是三個瀏覽器介面。web 開的是 NVTX 樹的專屬瀏覽器,Day 8 你掛的那棵樹、每個 range 底下歸了哪些 kernel,點著逛;timeline-web 是多卡 timeline,漸進式渲染,先把頁面殼端出來、資料在背景慢慢備,八卡的檔也能先動起來;diff-web 給優化前後並排看。都是一行起服務,--port 挑埠、--no-browser 給遠端用。我自己的用法是,精讀因果還是開原廠 GUI,快速瀏覽、丟給同事看用 web 版,對方瀏覽器打開就能看,連裝都不用裝。
再來是 session。會診過程的發現、跑過的 diff、做過的決策,存進一個 session 目錄,命令列跟 web 介面共用。Day 10 才唸過 baseline 檔名要帶日期跟 commit hash,session 把這種歸檔紀律直接做進工具,你休假,同事接手的是整包會診紀錄。文件的主線工作流也照這個節奏寫,錄、診斷、提案、diff、決策,一圈一圈轉,這就是 Day 30 要收的那句口令,量測、假設、再量測。
接著兩個是給 agent 生態的接口。Claude Code 使用者裝了 plugin 就多一個 /nsys-ai 指令,在編輯器裡直接問手上的 profile;MCP server 裝 [mcp] 就有,任何支援 MCP 的 agent 都能把這 38 片花瓣當工具箱接走。最後是 agent 系列指令,analyze 自動跑一輪、ask 用問的,這兩個今天先不玩,Day 23 到 26 整整四天專門收拾它,今天只立一條規矩,agent 就是那隻蜜蜂,只能採花瓣裡有的蜜,不能憑空釀,到時候我們會拿對照實驗驗這件事。
比較的那條線也先報個路標。優化前後兩顆檔一行對比,baseline 存起來之後拿新的來撞:
nsys-ai diff before.sqlite after.sqlite
nsys-ai baseline tag main run.sqlite --reason green-main
nsys-ai diff --against baseline:main candidate.sqlite
這三行是 Day 27 跟 Day 29 的主菜,repo 裡連 CI 怎麼架 diff 閘門都有專頁文件,今天知道有這條路就好。工程習慣先補一條,skill 目錄是活的、版本走得快,八月初 PyPI 上還是 0.2.3,寫這篇的時候 0.3.0 已經到位,要把它放進 CI 或共用腳本,版本釘死再上,升級當成一次有意識的變更來做,別讓活目錄變成 pipeline 裡的活地雷。
最後把界線立清楚,跟 Day 5 對 analyze 立的規矩一字不改,線索不是定論。
花瓣吐的是數字,數字忠實,但值不值得修、先修哪個、修了划不划算,花不會替你決定,那是你的判斷。gpu_idle_gaps 說洞佔兩成,要不要動手,得回 Day 10 那課,看絕對值、看工程成本、看帳單。它把量測做到又快又準,正是為了讓你把時間花在判斷上,而不是替你判斷。
更難得的是,這些界線產品自己寫成了一頁文件,known limits,挑三條你一定要知道。第一,diff 的判定不是因果證明,它說兩份錄影哪裡不一樣,不能證明是你那行程式碼改的,Day 27 拿實驗設計補這個洞。第二,錄影之外的問題答不了,功耗、沒插樁的服務、哪一行原始碼慢,不在 trace 裡的任何工具都生不出來。第三,百分比要跟分子分母一起看才有意義,Day 10 我們在 mem_time_sum 上踩過同一課,文件補了個狠例子,跨 stream 的 idle 百分比可以加出超過 100%,一條在睡、另一條還在跑。願意把不敢保證的事列成清單的產品,比任何功能列表都值得信。
這也是前面十一天不白練的原因。花瓣吐出的每一個數字,你知道它在講片子上的哪一塊,聯集是哪三天的欠帳、佔比要配哪個絕對值、overlap 對應 timeline 上哪兩條 stream 的並排。只會摘花而不會讀片的人,答案上每個字都認得,連起來不知道意思,這種人每間機房都有一個,別當第二個。
順手留個書籤。repo 的 docs 底下有一整排照主題寫的 user guide,skills、選窗、輸入格式、三個 web 介面、怎麼讀一份 diff、troubleshooting,一路到 0.2.3 升 0.3.0 的遷移指引;連 Day 4 到 9 我們讀過的那些 Nsight 官方主題,它也整理了一份節錄擺在旁邊。這個系列只挑跟會診有關的講,其他的,缺什麼翻什麼。
今天這朵花看完了,四件事收好。位置,它開在 nsys 的土上,同一盆土,三種土質。界線,育土要 nsys,賞花免 CUDA。核心,一瓣一問,確定性,同輸入同輸出,才配當證據。對照,每條分診線一片花瓣,就是下週課表。
明天 Day 13 開摘。病歷首頁上 top kernel 那格寫著 flash attention 三成,80/20 教我們先打最肥的,top_kernels 這一瓣會告訴我們刀口在哪。
花開好了,瓣也數清了。明天,摘第一瓣。
.nsys-rep):HF GindaChen/nsys-hero;轉檔用 nsys export(Day 4)。rich7421/fastvideo-wan-h100-sp1-nsys。