一、整体关系

vllm-ascend是一个硬件插件,它不独立工作,必须配合vLLM核心引擎一起使用。理解它们的衔接关系,关键要搞清楚:哪些代码是vLLM的,哪些代码是vllm-ascend的,它们之间通过什么接口对接。

图1:vLLM与vllm-ascend的边界
graph LR
    subgraph "vLLM核心引擎(上游)"
        A1[LLMEngine] --> A2[Scheduler]
        A2 --> A3[Executor]
        A3 --> A4[Worker]
        A5[Platform接口] --> A6[ModelRegistry]
    end
    
    subgraph "vllm-ascend插件(本项目)"
        B1[NPUPlatform]
        B2[Attention Backend]
        B3[Custom Ops]
        B4[NPUModelRunner]
        B5[Model注册]
    end
    
    A5 -->|实现| B1
    A4 -->|调用| B1
    A4 -->|调用| B2
    A4 -->|调用| B3
    A4 -->|使用| B4
    A6 -->|注册| B5
                

二、接口对接:vLLM定义接口,vllm-ascend实现接口

vLLM定义了一套Hardware Plugin接口,告诉插件开发者:"你需要实现这些方法,我才能用你的硬件"。vllm-ascend实现了这些接口,让vLLM能够在NPU上运行。

2.1 Platform接口(核心对接点)

vLLM在vllm/platforms/interface.py中定义了Platform基类,vllm-ascend在vllm_ascend/platform.py中实现NPUPlatform类继承它。

vLLM定义的Platform接口(vllm/platforms/interface.py)
class Platform:
    """硬件平台基类,插件需要继承并实现这个类"""
    
    _enum: PlatformEnum  # 平台枚举值
    device_name: str     # 设备名称,如 "npu"
    device_type: str     # 设备类型,如 "npu"
    
    def get_attn_backend_cls(self):
        """返回注意力后端类"""
        raise NotImplementedError
    
    def get_device_name(self):
        """返回设备名称"""
        return self.device_name
vllm-ascend实现的NPUPlatform(vllm_ascend/platform.py)
class NPUPlatform(Platform):
    """昇腾NPU平台实现"""
    
    _enum = PlatformEnum.OOT
    device_name: str = "npu"
    device_type: str = "npu"
    
    def get_attn_backend_cls(self, config):
        """根据模型配置返回对应的注意力后端"""
        if config.use_mla:
            return "vllm_ascend.attention.AscendMLABackend"
        elif config.use_sparse:
            return "vllm_ascend.attention.AscendSFABackend"
        else:
            return "vllm_ascend.attention.AscendAttentionBackend"

2.2 模型注册接口

vLLM定义了ModelRegistry,vllm-ascend通过register_model()将NPU优化的模型注册进去。

vllm-ascend注册模型(vllm_ascend/models/__init__.py)
from vllm import ModelRegistry

def register_model():
    # 将NPU优化的模型注册到vLLM的ModelRegistry
    ModelRegistry.register_model(
        "DeepseekV4ForCausalLM",  # 模型名称(用户指定)
        "vllm_ascend.models.deepseek_v4:AscendDeepseekV4ForCausalLM",  # 类路径
    )

对接流程总结

1. vLLM定义接口(Platform、ModelRegistry等)

2. vllm-ascend实现接口(NPUPlatform、register_model等)

3. vLLM启动时扫描插件,调用vllm-ascend的register函数

4. vllm-ascend将NPUPlatform注册到vLLM,告诉vLLM"我支持NPU"

5. 用户指定模型时,vLLM从ModelRegistry找到vllm-ascend注册的模型类

三、模型加载衔接:用户指定名称 → 怎么找到模型类

当用户指定"model=DeepseekV4ForCausalLM"时,vLLM需要找到对应的模型类并实例化。这个过程涉及vLLM和vllm-ascend的协作。

图2:模型加载衔接流程
sequenceDiagram
    participant U as 用户
    box rgb(255,243,205) 上游vLLM
    participant E as Engine
    participant R as ModelRegistry
    participant W as Worker
    end
    box rgb(212,237,218) 本项目vllm-ascend
    participant M as 模型类
    end
    
    U->>E: model="DeepseekV4ForCausalLM"
    E->>R: 查找模型
    R->>R: 在注册表中搜索
    Note over R: 找到: "vllm_ascend.models.deepseek_v4:AscendDeepseekV4ForCausalLM"
    R-->>E: 返回类路径
    E->>E: importlib动态导入
    E->>M: 获取类并实例化
    M->>M: __init__(config) 创建模型结构
    M->>M: 加载预训练权重到NPU
    M-->>E: 返回模型对象
    E->>W: 传入模型对象
    W->>W: 准备推理环境
    W-->>U: 模型就绪
                
