尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

AIBrix GPU Optimizer 性能剖析实战:用 benchmark.sh 采集 GPU 吞吐矩阵、以 gen_profile.py 生成满足 SLO 的 GPU Profile

AIBrix GPU Optimizer 性能剖析实战:用 benchmark.sh 采集 GPU 吞吐矩阵、以 gen_profile.py 生成满足 SLO 的 GPU Profile AIBrix GPU Optimizer 性能剖析实战用 benchmark.sh 采集 GPU 吞吐矩阵、以 gen_profile.py 生成满足 SLO 的 GPU Profile【免费下载链接】aibrixCost-efficient and pluggable Infrastructure components for GenAI inference项目地址: https://gitcode.com/GitHub_Trending/ai/aibrix导读GPU Profiling 是 AIBrix GPU Optimizer异构 GPU 自动扩缩容组件的数据入口它先通过benchmark.sh对目标 GPU 上运行的 vLLM 推理服务做多维度压测采集不同输入/输出长度与请求速率下的吞吐、延迟等 SLO 数据再借助gen_profile.py将原始基准结果合成为一张该 GPU 在不同请求规模下的最大吞吐矩阵即 GPU Profile。本文以 profiling/README.md 为骨架结合同一目录下的benchmark.sh、gpu_benchmark.py、gen_profile.py源码与result/样例数据完整讲解从部署模型、参数配置、压测执行到 Profile 生成与消费的全链路读完即可在自己的 GPU 环境复现这套性能剖析流程。GPU Profiling 在 AIBrix 中的定位AIBrix 的 GPU Optimizer 是一个支持异构 GPU 的 vLLM Auto Scaler见 gpu_optimizer/README.md 开头对组件的定义。它做扩缩容决策的前提是知道每种 GPU 在当前模型负载下到底能扛多少吞吐、延迟表现如何。这正是 profiling 目录下工具集的价值第一步用benchmark.sh得到目标 GPU 上不同输入/输出长度下的throughput、latency 及其他 SLO第二步用gen_profile.py基于这些数据生成满足指定 SLO 的 GPU Profile吞吐矩阵第三步Profile 被下游消费存入 Redis 供 GPU Optimizer 加载或喂给 Mélange 求解器做异构 GPU 成本优化。整个工具集位于 python/aibrix/aibrix/gpu_optimizer/optimizer/profiling/包含 5 个核心文件benchmark.sh压测入口、benchmark.pyshell 脚本的 Python 包装、gpu_benchmark.py底层压测引擎、gen_benchmark_prompt.pytrace 驱动的请求生成、gen_profile.pyProfile 合成器以及存放结果的result/目录。一、benchmark.sh一键采集 GPU 性能数据的压测入口1. 前置条件先让模型跑起来官方文档明确指出先在你要剖析的 GPU 上部署好目标模型。当前仓库支持 vLLM 这类推理引擎gpu_benchmark.py的 docstring 也说明其源自 vLLM 的benchmarks/benchmark_serving.py。部署完成后如果模型跑在 Kubernetes Pod 里需要先把 Pod 端口映射到本地再压测kubectl port-forward [pod_name] 8010:8000 1/dev/null 21 这样本地8010端口就能访问到 Pod 内的 vLLM 服务默认端口 8000。gpu_benchmark.py默认请求路径为http://localhost:8010/v1/completions见 gpu_benchmark.py 中api_url的拼接逻辑。如果没有真实 GPU 环境仓库还提供了 CPU 版 vLLM 模拟器方案并在 profiling/result/ 内置了模拟器样例 Profile可直接用于流程验证详见本文第五节。2. 六个核心 profiling 参数README 要求修改benchmark.sh来配置剖析范围这六个参数控制着压测的三维搜索空间输入长度 × 输出长度 × 请求速率参数含义脚本内默认值说明input_start输入长度起点4profiling 的最小 input token 数input_limit输入长度终点2**124096即 4Kprofiling 的最大 input token 数output_start输出长度起点4最小 output token 数output_limit输出长度终点2**124096即 4K最大 output token 数rate_start请求速率起点1最小 req/srate_limit请求速率终点2**664最大 req/s从 benchmark.sh 的循环逻辑可以看到脚本按2 倍步长遍历各维度——input_len从input_start起每次*2output_len同理req_rate也从rate_start起每次*2直到rate_limit形成完整的组合矩阵例如默认配置即覆盖 input/output 均为 4、8、16…4096速率 1、2、4…64 的所有组合。因此这几个参数决定了一次剖析的粒度与总耗时范围越大、步长越小采样点越多结果越精细但压测总时长也越长。3. 完整命令行参数benchmark.sh除支持直接改脚本变量外还内置了完整的命令行参数解析whilecase结构便于不修改脚本即可定制每次剖析参数作用默认值-m, --model模型名称会写入结果并传给压测请求llama2-7b-o, --output结果输出文件路径脚本目录/result/model.jsonl--input-start / --input-limit输入 token 长度范围4/4096--output-start / --output-limit输出 token 长度范围4/4096--rate-start / --rate-limit请求速率范围req/s1/64--dry-run只打印配置不真正压测关闭--api-key模型服务的 API Key无--temperature生成温度0.0--workload指定 workload 数据集文件见第三节无另外脚本顶部还有两个可调变量TOTAL100每轮压测的请求数和TEMPERATURE0.0。执行时只需pip install -r requirements.txt # 安装依赖 ./benchmark.sh [your deployment name]结果会输出到result/目录OUTPUT_FILE默认值为${PATH_PREFIX}/result/${MODEL}.jsonlPATH_PREFIX即脚本所在目录。注意脚本会先在输出目录下建立prompts/子目录用于存放 workload 相关文件并把每轮gpu_benchmark.py的输出以追加方式写入同一个.jsonl文件--stream $OUTPUT_FILE因此一个结果文件里会包含多轮、多组合的全部指标记录。若只想快速验证参数配置是否正确可加--dry-run脚本会打印Start benchmark ...配置摘要后直接退出不发起任何压测请求。二、gpu_benchmark.py底层压测引擎与指标口径benchmark.sh的每个循环组合最终都调用 gpu_benchmark.py 执行一轮真实压测。它支持两种后端vllm真实压测与dryrun仅 sleep 1ms用于流程调试。请求到达模型遵循泊松过程——get_request中用np.random.exponential(1.0 / request_rate)采样相邻请求间隔若request_rate为inf则所有请求在 t0 一次性发出。每轮压测输出多条 JSON 指标记录metric 字段区分五类指标metric含义TPUT请求吞吐requests/slen(REQUEST_LATENCY) / benchmark_timeTTToken 吞吐tokens/s按 output token 总数计E2E端到端请求延迟含mean/P50/P90/P99TTFT首 Token 延迟Time To First TokenTPOT每输出 Token 延迟Time Per Output Token以仓库内置的 simulator-llama2-7b-a100.jsonl 为例同一组合input_tokens128, output_tokens4, request_rate1.0对应 5 条记录{input_tokens: 128, output_tokens: 4, request_rate: 1.0, seed: 0, model: llama2-7b, samples: 100, metric: TPUT, mean: 1.086357362685611} {input_tokens: 128, output_tokens: 4, request_rate: 1.0, seed: 0, model: llama2-7b, samples: 100, metric: TT, mean: 4.345429450742444} {input_tokens: 128, output_tokens: 4, request_rate: 1.0, seed: 0, model: llama2-7b, samples: 100, metric: E2E, mean: 0.5771615283563734, P50: 0.07662364543648437, P90: 1.549518520978747, P99: 3.8811742244416414} {input_tokens: 128, output_tokens: 4, request_rate: 1.0, seed: 0, model: llama2-7b, samples: 100, metric: TTFT, mean: 1.7528682947158812e-05, P50: 1.0521034710109234e-05, P90: 2.0274636335670964e-05, P99: 0.00016197128919884568} {input_tokens: 128, output_tokens: 4, request_rate: 1.0, seed: 0, model: llama2-7b, samples: 100, metric: TPOT, mean: 0.0, P50: 0.0, P90: 0.0, P99: 0.0}这就是gen_profile.py合成 Profile 的原始输入格式。该文件共 1400 行覆盖了 input 4~4K、output 4~4K、速率 1~64 的全部组合也可作为理解基准数据结构的现成参考。三、gen_benchmark_prompt.py让压测请求贴近真实负载默认情况下gpu_benchmark.py用hi * input_len生成合成 prompt见其sample_requests函数。若希望压测流量更贴近真实场景可用 gen_benchmark_prompt.py 从历史 trace如 JSONL 格式的真实对话记录中挑选出符合目标 input 长度、且模型实际 completion token 数不低于目标 output 长度的真实 prompt生成 workload 文件python gen_benchmark_prompt.py workload_path \ --input-tokens 128 --min-output-tokens 64 \ --tolerance 0.1 --qps 2.0 \ --host localhost --port 8010 --api-key any_key \ --total-prompts 100 --model llama2-7b \ --temperature 0.0 --output-dir ./result关键行为对应源码逻辑用 HuggingFaceAutoTokenizer对每条 trace 统计 prompt token 数失败时回退到 tiktoken只保留落在input_tokens × (1 ± tolerance)范围内的候选默认容差 0.1benchmark.sh内置调用时传 0.2对候选按 input 长度差异排序后逐个请求模型获取真实completion_tokens命中 min_output_tokens即停止生成的 workload 文件写入output-dir/prompts/prompt_inin_outout.json并以Timestamp字段模拟请求到达时间供gpu_benchmark.py的--workload-dataset-file选项按时间间隔回放。在benchmark.sh中只要传入--workload trace文件脚本就会为每个 (input, output) 组合自动调用该生成器内置参数tolerance 0.2、qps 2.0并把生成的 workload 文件传给gpu_benchmark.py --workload_dataset_file。需要说明gen_benchmark_prompt.py内置默认的tokenizer/model是 deepseek 系列deepseek-ai/deepseek-coder-6.7b-instruct/deepseek-coder-7b实际使用时应按你的模型替换。四、gen_profile.py把基准结果合成为满足 SLO 的 GPU Profile这是 README 介绍的第二个工具。运行python gen_profile.py -h即可查看完整帮助它的职责是读取 benchmark 产生的.jsonl结果按你设定的 SLO 目标筛选每个 (input, output) 组合下可达的最大吞吐输出一张 GPU Profile 矩阵。1. 支持的 SLO 参数源码中通过slos字典统一定义了 6 种可配置目标field即指标名见 gen_profile.py命令行参数SLO 含义默认值--tput吞吐目标RPSrequests/s0.0未设置--ttToken 吞吐目标tokens/s0.0未设置--e2e端到端延迟目标秒inf未设置--ttft首 Token 延迟目标秒inf未设置--tpat每所有 Token 时间目标秒inf未设置--tpot每输出 Token 时间目标秒inf未设置筛选逻辑gen函数核心对每个 (input, output) 组合先从基准 DataFrame 中取出该组合的全部记录再逐条 SLO 过滤——时间类指标默认inf取百分位值 slo.value的记录吞吐类指标默认0取mean slo.value的记录多 SLO 之间用请求速率求交集逐层收窄。最后在通过全部 SLO 的速率候选中用TPUT_TOLERANCE 0.9排除吞吐 请求速率 × 0.9的速率防止请求堆积再取满足条件的最大请求速率作为该格点的结论吞吐。2. 其他重要参数参数作用默认值--percentile延迟类 SLO 用哪个百分位0/50/90/990 表示用 mean0--cost该 GPU 的小时成本会写入 Profile 供成本优化使用1.0--benchmark指定基准结果文件路径默认读result/deployment.jsonlNone-o输出目标支持文件路径或 Redis URLNone打印到 stdout--verbose / -v打印详细生成过程与缩进 JSON关闭deployment位置参数部署名决定默认读取的基准文件与 Profile 的gpu字段必填3. 输出 Profile 的结构以仓库内置样例 simulator-llama2-7b-a100.json 为例生成的 Profile JSON 关键字段gpuGPU/部署标识如simulator-llama2-7b-a100costGPU 小时成本tputs二维吞吐矩阵行对应indexes[0]output tokens列对应indexes[1]input tokens每个格点值即该请求规模下满足 SLO 的最大吞吐requests/sindexes[output_tokens列表, input_tokens列表]与本例中[[4,8,16,32,64,128,256,512], [128,256,512,1024,2048]]一一对应e2e对应格点的端到端延迟矩阵秒ttft仅当设置了--ttft时才输出slos记录本次生成所使用的 SLO 条件如{percentile: 99, e2e: 5.0}——表示该 Profile 是P99 延迟 ≤ 5 秒约束下生成的结果。可以观察到一个直观规律input/output 越长格点吞吐越低、延迟越高矩阵右下角甚至出现0.0该规模下没有满足 SLO 的速率点。这正是 Profile 对GPU 能力边界的客观刻画。4. 输出到 Redis供 GPU Optimizer 直接消费-o参数除了写本地文件还支持 Redis URL格式为-o redis://[username:password]hostname:port[/db_name]?model[model_name]源码_try_store_redis会解析 URL、连接 Redis并以REDIS_PROFILE_KEY aibrix:profile_%s_%s % (model_name, deployment)作为 key 写入例如aibrix:profile_llama2-7b_simulator-llama2-7b-a100。注意model查询参数必填否则会报错退出。五、Profile 的下游消费与一键命令1. GPU Optimizer 的完整接入流程gpu_optimizer/README.md 给出了端到端接入步骤假设已在 Kubernetes 部署 GPU Optimizer 与 vLLM 模型# 1) 可选准备性能基准先暴露 Pod 端口 kubectl port-forward [pod_name] 8010:8000 1/dev/null 21 # 2) 生成 Profile 并写入 Redis先暴露 Redis 端口或用 make debug-init kubectl -n aibrix-system port-forward svc/aibrix-redis-master 6379:6379 1/dev/null 21 python optimizer/profiling/gen_profile.py simulator-llama2-7b-a100 -o redis://localhost:6379/?modelllama2-7b # 3) 通知 GPU Optimizer 重载 Profile通常非必需优化器会在数据足够时自动重载 kubectl -n aibrix-system port-forward svc/aibrix-gpu-optimizer 8080:8080 1/dev/null 21 curl http://localhost:8080/update_profile/llama2-7b # 4) 启动负载观察扩缩容效果走 gateway 8888 端口 python optimizer/profiling/gpu_benchmark.py --backendvllm --port 8888 --request-rate10 --num-prompts100 --input-len 2000 --output-len 128 --modelllama2-7b其中update_profile接口、/dash/model工作负载可视化均运行在 GPU Optimizer 的 8080 端口上。2. Profile 的读取端实现load_monitor/profile_reader.py 提供了两种读取器FileProfileReader从本地文件读兼容单 JSON 或 JSONL 多行格式和RedisProfileReader按aibrix:profile_%s_前缀从 Redis 拉取。两者最终都构造为GPUProfile对象定义于optimizer/types.py供扩缩容决策使用。3. 对接 Mélange异构 GPU 成本优化Profile 的tputs矩阵同样服务于 optimizer/solver/melange/ 目录下的 Mélange 求解器源自论文Mélange: Cost Efficient Large Language Model Serving by Exploiting GPU Heterogeneity。求解器输入中gpu_info列表的每个 GPU 需要提供name、cost小时租金和tputs与workload_distribution矩阵对齐的吞吐矩阵——这三者恰好就是gen_profile.py输出的gpu/cost/tputs字段。求解器据此给出用哪几种 GPU、各多少块、总小时成本最低的异构部署方案输出形如{A10G: 3, A100-80GB: 1, cost: 6.7}的推荐结果。这也解释了为什么gen_profile.py要单独保留cost参数它直接参与成本优化建模。4. Makefile 快捷命令仓库的 Makefile 封装了常用操作避免手敲长命令make DPsimulator-llama2-7b-a100 benchmark # 等价于 benchmark.sh -m DP make DPsimulator-llama2-7b-a100 gen-profile # 生成 Profile 写入本地 Redis make debug-init # 一键 port-forward GPU Optimizer 与 Redis make debug-update-profile # curl 更新 Profile make debug-workload # 用 10 req/s 负载触发扩缩容演示六、样例与快速验证没有 GPU 也能跑通流程如果暂时没有 GPU 环境仓库内置了CPU 版 vLLM 模拟器的样例结果见 gpu_optimizer/README.md 的说明位于 profiling/result/simulator-llama2-7b-a100.jsonl原始基准数据1400 行五类指标simulator-llama2-7b-a100.json已生成的 ProfileP99 E2E ≤ 5ssimulator-llama2-7b-a40.json/simulator-llama2-7b-a40.jsonl另一型号 GPU 的对应样例_obsoleted_v1.json为废弃的旧版格式。用模拟器验证完整链路的命令为make debug-init # 暴露 Redis 6379 与 GPU Optimizer 8080 python optimizer/profiling/gen_profile.py simulator-llama2-7b-a100 -o redis://localhost:6379/?modelllama2-7b成功执行后可在 Redis 中看到aibrix:profile_llama2-7b_simulator-llama2-7b-a100键说明 Profile 已就绪。A100 与 A40 两份样例 Profile 还可用于对比不同 GPU 能力或作为 Mélange 求解器异构优化演示的输入。总结AIBrix 的 GPU Profiling 工具集是一条完整的数据流水线benchmark.sh编排三维压测空间input × output × rategpu_benchmark.py产出五类指标TPUT/TT/E2E/TTFT/TPOT及 P50/P90/P99 百分位可选地由gen_benchmark_prompt.py注入真实 trace 负载最后由gen_profile.py在 SLO 约束下合成 GPU Profile 矩阵并通过 Redis 或文件交付给 GPU Optimizer 扩缩容器与 Mélange 成本求解器。掌握这套流程后你可以为任何 vLLM 模型 GPU 组合生成专属能力画像为异构 GPU 集群的自动扩缩容与成本优化提供量化依据。关键参考文件官方指南 profiling/README.md本文骨架、压测编排 benchmark.sh、压测引擎 gpu_benchmark.py、Profile 合成器 gen_profile.py、trace 请求生成 gen_benchmark_prompt.py、组件集成说明 gpu_optimizer/README.md、求解器说明 solver/melange/README.md。【免费下载链接】aibrixCost-efficient and pluggable Infrastructure components for GenAI inference项目地址: https://gitcode.com/GitHub_Trending/ai/aibrix创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表