AFD config reference: the additional_config["afd"] keys
Code version: afd-plugin @ 7452d52 · 2026-10-27 · vLLM @ ced6857
In one sentence
This page lists every AFD config key, its alias, type, default and validation, and the connector_extra_config keys that each connector accepts.
How the config is passed#
You give AFD config to vLLM under one key. Each vllm serve process gets
--additional-config '{"afd": { ... }}'. vLLM stores the outer mapping on its
additional_config field (vllm:vllm/config/vllm.py:434). The plugin reads the inner
"afd" mapping and builds an AFDConfig dataclass
(afd_plugin/config.py:42).
The two tables in the next section are generated from the source. The validation, read-site and example tables that follow are hand-written, each row with a citation.
The keys#
The build generates the tables below from AFDConfig and the connector source, so the names,
types, defaults and lines stay correct at the pinned commit. Run
python3 tools/gen_afd_config.py to refresh them.
Generated by tools/gen_afd_config.py from afd_plugin/config.py and the connector source. Do not edit between the markers.
The afd keys#
| Key | Alias | Type | Default | What it is | Source |
|---|---|---|---|---|---|
connector | afd_connector | str | 'P2pNcclAFDConnector' | Connector implementation name used to create the backend data path. | afd_plugin/config.py:52 |
async_dp | async | bool | False | Whether AFD owns async data-parallel runtime patches for this process. | afd_plugin/config.py:54 |
role | afd_role | AFDRole | 'attention' | Role owned by this process: Attention sends hidden states; FFN receives. | afd_plugin/config.py:56 |
port | afd_port | int | 1239 | Port used by the AFD connector rendezvous/control path. | afd_plugin/config.py:58 |
host | afd_host | str | '127.0.0.1' | Host used by the AFD connector rendezvous/control path. | afd_plugin/config.py:60 |
num_attention_ranks | — | int | 1 | Number of AFD Attention ranks participating in this topology. | afd_plugin/config.py:62 |
num_ffn_ranks | — | int | 1 | Number of AFD FFN ranks participating in this topology. | afd_plugin/config.py:64 |
compute_gate_on_attention | — | bool | False | Whether Attention computes MoE gate outputs before sending to FFN. | afd_plugin/config.py:66 |
afd_process_group_timeout_s | — | int | 120 | Timeout, in seconds, for the AFD world process group rendezvous. The right value depends on rank count, placement, and model size, so it is left to the caller (deployment tooling) rather than derived here. | afd_plugin/config.py:70 |
connector_extra_config | — | dict[str, Any] | {} (empty mapping) | afd_plugin/config.py:71 |
connector_extra_config by connector#
P2pNcclAFDConnector (GPU): no keys. A non-empty connector_extra_config raises ValueError (afd_plugin/connectors/gpu/p2p.py:155).
CAMP2pAFDConnector (NPU)
| Key | Type | Default | Source |
|---|---|---|---|
core_num | int > 0 | 8 | afd_plugin/connectors/npu/camp2p.py:116 |
attn_core_num | int > 0, or null | None | afd_plugin/connectors/npu/camp2p.py:120 |
ffn_core_num | int > 0, or null | None | afd_plugin/connectors/npu/camp2p.py:124 |
compute_gate_on_attention | bool | False | afd_plugin/connectors/npu/camp2p.py:128 |
hccl_buffer_size | int > 0, or null | None | afd_plugin/connectors/npu/camp2p.py:132 |
quant_mode | int | 0 | afd_plugin/connectors/npu/camp2p.py:136 |
CAMAsyncAFDConnector (NPU)
The async connector accepts the wire key dynamicQuant for its typed field dynamic_quant.
| Key | Type | Default | Source |
|---|---|---|---|
dynamicQuant | int | 0 | afd_plugin/connectors/npu/async_cam.py:183 |
attn_ranks_per_dp | int > 0 | 1 | afd_plugin/connectors/npu/async_cam.py:187 |
hccl_buffer_size | int > 0, or null | None | afd_plugin/connectors/npu/async_cam.py:191 |
ffn_two_stream | bool | False | afd_plugin/connectors/npu/async_cam.py:195 |
ffn_compute_aic_num | int > 0 | 12 | afd_plugin/connectors/npu/async_cam.py:198 |
ffn_compute_aiv_num | int > 0 | 24 | afd_plugin/connectors/npu/async_cam.py:201 |
ffn_combine_aiv_num | int > 0 | 24 | afd_plugin/connectors/npu/async_cam.py:204 |
Validation rules#
The plugin coerces each value to its type, then validates it. Coercion happens in
_normalize_mapping (afd_plugin/config.py:120-176); validation happens in
validate_afd_config (afd_plugin/config.py:311-350). An invalid value raises before the
run starts.
| Rule | Applies to | Source |
|---|---|---|
Unknown afd key raises ValueError | any key not a field or alias | afd_plugin/config.py:134-139 |
An alias and its canonical key together raise ValueError | for example
role and afd_role | afd_plugin/config.py:140-144 |
role must be "attention" or "ffn" | role |
afd_plugin/config.py:318-321 |
connector must be one of the three registered names | connector |
afd_plugin/config.py:326-330 |
async_dp=true needs connector="CAMAsyncAFDConnector" |
async_dp | afd_plugin/config.py:331-334 |
host must be non-empty | host |
afd_plugin/config.py:339-340 |
port must be in 1..65535 | port |
afd_plugin/config.py:341-342 |
num_attention_ranks and num_ffn_ranks must be positive |
both rank counts | afd_plugin/config.py:343-350 |
For P2pNcclAFDConnector: num_attention_ranks >= num_ffn_ranks |
GPU P2P only | afd_plugin/distributed/topology.py:52-58 |
Booleans accept true/false, 1/0, yes/no, on/off |
async_dp, compute_gate_on_attention |
afd_plugin/config_utils.py:8-24 |
Integers reject bool and float inputs |
port, rank counts | afd_plugin/config_utils.py:35-45 |
Where each value is read, and what it changes#
The table lists the main GPU read site of each key. The NPU connectors read the same keys through their own code.
| Key | Read at (GPU) | What it changes |
|---|---|---|
connector | afd_plugin/connectors/factory.py:57-60 |
Which connector class the factory builds. |
role | afd_plugin/validation.py:350-354 |
The expected worker class, so attention or FFN. The worker runs the matching runner. |
host, port | afd_plugin/connectors/gpu/p2p.py:271 |
The TCP rendezvous where the two roles set up the connector groups. |
num_attention_ranks, num_ffn_ranks |
afd_plugin/distributed/topology.py:46-49 |
The world size and the per-FFN subgroups
(afd_plugin/distributed/topology.py:118-146). |
async_dp | afd_plugin/config.py:303-308 |
Selects AFD async mode through is_afd_async_dp. It gates the NPU async-DP patches
(afd_plugin/compat/npu/runtime.py:44-53); on GPU it must be false. |
compute_gate_on_attention | afd_plugin/v1/worker/ffn_model_runner.py:211-215 |
Whether the attention side computes the MoE gate; the FFN side then runs only the expert layers. |
afd_process_group_timeout_s | afd_plugin/connectors/gpu/p2p.py:275 |
How long the world process-group rendezvous waits before it fails. |
connector_extra_config | afd_plugin/connectors/base.py:105-107 |
The per-connector options; stored on extra_info after the connector parses it. |
Where the final value is set#
Lesson from the fact checks: a default is not final until the code sets it. Trace each value through four steps. A missing key takes the dataclass default; a present key is coerced, stored, then validated.
- Recipe or CLI. The
--additional-configJSON gives the raw mapping. vLLM stores it onadditional_config(vllm:vllm/config/vllm.py:434). - Normalize.
_normalize_mappingrewrites aliases, splits outconnector_extra_config, and coercesport, the rank counts, the timeout and the booleans (afd_plugin/config.py:147-174). - Construct.
AFDConfig(**normalized)fills any absent key with the dataclass default (afd_plugin/config.py:189-190). So the defaults in the table apply only to keys the recipe omits. - Validate.
validate_afd_configraises on a bad value (afd_plugin/config.py:311-350). The worker re-parses and re-validates throughassert_compatible_afd_stack(afd_plugin/validation.py:328).
Worked example: the recipe's afd block#
This block is the attention server from the simplest GPU recipe, 2a2f_eager_dbo_dp1tp2.sh
(recipe/gpu/P2pNcclAFDConnector/deepseek_v2_lite/prefill_decode_colocation/2a2f_eager_dbo_dp1tp2.sh:11-20).
The FFN server uses the same block with "role": "ffn". The tour Tour: Life of a request
follows a request through this recipe.
{
"afd": {
"role": "attention",
"connector": "P2pNcclAFDConnector",
"host": "127.0.0.1",
"port": 6269,
"num_attention_ranks": 2,
"num_ffn_ranks": 2
}
}
| Key | Value | Effect for this recipe |
|---|---|---|
role | "attention" |
This server runs the attention worker and the API server. The FFN server sets "ffn". |
connector | "P2pNcclAFDConnector" |
The GPU connector. It takes no connector_extra_config. |
host, port | "127.0.0.1", 6269 |
Both servers meet at this address. The value overrides the default port 1239. |
num_attention_ranks | 2 |
Two attention ranks (A0, A1). The server runs --tensor-parallel-size 2. |
num_ffn_ranks | 2 |
Two FFN ranks (F0, F1). A0 maps to F0 and A1 maps to F1
(afd_plugin/distributed/topology.py:135-136). |
The recipe omits five keys, so they take their defaults: async_dp=false,
compute_gate_on_attention=false, afd_process_group_timeout_s=120, an empty
connector_extra_config, and the coerced port and rank integers. The A >= F
rule holds because both counts are 2 (afd_plugin/distributed/topology.py:52-58).