vLLM查找并加载模型的代码(简化版)
# vLLM内部代码(vllm/v1/engine/llm_engine.py)
def load_model(self, model_name):
    # 1. 从ModelRegistry查找类路径
    model_cls_path = ModelRegistry.get_model_class(model_name)
    # 例如: "vllm_ascend.models.deepseek_v4:AscendDeepseekV4ForCausalLM"
    
    # 2. 动态导入模块
    module_path, class_name = model_cls_path.split(":")
    module = importlib.import_module(module_path)
    
    # 3. 获取模型类并实例化
    model_cls = getattr(module, class_name)
    model = model_cls(config)  # 调用vllm-ascend定义的__init__
    
    # 4. 加载预训练权重
    model.load_weights(weights_path)
    
    return model  # 返回给Worker使用

四、推理执行衔接:Worker怎么调用vllm-ascend的组件

Worker是vLLM的核心执行器,它负责在GPU/NPU上执行推理。Worker通过vllm-ascend提供的组件(Attention Backend、Custom Ops、Model Runner)完成实际计算。

图3:推理执行衔接流程
sequenceDiagram
    box rgb(255,243,205) 上游vLLM
    participant W as Worker
    end
    box rgb(212,237,218) 本项目vllm-ascend
    participant MR as NPUModelRunner
    participant A as Attention Backend
    participant O as Custom Ops
    end
    participant N as NPU设备
    
    W->>MR: model_runner.execute(input_ids)
    MR->>O: 调用RMSNorm算子
    O->>N: NPU执行归一化
    N-->>O: 返回结果
    MR->>A: 调用注意力后端
    A->>N: NPU执行注意力计算
    N-->>A: 返回注意力结果
    MR->>O: 调用FFN算子
    O->>N: NPU执行前馈网络
    N-->>O: 返回结果
    MR-->>W: 返回logits
                
Worker调用vllm-ascend组件的代码(简化版)
# vLLM Worker代码(vllm/v1/worker/gpu_worker.py)
class Worker:
    def execute_model(self, input_ids):
        # 1. 获取ModelRunner(由vllm-ascend提供)
        model_runner = self.model_runner  # NPUModelRunner实例
        
        # 2. 调用ModelRunner执行前向传播
        logits = model_runner.execute(input_ids)
        
        # 3. ModelRunner内部调用vllm-ascend的组件:
        #    - 调用Attention Backend计算注意力
        #    - 调用Custom Ops执行自定义算子
        #    - 所有计算都在NPU上执行
        
        return logits
NPUModelRunner执行前向传播(vllm_ascend/worker/model_runner_v1.py)
class NPUModelRunner:
    def execute(self, input_ids):
        # 1. 调用自定义算子处理输入
        hidden_states = self.model.embed_tokens(input_ids)
        
        # 2. 逐层执行Transformer
        for layer in self.model.layers:
            # 调用RMSNorm算子
            hidden_states = layer.input_layernorm(hidden_states)
            
            # 调用注意力后端
            attn_output = layer.attention(hidden_states)
            
            # 调用FFN算子
            ffn_output = layer.feed_forward(attn_output)
        
        # 3. 返回logits
        return self.model.head(hidden_states)

五、完整链路:从用户输入到推理结果

将所有环节串起来,一次完整的推理请求经历以下流程:

图4:完整推理链路
sequenceDiagram
    participant U as 用户
    box rgb(255,243,205) 上游vLLM
    participant E as Engine
    participant R as ModelRegistry
    participant W as Worker
    participant S as Sampler
    end
    box rgb(212,237,218) 本项目vllm-ascend
    participant P as Ascend插件
    participant MR as NPUModelRunner
    participant A as Attention
    participant O as Ops
    end
    participant N as NPU
    
    U->>E: model=DeepseekV4, input=你好
    E->>P: 初始化插件
    P->>R: register_model()
    R->>R: 存储模型映射
    
    E->>R: 查找模型
    R-->>E: 返回类路径
    E->>MR: 动态导入并实例化
    MR->>MR: 加载权重
    
    loop 每个token
        E->>W: 发送输入
        W->>O: RMSNorm归一化
        O->>N: NPU执行
        N-->>O: 结果
        W->>A: MLA注意力计算
        A->>N: NPU执行
        N-->>A: 结果
        W->>O: FFN前馈网络
        O->>N: NPU执行
        N-->>O: 结果
        W->>S: 采样得到token
        S-->>W: token
    end
    W-->>U: 返回: 你好, 我是...
                

关键点总结

1. vLLM负责什么:请求调度、资源管理、Worker进程管理、采样策略

2. vllm-ascend负责什么:NPU硬件适配、注意力计算、自定义算子、模型注册

3. 接口是什么:Platform接口(硬件抽象)、ModelRegistry(模型注册)、AttentionBackend(注意力后端)

4. 数据怎么流动:用户输入 → Engine → Worker → ModelRunner → Attention 后端 → Custom Ops → NPU → 结果返回

首页