跳转至

vLLM Ascend 中的补丁

vLLM Ascend 是 vLLM 的一个平台插件。由于 vLLM 和 vLLM Ascend 的发布周期不同以及硬件限制,我们需要对 vLLM 中的部分代码进行补丁,以使其与 vLLM Ascend 兼容。

在 vLLM Ascend 代码中,我们提供了一个补丁模块 vllm_ascend/patch,用于适配 vLLM 的变更。

原则

我们应该牢记,补丁并非使 vLLM Ascend 兼容的最佳方式,它只是一个临时解决方案。最佳方式是将变更贡献给 vLLM,使其从一开始就与 vLLM Ascend 兼容。在 vLLM Ascend 中,我们对于补丁策略有以下基本原则:

  1. 少即是多。除非是当前唯一的方法,否则请不要打补丁。
  2. 一旦添加了补丁,必须描述未来移除该补丁的计划。
  3. 随时欢迎清理补丁代码。

工作原理

vllm_ascend/patch 中,你可以看到如下代码结构:

vllm_ascend
├── patch
   ├── platform
      ├── patch_xxx.py
   ├── worker
      ├── patch_yyy.py
└───────────
  • platform: 此目录中的补丁代码用于修补 vLLM 主进程中的代码。它在 vLLM 初始化时由 vllm_ascend/platform::NPUPlatform::pre_register_and_update 非常早地调用。
    • 对于在线模式,vLLM 进程在解析 CLI 参数时调用 vllm/vllm/engine/arg_utils.py::AsyncEngineArgs.add_cli_args 中的平台补丁。
    • 对于离线模式,vLLM 进程在解析输入参数时调用 vllm/vllm/engine/arg_utils.py::EngineArgs.create_engine_config 中的平台补丁。
  • worker: 此目录中的补丁代码用于修补 vLLM 工作进程中的代码。它在 vLLM 工作进程初始化时由 vllm_ascend/worker/worker::NPUWorker::__init__ 调用。
    • 对于在线和离线模式,vLLM 引擎核心进程在初始化工作进程时调用 vllm/vllm/worker/worker_base.py::WorkerWrapperBase.init_worker 中的工作进程补丁。

如何编写补丁

在编写补丁之前,遵循上述原则,我们应该修补最少的代码。如果有必要,我们可以在 platformworker 文件夹中修补代码。以下是一个修补 vLLM 中 distributed 模块的示例。

  1. 确定我们应该修补 vLLM 的哪个版本。例如,经过分析,这里我们想要修补 vLLM 的 0.10.0main 版本。
  2. 确定我们应该修补哪个进程。例如,这里的 distributed 属于 vLLM 主进程,所以我们应该修补 platform
  3. 在正确的文件夹中创建补丁文件。文件应命名为 patch_{module_name}.py。此处的示例是 vllm_ascend/patch/platform/patch_distributed.py
  4. 在新文件中编写你的补丁代码。示例如下:

    import vllm
    
    def patch_destroy_model_parallel():
        # your patch code
        ...
    
    vllm.distributed.parallel_state.destroy_model_parallel = patch_destroy_model_parallel
    
  5. __init__.py 中导入补丁文件。在此示例中,将 import vllm_ascend.patch.platform.patch_distributed 添加到 vllm_ascend/patch/platform/__init__.py

  6. vllm_ascend/patch/__init__.py 中添加补丁的描述。描述格式如下:

    # ** File: <The patch file name> **
    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    #   1. `<The target patch module in vLLM>`
    #    Why:
    #       <Describe the reason why we need to patch>
    #    How:
    #       <Describe the way to patch>
    #    Related PR (if no, explain why):
    #       <Add a link to the related PR in vLLM. If there is no related PR, explain why>
    #    Future Plan:
    #       <Describe the future plan to remove the patch>
    
  7. 添加单元测试和端到端测试。vLLM Ascend 中任何新添加的代码都应包含单元测试和端到端测试。你可以在测试指南中找到更多详细信息。

限制

  1. 在 V1 引擎中,vLLM 启动三种进程:主进程、EngineCore 进程和工作进程。目前 vLLM Ascend 默认只能修补主进程和工作进程中的代码。如果你想修补在 EngineCore 进程中运行的代码,你需要在安装过程中完整地修补 EngineCore 进程。在 vllm.v1.engine.core 中找到完整代码。请完整地重写 EngineCoreProcDPEngineCoreProc
  2. 如果你运行的是经过编辑的 vLLM 代码,vLLM 的版本可能会自动更改。例如,如果你运行基于 v0.9.n 编辑的 vLLM,vLLM 的版本可能会变为 v0.9.nxxx。在这种情况下,vLLM Ascend 中针对 v0.9.n 的补丁将无法按预期工作,因为 vLLM Ascend 无法区分你正在使用的 vLLM 版本。在这种情况下,你可以设置环境变量 VLLM_VERSION 来指定你正在使用的 vLLM 版本,然后针对该版本(例如 v0.9.n)的补丁应该可以正常工作。