kitt-stt · Performance evidence

2026-09-12 · latest-main worktree · RTX 4090 · local research

kitt-stt 效能與記憶體研究

2026-09-12 · 67160fab1a16f52945e11da37070a144cc6511d1 · RTX 4090

已證實的主要成本是 interim 重算/排隊、hotword beam search,以及 tracing 的鎖內序列化。 四席 30 秒音訊,把 interim 起始與最小間隔從 0.5 秒改為 1 秒,final 中位數為 301.5 ms;兩次 0.5 秒對照分別是 539.6/487.8 ms,相對降低 38.2–44.1%。這是固定音訊的實測改善,字幕更新頻率與喚醒/轉錄品質限制見下文。

這份報告把可重播的改善、已量到的成本,以及仍需要實驗的候選方向分開標示。沒有修改 production source、push 或部署。所有結果只代表本次硬體、模型、設定與音訊;不能宣稱已窮盡任意輸入與部署環境的所有瓶頸。

優化優先順序

優先 方向 本次證據 建議與限制
1 降低長語音的 interim 重算頻率 真實 WebSocket A/B;兩邊都關閉 production tracing 先考慮負載/語音長度感知的頻率。1 秒組的改善見下表;短語音未必更快,即時字幕更新會變疏。不能把這組結果當成模型辨識品質驗證。
1 減少 shared recognizer 排隊與 final 前等待 rec_lock_wait、四席 VAD callback 時序、client/server latency 差距 final priority、排程公平性與真正 batching 是後續設計方向。排隊成本已證實,各種排程改法的產品效果需另外測量。直接刪除 shared lock 尚未驗證執行緒安全。
1 降低 tracing 的序列化與鎖內工作量 真實 PerfettoTracer microbenchmark、production flush span、native sampling、compact live replay 去除 JSON 縮排是已測的低範圍實驗;56,268 events 的 write peak 明顯下降。snapshot 後在鎖外寫入是下一步候選,須保留一致性與檔案輪替契約。端到端 final 改善不能直接套用 microbenchmark 百分比。
1 調整 hotword decoder 的搜尋成本 greedy/beam 4/beam 8 真實單變因 A/B、功能 fixture、allocation capture 見下方速度與逐筆轉錄;變更 decoder 會影響詞彙 bias,需更廣的準確率資料集。
2 減少 frame 序列化配置 Memray 的 MsgPack/deflate 累積配置 成本已定位,buffer 重用、frame batching 或壓縮策略的收益尚未量測;須維持協定與頻寬契約。
2 修正 GPU memory 觀測 已核對 host PID、NVML 與容器 PID 1 的不一致 先修量測才能評估模型/allocator 記憶體;缺失值應保留 null。
2 管理長 VAD segment 與 debug buffer 的保留上限 真實元件 allocation control、長音訊與正常斷線試驗 TurnSense tail 已有 8 秒上限;ASR segment 隨發話成長。考慮最大發話長度或更小的快照/特徵持有量。log 是條數上限,並非 byte 上限。
2 區分 final 與 EOT policy 等待 final/EOT 兩個 carrier、model decision、2,000 ms wait 使用者感受到的 turn completion 可能主要是 policy 等待。調整門檻或 wait band 必須用標註語料驗證誤截斷,不能用本次短句直接決策。
條件式 final-only 降級 真實 A/B,interim count 為 0 大幅減少 ASR 工作量,但失去即時字幕;final latency 不一定優於保留 incremental stream 的 1 秒組。
先不投入 增加 WebSocket 數量、ITN 微調、盲目調 threads 拓撲重播、階段 trace、4 CPU quota 試驗 依下方實測決定;四條 WS 未帶來穩定改善。ITN 結果僅覆蓋這份沒有數字的固定短句。

實驗身分與可重播性

項目 實際條件
Base fetch 後的 origin/main,完整 SHA 如頁首
Branch research/performance-bottlenecks-20260912
Worktree kitt-stt-research-performance-bottlenecks-20260912,與 branch 使用同一名稱主體
Server image sha256:f51393696ba3b913c73bd6db38ec79fb75393d165eac54827f474a2423d1fece
CPU/RAM Intel i9-13900K,32 logical CPUs/24 cores,128,412 MiB RAM
GPU NVIDIA RTX 4090,24,564 MiB,driver 580.173.02
Server Python 3.10.19;client Python 3.10.12
Runtime vendored sherpa-onnx 1.13.0+cuda;ORT 1.23.2;kitt-core 0.3.7;Pipecat 0.0.108
Models SenseVoice kitt-wake-lora-v2 FP32;TurnSense 1.1 FP32;model/config/audio hashes 見 evidence manifest
Baseline CUDA、preload singleton、interim 約 0.5 秒起始/下限、tracing true/10 秒 flush/600 秒 retention
Decoder hotwords 有 9 條實際詞條,modified_beam_search、max_active_paths=8;不是空 hotword 的 greedy no-op
Production 範圍 source 與預設設定維持 main;實驗 override 與 runtime wrappers 只存在隔離容器

ASR provider API 本身未提供 active-provider accessor。本次 native sample 在同一條 decode_stream → _sherpa_onnx → ONNX Runtime 堆疊中實際觀測到 CUDA provider/CUDA driver;因此可以確認 ASR 執行了 CUDA 路徑,但不能說所有 operator 都在 GPU。TurnSense 額外保存 session.get_providers(),並有啟動時 CUDA assertion。這比只看 available_providers 或模型設定更強;它仍不是 GPU kernel 計時。

所有音訊以 repository 的 tests/functional/audios/say-open-door.wav 為來源,重複其真實 PCM 並裁成 1/3/6/15/30/60 秒;沒有呼叫 TTS 或使用 generator 的 BASE_TEXT。這是固定「打開車門」內容的延遲負載,並非多語言或辨識準確率資料集。來源 WAV、每個 clip 的長度與 SHA-256 都有保存。另有中文/英文 wake 的既有 fixture 小型功能對照,與延遲負載分開。

測試重用 repository 的 RemoteFrameProcessor、真實 WebSocket、VAD frames 與 collector。每回合先送 2 秒靜音 preroll,再按絕對 20 ms deadline 送 PCM。標準組為每種長度 3 個同步回合、每回合 4 席;每長度的 12 筆席位結果共享模型,不能當成 12 次獨立試驗。warmup 有獨立欄位並排除於延遲表;raw rows 仍保留。所有 p95 都只是這些樣本的描述,不是 SLO 或 production p95 估計。

重播的 status=ok 只表示收到預期 final 與 EOT commit、沒有重複/跨回合污染,且 pacing 合格。reason=timeout 另外保存,不能因此稱為 Smart Turn 品質測試通過;本次沒有做完整 EOT 分類評分。

速度 A/B

新程序/四席條件 3s median ms 15s median ms 30s median ms 30s max ms
baseline/原 tracing 86.59 217.94 529.54 866.53
trace-off A/0.5s 72.39 305.45 539.60 762.75
trace-off B/0.5s 90.47 298.04 487.82 674.97
trace-off/1.0s 81.06 162.63 301.48 487.02
trace-off/final-only 75.81 247.94 413.33 645.87
compact tracing/0.5s 78.31 304.99 538.75 905.75
trace-off/greedy 52.09 79.08 109.97 172.25
trace-off/beam 4 68.53 144.70 237.65 396.37
trace-off/4 CPU quota 73.78 250.72 520.91 732.45
image/svg+xml Matplotlib v3.10.9, https://matplotlib.org/ Control A Repeat B 1.0s Final 0 100 200 300 400 500 600 700 800 VAD-stop to segment final (ms) 72 90 81 76 3s audio · n=12 seat-turns Control A Repeat B 1.0s Final 305 298 163 248 15s audio · n=12 seat-turns Control A Repeat B 1.0s Final 540 488 301 413 30s audio · n=12 seat-turns Clean WebSocket trials · median bars, min–max whiskers 0.5s / control A 0.5s / repeat B 1.0s interim Final only
兩個 0.5 秒對照程序,以及 1 秒與 final-only 的單變因比較。三種長度各 3 回合 × 4 席;誤差線是 min–max。

client_final_latency_ms 從 client 排入 VAD-stop 起算,到 segment final 到達;它含傳輸與 pipeline 等待。server_latency_ms 是 ASR 階段的既有指標,沒有涵蓋該 callback 開始前的等待,也不能當成完整 final latency。eot_latency_ms 則等到帶 metadata.eot.decision 的 commit,涵蓋 final-transcription carrier 或明確 stop carrier。

「累計 ASR path」包含 interim/final 各次 inference 的 latency 與 recognizer queue;多席位等待會重疊。它是工作量/排隊壓力的指標,不能加總成 GPU kernel time 或直接當 CPU 使用率。

條件 30s interim 次數 median 30s 累計 ASR path ms median CPU seconds/完整重播含 warmup
baseline/原 tracing 57.00 8,560.94 81.94
trace-off A/0.5s 59.00 8,611.23
trace-off B/0.5s 59.00 8,447.21 75.26
trace-off/1.0s 30.00 4,803.60 46.65
trace-off/final-only 0.00 142.47 17.18
compact tracing/0.5s 58.00 8,057.60 80.22
trace-off/greedy 59.00 3,421.89 40.89
trace-off/beam 4 59.00 6,903.83 59.59
trace-off/4 CPU quota 59.00 9,239.44 74.73
早期探索/已暖機程序 3s median 15s median 30s median 30s max
baseline-1seat 38.67 78.36 124.01 135.58
baseline-4seat 76.47 226.36 406.89 715.81
baseline-4ws 82.81 212.85 473.17 1,307.01

