connectors/base.py, factory.py, metadata.py: the connector core
Code version: afd-plugin @ 7452d52 · 2026-10-27 · vLLM @ ced6857
In one sentence
Three files form the connector core: base.py (the contract), factory.py (name to class) and metadata.py (the shared data objects).
Purpose#
These files hold the parts every connector shares. The contract and the factory are explained on the The connector contract: the Attention/FFN transport page; this page maps the three files and reads the metadata objects and the factory loader.
| Item | Value |
|---|---|
| Files (lines, origin) | base.py (310), factory.py (105), metadata.py (438); AFD-owned |
| Main types | AFDConnectorBase, AFDControlPlane, AFDConnectorFactory, the AFD* metadata dataclasses |
| Runs in | every attention and FFN worker process; metadata encode/decode on the CPU |
| Called by | the role runners and the model wrappers (afd_plugin/v1/worker/ffn_model_runner.py:80-85) |
| Calls | importlib, torch, json, and the AFD config helpers |
| Not in this file | the transports: the GPU P2P connector is in connectors/gpu/p2p.py, the NPU ones in connectors/npu/ |
Where it sits#
Who calls it#
The factory builds a connector for a runner. The FFN runner calls create_connector at
construction (afd_plugin/v1/worker/ffn_model_runner.py:80-85); the attention runner does the same.
The model wrappers build the metadata objects for each transfer
(afd_plugin/model_executor/models/deepseek_v2.py:140-145).
What it calls#
base.py reads the AFD config helper connector_extra_config_from_source
(afd_plugin/connectors/base.py:105-107). factory.py imports the connector module lazily
with importlib (afd_plugin/connectors/factory.py:38-45). metadata.py encodes
the control payload with json (afd_plugin/connectors/metadata.py:344-346).
Key classes and functions#
| Name | Line | Role |
|---|---|---|
AFDConnectorBase | afd_plugin/connectors/base.py:37 | the connector contract (see The connector contract: the Attention/FFN transport) |
AFDControlPlane | afd_plugin/connectors/base.py:258 | the control-plane contract |
AFDConnectorFactory | afd_plugin/connectors/factory.py:23 | name → class, build an instance |
AFDDPMetadata | afd_plugin/connectors/metadata.py:23 | per-DP-rank token counts for the control plane |
AFDControlPayload | afd_plugin/connectors/metadata.py:107 | the control-plane envelope (per-stage metadata + flags) |
AFDTransferMetadata | afd_plugin/connectors/metadata.py:171 | layer, stage and per-peer lengths for one transfer |
AFDTransferContext | afd_plugin/connectors/metadata.py:234 | transfer metadata plus optional backend state |
AFDA2FTransferPayload | afd_plugin/connectors/metadata.py:261 | the FFN-side receive payload (hidden states + extras) |
encode_control_payload | afd_plugin/connectors/metadata.py:320 | payload → compact JSON bytes |
send_control_payload | afd_plugin/connectors/metadata.py:376 | send the size tensor and the byte tensor |
Walk through the main methods#
AFDTransferMetadata: the per-transfer record#
This dataclass describes one layer-and-stage transfer. It validates its lengths and derives the total
token count (afd_plugin/connectors/metadata.py:171-200).
layer_idx: int
stage_idx: int
seq_lens: list[int]
def __post_init__(self) -> None:
if not self.seq_lens:
raise ValueError("seq_lens cannot be empty")
if any(length <= 0 for length in self.seq_lens):
raise ValueError("all sequence lengths must be positive")
@property
def total_tokens(self) -> int:
return sum(self.seq_lens)- Line 188-190. The fields:
layer_idx,stage_idx, and the per-peerseq_lenslist. - Line 192-196.
__post_init__rejects an empty list and any non-positive length. - Line 198-200.
total_tokensis the sum of the lengths; it is the expected leading dimension.
Two class methods build the attention form (one length) and the FFN form (a list of lengths)
(afd_plugin/connectors/metadata.py:202-228). The shape check is
validate_tensor_shape (afd_plugin/connectors/metadata.py:230-231).
encode_control_payload: the wire format#
The control payload is serialized to compact JSON, with only the fields the FFN side reads back
(afd_plugin/connectors/metadata.py:320-346).
metadata_payload: dict[str, dict[str, int | list[int]]] = {}
for stage_idx, dp_metadata in payload.dp_metadata_list.items():
stage_payload: dict[str, int | list[int]] = {
"num_tokens_across_dp_cpu": dp_metadata.num_tokens_across_dp_cpu.tolist(),
"max_tokens_across_dp_cpu": _to_int(dp_metadata.max_tokens_across_dp_cpu),
}
metadata_payload[str(int(stage_idx))] = stage_payload
wire_payload = {
"dp_metadata_list": metadata_payload,
"is_graph_capturing": bool(payload.is_graph_capturing),
"is_warmup": bool(payload.is_warmup),
"is_graph_replaying": bool(payload.is_graph_replaying),
"is_profile": bool(payload.is_profile),
}
return json.dumps(wire_payload, separators=(",", ":"), sort_keys=True).encode(
"utf-8",
)- Line 329-335. One entry per stage: the per-DP-rank token list and its max.
- Line 337-343. The graph-capture, warm-up, replay and profile flags.
- Line 344-346.
json.dumpswith sorted keys and no spaces. The The control plane: DP metadata once per step page reads the send and receive.
AFDConnectorFactory: name to class#
The factory keeps a registry of loaders. register_connector stores a loader that imports the
module lazily (afd_plugin/connectors/factory.py:26-47); create_connector looks the name
up, resolves the role rank, and builds the instance
(afd_plugin/connectors/factory.py:49-68).
def loader() -> type[AFDConnectorBase]:
module = importlib.import_module(module_path)
connector_cls = vars(module)[class_name]
if not issubclass(connector_cls, AFDConnectorBase):
raise TypeError(
f"{module_path}.{class_name} is not an AFDConnectorBase",
)
return connector_cls
cls._registry[name] = loaderThree connectors are registered at import time; an unknown name raises
(afd_plugin/connectors/factory.py:58-59, afd_plugin/connectors/factory.py:88-102).
Deep dive#
Deep diveThe metadata objects at a glance
The dataclasses split the control plane from the data plane.
| Object | Plane | Carries |
|---|---|---|
AFDDPMetadata | control | per-DP-rank token counts (afd_plugin/connectors/metadata.py:23-44) |
AFDControlPayload | control | per-stage DP metadata + flags (afd_plugin/connectors/metadata.py:135-139) |
AFDTransferMetadata | data | layer, stage, per-peer lengths (afd_plugin/connectors/metadata.py:188-190) |
AFDTransferContext | data | metadata + optional backend state (afd_plugin/connectors/metadata.py:257-258) |
AFDA2FTransferPayload | data | hidden states, context, optional logits and IDs (afd_plugin/connectors/metadata.py:279-282) |
AFDTransferContext.states defaults to None so the generated
__init__ stays traceable by torch.compile
(afd_plugin/connectors/metadata.py:244-249).
Related concepts#
- The connector contract: the Attention/FFN transport — the ABC, the lifecycle and the factory in full.
- The control plane: DP metadata once per step — how the control payload is published and received.
- Data on the wire: tensors per layer and stage — how the transfer metadata drives the fan-in and split.
- connectors/gpu/p2p.py: the GPU P2P connector — the GPU connector that implements the contract.
Check yourself#
- 1Which file holds the shared metadata dataclasses?easy
Show answer
connectors/metadata.py. It definesAFDDPMetadata,AFDControlPayload,AFDTransferMetadataand the transfer payloads (afd_plugin/connectors/metadata.py:23,afd_plugin/connectors/metadata.py:171). - 2How does the factory load a connector class?medium
Show answer
Lazily.
register_connectorstores a loader that imports the module withimportliband checks the subclass only when the name is first used (afd_plugin/connectors/factory.py:38-47). - 3What ishard
total_tokens, and where is it checked?Show answer
It is the sum of the per-peer
seq_lens(afd_plugin/connectors/metadata.py:198-200).validate_tensor_shapechecks that a tensor's leading dimension equals it (afd_plugin/connectors/metadata.py:230-231).