Skip to content

Commit 9fdbb3a

Browse files
committed
Improve the convert and skipped_module parts in lite module
1 parent 74687f5 commit 9fdbb3a

16 files changed

Lines changed: 246 additions & 269 deletions

File tree

lmdeploy/archs.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
# Copyright (c) OpenMMLab. All rights reserved.
2-
import os
32
from typing import Literal
43

54
from transformers import AutoConfig
@@ -138,9 +137,6 @@ def get_task(backend: str, model_path: str, trust_remote_code: bool = False):
138137
"""Get pipeline type and pipeline class from model config."""
139138
from lmdeploy.serve.core import AsyncEngine
140139

141-
if os.path.exists(os.path.join(model_path, 'triton_models', 'weights')):
142-
# workspace model
143-
return 'llm', AsyncEngine
144140
_, config = get_model_arch(model_path, trust_remote_code=trust_remote_code)
145141
if check_vl_llm(backend, config.to_dict()):
146142
from lmdeploy.serve.core import VLAsyncEngine

lmdeploy/lite/apis/auto_awq.py

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
import torch
99
from torch import nn
1010

11-
from lmdeploy.lite.apis.calibrate import LAYER_TYPE_MAP, MOE_MODEL_LIST, calibrate, load_model_and_tokenizer
12-
from lmdeploy.lite.moe_mlp_modules import CONVERT_MOE_MODELS
11+
from lmdeploy.lite.apis.calibrate import LAYER_TYPE_MAP, calibrate, load_model_and_tokenizer
12+
from lmdeploy.lite.model import MODELS
1313
from lmdeploy.lite.quantization.awq import FC_FCS_MAP, NORM_FCS_MAP, awq_layers, quant_weights, smooth_layers
1414
from lmdeploy.lite.utils import collect_target_modules
1515
from lmdeploy.utils import try_import_deeplink
@@ -87,26 +87,31 @@ def auto_awq(model: str,
8787
model = get_model(model, revision=revision, download_dir=download_dir)
8888
model_path = model
8989
if calib_samples == 0:
90-
arch, vl_model, model, tokenizer, _, _ = load_model_and_tokenizer(model, dtype=dtype, work_dir=work_dir)
90+
arch, vl_model, model, tokenizer, _, _ = load_model_and_tokenizer(model,
91+
dtype=dtype,
92+
work_dir=work_dir,
93+
trust_remote_code=trust_remote_code)
9194
else:
92-
arch, vl_model, model, tokenizer = calibrate(model,
93-
calib_dataset,
94-
calib_samples,
95-
calib_seqlen,
96-
work_dir,
97-
device,
98-
w_bits=w_bits,
99-
w_group_size=w_group_size,
100-
search_scale=search_scale,
101-
dtype=dtype,
102-
batch_size=batch_size)
95+
arch, vl_model, model, tokenizer, _ = calibrate(model,
96+
calib_dataset,
97+
calib_samples,
98+
calib_seqlen,
99+
work_dir,
100+
device,
101+
w_bits=w_bits,
102+
w_group_size=w_group_size,
103+
search_scale=search_scale,
104+
dtype=dtype,
105+
batch_size=batch_size,
106+
trust_remote_code=trust_remote_code)
103107

104108
layer_type = LAYER_TYPE_MAP[type(model).__name__]
105109
layers = collect_target_modules(model, layer_type)
106110
fcs = {}
111+
model_layer = MODELS.get(arch)
107112
for l_name, layer in layers.items():
108-
if arch in MOE_MODEL_LIST:
109-
CONVERT_MOE_MODELS.get(arch)(layer)
113+
if model_layer:
114+
model_layer(layer)
110115
name2fc = collect_target_modules(layer, nn.Linear, prefix=l_name)
111116
fcs.update(name2fc)
112117

@@ -122,15 +127,14 @@ def auto_awq(model: str,
122127
act_scales = input_stats['absmax']
123128
smooth_layers(layers, fc2fcs, norm2fcs, act_scales, w_group_size, device)
124129

125-
matched_exclude_modules = quant_weights(model, fcs, w_bits, w_sym, w_group_size, device,
126-
arch=arch)
130+
skipped_modules = quant_weights(model, fcs, w_bits, w_sym, arch, w_group_size, device)
127131
quantization_config = dict(quant_method='awq',
128132
version='gemm',
129133
bits=w_bits,
130134
group_size=w_group_size,
131135
zero_point=not w_sym)
132-
if matched_exclude_modules:
133-
quantization_config['modules_to_not_convert'] = matched_exclude_modules
136+
if skipped_modules:
137+
quantization_config['modules_to_not_convert'] = skipped_modules
134138
model.config.update(dict(quantization_config=quantization_config))
135139

136140
if vl_model:

lmdeploy/lite/apis/calibrate.py

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
'LlavaLlamaForCausalLM': 'LlamaDecoderLayer',
2828
'MGMLlamaForCausalLM': 'LlamaDecoderLayer', # mini gemini
2929
'InternLMXComposer2ForCausalLM': 'InternLM2DecoderLayer',
30+
'InternS2PreviewForConditionalGeneration': 'InternS2PreviewDecoderLayer',
3031
'Phi3ForCausalLM': 'Phi3DecoderLayer',
3132
'ChatGLMForConditionalGeneration': 'GLMBlock',
3233
'MixtralForCausalLM': 'MixtralDecoderLayer',
@@ -51,6 +52,7 @@
5152
'LlavaLlamaForCausalLM': 'LlamaRMSNorm',
5253
'MGMLlamaForCausalLM': 'LlamaRMSNorm', # mini gemini
5354
'InternLMXComposer2ForCausalLM': 'InternLM2RMSNorm',
55+
'InternS2PreviewForConditionalGeneration': 'InternS2PreviewRMSNorm',
5456
'Phi3ForCausalLM': 'Phi3RMSNorm',
5557
'ChatGLMForConditionalGeneration': 'RMSNorm',
5658
'MixtralForCausalLM': 'MixtralRMSNorm',
@@ -75,6 +77,7 @@
7577
'LlavaLlamaForCausalLM': 'lm_head',
7678
'MGMLlamaForCausalLM': 'lm_head', # mini gemini
7779
'InternLMXComposer2ForCausalLM': 'output',
80+
'InternS2PreviewForConditionalGeneration': 'lm_head',
7881
'Phi3ForCausalLM': 'lm_head',
7982
'ChatGLMForConditionalGeneration': 'output_layer',
8083
'MixtralForCausalLM': 'lm_head',
@@ -83,12 +86,6 @@
8386
'MistralForCausalLM': 'lm_head',
8487
}
8588

86-
MOE_MODEL_LIST = [
87-
'Qwen3MoeForCausalLM',
88-
'Qwen3_5MoeForConditionalGeneration',
89-
'MixtralForCausalLM'
90-
]
91-
9289

9390
def check_vl_llm(backend: str, config: dict) -> bool:
9491
"""Check if the model is a vl model from model config."""
@@ -110,7 +107,8 @@ def check_vl_llm(backend: str, config: dict) -> bool:
110107
'Qwen3_5MoeForConditionalGeneration', 'MllamaForConditionalGeneration', 'MolmoForCausalLM',
111108
'Gemma3ForConditionalGeneration', 'Llama4ForConditionalGeneration', 'InternVLForConditionalGeneration',
112109
'InternS1ForConditionalGeneration', 'InternS1ProForConditionalGeneration',
113-
'InternS1_1_ForConditionalGeneration', 'Glm4vForConditionalGeneration'
110+
'InternS1_1_ForConditionalGeneration', 'Glm4vForConditionalGeneration',
111+
'InternS2PreviewForConditionalGeneration'
114112
])
115113
if arch == 'QWenLMHeadModel' and 'visual' in config:
116114
return True
@@ -125,11 +123,7 @@ def check_vl_llm(backend: str, config: dict) -> bool:
125123