4 WS 各 1 席使用同步 barrier;其 clock skew 與 pacing 在 raw rows 中保留。這組是共用已暖機程序的拓撲探索,不能直接和上方新程序 A/B 合併。沒有看到穩定改善,因此不建議把多開 WS 當成已證明的優化。

Hotwords/beam search 與功能代價

trace-off/decoder 30s final median ms CPU seconds(含 warmup)
beam 8 487.82 75.26
beam 4 237.65 59.59
greedy/無 hotword bias 109.97 40.89

以全新服務只改 hotwords enable 或 beam paths,cadence 與 tracing 不變。關掉 hotwords 同時切換成 greedy search;這不是只略過一個字串表。因此效能差距是整個 decoding policy 的差異,需要一起評估專有詞、英文 wake、同音字與誤喚醒/漏喚醒。下表重用既有三種 fixture 的 _run,每種每設定 5 次,保存每筆 finals/TTS/errors;通過條件是精確 normalized final、無 error,active case 另要求 TTS。這個固定小 corpus 不能證明整體辨識品質不變。

條件 現有 fixture 行為 精確通過/重播 normalized final
beam4 wake_immediate 5/5 打開後車廂
beam4 wake_english 5/5 打開車窗
beam4 active_wake_filter 5/5 打開後車廂
hotwords-off wake_immediate 5/5 打開後車廂
hotwords-off wake_english 5/5 打開車窗
hotwords-off active_wake_filter 5/5 打開後車廂
interim-1s wake_immediate 5/5 打開後車廂
interim-1s wake_english 5/5 打開車窗
interim-1s active_wake_filter 5/5 打開後車廂
trace-off wake_immediate 5/5 打開後車廂
trace-off wake_english 5/5 打開車窗
trace-off active_wake_filter 5/5 打開後車廂

baseline 功能結果 · greedy · beam 4 · 1 秒 interim;不是原本 15 repeats、90% threshold 的完整 live pytest suite。

Frame timeline 與原生 flamegraph

image/svg+xml Matplotlib v3.10.9, https://matplotlib.org/ 0 100 200 300 400 500 600 700 Milliseconds after client queues VAD stop · diamond = received final front_left front_right rear_left rear_right Last 30s round · 1 WebSocket / 4 seats · timing supplement, no py-spy VAD callback ASR prep ASR lock wait ASR decode ITN TurnSense path TS features TS ONNX
輕量 supplement、沒有 native sampling:最後一回合 30 秒音訊的四席 final critical path。

整合 Perfetto trace:ASR/TurnSense/client/memory · 整合 SQL · 實際查詢結果。所有時間按原始 monotonic origins 對齊;保留 warmup,memory 排除 shutdown。可載入 Perfetto UI,或交給官方 TraceProcessor API 分析。

這張圖對齊 client 的 monotonic clock 與兩份 tracer origin。四席同一條 WS 的 VAD-stop callback 依序處理,之後每席的 ASR 與 TurnSense 可在自身 callback 內並行。後面席位在 callback 開始前的等待不會出現在該席的 rec_lock_wait(final),因此不能只找最大 decode span。

Span/phase(包含 warmup) n median ms p95 ms max ms sum ms
prep/interim 1135 2.66 7.65 99.79 3,632.83
rec_lock_wait/interim 1135 54.73 181.05 718.05 71,763.20
decode/interim 1135 45.02 104.05 131.01 57,656.15
prep/final 40 1.60 4.48 31.61 95.49
rec_lock_wait/final 40 0.00 163.34 232.33 753.94
decode/final 40 56.32 112.50 117.91 2,422.47
itn/final 40 0.19 0.29 0.31 7.77
seg_lock_wait/interim 1136 0.00 0.01 326.94 330.86
turnsense.frontend.prepare 40 0.00 0.01 0.20 0.33
turnsense.frontend.extract 40 6.19 11.12 18.50 255.17
turnsense.native_onnx 40 13.37 17.93 22.40 546.76
turnsense.path 40 21.31 28.54 37.11 831.73

ASR 的 preprec_lock_waitdecodepostitnseg_lock_wait 用 Perfetto SQL 與 raw JSON 逐組核對 count/sum。TurnSense supplement 分出 waveform prepare、feature extraction、native ONNX 與整體 path;剩餘差值仍可能包含排程與 semaphore 等待,不強行分配成某個原因。既有 final_tm_break.itn_ms=0 欄位不能替代真實 itn span。

