AFD Plugin Explained

The plugin entry point: register_afd

IntermediateAFD conceptsabout 5 min read + 2 min deep dives

Code version: afd-plugin @ 7452d52 · 2026-10-27 · vLLM @ ced6857

In one sentence

register_afd() is the one function vLLM calls to install AFD. It is safe to call many times, and safe to import without vLLM.

The idea#

afd-plugin is one general plugin. vLLM calls its entry function, register_afd, once in each process that loads plugins. The function installs the compat patches, the routing strategy, the DBO custom op and the model wrappers. Then it stops; it runs no model.

Two facts shape the function. First, vLLM calls it in many processes, and the vLLM guard resets in each new process. So the function must be idempotent: safe to run again with no change. Second, the package must import on a machine with no vLLM, so local tests work. The function handles both with guards and early returns.

An everyday comparison. Think of a self-check at the start of a shift. You run it once; if someone runs it again, it sees the ticks and stops. The comparison stops here: each new process starts with an empty checklist, so the plugin runs the whole check again.

The picture#

Figure: two guards make register_afd safe to repeat (panel 1); three checks can return before any registration (panel 2).
Open full size ↗

Read panel 1 as the two guards: one in vLLM, one in the plugin. Read panel 2 as the three checks at the top of the function. The version check warns and continues; the other two return.

In the code#

Step 1: Two guards make it idempotent#

vLLM keeps a module flag, plugins_loaded, so load_general_plugins runs the plugins at most once per process (vllm:vllm/plugins/__init__.py:82-85). The plugin adds its own flag, _registered. A second call to register_afd in the same process returns at once (afd_plugin/__init__.py:150-153).

    global _registered
    if _registered:
        _logger.debug("AFD plugin: register_afd() already completed")
        return
The plugin's own guard: return if already registered.

Step 2: Import safety without vLLM#

The function returns early when vLLM is not importable. It sets _registered first, so a later call does not retry (afd_plugin/__init__.py:157-160). So importing afd_plugin stays safe on a machine with no vLLM.

    if importlib.util.find_spec("vllm") is None:
        _logger.debug("AFD plugin: vLLM not found, skipping runtime registration")
        _registered = True
        return
No vLLM: mark done and return before any registration.

Step 3: The version gate warns, it does not stop#

The function checks the vLLM version with strict=False. A mismatch gives a warning, not an error (afd_plugin/__init__.py:162-165). The helper raises only when strict is true; otherwise it calls warnings.warn (afd_plugin/compat/vllm.py:38-50).

def assert_vllm_version_supported(*, strict: bool = True) -> None:
    installed_version = get_installed_vllm_version()
    if is_vllm_version_supported(installed_version):
        return

    message = (
        "AFD plugin currently supports exactly vLLM "
        f"{TARGET_VLLM_VERSION}; installed vLLM version is "
        f"{installed_version or 'not installed'}"
    )
    if strict:
        raise RuntimeError(message)
    warnings.warn(message, RuntimeWarning, stacklevel=2)
strict=False: warn instead of raise.

Step 4: What it registers, and in which order#

After the checks, the function runs these steps in order. Each is one or a few lines; the afd_plugin/__init__.py: the plugin entry module page reads them line by line.

  1. Import the four patch modules. Importing a patch module applies it (afd_plugin/__init__.py:172-176).
  2. Register the AFD routing strategy (afd_plugin/__init__.py:183-187).
  3. Register the DBO yield custom op (afd_plugin/__init__.py:189-192).
  4. NPU only: apply the Ascend config patch, when the device type is "npu" (afd_plugin/__init__.py:202-209).
  5. Register each model under its AFD<arch> name (afd_plugin/__init__.py:211-214).
  6. Set _registered = True (afd_plugin/__init__.py:216).

Step 5: Which steps are wrapped in try/except#

Three steps swallow their own errors; three do not. A wrapped step logs at debug and lets the rest go on. An unwrapped step lets its error propagate and stop the process.

StepLinesOn failure
Version checkafd_plugin/__init__.py:162-170Caught: logged at debug.
Import the 4 patchesafd_plugin/__init__.py:172-181Caught: logged at debug.
DBO custom opafd_plugin/__init__.py:189-197Caught: logged at debug.
Routing strategyafd_plugin/__init__.py:183-187Not caught: propagates.
NPU Ascend patchafd_plugin/__init__.py:199-209Not caught: propagates.
Model registrationafd_plugin/__init__.py:211-214Not caught: propagates.

Deep dive#

Deep dive

Idempotence across processes, and the order of the guards

The two guards work at different levels, and the order matters.

  1. vLLM calls load_general_plugins from five call sites, in four kinds of process (for example vllm:vllm/v1/engine/core.py:119 and vllm:vllm/v1/worker/worker_base.py:271). The How vLLM plugins work page lists all five.
  2. The vLLM guard plugins_loaded stops a second call in the same process (vllm:vllm/plugins/__init__.py:82-85). It is module state, so a new process starts it at False again.
  3. Inside one call, the plugin guard _registered stops repeated work if register_afd is reached twice in one process (afd_plugin/__init__.py:150-153).

Because the vLLM guard resets per process, the registration steps run again in each process. So each step must be safe to run more than once. ModelRegistry.register_model and the module-attribute patches both satisfy this: the patch install saves each original target once, behind a hasattr guard, so a repeat keeps the real original (afd_plugin/compat/patches/config_validation.py:235-248).

Deep dive

Two different version checks

There are two version checks, and they are not the same.

So on a non-matching, non-dev vLLM, the explicit check warns, the function continues, but the patches do not install. AFD then does not take effect. The two checks let the import stay safe while the patches stay strict.

What can go wrong#

Why it matters. AFD is installed only by this function. A warning that the version does not match is the one sign that the patches did not install and AFD is off.

Check yourself#

  1. 1
    What are the two guards that make register_afd idempotent?
    easy
    Show answer

    vLLM's plugins_loaded (vllm:vllm/plugins/__init__.py:82-85) and the plugin's own _registered (afd_plugin/__init__.py:150-153).

  2. 2
    Which registration step runs only on NPU?
    easy
    Show answer

    The Ascend config patch, applied only when the device type is "npu" (afd_plugin/__init__.py:202-209).

  3. 3
    The vLLM version does not match. Does the process stop?
    medium
    Show answer

    No. The explicit check uses strict=False and only warns (afd_plugin/compat/vllm.py:48-50). But the patches skip install, so AFD does not activate (afd_plugin/compat/patches/config_validation.py:235-261).

  4. 4
    Why must each registration step be safe to run more than once?
    medium
    Show answer

    vLLM calls the function in several processes, and the plugins_loaded guard resets in each new process (vllm:vllm/plugins/__init__.py:82-85).

  5. 5
    The routing strategy step is not wrapped in try/except, but the DBO op step is. What is the effect of that difference?
    hard
    Show answer

    A failure in the routing strategy propagates and stops the process (afd_plugin/__init__.py:183-187). A failure in the DBO op is caught and logged at debug, so registration continues (afd_plugin/__init__.py:189-197).