上个月帮一个朋友调他新买的工作站,那张显卡显存看着挺大,跑一个7B的模型按理说绰绰有余,结果生成速度惨到每秒几个token,跟网页版对话体验差出一条街。他第一反应是模型被"喂坏了",换了好几个量化版本问题依旧。最后我帮他看了一眼推理日志和显存带宽,问题一下就清楚了——他跑的是FP16权重,加上KV Cache一路膨胀,显存早就被吃满,系统开始疯狂换页。这类场景我见过太多:大家选卡时只盯着显存大小,跑起来才发现内存带宽、量化方式、并发策略才是真正决定体验的东西。
这篇内容想围绕推理优化和部署,把量化、蒸馏、模型选型这几块一次性讲透。适合正在做本地大模型部署、想优化推理性能、或者在两个模型版本之间犹豫选哪个的工程师和进阶玩家。我会尽量把"为什么这样选"讲清楚,而不是只丢结论。
1. 推理卡在哪儿:先算清楚硬件的"底线"
1.1 大模型推理的两张面孔:prefill和decode
大模型生成回答的过程不是一个黑盒一气呵成,它分两个阶段:prefill(预填充)和decode(逐token生成)。
- prefill阶段:把用户输入的prompt一次性喂给模型,模型并行计算所有输入token的注意力,生成首个token的logits。这一步是典型的计算密集型任务,GPU的算力(TOPS/TFLOPS)在这里起决定性作用。
- decode阶段:模型根据已生成的token序列,一个一个地预测下一个token。每生成一个token,都需要把整个模型权重重新读一遍,同时KV Cache逐行增长。这一步是典型的内存带宽密集型任务——GPU的显存带宽(GB/s)成了天花板。
理解这两个阶段,才能理解为什么同样的模型在不同场景下感受完全不一样。输入prompt很长时要prefill算得快,输出长文本时decode要跑得稳。很多部署框架的优化策略(比如vLLM的Continuous Batching)本质都是针对这两阶段特性做的牌。
我实际测过:同样是7B模型,在A100上prefill每秒能处理上万token,但decode阶段最多也就每秒几十个token。所以如果你只看prefill的速度,会被严重误导。真实的交互体验里,decode才是你盯着光标等字跳出来的那段"漫长"时间。
1.2 显存、带宽、并发,三个互相牵制的变量
很多人在"模型选型"时只算了一道题:模型权重多大,显存够不够放。但这只是第一层,部署起来还有第二层和第三层:
- 模型权重:FP16下,7B模型权重约14GB;INT8约7GB;INT4约3.5-4GB。这是你必须要填的"底座"。
- KV Cache:每个并发请求都要占用一部分显存。序列越长、并发数越高,KV Cache占用越大。公式通常近似为
2 × 层数 × 头数 × 维度 × 序列长度 × 字节数,一个7B模型在长上下文下,KV Cache轻松吃掉几GB。 - 带宽限制:decode阶段的token速度约等于
显存带宽 / 模型权重体积。就拿4090举例,带宽约1TB/s,跑一个INT4量化后的7B模型(约4GB),理论上限约每秒250个token;但如果跑FP16(14GB),理论上限骤降到每秒70个token左右。显存带宽是物理指标,靠软件优化很难质变。
这三者是一个三角:显存决定你能放多大的模型和多少并发,带宽决定你decode的极限速度,算力决定你prefill的极限速度。选模型和部署框架之前,先把自己机器的这三个数查清楚。
提示:这里说的量化是指模型权重的低比特化(比如从FP16转INT8),跟金融领域的"量化交易"完全是两个概念。我见过好几个第一次接触部署的人把这两件事搞混,在群里问"量化交易数据API怎么选"问到了模型部署频道。
1.3 延迟和吞吐:两个最容易搞混的指标
衡量推理性能时,延迟(Latency)和吞吐(Throughput)是两个完全不同、甚至互相矛盾的指标。
- 延迟:单个请求从发出到收到完整回答的耗时。聊天机器人、代码助手这类高频交互场景,优先看延迟。
- 吞吐:系统在单位时间内能处理多少请求,通常用 tokens/s 衡量。批处理任务、离线分析、API服务,优先看吞吐。
优化方向也不同。降低延迟往往需要牺牲一部分批量处理能力来减少排队;提升吞吐则可以把多个请求合并起来连续推理,牺牲单个请求的响应时间。部署框架的选择上,vLLM牺牲一定首token延迟换极高的吞吐,而传统exllama、llama.cpp这类方案则更适合低并发下的低延迟。
我自己的经验是:先问自己到底是交互型场景还是批处理型场景,再选框架和指标,不然很容易被参数对比表带偏。
2. 量化:压内存的最直接手段,讲究的是分寸
2.1 量化的数学本质和两条主流路线
量化的本质很简单:用更少的数据位来描述权重和激活值。一个FP32的浮点数占32位,FP16占16位,INT8占8位,INT4占4位。数值从连续的浮点空间映射到离散的整数空间,必然有精度损失,而量化技术研究的核心议题就是怎么把这个损失控制到最小。
具体实现上,一句话概括是:q = round(r / scale) + zero_point,其中r是原始浮点值,scale是缩放系数,zero_point是零点偏移,q是量化后的整数。反量化则反过来把整数还原成近似浮点值。
两条主流路线:
- 对称量化:把浮点数的范围对称映射到整数范围,
zero_point固定为0。实现简单,推理速度快,但面对分布偏斜的tensor时量化误差较大。 - 非对称量化:允许零点偏移,能更好地适配分布不对称的tensor,精度通常好一点,但实现复杂度和计算开销也略高。
对于大模型来说,大多数框架默认对权重做对称量化、对激活做非对称量化,在速度和精度之间找一个还不错的平衡点。量化后的收益非常直接:INT8把内存占用直接砍半,INT4砍到四分之一。显存一降下来,能跑的并发数就上去了,decode阶段的实际速度也随权重体积减小而提升。
2.2 动态量化、静态量化、量化感知训练,实战怎么选
按量化时机和是否需要校准数据,量化分三种:
| 类型 | 校准数据 | 量化时机 | 适用场景 | 精度损失 |
|---|---|---|---|---|
| 动态量化 | 不需要 | 推理时实时计算 | CPU部署、快速验证 | 低 |
| 静态量化 | 需要少量样本 | 提前校准,推理时固定 | 生产环境、边缘设备 | 较低 |
| 量化感知训练(QAT) | 需要完整训练流程 | 训练中模拟量化误差 | 精度要求高的场景 | 最低 |
动态量化是最省事的——你只需要一个原始模型,推理前把权重转成INT8,激活值在运行时再算scale。因为没有校准步骤,它省去了很多准备工作,很多本地工具链里对CPU做的默认优化就是这个。速度提升主要来自内存带宽减半,但CPU上如果指令集不支持高效的INT8运算,收益会打折扣。
静态量化比动态量化多了一步"校准":用一批有代表性的数据喂给模型,统计每一层激活值的分布范围,提前算好scale。这一步让激活值在推理时省掉了实时计算的麻烦,精度和速度都更稳定,但前提是你得有一份合适的校准数据集。这一步尤其要小心数据分布不能偏离真实使用场景,否则校准出来的scale不准,量化后模型表现会突然崩掉。
量化感知训练是效果最好的,因为它不是事后弥补,而是在训练阶段就模拟量化误差,让模型自己适应低比特表示带来的扰动。代价是成本高——你需要有继续训练的基础设施和足够的数据。对大模型来说,通常只会在有专门优化预算的团队里做。
我自己的建议:如果你只是想把模型跑起来,动态量化优先;如果是正式产品,至少做静态量化;如果量化前后质量下降明显,再考虑QAT或者换更强的量化方法。
2.3 ONNX INT8落地时容易踩的坑
在实际项目里用ONNX Runtime做INT8量化,是边缘设备和服务端跨平台部署的高频选择。基础流程看起来很简单:
from onnxruntime.quantization import quantize_dynamic, QuantType quantize_dynamic( 'model_fp32.onnx', 'model_int8.onnx', weight_type=QuantType.QInt8 )几行代码就能出一个INT8模型,但落地过程中有几个问题很容易踩:
- 哪些算子真正降了精度。动态量化默认会对MatMul、Gemm、Attention这类算子做权重INT8化,但LayerNorm、Softmax这类对数值敏感的操作通常被排除在量化范围之外。原因很简单:LayerNorm做了归一化,数值范围本身很小,一旦量化误差会被放大。所以如果你的模型里手写了自定义算子,量化工具不一定认,最后可能白量化了一场。
- 校准数据不代表一切。有的场景用静态量化,校准集用了通用文本,但上线后用户输入都是专业术语,激活值分布完全不一样,质量立刻下降。这种情况不是模型坏了,是校准分布不匹配,需要替换校准集重新量化。
- 量化后推理变慢是可能的。如果目标平台的CPU不支持AVX512-VNNI这类INT8加速指令集,反量化的额外开销反而会让推理变慢。所以量化前先查清楚硬件的指令集支持情况——这不是所有教程都会提醒你的。
我见过最多的问题不是量化本身,而是量化和部署框架的版本匹配。ONNX Runtime的算子实现一直在变,不同版本对INT8算子的支持程度不同,建议先在目标硬件上跑一个quick sanity check再大规模上线。
2.4 INT4时代:GGUF、GPTQ、AWQ怎么挑
说完INT8,再说INT4。这几年本地大模型之所以能跑起来,很大程度上靠的是INT4量化。市面主流的三种格式各有侧重:
- GGUF:llama.cpp生态的格式。以CPU+GPU混合推理为设计目标,支持在解码时动态加载部分层到GPU、部分留在CPU,非常适合个人电脑这种显存紧张的环境。Ollama底层的模型格式就是GGUF,这也是它能做到一行命令跑大模型的秘密之一。
- GPTQ:针对GPU推理优化的后训练量化方案,采用二阶近似误差最小化,量化后每层权重误差很小,原始模型的质量保留得比较好。适合一次性把模型完整加载进GPU的服务端场景。
- AWQ:基于激活值感知的量化方法——不是所有权重都同样重要,它通过观察激活值的分布来保护更敏感的通道。AWQ在低比特下往往比GPTQ保留更多生成质量,且量化过程计算开销更低。
三者怎么选?我个人的建议是:
- 个人电脑、笔记本上玩,优先GGUF,因为Ollama和llama.cpp对它的支持最成熟,混合推理策略对显存不宽裕的人太友好了。
- 服务端有完整GPU资源,追求单卡满负载,可以选GPTQ或AWQ,具体哪个好要跑自己的任务评测集——不同模型、不同任务,两者的胜负关系不固定。
- 不要只看量化格式,量化后的实测perplexity(困惑度)和生成质量比格式本身更重要。有些量化参差不齐,同一格式不同量化等级能差出一大截。
3. 蒸馏:让小模型学会大模型的"思考方式"
3.1 教师-学生网络里学的是什么
知识蒸馏(Knowledge Distillation)的核心结构是teacher-student network:一个参数量更大的教师模型(teacher)把一个参数量更小的学生模型(student)"带"出来。教师模型提供监督信号,学生模型在它的引导下去拟合训练目标。
但"监督信号"具体是什么,很多人理解得不够透。常见误区是:蒸馏就是让小模型直接模仿大模型的输出结果。可真正的蒸馏学的不只是最终答案,还有大模型的答案分布。
举个直接的例子:分类任务里,对于一张"很像猫的狗"图片,大模型给出的概率可能是猫:0.6, 狗:0.35, 其他:0.05。如果直接取argmax,学生只能学到"这是猫"这个粗糙结论;但蒸馏让学生去拟合完整分布,它就会知道"这玩意儿虽然大概率是猫,但跟狗也很接近"——这种类别间的暗信息对模型泛化能力的提升至关重要。
这就是"软标签"(soft label)比"硬标签"(hard label)有价值的原因,也是蒸馏能用更少参数量逼近甚至超过直接训练同规模模型的根本逻辑。
3.2 蒸馏的三种常见形式,按场景对号入座
在实际工程里,蒸馏不是一个单点操作,而是一个方法论体系。最常见的三种形式:
1. Logit蒸馏(响应蒸馏)
最经典的形式:让学生的输出logits去拟合教师的软标签。温度参数(temperature)在这里起放大或压缩分布差异的作用。温度越高,分布的"尾巴"越清晰,学生能学到的暗信息越多;但温度太高,噪声也会被放大。实践中建议从一个适中的温度(比如4-8)开始扫一轮,看验证集表现再定。
2. 特征蒸馏(中间层蒸馏)
不只学最后一层输出,还让学生去拟合教师某一中间隐藏层的特征表示。典型代表是TinyBERT、MiniLM——它们会对齐中间层的attention map和hidden state,能让学生在更深层次模仿教师的"表征习惯",对语义理解类任务的提升非常明显。
3. 行为蒸馏(反事实蒸馏)
不局限于在固定数据集上对齐输出,而是让教师模型在更多生成的、甚至反事实的样本上做演示,学生跟着模仿。这在LLM场景里逐渐成为主流——大模型生成高质量指令回答,小模型用这些数据微调,本质上也属于一种"行为蒸馏"。
工程上怎么选?如果任务偏分类/排序,logit蒸馏成本最低;如果任务是文本生成、语义匹配,特征蒸馏往往更有效;如果重点在于让模型"会做事"而不是"会判断",那行为蒸馏(数据合成)就是最实际的路径。
3.3 蒸馏和量化组合使用,叠加收益还是互相干扰?
很多人的直觉是:先蒸馏再量化,两个优化手段叠加,效果应该越来越好。真实情况要复杂一些。
- 蒸馏把一个14B模型的知识压进7B模型,7B模型再INT4量化,理论上显存占用和速度都非常理想。
- 但蒸馏后的模型往往对参数扰动更敏感——因为它是在拟合一个更高容量模型的分布,本身就处于一个比较"紧"的参数状态,再叠加量化噪声,误差会被放大。
我自己实践下来的建议是:如果量化后效果崩了,优先检查学生模型的蒸馏充分程度,而不是急着换更强的量化方法。很多时候不是量化的问题,是学生模型本身还没"学到位",基准能力就弱,量化只是放大了这个弱项。
另一个经验是,蒸馏+量化组合时,最好在蒸馏阶段就引入量化噪声模拟(类似QAT的思路),让学生模型在训练时适应低比特环境。这比"训练完再事后量化"稳定得多,但工程复杂度也上了一个台阶——需要同时维护蒸馏训练流程和量化模拟逻辑。短平快的项目不推荐一上来就组合拳,先做单一优化,确认瓶颈,再加第二层。
3.4 蒸馏一个能用的小模型,完整链路长什么样
如果我现在要蒸馏一个7B级的学生模型,完整链路大致是:
- 确定教师模型:选一个质量过硬的强模型(比如DeepSeek、Qwen大杯版本或商业API),作为数据生成器和打分器。
- 准备训练数据:从目标场景收集种子任务(几十到几百条),让教师模型扩展生成指令-回答对,形成蒸馏数据集。这一步关键是覆盖目标场景的分布,不是越多越好。
- 初始化学生模型:从同系列小模型开始初始化,比随机初始化快得多、稳得多。
- 设计训练目标:常规的token级交叉熵 + 蒸馏损失(让学生的输出分布去拟合教师的输出分布),加上温度参数控制拟合强度。
- 训练与评估:在验证集上做对比,既看perplexity,也要跑任务级评测集(如MMLU、GSM8K、领域问答),不能只看训练loss。
- 部署前压测:蒸馏后的模型量化、部署、做基准测试,把速度、内存、质量数据拉通对比。
这条链路对个人开发者来说成本不低,但效果往往比单纯用小模型直接微调好得多。尤其在垂直领域——教师模型把关参考答案,学生的表现能显著超过直接训练的同等规模模型。
4. 部署框架怎么选:vLLM、Ollama、LM Studio横向对比
4.1 先分清场景,再谈框架选型
部署框架没有"最好的",只有"最合适的"。我通常把部署场景粗分成三类:
- 场景A:单机调试/个人体验。在家里显卡上跑一个模型,自己对话,偶尔调参。追求的是简单、省心,能快速跑起来。
- 场景B:个人应用/小规模服务。比如做一个GPT应用、本地Agent,提供给几个或几十个用户使用,需要一定的并发能力和稳定性。
- 场景C:生产环境/大规模服务。面向几百上千并发、追求高吞吐和低成本,需要高级调度、动态批处理、完善的监控运维。
场景不同,选型逻辑完全不同。在场景A里用vLLM就是给自己找罪受,在场景C里用Ollama也撑不住。
4.2 vLLM:面向生产的高吞吐引擎
vLLM是我在生产环境里最常用的框架,它在推理优化的核心创新是PagedAttention——把KV Cache分割成固定大小的块(page),通过虚拟内存映射来管理,显存利用率大幅提升,碎片化显著降低。配合Continuous Batching,能让GPU在等待生成的同时去处理新请求,吞吐量相比naive方案经常有数倍提升。
几个实际使用体验:
- 部署很简单:
vllm serve一条命令就能起OpenAI兼容接口。 - 并发能力强:同一张卡上可以跑很多并发请求,显存管理做得干净,长上下文场景尤其明显。
- 量化支持友好:GPTQ、AWQ、FP8等都能直接加载,启动参数里指定即可。
- 代价是调度开销:对单请求低延迟场景,vLLM的每个token一次调度不如专用小框架来得快。
4.3 Ollama与LM Studio:本地跑模型的省心选项
Ollama是本地部署里最"傻瓜"的选择。一条命令ollama run qwen2.5:7b就能把模型拉下来跑起来。它内置了llama.cpp后端,支持GPU/CPU混合推理,底层模型就是GGUF格式。它对显存不大的机器特别友好——哪怕你只有8GB显存,也能通过部分层offload到CPU来跑一个7B INT4模型,速度虽然一般,但能跑。Ollama也提供OpenAI兼容的API端口,开发时直接对接很方便。
LM Studio则是带图形界面的Ollama,适合完全不想碰命令行的人。下载模型、加载、调参数全靠鼠标点,还能可视化看每层推理耗时和显存占用,调试阶段非常好用。但它的定位是个人应用、实验验证,不太适合直接做生产服务。
这两个工具的实际局限在于可调参数和调度策略相对刻板,并发高了以后性能下滑明显,也不适合做精细的量化策略控制。但它们的优势是"零门槛"——我给我那个朋友就是先用Ollama把模型跑通,让他找到体验基线,再去考虑更精细的优化。
4.4 表格对比:主流部署框架定位速查
| 框架 | 核心形态 | 适合场景 | 并发能力 | 量化支持 | 上手成本 |
|---|---|---|---|---|---|
| llama.cpp | C++推理库 | 个人/边缘,CPU+GPU混跑 | 低 | GGUF全系 | 中 |
| Ollama | 封装llama.cpp的应用 | 个人体验、快速踩坑 | 低-中 | GGUF | 极低 |
| LM Studio | 图形界面应用 | 个人调试、可视化分析 | 低 | GGUF | 极低 |
| vLLM | Python推理服务 | 生产环境、高并发 | 高 | GPTQ/AWQ/FP8 | 中高 |
| ONNX Runtime | 跨平台推理引擎 | 边缘设备、服务端跨架构 | 中 | INT8/FP16等 | 中高 |
| TensorRT-LLM | NVIDIA专属引擎 | 极致延迟、高吞吐 | 高 | INT4/INT8/FP8 | 高 |
选型建议就一句:能用Ollama跑通的场景别先上vLLM,能把Ollama跑满的场景再去考虑vLLM换收益,生产环境从第一天就上vLLM这类专门框架。
4.5 本地部署里容易被忽略的环境准备细节
部署框架选好之后,环境准备是很多人翻车的第一步,几个细节值得单独说:
- CUDA和PyTorch版本要匹配,不只是"都装上",而是
torch.version.cuda和nvcc -V要保持一致,不然某些算子会悄悄退回到CPU执行,性能断崖式下跌。 - 依赖安装不要一股脑用最新版。vLLM对某些库的版本有硬性要求,比如
transformers、triton,装错了版本很可能是"能启动但爆显存"或者"OOM但显存还剩一半"这类诡异问题。 - 检查系统swap和文件句柄限制。跑大模型时进程占用内存大,文件句柄数也有可能冲高,在Linux上提前调一下
ulimit能省掉不少麻烦。
另外一个容易被忽略但很重要的点:磁盘IO速度。加载一个7B INT4模型大概是4GB,如果从机械硬盘加载要等很久;但如果是NVMe SSD,模型加载时间可以缩短到几秒级别。做本地部署时,模型文件放在SSD上是基本素质。
5. 模型选型决策框架:算力、精度、延迟怎么平衡
5.1 参数规模不是越大越好
模型选型时最常犯的错误是"排行榜焦虑"——看到某个大杯模型分数高就想上,忽略了自己机器的硬件上限。这里有一个简单的思考框架:
- 你机器的显存决定了权重体积的上限。用INT4量化,7B模型约4GB,14B模型约8GB,32B模型约16-20GB。加上KV Cache和系统开销,一张24GB显存的卡,想跑32B模型的INT4版本已经很紧了。
- decode速度由带宽决定。一张带宽800GB/s的卡跑4GB的INT4模型,理论上限约200 token/s;跑8GB的模型就只剩100 token/s。模型越大,每个token的生成越慢,这是物理规律,不是软件能救的。
- 质量是另一个维度。大模型的优势在复杂推理、长上下文、代码生成等场景,但如果你只是做分类、抽取、格式规整这类简单任务,小模型完全够用,却省下一大截部署成本。
我见过很多项目,部署一个70B模型费了九牛二虎之力,最后实际任务只是"从文档里抽关键字段"——千问和Llama的小杯模型用INT8就轻轻松松完成,成本几乎可以忽略。选模型的第一步不是看排行榜,而是看任务复杂度上限。
5.2 怎么判断一个量化模型"能不能用"
量化模型的质量判断,不能只看"跑起来不报错"。我通常按以下顺序验证:
- perplexity对比:同一模型在不同量化等级下的困惑度,如果INT4比FP16明显退化(比如上涨超过5%),说明量化方案对这个模型不友好,考虑换方法。
- 任务级评测:跑一个跟你的真实场景最接近的评测集(10-20条有代表性的样本就够),对比量化前后的输出,看语义是否一致性保持。
- 输出稳定性检查:量化模型有时会突然输出乱码、重复、无意义内容。让模型生成10次相同的prompt,观察是否有异常波动。
- 边界case测试:至少测一下长文本生成、多轮对话、非中文输入,这些场景最容易暴露量化误差。
这些验证做完,才能决定一个量化版本能不能上线。不建议直接用榜单上的perplexity数字做决策——那测的是通用数据分布,你的场景可能差异很大。
5.3 三类典型需求的具体选型建议
结合最近这波开源模型的热度,我给三类常见需求列一个选型参考:
需求一:个人本地体验,硬件是消费级显卡(8-24GB显存)
- 首选:Ollama + Qwen2.5 7B或14B的INT4/INT8版本,或DeepSeek蒸馏版小模型。
- 理由:Ollama的GGUF混合推理非常适应消费级显卡的小显存;Qwen和DeepSeek的中文能力在同级模型里表现突出。
- 预期:INT4 7B在4090上大概能跑到60-100 token/s,日常聊天完全够用。
需求二:垂直领域应用(代码生成、文档问答、本地知识库)
- 首选:vLLM + 14B/32B级别的INT4/AWQ模型 + RAG架构。
- 理由:14B-32B级别在复杂指令跟随和推理能力上明显强于7B,配合RAG可以在不影响吞吐的前提下补充领域知识。
- 关键:量化用AWQ或GPTQ,优先保质量;并发用vLLM,保吞吐。
需求三:低延迟交互型服务(聊天助手、实时翻译、Agent工具调用)
- 首选:TensorRT-LLM或vLLM + 小模型(7B-8B)INT8/FP8优化。
- 理由:这类场景对首token延迟和每token速度要求极高,小模型配合高效的批处理和算子融合,才能做到"人感觉不到的等待"。
- 建议:并发控制在这个场景更重要,不要盲目开大并发,延迟会指数级恶化。
5.4 一个实际项目的选型复盘
拿我之前做过的一个本地知识库问答项目举例:初期想直接用最强的70B模型,结果一张A100 80GB都要上INT4才能勉强放下,并发一上来吞吐掉得离谱。后来我们把需求拆开——80%的问题其实是"检索+摘要"级别,用14B INT4就能给出满意回答;只有5%的疑难推理问题需要更强模型。最终架构是:14B模型做第一层回答,高置信度直接返回,低置信度才路由到云端更大模型。整体成本下降了接近70%,用户感知到的响应速度和回答质量反而更好了。
这个案例想说明的是:模型选型不是"选一个模型"的事,而是"设计一套决策策略"的事。在算力有限的情况下,分级路由(小模型优先、大模型兜底)往往比一味追求单个大模型更务实。
6. 写在最后:几个让我反复受益的实操习惯
做推理优化和部署这几年,有几个习惯让我省下了不少瞎折腾的时间,分享出来供你参考:
第一,任何优化动作之前,先做基线测量。不管是要量化、换框架、还是上蒸馏,先把你当前的显存占用、吞吐、延迟、质量跑一遍记录下来。没有基线,你怎么知道自己优化是变好了还是变差了?我见过太多人换了框架之后"感觉变快了",结果一测数据反而更慢,只是心理作用。
第二,一次只动一个变量。量化、蒸馏、换框架、调并发,每一项单独做,跑对比,再动下一个。动多个变量同时调整,出了问题你根本无法定位是哪个环节造成的。这个原则听起来很简单,但执行起来特别容易被"顺便一起改了"带偏。
第三,把"质量验收集"固定下来。每个项目我至少会留15-20条质量验收样本,每次优化完跑一遍。这样做的好处是,任何改动导致的性能回退都能第一时间被发现。尤其是量化版和蒸馏版,没有固定验收集就纯粹靠感觉,很容易被调整参数时的偶然表现误导。
推理优化这条路没有终点,模型在换代、框架在迭代、硬件也在更新。今天的最优解过半年可能就成了常规操作,但底层那套"理解瓶颈、量化取舍、验证质量"的方法论不会过时。希望这篇内容能帮你少踩几个我踩过的坑,把更多精力花在真正有趣的问题上。