### What this PR does / why we need it?
Supports Deepseek-R1 w4a8 quantization.
Since R1 w4a8 uses mixed quantization, only the MOE layer uses
w4a8_dynamic quantization, so we added the w4a8_dynamic.py file, which
includes the AscendW4A8DynamicFusedMoEMethod class.
### Does this PR introduce _any_ user-facing change?
no
### How was this patch tested?
Adding ut case in `tests/ut/quantization/test_w4a8_dynamic.py` and
`tests/ut/quantization/test_quantizer.py`
Adding e2e case in
`tests/e2e/multicard/test_offline_inference_distributed.py::test_models_distributed_DeepSeek_W4A8DYNAMIC`
to test deepseek w4a8_dynamic quantized model
#### 1.How to get weights using Modelslim
##### Installation steps
Use the branch master, the commit id is:
298e175d69b3b855111a1e09bbe2fcd12fdb4e24
git clone https://gitee.com/ascend/msit.git
cd msit/msmodelslim
bash install.sh
##### The required transformers environment
transformers>=4.48.2
##### Generate w4a8 weights
cd /example/DeepSeek
Command reference: msmodelslim/example/DeepSeek/README.md Execute the
[pre-check](https://gitee.com/ascend/msit/blob/master/msmodelslim/example/DeepSeek/README.md#%E8%BF%90%E8%A1%8C%E5%89%8D%E5%BF%85%E6%A3%80)
and [DeepSeek-R1 w4a8 mix
quantization](https://gitee.com/ascend/msit/blob/master/msmodelslim/example/DeepSeek/README.md#deepseek-r1-w4a8-%E6%B7%B7%E5%90%88%E9%87%8F%E5%8C%96%E5%89%8D%E4%B8%89%E5%B1%82-mlpw8a8-dynamic-%E9%87%8F%E5%8C%96mla%E5%85%B1%E4%BA%AB%E4%B8%93%E5%AE%B6w8a8%E9%87%8F%E5%8C%96%E8%B7%AF%E7%94%B1%E4%B8%93%E5%AE%B6w4a8-dynamic%E9%87%8F%E5%8C%96)
chapter
Reference command:python3 quant_deepseek_w4a8.py --model_path {Original
weight path} --save_path {Generate weight path} --mindie_format
##### Adapt to vllm-ascend
Since mindie_format generates mindie format, some adaptation
modifications are needed for vllm-ascend to use it:
`quant_model_description_w8a8_dynamic.json` rename to
`quant_model_description.json`, and add `"group_size": 256`
Modification in `config.json`:`"model_type":deepseekv2` is changed to
`"model_type":deepseek_v3`; `quantization_config` is removed;
tips:The group_size and weights match. If the w4a8 weights are not
generated using msmodelslim, you can check the group_size in
quantization_config in config.json.
#### 2.How to run w4a8
##### a.How to run eager mode
export VLLM_USE_V1=1 # v1
python -m vllm.entrypoints.openai.api_server --model=$1
--trust-remote-code -tp $2 -dp $3 --enable_expert_parallel
--quantization ascend --port $4 --max-model-len $5 --max-num-seqs $6
--enforce-eager
eg: python -m vllm.entrypoints.openai.api_server
--model=/weightpath/w4a8_4_layer --trust-remote-code -tp 4 -dp 4
--enable_expert_parallel --quantization ascend --port 8002
--max-model-len 5120 --max-num-seqs 128 --enforce-eager
##### b.How to run graph mode
export VLLM_USE_V1=1 # v1
export HCCL_BUFFSIZE=1024
python -m vllm.entrypoints.openai.api_server --model=$1
--trust-remote-code -tp $2 -dp $3 --enable_expert_parallel
--quantization ascend --port $4 --max-model-len $5
--additional_config='{"ascend_scheduler_config":{"enabled":true},"torchair_graph_config":{"enabled":true}}'
eg: python -m vllm.entrypoints.openai.api_server
--model=/weight/dsr1_w4a8_vllm --trust-remote-code -tp 4 -dp 4
--enable_expert_parallel --quantization ascend --port 8002
--max-model-len 5120
--additional_config='{"ascend_scheduler_config":{"enabled":true},"torchair_graph_config":{"enabled":true}}'
- vLLM version: v0.10.0
- vLLM main:
c494f96fbc
---------
Signed-off-by: Wang Kunpeng <1289706727@qq.com>
237 lines
7.9 KiB
Python
237 lines
7.9 KiB
Python
#
|
|
# Copyright (c) 2025 Huawei Technologies Co., Ltd. All Rights Reserved.
|
|
# Copyright 2023 The vLLM team.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
# This file is a part of the vllm-ascend project.
|
|
# Adapted from vllm/tests/basic_correctness/test_basic_correctness.py
|
|
#
|
|
"""Compare the short outputs of HF and vLLM when using greedy sampling.
|
|
|
|
Run `pytest tests/test_offline_inference.py`.
|
|
"""
|
|
import os
|
|
from unittest.mock import patch
|
|
|
|
import pytest
|
|
from modelscope import snapshot_download # type: ignore
|
|
from vllm import SamplingParams
|
|
from vllm.model_executor.models.registry import ModelRegistry
|
|
|
|
from tests.e2e.conftest import VllmRunner
|
|
|
|
os.environ["PYTORCH_NPU_ALLOC_CONF"] = "max_split_size_mb:256"
|
|
|
|
|
|
def test_models_distributed_QwQ():
|
|
example_prompts = [
|
|
"Hello, my name is",
|
|
]
|
|
dtype = "half"
|
|
max_tokens = 5
|
|
with VllmRunner(
|
|
"Qwen/QwQ-32B",
|
|
dtype=dtype,
|
|
tensor_parallel_size=2,
|
|
distributed_executor_backend="mp",
|
|
) as vllm_model:
|
|
vllm_model.generate_greedy(example_prompts, max_tokens)
|
|
|
|
|
|
def test_models_distributed_DeepSeek_multistream_moe():
|
|
example_prompts = [
|
|
"Hello, my name is",
|
|
]
|
|
dtype = "half"
|
|
max_tokens = 5
|
|
with VllmRunner(
|
|
"vllm-ascend/DeepSeek-V3-Pruning",
|
|
dtype=dtype,
|
|
tensor_parallel_size=2,
|
|
distributed_executor_backend="mp",
|
|
additional_config={
|
|
"torchair_graph_config": {
|
|
"enabled": True,
|
|
"enable_multistream_moe": True,
|
|
},
|
|
"ascend_scheduler_config": {
|
|
"enabled": True,
|
|
},
|
|
"refresh": True,
|
|
},
|
|
enforce_eager=False,
|
|
) as vllm_model:
|
|
vllm_model.generate_greedy(example_prompts, max_tokens)
|
|
|
|
|
|
@patch.dict(os.environ, {"VLLM_ASCEND_ENABLE_DBO": "1"})
|
|
def test_models_distributed_DeepSeek_dbo():
|
|
example_prompts = ["The president of the United States is"] * 41
|
|
dtype = "half"
|
|
sampling_params = SamplingParams(max_tokens=100, temperature=0.0)
|
|
with VllmRunner(
|
|
"deepseek-ai/DeepSeek-V2-Lite",
|
|
dtype=dtype,
|
|
tensor_parallel_size=2,
|
|
distributed_executor_backend="mp",
|
|
) as vllm_model:
|
|
model_arch = 'DeepseekV2ForCausalLM'
|
|
registed_models = ModelRegistry.models
|
|
assert registed_models[
|
|
model_arch].module_name == "vllm_ascend.models.deepseek_dbo"
|
|
assert registed_models[
|
|
model_arch].class_name == "CustomDeepseekDBOForCausalLM"
|
|
vllm_model.generate(example_prompts, sampling_params)
|
|
|
|
|
|
@pytest.mark.skip(
|
|
reason=
|
|
"deepseek dbo dose not consider the support on half precision float, will enable this ut after we actually support it"
|
|
)
|
|
@patch.dict(os.environ, {"VLLM_ASCEND_ENABLE_DBO": "1"})
|
|
def test_models_distributed_DeepSeekV3_dbo():
|
|
example_prompts = ["The president of the United States is"] * 41
|
|
dtype = "half"
|
|
sampling_params = SamplingParams(max_tokens=100, temperature=0.0)
|
|
with VllmRunner(
|
|
"vllm-ascend/DeepSeek-V3-Pruning",
|
|
dtype=dtype,
|
|
tensor_parallel_size=2,
|
|
distributed_executor_backend="mp",
|
|
) as vllm_model:
|
|
model_arch = 'DeepseekV3ForCausalLM'
|
|
registed_models = ModelRegistry.models
|
|
assert registed_models[
|
|
model_arch].module_name == "vllm_ascend.models.deepseek_dbo"
|
|
assert registed_models[
|
|
model_arch].class_name == "CustomDeepseekDBOForCausalLM"
|
|
vllm_model.generate(example_prompts, sampling_params)
|
|
|
|
|
|
def test_models_distributed_pangu():
|
|
example_prompts = [
|
|
"Hello, my name is",
|
|
]
|
|
max_tokens = 5
|
|
|
|
with VllmRunner(
|
|
snapshot_download("vllm-ascend/pangu-pro-moe-pruing"),
|
|
max_model_len=8192,
|
|
enforce_eager=True,
|
|
dtype="auto",
|
|
tensor_parallel_size=2,
|
|
distributed_executor_backend="mp",
|
|
) as vllm_model:
|
|
vllm_model.generate_greedy(example_prompts, max_tokens)
|
|
|
|
|
|
@patch.dict(os.environ, {"VLLM_ASCEND_ENABLE_TOPK_TOPP_OPTIMIZATION": "1"})
|
|
def test_models_distributed_topk() -> None:
|
|
example_prompts = [
|
|
"vLLM is a high-throughput and memory-efficient inference and serving engine for LLMs.",
|
|
"Briefly describe the major milestones in the development of artificial intelligence from 1950 to 2020.",
|
|
"Compare and contrast artificial intelligence with human intelligence in terms of processing information.",
|
|
]
|
|
dtype = "half"
|
|
sampling_params = SamplingParams(max_tokens=5,
|
|
temperature=0.0,
|
|
top_k=50,
|
|
top_p=0.9)
|
|
|
|
with VllmRunner(
|
|
"deepseek-ai/DeepSeek-V2-Lite",
|
|
dtype=dtype,
|
|
tensor_parallel_size=2,
|
|
distributed_executor_backend="mp",
|
|
) as vllm_model:
|
|
vllm_model.generate(example_prompts, sampling_params)
|
|
|
|
|
|
@patch.dict(os.environ, {"VLLM_ASCEND_ENABLE_MOE_ALL2ALL_SEQ": "1"})
|
|
def test_models_distributed_alltoallv() -> None:
|
|
example_prompts = [
|
|
"vLLM is a high-throughput and memory-efficient inference and serving engine for LLMs.",
|
|
"Briefly describe the major milestones in the development of artificial intelligence from 1950 to 2020.",
|
|
"Compare and contrast artificial intelligence with human intelligence in terms of processing information.",
|
|
]
|
|
dtype = "half"
|
|
sampling_params = SamplingParams(max_tokens=5,
|
|
temperature=0.0,
|
|
top_k=50,
|
|
top_p=0.9)
|
|
|
|
with VllmRunner(
|
|
"deepseek-ai/DeepSeek-V2-Lite",
|
|
dtype=dtype,
|
|
tensor_parallel_size=2,
|
|
distributed_executor_backend="mp",
|
|
) as vllm_model:
|
|
vllm_model.generate(example_prompts, sampling_params)
|
|
|
|
|
|
def test_models_distributed_Qwen3_W8A8():
|
|
example_prompts = [
|
|
"Hello, my name is",
|
|
]
|
|
max_tokens = 5
|
|
|
|
with VllmRunner(
|
|
snapshot_download("vllm-ascend/Qwen3-8B-W8A8"),
|
|
max_model_len=8192,
|
|
dtype="auto",
|
|
tensor_parallel_size=2,
|
|
quantization="ascend",
|
|
) as vllm_model:
|
|
vllm_model.generate_greedy(example_prompts, max_tokens)
|
|
|
|
|
|
def test_models_distributed_Qwen3_W4A8DYNAMIC():
|
|
example_prompts = [
|
|
"Hello, my name is",
|
|
]
|
|
max_tokens = 5
|
|
|
|
with VllmRunner(
|
|
snapshot_download("vllm-ascend/Qwen3-8B-W4A8"),
|
|
max_model_len=8192,
|
|
dtype="auto",
|
|
tensor_parallel_size=2,
|
|
quantization="ascend",
|
|
) as vllm_model:
|
|
vllm_model.generate_greedy(example_prompts, max_tokens)
|
|
|
|
|
|
@patch.dict(os.environ, {"VLLM_ASCEND_MLA_PA": "1"})
|
|
def test_models_distributed_DeepSeek_W4A8DYNAMIC():
|
|
prompts = [
|
|
"Hello, my name is",
|
|
]
|
|
max_tokens = 5
|
|
with VllmRunner(
|
|
snapshot_download("vllm-ascend/DeepSeek-R1-w4a8-pruning"),
|
|
dtype="auto",
|
|
tensor_parallel_size=2,
|
|
quantization="ascend",
|
|
enforce_eager=True,
|
|
enable_expert_parallel=True,
|
|
additional_config={
|
|
"torchair_graph_config": {
|
|
"enabled": False,
|
|
},
|
|
"ascend_scheduler_config": {
|
|
"enabled": True,
|
|
}
|
|
},
|
|
) as vllm_model:
|
|
vllm_model.generate_greedy(prompts, max_tokens)
|