126124
def get_task(backend: str, model_path: str):
127125
"""Get pipeline type and pipeline class from model config."""
128-
import os
129126

130-
if os.path.exists(os.path.join(model_path, 'triton_models', 'weights')):
131-
# workspace model
132-
return 'llm'
133127
_, config = get_model_arch(model_path)
134128
if check_vl_llm(backend, config.to_dict()):
135129
return 'vlm'
@@ -260,22 +254,23 @@ def update_moe_mapping(model, model_type):
260254

261255
def load_model_and_tokenizer(model: str,
262256
dtype: Literal['float16', 'bfloat16', 'auto'] = 'auto',
263-
work_dir: str = './work_dir'):
257+
work_dir: str = './work_dir',
258+
trust_remote_code: bool = False):
264259
"""Load model and tokenizer."""
265260
model_type = get_task(backend='turbomind', model_path=model)
266261
make_compatible_internvl_config(model)
267262

268263
# Load tokenizer
269-
tokenizer = AutoTokenizer.from_pretrained(model, trust_remote_code=True)
264+
tokenizer = AutoTokenizer.from_pretrained(model, trust_remote_code=trust_remote_code)
270265

271266
# get model arch and config
272-
arch, original_config = get_model_arch(model)
267+
arch, original_config = get_model_arch(model, trust_remote_code=trust_remote_code)
273268