Recorded stack weights · consecutive anonymous native frames collapsed by moduleAll sampled threads 163.93 thread-sample seconds · 100.00% of sampled weightAll sampled threadsThread 164 "asyncio_0" 61.39 thread-sample seconds · 37.45% of sampled weightThread 164 "asyncio_0"clone · libc.so.6 61.39 thread-sample seconds · 37.45% of sampled weightclone · libc.so.6native: libc.so.6 61.39 thread-sample seconds · 37.45% of sampled weightnative: libc.so.6_bootstrap · threading.py:973 61.39 thread-sample seconds · 37.45% of sampled weight_bootstrap · threading.py:973_bootstrap_inner · threading.py:1016 61.39 thread-sample seconds · 37.45% of sampled weight_bootstrap_inner · threading.py:1016run · threading.py:953 61.39 thread-sample seconds · 37.45% of sampled weightrun · threading.py:953_worker · thread.py:83 58.78 thread-sample seconds · 35.86% of sampled weight_worker · thread.py:83run · thread.py:58 58.73 thread-sample seconds · 35.83% of sampled weightrun · thread.py:58_sync_decode_prepared · batch_asr_manager.py:255 57.40 thread-sample seconds · 35.01% of sampled weight_sync_decode_prepared · batch_asr_manager.py:255decode_stream · offline_recognizer.py:1826 57.39 thread-sample seconds · 35.01% of sampled weightdecode_stream · offline_recognizer.py:1826native: _sherpa_onnx.cpython-310-x86_64-linux-gnu.so 57.39 thread-sample seconds · 35.01% of sampled weightnative: _sherpa_onnx.cpython-310-x86_64-linux-gnu.sonative: libonnxruntime.so.1.23.2 25.46 thread-sample seconds · 15.53% of sampled weightnative: libonnxruntime.so.1.23native: libonnxruntime_providers_cuda.so 22.23 thread-sample seconds · 13.56% of sampled weightnative: libonnxruntime_procudnnBackendGetAttribute · libcudnn_graph.so.9 7.19 thread-sample seconds · 4.39% of sampled weightcudnnBacudnn::backend::EngineHeuristics::get_internal · libcudnn_graph.so.9 7.05 thread-sample seconds · 4.30% of sampled weightcudnn::cudnn::backend::EngcfgTmpVar::Results::emplace_back_on_success · libcudnn_graph.so.9 6.56 thread-sample seconds · 4.00% of sampled weightcudnn::cudnn::backend::EngineConfig::finalize_internal · libcudnn_graph.so.9 6.03 thread-sample seconds · 3.68% of sampled weightcudnn:cudnn::backend::Descriptor::finalize · libcudnn_graph.so.9 5.41 thread-sample seconds · 3.30% of sampled weightcudnncudnn::backend::Engine::finalize_internal · libcudnn_graph.so.9 5.40 thread-sample seconds · 3.29% of sampled weightcudnnnative: libcudnn_engines_precompiled.so.9 5.17 thread-sample seconds · 3.15% of sampled weightnativ__dynamic_cast · libstdc++.so.6.0.30 0.88 thread-sample seconds · 0.54% of sampled weight__cxxabiv1::__vmi_class_type_info::__do_dyncast · libstdc++.so.6.0.30 0.75 thread-sample seconds · 0.46% of sampled weight__cxxabiv1::__si_class_type_info::__do_dyncast · libstdc++.so.6.0.30 0.27 thread-sample seconds · 0.16% of sampled weightcudnn::cnn::GenericConvolution::init · libcudnn_graph.so.9 0.65 thread-sample seconds · 0.40% of sampled weightnative: libcudnn_graph.so.9 0.53 thread-sample seconds · 0.32% of sampled weightcudnn::cnn::EngineInterface::isSupported · libcudnn_graph.so.9 0.47 thread-sample seconds · 0.29% of sampled weightnative: libcudnn_engines_precompiled.so.9 0.47 thread-sample seconds · 0.29% of sampled weightcudnn::backend::EngineConfig::to_json_str[abi:cxx11] · libcudnn_graph.so.9 0.33 thread-sample seconds · 0.20% of sampled weightnative: onnxruntime_pybind11_state.cpython-310-x86_64-linux-gnu.so 3.29 thread-sample seconds · 2.01% of sampled weightnative: libonnxruntime_providers_cuda.so 1.99 thread-sample seconds · 1.21% of sampled weightcudaMemcpyAsync · libcudart.so.12 1.98 thread-sample seconds · 1.21% of sampled weightnative: libcudart.so.12 1.98 thread-sample seconds · 1.21% of sampled weightcuMemcpyDtoHAsync_v2 · libcuda.so.580.173.02 1.98 thread-sample seconds · 1.21% of sampled weightnative: libcuda.so.580.173.02 1.98 thread-sample seconds · 1.21% of sampled weightnative: libonnxruntime.so.1.23.2 0.84 thread-sample seconds · 0.51% of sampled weightcudaLaunchKernel · libcudart.so.12 2.73 thread-sample seconds · 1.67% of sampled weightnative: libcudart.so.12 2.73 thread-sample seconds · 1.67% of sampled weightcuLaunchKernel · libcuda.so.580.173.02 2.47 thread-sample seconds · 1.51% of sampled weightnative: libcuda.so.580.173.02 2.47 thread-sample seconds · 1.51% of sampled weightnative: libc.so.6 0.53 thread-sample seconds · 0.32% of sampled weightcublasSgemm_v2 · libcublas.so.12 2.12 thread-sample seconds · 1.29% of sampled weightnative: libcublas.so.12 2.11 thread-sample seconds · 1.29% of sampled weightcublasLtSSSMatmul · libcublasLt.so.12 1.59 thread-sample seconds · 0.97% of sampled weightnative: libcublasLt.so.12 1.59 thread-sample seconds · 0.97% of sampled weightcuLaunchKernel · libcuda.so.580.173.02 0.77 thread-sample seconds · 0.47% of sampled weightnative: libcuda.so.580.173.02 0.77 thread-sample seconds · 0.47% of sampled weightcublasLtSSSMatmulAlgoGetHeuristic · libcublasLt.so.12 0.34 thread-sample seconds · 0.21% of sampled weightnative: libcublasLt.so.12 0.33 thread-sample seconds · 0.20% of sampled weightcudnnBackendCreateDescriptor · libcudnn.so.9 0.78 thread-sample seconds · 0.48% of sampled weightcudnnBackendCreateDescriptor · libcudnn_graph.so.9 0.76 thread-sample seconds · 0.46% of sampled weightnative: libcudnn_graph.so.9 0.33 thread-sample seconds · 0.20% of sampled weightmalloc · libc.so.6 0.27 thread-sample seconds · 0.16% of sampled weightcublasSgemmStridedBatched · libcublas.so.12 0.70 thread-sample seconds · 0.43% of sampled weightnative: libcublas.so.12 0.70 thread-sample seconds · 0.43% of sampled weightcublasLtSSSMatmul · libcublasLt.so.12 0.51 thread-sample seconds · 0.31% of sampled weightnative: libcublasLt.so.12 0.51 thread-sample seconds · 0.31% of sampled weightoperator new · libstdc++.so.6.0.30 0.66 thread-sample seconds · 0.40% of sampled weightmalloc · libc.so.6 0.59 thread-sample seconds · 0.36% of sampled weightnative: libc.so.6 0.31 thread-sample seconds · 0.19% of sampled weightcudnnBackendDestroyDescriptor · libcudnn.so.9 0.55 thread-sample seconds · 0.34% of sampled weightcudnnBackendDestroyDescriptor · libcudnn_graph.so.9 0.52 thread-sample seconds · 0.32% of sampled weightcublasSgeam · libcublas.so.12 0.47 thread-sample seconds · 0.29% of sampled weightnative: libcublas.so.12 0.44 thread-sample seconds · 0.27% of sampled weightcuLaunchKernel · libcuda.so.580.173.02 0.33 thread-sample seconds · 0.20% of sampled weightnative: libcuda.so.580.173.02 0.33 thread-sample seconds · 0.20% of sampled weightcudnnBackendSetAttribute · libcudnn_graph.so.9 0.38 thread-sample seconds · 0.23% of sampled weightcudnnBackendExecute · libcudnn.so.9 0.35 thread-sample seconds · 0.21% of sampled weightcudnnBackendExecute · libcudnn_graph.so.9 0.35 thread-sample seconds · 0.21% of sampled weightcudnn::backend::execute · libcudnn_graph.so.9 0.34 thread-sample seconds · 0.21% of sampled weightcudnn::cnn::EngineInterface::execute · libcudnn_graph.so.9 0.31 thread-sample seconds · 0.19% of sampled weightnative: libcudnn_engines_precompiled.so.9 0.31 thread-sample seconds · 0.19% of sampled weightfree · libc.so.6 0.28 thread-sample seconds · 0.17% of sampled weightnative: libm.so.6 5.73 thread-sample seconds · 3.50% of sampled weightnativoperator new · libstdc++.so.6.0.30 4.46 thread-sample seconds · 2.72% of sampled weightopermalloc · libc.so.6 4.18 thread-sample seconds · 2.55% of sampled weightmallnative: libc.so.6 2.22 thread-sample seconds · 1.35% of sampled weightfree · libc.so.6 2.99 thread-sample seconds · 1.82% of sampled weightnative: libc.so.6 2.60 thread-sample seconds · 1.59% of sampled weightstd::_Rb_tree_insert_and_rebalance · libstdc++.so.6.0.30 0.56 thread-sample seconds · 0.34% of sampled weightnative: libc.so.6 0.37 thread-sample seconds · 0.23% of sampled weightstd::_Rb_tree_increment · libstdc++.so.6.0.30 0.33 thread-sample seconds · 0.20% of sampled weightnative: _sherpa_onnx.cpython-310-x86_64-linux-gnu.so 0.76 thread-sample seconds · 0.46% of sampled weightpthread_cond_timedwait · libc.so.6 0.54 thread-sample seconds · 0.33% of sampled weightnative: libc.so.6 0.54 thread-sample seconds · 0.33% of sampled weightrun_onnx · profile_server.py:155 0.42 thread-sample seconds · 0.26% of sampled weight_timed · profile_server.py:113 0.42 thread-sample seconds · 0.26% of sampled weight_run_onnx · runtime.py:130 0.42 thread-sample seconds · 0.26% of sampled weightrun · onnxruntime_inference_collection.py:287 0.42 thread-sample seconds · 0.26% of sampled weightnative: onnxruntime_pybind11_state.cpython-310-x86_64-linux-gnu.so 0.42 thread-sample seconds · 0.26% of sampled weightnative: libonnxruntime_providers_cuda.so 0.34 thread-sample seconds · 0.21% of sampled weight_worker · thread.py:81 2.60 thread-sample seconds · 1.59% of sampled weightnative: _queue.cpython-310-x86_64-linux-gnu.so 2.60 thread-sample seconds · 1.59% of sampled weightPyThread_acquire_lock_timed · libpython3.10.so.1.0 2.60 thread-sample seconds · 1.59% of sampled weightnative: libc.so.6 2.60 thread-sample seconds · 1.59% of sampled weightThread 165 "asyncio_1" 35.63 thread-sample seconds · 21.73% of sampled weightThread 165 "asyncio_1"clone · libc.so.6 35.63 thread-sample seconds · 21.73% of sampled weightclone · libc.so.6native: libc.so.6 35.63 thread-sample seconds · 21.73% of sampled weightnative: libc.so.6_bootstrap · threading.py:973 35.63 thread-sample seconds · 21.73% of sampled weight_bootstrap · threading.py:973_bootstrap_inner · threading.py:1016 35.63 thread-sample seconds · 21.73% of sampled weight_bootstrap_inner · threading.py:1016run · threading.py:953 35.63 thread-sample seconds · 21.73% of sampled weightrun · threading.py:953_worker · thread.py:83 33.68 thread-sample seconds · 20.55% of sampled weight_worker · thread.py:83run · thread.py:58 33.59 thread-sample seconds · 20.49% of sampled weightrun · thread.py:58_sync_decode_prepared · batch_asr_manager.py:255 32.70 thread-sample seconds · 19.95% of sampled weight_sync_decode_prepared · batch_asr_manadecode_stream · offline_recognizer.py:1826 32.70 thread-sample seconds · 19.95% of sampled weightdecode_stream · offline_recognizer.py:native: _sherpa_onnx.cpython-310-x86_64-linux-gnu.so 32.70 thread-sample seconds · 19.95% of sampled weightnative: _sherpa_onnx.cpython-310-x86_6native: libonnxruntime.so.1.23.2 13.21 thread-sample seconds · 8.06% of sampled weightnative: libonnxnative: libonnxruntime_providers_cuda.so 11.35 thread-sample seconds · 6.92% of sampled weightnative: libocudnnBackendGetAttribute · libcudnn_graph.so.9 3.53 thread-sample seconds · 2.15% of sampled weightcudnn::backend::EngineHeuristics::get_internal · libcudnn_graph.so.9 3.47 thread-sample seconds · 2.12% of sampled weightcudnn::backend::EngcfgTmpVar::Results::emplace_back_on_success · libcudnn_graph.so.9 3.34 thread-sample seconds · 2.04% of sampled weightcudnn::backend::EngineConfig::finalize_internal · libcudnn_graph.so.9 3.17 thread-sample seconds · 1.93% of sampled weightcudnn::backend::Descriptor::finalize · libcudnn_graph.so.9 2.90 thread-sample seconds · 1.77% of sampled weightcudnn::backend::Engine::finalize_internal · libcudnn_graph.so.9 2.89 thread-sample seconds · 1.76% of sampled weightnative: libcudnn_engines_precompiled.so.9 2.73 thread-sample seconds · 1.67% of sampled weight__dynamic_cast · libstdc++.so.6.0.30 0.43 thread-sample seconds · 0.26% of sampled weight__cxxabiv1::__vmi_class_type_info::__do_dyncast · libstdc++.so.6.0.30 0.34 thread-sample seconds · 0.21% of sampled weightcudnn::cnn::GenericConvolution::init · libcudnn_graph.so.9 0.34 thread-sample seconds · 0.21% of sampled weightnative: libcudnn_graph.so.9 0.28 thread-sample seconds · 0.17% of sampled weightnative: onnxruntime_pybind11_state.cpython-310-x86_64-linux-gnu.so 1.87 thread-sample seconds · 1.14% of sampled weightnative: libonnxruntime_providers_cuda.so 1.24 thread-sample seconds · 0.76% of sampled weightcudaMemcpyAsync · libcudart.so.12 1.24 thread-sample seconds · 0.76% of sampled weightnative: libcudart.so.12 1.24 thread-sample seconds · 0.76% of sampled weightcuMemcpyDtoHAsync_v2 · libcuda.so.580.173.02 1.24 thread-sample seconds · 0.76% of sampled weightnative: libcuda.so.580.173.02 1.24 thread-sample seconds · 0.76% of sampled weightnative: libonnxruntime.so.1.23.2 0.51 thread-sample seconds · 0.31% of sampled weightcudaLaunchKernel · libcudart.so.12 1.56 thread-sample seconds · 0.95% of sampled weightnative: libcudart.so.12 1.56 thread-sample seconds · 0.95% of sampled weightcuLaunchKernel · libcuda.so.580.173.02 1.41 thread-sample seconds · 0.86% of sampled weightnative: libcuda.so.580.173.02 1.41 thread-sample seconds · 0.86% of sampled weightcublasSgemm_v2 · libcublas.so.12 0.80 thread-sample seconds · 0.49% of sampled weightnative: libcublas.so.12 0.79 thread-sample seconds · 0.48% of sampled weightcublasLtSSSMatmul · libcublasLt.so.12 0.48 thread-sample seconds · 0.29% of sampled weightnative: libcublasLt.so.12 0.47 thread-sample seconds · 0.29% of sampled weightcudnnBackendCreateDescriptor · libcudnn.so.9 0.40 thread-sample seconds · 0.24% of sampled weightcudnnBackendCreateDescriptor · libcudnn_graph.so.9 0.39 thread-sample seconds · 0.24% of sampled weightcublasSgemmStridedBatched · libcublas.so.12 0.36 thread-sample seconds · 0.22% of sampled weightnative: libcublas.so.12 0.36 thread-sample seconds · 0.22% of sampled weightcublasLtSSSMatmul · libcublasLt.so.12 0.27 thread-sample seconds · 0.16% of sampled weightnative: libcublasLt.so.12 0.27 thread-sample seconds · 0.16% of sampled weightcudnnBackendDestroyDescriptor · libcudnn.so.9 0.34 thread-sample seconds · 0.21% of sampled weightcudnnBackendDestroyDescriptor · libcudnn_graph.so.9 0.33 thread-sample seconds · 0.20% of sampled weightnative: libm.so.6 3.14 thread-sample seconds · 1.92% of sampled weightoperator new · libstdc++.so.6.0.30 2.59 thread-sample seconds · 1.58% of sampled weightmalloc · libc.so.6 2.44 thread-sample seconds · 1.49% of sampled weightnative: libc.so.6 1.24 thread-sample seconds · 0.76% of sampled weightfree · libc.so.6 2.00 thread-sample seconds · 1.22% of sampled weightnative: libc.so.6 1.82 thread-sample seconds · 1.11% of sampled weightstd::_Rb_tree_insert_and_rebalance · libstdc++.so.6.0.30 0.36 thread-sample seconds · 0.22% of sampled weightnative: _sherpa_onnx.cpython-310-x86_64-linux-gnu.so 0.47 thread-sample seconds · 0.29% of sampled weightpthread_cond_timedwait · libc.so.6 0.33 thread-sample seconds · 0.20% of sampled weightnative: libc.so.6 0.33 thread-sample seconds · 0.20% of sampled weight_worker · thread.py:81 1.95 thread-sample seconds · 1.19% of sampled weightnative: _queue.cpython-310-x86_64-linux-gnu.so 1.95 thread-sample seconds · 1.19% of sampled weightPyThread_acquire_lock_timed · libpython3.10.so.1.0 1.95 thread-sample seconds · 1.19% of sampled weightnative: libc.so.6 1.95 thread-sample seconds · 1.19% of sampled weightThread 1 "MainThread" 30.93 thread-sample seconds · 18.87% of sampled weightThread 1 "MainThread"native: libc.so.6 30.89 thread-sample seconds · 18.84% of sampled weightnative: libc.so.6<module> · profile_server.py:400 30.89 thread-sample seconds · 18.84% of sampled weight<module> · profile_server.py:400main · profile_server.py:391 30.89 thread-sample seconds · 18.84% of sampled weightmain · profile_server.py:391run · runners.py:44 30.89 thread-sample seconds · 18.84% of sampled weightrun · runners.py:44run_until_complete · base_events.py:636 30.89 thread-sample seconds · 18.84% of sampled weightrun_until_complete · base_events.py:run_forever · base_events.py:603 30.88 thread-sample seconds · 18.84% of sampled weightrun_forever · base_events.py:603_run_once · base_events.py:1909 30.55 thread-sample seconds · 18.64% of sampled weight_run_once · base_events.py:1909_run · events.py:80 30.34 thread-sample seconds · 18.51% of sampled weight_run · events.py:80native: _asyncio.cpython-310-x86_64-linux-gnu.so 28.30 thread-sample seconds · 17.26% of sampled weightnative: _asyncio.cpython-310-x86_run_coroutine · task_manager.py:160 25.82 thread-sample seconds · 15.75% of sampled weightrun_coroutine · task_manager.p__input_frame_task_handler · frame_processor.py:1054 22.74 thread-sample seconds · 13.87% of sampled weight__input_frame_task_handler__process_frame · frame_processor.py:1027 22.53 thread-sample seconds · 13.74% of sampled weight__process_frame · frame_prprocess_frame · kitt_stt_service.py:1093 17.68 thread-sample seconds · 10.79% of sampled weightprocess_frame · kittprocess_frame · stt_service.py:386 12.49 thread-sample seconds · 7.62% of sampled weightprocess_frame push_frame · stt_service.py:446 12.40 thread-sample seconds · 7.56% of sampled weightpush_frame · spush_frame · frame_processor.py:759 12.12 thread-sample seconds · 7.39% of sampled weightpush_frame · __internal_push_frame · frame_processor.py:930 11.27 thread-sample seconds · 6.87% of sampled weight__internal_pqueue_frame · frame_processor.py:630 11.23 thread-sample seconds · 6.85% of sampled weightqueue_frame __process_frame · frame_processor.py:1027 10.96 thread-sample seconds · 6.69% of sampled weight__process_frprocess_frame · frame_processor_server.py:58 7.66 thread-sample seconds · 4.67% of sampled weightprocess_send · connection.py:487 4.11 thread-sample seconds · 2.51% of sampled weightsendsend_binary · protocol.py:359 4.07 thread-sample seconds · 2.48% of sampled weightsensend_frame · protocol.py:747 3.84 thread-sample seconds · 2.34% of sampled weightsenserialize · frames.py:299 3.14 thread-sample seconds · 1.92% of sampled weightencode · permessage_deflate.py:185 2.68 thread-sample seconds · 1.63% of sampled weightnative: zlib.cpython-310-x86_64-linux-gnu.so 2.62 thread-sample seconds · 1.60% of sampled weightdeflate · libz.so.1.2.13 1.94 thread-sample seconds · 1.18% of sampled weightnative: libz.so.1.2.13 1.91 thread-sample seconds · 1.17% of sampled weightpthread_cond_timedwait · libc.so.6 0.48 thread-sample seconds · 0.29% of sampled weightnative: libc.so.6 0.48 thread-sample seconds · 0.29% of sampled weightsend · connection.py:483 3.15 thread-sample seconds · 1.92% of sampled weight__aexit__ · contextlib.py:206 2.41 thread-sample seconds · 1.47% of sampled weightsend_context · connection.py:915 2.06 thread-sample seconds · 1.26% of sampled weightsend_data · connection.py:969 1.82 thread-sample seconds · 1.11% of sampled weightwrite · selector_events.py:924 1.66 thread-sample seconds · 1.01% of sampled weightnative: _socket.cpython-310-x86_64-linux-gnu.so 1.61 thread-sample seconds · 0.98% of sampled weightsend · libc.so.6 1.50 thread-sample seconds · 0.92% of sampled weightprocess_frame · frame_processor_server.py:52 2.90 thread-sample seconds · 1.77% of sampled weightserialize · msgpack_frame_serializer.py:129 1.72 thread-sample seconds · 1.05% of sampled weight<dictcomp> · msgpack_frame_serializer.py:131 1.51 thread-sample seconds · 0.92% of sampled weightserialize · msgpack_frame_serializer.py:133 0.55 thread-sample seconds · 0.34% of sampled weightpackb · __init__.py:36 0.50 thread-sample seconds · 0.31% of sampled weightpack · _cmsgpack.c:8510 0.37 thread-sample seconds · 0.23% of sampled weightpack · _cmsgpack.c:8576 0.31 thread-sample seconds · 0.19% of sampled weightPacker__pack · _cmsgpack.c:8316 0.31 thread-sample seconds · 0.19% of sampled weightserialize · msgpack_frame_serializer.py:131 0.43 thread-sample seconds · 0.26% of sampled weightfields · dataclasses.py:1202 0.31 thread-sample seconds · 0.19% of sampled weightprocess_frame · frame_processor_server.py:46 0.31 thread-sample seconds · 0.19% of sampled weight__internal_push_frame · frame_processor.py:919 0.74 thread-sample seconds · 0.45% of sampled weight__str__ · frames.py:1623 0.26 thread-sample seconds · 0.16% of sampled weightprocess_frame · stt_service.py:384 4.58 thread-sample seconds · 2.79% of sampled weightprocprocess_audio_frame · stt_service.py:362 4.45 thread-sample seconds · 2.71% of sampled weightprocprocess_generator · ai_service.py:212 4.23 thread-sample seconds · 2.58% of sampled weightprocrun_stt · kitt_stt_service.py:528 2.65 thread-sample seconds · 1.62% of sampled weight<genexpr> · kitt_stt_service.py:528 2.33 thread-sample seconds · 1.42% of sampled weightrun_stt · kitt_stt_service.py:550 0.36 thread-sample seconds · 0.22% of sampled weightrun_stt · kitt_stt_service.py:536 0.28 thread-sample seconds · 0.17% of sampled weightprocess_frame · stt_service.py:371 0.32 thread-sample seconds · 0.20% of sampled weightprocess_frame · kitt_stt_service.py:1101 2.10 thread-sample seconds · 1.28% of sampled weightprocess_frame · kitt_stt_service.py:1099 0.80 thread-sample seconds · 0.49% of sampled weightprocess_frame · kitt_stt_service.py:1103 0.43 thread-sample seconds · 0.26% of sampled weightprocess_frame · kitt_stt_service.py:1102 0.30 thread-sample seconds · 0.18% of sampled weight_interim_redecode_body · kitt_stt_service.py:1326 0.77 thread-sample seconds · 0.47% of sampled weightrun_interim_inference_incremental · batch_asr_manager.py:364 0.37 thread-sample seconds · 0.23% of sampled weights2t · text_normalizer.py:527 0.37 thread-sample seconds · 0.23% of sampled weight_to_traditional · text_normalizer.py:116 0.25 thread-sample seconds · 0.15% of sampled weight_get_converter · text_normalizer.py:96 0.25 thread-sample seconds · 0.15% of sampled weightnative: opencc_clib.cpython-310-x86_64-linux-gnu.so 0.25 thread-sample seconds · 0.15% of sampled weight__init__ · __init__.py:44 0.25 thread-sample seconds · 0.15% of sampled weightnative: opencc_clib.cpython-310-x86_64-linux-gnu.so 0.25 thread-sample seconds · 0.15% of sampled weightopencc::SimpleConverter::SimpleConverter · opencc_clib.cpython-310-x86_64-linux-gnu.so 0.25 thread-sample seconds · 0.15% of sampled weightopencc::Config::NewFromFile · opencc_clib.cpython-310-x86_64-linux-gnu.so 0.25 thread-sample seconds · 0.15% of sampled weightopencc::Config::NewFromString · opencc_clib.cpython-310-x86_64-linux-gnu.so 0.25 thread-sample seconds · 0.15% of sampled weightnative: opencc_clib.cpython-310-x86_64-linux-gnu.so 0.25 thread-sample seconds · 0.15% of sampled weightopencc::MarisaDict::NewFromFile · opencc_clib.cpython-310-x86_64-linux-gnu.so 0.25 thread-sample seconds · 0.15% of sampled weight_interim_redecode_body · kitt_stt_service.py:1318 0.68 thread-sample seconds · 0.41% of sampled weightarray_true_divide · _multiarray_umath.cpython-310-x86_64-linux-gnu.so 0.34 thread-sample seconds · 0.21% of sampled weightufunc_generic_fastcall · _multiarray_umath.cpython-310-x86_64-linux-gnu.so 0.33 thread-sample seconds · 0.20% of sampled weighttry_trivial_single_output_loop · _multiarray_umath.cpython-310-x86_64-linux-gnu.so 0.26 thread-sample seconds · 0.16% of sampled weightarray_astype · _multiarray_umath.cpython-310-x86_64-linux-gnu.so 0.27 thread-sample seconds · 0.16% of sampled weight__input_frame_task_handler · frame_processor.py:1044 0.57 thread-sample seconds · 0.35% of sampled weightget · frame_processor.py:132 0.44 thread-sample seconds · 0.27% of sampled weight_interim_redecode_body · kitt_stt_service.py:1311 0.30 thread-sample seconds · 0.18% of sampled weightconn_handler · server.py:376 1.89 thread-sample seconds · 1.15% of sampled weight_handle_connection · html_server.py:156 1.88 thread-sample seconds · 1.15% of sampled weight_handle_connection · frame_processor_server.py:161 1.15 thread-sample seconds · 0.70% of sampled weightdeserialize · msgpack_frame_serializer.py:145 0.64 thread-sample seconds · 0.39% of sampled weight_construct_dataclass · msgpack_frame_serializer.py:60 0.26 thread-sample seconds · 0.16% of sampled weight_handle_connection · frame_processor_server.py:159 0.28 thread-sample seconds · 0.17% of sampled weightrecv · connection.py:303 0.25 thread-sample seconds · 0.15% of sampled weight_handle_connection · frame_processor_server.py:169 0.26 thread-sample seconds · 0.16% of sampled weight_read_ready · selector_events.py:819 1.88 thread-sample seconds · 1.15% of sampled weight_read_ready__data_received · selector_events.py:876 0.99 thread-sample seconds · 0.60% of sampled weightdata_received · connection.py:1076 0.78 thread-sample seconds · 0.48% of sampled weightreceive_data · protocol.py:268 0.77 thread-sample seconds · 0.47% of sampled weightparse · server.py:565 0.76 thread-sample seconds · 0.46% of sampled weightparse · protocol.py:591 0.73 thread-sample seconds · 0.45% of sampled weightparse · frames.py:272 0.38 thread-sample seconds · 0.23% of sampled weight_read_ready__data_received · selector_events.py:862 0.88 thread-sample seconds · 0.54% of sampled weightnative: _socket.cpython-310-x86_64-linux-gnu.so 0.87 thread-sample seconds · 0.53% of sampled weightpthread_cond_timedwait · libc.so.6 0.84 thread-sample seconds · 0.51% of sampled weightnative: libc.so.6 0.84 thread-sample seconds · 0.51% of sampled weightThread 166 "asyncio_2" 13.68 thread-sample seconds · 8.35% of sampled weightThread 166 "asyclone · libc.so.6 13.68 thread-sample seconds · 8.35% of sampled weightclone · libc.sonative: libc.so.6 13.68 thread-sample seconds · 8.35% of sampled weightnative: libc.so_bootstrap · threading.py:973 13.68 thread-sample seconds · 8.35% of sampled weight_bootstrap · th_bootstrap_inner · threading.py:1016 13.68 thread-sample seconds · 8.35% of sampled weight_bootstrap_innerun · threading.py:953 13.68 thread-sample seconds · 8.35% of sampled weightrun · threading_worker · thread.py:83 12.89 thread-sample seconds · 7.86% of sampled weight_worker · threrun · thread.py:58 12.88 thread-sample seconds · 7.86% of sampled weightrun · thread.p_sync_decode_prepared · batch_asr_manager.py:255 12.24 thread-sample seconds · 7.47% of sampled weight_sync_decode_decode_stream · offline_recognizer.py:1826 12.24 thread-sample seconds · 7.47% of sampled weightdecode_streamnative: _sherpa_onnx.cpython-310-x86_64-linux-gnu.so 12.24 thread-sample seconds · 7.47% of sampled weightnative: _shernative: libonnxruntime.so.1.23.2 4.95 thread-sample seconds · 3.02% of sampled weightnativnative: libonnxruntime_providers_cuda.so 4.46 thread-sample seconds · 2.72% of sampled weightnaticudnnBackendGetAttribute · libcudnn_graph.so.9 1.47 thread-sample seconds · 0.90% of sampled weightcudnn::backend::EngineHeuristics::get_internal · libcudnn_graph.so.9 1.45 thread-sample seconds · 0.88% of sampled weightcudnn::backend::EngcfgTmpVar::Results::emplace_back_on_success · libcudnn_graph.so.9 1.33 thread-sample seconds · 0.81% of sampled weightcudnn::backend::EngineConfig::finalize_internal · libcudnn_graph.so.9 1.25 thread-sample seconds · 0.76% of sampled weightcudnn::backend::Descriptor::finalize · libcudnn_graph.so.9 1.11 thread-sample seconds · 0.68% of sampled weightcudnn::backend::Engine::finalize_internal · libcudnn_graph.so.9 1.11 thread-sample seconds · 0.68% of sampled weightnative: libcudnn_engines_precompiled.so.9 1.07 thread-sample seconds · 0.65% of sampled weight__dynamic_cast · libstdc++.so.6.0.30 0.25 thread-sample seconds · 0.15% of sampled weightnative: onnxruntime_pybind11_state.cpython-310-x86_64-linux-gnu.so 0.60 thread-sample seconds · 0.37% of sampled weightnative: libonnxruntime_providers_cuda.so 0.45 thread-sample seconds · 0.27% of sampled weightcudaMemcpyAsync · libcudart.so.12 0.45 thread-sample seconds · 0.27% of sampled weightnative: libcudart.so.12 0.45 thread-sample seconds · 0.27% of sampled weightcuMemcpyDtoHAsync_v2 · libcuda.so.580.173.02 0.45 thread-sample seconds · 0.27% of sampled weightnative: libcuda.so.580.173.02 0.45 thread-sample seconds · 0.27% of sampled weightcudaLaunchKernel · libcudart.so.12 0.57 thread-sample seconds · 0.35% of sampled weightnative: libcudart.so.12 0.56 thread-sample seconds · 0.34% of sampled weightcuLaunchKernel · libcuda.so.580.173.02 0.46 thread-sample seconds · 0.28% of sampled weightnative: libcuda.so.580.173.02 0.46 thread-sample seconds · 0.28% of sampled weightcublasSgemm_v2 · libcublas.so.12 0.29 thread-sample seconds · 0.18% of sampled weightnative: libcublas.so.12 0.28 thread-sample seconds · 0.17% of sampled weightnative: libm.so.6 1.37 thread-sample seconds · 0.84% of sampled weightoperator new · libstdc++.so.6.0.30 0.87 thread-sample seconds · 0.53% of sampled weightmalloc · libc.so.6 0.81 thread-sample seconds · 0.49% of sampled weightnative: libc.so.6 0.42 thread-sample seconds · 0.26% of sampled weightfree · libc.so.6 0.74 thread-sample seconds · 0.45% of sampled weightnative: libc.so.6 0.62 thread-sample seconds · 0.38% of sampled weightrun_onnx · profile_server.py:155 0.35 thread-sample seconds · 0.21% of sampled weight_timed · profile_server.py:113 0.35 thread-sample seconds · 0.21% of sampled weight_run_onnx · runtime.py:130 0.35 thread-sample seconds · 0.21% of sampled weightrun · onnxruntime_inference_collection.py:287 0.35 thread-sample seconds · 0.21% of sampled weightnative: onnxruntime_pybind11_state.cpython-310-x86_64-linux-gnu.so 0.35 thread-sample seconds · 0.21% of sampled weightnative: libonnxruntime_providers_cuda.so 0.30 thread-sample seconds · 0.18% of sampled weight_worker · thread.py:81 0.79 thread-sample seconds · 0.48% of sampled weightnative: _queue.cpython-310-x86_64-linux-gnu.so 0.79 thread-sample seconds · 0.48% of sampled weightPyThread_acquire_lock_timed · libpython3.10.so.1.0 0.79 thread-sample seconds · 0.48% of sampled weightnative: libc.so.6 0.79 thread-sample seconds · 0.48% of sampled weightThread 167 "asyncio_3" 11.22 thread-sample seconds · 6.84% of sampled weightThread 167 "clone · libc.so.6 11.22 thread-sample seconds · 6.84% of sampled weightclone · libcnative: libc.so.6 11.22 thread-sample seconds · 6.84% of sampled weightnative: libc_bootstrap · threading.py:973 11.22 thread-sample seconds · 6.84% of sampled weight_bootstrap ·_bootstrap_inner · threading.py:1016 11.22 thread-sample seconds · 6.84% of sampled weight_bootstrap_irun · threading.py:953 11.22 thread-sample seconds · 6.84% of sampled weightrun · thread_worker · thread.py:83 10.69 thread-sample seconds · 6.52% of sampled weight_worker · thrun · thread.py:58 10.69 thread-sample seconds · 6.52% of sampled weightrun · thread_sync_decode_prepared · batch_asr_manager.py:255 10.45 thread-sample seconds · 6.37% of sampled weight_sync_decoddecode_stream · offline_recognizer.py:1826 10.45 thread-sample seconds · 6.37% of sampled weightdecode_strenative: _sherpa_onnx.cpython-310-x86_64-linux-gnu.so 10.45 thread-sample seconds · 6.37% of sampled weightnative: _shnative: libonnxruntime.so.1.23.2 4.06 thread-sample seconds · 2.48% of sampled weightnatnative: libonnxruntime_providers_cuda.so 3.70 thread-sample seconds · 2.26% of sampled weightcudnnBackendGetAttribute · libcudnn_graph.so.9 1.06 thread-sample seconds · 0.65% of sampled weightcudnn::backend::EngineHeuristics::get_internal · libcudnn_graph.so.9 1.04 thread-sample seconds · 0.63% of sampled weightcudnn::backend::EngcfgTmpVar::Results::emplace_back_on_success · libcudnn_graph.so.9 0.97 thread-sample seconds · 0.59% of sampled weightcudnn::backend::EngineConfig::finalize_internal · libcudnn_graph.so.9 0.88 thread-sample seconds · 0.54% of sampled weightcudnn::backend::Descriptor::finalize · libcudnn_graph.so.9 0.79 thread-sample seconds · 0.48% of sampled weightcudnn::backend::Engine::finalize_internal · libcudnn_graph.so.9 0.79 thread-sample seconds · 0.48% of sampled weightnative: libcudnn_engines_precompiled.so.9 0.75 thread-sample seconds · 0.46% of sampled weightnative: onnxruntime_pybind11_state.cpython-310-x86_64-linux-gnu.so 0.69 thread-sample seconds · 0.42% of sampled weightnative: libonnxruntime_providers_cuda.so 0.41 thread-sample seconds · 0.25% of sampled weightcudaMemcpyAsync · libcudart.so.12 0.41 thread-sample seconds · 0.25% of sampled weightnative: libcudart.so.12 0.41 thread-sample seconds · 0.25% of sampled weightcuMemcpyDtoHAsync_v2 · libcuda.so.580.173.02 0.41 thread-sample seconds · 0.25% of sampled weightnative: libcuda.so.580.173.02 0.41 thread-sample seconds · 0.25% of sampled weightcudaLaunchKernel · libcudart.so.12 0.46 thread-sample seconds · 0.28% of sampled weightnative: libcudart.so.12 0.46 thread-sample seconds · 0.28% of sampled weightcuLaunchKernel · libcuda.so.580.173.02 0.38 thread-sample seconds · 0.23% of sampled weightnative: libcuda.so.580.173.02 0.38 thread-sample seconds · 0.23% of sampled weightcublasSgemm_v2 · libcublas.so.12 0.32 thread-sample seconds · 0.20% of sampled weightnative: libcublas.so.12 0.32 thread-sample seconds · 0.20% of sampled weightnative: libm.so.6 1.07 thread-sample seconds · 0.65% of sampled weightoperator new · libstdc++.so.6.0.30 0.84 thread-sample seconds · 0.51% of sampled weightmalloc · libc.so.6 0.81 thread-sample seconds · 0.49% of sampled weightnative: libc.so.6 0.34 thread-sample seconds · 0.21% of sampled weightfree · libc.so.6 0.62 thread-sample seconds · 0.38% of sampled weightnative: libc.so.6 0.54 thread-sample seconds · 0.33% of sampled weight_worker · thread.py:81 0.53 thread-sample seconds · 0.32% of sampled weightnative: _queue.cpython-310-x86_64-linux-gnu.so 0.53 thread-sample seconds · 0.32% of sampled weightPyThread_acquire_lock_timed · libpython3.10.so.1.0 0.52 thread-sample seconds · 0.32% of sampled weightnative: libc.so.6 0.52 thread-sample seconds · 0.32% of sampled weightThread 119 "Thread-1 (_periodic_flush)" 10.91 thread-sample seconds · 6.66% of sampled weightThread 119 "clone · libc.so.6 10.91 thread-sample seconds · 6.66% of sampled weightclone · libcnative: libc.so.6 10.91 thread-sample seconds · 6.66% of sampled weightnative: libc_bootstrap · threading.py:973 10.91 thread-sample seconds · 6.66% of sampled weight_bootstrap ·_bootstrap_inner · threading.py:1016 10.91 thread-sample seconds · 6.66% of sampled weight_bootstrap_irun · threading.py:953 10.91 thread-sample seconds · 6.66% of sampled weightrun · thread_periodic_flush · perfetto_trace.py:527 10.90 thread-sample seconds · 6.65% of sampled weight_periodic_flflush · perfetto_trace.py:577 10.90 thread-sample seconds · 6.65% of sampled weightflush · perfflush · profile_server.py:186 10.90 thread-sample seconds · 6.65% of sampled weightflush · profwrite_trace · perfetto_trace.py:360 6.76 thread-sample seconds · 4.12% of sampled weightwrite_tdumps · __init__.py:238 6.76 thread-sample seconds · 4.12% of sampled weightdumps ·encode · encoder.py:201 6.32 thread-sample seconds · 3.86% of sampled weightencode_iterencode · encoder.py:431 5.83 thread-sample seconds · 3.56% of sampled weight_itere_iterencode_dict · encoder.py:405 5.07 thread-sample seconds · 3.09% of sampled weight_iter_iterencode_list · encoder.py:325 4.32 thread-sample seconds · 2.64% of sampled weight_ite_iterencode_dict · encoder.py:405 2.07 thread-sample seconds · 1.26% of sampled weight_iterencode_dict · encoder.py:382 0.34 thread-sample seconds · 0.21% of sampled weight_iterencode_dict · encoder.py:382 0.29 thread-sample seconds · 0.18% of sampled weightencode · encoder.py:202 0.29 thread-sample seconds · 0.18% of sampled weightwrite_trace · perfetto_trace.py:367 3.89 thread-sample seconds · 2.37% of sampled weightwriwrite · gzip.py:289 3.82 thread-sample seconds · 2.33% of sampled weightnative: zlib.cpython-310-x86_64-linux-gnu.so 3.81 thread-sample seconds · 2.32% of sampled weightdeflate · libz.so.1.2.13 3.80 thread-sample seconds · 2.32% of sampled weightnative: libz.so.1.2.13 3.80 thread-sample seconds · 2.32% of sampled weight
180 秒 py-spy native profile 的真實堆疊 flamegraph;小於 0.15% 的分支不繪製,原始 JSON 完整保留。

