☰
大模型推理加速实战:量化、投机采样与PD分离全解析
2026/10/8 3:36:19 网站建设 项目流程

1. 先说清楚:大模型推理到底慢在哪

做推理加速的第一件事,不是去翻量化工具文档,而是先弄清楚大模型推理的瓶颈到底长什么样。我曾经见过不少朋友,GPU 还没买明白呢,上来就急着给模型套 INT4 量化,结果跑起来发现速度提升没想象中大,甚至输出质量明显崩塌,最后又灰溜溜地换回 FP16。这种问题几乎都是因为没搞清楚推理过程中的资源消耗结构。

先说一个最核心的概念:大模型推理的 Decode 阶段,也就是一个 token 一个 token 地往外蹦生成结果的阶段,绝大多数情况下是访存密集型(memory-bound),而不是计算密集型。这个结论直接决定了后面所有优化手段的方向。

一行 LLaMA-7B,权重大概 13~14GB(BF16 精度)。跑推理的时候,每生成一个 token,GPU 要把所有的权重从头到尾读一遍,再算一次矩阵乘法,得到一个输出。如果显卡的显存带宽是 1TB/s,读完这 14GB 权重需要 14 毫秒。而真正做矩阵乘法的时间,消耗在计算单元上的,往往只有几毫秒甚至更短。也就是说,你等的时间大部分花在"把卡车里的货搬下来"这件事上,而不是"在房间里处理货物"上。

这就是为什么决定推理速度的第一要素不是模型的参数量,不是显卡的算力 TFLOPS,而是显存带宽。如果你把权重从 14GB 压到 7GB(也就是 INT8 量化),哪怕算力一点没变,推理速度理论上也能翻倍,因为每次读权重的"过路费"减半了。

而 Prefill 阶段,也就是处理用户输入那段比较长的 prompt 的阶段,情况又不一样。这个阶段数学计算量很大(QKV 投影、attention 计算、FFN 展开),是典型的计算密集型(compute-bound)。一次性把几千个 token 并行算完,虽然计算量大,但 GPU 的并行度利用率很高,所以耗时会随输入长度增长,但速度往往不会成为主要瓶颈。

这两个阶段性能特征完全不同,所以优化的三种主流手段——量化、投机采样、PD 分离——本质上是分别"对症"这些不同的痛点:

  • 量化:压缩权重体积,降低访存开销,让 Decode 阶段更快,同时降低显存占用。
  • 投机采样:用一个更小更快的草稿模型先"预写"几个 token,然后再让大模型一次验证,减少 Decode 的迭代轮数。
  • PD 分离:让 Prefill 和 Decode 各自跑在不同节点或不同 GPU 上,避免两个阶段的内存特征互相干扰,把部署规模吃透。

下面我按顺序把这三种技术的原理、实操和踩坑经验展开说,最后给一套组合拳的打法建议。

2. 量化:把权重"瘦身",是性价比最高的第一刀

2.1 量化的底层逻辑:信息压缩与误差控制

量化的本质很简单:把模型的权重和激活值从高精度浮点数(BF16/FP16,占据 2 字节)转成更低的位宽(INT8 占 1 字节,INT4 占半字节),用更少的比特去表示原来的数值范围。

听起来是个纯工程活儿,但真正实现起来远比想的麻烦,因为大模型的权重分布不是均匀的。LLaMA 这类模型的权重数值往往集中在零附近一个比较窄的区间里,但偶尔会有一些离群的大数值。如果直接按最大值缩放到 INT8 的 [-128, 127],那些占绝大部分的小数值会被压缩到几个离散的台阶上,精度损失惨重。

所以现在的量化方案都围绕一个核心问题做文章:如何找到一组好的缩放参数(scale)和零点(zero point),把原始数值映射到整数空间,同时尽量降低误差。

实际工程里,我们通常不追求数学上的最优,而是用一组真实数据来做校准(calibration)。校准是什么意思?就是拿几十到一两百条有代表性的文本,喂给原始高精度模型,记录每层张量的实际数值分布,然后再决定每一层的 scale 应该设多少。

