技术博客

国产GPU大模型推理部署:vLLM在昇腾/DCU上的适配与性能调优

系统讲解在华为昇腾NPU和海光DCU上部署大语言模型推理服务的完整流程:vLLM Ascend/ROCm版本安装配置、主流LLM模型(Qwen2.5/LLaMA3/DeepSeek)的部署方法、PagedAttention显存优化、连续批处理性能调优,以及与NVIDIA A100的吞吐量对比分析。

vLLM昇腾海光DCU大模型推理LLMQwenAI基础设施国产GPU

大模型推理是国产 GPU 落地最多的场景,因为相比训练,推理的精度敏感性更低、迁移风险更小。vLLM 是目前最主流的高性能 LLM 推理引擎,昇腾和海光 DCU 均有官方适配版本。本文讲解完整的部署和调优流程。

推理硬件对比(2025年)

模型:Qwen2.5-72B(BF16),批量推理吞吐量(token/s)

硬件(8卡)         显存     吞吐量       相对 A100
NVIDIA A100 80G    640GB    约 12000     基准
华为昇腾 910B      512GB    约 8000      约 67%
海光 Z100L         256GB    约 5000      约 42%
NVIDIA H100 80G   640GB    约 20000     约 167%

注:实际吞吐量受批大小、序列长度、请求模式影响较大
以上为参考值,不同模型和场景差异较大

一、vLLM 昇腾版部署

安装 vLLM-Ascend

# 方法1:使用华为维护的 vLLM-Ascend(推荐)
# GitHub:https://github.com/vllm-project/vllm-ascend

# 前置条件:已安装 CANN 8.0+ 和 torch_npu

pip3 install torch==2.3.1 \
    --index-url https://download.pytorch.org/whl/cpu
pip3 install torch_npu==2.3.1.post2

# 安装 vLLM-Ascend
pip3 install vllm-ascend

# 或从源码安装(最新功能)
git clone https://github.com/vllm-project/vllm-ascend.git
cd vllm-ascend
pip3 install -e . -v
# 验证安装
python3 -c "
import vllm
print(f'vLLM 版本: {vllm.__version__}')
from vllm import LLM, SamplingParams
print('vLLM 导入成功')
"

启动推理服务

# 单 NPU 推理(适合小模型,如 7B)
python3 -m vllm.entrypoints.openai.api_server \
    --model Qwen/Qwen2.5-7B-Instruct \
    --device npu \                          # 指定昇腾 NPU
    --dtype bfloat16 \                      # BF16 精度(910B 原生支持)
    --max-model-len 8192 \                  # 最大上下文长度
    --port 8000

# 多 NPU 推理(张量并行,适合 70B+ 大模型)
python3 -m vllm.entrypoints.openai.api_server \
    --model Qwen/Qwen2.5-72B-Instruct \
    --device npu \
    --tensor-parallel-size 8 \             # 8 卡张量并行
    --dtype bfloat16 \
    --max-model-len 32768 \
    --gpu-memory-utilization 0.90 \        # 使用 90% NPU 显存
    --port 8000

# DeepSeek-V3 部署(超大模型,需要专家并行)
python3 -m vllm.entrypoints.openai.api_server \
    --model deepseek-ai/DeepSeek-V3 \
    --device npu \
    --tensor-parallel-size 8 \
    --pipeline-parallel-size 2 \           # 流水线并行(跨机器)
    --dtype bfloat16 \
    --port 8000

二、vLLM ROCm 版(海光 DCU)部署

# 使用 ROCm 官方 vLLM(支持 DCU,因为 DCU 兼容 ROCm)
pip3 install vllm --extra-index-url https://download.pytorch.org/whl/rocm6.0

# 或者从源码编译(针对 DCU 的 GFX 版本)
export PYTORCH_ROCM_ARCH="gfx926"  # 替换为你的 DCU GFX 版本
git clone https://github.com/vllm-project/vllm.git
cd vllm
pip3 install -e . --extra-index-url https://download.pytorch.org/whl/rocm6.0

# 启动推理服务
# DCU 上 vLLM 使用 cuda 设备名(HIP 透明)
python3 -m vllm.entrypoints.openai.api_server \
    --model Qwen/Qwen2.5-7B-Instruct \
    --device cuda \                         # DCU 使用 cuda(HIP 兼容)
    --dtype bfloat16 \
    --tensor-parallel-size 4 \
    --max-model-len 8192 \
    --port 8000

三、模型量化(降低显存需求)

# 场景:显存不足以加载原始 BF16 模型时,使用量化

# INT8 量化(W8A8)
python3 -m vllm.entrypoints.openai.api_server \
    --model Qwen/Qwen2.5-72B-Instruct \
    --device npu \
    --quantization w8a8 \                  # 昇腾 CANN 原生支持 W8A8
    --tensor-parallel-size 8 \
    --port 8000

# GPTQ 量化模型(预量化,直接下载使用)
python3 -m vllm.entrypoints.openai.api_server \
    --model Qwen/Qwen2.5-72B-Instruct-GPTQ-Int4 \  # 已量化的模型
    --device npu \
    --quantization gptq \
    --tensor-parallel-size 4 \             # 量化后显存减半,可以减少卡数
    --port 8000

# 量化后的性能影响:
# INT4 量化:速度 ≈ 原速,精度损失 1-3%,显存减少 75%
# INT8 量化:速度 ≈ 原速,精度损失 < 1%,显存减少 50%

四、性能调优

# vLLM 核心性能参数

# 1. 批处理配置(影响吞吐量)
python3 -m vllm.entrypoints.openai.api_server \
    --model MODEL \
    --device npu \
    --max-num-seqs 256 \                   # 最大并发序列数(默认 256)
    --max-num-batched-tokens 16384 \       # 每批最大 token 数(默认 8192)

