五期-基础岛03-LMDeploy
基础岛
L1G3-LMDeploy 课程
1 概念
LMDeploy 是什么
- 它是一个高效的LLMs模型部署工具箱,功能包括:量化,推理和服务。
推理方面,和个人常用的ollama工具一样码
- Ollama:“傻瓜相机”,适合快速体验模型,但功能和性能受限于封装。
- LMDeploy 等框架:“专业单反”,适合开发者按需定制,可挖掘硬件极限性能
如果需要快速部署个人 AI 助手,Ollama 是理想选择;但如果需要在企业级场景中部署多模态模型或追求极致性能,LMDeploy 等框架更具优势。
使用场景对比图
场景 Ollama 更适合 LMDeploy 更适合 个人本地试用 ✅(5 分钟内启动模型) ❌(需配置环境和参数) 企业私有化部署 ❌(功能有限,难定制) ✅(支持多卡并行、安全审计) 多模态应用开发 ❌(需自行整合视觉模型) ✅(原生支持图文联合推理) 性能极致优化 ❌(依赖 llama.cpp 固定优化) ✅(可自定义 TensorRT 计算图)
量化方面
LMDeploy 支持的量化服务是一种通过降低模型参数精度来优化推理效率的技术,其核心目标是在保持模型性能的前提下,大幅减少计算资源消耗。
什么是量化服务:将模型权重(通常为 FP32/FP16 高精度浮点数)转换为低精度格式(如 INT8/INT4 整数)的过程。
- FP16 → INT8:将 16 位浮点数压缩为 8 位整数,显存占用减少一半。
- FP16 → INT4:压缩为 4 位整数,显存占用降至 1/4。
LMDeploy 支持的量化算法包括:
- GPTQ:基于 Hessian 矩阵估计的量化方法,在 INT4 精度下保持接近原生模型的性能。
- AWQ(Activation-aware Weight Quantization):零样本权重量化,无需微调即可实现高精度 INT4 压缩。
- INT8 量化:通用量化方案,兼容性强,适合大多数场景。
适用场景:
场景 | 量化方案推荐 | 收益 |
---|---|---|
本地部署(消费级 GPU) | INT4 (GPTQ/AWQ) | 在 RTX 4090 上运行 70B 模型 |
云端服务(高并发) | INT8 或 INT4 | 吞吐量提升 2-3 倍,降低 50% 硬件成本 |
边缘设备(低功耗) | INT8 | 在 Jetson AGX 上实时运行多模态模型 |
高精度要求场景 | INT8 或 FP16(不量化) | 医疗影像分析等对精度敏感的任务 |
2 环境安装
1 安装
使用miniconda环境,需要同学们优先安装好miniconda。
conda create -n lmdeploy python=3.10
conda activate lmdeploy
pip install lmdeploy
pip install timm==1.0.15 #安装本地推理需要的依赖
3 部署LLMs(大语言模型)
1. 单卡部署
import lmdeploy
from lmdeploy import GenerationConfig
pipe = lmdeploy.pipeline("/root/share/new_models/internlm3/internlm3-8b-instruct")
response = pipe(prompts=["Hi, pls intro yourself", "Shanghai is"],
gen_config=GenerationConfig(max_new_tokens=1024,
top_p=0.8,
top_k=40,
temperature=0.6))
参数解释:
token是回答的长度限制。
temperature是回答随机性控制,别太死板,但也别太离谱。
用词别太生僻(只考虑概率高的词,top_p=0.8, top_k=40)
2. 多卡部署
from lmdeploy import pipeline, TurbomindEngineConfig
from lmdeploy import pipeline, PytorchEngineConfig
### TurbomindEngineConfig推理引擎
pipe = pipeline('/root/share/new_models/internlm3/internlm3-8b-instruct',
backend_config=TurbomindEngineConfig(
tp=2,
max_batch_size=32,
enable_prefix_caching=True,
cache_max_entry_count=0.8,
session_len=8192,
))
### PytorchEngineConfig推理引擎
pipe = pipeline('/root/share/new_models/internlm3/internlm3-8b-instruct',
backend_config=PytorchEngineConfig(
tp=2,
max_batch_size=32,
enable_prefix_caching=True,
cache_max_entry_count=0.8,
session_len=8192,
))
3. 部署类OpenAI 服务
3.1 不启用权限鉴别(api-key)
lmdeploy serve api_server /root/share/new_models/InternVL3/InternVL3-1B --server-port 23333
from openai import OpenAI
client = OpenAI(
api_key='none',# 若未启用鉴权,可填任意值(如 "none")
base_url="http://0.0.0.0:23333/v1"
)
model_name = client.models.list().data[0].id
response = client.chat.completions.create(
model=model_name,
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": " provide three suggestions about time management"},
],
temperature=0.8,
top_p=0.8
)
print(response)
3.2 启用权限鉴别(api-key)
lmdeploy serve api_server /root/share/new_models/internlm3/internlm3-8b-instruct --server-port 23333 --api-keys "token"
接口调用带token:
from openai import OpenAI
client = OpenAI(
api_key='token',
base_url="http://0.0.0.0:23333/v1"
)
model_name = client.models.list().data[0].id
response = client.chat.completions.create(
model=model_name,
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": " provide three suggestions about time management"},
],
temperature=0.8,
top_p=0.8
)
print(response)
3.3 异步访问(api-key)
import asyncio
from openai import AsyncOpenAI
async def main():
client = AsyncOpenAI(api_key='token',
base_url='http://0.0.0.0:23333/v1')
model_cards = await client.models.list()._get_page()
response = await client.chat.completions.create(
model=model_cards.data[0].id,
messages=[
{
'role': 'system',
'content': 'You are a helpful assistant.'
},
{
'role': 'user',
'content': ' provide three suggestions about time management'
},
],
temperature=0.8,
top_p=0.8)
print(response)
asyncio.run(main())
使用异步访问返回会快一些,LMDeploy 的异步访问(如使用 async/await
)和直接同步访问的主要区别在于 执行模式 和 资源利用率。
执行模式
同步访问 | 异步访问 |
---|---|
代码按顺序执行,请求会阻塞线程 | 使用协程(coroutine)非阻塞执行 |
必须等待当前请求完成才能处理下一个 | 可以同时处理多个请求(I/O 多路复用) |
适合单任务、简单流程 | 适合高并发、多任务场景 |
资源利用率
- 同步:在等待模型响应时,线程处于阻塞状态,无法处理其他请求。
- 异步:在等待模型响应时,线程可以去处理其他请求,提高吞吐量。
性能表现
- 同步:处理单个请求时延迟可能更低,但并发能力差。
- 异步:单个请求的延迟可能略高(但差距通常很小),但大量并发请求时总吞吐量显著提升,整体响应速度更快。
为什么返回变快的可能理由:
- 减少线程阻塞:
- 即使只有一个请求,异步模式也能避免在网络 I/O 或模型推理时阻塞线程,让其他任务(如 UI 更新)可以继续执行。
- LMDeploy 的优化:
- LMDeploy 的异步引擎针对 GPU 推理做了优化(如批量处理、内存预分配),可能进一步提升了性能。
4 使用APIClient 接口
启动服务同3:
lmdeploy serve api_server /root/share/new_models/internlm3/internlm3-8b-instruct --server-port 23333 --api-keys "token"
使用APIClinet进行推理:
from lmdeploy.serve.openai.api_client import APIClient
client = APIClient(
api_server_url="http://localhost:23333",
api_key="token"
)
model_name = client.available_models[0]
messages = [{"role": "user", "content": "你好"}]
for item in client.chat_completions_v1(model=model_name, messages=messages):
print(item)
5. Requests调用
1. 启动服务
lmdeploy serve api_server /root/share/new_models/internlm3/internlm3-8b-instruct --server-port 23333 --api-keys "token"
2. request发送请求
import requests
url = "http://localhost:23333/v1/chat/completions"
headers = {
"Authorization": "Bearer token", # Bearer + Token
"Content-Type": "application/json"
}
data = {
"model": "/root/share/new_models/internlm3/internlm3-8b-instruct",
"messages": [{"role": "user", "content": "你好"}]
}
response = requests.post(url, headers=headers, json=data)
print(response.json()["choices"][0]["message"]["content"])
4 视觉-语言模型(VLMs)部署
1. 离线部署
from lmdeploy import pipeline
from lmdeploy.vl import load_image
pipe = pipeline('/root/share/new_models/InternVL3/InternVL3-1B')
image = load_image('https://raw.githubusercontent.com/open-mmlab/mmdeploy/main/tests/data/tiger.jpeg')
response = pipe(('describe this image', image))
print(response)
2. 多卡并行
from lmdeploy import pipeline, TurbomindEngineConfig,PytorchEngineConfig
from lmdeploy.vl import load_image
pipe = pipeline('root/share/new_models/InternVL3/InternVL3-1B',
backend_config=PytorchEngineConfig(tp=2))
image = load_image('tiger.jpeg')
response = pipe(('describe this image', image))
print(response)
3. 图片 token
1.图像标记
IMAGE_TOKEN = '<IMAGE_TOKEN>'
常见模型的图像标记格式
不同模型可能使用不同的图像标记,常见格式包括:
模型 | 图像标记格式 | ||||
---|---|---|---|---|---|
InternVL | `< | ImageBegin | >< | ImageEnd | >` |
LLaVA | <image> | ||||
MiniGPT-4 | [IMAGE] |
对于 InternVL3,建议查看其官方文档或配置文件确认具体格式。
IMAGE_TOKEN是一个特殊的token,在文本序列中插入 IMAGE_TOKEN 可以明确标注图像的位置,帮助模型区分文本和图像的边界。
2. 代码执行
from lmdeploy import pipeline, VisionConfig
from lmdeploy.vl import load_image
from lmdeploy.vl.constants import IMAGE_TOKEN
pipe = pipeline('/root/share/new_models/InternVL3/InternVL3-1B',
vision_config=VisionConfig(
max_batch_size=8
))
image = load_image('https://raw.githubusercontent.com/open-mmlab/mmdeploy/main/tests/data/tiger.jpeg')
response = pipe((f'describe this image{IMAGE_TOKEN}', image))
print(response)
4. 自定义对话模板
from lmdeploy.model import MODELS, BaseChatTemplate
@MODELS.register_module(name='customized_model')
class CustomizedModel(BaseChatTemplate):
"""A customized chat template."""
def __init__(self,
system='<|im_start|>system\n',
meta_instruction='You are a robot developed by LMDeploy.',
user='<|im_start|>user\n',
assistant='<|im_start|>assistant\n',
eosys='<|im_end|>\n',
eoh='<|im_end|>\n',
eoa='<|im_end|>',
separator='\n',
stop_words=['<|im_end|>', '<|action_end|>']):
super().__init__(system=system,
meta_instruction=meta_instruction,
eosys=eosys,
user=user,
eoh=eoh,
assistant=assistant,
eoa=eoa,
separator=separator,
stop_words=stop_words)
from lmdeploy import ChatTemplateConfig, pipeline
messages = [{'role': 'user', 'content': 'who are you?'}]
pipe = pipeline('/root/share/new_models/InternVL3/InternVL3-1B',
chat_template_config=ChatTemplateConfig('customized_model'))
for response in pipe.stream_infer(messages):
print(response.text, end='')
输出:
I am an AI developed by LMDeploy, designed to assist with a wide range of tasks and provide information. My purpose is to help users by answering questions, offering explanations, and providing guidance on various topics. If you have any specific questions or need assistance with something, feel free to ask!
5 视觉模型参数
max_batch_size 就是最大处理几张图片
thread_safe 单线程执行还是多线程执行
from lmdeploy import pipeline, VisionConfig
from lmdeploy.vl import load_image
vision_config=VisionConfig(max_batch_size=16)
pipe = pipeline('/root/share/new_models/InternVL3/InternVL3-1B', vision_config=vision_config)
image = load_image('https://raw.githubusercontent.com/open-mmlab/mmdeploy/main/tests/data/tiger.jpeg')
response = pipe(('describe this image', image))
print(response)
###VisionConfig 源码
from dataclasses import dataclass
@dataclass
class VisionConfig:
"""Vison model configs.
Args:
max_batch_size (int): the max image size passed to the model, since
some models will use image patch, the actual running batch could
be larger than this value. 一次处理的最大图片数量
thread_safe (bool): Specifies whether the engine instance is
thread-safe. Please set it to True when using the pipeline
in a multi-threaded environment. false 单线程 true 多线程执行
"""
max_batch_size: int = 1
thread_safe: bool = False
输出:
2025-07-03 20:25:45,575 - lmdeploy - WARNING - async_engine.py:652 - Since v0.6.0, lmdeploy add `do_sample` in GenerationConfig. It defaults to False, meaning greedy decoding. Please set `do_sample=True` if sampling decoding is needed
Response(text='The image shows a tiger lying on a grassy area. The tiger has distinctive orange fur with black stripes, and it appears to be relaxed, with its front paws resting on the grass. The background is a lush green, suggesting a natural or zoo-like setting.', generate_token_len=54, input_token_len=1843, finish_reason='stop', token_ids=[785, 2168, 4933, 264, 51735, 20446, 389, 264, 16359, 88, 3082, 13, 576, 51735, 702, 34847, 18575, 18241, 448, 3691, 54688, 11, 323, 432, 7952, 311, 387, 30367, 11, 448, 1181, 4065, 281, 8635, 40119, 389, 279, 16359, 13, 576, 4004, 374, 264, 57267, 6176, 11, 22561, 264, 5810, 476, 40914, 12681, 6243, 13], logprobs=None, logits=None, last_hidden_state=None, index=0)
6.多图推理
from lmdeploy import pipeline, TurbomindEngineConfig
from lmdeploy.vl import load_image
pipe = pipeline('/root/share/new_models/InternVL3/InternVL3-1B',
backend_config=TurbomindEngineConfig(session_len=8192))
image_urls=[
'https://raw.githubusercontent.com/open-mmlab/mmdeploy/main/demo/resources/human-pose.jpg',
'https://raw.githubusercontent.com/open-mmlab/mmdeploy/main/demo/resources/det.jpg'
]
images = [load_image(img_url) for img_url in image_urls]
response = pipe(('describe the two images', images))
print(response)
输出:
2025-07-03 20:28:35,366 - lmdeploy - WARNING - async_engine.py:652 - Since v0.6.0, lmdeploy add `do_sample` in GenerationConfig. It defaults to False, meaning greedy decoding. Please set `do_sample=True` if sampling decoding is needed
Response(text='
The first image shows a person skiing on a snowy slope. The individual is dressed in winter gear, including a red jacket, black pants, a striped beanie, and sunglasses. They are holding ski poles and appear to be in motion, possibly taking a break or enjoying the activity. The background features a snow-covered landscape with trees and parked cars along a road.\n\n
The second image depicts a park setting with a bench situated on a grassy area. There are several trees providing shade, and a paved path runs alongside the grass. In the background, there are parked cars and a road with more trees and buildings visible. The bench is empty, suggesting it might be a quiet time of day or a less frequented area.'
, generate_token_len=145, input_token_len=3636, finish_reason='stop', token_ids=[785, 1156, 2168, 4933, 264, 1697, 62017, 389, 264, 89773, 30232, 13, 576, 3842, 374, 25365, 304, 12406, 14448, 11, 2670, 264, 2518, 26208, 11, 3691, 24549, 11, 264, 67590, 387, 19151, 11, 323, 59369, 13, 2379, 525, 9963, 28679, 50779, 323, 4994, 311, 387, 304, 11379, 11, 10767, 4633, 264, 1438, 476, 21413, 279, 5702, 13, 576, 4004, 4419, 264, 11794, 83308, 18414, 448, 12408, 323, 42235, 9331, 3156, 264, 5636, 382, 785, 2086, 2168, 61891, 264, 6118, 6243, 448, 264, 13425, 30083, 389, 264, 16359, 88, 3082, 13, 2619, 525, 3807, 12408, 8241, 27501, 11, 323, 264, 62575, 1815, 8473, 16263, 279, 16359, 13, 758, 279, 4004, 11, 1052, 525, 42235, 9331, 323, 264, 5636, 448, 803, 12408, 323, 13702, 9434, 13, 576, 13425, 374, 4287, 11, 22561, 432, 2578, 387, 264, 11340, 882, 315, 1899, 476, 264, 2686, 6166, 15864, 3082, 13], logprobs=None, logits=None, last_hidden_state=None, index=0)
7.多轮对话
使用pipeline 进行多轮对话有两种方式,一种是按照 openai 的格式来构造 messages,另外一种是使用 pipeline.chat 接口。
pipeline.chat 多轮对话
from lmdeploy import pipeline, TurbomindEngineConfig, GenerationConfig
from lmdeploy.vl import load_image
pipe = pipeline('/root/share/new_models/InternVL3/InternVL3-1B', # 注意加了 `/`
backend_config=TurbomindEngineConfig(session_len=8192))
image = load_image('https://raw.githubusercontent.com/open-mmlab/mmdeploy/main/demo/resources/human-pose.jpg')
gen_config = GenerationConfig(top_k=40, top_p=0.8, temperature=0.6)
# 第一句图文对话
sess = pipe.chat(('describe this image', image), gen_config=gen_config)
print(sess.response.text)
# 第二轮多轮对话
sess = pipe.chat('What is the woman doing?', session=sess, gen_config=gen_config)
print(sess.response.text)
输出:
2025-07-03 20:48:54,933 - lmdeploy - WARNING - async_engine.py:652 - Since v0.6.0, lmdeploy add `do_sample` in GenerationConfig. It defaults to False, meaning greedy decoding. Please set `do_sample=True` if sampling decoding is needed
The image shows a person skiing on a snowy slope. They are wearing a red and white jacket, black pants, a striped beanie, sunglasses, and gloves. The skier is holding ski poles and appears to be in a relaxed stance. The background is a snowy landscape with a ski trail visible in the distance.
The woman is skiing on a snowy slope. She is holding ski poles and seems to be in a relaxed skiing posture.
8 类OpenAI服务
参考3.3等LLMs的部署方式。
5.模型量化
1 量化模型
LMDeploy 量化模块目前仅支持 AWQ 量化算法。
量化是指将高精度数字转换为低精度数字。低精度实体可以存储在磁盘上很小的空间内,从而减少内存需求。
conda activate lmdeploy
pip uninstall -y datasets && pip install --no-cache-dir "datasets==2.19.2"
1.1 量化internlm2-chat-7b
的命令
export HF_MODEL=/root/share/model_repos/internlm2-chat-7b
export WORK_DIR=/root/LMDeploy/internlm2-chat-7b-4bit
lmdeploy lite auto_awq $HF_MODEL --calib-dataset 'ptb' --calib-samples 128 --calib-seqlen 2048 --w-bits 4 --w-group-size 128 --batch-size 1 --work-dir $WORK_DIR
也许在执行第一次时什么也没出现,继续执行量化,执行语句本身没有问题;
参数解释:
--work-dir $WORK_DIR
1. $HF_MODEL
作用:指定要量化的大语言模型的路径或名称。
大白话:告诉程序 “我要优化这个模型”,可以是本地文件夹路径(如 /root/.../model),也可以是 Hugging Face 上的模型名称(如 gpt2)。
2. --calib-dataset 'ptb'
作用:指定用于校准(收集统计信息)的数据集。
大白话:“用这个数据集来教模型怎么压缩”。ptb 是一个小型英文语料库(Penn Treebank),类似 “练习题”,让模型在压缩前先 “学一学”。
3. --calib-samples 128
作用:从校准数据集中选取多少样本用于校准。
大白话:“只挑 128 道题给模型练习”,样本太多会慢,太少则可能学不扎实。
4. --calib-seqlen 2048
作用:每个校准样本的最大长度(token 数量)。
大白话:“每道练习题最长 2048 个字”,超过部分会被截断(比如小说只取前 2048 个字)。
5. --w-bits 4
作用:将模型权重压缩到多少位(bit)。
大白话:“把模型的‘精度’从 32 位砍到 4 位”。位数越低,模型越小(如从 7GB 变成 2GB),但可能会损失一些 accuracy。
6. --w-group-size 128
作用:权重分组的大小,用于更精细的压缩。
大白话:“每 128 个权重分为一组,每组单独压缩”。分组越小,压缩越精准,但计算量也越大。
7. --batch-size 1
作用:校准过程中每次处理的样本数量。
大白话:“每次只让模型做 1 道题”。batch 越大,速度越快,但可能需要更多显存。
8. --work-dir $WORK_DIR
作用:保存压缩后模型的输出目录。
大白话:“把压缩好的模型放在这个文件夹里”,例如 /output/model_4bit。
总结
这个命令的核心是:
“用 PTB 数据集的 128 个样本(每个最长 2048 字),把 $HF_MODEL 这个大模型压缩成 4 位精度,每 128 个权重一组,每次处理 1 个样本,最后把结果保存在 $WORK_DIR 里。”
压缩后的模型会更小、更快,但可能会比原始模型稍微 “笨” 一点。
为什么会用到PTB数据集量化:‘
在模型量化过程中使用PTB(Penn Treebank)数据集或类似的校准数据集是为了**让量化后的模型尽可能保持原始精度**。下面我用通俗易懂的语言解释其核心原因:
### **为什么需要校准数据集?**
量化(比如从32位浮点数压缩到4位整数)会不可避免地损失精度,就像把高清照片压缩成小尺寸JPG会变模糊一样。为了让模型在变“小”的同时尽量不“变笨”,需要让它在压缩前“学习”如何更好地舍入和近似。
**PTB数据集的作用**:
1. **收集统计信息**:通过让模型处理PTB中的文本,收集权重和激活值的分布情况(比如最大值、最小值、均值)。这些统计信息用于确定最优的量化参数(比如如何将32位值映射到4位空间)。
2. **最小化精度损失**:基于PTB的统计信息,量化算法可以智能地调整舍入策略,减少关键信息的丢失。
### **为什么是PTB?**
PTB是一个经典的英文语料库,包含约100万个词,覆盖了新闻、小说等多种文本类型。它被广泛用于语言模型训练和评估,原因是:
- **规模适中**:不大不小,既能代表真实文本的多样性,又不会导致校准时间过长。
- **公开且标准化**:大家都用它,便于不同模型和方法的公平比较。
- **通用性**:英文文本的统计特性(如词频分布)具有一定普适性,适用于大多数英文模型。
### **能否用其他数据集替代?**
当然可以!PTB只是一个常用选择,实际中你可以使用:
- **其他公开数据集**:如WikiText、C4等。
- **自定义数据集**:如果你的模型是针对特定领域(如医疗、法律),使用领域内的文本作为校准数据可能效果更好。
**关键要求**:校准数据需要与模型的实际使用场景**分布相似**。例如,如果你用PTB校准一个医疗模型,效果可能不佳,因为医疗文本的词汇和语法与新闻文本差异较大。
### **大白话类比**
想象你是一个老师,要把一本百科全书(原始模型)压缩成一本精简版手册(量化模型),同时让学生(模型)尽量记住关键知识:
1. 你会先让学生做一些代表性的练习题(PTB数据集),观察他们哪些知识点容易混淆。
2. 根据练习结果,你在精简手册时会特别注意保留那些易错但重要的内容(调整量化参数)。
3. 最终学生拿到的手册虽然薄了,但因为针对性地保留了关键信息,依然能考出好成绩。
### **总结**
校准数据集(如PTB)是量化过程中的“训练材料”,帮助模型在压缩后仍能保持良好的性能。选择合适的校准数据对最终效果至关重要!
量化结果:

