本文作者kaiyuanSGLang Profiling入门数据采集与分析想深耕AI Infra领域欢迎访问InfraTech库内容涵盖大模型基础、PyTorch/vLLM/SGLang框架入门、性能加速等核心方向配套50知识干货及适合初学者的notebook练习:https://github.com/CalvinXKY/InfraTech在进行推理性能优化时Profiling(性能剖析)是不可或缺的环节。本文将基于GPU-A100环境以Qwen2.5-Instruct模型为例从模型下载、镜像构建、样例运行到数据导出与分析带领读者逐步完成Profiling的采集与解读全流程。模块时序图1 profiling数据获取1.1 搭建环境运行环境的搭建主要包括机器配置、模型与数据准备、镜像与容器启动三个环节。不同规模的模型所需的机器数量及启动参数有所差异为确保单卡能够加载整个模型所选模型的参数量不宜过大本文以7B规模的模型为例进行说明。此外GPU服务器需重点检查驱动是否满足镜像启动要求如不满足则需提前升级驱动。模型Qwen2.5-7B-Instruct从huggingface下载https://huggingface.co/Qwen/Qwen2-7B-Instruct镜像nvcr.io/nvidia/sglang:26.01-py3从NVIDIA的ngc[1]直接获取环境搭建详细步骤见sglang_profiling_from_scratch.ipynb 第1节[2]1.2 数据采集在SGLang框架中Profiling数据记录功能基于PyTorch实现并由SGLang完成了封装。用户采集数据时可直接调用SGLang提供的接口。其官方文档中也给出了若干种常用的采集方式方便用户按需使用[3]sglang.bench_servingsglang.bench_offline_throughputsglang.profilerHTTP API endpoints我们采用基于HTTP API接口的方式该方式配置较为简便。服务端仅需添加一个环境变量客户端则通过发送不同请求来控制性能分析profiling的开启与停止。用于触发性能分析采集的请求端点示例如下开启http://127.0.0.1:30000/start_profile关闭http://127.0.0.1:30000/stop_profile在测试时可启动两个容器分别运行服务端server与客户端client。服务端# 配置profiling导出位置(必须) export SGLANG_TORCH_PROFILER_DIR/data/kaiyuan/llm_infer/profiles # 启动服务器 python -m sglang.launch_server --model-path /data/kaiyuan/models/Qwen2.5-7B-Instruct客户端客户端可通过curl命令或Python脚本发送请求以Python脚本为例# -*- coding: gbk -*- import requests import time base_url http://127.0.0.1:30000 # 开始性能分析 requests.post(f{base_url}/start_profile, timeout5) # 发送5个推理请求 for i in range(5): requests.post( f{base_url}/v1/completions, json{ model: default, prompt: f测试请求 {i1}: 请解释人工智能的基本概念, max_tokens: 30, temperature: 0.1 }, timeout15 ) time.sleep(0.5) # 等待并停止性能分析 time.sleep(5) requests.post(f{base_url}/stop_profile)运行成功后在服务端能够看到如下输出采集单机多卡的运行增加(tp-size 1)服务端的启动变为SGLANG_TORCH_PROFILER_DIR/data/kaiyuan/llm_infer/profiles \ python -m sglang.launch_server \ --model-path /data/kaiyuan/models/Qwen2.5-7B-Instruct \ --host 127.0.0.1 \ --tp-size 4 \ --port 30000运行成功后的打印输出如下如果需要关闭图模式采集数据配置环境变量SGLANG_CUDA_GRAPH_MODE0 SGLANG_CACHE_GRAPH0 CUDA_LAUNCH_BLOCKING11.3 数据加载采集完成后将得到的trace.json文件如为压缩包需先解压导入到Perfetto[4]中即可查看详细的时序图timeline并进行性能分析。2 profiling数据分析导入单机单卡的采集数据后界面会显示若干按类别划分的时序条可以找到Python层和GPU层的运行数据。2.1 python层数据首先观察Python层的运行情况定位到主线程对应的数据。本次共发送了5个请求在火焰图上可以逐一找到其对应的触发位置。将时间轴放大后可以清晰观察到请求处理与等待交替出现的细节。如图中标注所示“请求处理过程”与“请求之间的等待”两个阶段被明确区分。将这两处时序进一步放大以观察细节其中“请求之间的等待”过程主要由循环等待构成该阶段不涉及GPU计算操作。而“请求处理过程”放大后如下图所示主要包括prefill阶段与decode阶段。prefill阶段采用单算算子模式decode阶段则使用CUDA graph模式。Prefill阶段将时间轴进一步放大以观察prefill阶段的详细过程可以看到从输出处理、embedding、各层(layer)计算到生成samples的完整流程。Embedding计算如下图所示。在本例中embedding计算耗时较短需将时序图放大到一定程度才能清晰识别可通过先定位layer0再向上回溯找到embedding的位置。模型共包含28层Layer计算其中第0层的执行时间较长主要耗时来源于FlashInfer JIT的编译构建过程。模型共包含28层Layer计算其中第0层的执行时间较长主要耗时来源于FlashInfer JIT的编译构建过程。Attention之前的计算过程Attention到MLP的计算过程logits与sampling的计算在layer_27之后过程Decode阶段Decode阶段默认会启用CUDA Graph因此前向计算过程实际上是该Graph的回放过程。而sampler并未被包含在Graph中需要单独调用算子计算。当计算图被下发至GPU后Python进程便会等待CUDA返回计算结果。2.2 GPU层CUDAGPU层主要负责记录流stream中算子kernel的执行时序以及这些算子与上层Python操作之间的依赖关系。在下方的菜单栏里面可看到每个算子的详细数据。2.3 多卡的融合数据在多卡数据采集时系统会生成多个数据文件。逐个查看文件不利于多维度对比分析建议将来自不同 TP 的数据整合到单个JSON文件中便于统一对照分析。在开启profiling采集时添加“merge_profiles”参数。base_url http://127.0.0.1:30000 # 开始性能分析 url http://127.0.0.1:30000/start_profile headers {Content-Type: application/json} data {merge_profiles: True} # 多TP采集融合 response requests.post(url, headersheaders, jsondata)融合数据在采用TP切分后相关的线性层计算完成后会额外增加集合通信操作步骤。本文的完整用例参考sglang_profiling_from_scratch.ipynb[2]vLLM与NPU版本的profiling采集过程参考GPU/NPU推理Profiling阅读引导(上GPU/NPU推理Profiling阅读引导(下参考:[1]https://catalog.ngc.nvidia.com/orgs/nvidia/containers/sglang?version26.01-py3[2]abhttps://github.com/CalvinXKY/InfraTech/blob/main/llm_infer/sglang_profiling_from_scratch.ipynb[3]https://docs.sglang.io/developer_guide/benchmark_and_profiling.html#profile-a-server-with-http-api-endpoints[4]https://ui.perfetto.dev/InfraTech申明未经允许不得转载