vLLM main bbd7c24(2026-09-24 克隆) vllm-ascend a71b766ce(2026-09-23) 采集工具两条线:Ascend PyTorch Profiler(算子级)· MS Service Profiler(服务级)
推理服务的性能采集要回答两类问题:"哪个算子慢"(算子/内核级)和 "服务流程哪一段慢"(调度、批处理、KV 管理的函数级)。昇腾官方指南给出两条对应的采集线:
| 特性 | 线一:Ascend PyTorch Profiler | 线二:MS Service Profiler |
|---|---|---|
| 安装 | 内置,命令行即开 | 需从源码构建 msserviceprofiler(CANN Toolkit 预装) |
| 采集粒度 | PyTorch 算子级 | 服务框架函数级(也可含算子) |
| 控制方式 | API 请求控制(/start_profile、/stop_profile) | 配置文件控制(enable 0→1) |
| 数据格式 | ascend_pt 格式 | Chrome Tracing + CSV |
| 适用场景 | 模型算子性能分析 | 服务框架工作流分析 |
两条线共用上游 vLLM 的骨架:ProfilerConfig(参数)、
Worker.profile()(入口)、WorkerProfiler(生命周期状态机)。
vllm-ascend 做两件事:把线一的执行器换成 torch_npu.profiler;
给线二生成昇腾专用的符号打点表。这就是本页的两条主线。
启动服务时带 --profiler-config(只设了它,/start_profile 端点才会注册,否则 404);
稳定后 curl 开采集 → 跑业务请求 → curl 停采集 → 离线 analyse → 用 MindStudio Insight 看。
注意 2026-01-19 起上游废弃了 VLLM_TORCH_PROFILER_DIR 环境变量(vllm-ascend PR #5928),统一用
--profiler-config '{"profiler":"torch","torch_profiler_dir":"./vllm_profile","torch_profiler_with_stack":false}'。
上游侧(vLLM main):ProfilerConfig 定义参数;
gpu_worker.profile(is_start)(vllm/v1/worker/gpu_worker.py:1297)是入口;
WorkerProfiler(vllm/profiler/wrapper.py)是生命周期状态机——管理
delay_iterations(启动后延迟几步再采)、max_iterations(最多采几步),
每步 worker 循环调一次 step() 推进状态;
工厂 create_worker_profiler(wrapper.py:675)按 profiler 类型发
TorchProfilerWrapper / CudaProfilerWrapper / ProtonProfilerWrapper
——只有 CUDA 三分支,没有 NPU。
昇腾侧(vllm-ascend):NPU 的 NPUWorker.profile()
(vllm_ascend/worker/worker.py:1170)不走上游工厂,直接实例化
TorchNPUProfilerWrapper(worker/worker.py:1177)——
它继承上游 WorkerProfiler(状态机、延迟/步数限制全部复用),
只把底下的执行器从 torch.profiler 换成 torch_npu.profiler。
"继承骨架、替换执行器"就是这条线的全部联动设计。
vllm_ascend/profiler/torch_npu_profiler.py · TorchNPUProfilerWrapper · L29-86class TorchNPUProfilerWrapper(WorkerProfiler):
"""Subclass of vLLM ``WorkerProfiler`` that wires in ``torch_npu.profiler``."""
@staticmethod
def _create_profiler(profiler_config, trace_name):
...
msmonitor_use_daemon = get_ascend_config().msmonitor_use_daemon # ↳昇腾侧配置
if msmonitor_use_daemon:
raise RuntimeError("msmonitor_use_daemon and torch profiler 不能同开") # ⚡互斥红线
experimental_config = torch_npu.profiler._ExperimentalConfig(
export_type=torch_npu.profiler.ExportType.Text, # ↳导出文本型产物
profiler_level=torch_npu.profiler.ProfilerLevel.Level1,
aic_metrics=torch_npu.profiler.AiCMetrics.PipeUtilization, # ⚡AI Core 各流水线利用率
data_simplification=True, # ↳数据精简,控制体积
)
return torch_npu.profiler.profile(
activities=[CPU, NPU], # ⚡与 CUDA 版的关键差异:NPU activity
with_stack=False,
profile_memory=profiler_config.torch_profiler_with_memory,
# NOTE: torch_npu 的 with_modules 等价于 torch.profiler.with_stack,
# with_stack 在 torch_npu 上开销显著 → 用 with_modules 替代(⚡昇腾特有取舍)
with_modules=profiler_config.torch_profiler_with_stack,
on_trace_ready=torch_npu.profiler.tensorboard_trace_handler(
profiler_config.torch_profiler_dir, worker_name=trace_name),
)
def _start(self): self.profiler.start()
def _stop(self): self.profiler.stop()
def _profiler_step(self): return True
vllm_ascend/worker/worker.py · NPUWorker.profile · L1170-1184 if is_start:
rank_suffix = get_worker_rank_suffix(global_rank=self.rank)
trace_name = f"{profile_prefix}_{rank_suffix}" if profile_prefix else rank_suffix
if self.profiler is None:
# ⚡上游 create_worker_profiler 只有 torch/cuda/proton 三分支(无 NPU),
# 因此 NPUWorker 在这里直接实例化昇腾 wrapper(联动替换点)
self.profiler = TorchNPUProfilerWrapper(self.profiler_config, trace_name)
self.profiler.start()
else:
# 已初始化:重启采集但保留首次的 trace 名
self.profiler.start()
停采集后 torch_profiler_dir 下出现 *_ascend_pt 目录,先调
torch_npu.profiler.profiler.analyse() 解析,再看 ASCEND_PROFILER_OUTPUT:
kernel_details.csv(内核级)、operator_details.csv(算子级)、
op_statistic.csv(算子利用率)、step_trace_time.csv(步调度)、
trace_view.json(Chrome tracing,用 MindStudio Insight 打开)——
这正是半年目标 KR1.3 里"profile 分解 Cube/Vector/通信"的数据来源。
PD 分离下 P/D 是两个独立实例:两边都要带 --profiler-config(目录错开), 负载均衡代理不转发 /start_profile、/stop_profile——必须分别 curl 各节点; EPD 代理(layerwise)则支持向全部 E/P/D 实例广播。
线二的核心配置是一份符号表 YAML:声明"哪些函数要打点、用什么 handler 记录"。
vllm_ascend/profiling_config.py 在 vLLM 启动时自动生成
~/.config/vllm_ascend/service_profiling_symbols.<版本>.yaml
(文件名带 vLLM 版本号,generate_service_profiling_config L538 原子写入)。
清单覆盖服务全链路,且每条可带 min_version/max_version——上游接口一变,
换一条符号声明即可,这是它对齐上游快速演进的关键手段:
OpenAIServingChat.create_chat_completion、AsyncLLM.generateScheduler.schedule / add_request(上游类 + 昇腾 AscendScheduler 各一条)KVCacheManager.free / get_computed_blocksExecutor.execute_model、NPUModelRunner.execute_model / _update_states / _prepare_inputs、logits、samplerpropose_draft_token_ids 等专用 handlervllm_ascend/profiling_config.py · SERVICE_PROFILING_SYMBOLS_YAML · 节选(L27-157)- symbol: vllm.v1.core.sched.scheduler:Scheduler.schedule # ↳上游调度入口
min_version: "0.9.1"
handler: ms_service_profiler.patcher.vllm.handlers.v1.batch_handlers:schedule
name: batchFrameworkProcessing
- symbol: vllm_ascend.worker.model_runner_v1:NPUModelRunner.execute_model # ⚡昇腾自己的执行器
name: modelRunnerExec
handler: ...v1.model_handlers:execute_model_runner
domain: Execute
# ⚡执行时长采集的版本演进:旧 API 只到 0.14.0rc1,0.15.0rc1 起换上游新接口
- symbol: vllm_ascend.utils:ProfileExecuteDuration.capture_async
min_version: "0.9.1"
max_version: "0.14.0rc1"
handler: ...v1.model_handlers:capture_async
- symbol: vllm.v1.utils:record_function_or_nullcontext
min_version: "0.15.0rc1"
handler: ...v1.model_handlers:record_function_or_nullcontext
配置文件(ms_service_profiler_config.json)常用字段:enable(0/1 总开关)、
prof_dir(默认 ~/.ms_server_profiler)、acl_task_time(算子下发/执行时延,
0/1/2/3 四档,3=Torch Profiler dump)、timelimit(进程自动停止时长,0-7200 秒)、
domain(限定 Request/KVCache/ModelExecute/BatchSchedule/Communication 域,减数据量)。
产物四件:chrome_tracing.json(Insight 打开)、request.csv、
kvcache.csv、batch.csv——服务级"请求→批→KV"全链路即可视化。
VLLM_TORCH_PROFILER_DIR 2026-01-19 起废弃(PR #5928),改用 --profiler-config(在线)/ profiler_config(离线);老文档/脚本里的旧用法要迁。msmonitor_use_daemon 与 torch profiler 不能同开(TorchNPUProfilerWrapper 启动即抛错)。with_stack 开销显著,wrapper 用 with_modules 等价替代;指南建议默认关 python stack(torch_profiler_with_stack=false)。ProfileExecuteDuration.capture_async 只支持到 vLLM 0.14.0rc1,0.15.0rc1 起上游换 record_function_or_nullcontext——符号表用双条目按版本分流(升级 vLLM 后符号表自动跟着版本号切换)。与半年目标的衔接:线一产出(kernel/operator/step_trace 三张 csv)正是 KR1.3 的 "profile 分解 Cube/Vector/通信占比"的输入;线二的 batch/kvcache/request 三张 csv 正好覆盖调度与 KV 工程的问题定位;两线数据在 MindStudio Insight 里同源查看。