274269
if model_type == 'llm':
275-
model = load_hf_from_pretrained(model, dtype=dtype, trust_remote_code=True)
270+
model = load_hf_from_pretrained(model, dtype=dtype, trust_remote_code=trust_remote_code)
276271
vl_model = None
277272
elif model_type == 'vlm':
278-
vl_model = load_vl_model(model, backend=None, with_llm=True).vl_model
273+
vl_model = load_vl_model(model, backend=None, with_llm=True, trust_remote_code=trust_remote_code).vl_model
279274
model = vl_model
280275
if hasattr(vl_model, 'language_model'): # deepseek-vl, ...
281276
model = vl_model.language_model
@@ -355,7 +350,7 @@ def calibrate(model: str,
355350
'`neuralmagic_calibration`, `open-platypus`, `openwebtext`.'
356351

357352
arch, vl_model, model, tokenizer, model_type, work_dir = load_model_and_tokenizer(
358-
model, dtype=dtype, work_dir=work_dir)
353+
model, dtype=dtype, work_dir=work_dir, trust_remote_code=trust_remote_code)
359354

360355
if model_type in ['MixtralForCausalLM']:
361356
update_moe_mapping(model, model_type)
@@ -401,7 +396,7 @@ def calibrate(model: str,
401396

402397
calib_ctx.export(work_dir)
403398

404-
return arch, vl_model, model, tokenizer
399+
return arch, vl_model, model, tokenizer, work_dir
405400

406401

407402
if __name__ == '__main__':

lmdeploy/lite/apis/smooth_quant.py

Lines changed: 48 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from torch import nn
99

1010
from lmdeploy.lite.apis.calibrate import LAYER_TYPE_MAP, NORM_TYPE_MAP, calibrate
11+
from lmdeploy.lite.model import MODELS
1112
from lmdeploy.lite.quantization.awq import FC_FCS_MAP, NORM_FCS_MAP, awq_layers, skipped_module, smooth_layers
1213
from lmdeploy.lite.utils import collect_target_modules
1314
from lmdeploy.pytorch.models import QLinear, QRMSNorm
@@ -26,7 +27,8 @@ def smooth_quant(model: str,
2627
device: str = 'cuda',
2728
quant_dtype: Literal['int8', 'fp8', 'float8_e4m3fn', 'float8_e5m2'] = 'int8',
2829
revision: str = None,
29-
download_dir: str = None):
30+
download_dir: str = None,
31+
trust_remote_code: bool = False):
3032
try_import_deeplink(device)
3133
if quant_dtype == 'fp8':
3234
quant_dtype = 'float8_e4m3fn'
@@ -44,17 +46,18 @@ def smooth_quant(model: str,
4446
from lmdeploy.utils import get_model
4547
model = get_model(model, revision=revision, download_dir=download_dir)
4648
model_path = model
47-
vl_model, model, tokenizer, work_dir = calibrate(model,
48-
calib_dataset,
49-
calib_samples,
50-
calib_seqlen,
51-
work_dir,
52-
device,
53-
w_bits=w_bits,
54-
w_group_size=-1,
55-
search_scale=search_scale,
56-
dtype=dtype,
57-
batch_size=batch_size)
49+
arch, vl_model, model, tokenizer, work_dir = calibrate(model,
50+
calib_dataset,
51+
calib_samples,
52+
calib_seqlen,
53+
work_dir,
54+
device,
55+
w_bits=w_bits,
56+
w_group_size=-1,
57+
search_scale=search_scale,
58+
dtype=dtype,
59+
batch_size=batch_size,
60+
trust_remote_code=trust_remote_code)
5861

5962
# calibrate function exports the calibration statistics
6063
# (inputs, outputs, keys and values) to `work_dir`.
@@ -95,32 +98,41 @@ def smooth_quant(model: str,
9598

9699
rmsnorms = collect_target_modules(model, norm_type)
97100

98-
for name, linear in fcs.items():
99-
if skipped_module(name, model.config.architectures[0])[0]:
100-
continue
101-
linear.to(device)
102-
q_linear = QLinear.from_float(linear, quant_dtype=quant_dtype)
103-
parent_name, _, child_name = name.rpartition('.')
104-
parent = model.get_submodule(parent_name)
105-
setattr(parent, child_name, q_linear)
106-
linear.to('cpu')
107-
q_linear.to('cpu')
108-
torch.cuda.empty_cache()
109-
110-
for name, norm in rmsnorms.items():
111-
if skipped_module(name, model.config.architectures[0])[0]:
112-
continue
113-
norm.to(device)
114-
q_norm = QRMSNorm.from_float(norm, quant_dtype=quant_dtype)
115-
parent_name, _, child_name = name.rpartition('.')
116-
parent = model.get_submodule(parent_name)
117-
setattr(parent, child_name, q_norm)
118-
norm.to('cpu')
119-
q_norm.to('cpu')
120-
torch.cuda.empty_cache()
101+
patterns = []
102+
skipped_modules = []
103+
arch = model.config.architectures[0]
104+
model_layer = MODELS.get(arch)
105+
if model_layer:
106+
patterns = model_layer.skipped_modules()
107+
skipped_modules.extend(patterns)
108+
109+
for modules, q_cls in ((fcs, QLinear), (rmsnorms, QRMSNorm)):
110+
for name, module in modules.items():
111+
skipped, skipped_pattern = skipped_module(name, patterns)
112+
if skipped:
113+
if skipped_pattern and skipped_pattern not in skipped_modules:
114+
skipped_modules.append(skipped_pattern)
115+
continue
116+
117+
module.to(device)
118+
q_module = q_cls.from_float(module, quant_dtype=quant_dtype)
119+
120+
parent_name, _, child_name = name.rpartition('.')
121+
parent = model.get_submodule(parent_name)
122+
setattr(parent, child_name, q_module)
123+
124+
module.to('cpu')
125+
q_module.to('cpu')
126+
torch.cuda.empty_cache()
127+
121128

122129
quant_dtype_s = str(quant_dtype).split('.')[1]
123-
model.config.update(dict(quantization_config=dict(quant_method='smooth_quant', quant_dtype=f'{quant_dtype_s}')))
130+
quantization_config = dict(quant_method='smooth_quant',
131+
quant_dtype=f'{quant_dtype_s}')
132+
if skipped_modules:
133+
quantization_config['modules_to_not_convert'] = skipped_modules
134+
model.config.update(dict(quantization_config=quantization_config))
135+
# model.config.update(dict(quantization_config=dict(quant_method='smooth_quant', quant_dtype=f'{quant_dtype_s}')))
124136

125137
if vl_model:
126138
from .auto_awq import save_vl_model

lmdeploy/lite/model/__init__.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Copyright (c) OpenMMLab. All rights reserved.
2+
3+
from . import (
4+
mixtral, # noqa: F401
5+
qwen, # noqa: F401
6+
)
7+
from .base import MODELS
8+
9+
__all__ = ['MODELS']

0 commit comments

Comments
 (0)