保存 16,393 samples、5,606 個 frame definitions、7 個 thread profiles;py-spy log 記錄 36 個 errors。這份 profile 的 30s final 中位數 1133.7 ms,顯著高於 clean baseline 529.5 ms,因此不以它的 span duration 作為 production 效能數字。上方階段表與 frame timeline 改用沒有 py-spy 的獨立重播。

完整 Speedscope · thread weights 與 ASR→CUDA 原始 stack 範例

橫軸是堆疊取樣權重,沒有時間先後順序;不同執行緒的權重可以重疊。native CUDA host call 的等待不等於 GPU kernel 執行時間。圖中相鄰、未解析符號的同一 native module 合併為模組名稱,完整位址/檔案/行號與 thread profiles 都在 Speedscope JSON。原生 library 多數沒有完整 debug symbols,因此不要從十六進位位址推測 operator。

Tracing 對量測本身的成本

PerfettoTracer.write_trace() 在同一把 lock 中完成 trimming、metadata 建構、json.dumps(indent=2)、gzip、atomic rename 與舊檔清理。producer 也拿同一把 lock。source 指向 utils/perfetto_trace.py:317–380;詳細 caller inventory 與所有 raw microbenchmark 參見 tracer.md

synthetic events/5 pairs pretty JSON median ms compact JSON median ms gzip baseline median ms pretty extra peak MiB compact extra peak MiB
1000 4.23 0.94 6.25 1.81 1.41
10000 44.05 8.80 66.25 18.03 4.27
56268 276.93 68.47 397.36 102.27 15.26
75000 1,815.00 1,237.79 512.62 134.95 20.37

