江苏网站建设价格低宏基陆通工程建设有限公司网站
江苏网站建设价格低,宏基陆通工程建设有限公司网站,创建全国文明城市应知应会,桂林生活最新网高性能计算#xff1a;优化InternLM2-Chat-1.8B在GPU上的并行推理速度
最近在折腾大模型推理#xff0c;发现一个挺有意思的现象#xff1a;很多朋友把模型部署起来#xff0c;能跑通就满足了#xff0c;但很少去琢磨怎么让它跑得更快、更省资源。这就像你买了一台性能强…高性能计算优化InternLM2-Chat-1.8B在GPU上的并行推理速度最近在折腾大模型推理发现一个挺有意思的现象很多朋友把模型部署起来能跑通就满足了但很少去琢磨怎么让它跑得更快、更省资源。这就像你买了一台性能强劲的电脑却只用来处理文档有点浪费了它的潜力。特别是像InternLM2-Chat-1.8B这样的轻量级模型很多人觉得它参数少推理速度肯定不差。但实际上如果配置不当它的性能可能连一半都发挥不出来。今天咱们就来聊聊怎么在GPU上尤其是像星图这样的云平台上把InternLM2-Chat-1.8B的推理速度“榨干”让它真正跑出高性能。这篇文章不是泛泛而谈我会结合具体的代码和配置带你一步步调整目标是让你部署的模型在保证回答质量的同时吞吐量单位时间处理的请求数和延迟单个请求的响应时间都有肉眼可见的提升。无论你是做原型验证还是准备上线服务这些优化思路都能用得上。1. 理解推理速度的“瓶颈”在哪里在开始动手调优之前咱们得先搞清楚到底是什么在拖慢模型推理的后腿。盲目调整参数效果可能适得其反。1.1 主要性能开销分析模型推理简单说就是数据在计算图里走一圈。这个过程里最耗时的通常是以下几块计算本身也就是矩阵乘法、注意力机制这些核心运算。这块主要吃GPU的算力FLOPS。内存访问把模型参数、中间结果从显存搬到GPU核心里计算这个过程如果慢GPU算力再强也得等着。这被称为“内存墙”。数据准备与传输包括把用户的输入文本转换成模型能懂的Token以及把GPU计算好的结果取回来再转换成文本。这部分在CPU上进行如果处理不好GPU就会经常闲着。框架开销你用的推理框架比如PyTorch原生的、或者vLLM、TensorRT-LLM等本身也有调度、管理的成本。对于InternLM2-Chat-1.8B这样的小模型“内存访问”和“数据准备/传输”往往比“纯计算”更容易成为瓶颈。因为它的计算量相对不大但如果数据搬运效率低或者CPU预处理太慢GPU的利用率就上不去。1.2 关键优化指标吞吐量 vs 延迟优化前你得明确自己的目标是什么因为这两个指标有时候是“鱼与熊掌”。吞吐量指服务器每秒能处理多少个请求比如requests per second, RPS。如果你在做批量处理或者希望服务能同时应对很多用户这个指标就特别重要。提高批处理大小batch size是提升吞吐量最直接有效的方法。延迟指处理单个请求所需要的时间从收到请求到返回结果。对于聊天机器人这种需要即时交互的场景低延迟是关键。过大的批处理可能会增加队列等待时间反而拉高延迟。我们的优化就是在吞吐量和延迟之间根据你的实际场景找到一个最佳的平衡点。2. 核心优化手段一批处理大小调优批处理Batching是提升GPU利用率和吞吐量的“王牌”手段。原理很简单让GPU一次处理多个请求分摊掉内存读取和内核启动的开销。2.1 如何找到最佳批处理大小不是越大越好。你需要找到一个“甜点”sweet spot。下面是一个简单的测试脚本帮你寻找这个点。import torch from transformers import AutoTokenizer, AutoModelForCausalLM import time # 加载模型和分词器 model_name internlm/internlm2-chat-1_8b tokenizer AutoTokenizer.from_pretrained(model_name, trust_remote_codeTrue) model AutoModelForCausalLM.from_pretrained( model_name, torch_dtypetorch.float16, # 使用半精度节省显存加速计算 device_mapauto, # 自动分配到可用GPU trust_remote_codeTrue ) model.eval() # 切换到推理模式 # 准备测试提示词 prompts [ 请用一句话介绍人工智能。, Python和Java的主要区别是什么, 如何学习深度学习, 写一首关于春天的五言绝句。, ] * 5 # 复制几次制造更多测试数据 print(f总共准备了 {len(prompts)} 个提示词用于测试。) # 测试不同的批处理大小 batch_sizes [1, 2, 4, 8, 16] results {} for batch_size in batch_sizes: print(f\n正在测试批处理大小: {batch_size}) total_tokens 0 start_time time.time() # 分批处理 for i in range(0, len(prompts), batch_size): batch_prompts prompts[i:ibatch_size] # 编码批处理数据 inputs tokenizer(batch_prompts, return_tensorspt, paddingTrue, truncationTrue, max_length512).to(model.device) with torch.no_grad(): # 禁用梯度计算节省内存和计算 outputs model.generate( **inputs, max_new_tokens50, # 每个提示生成50个新token do_sampleFalse, # 贪婪解码速度更快适合性能测试 temperature0.1, ) # 解码并计算生成的token总数粗略估计 for output_seq in outputs: generated_tokens output_seq[inputs[input_ids].shape[1]:] # 获取新生成的部分 total_tokens len(generated_tokens) end_time time.time() total_duration end_time - start_time # 计算指标 throughput total_tokens / total_duration # Tokens per second avg_latency total_duration / (len(prompts) / batch_size) * 1000 # 平均每批的延迟毫秒 results[batch_size] { 总耗时(秒): round(total_duration, 2), 总生成token数: total_tokens, 吞吐量(tokens/秒): round(throughput, 2), 平均批延迟(毫秒): round(avg_latency, 2) } print(f 吞吐量: {throughput:.2f} tokens/秒, 平均批延迟: {avg_latency:.2f} 毫秒) # 打印结果对比 print(\n *60) print(批处理大小优化测试结果总结) print(*60) for bs, metrics in results.items(): print(fBatch Size {bs}: 吞吐量{metrics[吞吐量(tokens/秒)]} tok/s, 延迟{metrics[平均批延迟(毫秒)]}ms)运行这个脚本你会看到类似下面的输出。关键看吞吐量的增长曲线。通常随着batch size增大吞吐量会先快速上升然后增长变缓甚至可能因为显存不足OOM而下降。那个拐点附近的值就是比较理想的批处理大小。2.2 动态批处理与持续批处理上面的例子是静态批处理。在实际服务中请求是随机到达的更高级的做法是动态批处理服务端收集一小段时间内到达的请求凑成一个批次进行处理。这需要推理框架的支持如vLLM、TGI。持续批处理这是vLLM等框架的“杀手锏”。在流式输出时如果一个请求先生成完了可以立刻释放它占用的资源用来处理新请求的初始部分极大提升GPU利用率。对于聊天这种交互场景效果显著。给你的建议在星图平台上部署时如果追求极致性能强烈考虑使用支持持续批处理的推理后端。3. 核心优化手段二选择高效的推理后端用原生的PyTorchtransformers库跑推理简单但效率未必最高。专业的推理后端做了大量底层优化。3.1 vLLM为吞吐量而生vLLM 是当前大模型推理领域的明星它的核心是PagedAttention技术能像操作系统管理内存一样管理Attention的KVCache极大减少了内存碎片从而支持更大的批处理。在星图平台你可以寻找预置了vLLM的镜像或者自己安装。使用vLLM运行InternLM2-Chat-1.8B非常简单# 启动vLLM服务假设已在有GPU的环境安装好vLLM python -m vllm.entrypoints.openai.api_server \ --model internlm/internlm2-chat-1_8b \ --served-model-name internlm2-chat-1.8b \ --tensor-parallel-size 1 \ # 张量并行数单卡设为1 --gpu-memory-utilization 0.9 \ # GPU显存使用率目标 --max-model-len 2048 # 模型最大上下文长度然后你就可以用OpenAI兼容的API来调用了from openai import OpenAI client OpenAI( api_keytoken-abc123, base_urlhttp://localhost:8000/v1 # vLLM服务地址 ) # 单个请求 response client.chat.completions.create( modelinternlm2-chat-1.8b, messages[{role: user, content: 你好请介绍一下你自己。}], temperature0.1, max_tokens100, ) print(response.choices[0].message.content) # 批处理请求 (vLLM会自动优化) batch_responses [] prompts [问题1, 问题2, 问题3] for prompt in prompts: completion client.chat.completions.create( modelinternlm2-chat-1.8b, messages[{role: user, content: prompt}], max_tokens50, ) batch_responses.append(completion)vLLM会自动管理批处理你只需要像调用普通API一样发送请求它会在后台高效地组织计算。3.2 TensorRT-LLMNVIDIA的终极优化如果你使用的是NVIDIA GPU星图平台通常提供并且模型已经支持那么TensorRT-LLM 能带来最大的性能提升。它将模型编译成高度优化的内核充分利用Tensor Core。不过它的使用步骤稍复杂需要将Hugging Face格式的模型先编译build成TensorRT引擎。这个过程有点像把Python代码编译成C一次编译多次高效运行。简单对比一下易用性transformersvLLMTensorRT-LLM极致性能TensorRT-LLMvLLMtransformers功能特性vLLM持续批处理、前缀缓存 transformersTensorRT-LLM更偏底层性能对于InternLM2-Chat-1.8B如果你的首要目标是高并发、高吞吐vLLM是目前最省心且效果显著的选择。如果追求单请求的最低延迟并且愿意花时间折腾可以研究TensorRT-LLM。4. 核心优化手段三GPU内存与计算精度4.1 使用半精度FP16/BF16现代GPU如V100、A100、H100对半精度计算有硬件加速速度更快而且显存占用减半。这几乎是必选项。# 加载模型时直接指定半精度 model AutoModelForCausalLM.from_pretrained( model_name, torch_dtypetorch.float16, # 或者 torch.bfloat16 (如果GPU支持) device_mapauto, trust_remote_codeTrue )注意torch.bfloat16的数值表示范围更接近FP32训练时更稳定推理时如果GPU支持如A100及以上用BF16可能更好。FP16更通用。4.2 量化Quantization如果还想进一步压缩显存、提升速度可以考虑量化。比如使用4-bit或8-bit量化。from transformers import BitsAndBytesConfig # 使用bitsandbytes进行4-bit量化加载 bnb_config BitsAndBytesConfig( load_in_4bitTrue, bnb_4bit_compute_dtypetorch.float16, # 计算时仍用FP16 bnb_4bit_use_double_quantTrue, bnb_4bit_quant_typenf4, # 4-bit NormalFloat量化 ) model AutoModelForCausalLM.from_pretrained( model_name, quantization_configbnb_config, # 指定量化配置 device_mapauto, trust_remote_codeTrue )重要提醒量化会轻微损失模型精度可能影响生成质量。对于1.8B的小模型FP16通常已经足够快和轻量量化带来的收益可能不如大模型明显建议先测试效果再决定。4.3 利用Flash Attention 2如果推理后端支持如最新版的transformers、vLLM确保启用Flash Attention 2。它能大幅优化Attention计算的内存和速度。# 安装 flash-attn 库 # pip install flash-attn --no-build-isolation model AutoModelForCausalLM.from_pretrained( model_name, torch_dtypetorch.float16, device_mapauto, trust_remote_codeTrue, attn_implementationflash_attention_2, # 启用Flash Attention 2 )5. 实战在星图GPU平台上进行综合调优假设你在星图平台拥有一台A100的GPU实例。我们的优化组合拳可以这样打选择镜像优先选择预装了vLLM或TGI的深度学习镜像省去环境配置的麻烦。部署模型使用vLLM部署InternLM2-Chat-1.8B。启动命令可以调整关键参数python -m vllm.entrypoints.openai.api_server \ --model /path/to/internlm2-chat-1_8b \ --served-model-name internlm2-chat \ --tensor-parallel-size 1 \ --gpu-memory-utilization 0.85 \ # 留一点余量给系统 --max-num-batched-tokens 4096 \ # 限制单批最大token数控制延迟 --max-num-seqs 256 \ # 最大并发序列数 --dtype half # 使用FP16客户端优化实现一个简单的客户端批处理队列将短时间内收到的用户请求聚合后再发送给vLLM服务端。对于流式响应使用Server-Sent Events (SSE)等方式并利用vLLM的持续批处理特性。监控与调整使用nvidia-smi监控GPU利用率Volatile GPU-Util。理想情况下应长期保持在70%以上。监控服务的延迟P50, P99和吞吐量RPS。根据监控数据动态调整--max-num-batched-tokens和--max-num-seqs参数。6. 总结给InternLM2-Chat-1.8B这类模型做推理加速其实是个系统工程不是改一个参数就万事大吉。从今天的讨论来看最立竿见影的通常是启用vLLM并配合适当的批处理大小。它解决了内存管理和请求调度的大问题让你不用太操心底层细节。精度方面FP16是起步点能省一半显存速度也有提升。量化可以尝试但对小模型要谨慎先看看生成质量能不能接受。Flash Attention 2这类优化只要环境支持就顺手打开基本是“免费的午餐”。最后一定要结合业务场景。如果是后台批量处理任务就大胆提高批处理大小追求吞吐量。如果是实时对话就要在批处理大小和延迟之间仔细权衡利用好持续批处理技术。在星图这样的云平台上多利用预置的高性能镜像和监控工具能让你事半功倍。优化本身也是个迭代过程最好的办法就是搭起一个简单的测试环境用我们今天提到的几个方法轮番试一遍用真实数据说话找到最适合你那个场景的“黄金配置”。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。