服务剖析指南#

在推理服务进程中,我们有时需要监控推理服务框架的内部执行流程,以便识别性能问题。通过收集关键进程的开始和结束时间戳、识别关键函数或迭代、记录关键事件、捕获多种信息类型,可以快速定位性能瓶颈。

本指南将引导您为 vllm-ascend 服务框架和算子收集性能数据。它涵盖了从准备、收集到分析和可视化的完整工作流程,帮助您快速上手剖析工具。

快速开始#

0 安装#

使用 pip 安装 msserviceprofiler

pip install msserviceprofiler==1.2.2

1 准备工作#

在启动服务之前,请将环境变量 SERVICE_PROF_CONFIG_PATH 设置为指向剖析配置文件,并将环境变量 PROFILING_SYMBOLS_PATH 设置为指定需要导入的符号的 YAML 配置文件。之后,根据您的部署方式启动 vLLM 服务。

cd ${path_to_store_profiling_files}
# Set environment variable
export SERVICE_PROF_CONFIG_PATH=ms_service_profiler_config.json
export PROFILING_SYMBOLS_PATH=service_profiling_symbols.yaml

# Start vLLM service
vllm serve Qwen/Qwen2.5-0.5B-Instruct &

文件 ms_service_profiler_config.json 是剖析配置文件。如果该文件在指定路径下不存在,系统将自动生成一个默认配置。如有需要,您可以根据下文“剖析配置文件”部分的说明提前进行自定义。

service_profiling_symbols.yaml 是包含需要导入的剖析点的配置文件。您可以选择 **不** 设置 PROFILING_SYMBOLS_PATH 环境变量,此时系统将使用默认配置文件。如果您指定的路径下文件不存在,同样,系统将在您指定的路径生成配置文件供后续配置。您可以根据下文“Symbols 配置文件”部分的说明进行自定义。

2 启用剖析#

要启用性能数据收集开关,请在配置文件 ms_service_profiler_config.json 中将 enable 字段从 0 修改为 1。可以通过执行以下 sed 命令完成:

sed -i 's/"enable":\s*0/"enable": 1/' ./ms_service_profiler_config.json

3 发送请求#

请根据您的实际剖析需求选择合适的请求发送方式。

curl https://:8000/v1/completions \
    -H "Content-Type: application/json"  \
    -d '{
         "model": "Qwen/Qwen2.5-0.5B-Instruct",
        "prompt": "Beijing is a",
        "max_tokens": 5,
        "temperature": 0
}' | python3 -m json.tool

4 分析数据#

# xxxx-xxxx is the directory automatically created based on vLLM startup time
cd /root/.ms_server_profiler/xxxx-xxxx

# Analyze data
msserviceprofiler analyze --input-path=./ --output-path output

5 查看结果#

分析完成后,output 目录下将包含:

  • chrome_tracing.json: Chrome tracing 格式数据,可在 MindStudio Insight 中打开。

  • profiler.db: 数据库格式的性能数据。

  • request.csv: 与请求相关的数据。

  • request_summary.csv: 整体请求指标。

  • kvcache.csv: KV Cache 相关数据。

  • batch.csv: Batch 调度相关数据。

  • batch_summary.csv: 整体 Batch 调度指标。

  • service_summary.csv: 整体服务层指标。


附录#

1 剖析配置文件#

剖析配置文件控制着剖析参数和行为。

文件格式#

配置采用 JSON 格式。主要参数:

参数

描述

必需

enable

剖析开关
0: 禁用
1: 启用
默认值: 0

prof_dir

用于存储收集到的性能数据的目录。
默认值: $HOME/.ms_service_profiler

profiler_level

数据收集级别。默认为“INFO”(正常级别)。

host_system_usage_freq

主机 CPU 和内存指标的采样频率。默认禁用。范围:整数 1–50,单位:Hz(每秒采样次数)。设置为 -1 表示禁用。
注意:启用此选项可能会消耗大量内存。

npu_memory_usage_freq

NPU 内存使用率的采样频率。默认禁用。范围:整数 1–50,单位:Hz(每秒采样次数)。设置为 -1 表示禁用。
注意:启用此选项可能会消耗大量内存。

acl_task_time

收集算子调度延迟和执行延迟的开关
0: 禁用(默认;0 或无效值表示禁用)。
1: 启用;调用 aclprofCreateConfig 时指定 ACL_PROF_TASK_TIME_L0
2: 启用 MSPTI 数据转储;使用 MSPTI 进行剖析,需要:export LD_PRELOAD=$ASCEND_TOOLKIT_HOME/lib64/libmspti.so

acl_prof_task_time_level

剖析的级别和持续时间
L0:仅收集算子调度和执行延迟;开销较低(无算子基本信息)。
L1:收集 AscendCL 接口性能(Host-Device 和 Device-Device 同步/异步内存拷贝延迟),以及算子调度、执行和基本信息,用于全面分析。
time:剖析持续时间,整数 1–999,单位:秒。
如果未设置,则默认为 L0 直到程序退出;无效值将回退到默认值。
级别和持续时间可以组合,例如:"acl_prof_task_time_level": "L1,10"