56,268 是已保存 live snapshot 的 regular event count,該 snapshot 涵蓋一席、四席與 idle,並非單一四席 turn;75,000 是額外壓力樣本。compact 的每個正式 pair 都逐次核對完整 decoded JSON 相等。75k compact 的三輪 p50 曾出現 811/90/1,238 ms,原因尚未確診,全部保存,不能只採最快一次或外推成固定加速比。

image/svg+xml Matplotlib v3.10.9, https://matplotlib.org/ 0 200 400 600 Loop lag (ms) profile-flow-4seat 0 25 50 75 100 125 150 175 Seconds from first speech start; orange = production write_trace span 0 200 400 600 Loop lag (ms) profile-compact-4seat
production tracing 的 write_trace span 與 100 ms timer 的 event-loop lag;兩邊都只有輕量 supplement。
live/含 warmup flush n flush median ms flush max ms loop lag max ms lag≥5ms 與 flush 重疊
profile-flow-4seat 17 393.27 756.70 654.32 27/30
profile-compact-4seat 18 196.81 379.35 281.60 22/27

重疊是時間對照;搭配真實 lock probe 才支持 producer 阻塞機制。時間點本身不足以把所有 final 尾延遲歸給 tracing。兩種 tracing 的 final median 沒有一致改善,應以 flush/loop continuity 與記憶體成本評估這個改法。

