vllm-project/vllm · error · ValueError

When PCP is enabled, DCP must be disabled, span the PCP axis

Error message

When PCP is enabled, DCP must be disabled, span the PCP axis, or span the full TP x PCP axis. Got TP={tp}, PCP={pcp}, DCP={dcp}; valid DCP sizes are {sorted({1, pcp, tp * pcp})}.

What it means

When PCP is enabled, DCP must be disabled (1), span exactly the PCP axis (dcp == pcp), or span the full TP x PCP axis (dcp == tp * pcp); these are the only factorizations the rank layout supports. Any other DCP value is rejected with the valid set listed in the message.

Source

Thrown at vllm/config/parallel.py:534

            if self.eplb_config.num_redundant_experts != 0:
                raise ValueError(
                    "num_redundant_experts is set to "
                    f"{self.eplb_config.num_redundant_experts} but EPLB is not "
                    "enabled. Either enable EPLB or unset "
                    "num_redundant_experts."
                )

        tp = self.tensor_parallel_size
        pcp = self.prefill_context_parallel_size
        dcp = self.decode_context_parallel_size
        if pcp > 1 and self.data_parallel_size > 1:
            raise ValueError("PCP does not support data parallelism yet.")
        if pcp == 1:
            # DCP reuses the TP ranks when PCP is disabled.
            if tp % dcp != 0:
                raise ValueError(f"tp_size={tp} must be divisible by dcp_size={dcp}.")
        elif dcp not in (1, pcp, tp * pcp):
            raise ValueError(
                "When PCP is enabled, DCP must be disabled, span the PCP "
                "axis, or span the full TP x PCP axis. "
                f"Got TP={tp}, PCP={pcp}, DCP={dcp}; valid DCP sizes are "
                f"{sorted({1, pcp, tp * pcp})}."
            )

        if self.dcp_comm_backend == "a2a" and self.decode_context_parallel_size <= 1:
            raise ValueError(
                "dcp_comm_backend='a2a' requires decode_context_parallel_size > 1."
            )

        return self

    @property
    def world_size_across_dp(self) -> int:
        """Process world size across TP, PCP, PP, and DP."""
        return self.world_size * self.data_parallel_size

View on GitHub (pinned to c794754062)

Solutions

  1. Choose DCP from the valid set printed in the error: 1, PCP, or TP*PCP.
  2. If a finer-grained DCP is required, reshape PCP/TP so that tp*pcp hits the desired value.
  3. Disable DCP (set it to 1) if decode context parallelism is optional for the deployment.

Example fix

# before
--tensor-parallel-size 2 --prefill-context-parallel-size 2 --decode-context-parallel-size 3
# after
--tensor-parallel-size 2 --prefill-context-parallel-size 2 --decode-context-parallel-size 4  # == tp*pcp
Defensive patterns

Strategy: validation

Validate before calling

def pcp_dcp_valid(tp: int, pcp: int, dcp: int) -> bool:
    return pcp == 1 or dcp in (1, pcp, tp * pcp)

assert pcp_dcp_valid(2, 2, 4)

Prevention

When it happens

Trigger: PCP > 1 with a decode_context_parallel_size not in {1, pcp, tp*pcp}, e.g. TP=2, PCP=2, DCP=2 is fine (== pcp) but DCP=3 or DCP=4 (== tp*pcp only when tp*pcp=4, so 4 is valid) — a value like DCP=8 with TP=2/PCP=2 fails.

Common situations: Mixing context-parallel knobs copied from different recipes; assuming DCP can be an arbitrary divisor of world size like TP.

Related errors


AI-assisted analysis of vllm-project/vllm@c794754062 (2026-08-14). Data as JSON: /api/errors/4c11d3c5ea741097. Report an issue: GitHub.