api_filter

过滤以选择要转储的 API 性能数据。例如,指定“matmul”将转储 name 包含“matmul”的所有 API 数据。字符串,区分大小写;使用“;”分隔多个目标。空表示转储所有。
仅在 acl_task_time 为 2 时有效。

kernel_filter

过滤以选择要转储的 Kernel 性能数据。例如,指定“matmul”将转储 name 包含“matmul”的所有 Kernel 数据。字符串,区分大小写;使用“;”分隔多个目标。空表示转储所有。
仅在 acl_task_time 为 2 时有效。

timelimit

服务的剖析持续时间。进程在此时间后自动停止。范围:整数 0–7200,单位:秒。默认值 0 表示无限制。

domain

将剖析限制在指定域以减少数据量。字符串,用分号分隔,区分大小写,例如:“Request; KVCache”。
空表示所有可用域。
可用域:Request, KVCache, ModelExecute, BatchSchedule, Communication。
注意:如果选择的域不完整,分析输出可能会显示警告,因为缺少数据。请参阅 表 1

示例配置#

{
  "enable": 1,
  "prof_dir": "vllm_prof",
  "profiler_level": "INFO",
  "acl_task_time": 0,
  "acl_prof_task_time_level": "",
  "timelimit": 0
}

2 Symbols 配置文件#

Symbols 配置文件定义了要剖析的函数/方法,并支持通过自定义属性收集进行灵活配置。

2.1 文件名与加载#

  • 默认加载路径:~/.config/vllm_ascend/service_profiling_symbols.MAJOR.MINOR.PATCH.yaml(根据 vllm 的安装版本)

如果您需要自定义剖析点,强烈建议使用 PROFILING_SYMBOLS_PATH 环境变量将剖析配置文件复制到您的工作目录。

2.2 字段说明#

字段

描述

示例

symbol

Python 导入路径 + 属性链

"vllm.v1.core.kv_cache_manager:KVCacheManager.free"

handler

处理器类型

"timer"(默认)或 "pkg.mod:func"(自定义)

domain

Domain 标签

"KVCache", "ModelExecute"

名称

事件名称

"EngineCoreExecute"

min_version

上限版本约束

"0.9.1"

max_version

下限版本约束

"0.11.0"

attributes

自定义属性收集

仅支持 "timer" 处理器。请参见下文部分。

2.3 示例#

  • 示例 1:自定义处理器

- symbol: vllm.v1.core.kv_cache_manager:KVCacheManager.free
  handler: vllm_profiler.config.custom_handler_example:kvcache_manager_free_example_handler
  domain: Example
  name: example_custom
  • 示例 2:默认计时器

- symbol: vllm.v1.engine.core:EngineCore.execute_model
  domain: ModelExecute
  name: EngineCoreExecute
  • 示例 3:版本约束

- symbol: vllm.v1.executor.abstract:Executor.execute_model
  min_version: "0.9.1"
  # No handler specified -> default timer

2.4 自定义属性收集#

字段 attributes 支持灵活的自定义属性收集,并允许对函数参数和返回值进行操作和转换。

基本语法#
  • 参数访问:直接使用参数名,例如:input_ids

  • 返回值访问:使用 return 关键字

  • 管道操作:使用 | 链接多个操作

  • 属性访问:使用 attr 访问对象属性

示例#
- symbol: vllm_ascend.worker.model_runner_v1:NPUModelRunner.execute_model
  name: ModelRunnerExecuteModel
  domain: ModelExecute
  attributes:
  - name: device
    expr: args[0] | attr device | str
  - name: dp
    expr: args[0] | attr dp_rank | str
  - name: batch_size
    expr: args[0] | attr input_batch | attr _req_ids | len
表达式说明#
  1. len(input_ids):获取参数 input_ids 的长度。

  2. len(return) | str:获取返回值的长度并转换为字符串(等同于 str(len(return)))。

  3. return[0] | attr input_ids | len:获取返回值第一个元素的 input_ids 属性的长度。

支持的表达式类型#
  • 基本操作:len(), str(), int(), float()

  • 索引访问:return[0], return['key']

  • 属性访问:return | attr attr_name

  • 管道组合:使用 | 链接操作

进阶示例#
attributes:
  # Get tensor shape
  - name: tensor_shape
    expr: input_tensor | attr shape | str
  
  # Get specific value from a dict
  - name: batch_size
    expr: kwargs['batch_size']
  
  # Conditional expression (requires custom handler support)
  - name: is_training_mode
    expr: training | bool
  
  # Complex data processing
  - name: processed_data_len
    expr: data | attr items | len | str

2.5 自定义处理器#

handler 指定了自定义函数时,该函数必须符合以下签名:

def custom_handler(original_func, this, *args, **kwargs):
    """
    Custom handler
    
    Args:
        original_func: the original function object
        this: the bound object (for methods)
        *args: positional arguments
        **kwargs: keyword arguments
    
    Returns:
        processing result
    """
    # Custom logic
    pass

如果自定义处理器导入失败,系统将自动回退到默认的计时器模式。