去除縮排、減少高頻 trace 事件、縮短 retention、snapshot 後移出 lock,分別會影響序列化、記憶體與 producer 阻塞。只有 compact 是本次已實作的暫時 A/B;其他方向須保持 thread safety、UID metadata、輪替與 trace 完整性後再測。關閉 tracing 會減少可觀測性,因此報告不把它當作唯一解法。

記憶體:用量、保留與生命週期

完整新程序試驗 RSS peak MiB PSS idle MiB USS idle MiB GPU peak MiB GPU idle MiB
baseline/原 tracing 2,641.92 2,581.83 2,578.43 4,538.00 4,538.00
trace-off A/0.5s 2,453.36 2,268.86 2,086.85 4,540.00 4,540.00
trace-off B/0.5s 2,522.94 2,519.59 2,516.23 4,540.00 4,540.00
trace-off/1.0s 2,466.07 2,462.78 2,459.50 3,516.00 3,516.00
trace-off/final-only 2,427.68 2,424.42 2,421.16 3,514.00 3,514.00
compact tracing/0.5s 2,612.37 2,595.26 2,591.95 4,538.00 4,538.00
trace-off/greedy 2,468.00 2,464.72 2,461.45 4,538.00 4,538.00
trace-off/beam 4 2,481.29 2,477.98 2,474.67 4,538.00 4,538.00
trace-off/4 CPU quota 2,507.77 2,504.42 2,501.07 4,536.00 4,536.00
image/svg+xml Matplotlib v3.10.9, https://matplotlib.org/ 2000 2500 3000 3500 4000 4500 MiB fresh-baseline-4seat RSS PSS USS GPU MiB trace-off-repeat-4seat 0 25 50 75 100 125 150 175 200 Seconds from first speech start; shaded = speech 2000 2500 3000 3500 4000 4500 MiB interim-1s-4seat 0 25 50 75 100 125 150 175 200 Seconds from first speech start; shaded = speech MiB final-only-4seat Host RSS/PSS/USS and per-process GPU memory · shutdown excluded
陰影是發話區間,虛線是最後 EOT;memory floor 排除 server shutdown。不同程序的 allocator high-water 可能不同。