1.2 量化InternVL3-1B
量化InternVL3-1B
的命令:
lmdeploy lite auto_awq /root/share/new_models/InternVL3/InternVL3-1B \
--work-dir /root/InternVL3-1B-4bit
2 W8A8量化
LMDeploy 提供了使用 8-bit 整数(INT8)和浮点数(FP8)对神经网络模型进行量化和推理的功能。
安装环境:
pip install lmdeploy[all]
量化命令: 8-bit 整数
export HF_MODEL=/root/share/model_repos/internlm2-chat-7b
export WORK_DIR=/root/LMDeploy/internlm2-chat-7b-int8
lmdeploy lite smooth_quant \
$HF_MODEL \
--work-dir $WORK_DIR \
--quant-dtype int8
输出:

量化命令: 浮点数(FP8)
lmdeploy lite smooth_quant $HF_MODEL --work-dir $WORK_DIR --quant-dtype fp8
3 Key-Value(KV) Cache 量化
自 v0.4.0 起,LMDeploy 支持在线 kv cache int4/int8 量化,量化方式为 per-head per-token 的非对称量化。
通过 LMDeploy 应用 kv 量化非常简单,只需要设定 quant_policy 参数即可。
from lmdeploy import pipeline, TurbomindEngineConfig
engine_config = TurbomindEngineConfig(quant_policy=8)
pipe = pipeline("/root/share/model_repos/internlm2-chat-7b",
backend_config=engine_config)
response = pipe(["Hi, pls intro yourself", "Shanghai is"])
print(response)
LMDeploy 规定 qant_policy=4 表示 kv int4 量化
quant_policy=8 表示 kv int8 量化。
4 对比上面三种量化和各自应用场景
1 LMDepoly 量化方法对比(W8A8、量化模型、KV Cache 量化)
量化方法 | 核心优化对象 | 优点 | 缺点 | 适用场景 |
---|---|---|---|---|
W8A8 量化 | 权重(8 位)+ 激活(8 位) | 1. 精度损失小,接近 FP16/FP32 模型性能 2. 硬件兼容性好(大多数 GPU 支持 INT8 计算) 3. 计算效率高,减少内存带宽压力 | 1. 模型压缩率有限(约 4 倍) 2. 仍需较大显存(相比更低位宽) | 1. 云端高性能推理(如 ChatGPT 服务) 2. 对精度要求高的任务(如医疗、金融) 3. 实时对话系统 |
量化模型 | 全量模型参数 | 1. 极致压缩率(如 4 位 / 2 位量化) 2. 显著降低内存占用和推理成本 3. 适合资源受限环境 | 1. 精度损失随位宽降低而增加 2. 需要特殊硬件或软件库支持(如 AWQ、GPTQ 算法) | 1. 边缘设备部署(如手机、Raspberry Pi) 2. 多模型并行场景(节省显存) 3. 模型快速分发(如端侧 AI) |
KV Cache 量化 | 注意力机制的 KV 缓存 | 1. 减少自回归生成过程中的内存占用 2. 加速连续 token 生成(降低 KV 缓存读写延迟) 3. 与其他量化方法兼容 | 1. 仅优化 KV 缓存,对模型本身大小无影响 2. 需模型支持动态 KV 缓存管理 | 1. 长文本生成任务(如小说写作、代码生成) 2. 多轮对话(减少历史对话缓存占用) 3. 显存受限的实时生成场景 |
2 关键差异解析
- 优化目标不同:
- W8A8:平衡精度和效率,适用于大多数场景。
- 量化模型:以最小化模型尺寸为目标,牺牲部分精度换取资源节省。
- KV Cache 量化:专门优化生成过程中的临时缓存,不改变模型本身。
- 精度损失:
- W8A8 < 量化模型(4 位 / 2 位) < KV Cache 量化(通常无精度损失,仅优化存储)。
- 兼容性:
- W8A8:最广泛支持(如 TensorRT、ONNX Runtime)。
- 量化模型:依赖特定量化算法(如 AWQ、GPTQ)和硬件支持。
- KV Cache 量化:需模型架构支持(如 Llama、Falcon 等新一代模型)。
3 组合应用场景
场景示例 | 推荐量化策略 | 理由 |
---|---|---|
云端对话 API(高精度) | W8A8 + KV Cache 量化 | 保证精度同时优化生成速度,适合实时交互。 |
手机端 AI 助手(小体积) | 4 位量化模型 + KV Cache 量化 | 最小化模型尺寸和运行时内存,适合移动设备。 |
长文本摘要(显存受限) | W4A8 + KV Cache 量化 | 平衡精度与显存,优化长文本生成时的 KV 缓存占用。 |
边缘端离线推理(极低功耗) | 2 位量化模型 + KV Cache 量化 | 极致压缩模型,减少运行时内存,适合电池供电设备。 |
4 性能对比(示例)
量化方法 | 模型大小(7B 模型) | 显存占用(生成时) | 推理速度(tokens/s) | 相对精度(对比 FP16) |
---|---|---|---|---|
FP16(基线) | 13.8GB | 15GB+ | 100 | 100% |
W8A8 | 7GB | 8GB+ | 120 | 98-99% |
W4A8 | 3.5GB | 5GB+ | 140 | 95-97% |
W4A8 + KV8 位 | 3.5GB | 3.8GB+ | 160 | 95-97% |
2 位量化 | 1.75GB | 3GB+ | 180 | 90-94% |
注:实际性能因模型架构、硬件平台而异。KV Cache 量化主要减少生成时的显存占用,对模型大小无影响。