跳转至

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_ascend/platform::NPUPlatform::pre_register_and_update 在 vLLM 初始化早期调用。
    • 对于在线模式,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 Worker 进程中的代码。它由 vllm_ascend/worker/worker::NPUWorker::__init__ 在 vLLM Worker 进程初始化时调用。
    • 对于在线和离线模式,vLLM EngineCore 进程在初始化 Worker 进程时,会在 vllm/vllm/worker/worker_base.py::WorkerWrapperBase.init_worker 中调用 worker 补丁。

如何编写补丁

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

  1. 确定我们应该修补哪个版本的 vLLM。例如,经过分析后,这里我们希望同时修补 vLLM 的 0.10.0 和 main。
  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. 添加单元测试和 E2E 测试。vLLM Ascend 中任何新增代码都应包含单元测试和 E2E 测试。你可以在 测试指南 中找到更多详细信息。

限制

  1. 在 V1 Engine 中,vLLM 会启动三种进程:主进程、EngineCore 进程和 Worker 进程。目前 vLLM Ascend 默认只能修补主进程和 Worker 进程中的代码。如果你想修补在 EngineCore 进程中运行的代码,你应该在初始化期间完全修补 EngineCore 进程。请在 vllm.v1.engine.core 中找到完整代码。请完全重写 EngineCoreProc 和 DPEngineCoreProc。
  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)的补丁应该可以正常工作。

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 vl/vllm-ascend