RSS 來自 /proc/<host PID>/status,PSS/USS 來自 smaps_rollup;USS 為 Private_Clean + Private_Dirty。GPU 使用 host PID 精確比對 nvidia-smi,每秒更新;process memory 每 200 ms 取樣,保留 PID starttime 防止誤讀重用 PID。缺失值保留 null,沒有用零補值。CPU seconds 使用 /proc/<pid>/stat,與 stack-sample 權重分開。

目前 config-k8s.yaml 繼承 base 的 production tracing,並明確開啟 debug log endpoint。deployment/k8s/kitt-stt/deployment.yaml:49–57 的 CPU request/limit 為 2/4、memory 8/20 GiB,dev deployment 也相同,不能直接把這台 32 logical CPU host 的數字當作部署容量。

表中的 idle floor 排除 server shutdown:runner 在 client 結束後至少等 12 秒才關閉 server,分析只使用最後 EOT 後 11 秒內的資料,再取最後 10 筆中位數。否則 CUDA context 拆除時的低值會造成假的「釋放」結論。VmHWM 只保留作輔助,不用來判斷 leak。PSS/USS 與 RSS 的差異、native arena 與 GPU pool 的保留都不能直接歸因為 Python leak。1 秒 interim 圖中約 125–165 秒的 PSS/USS 暫降,並未伴隨 RSS 相同幅度下降;本輪未保存完整 VMA sharing 明細,不將它解讀為釋放了等量實體記憶體。

20 次正常連線/發話/斷線均收到 final 與 commit。live service 最大為 3,最後為 1;session/segment bytes 都回到 0,preroll 剩 64,000 bytes。最後 USS floor 為 2263.3 MiB,沒有觀察到 service 數量按 20 次連線線性增加。仍有最後一個 service/preroll 保留,不宣稱完全清零;也沒有涵蓋 native inference 進行中的突然 abort 或數小時 soak。

image/svg+xml Matplotlib v3.10.9, https://matplotlib.org/ 0 500 1000 1500 2000 2500 Live object count app.live_services app.sessions 0 25 50 75 100 125 150 175 Seconds; vertical lines = new connection speech 0 500 1000 1500 2000 2500 MiB uss_bytes gpu_memory_bytes 20 normal connect / utterance / disconnect cycles · tracing off, supplement on
20 次正常 lifecycle;曲線揭示保留物件數與 allocator residency,不能用單次 RSS 上升判定 leak。

獨立元件試驗只 import 真實 UserSessionTurnStateDebugLogBuffer:12 秒 PCM 的 ASR segment 為 384,000 bytes,TurnSense tail 被 8 秒 cap 限制為 256,000 bytes;log 的同樣 4 筆可由 4 bytes 變成 400,000 bytes,證明條數上限不等於 byte 上限。tracemalloc live 1,906,745 bytes,釋放元件後剩 1,886 bytes。這證明這個受控生命週期的物件可釋放,不能當成 live service 沒有 leak 的證據。

真實服務的 Memray native capture 涵蓋四席 3/15/30 秒各一回合(12 席位),模型 preload 後開始,共 83,972,013 次 allocation、累積 34.06 GiB;tracked allocation peak(含 MMAP) 1302.9 MiB。累積配置量包含釋放後重複使用,不是 RSS 或同時存活量;tracked peak 也不包含開始 capture 前已配置的模型。decode_stream 所在 Python call path 占累積 bytes 的 82.7%,其下包含 Sherpa/ORT 原生配置,不能全部歸因為 Python object。

累積配置的 Python call site GiB(流量)
decode_stream:/app/sherpa-onnx/build/sherpa_onnx/offline_recognizer.py:1826 28.16
packb:/app/.venv/lib/python3.10/site-packages/msgpack/init.py:36 2.70
_read_ready__data_received:/usr/local/lib/python3.10/asyncio/selector_events.py:862 1.30
encode:/app/.venv/lib/python3.10/site-packages/websockets/extensions/permessage_deflate.py:185 0.67
decode:/app/.venv/lib/python3.10/site-packages/websockets/extensions/permessage_deflate.py:140 0.34

MsgPack/WebSocket deflate 也是已觀測到的配置來源。減少 frame 序列化次數、重用 packer/buffer、評估 PCM 傳輸壓縮策略是可繼續驗證的方向;本輪沒有給這些改法的速度收益,網路頻寬與跨程序 frame 契約也要一起驗證。

真實服務 allocation flamegraph(可互動、離線) · 完整 allocation 統計。capture 的 30s final 中位數為 2,876.45 ms,工具成本很大,不能用作 clean latency。

首次 capture 啟動失敗:實驗掛載覆蓋 PYTHONPATH,誤導入已安裝的 Sherpa 1.12.36,其 max_active_paths 介面與 vendored 1.13.0+cuda 不同。修正為保留 image 搜尋路徑後重跑成功;失敗 log 保留但不計入 benchmark。

同矩陣/Memray native allocation 次數 累積配置 GiB tracked peak MiB sampler RSS peak MiB GPU peak MiB
beam 8 83,972,013.00 34.06 1,302.94 2,632.89 3,514.00
greedy 11,754,668.00 17.11 2,346.32 2,500.74 4,538.00