这比我说的要细不少,但你要记住一个概念:calibration 用的数据必须尽量贴近线上真实的输入分布。一台专门跑法律文书的机器,你拿一堆代码问答数据去校准,量化出来的模型往往表现不佳。我自己就踩过这个坑,当时图省事直接拿公开的 C4 数据集校准了模型,上线后发现合同文本生成能力肉眼可见地变差。

2.2 主流量化方案的取舍:GPTQ、AWQ、GGUF,到底用哪个

这三年量化生态已经非常成熟了,基本上你打开 HuggingFace 搜模型名,就能看到一票带"GPTQ""AWQ""GGUF"标签的模型。但选型上很多人是懵的,我这里直接给结论:

方案位宽典型场景推理引擎备注
GPTQINT4 / INT3GPU 推理,单卡或小集群ExLlama、vLLM、llama.cpp 部分支持成熟度高,生态好,推荐入门首选
AWQINT4GPU 推理,对精度敏感的生产环境vLLM、TensorRT-LLM、SGLang基于激活值感知的权重量化,少跑偏
GGUFINT8 / INT4 / Q2 等CPU + GPU 混合部署、端侧llama.cpp / ollama分块量化,k_quants 系列均衡性好
FP8FP8Hopper 及以上架构 GPUTensorRT-LLM、vLLM硬件级支持,精度损失极小,但老卡跑不了

GPTQ 和 AWQ 最大的区别在于:GPTQ 是从误差修正的角度,逐层、逐列的"裁剪"权重,在量化过程中补偿误差;AWQ 则是盯着每一层激活值的分布,对那些对激活值影响大的关键权重通道保护不走样。用大白话说,AWQ 更"识货",知道哪部分权重是命门,所以它量化的模型在长尾任务上通常表现更稳。

至于 GGUF,它更像是一个封装格式,里面可以装各种量化方式。它的优势在于分块策略灵活,不同层的敏感度不同,可以给不同层分配不同的位宽,比如关键层 Q4,非关键层 Q5 甚至 Q8,均衡效果极好。如果你需要在 CPU 上跑,或者显存特别紧,GGUF 是目前最可靠的选项。

2.3 实操:用 AutoGPTQ 跑一次 INT4 量化

这里我不讲太复杂的命令行封装,直接给你一套我常用的基于 AutoGPTQ 的脚本思路,可复现性很高。

