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

资讯详情

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

大模型推理优化实战指南:从原理到部署调优

大模型推理优化实战指南:从原理到部署调优 我做了几年大模型应用落地发现一个特别普遍的现象很多人训练、微调玩得挺溜一到推理阶段就卡壳。模型是跑起来了但响应慢得像蜗牛显存动不动就爆并发一上来直接OOM成本更是高得让人肉疼。这个“LLM 4: 大模型推理优化基础”其实就是我们团队内部做推理性能调优的实战沉淀。以前大家总觉得推理优化是个黑盒好像很玄乎其实拆开来看核心就是围绕延迟、吞吐量、显存占用、成本这四个维度做文章。很多人问我说大模型部署到底怎么搞本地部署用Ollama还是vLLM为什么同一个模型在不同框架下性能差那么多这些问题归根结底都指向同一个东西推理优化。这篇文章我不会跟你扯太悬的理论就从实际工程角度出发把大模型推理优化的底层逻辑、关键技术、框架选型和实战调参经验一次性讲清楚。不管你是刚入门想了解大模型推理原理还是已经在做部署优化但效果不理想这篇文章应该都能给你一些参考。1. 大模型推理优化到底在解决什么问题咱们先把问题定义清楚。很多人一上来就谈量化、剪枝、蒸馏但连推理优化的目标都没搞明白。推理优化的核心矛盾就是模型计算需求与实际硬件资源之间的差距。我们需要从四个维度理解这个差距。1.1 延迟、吞吐量、显存、成本四个维度的博弈延迟很好理解就是从你输入问题到模型输出第一个字的时间。在对话场景里我们通常更关心首Token延迟和每个Token的生成速度。你打开一个AI对话应用输入一句话转圈圈转了10秒钟用户体验就非常差了这个就是延迟问题。吞吐量则是指单位时间内系统能处理的请求数量或生成的Token数量。如果你在做的是一个面向大量用户的API服务吞吐量往往比单次延迟更重要。高吞吐意味着同样的硬件资源能服务更多用户体现在账面上就是成本下降。显存占用是个硬约束。大模型的参数量和显存占用基本成正比比如一个70B参数量的模型光权重用FP16存就需要约140GB显存单张A100 80G都放不下。显存不够模型就跑不起来更别提什么优化了。成本是前三个维度的综合体现。显卡很贵电费不便宜同样的服务如果能让GPU利用率翻倍一年省下来的钱非常可观。说到底推理优化就是在延迟、吞吐、显存、成本这四者之间找平衡点。1.2 为什么解码阶段比预填充阶段更值得关注大模型生成文本的过程分为两个阶段预填充和自回归解码。预填充阶段模型并行处理你输入的所有Token一次性计算出Key和Value解码阶段模型逐Token生成每生成一个字都需要一次完整的前向计算。有意思的是解码阶段往往占据了整个推理时间的大部分。假设你输入100个Token输出500个Token预填充阶段只做一次前向计算解码阶段要做500次。这个比例直接决定了我们需要把优化重心放在哪里。解码阶段的根本瓶颈在于带宽不仅仅在于计算。因为每个Token的生成都要读取模型全部权重参数而权重本身有几百GB。我打个比方模型权重就像一个巨大的图书馆每次生成一个Token都要把整个图书馆翻一遍。GPU计算速度很快但在读取权重这件事上却成了瓶颈这就是著名的“内存墙”问题。2. 推理优化的核心技术原理搞懂这些菜鸟也能变老手聊完方向接下来进入核心环节。这一部分我会逐项拆解推理优化的关键技术包括KV Cache、量化、批处理策略、投机解码和模型架构调整。每一项单独看都不复杂但组合起来效果非常可观。2.1 KV Cache为什么缓存K和V矩阵能大幅提速KV Cache是大模型推理优化里最基础、最重要的一项技术。简单理解在生成第N个Token时模型需要计算当前Token与之前所有Token的注意力关系。如果不做缓存每次都要重新计算之前所有Token的Key和Value矩阵这个计算量会随着生成长度线性增长非常浪费。有了KV Cache情况就不一样了。在预填充阶段我们把输入Token的K和V矩阵算好并缓存到显存里在后续的解码阶段只需要计算当前Token的K和V然后从缓存里取出之前的全部K和V做注意力计算。以一个输入100个Token、输出1000个Token的请求为例不使用KV Cache意味着每次解码都要重新计算之前所有Token的K和V总计算量大概是使用缓存方案的数百倍。这不是夸张是实打实的计算复杂度分析结果。需要特别注意的是KV Cache会占用额外的显存。每个Token的KV大小取决于模型层数、注意力头数、Head尺寸和精度。假设一个7B模型有32层、32个注意力头、Head维度为128使用FP16精度那么每个Token的KV Cache占用约0.5MB。当并发请求多、序列又长时KV Cache的显存占用甚至会超过模型权重本身。2.2 量化如何在精度损失和性能提升之间取平衡量化就是减少模型权重的数值精度。把FP32的浮点数变成INT8或者INT4模型体积和显存占用都能显著下降同时推理速度也会因为更少的数据搬运而提升。为什么量化能提效回到刚才“内存墙”的解释。解码过程每次要读取全部模型权重权重数据量小了读取时间就短了。比如FP16的7B模型权重要14GBW8A8量化后能压到7GBINT4量化后能压到3.5GB左右。量化的主要技术路线有三条训练后量化PTQ、量化感知训练QAT和近年来很火的FP8混合精度训练。PTQ最简单不需要重新训练直接对训练好的模型做权重转换QAT精度保持最好但需要重新训练成本高FP8更适合H100这些新硬件的场景。实际落地时我的经验是先从PTQ开始试。绝大多数场景下INT8量化结合适当的校准数据质量损失可以控制在1%-2%以内但推理速度提升和显存节约非常明显。INT4量化风险更高需要谨慎评估业务场景对模型精度的容忍度。如果你跑的是代码生成、数学推理这些对精度敏感的任务建议先做一轮完整的评估再决策。2.3 连续批处理和PagedAttention提高GPU利用率的杀手锏很多人以为批处理就是把多个请求拼在一起处理听起来很简单。但大模型推理有个特殊性不同请求的输入输出长度差别很大如果同步处理必须等最长的请求完成才能释放资源会产生大量碎片时间和显存浪费。连续批处理解决了这个问题的关键部分。它的思路是动态地往GPU上添加和移除请求一个请求生成完了就立刻释放它的位置把新的请求补进来。这样GPU始终在满负荷运转吞吐量提升非常明显。PagedAttention则是从显存管理角度做的优化思路参考了操作系统里的虚拟内存分页机制。它把KV Cache切分成固定大小的块不要求显存物理连续从而显著减少显存碎片。vLLM框架的核心卖点之一就是PagedAttention实测在长序列、高并发场景下吞吐量比朴素实现能提升好几倍。2.4 投机解码把串行生成变成并行查找自回归解码的痛点是串行每生成一个Token都要等待前一个Token完成。投机解码的思路则比较巧妙它用一个小模型Draft Model先快速草拟出后续几个Token再让大模型一次性验证这些Token的正确性。因为小模型速度快草拟过程几乎不耗时而大模型只需要做一次并行前向计算来验证。如果草拟的Token都对了那么一次前向就能生成多个Token效率翻倍。如果某些Token被拒绝了就从头开始也算是有一定收益。实际落地中投机解码对延迟的改善非常显著尤其是小批次、低并发的场景。但在大批次场景下收益会有所回落因为此时大模型本身的计算已经很饱和小模型草拟节省的那点计算量相对有限。2.5 模型架构层面的优化思路除了运行时优化模型结构本身也能做文章。多查询注意力MQA和分组查询注意力GQA是当前大模型架构设计的主流选择它们通过让多个查询头共享一组Key和Value显著减少KV Cache的大小和带宽消耗。LLaMA 2和LLaMA 3都用了GQA稳定版推理优化效果比MHA版本好得多。另外如今大模型序列长度越来越长从2K到8K、32K甚至128K。长序列场景下可以针对注意力计算做稀疏化或线性化近似减少远距离Token之间的注意力计算量。模型架构优化不一定适合每个人因为一般需要重新训练或继续预训练。我建议优先从KV Cache、量化、批处理这些运行时优化入手性价比更高。3. 推理框架选型与部署实战各显神通怎么选原理讲明白后我们进入实操环节。当前主流的大模型推理框架有vLLM、TensorRT-LLM、Ollama、Hugging Face TGI等各有各的强项和适用场景。工具选对了事半功倍选错了再牛的优化技巧也白搭。3.1 vLLM、TensorRT-LLM、Ollama、TGI主流方案优缺点对比vLLM是目前开源社区热度最高、上手最快的方案。它的核心优势是PagedAttention 连续批处理吞吐量非常优秀API兼容OpenAI格式和LangChain、LlamaIndex等生态无缝对接。如果你需要快速上线一个高并发的GPU推理服务vLLM是第一选择。TensorRT-LLM是英伟达的亲儿子能够把模型编译成高度优化的TensorRT引擎单卡性能通常比vLLM还要好但配置复杂得多。它的量化支持也做得非常细从FP8、INT8到INT4都有完整工具链。如果你的环境是英伟达的卡且追求极致性能愿意花时间调优TensorRT-LLM是值得投入的。Ollama主打的是轻量化和易用性。一条命令就能把模型拉下来跑起来非常适合本地开发、个人学习或者小规模内部服务。我平时做Demo、验证模型效果时基本都用Ollama。但它在高并发、大规模场景下表现一般生产环境不太推荐。Hugging Face TGI是Hugging Face官方的推理方案胜在和Transformers生态紧密集成支持各种新模型架构。它的性能和vLLM差不多但显存利用效率略逊一筹。如果你的团队本来就在用Transformers做研究TGI的切换成本更低。四者之间没有绝对的好坏主要看你的场景。我列个表格方便你快速对比参考框架核心优势适合场景上手难度性能表现vLLMPagedAttention、高吞吐生产环境高并发API服务低优秀TensorRT-LLM极致性能、深度量化英伟达GPU生产环境高最佳Ollama简单易用、开箱即用本地开发、学习、小规模极低一般TGI生态集成好研究环境和Transformers用户低良好3.2 本地部署实操我用Ollama快速跑通一个7B模型如果你想最快速度体验大模型推理我推荐先用Ollama跑通一遍流程。这里以目前最常用的Qwen2.5-7B-Instruct为例。第一步是安装Ollama。Linux环境下一行命令就搞定curl -fsSL https://ollama.com/install.sh | sh安装完成后启动服务ollama serve然后拉取模型并运行ollama pull qwen2.5:7b-instruct ollama run qwen2.5:7b-instruct参数很简单模型名称加版本标签即可。Ollama默认会自动做INT4/INT8量化和层数裁剪所以即使你的显卡只有8G显存也能勉强跑起来7B模型。Ollama也提供了OpenAI兼容的API接口方便你自己写客户端调用这里顺便说一下curl http://localhost:11434/v1/chat/completions \ -H Content-Type: application/json \ -d { model: qwen2.5:7b-instruct, messages: [{role: user, content: 你好介绍一下你自己}] }Ollama默认会下载Q4_K_M量化版本的模型也就是4-bit量化。这样7B模型大概只需要4.5GB显存普通消费级显卡就能运行。如果你追求更好的生成质量可以改成Q8或者FP16版本显存需求会上升到8-14GB但效果确实会更好。3.3 vLLM部署生产级推理服务参数配置详解如果你要部署生产环境我的主力推荐还是vLLM。这里分享一个完整的部署方案。先把依赖装好pip install vllm然后写一个标准的启动命令python -m vllm.entrypoints.openai.api_server \ --model /path/to/model \ --served-model-name my-model \ --tensor-parallel-size 2 \ --gpu-memory-utilization 0.9 \ --max-model-len 8192 \ --max-num-seqs 32 \ --quantization awq几个关键参数要特别注意--tensor-parallel-size表示使用几张GPU做张量并行。当单卡显存放不下模型时必须把这个参数调大让多张卡共同承载模型权重和KV Cache。--gpu-memory-utilization控制最多使用多少比例的显存默认值0.9表示预留10%给CUDA上下文和其他开销。这个值可以适当调高但不能到1.0否则容易OOM。--max-model-len是最大序列长度包括输入和输出。这个值不是越大越好因为KV Cache显存占用和序列长度成正比。--max-num-seqs是单次批处理的最大请求数。调高能提高吞吐但也会增加显存压力。vLLM启动后会监听8000端口同样兼容OpenAI格式API。你可以直接接LangChain等现成的Agent框架非常方便。3.4 张量并行的原理与多GPU部署详解当单卡放不下模型时张量并行是你首先需要考虑的方案。它的原理是把注意力头的计算拆分到不同GPU上每个GPU只计算一部分然后通过高速互联如NVLink汇总结果。以70B模型为例FP16权重约140GB一张A100 80G放不下两张A100 80G则正好。使用--tensor-parallel-size 2每个GPU负责分配到的层和注意力头计算模型就能跑起来了。推理延迟比单卡假设能放下高一些因为引入了通信开销但规避了显存不够的问题。张量并行比较依赖卡间通信带宽一般建议用同一Node内的GPU做张量并行尽量避免跨机。如果你有多台机器可以考虑流水线并行这是更深的话题了在初期不必深入。4. 推理性能调优实战参数怎么调心里要有数框架选好了模型部署上去了接下来就是真正的调优环节。很多人到这里就是乱试参数今天调大这个明天调小那个效果全凭感觉。我这一部分会结合实测数据把关键参数的调整思路和背后的道理讲透。4.1 关键参数深入拆解从TP/BS/序列长度说起Batch Size直接决定了吞吐量的上限。Batch太小GPU算力吃不满Batch太大KV Cache显存不够甚至OOM。经验做法是从小到大逐步增高同时观察GPU利用率和显存占用找到一个峰值平衡点。Tensor Parallel Size影响的是单Token生成的关键路径。TP越大单张卡的计算负担越轻但通信开销越大。一般经验4卡以内的张量并行扩展效率还能接受超过8卡收益就非常有限了。我建议优先测试TP2和TP4两种配置对比延迟和吞吐再定。Max Sequence Length这个参数容易被忽视但它对显存的影响非常大。假设模型最大序列长度是8192KV Cache总量能容纳的Token数是根据它算的序列长度设越大能同时服务的请求数就越少。如果你的业务实际平均长度只有2000就不要一味调到8192或更大浪费显存。Temperature、Top-P等生成参数也会影响推理速度。Tem高意味着采样更随机可能触发不同的CUDA内核分支从而略微影响效率但影响幅度很小。主要影响还是前面说的几个系统级参数。4.2 性能评测方法论不要只盯着日志看很多同学部署完模型只会看个响应时间就觉得完事了。这是远远不够的。性能评测需要系统化的指标我日常最关心这几个Time to First TokenTTFT首Token延迟衡量用户等待的体感。Tokens Per SecondTPS输出速度衡量模型生成一个Token所需时间。Throughput单位时间处理的请求数或Token数衡量系统的整体服务能力。GPU UtilizationGPU算力使用率衡量资源利用效率。指标怎么测vLLM自带了一个benchmark工具可以模拟并发请求。你也可以自己写个简单的压测脚本比如用Python的asyncio并发发请求记录每次的TTFT和TPS。我分享一个简易的压测思路不依赖任何特殊工具。编写脚本循环发送多次请求记录每次请求的响应时间和输出Token数。采样次数建议不低于50次取P50、P95、P99三个分位数。P95和P99才是衡量用户体验的硬指标平均值很容易被极端值掩盖。真实经验来看当并发从1升到32时TPS通常先升后降。GPU存在一个最佳并发区间超过这个区间后排队和显存换出的开销会拖垮系统。这个区间需要你压测后画个图去寻找不是拍脑袋定的。4.3 实战案例从配置混乱到性能翻倍的真实调优记录分享一个我们实际做过的调优案例。客户有个在线创作类应用跑一个13B模型线上反馈巨慢单次请求动不动就要十几秒。第一次排查就发现了一个低级问题模型是用FP16加载的完全没有量化。显存占用接近26GB只部署了一张48G的卡并发稍微一高就全卡住。然后做了三个调整。第一启用了INT8量化模型权重从26GB降到约13GB给KV Cache留出了大量空间第二把连续批处理的并发限制从8调到了16第三把最大序列长度从16384调整到8192。改完以后单请求延迟从12秒降到了3秒左右吞吐量提升接近4倍。同样的场景仅仅是合理的显存分配和量化策略就做到了这个程度说明推理优化的杠杆效应有多强。由此得到一个经验你的首要优化顺序应该是先确认权重精度是否合理再考虑KV Cache和批处理策略最后才去纠结更高级的框架参数。4.4 量化实践技巧AWQ vs GPTQ vs FP8该选哪个常见的量化方法有AWQ、GPTQ和FP8。它们思路各不相同适用场景也不一样GPTQ基于二阶梯度信息做后训练量化精度较好量化速度适中。它属于经典的PTQ路线。AWQ基于激活值分布做加权缩放对权重中重要通道做保护量化后精度损失通常更小量化后的模型推理速度也不错。FP8是英伟达Hopper架构H100为代表上的新选择精度接近FP16但性能翻倍。它需要硬件支持老卡用不了。实际选择时我建议按这个逻辑如果是A100/H100这类新卡优先考虑FP8如果是老卡或消费级显卡在7B-13B规模用AWQ在更大规模模型如70B上用GPTQ。理由很简单7B-13B模型显存余量相对充足AWQ的保护机制能最大化精度70B级别显存紧张GPTQ的压缩率更可控一些。具体命令行参数可以参考# AWQ量化示例使用AutoAWQ python -m autoawq.entry \ --model_path /path/to/model \ --quant_path /path/to/output \ --quant_type awq \ --bits 4 # GPTQ量化示例使用AutoGPTQ python -m auto_gptq.quantize \ --pretrained_model_dir /path/to/model \ --quantized_model_dir /path/to/output \ --bits 4 \ --group_size 1284.5 长序列场景的显存和注意力优化长文本是当前大模型应用的重要方向但长序列推理对显存和注意力计算的挑战很大。序列长度翻倍KV Cache显存占用就跟着翻倍。针对长序列有几种常用优化办法。第一是滑动窗口注意力让模型只关注最近的N个Token减少注意力矩阵的规模。LLaMA 3.1和Mistral都用了这种思路。但滑动窗口有个局限模型无法关注到窗口之外的远期信息可能影响长文档理解能力。第二是稀疏注意力有策略地跳过一部分远距离Token的注意力计算。这种方案结合了全局和局部两种注意力模式效果不错但实现较复杂。第三也是最现实的就是合理设置max-model-len不要让模型支持超过业务需求的序列长度。很多应用声称支持128K实际上根本不会用到白白让KV Cache占了大量显存。5. 常见问题与排查技巧实录这些坑我替你踩过了这部分内容来自我们长期的实战积累。讲真大部分推理性能问题不是玄学只要掌握正确的排查思路很快就能定位根因。5.1 显存不够、OOM、频繁报错先分清是权重还是KV Cache遇到显存相关报错首先需要判断到底是谁吃掉了显存。最实用的方法是观察报错信息比如“CUDA out of memory”但同时模型还没跑起来大概率是权重加载阶段出了问题如果模型能跑但并发一高就OOM大概率是KV Cache显存分配不够。你可以用nvidia-smi实时查看显存分配情况。注意观察模型占用的固定显存和动态增长的缓存区。如果模型权重占了70%-80%那么KV Cache的空间就很紧张了可以考虑降低max-num-seqs或者用INT8/INT4量化腾出空间。我自己踩过的一个坑是FP16模型加很大并发总觉得量化会损害效果抗拒做量化。后来跑了个评测对比发现INT8在大多数任务上掉点不超过1%但显存和速度改善极大。从此以后显存受限时我第一个想到的是量化而不是去削减并发。警惕一种隐蔽的OOM多进程或多卡环境中其他进程占用了显存导致当前进程申请显存失败。这跟模型本身无关排查时要留意系统里是否有其他GPU进程。5.2 推理速度慢、卡顿、延迟高从这几步开始排查用户反馈“模型很慢”我们需要把慢拆开来看。先判断慢在预填充还是解码阶段。如果首Token延迟特别长往往是输入序列太长。预填充阶段的计算量随着输入长度线性增长如果用户粘贴了一篇大文档进去慢是正常的。优化思路包括限制输入长度上限、使用更好的量化精度、或者对大文档做分块摘要再送入模型。如果是生成速度慢比如每秒只有个位数Token需要检查目标硬件算力和模型大小的匹配度。一个消费级显卡跑70B模型就算能跑起来速度也必然是惨不忍睹。这时可以考虑蒸馏到更小模型或者换更强的显卡。还要看看是否真的用上了GPU。有时候CUDA环境配置不完整模型回退到CPU推理速度慢十倍不止。排查方法很简单看nvidia-smi里的GPU利用率是否为0或者进程是否真正占用了显存。5.3 质量变差、输出异常量化太高还是上下文太短很多人在量化后发现模型输出质量下降首先怀疑量化方法有问题。来分享一下我的排查顺序先用未量化的FP16模型跑一遍如果FP16输出也很差那问题不在量化而是模型本身或提示词的问题。如果FP16正常但量化后变差再判断量化粒度GROUP_SIZE 32通常精度比128好但会带来一定的显存和计算开销。检查是否出现过量裁剪好压缩。有些量化工具会顺手做激活裁剪裁剪太激进会损失大量有用信息。另外“上下文丢失”也会让人误以为模型变笨了。如果用户输入的文本太长超过模型支持的上下文长度模型可能只看到中间一段或开头一段输出自然牛头不对马嘴。确认下max-model-len是否远大于实际输入长度。还有一个常见原因是提示词本身写得不好。同一道题提示词写法不同模型输出差别很大这属于工程调优的范畴。推荐用差不多的题多测几次排除随机性因素。5.4 并发一高就崩连续批处理和显存上限的终极排查曾经遇到过这么一个问题单请求正常压测到20并发时就频繁OOM、超时。检查了半天发现根因是gpu-memory-utilization设置太高预留的KV Cache空间根本不够处理高并发一旦请求一多就爆。后来把gpu-memory-utilization从0.95调整回0.88并启用--enable-prefix-caching同时给服务设置了请求排队机制问题就解决了。核心经验显存利用率不等于越高越好要给KV Cache留出足够空间来应对动态请求波动。再说一个容易被忽略的点连续批处理框架如vLLM默认会贪心地提升并发直到触达显存上限。如果你不在框架层设置并发上限框架自己可能会往死里压。建议明确max-num-seqs给系统一个安全边界。5.5 多卡扩展效率低Tensor Parallel与通信瓶颈Tensor Parallel本是解决显存问题的利器但如果你发现加了卡性能提升不明显甚至不升反降多半是通信瓶颈在作祟。排查办法观察训练或推理时的GPU利用率。如果很多GPU利用率只有30%-50%大概率不是计算不行而是等待通信数据的时间太长。张量并行要求卡间通信速率很高NVLink互联的多卡效率远高于PCIe互联。建议优先选NVLink全互联的机型PCIe方案在多卡并行时容易成为瓶颈。控制TP规模尽量不超过8卡。真需要更大规模时考虑流水线并行和数据并行方案的组合。如果条件允许升级网络架构和数据调度方式会带来更大收益。写在最后大模型推理优化这事看起来技术壁垒很高实际拆解下来核心就是理解显存、计算量和通信三者之间的关系然后在此基础上选好工具、调好参数。我在实操中最深的体会是优化是个持续迭代的过程先跑起来再量化测试再调并发一步步逼近当前硬件条件下的最优解。最后再分享一个小技巧遇到推理性能问题时建议第一时间用nvidia-smi看一眼显存分配和GPU利用率再配合日志判断慢在哪个阶段。大部分问题在这个环节就能定位一大半。如果模型量大、并发高、延迟敏感点多建议优先在vLLM生态里解决这个社区现在很卷很多坑已经有人帮你填好了。
返回列表