ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

模型压测评估

模型压测评估 EvalScope模型压测文章目录EvalScope模型压测一、环境构建1.1 硬件与驱动环境1.2 模型部署 (LlamaFactory)1.3 压测工具部署 (EvalScope)二、压测实施与参数配置2.1 压测目标与指标2.2 压测场景设计2.3 EvalScope 压测命令示例三、压测结果与分析3.1 性能数据汇总3.2 瓶颈分析3.3 **HuggingfaceEngine Token 吞吐量瓶颈原因分析**1. 静态单请求推理batch_size1造成 GPU 算力浪费2. semaphore 增加显存增大但是token吞吐量不变四、总结与后续验证一、环境构建1.1 硬件与驱动环境关键组件当前版本/型号显卡型号NVIDIA GeForce RTX 5060 (WDDM)显卡驱动577.05CUDA 版本12.9显卡内存8 GB1.2 模型部署 (LlamaFactory)部署模型命令llamafactory-cli api examples/inference/qwen3.yamlmodel_name_or_path:D:\LlamaFactory\model\Qwen2.5-0.5B-Instruct-FULL# 全量微调后的模型template:qweninfer_backend:huggingfacetrust_remote_code:true# 生成参数配置压测时需关注其对性能的影响do_sample:true# 开启采样模式若追求极致速度可设为 falsetemperature:0.1# 较低的 temperature 可减少随机性加速生成top_p:0.8# 核采样概率repetition_penalty:1.1# 重复惩罚系数适中设置可避免无效生成1.3 压测工具部署 (EvalScope)EvalScope 安装参考官网https://evalscope.readthedocs.io/zh-cn/latest/get_started/installation.html。功能模块安装命令核心性能评估pip install evalscope[perf]Web 可视化服务pip install evalscope[service]二、压测实施与参数配置2.1 压测目标与指标本次压测主要评估微调后 Qwen2.5-0.5B-Instruct 模型在特定硬件上的服务性能核心指标包括-吞吐量Throughput每秒处理的 Token 数量Tokens/s。延迟Latency首 Token 延迟Time to First TokenTTFT从请求发出到收到第一个 Token 的时间。生成延迟每个 Token 的平均生成时间。资源利用率GPU 利用率、显存占用情况。错误率请求失败比例。2.2 压测场景设计为系统性验证模型推理性能的两个核心维度设计以下两组测试用例第一组预填充性能测试验证输入长度对首 Token 延迟的影响此组测试固定并发数为 5通过改变输入长度观察模型预填充Prefill阶段的计算开销对首 Token 延迟TTFT的影响。场景编号并发用户数输入长度 (Tokens)输出长度 (Tokens)核心验证目标P15512100短输入下的基准 TTFTP251024100中等长度输入的 TTFT 变化P352048100中长输入下的 TTFTP454096100长输入下的TTFT第二组并发性能测试验证并发场景下的性能瓶颈此组测试固定输入/输出长度通过逐步增加并发用户数探测系统吞吐量瓶颈、延迟增长趋势及资源饱和点。场景编号并发用户数输入长度 (Tokens)输出长度 (Tokens)C152048100C2102048100C3202048100C4302048100C5402048100C65020481002.3 EvalScope 压测命令示例启动压测的脚本如下需先确保模型 API 服务已运行在http://localhost:9001由于本地 8000 端口被占用部署时使用了 9001 端口fromevalscope.perf.mainimportrun_perf_benchmarkfromevalscope.perf.argumentsimportArguments### 预填充性能测试验证输入长度对首 Token 延迟的影响forinput_tokenin[512,1024,2048,4096]:task_cfgArguments(parallel5,number10,modelmodel name,urlhttp://127.0.0.1:9001/v1,apiopenai,datasetrandom,api_key*********,min_tokens100,max_tokens100,prefix_length0,min_prompt_lengthinput_token,max_prompt_lengthinput_token,tokenizer_pathQwen/Qwen2.5-0.5B-Instruct,extra_args{ignore_eos:True})resultsrun_perf_benchmark(task_cfg)### 并发场景下的性能测试验证 token 的生成吞吐量与延迟task_cfgArguments(parallel[5,10,20,30,40,50],number[10,20,40,60,80,100],modelmodel name,urlhttp://127.0.0.1:9001/v1,apiopenai,datasetrandom,api_key*********,min_tokens100,max_tokens100,prefix_length0,min_prompt_length2048,max_prompt_length2048,tokenizer_pathQwen/Qwen2.5-0.5B-Instruct,extra_args{ignore_eos:True})resultsrun_perf_benchmark(task_cfg)三、压测结果与分析3.1 性能数据汇总下表展示了预填充性能测试场景下的关键性能指标场景并发数输入长度 (Tokens)TTFT 最大值ms平均 TTFT (ms)GPU 利用率峰值请求成功率P1551216.4813.2260%100%P25102460.6516.7585%100%P35204844.3621.19100%100%P45409682.6326.83100%100%下表展示了并发性能测试场景下的关键性能指标3.2 瓶颈分析预填充性能测试从 P1512 Tokens到 P44096 Tokens输入长度增加 8 倍平均 TTFT 从 13.22ms 增长到 26.83ms约翻一倍。预填充阶段的计算开销与输入长度呈正相关且在该模型和硬件上增长相对可控。并发性能测试压测场景下HuggingfaceEngine#### MAX_CONCURRENT最大协程并发默认1self.semaphoreasyncio.Semaphore(int(os.getenv(MAX_CONCURRENT,1)))问题1模型部署的协程并发 semaphore 默认为 1token的吞吐量在并发增加的情况下稳定在40左右显存基本稳定在 30%#### MAX_CONCURRENT最大协程并发默认30self.semaphoreasyncio.Semaphore(int(os.getenv(MAX_CONCURRENT,30)))问题2模型部署的协程并发 semaphore 设置为 30token的吞吐量在并发增加的情况下输出的token吞吐量依然在40左右。显存利用率升到 100%3.3HuggingfaceEngine Token 吞吐量瓶颈原因分析基于上述测试结果分析了 HuggingfaceEngine 实现发现以下两个核心瓶颈1. 静态单请求推理batch_size1造成 GPU 算力浪费问题每个请求独立调用 model.generate()传入的 input_ids 形状硬编码为 [1, seq_len]即 batch_size1。如 hf_engine.py:118 及 _stream_chat 函数所示每个请求独占一个 Thread 与 TextIteratorStreamer 实例形成“一请求一线程一流”的强绑定模式。####### hf_engine.py:118 — 构造模型推理请求参数prompt_lengthlen(prompt_ids)inputstorch.tensor([prompt_ids],devicemodel.device)####### hf_engine.py _stream_chat函数streamerTextIteratorStreamer(tokenizer,skip_promptTrue,skip_special_tokensgetattr(gen_kwargs[generation_config],skip_special_tokens,True),)gen_kwargs[streamer]streamer threadThread(targetmodel.generate,kwargsgen_kwargs,daemonTrue)thread.start()defstream():try:returnstreamer.__next__()exceptStopIteration:raiseStopAsyncIteration()returnstream2. semaphore 增加显存增大但是token吞吐量不变问题增大 MAX_CONCURRENT 仅放宽了 Python 层的并发准入允许更多请求同时进入 model.generate()但这会触发显存线性膨胀而无法换取吞吐提升显存开销每个请求独立分配 KV Cache显存占用随并发数线性增长。MAX_CONCURRENT 1 → 显存 ≈ 模型权重 1 × KV CacheMAX_CONCURRENT 30→ 显存 ≈ 模型权重 30 × KV Cache显存膨胀吞吐停滞尽管并发数增加系统有效吞吐量保持不变根源在于以下架构瓶颈的叠加效应所有请求共享同一个 CUDA Default StreamGPU Kernel 严格按提交顺序排队执行。30个请求并非并行计算而是时分复用 GPU 算力导致大量空闲等待。# hf_engine.py L312: 多线程共享默认 CUDA StreamthreadThread(targetmodel.generate,kwargsgen_kwargs,daemonTrue)四、总结与后续验证总结Semaphore 控制的是 Python 层的并发准入而 GPU 的实际并行度取决于推理引擎是否支持 Continuous Batching如 vLLM/SGLang。HuggingFace Engine 的 Static Batching 机制决定了其 GPU 利用率与并发数无关。以上分析基于当前环境与 HuggingFace Engine 实现欢迎交流探讨不同见解或优化方案。后续验证计划为充分挖掘 RTX 5060 硬件的潜力验证其极限 Token 吞吐量下一步将采用 vLLM 推理引擎重新部署该模型进行对比测试。
返回列表