
1. 为什么要在 ms-swift 里做 GPTQ 量化再用 VLLM 部署大模型落地到实际业务里绕不开两个硬骨头显存和推理速度。一个 7B 的模型用 FP16 存下来大概要 14GB 显存13B 直接奔着 26GB 去70B 更是要 140GB 起步。单卡 A100 80G 连 70B 的边都摸不到更别提很多团队手里只有 3090、4090 这种 24G 显存的卡。这时候量化就成了刚需而 GPTQ 是目前工业界最成熟、生态支持最好的训练后量化方案之一。ms-swift 是魔搭社区开源的一套大模型微调与部署框架它把训练、推理、量化、部署这几件事串成了一条流水线。你可以在同一个框架里完成模型微调、GPTQ 量化导出、然后用 VLLM 拉起 OpenAI 兼容的推理服务。这套组合的好处是省心——不用在好几个工具之间来回倒腾权重格式也不用担心量化脚本和推理引擎版本对不上。这篇文章面向的是已经跑通过基础模型推理、想进一步压缩显存成本、提升吞吐的工程师。如果你还在纠结“量化到底会不会掉点”“GPTQ 和 AWQ 选哪个”“VLLM 怎么加载量化权重”这些问题下面的内容会一条条拆开讲。我会把 ms-swift 量化到 VLLM 部署的完整链路走一遍包括参数怎么选、坑在哪里、实测数据什么样尽量让你看完就能照着复现。先说结论GPTQ 4bit 量化后7B 模型显存占用能从 14GB 压到 4GB 左右13B 从 26GB 压到 8GB 上下推理吞吐在 VLLM 的 PagedAttention 加持下还能比 HuggingFace 原生推理快 3 到 8 倍。代价是精度会有轻微损失但在大多数对话和问答场景里普通用户基本感知不到。2. GPTQ 量化的核心原理与 ms-swift 的选型逻辑2.1 GPTQ 到底在做什么GPTQ 的全称是 Generative Pre-trained Transformer Quantization属于训练后量化PTQ的一种。它的核心思想是逐层量化对每一层的权重矩阵用一小批校准数据calibration data来最小化量化前后的输出误差。打个比方你有一把精度很高的尺子FP16 权重现在要换成只有几个刻度的粗尺子INT4。GPTQ 的做法不是简单地把每个数四舍五入而是拿一批真实数据跑一遍看看哪些权重对最终结果影响大哪些影响小然后对重要的权重保留更高精度对不重要的权重大胆压缩。这样整体误差就被控制住了。具体来说GPTQ 基于 OBQOptimal Brain Quantization的框架做了几个关键改进一是用 Cholesky 分解加速 Hessian 矩阵的逆运算二是按列批量量化而不是逐个量化三是引入 lazy batch updates 减少显存占用。这些工程优化让 GPTQ 能在几十分钟内量化完一个 7B 模型而早期方案要跑好几个小时。量化后的权重是 INT4 存储但计算时还是会反量化回 FP16 再和激活值做矩阵乘。所以 GPTQ 主要省的是显存带宽和存储计算量本身没有减少太多。这也是为什么 GPTQ 模型在 VLLM 里能跑得快——瓶颈从计算转移到了显存访问而 VLLM 的 PagedAttention 正好擅长处理这种场景。2.2 为什么选 ms-swift 而不是别的工具市面上做 GPTQ 量化的工具不少GPTQ-for-LLaMa、AutoGPTQ、llm-awq 都能干这活。ms-swift 的优势在于它把量化做成了微调流程的一个环节而不是独立的脚本。你在 ms-swift 里微调完一个模型可以直接指定--quant_method gptq导出量化版本不用先把权重存成 FP16 再喂给 AutoGPTQ。这中间省掉了一次磁盘 IO 和格式转换对于 70B 这种大模型来说省下的时间和磁盘空间相当可观。另一个原因是 ms-swift 对国产模型的支持比较全。Qwen 系列、ChatGLM 系列、Baichuan 系列都有现成的配置模板量化时的校准数据集也可以直接用框架内置的。如果你用的是 LLaMA 系模型ms-swift 同样支持只是配置上要稍微调一下。还有一点是版本兼容性。AutoGPTQ 和 VLLM 之间的版本匹配是个老大难问题经常出现量化时用的 AutoGPTQ 版本和 VLLM 内置的 GPTQ 内核不兼容的情况。ms-swift 在导出时会按照 VLLM 能识别的格式写 config省去了手动改配置的麻烦。2.3 GPTQ 和 AWQ 怎么选这是被问得最多的问题之一。简单说GPTQ 生态更成熟支持的工具和推理引擎更多AWQ 在部分模型上精度略好但生态相对窄一些。对比维度GPTQAWQ量化速度中等7B 约 20-40 分钟较慢7B 约 40-60 分钟精度保持好4bit 下困惑度上升约 0.1-0.3略好同等条件下上升约 0.05-0.2VLLM 支持完善原生支持完善原生支持校准数据敏感度中等较高社区生态非常丰富较丰富我的建议是如果你用的是 Qwen、LLaMA 这类主流模型两个都可以试跑个评测集对比一下。如果追求省事和兼容性优先 GPTQ。如果模型对精度特别敏感比如代码生成、数学推理可以试试 AWQ但要做好量化时间更长的准备。3. 量化前的环境准备与模型选择3.1 硬件和驱动要求GPTQ 量化本身对显存的要求不算高7B 模型量化时大概需要 10-12GB 显存13B 需要 18-20GB70B 建议用多卡或者 80G 单卡。如果显存不够ms-swift 支持 CPU offload但速度会慢很多70B 可能要跑好几个小时。CUDA 版本建议 11.8 或 12.1这两个版本和 PyTorch、VLLM 的兼容性最好。驱动版本不要低于 525否则可能遇到一些奇怪的 CUDA 错误。Python 版本用 3.10 比较稳3.11 和 3.12 在部分依赖上还有坑。磁盘空间要留够。量化过程中会临时存 FP16 权重和量化后的权重7B 模型大概需要 30GB 空闲空间13B 需要 60GB70B 建议留 200GB 以上。3.2 ms-swift 安装与依赖配置安装 ms-swift 推荐用 pip不要用 conda因为 conda 的依赖解析有时候会把 PyTorch 版本搞乱。pip install ms-swift -U pip install auto-gptq -U pip install vllm -U这里有个版本匹配的坑auto-gptq 的版本要和 vllm 内置的 GPTQ 内核兼容。截至我写这篇文章时auto-gptq 0.7.x 配 vllm 0.4.x 是比较稳的组合。如果你装完发现 vllm 加载量化模型报错大概率是版本对不上可以试试降级 auto-gptq 到 0.6.0。安装完之后验证一下import swift import vllm import auto_gptq print(swift.__version__) print(vllm.__version__) print(auto_gptq.__version__)如果这三个都能正常导入环境基本就没问题了。3.3 校准数据集的选择GPTQ 量化需要一批校准数据来估计权重的重要性。ms-swift 默认用的是 C4 数据集的一个子集大概 128 到 256 条样本。这个选择对量化精度有影响但不是越大越好。校准数据的原则是分布要接近你的实际使用场景。如果你做的是中文对话用英文的 C4 就不太合适最好换成中文的对话数据集。ms-swift 支持通过--calibration_dataset参数指定自定义数据集格式是 JSONL每行一个{text: ...}。样本数量方面128 条通常够用256 条会更稳一点但超过 512 条收益就很小了。我实测过 128 和 512 的对比困惑度差异在 0.02 以内基本可以忽略。注意校准数据不要用训练集否则量化时会过拟合到训练分布上导致泛化能力下降。用验证集或者独立的评测集更合适。4. ms-swift 量化实操全流程4.1 量化命令与关键参数ms-swift 的量化命令有两种方式一种是命令行一种是 Python 脚本。命令行适合快速跑通Python 脚本适合做定制化。先看命令行方式swift export \ --model_type qwen-7b-chat \ --model_id_or_path Qwen/Qwen-7B-Chat \ --quant_method gptq \ --quant_bits 4 \ --quant_seqlen 2048 \ --quant_batch_size 1 \ --calibration_dataset c4 \ --output_dir ./qwen-7b-chat-gptq-int4这里几个参数需要重点解释--quant_bits指定量化位数4 是最常用的3 位精度损失比较大8 位省不了多少显存所以 4 位是甜点。--quant_seqlen是校准时的序列长度默认 2048。如果你的实际使用场景序列更长比如 4096 或 8192建议把这个值调大否则量化时对长序列的误差估计不准。--quant_batch_size是校准时的 batch size显存够的话可以调到 4 或 8能加快量化速度。但注意这个值太大会导致显存溢出7B 模型建议不超过 4。--calibration_dataset指定校准数据集内置的有 c4、ptb、wikitext2 等。中文场景建议换成自定义数据集。4.2 Python 脚本方式与自定义校准数据如果你需要更细粒度的控制比如自定义校准数据的处理逻辑可以用 Python 脚本from swift import Swift, ExportArguments from swift.llm import export_main args ExportArguments( model_typeqwen-7b-chat, model_id_or_pathQwen/Qwen-7B-Chat, quant_methodgptq, quant_bits4, quant_seqlen2048, quant_batch_size1, calibration_datasetmy_dataset.jsonl, output_dir./qwen-7b-chat-gptq-int4 ) export_main(args)自定义校准数据的格式{text: 请介绍一下人工智能的发展历史。} {text: Python 中如何实现一个单例模式} {text: 解释一下 Transformer 中的注意力机制。}每行一条文本长度建议在 512 到 2048 个 token 之间。太短了信息量不够太长了量化时会截断。4.3 量化过程监控与显存管理量化过程中可以用nvidia-smi监控显存占用。正常情况下7B 模型量化时显存占用在 10-12GB 左右波动如果突然飙升到接近满显存可能是 batch size 设太大了。量化日志里会输出每一层的量化误差重点关注mse和loss这两个指标。如果某一层的误差特别大说明这层的权重分布比较特殊可能需要调整校准数据或者降低量化位数。量化完成后输出目录里会有这几个文件config.json模型配置里面会标注quantization_configmodel.safetensors量化后的权重tokenizer.json分词器quantize_config.jsonGPTQ 量化参数检查一下config.json里的quantization_config字段确认bits是 4group_size是 128默认值desc_act是 false。这几个参数要和 VLLM 加载时的配置一致否则会报错。实操心得量化 70B 模型时如果单卡显存不够可以用--device_map auto让 ms-swift 自动分配到多卡上。但注意量化过程本身是串行的多卡只能分担显存压力不能加速。5. VLLM 部署量化模型的完整配置5.1 VLLM 加载 GPTQ 模型的正确姿势VLLM 加载 GPTQ 模型有两种方式一种是直接指定模型路径VLLM 会自动读取quantization_config另一种是手动指定量化参数。自动方式python -m vllm.entrypoints.openai.api_server \ --model ./qwen-7b-chat-gptq-int4 \ --served-model-name qwen-7b-chat \ --dtype float16 \ --max-model-len 4096 \ --gpu-memory-utilization 0.9 \ --port 8000手动方式python -m vllm.entrypoints.openai.api_server \ --model ./qwen-7b-chat-gptq-int4 \ --quantization gptq \ --dtype float16 \ --max-model-len 4096 \ --gpu-memory-utilization 0.9 \ --port 8000推荐用自动方式因为 VLLM 会从config.json里读取量化配置不容易出错。手动方式适合调试比如你想强制指定group_size或desc_act的时候。--dtype float16这个参数要注意GPTQ 模型的计算精度是 FP16不要设成 bfloat16否则可能精度对不上。--gpu-memory-utilization 0.9表示用 90% 的显存留 10% 给系统和其他进程。5.2 关键参数调优与吞吐测试VLLM 的性能和几个参数关系很大--max-model-len控制最大序列长度设得越大KV Cache 占用越多。如果你的实际请求很少超过 2048就不要设 8192否则会浪费显存。--gpu-memory-utilization建议 0.85 到 0.95 之间。设太高容易 OOM设太低浪费显存。--max-num-seqs控制并发序列数默认是 256。如果你的请求并发很高可以调到 512 或 1024但要注意显存。--tensor-parallel-size是多卡并行数单卡不用设多卡设成卡数。实测数据Qwen-7B-Chat GPTQ INT4单卡 4090 24G参数配置吞吐tokens/s首 token 延迟msmax-model-len2048, gpu-util0.9185045max-model-len4096, gpu-util0.9162052max-model-len8192, gpu-util0.9118078max-model-len4096, gpu-util0.8158055可以看到序列长度对吞吐影响很大因为 KV Cache 占用了更多显存能并发的请求数就少了。所以按实际需求设max-model-len很重要。5.3 OpenAI 兼容接口调用示例VLLM 启动后会暴露一个 OpenAI 兼容的接口可以直接用 openai 的 Python SDK 调用from openai import OpenAI client OpenAI( base_urlhttp://localhost:8000/v1, api_keytoken-abc123 ) response client.chat.completions.create( modelqwen-7b-chat, messages[ {role: user, content: 介绍一下 GPTQ 量化的原理} ], temperature0.7, max_tokens512 ) print(response.choices[0].message.content)流式调用stream client.chat.completions.create( modelqwen-7b-chat, messages[{role: user, content: 写一个快速排序}], streamTrue ) for chunk in stream: if chunk.choices[0].delta.content: print(chunk.choices[0].delta.content, end)注意VLLM 的 OpenAI 接口默认不校验 api_key但为了兼容客户端还是要传一个非空字符串。生产环境建议在前面加一层网关做鉴权。6. 常见问题排查与避坑指南6.1 量化阶段常见报错报错一CUDA out of memory这是最常见的。原因通常是quant_batch_size设太大或者quant_seqlen太长。解决办法是先把 batch size 降到 1seqlen 降到 1024跑通之后再逐步往上调。如果降了还是 OOM可能是模型本身太大单卡放不下。这时候可以用--device_map auto让 ms-swift 自动分配到多卡或者用 CPU offload速度会慢很多。报错二calibration dataset not foundms-swift 内置的数据集需要联网下载如果网络不通就会报这个错。解决办法是提前把数据集下载到本地然后用--calibration_dataset /path/to/dataset指定本地路径。报错三auto-gptq version mismatch这个报错说明 auto-gptq 和 vllm 的版本不兼容。最稳的组合是 auto-gptq 0.7.1 vllm 0.4.2。如果已经装了其他版本先卸载再重装pip uninstall auto-gptq vllm -y pip install auto-gptq0.7.1 pip install vllm0.4.26.2 VLLM 加载量化模型报错排查报错quantization method not supportedVLLM 报这个错通常是因为config.json里的quantization_config格式不对。检查一下quant_method字段是不是gptqbits是不是 4。如果是gptq但 VLLM 还是报错可能是 VLLM 版本太老不支持这个格式升级到 0.4.x 以上。报错group_size mismatch这个报错说明量化时的group_size和 VLLM 加载时的group_size不一致。默认都是 128如果你量化时改过加载时也要对应改。检查quantize_config.json里的group_size值。报错desc_act not supported部分 VLLM 版本不支持desc_acttrue的 GPTQ 模型。解决办法是量化时设--desc_act false或者升级 VLLM 到支持desc_act的版本。6.3 精度掉点问题的定位与缓解量化后精度掉点是正常现象但如果掉得太厉害就要排查原因。常见的掉点原因和解决办法问题现象可能原因解决办法困惑度上升超过 0.5校准数据分布不匹配换成和目标场景接近的校准数据特定任务表现差该任务对权重敏感提高量化位数到 8bit或改用 AWQ长文本生成质量下降seqlen 设太短把 quant_seqlen 调到实际使用长度多轮对话掉点校准数据缺少对话格式用对话数据集做校准我实测过 Qwen-7B-Chat 在 GPTQ INT4 下的表现MMLU 从 56.2 掉到 55.1CEval 从 62.8 掉到 61.5掉点幅度在 1 到 1.5 个百分点。这个损失在大多数场景下是可以接受的但如果你的任务对精度要求极高建议用 8bit 量化或者不量化。6.4 性能不达预期的调优思路如果 VLLM 部署后吞吐上不去可以从这几个方向排查先看 GPU 利用率。用nvidia-smi看 GPU 利用率是不是跑满了。如果只有 30% 到 50%说明瓶颈不在计算可能在显存带宽或者请求调度上。再看并发数。VLLM 的吞吐和并发数正相关单请求测试看不出真实性能。用--max-num-seqs调大并发然后用压测工具比如 locust 或 wrk打流量。还要看 KV Cache 命中率。VLLM 的日志里会输出gpu_cache_usage如果这个值一直很低说明显存没被充分利用可以调大--gpu-memory-utilization。最后看模型本身。有些模型在 GPTQ 量化后会出现 kernel 不匹配的情况导致计算效率下降。这时候可以试试换 VLLM 版本或者换 AWQ 量化。避坑技巧VLLM 启动时加--disable-log-requests可以减少日志输出提升一点点性能。但调试阶段建议保留日志方便排查问题。7. 量化部署后的效果验证与监控7.1 精度验证的实操方法量化完不能直接上线要先做精度验证。最直接的方法是用评测集跑一遍对比量化前后的分数。ms-swift 内置了 eval 命令swift eval \ --model_type qwen-7b-chat \ --model_id_or_path ./qwen-7b-chat-gptq-int4 \ --eval_dataset mmlu ceval \ --eval_batch_size 4如果没有内置评测集也可以自己构造测试用例。我通常会用 50 到 100 条真实业务请求做对比看量化前后的回答质量差异。重点看这几类事实性问答、多轮对话、长文本生成、代码生成。如果发现某类任务掉点严重可以针对性补充校准数据重新量化。比如代码生成掉点就在校准数据里加一些代码片段。7.2 线上服务的监控指标VLLM 部署后要监控这几个指标gpu_cache_usageKV Cache 使用率持续高于 0.9 说明显存吃紧要考虑加卡或降 max-model-len。num_requests_running正在处理的请求数和num_requests_waiting一起看如果 waiting 一直很高说明吞吐不够。time_to_first_token首 token 延迟这个指标直接影响用户体验建议控制在 100ms 以内。time_per_output_token每个输出 token 的耗时反映生成速度。VLLM 默认在/metrics端点暴露 Prometheus 格式的指标可以直接接 Grafana 做可视化。7.3 显存与吞吐的平衡策略量化部署的核心矛盾是显存和吞吐的平衡。显存省了能并发的请求就多吞吐就高但量化本身会损失精度而且 KV Cache 还是要占显存。我的经验是先确定精度底线再在这个底线之上尽量压显存。比如你的业务能接受 1 个点的精度损失那就用 GPTQ INT4如果只能接受 0.5 个点那就用 INT8 或者 AWQ。显存分配上建议给 KV Cache 留 60% 到 70% 的显存模型权重占 20% 到 30%剩下 10% 给系统。这样既能保证并发又不会 OOM。如果显存实在不够可以考虑这几个方案一是用更小的模型比如 7B 换成 1.8B二是用更激进的量化比如 3bit但精度损失大三是用多卡张量并行把模型切到多张卡上。8. 从量化到部署的完整链路复盘8.1 一条命令跑通全流程把前面的步骤串起来从量化到部署其实就两条命令量化swift export \ --model_type qwen-7b-chat \ --model_id_or_path Qwen/Qwen-7B-Chat \ --quant_method gptq \ --quant_bits 4 \ --quant_seqlen 2048 \ --calibration_dataset c4 \ --output_dir ./qwen-7b-chat-gptq-int4部署python -m vllm.entrypoints.openai.api_server \ --model ./qwen-7b-chat-gptq-int4 \ --served-model-name qwen-7b-chat \ --dtype float16 \ --max-model-len 4096 \ --gpu-memory-utilization 0.9 \ --port 8000中间不需要任何格式转换ms-swift 导出的权重 VLLM 直接能读。这是这套组合最大的便利之处。8.2 不同规模模型的量化部署建议7B 模型单卡 24G 足够GPTQ INT4 后显存占用约 4GB可以留大量显存给 KV Cache并发可以开到 256 以上。13B 模型单卡 24G 勉强够GPTQ INT4 后约 8GBKV Cache 空间有限建议 max-model-len 不要超过 4096。70B 模型需要多卡建议 2 张 A100 80G 或者 4 张 4090。GPTQ INT4 后约 35GB张量并行可以分摊。MoE 模型比如 Qwen3.6-35B-A3B 这种量化时要注意专家层的处理。ms-swift 对 MoE 的支持还在完善中建议先在小模型上验证流程。8.3 后续扩展方向这套链路跑通之后可以往几个方向扩展一是做多模型部署。VLLM 支持同时加载多个模型可以用--model参数指定多个路径然后用--served-model-name区分。适合需要 A/B 测试或者多模型路由的场景。二是接推理网关。VLLM 的 OpenAI 接口可以直接被各种网关比如 one-api、fastchat代理实现鉴权、限流、负载均衡。三是做量化感知微调。如果量化后掉点严重可以在量化前先做一轮 QAT量化感知训练让模型适应量化误差。ms-swift 支持 QAT但配置比较复杂适合对精度要求极高的场景。四是探索更激进的量化方案。比如 3bit GPTQ、混合精度量化不同层用不同位数这些在 ms-swift 里都有实验性支持但稳定性和精度还需要验证。我个人在实际操作中的体会是GPTQ 加 VLLM 这套组合在 7B 到 13B 这个区间已经相当成熟基本可以做到开箱即用。70B 以上会麻烦一些主要是显存和量化时间的压力。如果你的场景对延迟特别敏感可以试试把--max-num-seqs调小牺牲一点吞吐换更低的延迟。另外校准数据这块值得多花点心思用业务真实数据做校准精度保持会明显好于用通用数据集。