# 2. 前缀缓存(加速相同 system prompt 的重复请求)
    --enable-prefix-caching \             # 开启 Prompt 缓存

# 3. 推测解码(Speculative Decoding,加速小模型生成)
    --speculative-model Qwen/Qwen2.5-0.5B \  # 用小模型猜测
    --num-speculative-tokens 5

# 4. 显存分配(PagedAttention KV Cache)
    --gpu-memory-utilization 0.90 \        # 90% 用于 KV Cache
    --block-size 16 \                      # KV Cache 块大小(16 或 32)
# 性能测试脚本(测量吞吐量)
from vllm import LLM, SamplingParams
import time

llm = LLM(
    model="Qwen/Qwen2.5-7B-Instruct",
    device="npu",
    dtype="bfloat16",
    tensor_parallel_size=4,
)

# 生成 100 个请求测试吞吐量
prompts = ["介绍一下深度学习"] * 100
sampling_params = SamplingParams(temperature=0.7, max_tokens=256)

start = time.time()
outputs = llm.generate(prompts, sampling_params)
elapsed = time.time() - start

total_tokens = sum(len(o.outputs[0].token_ids) for o in outputs)
print(f"总 token 数: {total_tokens}")
print(f"耗时: {elapsed:.2f}s")
print(f"吞吐量: {total_tokens/elapsed:.0f} token/s")

五、Kubernetes 推理服务部署

# vllm-ascend-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: vllm-qwen-ascend
  namespace: inference
spec:
  replicas: 1
  selector:
    matchLabels:
      app: vllm-qwen-ascend
  template:
    metadata:
      labels:
        app: vllm-qwen-ascend
    spec:
      nodeSelector:
        accelerator: huawei-npu
        npu-model: 910b
      tolerations:
        - key: accelerator
          value: huawei-npu
          effect: NoSchedule
      containers:
        - name: vllm-server
          image: vllm-ascend:latest
          ports:
            - containerPort: 8000
          command:
            - "python3"
            - "-m"
            - "vllm.entrypoints.openai.api_server"
            - "--model=/models/Qwen2.5-72B-Instruct"
            - "--device=npu"
            - "--tensor-parallel-size=8"
            - "--dtype=bfloat16"
            - "--max-model-len=32768"
            - "--gpu-memory-utilization=0.90"
            - "--port=8000"
            - "--host=0.0.0.0"
          resources:
            limits:
              huawei.com/Ascend910: 8
          env:
            - name: ASCEND_VISIBLE_DEVICES
              value: "0,1,2,3,4,5,6,7"
          volumeMounts:
            - name: driver
              mountPath: /usr/local/Ascend/driver
              readOnly: true
            - name: model-storage
              mountPath: /models
          livenessProbe:
            httpGet:
              path: /health
              port: 8000
            initialDelaySeconds: 120    # 大模型加载需要时间
            periodSeconds: 30
          readinessProbe:
            httpGet:
              path: /health
              port: 8000
            initialDelaySeconds: 120
            periodSeconds: 10
      volumes:
        - name: driver
          hostPath:
            path: /usr/local/Ascend/driver
        - name: model-storage
          persistentVolumeClaim:
            claimName: model-storage-pvc

---
apiVersion: v1
kind: Service
metadata:
  name: vllm-qwen-ascend
  namespace: inference
spec:
  selector:
    app: vllm-qwen-ascend
  ports:
    - port: 8000
      targetPort: 8000
  type: ClusterIP

六、常见问题

# 问题1:模型加载报错 "OOM"
# 原因:模型太大,显存不足
# 解决:
# a. 使用量化:--quantization w8a8 或 gptq
# b. 增加 tensor-parallel-size(更多 NPU 分摊)
# c. 减少 max-model-len(KV Cache 占用更少显存)
# d. 降低 gpu-memory-utilization(0.85 → 0.75)

# 问题2:推理速度慢(相对 NVIDIA 差距大)
# 检查 NPU 利用率
watch -n 1 'npu-smi info -i 0 -t common | grep AICore'
# 如果 AICore < 50%,说明计算未饱和
# 原因1:batch size 太小,增加并发请求数
# 原因2:某些算子未优化,通过 CANN 版本升级改善

# 问题3:多 NPU 推理 HCCS 通信失败
# 检查:tensor_parallel_size 与卡数是否匹配
# 检查:HCCS 链路是否正常
npu-smi info -i 0 -t link-info

# 问题4:精度异常(生成乱码)
# 尝试降低精度要求:BF16 → FP32(部分算子以 FP32 运行)
python3 -m vllm.entrypoints.openai.api_server \
    --dtype float32 ...   # 精度优先(速度更慢)

# 问题5:vLLM-Ascend 不支持某些模型架构
# 查看支持的模型列表:
python3 -c "
from vllm.model_executor.models import ModelRegistry
for model in ModelRegistry.get_supported_archs():
    print(model)
"

小结

在国产 GPU 上部署 LLM 推理服务,vLLM 是目前最可行的方案:昇腾用 vllm-ascend(设备参数 --device npu),海光 DCU 用 ROCm 版 vLLM(设备参数 --device cuda,HIP 透明)。主流国产模型(Qwen2.5、DeepSeek)的支持最好,因为这些模型本身就在昇腾上训练或验证过。性能上:昇腾 910B 推理吞吐约为 A100 的 60-70%,在成本合规的前提下是可接受的。最重要的调优方向是 gpu-memory-utilization(影响 KV Cache 大小)和 max-num-seqs(影响并发数),这两个参数决定了整体吞吐量。