from transformers import AutoTokenizer from auto_gptq import AutoGPTQForCausalLM, BaseQuantizeConfig model_id = "meta-llama/Llama-3.1-8B-Instruct" quantize_config = BaseQuantizeConfig( bits=4, # 目标位宽 4bit group_size=128, # 分组大小,按 128 个权重共享 scale desc_act=True, # 按激活值降序排列权重通道,精度更好 damp_percent=0.01, sym=True # 对称量化,INT4 通常用对称 ) tokenizer = AutoTokenizer.from_pretrained(model_id) model = AutoGPTQForCausalLM.from_pretrained(model_id, quantize_config) # 校准数据与预处理 examples = [tokenizer(calib_text) for calib_text in calib_set] model.quantize( examples, batch_size=1, use_triton=False ) model.save_quantized("llama-3.1-8b-int4-gptq")

几个参数帮你解释一下,这是最容易踩坑的地方:

  • group_size=128:意思是每 128 个权重共享一组 scale 和 zero point。group_size 越小,量化粒度越细,精度越好,但模型体积和计算开销会略增。128 是性价比比较高的中间档,追求极致精度可以用 64,显存极度紧张想再压一截可以用 256。
  • desc_act=True:官方叫"descending activation order",把权重通道按照激活值大小重新排序,这能把量化误差降到最低,代价是推理时会多一些 permute 计算。网上很多老教程图省事关掉它,实际上精度损失能差出半个点以上,我不建议关。

量化完成后,需要在同样的校准集上跑一遍生成对比,肉眼检查输出是否和 FP16 版本一致。如果出现明显乱码、重复堆叠无意义 token,先别急着认为是量化本身的问题,把 calibration 集换一批数据再做一次,很多情况是校准分布不匹配导致的。

2.4 量化之后的收益与隐藏代价

量化最直观的收益我心里有本账:

  • 显存占用直接减半或降到三分之一(BF16 到 INT8 减半,BF16 到 INT4 减到四分之一,但因为组粒度的元数据开销,实际大概是 28%~30% 的残存体积)。
  • 推理吞吐量提升。Decode 阶段是访存瓶颈,权重变小后单卡能塞进更大的 batch,利用率一下就上来了。
  • 部署成本大幅下降,原来需要 2 张 80G A100 的模型,现在一张 40G 的卡就能跑。

但隐藏代价必须说清楚。量化不是免费的午餐,第一代价是精度损失,第二代价是有时会触发"异常放大"效应。具体来说,量化误差在浅层网络可能不大,但经过几十层 transformer 逐层累积、放大,最后输出的语义可能完全飘掉,尤其是长上下文、数字计算、结构化代码生成这些场景,对精度极敏感。

所以我在生产环境里的策略是:聊天、摘要、分类这类宽松任务用 INT4 没有压力;但涉及数学、SQL 生成、代码执行等必须保证精确的,宁可上 INT8 或者让部分敏感层保持高精度。GGUF 早期就是能手动指定 attention 层不量化,这个思路值得借鉴。

还有一个容易忽略的点:量化之后要重启检查显存占用与推理延迟。有些框架在加载时还是会临时把权重反量化回高精度进行计算,这意味着你的显存收益可能没那么大,推理速度也没跑起来。当时我在 ExLlama 上遇到过一次,折腾半天发现是配置项没打开"fused attention + quantized weight 直接计算"选项,权重还是被额外地反量化缓存了一份。

3. 投机采样:用"小号"打草稿,让大模型只负责校对

3.1 投机采样的三个关键角色:草稿、验证、接受率

投机采样(Speculative Sampling)的思路非常有趣。它不改进单次推理的速度,而是减少生成 N 个 token 所需的大模型前向迭代次数。

直接讲原理。常规生成流程是逐个 token 迭代:输入一串历史 token,大模型预测下一个 token;然后把这个新 token 拼回去,再预测下一个……每生成一个 token 都要做一次完整的前向传播,访存开销巨大。

投机采样引入了两个模型:一个草稿模型(draft model),一个小得多、跑得快的模型,通常是大模型缩小版本或者专门蒸馏出来的两三亿参数的小模型;一个大模型本体。

流程是这样的:

  1. 草稿模型先以自回归方式快速生成 k 个候选 token(比如 5 个)。
  2. 大模型把这 k 个候选 token 连同当前上下文一次性喂进去,一次前向传播,同时算出这 k 个位置的真实概率分布。
  3. 大模型逐个检查草稿预测和真实分布是否一致(严格来说是用"接受/拒绝"采样法则,即对比草稿分布与大模型分布,按概率接受)。
  4. 接受的 token 直接留下,一旦遇到拒绝的 token,就用大模型自己的分布重新采样,从这个 token 开始继续下一轮,同步丢弃后续候选项。

重点来了:大模型一次前向可以验证 k 个位置,如果草稿模型足够聪明,平均有 60%~80% 的 token 被接受,那一次前向就能顶 3~5 次前向使用。虽然是"小模型跑 5 次 + 大模型跑 1 次",但小模型每次前向开销远低于大模型,总体提速非常可观。

这里的核心概念叫接受率(acceptance rate),直接决定了加速上限。接受率越高,浪费的草稿 token 越少,加速比越大。理论极限就是草稿模型和大模型概率分布完全一致(这种情况加速比约等于 k:草稿跑 k 次 + 大模型验证 1 次),现实中因为草稿模型能力有限,接受率通常在 50%~80%。

3.2 工程实现:草稿模型从哪来,参数怎么配

实际工程里,最省心的方式是直接用同系列的小模型做草稿模型。比如主模型是 Qwen2.5-32B-Instruct,草稿模型就用 Qwen2.5-0.5B-Instruct。这有一个隐形好处:vocab(词表)完全一致,tokenizer 输出的 token id 才是同一个空间里的,否则还得映射索引,非常麻烦。

如果手头没有同系列小模型,也可以用 Medusa 这种方案。Medusa 的思路是在主模型的最后一层上挂多个并行的"多 token 预测头",用一个小型训练集去训练这些预测头,让同一个主模型在推理时不仅预测下一个 token,还能同时预测下下个、下下下个 token,本质上省掉了独立的草稿模型。

vLLM 里启用投机采样非常简单:

python -m vllm.entrypoints.openai.api_server \ --model Qwen/Qwen2.5-32B-Instruct \ --draft-model Qwen/Qwen2.5-0.5B-Instruct \ --speculative-config "num_speculative_tokens=5" \ --target-output-num 1024 \ --gpu-memory-utilization 0.9

几个关键参数:

  • num_speculative_tokens(k):每次草稿模型预测的候选 token 数。k 太小加速不明显,k 太大,草稿模型后半段的预测质量下降,接受率暴跌,反而浪费。实测下来我通常取 4~6 之间,结合草稿模型质量动态调整。
  • 草稿模型与主模型的速度比:这个很少有人提,但很重要。如果草稿模型只比主模型快 3 倍,而你要让草稿跑 5 个 token,那草稿部分就已经消耗了主模型全速跑 5/3≈1.67 次前向的时间,如果接受率不够高,可能连打草稿的成本都收不回来。
  • temperature / top_p:投机采样在低 temperature(比如 0.1~0.3)时效果最好。因为低熵分布下草稿命中率高。一旦调到 temperature=1 甚至更高,分布变得平坦,草稿模型跟大模型"想到一块去"的概率急剧下降,提速效果大打折扣。

3.3 投机采样不生效的时候,大概率是这四个原因

第一,草稿模型能力过于拉胯,和主模型水平差距太大。比如你拿一个对话能力极强的主模型,却配了一个连句子连贯性都拿捏不住的小模型,草稿 token 基本是被拒绝的,等于大模型每次只验证一两个 token,还倒贴了小模型前向的开销。这个问题的排查方式很简单:看接受的 token 数与总生成 token 数的比值,如果低于 0.4,赶紧换草稿模型。

第二,batch 太大时投机采样的收益会被稀释。投机采样在小 batch(通常是 1~8)时提速明显,但当 batch 增大到 32、64 时,大模型的前向已经能填满 GPU 算力,访存不再是唯一瓶颈,草稿模型的收益自然下降。所以做高并发服务时,不一定非要开投机,这点容易想当然出问题。

第三,服务端加了投机采样但客户端没换生成的重复惩罚参数,有些框架的重复惩罚(repetition penalty)会影响接受概率分布,导致草稿模型大量被拒。如果发现开投机后生成反而更慢更卡,先检查采样参数,尤其是 repetition_penalty 调太高的情况。

第四,synchronize 模式开销太大。早期的一些实现为了逐 token 校验,频繁在草稿模型和目标模型之间同步通信,通信开销直接吃掉了计算收益。新一点的实现支持异步投机采样,让草稿模型提前为下一条候选序列继续迭代,减少等待。

4. PD 分离:让"写作文"和"念作文"各用各的卡

4.1 Prefill 和 Decode 为什么不能愉快地混在一起

前面提到了 Prefill 和 Decode 的性能特征完全不同。这里要展开讲清楚,因为 PD 分离的动机全在于此。

Prefill 阶段:输入 prompt 是几百乃至几千个 token,模型可以并行处理所有位置的 attention 计算。计算量巨大,但 GPU 利用率高,是一个典型的计算密集任务。为了方便理解,可以类比成"写作文",一次性读完题目、构思完整篇,这个阶段 GPU 算力跑得很满。

Decode 阶段:每次只处理一个新 token,依赖前面所有 token 的历史,无法并行,注意力权重需要逐个读缓存计算。比起算力,这段时间的瓶颈更在于把模型权重和 KV Cache 反复从显存搬到计算单元。它像"念作文",一个字一个字往外蹦,计算量小但跑的次数多,GPU 算力大量闲置,带宽却拉满。

问题就出在这里。当 Prefill 和 Decode 请求混在同一张卡上时,一个长输入的 Prefill 请求会把算力全部吃满,导致当前正在 Decode 的所有其他请求全部被阻塞。你用过那些"输入一长就吞吞吐吐"的 API 服务,多半就是这个原因。

另外,显存占用规律也不同。Prefill 阶段内存消耗主要体现在构建大量的 KV Cache;Decode 阶段则是不断追加新 token,KV Cache 持续增长。混在一起,显存波动剧烈,调度器稍有不慎就会引发 OOM。

4.2 PD 分离部署:谁的活谁干,缓存提前传

PD 分离的思路是把 Prefill 和 Decode 拆到不同的 GPU 实例上,甚至不同节点上。Prefill 实例专用长输入计算,Decode 实例专职 streaming 输出。中间通过 KV Cache 把两段衔接起来。

你可以把它理解成流水线:有人负责"写草稿"(Prefill),写完了整篇交给"朗诵者"(Decode),朗诵者不需要回到草稿阶段重新构思,它只需要拿着写好的稿子一个字一个字念。

实现上最核心的难点在于KV Cache 的转换与传输。Prefill 实例在计算完输入序列后,会生成一组状态的 KV Cache,这组 cache 必须传给 Decode 实例。但在分布式环境中,KV Cache 有可能分散在多张 GPU 和多块显存里,怎么高效地聚合、传输、重组,直接决定了这套方案的可行性。

成熟一点的做法是把 KV Cache 放到CPU 内存或远端缓存池。Prefill 完成后,KV Cache 先落到缓存池,再把元数据告诉 Decode 实例;Decode 实例启动时按需把对应部分的 KV Cache 拉回来。Kimi 的 Mooncake 架构就是 PD 分离的标杆案例,它这个 KV Cache 的"中转仓库"做得非常细致。

还有一个折中的实现值得知道,叫Chunked Prefill(分块预填充)。不需要物理上拆成两套 GPU,而是在同一个推理服务里,把过长的 prompt 切成若干个 chunk,把 Prefill 计算分散在 Decode 的间隙里执行,保证单卡上既有长请求进来也不会长时间霸占算力。vLLM 里的--max-prefill-tokens参数就是控制这个的。

4.3 什么时候你才需要动 PD 分离

PD 分离大概是三招里工程成本最高的一招,不是新项目建议别一上来就上。它主要救的是两种场景:

场景一:超长上下文的单请求。单次请求的 prompt 很长(比如长文档问答、Agent 长流程梳理),或者输出的 streaming 节奏极慢。当你发现 GPU 算力利用率只有 20% 左右,但显存和带宽频繁告警,PD 分离能明显提升响应稳定性。

场景二:并发请求混部严重。大量小 batch 的 Decode 请求与偶发的大 batch Prefill 请求混在一起,导致延迟抖动剧烈。PD 分离之后,不同类型的请求各吃各自的资源,端到端的 P99 延迟会明显平滑。

如果你只是一个小规模服务,用一张卡同时应付 Prefill 和 Decode,P50 延迟都不太难看,那就没必要折腾 PD 分离。Chunked Prefill + 合理的 scheduling 策略,比如 vLLM 或 SGLang 默认的连续批处理,已经能解决大部分抖动问题。

4.4 PD 分离实操里的三个关键参数

如果你真的要做 PD 分离,或者至少做分节点部署,下面这几个点必须想清楚。

第一,调度策略要能感知 KV Cache 的物理位置。不能让 Decode 实例在一张远端卡上运行,却把 KV Cache 存在另一张远端卡上,不然每次读取都要跨过 PCIe/NVLink 绕远路,延迟直接爆炸。KV Cache 的放置要和计算实例强绑定,最好由调度器在放置实例时就确定。

第二,KV Cache 的显存预留比例。很多框架喜欢把 KV Cache 占显存的比例设成一个可调参数,比如 0.2~0.4。在 PD 分离架构里,Decode 端的 KV Cache 还会持续增长,预留比例给太小,长对话到一半就被强制清缓存;给太大,留给权重的空间不够,模型都加载不进去。一个经验做法:Decode 端的 KV Cache 峰值按max_output_len来算,预留 1.5 倍峰值,同时把权重放在另一块独立显存或说是复用高精度权重存储区域。

第三,网络带宽是天花板。KV Cache 的传输速度和你机房的 RDMA/Infiniband 带宽直接相关。如果一次长 prompt 的 KV Cache 有上百 MB,一次传输就需要几百毫秒到秒级,直接烧穿用户可感知的首个 token 延迟(TTFT)。想让 TTFT 可控,KV Cache 传输要并行化,或者直接做范围预热,提前把高频前缀的 KV Cache 缓存到 Decode 端。

5. 组合拳:量化、投机、PD 分离怎么搭

5.1 不同规模模型的加速方案矩阵

三种技术不是互斥的,但不同量级、不同场景的模型,最优组合差异很大。我按实际部署经验整理了一个参考矩阵:

模型规模典型显存推荐组合原因
3B 以下小模型8G~24G量化为主,投机采样可开可不开模型本身访存开销小,投机采样的收益有限,主要靠量化降本
7B~13B 中等模型16G~40GINT8/INT4 量化 + 投机采样显存紧凑,开投机后单卡吞吐显著提升
30B~70B 大模型80G+INT4 量化 + 投机采样 + Chunked Prefill显存压力极大,需要量化节省空间;同时用投机缓解单 token 生成延迟
100B+ 超大模型或多租户高并发多卡集群大规模 PD 分离为中心,量化为辅算力分配、资源编排优先级高于单卡收益,PD 分离解决混部问题

5.2 组合使用时各参数的"并联"原则

这三个技术叠加使用时有个规则容易被忽略:每个优化都改变了下游热点的资源曲线。

举个例子,量化主要是降低了 Decode 的访存压力,但同时它也让 Prefill 阶段的算力相对变高,这时候你如果又开了投机采样,草稿模型同样需要量化才能和主模型"同频"跑动。如果草稿模型保持不变还是高精度,它的访存开销相对主模型反而更突出,这会拖累整体链路。

我的经验是:

  1. 先做权重量化,把主模型和草稿模型统一压到同一位宽,再评估速度和精度衰减。
  2. 随后开投机采样,先单独测主模型的生成延迟与吞吐,再单独测草稿模型的开销,最后带采样参数实测整体收益。
  3. 最后才考虑要不要上 PD 分离或 Chunked Prefill。因为前两者已经把显存和算力压力降下来,很多场景根本不需要拆两套集群了。

5.3 实测中的一组对比数据

拿 Qwen2.5-32B-Instruct 举例。单张 A100 80G,BF16 权重,batch=1,生成长度 512 token:

  • 纯 FP16 推理:约 12 token/s,P99 显存 58G
  • INT4 权重量化:约 23 token/s,显存降到 22G
  • INT4 + 投机采样(草稿模型 Qwen2.5-1.5B):约 31 token/s
  • INT4 + 投机采样 + Chunked Prefill(max-prefill-tokens=1024):单请求吞吐差不多,但把两个长 prompt 请求混在一起时,P99 延迟从原来的 9.8s 降到了 4.6s

这张数据说明一个问题:量化和投机采样解决的是"单请求速度"和"吞吐上限",而 PD 分离或 Chunked Prefill 解决的是"并发下的流畅度"。它俩的目标不一样,别拿一个去替代另一个。

6. 常见问题与排查技巧实录

6.1 量化精度崩了,先查校准数据再查分组参数

问题表现:量化后模型输出经常重复话术、数字计算错误、指令遵循能力锐减。

排查思路:先确认校准数据与线上数据分布是否匹配。如果线上以代码为主,你拿通用文本校准,量化误差会集中爆发。其次检查 group_size 是不是设太大(比如 256)且 desc_act 被关闭了,这两个参数对敏感任务的影响非常大。最后,对实在保不住的层,用 Mixed precision quantization 思路保住注意力层和 layernorm 层的高精度。

6.2 投机采样开了反而变慢

问题表现:开启投机采样后 token/s 不升反降,或者显存占用猛增。

排查思路:分三步看。

先看接受率,日志里通常能查到接受率,低于 0.4 基本就是草稿模型太弱或温度太高。

再看草稿模型加载位置,有些框架会把草稿模型也拷贝到显存里,如果显存余量不够,主模型和草稿模型互相挤兑,频繁做显存换入换出,反而把一切拖垮。检查显存剩余容量,如果都大于 80%,再关掉一些 GPU memory fraction 限制。

最后调整num_speculative_tokens,从 5 降到 3 试试,不少场景下 k=3 的稳态收益比 k=5 更高。

6.3 PD 分离后 TTFT 反而变高

问题表现:部署了 PD 分离之后,用户感知的首 token 延迟(TTFT)没降反升。

排查思路:这几乎都是 KV Cache 传输链路太长导致的。Prefill 实例计算完,KV Cache 要先写到中央缓存池,再被 Decode 实例拉取,中间多了一次磁盘/网络 IO。优先把这一步内存化,不要落盘;如果是跨机,就检查网卡带宽是不是存在瓶颈,必要时对高频前缀做 KV Cache 预热,让 Decode 实例提前把常用上下文缓存好。

6.4 一张速查表,排障时照着对

症状可能原因优先动作
量化后精度下降明显校准分布不匹配换校准集,开 desc_act
量化后显存没降框架未启用量化计算检查推理后端配置,确认反量化路径
投机采样没提速接受率低 / 草稿模型弱看接受率,换草稿模型,调 temperature
投机采样显存爆掉草稿模型占显存开量化草稿模型,限制草稿模型显存
长 prompt 首 token 特别慢Prefill 与 Decode 混部上 Chunked Prefill,或物理拆分 PD
PD 分离后 TTFT 高KV Cache 传输慢内存化缓存池,并行传输,前缀预热
并发一高延迟抖动大调度策略没调好调整连续批处理窗口,控制 prefill token 数量

7. 最后,一些我自己反复用的复盘经验

这几轮折腾下来,我最想对新人说的是:不要一上来就追最新最炫的框架,先把三个技术的适用场景钉死在脑子里。

量化解决的是"放不放得下、读得快不快",它最普适,也最容易上手;投机采样解决的是"少读几趟",前提是有一个跟你主模型同词表、能力不拉胯的小模型;PD 分离解决的是"互不干扰",但工程复杂度陡增,没有巨大的并发压力或超长上下文的场景,尽量先用 Chunked Prefill 扛一扛。

另外我有个习惯,每次做加速实验,都会先花二十行脚本做一个最小对比实验:固定同样的输入、同样的 seed、同样的采样参数,分别跑一个脚本对比性能与输出一致性。没有这个基线,你根本分不清这次的提升是量化带来的还是运气好让 batch 部署跑得更均匀。

最后分享一个非常实用的调参技巧:在 vLLM 这类框架里,max-num-seqs(最大并发序列数)这个参数和投机采样、量化是强耦合的。你把权重压到 INT4 后,能同时处理的序列数会变多,但如果你不手动调大max-num-seqs,并发吞吐根本吃不满新硬件余量;反过来,如果你在 PD 分离架构下把它调太大,KV Cache 会在 Decode 端爆炸。这个参数值得你每次改动后重新做一轮压测。

说到压测,我平时会用一个小脚本按不同并发数(16、32、64、128)分别打请求,记录 TTFT、TPOT(每个 token 的平均生成时间)、P99 延迟三个指标。如果一个优化手段让 TPOT 变好了,但 TTFT 明显恶化,那这不是提速,是把时间从生成端挪到了排队端,要警惕。大模型推理加速这个领域很宽,但当你把这三种技术都亲手跑通一遍、能把各自的作用边界讲清楚的时候,很多生产环境的性能问题就已经不再是问题了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询