Greedy 的配置次數降低 86.0%,累積 bytes 降低 49.8%;但 tracked peak 與 GPU residency 沒有同步下降。每組只有一次 allocation capture,allocator reservation/工作排程會影響 high-water,不能推論 greedy 必然更省常駐記憶體。兩次 capture 各有 12 次 final,但實際 interim 數為 beam 8 的 221 次、greedy 的 379 次;profiler 開銷改變了自適應排程。因此以上是相同音訊矩陣的完整 capture 比較,不是固定 decode call 數的成本比,也不能把 86% 當作未掛 profiler 的 allocation 改善率。peak records 顯示 beam 8 當時有 1 個、greedy 有 2 個 1 GiB 的 MMAP;其 stack 都在 native decode 下。這是映射配置量,並非已駐留的實體 pages,應以 RSS/PSS/USS 分開核對。baseline 與 greedy 的 MsgPack 配置仍都約 2.7 GiB,顯示這個傳輸成本沒有隨 decoder 一起消失。

Greedy allocation flamegraph · Greedy allocation 統計 · beam 8 peak stacks · greedy peak stacks

詳見 memory.md元件 allocation flamegraph。Memray 觀測 host allocation;GPU 記憶體仍由 NVML 補足,兩者不是同一個記憶體集合。

長語音、CPU quota 與 batching

一席長度/各2 measured rounds final median ms interim count median 累計 ASR path median ms
3 36.30 6.00 256.66
15 84.66 30.00 1,591.18
30 139.39 58.50 4,503.41
60 332.83 117.00 15,220.62

4 CPU quota 的 nr_throttled 在 workload 前後為 28→28,throttled_usec 為 50499140→50499140。啟動階段有 quota throttle,這份四席 steady workload 沒有增加 throttle。server CPU 為 74.73s,無 quota 的重複對照為 75.26s;因此不能說 steady latency 受 4 CPU quota 飽和支配。這不涵蓋更高並發、其他硬體或 cold-start SLO。

原生/4 streams/5 AB-BA pairs serial decode ms batch decode ms group 改善 第一席 serial ms 第一席 batch ms
3 73.81 50.08 32.15% 24.09 50.06
15 212.91 187.65 11.86% 56.97 187.62
30 418.73 397.15 5.15% 106.43 397.13

真正呼叫同一 native recognizer 的 decode_streams(4),每個 shape 各自 warmup,serial 與 batch 交替順序。所有 15 對的四席文字逐次相等且非空;原生輸出為簡體,尚未經完整服務文字處理。這證明同長輸入的原生 group throughput 有收益,但長音訊僅約 5%;第一席必須等整組完成。沒有把 batch 接進 WebSocket scheduler,也沒有不同長度 padding、batch formation wait 或即時排程結果,所以不把這個百分比當成端到端 final 改善。prepare 時間另外保存,沒有混入表中 decode。

原生 batch 全部 pairs/設定/文字 · host PID memory samples

目前 main 已有 incremental feature feed 與 final stream handover。降低重算頻率是現有路徑上的策略調整,不應把已存在的 incremental feeding 列成新功能。長語音仍反覆執行整個成長中 segment 的 offline decode;更進一步的 streaming backend、切段或增量模型狀態需要重新驗證轉錄與 turn 行為。

EOT 完成時間與辨識時間

0.5s control B/4 seats final median ms EOT median ms final→EOT median ms commit reasons
3 90.47 2,091.88 2,001.67 {'timeout': 12}
15 298.04 298.04 0.00 {'model': 12}
30 487.82 2,490.09 2,001.84 {'timeout': 12}

這份固定音訊在 3/30 秒組的 commit 多由 reason=timeout 觸發,decision 的 wait_ms=2000;15 秒組由 model 直接 commit。final 到 EOT 的差距約 2 秒,遠大於 TurnSense native ONNX 的幾十毫秒。因此應把 policy 等待與模型速度分開優化;改短 wait 可能增加過早截斷,需完整語意 turn 的標註資料,這次不能證明應改成多少。

已排除與仍未證實

項目 本次可說到哪裡
多開 WebSocket 已實測,沒有穩定 final latency 改善;共享 recognizer 仍在。
ITN/frame building 本語料下很小;沒有數字、日期、多語言的覆蓋,不能普遍排除。
segment buffer lock 本 trace 下可與 recognizer lock 分開量測,見階段表;不因為存在 lock 就假定是瓶頸。
TurnSense policy 等待 2,000 ms 等待由 EOT decision 證明;不是 2 秒模型推論。
模型 preload/arena 實際程序保留量已測;process lifetime cache 不能直接稱為 leak。
持續 VAD、inflight abort、無上限 unique user IDs 本次正常 lifecycle 與最長 60 秒輸入不涵蓋所有異常生命週期;不得宣稱完全沒有 leak。
TensorRT、FP16/INT8、CUDA Graph、其他模型 本 image 未提供相同模型的完整替代 artifact/provider 條件;沒有給虛構加速數字。須先驗證 provider、精度、辨識品質、peak memory,再按同矩陣比較。
Orin、Thor、C-X1、GKE 未在這些目標重播;4 CPU quota 是同一 4090 host 的限制試驗,不等於目標硬體驗證。
GPU kernel bottleneck 未做 Nsight/CUPTI kernel trace;native flamegraph 只能定位 host call path,不能判斷個別 CUDA kernel 或 SM occupancy。

如何讓 AI 檢查,而不只看一張 flamegraph

  1. Perfetto Python API 載入 trace,執行 analysis.sql。本次實際使用 trace_processor v57.2;結果保存於 analysis.json,並與 raw JSON count/sum assert 一致。官方也提供 AI trace analysis 工作流程
  2. py-spy 保存真實 Python + native sampling 的 Speedscope JSON。AI 可先聚合 thread/file/stack,再回到 frame timeline 確認因果,避免把寬的等待堆疊當成純 CPU 工作。
  3. Memray 補 host allocation stacks;native mode 的符號可見度取決於 debug information。搭配 PSS/USS/NVML 曲線與 disconnect tail,才能區分暫態 peak、allocator residency 與持續保留。

重播與檢查

從同一 worktree 使用本地 .venv、相同 immutable image 與本報告的 clip hashes。clip 是 ignored fixtures,新 checkout 可用以下 stdlib 重建:

from pathlib import Path
import wave
source = Path("tests/functional/audios/say-open-door.wav")
with wave.open(str(source), "rb") as wav:
    assert (wav.getnchannels(), wav.getsampwidth(), wav.getframerate()) == (1, 2, 16000)
    pcm = wav.readframes(wav.getnframes())
out = Path("tests/batch_decode/audio")
out.mkdir(exist_ok=True)
for seconds in (1, 3, 6, 15, 30, 60):
    size = seconds * 16000 * 2
    with wave.open(str(out / f"clip-{seconds}s.wav"), "wb") as wav:
        wav.setparams((1, 2, 16000, 0, "NONE", "not compressed"))
        wav.writeframes((pcm * ((size + len(pcm) - 1) // len(pcm)))[:size])

執行量測與檢查:

.venv/bin/python utils/performance/workload.py --self-check
.venv/bin/python utils/performance/profile_server.py --self-check
python3 utils/performance/memory_probe.py --self-check
python3 utils/performance/tracer_probe.py self-check
.venv/bin/python utils/performance/batch_probe.py --self-check

.venv/bin/python utils/performance/run_case.py \
  --case interim-1s --label your-unique-label \
  --image sha256:f51393696ba3b913c73bd6db38ec79fb75393d165eac54827f474a2423d1fece \
  --out /tmp/your-new-evidence-directory

# 在包含官方 perfetto Python package 的 tools environment 中:
python utils/performance/analyze.py --sql \
  --evidence /tmp/kitt-stt-performance-20260912 \
  --out /tmp/kitt-stt-performance-20260912/analysis.json

run_case.py 建立新容器、驗證 health 與 TurnSense CUDA、啟動 host PID sampler、執行真實重播、保存 log/config/trace/結果後清理自身容器。run.json 保存每組命令、image、source;後續組另保存 experiment script/audio hashes。早期探索組的來源 hashes 由 環境與音訊 manifest 補足。artifact 的最終 hashes 見 manifest.json。大型 Memray .bin 已保存在 worktree 的 evidence 目錄並加入本報告的 .gitignore;可互動 HTML 與小型 raw 結果可直接 review。

獨立 tools environment 使用 py-spy、Perfetto、Memray、matplotlib;沒有把 profiler 加入 production dependency。完整 source 路徑與 caller 關係見 flow.md

範圍與證據限制

這是一台有其他服務的工作站,沒有固定 CPU/GPU 時脈或宣稱獨占 host。GPU 模型試驗按順序執行,profiled 組與 clean latency 組分列;不能把 instrumentation 的延遲拿來當 production benchmark。記憶體 sampler、trace retention/flush、測量時間窗與冷/暖狀態都有列出。原生 sampling 有少量 sample errors,完整計數保留;不是每一條 native symbol 都可解析。

三個方向的 Luna max 子代理分別負責 flow instrumentation、tracer 證明與 memory probe/元件控制。主控重跑與核對 raw data,修正了假設錯誤、跨檔案系統保存、memory shutdown floor、EOT carrier 與單變因比較等問題;子代理提供的來源推測不會直接升格成結果。

公開版範圍:本頁保留完整分析、圖表與結論;raw workload、trace、log、profile 與 allocation binaries 只保留在受控的本機 worktree,未公開上傳。