Expert Parallelism › Communication Overhead Analysis

Michael BrenndoerferNovember 19, 202510 min read
Language AI HandbookAll chapters
Part 33 of 67Mixture of Experts
Chapter 246Expert Parallelism › Communication Overhead Analysis
Reading section 5 of 12 · Communication Overhead Analysis · 10 minSection 5 of 12 · 10 min

Book contents

Section 5 of 12 · 10 min read

Expert Parallelism › Communication Overhead AnalysisOne section · Sections in this chapter5 / 12 ↓
Reading tools Definitions & inline links

Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.

Article links

Make inline references clickable

Expert parallelism introduces communication costs that do not exist in dense models. Understanding these costs is needed for system design and performance optimization. While dense model training also involves communication (for gradient synchronization, for example), the all-to-all operations in MoE occur in the forward pass itself, directly adding latency to every training step. Unlike gradient synchronization, which can often be overlapped with the backward pass computation through techniques like gradient bucketing, the dispatch and combine all-to-all operations in the forward pass sit on the necessary path: the expert computation cannot begin until the dispatch is complete, and the next layer cannot begin until the combine is complete.

This is a subtle but important distinction. In data-parallel training with gradient synchronization, the communication is largely "free" from a latency perspective because it happens in the background while computation continues. In expert parallelism, the forward-pass communication creates unavoidable serial dependencies. The training step time is therefore: routing computation, plus dispatch all-to-all, plus expert computation, plus combine all-to-all, plus remaining layer computation. The all-to-all operations add directly to the necessary path length, not just to bandwidth utilization.

Communication Volume

For each MoE layer, we perform two all-to-all operations. The first operation dispatches tokens from their originating devices to the devices holding their target experts. The second operation returns the processed results back to the originating devices. Each operation moves the same amount of data, as every token that goes out must come back. The total communication volume is therefore symmetric: dispatch and combine are mirror images of each other.

The total communication volume VlayerV_{\text{layer}} (in elements) per MoE layer can be expressed in terms of the key configuration parameters. We compute this by multiplying the number of token-expert pairs by the size of each token representation, then doubling for the two communication phases:

Vlayer=2×B×S×K×DV_{\text{layer}} = 2 \times B \times S \times K \times D

where:

  • BB: the batch size (number of sequences). Larger batches increase throughput but also increase the total number of tokens that must be routed.
  • SS: the sequence length (number of tokens per sequence). Longer sequences mean more tokens per batch, directly scaling communication.
  • KK: the top-kk parameter (number of experts per token). When k=2k=2, each token creates two communication events rather than one.
  • DD: the hidden dimension (size of each token vector). Larger models with wider hidden dimensions must send more data per token.
  • 22: accounts for the two all-to-all operations (dispatch and combine). This factor is fixed by the algorithm structure.

Why does this formula make sense? Notice that B×SB \times S gives the total number of tokens in the batch. Multiplying by KK gives the total number of token-expert pairs, since each token creates KK routing events. Multiplying by DD converts token count to element count, since each token is a vector of DD elements. The factor of 2 reflects that each element travels twice: once to the expert device and once back. The multiplicative relationship between these factors means that communication volume grows rapidly with any of the individual parameters. Doubling any single factor doubles the communication cost.

In[16]:
Code
def calculate_communication_volume(
    batch_size: int,
    seq_len: int,
    hidden_dim: int,
    top_k: int,
    num_moe_layers: int,
    bytes_per_element: int = 2,  # bf16
) -> dict:
    """
    Calculate total communication volume for MoE forward pass.
    """
    # Tokens communicated per MoE layer
    tokens_per_layer = batch_size * seq_len * top_k
    elements_per_layer = tokens_per_layer * hidden_dim

    # Two all-to-all operations per layer (dispatch + combine)
    elements_per_layer_total = elements_per_layer * 2

    # Total across all MoE layers
    total_elements = elements_per_layer_total * num_moe_layers
    total_bytes = total_elements * bytes_per_element

    return {
        "tokens_per_layer": tokens_per_layer,
        "elements_per_all_to_all": elements_per_layer,
        "total_elements": total_elements,
        "total_bytes": total_bytes,
        "total_gb": total_bytes / (1024**3),
    }


# Typical training configuration
comm_volume = calculate_communication_volume(
    batch_size=32,
    seq_len=2048,
    hidden_dim=4096,
    top_k=2,
    num_moe_layers=16,  # MoE in every other layer of 32-layer model
)
Out[17]:
Console
Communication volume analysis:
  Tokens per MoE layer: 131,072
  Elements per all-to-all: 536,870,912
  Total elements (forward pass): 17,179,869,184
  Total communication: 32.00 GB

This substantial volume of data movement, roughly 32 GB per forward pass for a single batch, highlights why network bandwidth is often the bottleneck in MoE training. To put this in perspective, even with high-bandwidth interconnects capable of 200 GB/s, transferring 32 GB takes around 160 milliseconds if the transfers were purely sequential. In practice, the all-to-all implementation uses bidirectional transfers and pipeline overlap to reduce effective latency, but the basic constraint remains: you cannot transfer 32 GB faster than the interconnect bandwidth allows. The communication cost scales linearly with the number of MoE layers, making efficient routing needed. This is one reason why some architectures use MoE layers only in alternating positions rather than in every layer, reducing the number of all-to-all operations by half at the cost of slightly reduced expert capacity.

Communication vs Computation Trade-off

The key metric for understanding expert-parallelism efficiency is the ratio of communication time to computation time. If communication dominates, adding more devices provides diminishing returns because each device spends more time waiting for data than computing. Conversely, if computation dominates, the system can efficiently use additional devices for expert computation without communication becoming a bottleneck.

This ratio is determined by what is sometimes called the arithmetic intensity of the all-to-all: the ratio of compute operations performed to bytes transferred. For expert parallelism, we transfer token representations to expert devices and get back transformed representations. The computation performed on those representations is the expert forward pass, which involves two matrix multiplications per token. The ratio of FLOP to bytes transferred determines whether the system is compute-bound or bandwidth-bound.

As we scale to more devices, the fraction of tokens that must cross device boundaries increases. With NN devices, approximately (N−1)/N(N-1)/N of all token-expert pairs must be transferred across the network (assuming uniform routing). As NN grows, this fraction approaches 1, meaning almost all communication is cross-device. This is why communication overhead grows with device count: more devices means more cross-device traffic for the same total token count.

In[18]:
Code
def analyze_scaling_efficiency(
    hidden_dim: int,
    ffn_hidden: int,
    tokens_per_device: int,
    top_k: int,
    num_devices_list: list,
    bandwidth_gb_per_sec: float = 200,  # NVLink bandwidth
    tflops: float = 150,  # GPU compute throughput
) -> dict:
    """
    Analyze how communication overhead scales with device count.
    """
    results = []

    for num_devices in num_devices_list:
        # Communication: tokens × hidden_dim × 2 (dispatch + combine)
        # Each token sends/receives from other devices
        # Fraction of traffic that crosses device boundaries
        cross_device_fraction = (num_devices - 1) / num_devices

        comm_elements = (
            tokens_per_device * top_k * hidden_dim * 2 * cross_device_fraction
        )
        comm_bytes = comm_elements * 2  # bf16
        comm_time = comm_bytes / (bandwidth_gb_per_sec * 1e9)

        # Computation: expert forward pass
        # FLOPs = 2 * tokens * hidden_dim * ffn_hidden * 2 (two linear layers)
        flops = 2 * tokens_per_device * top_k * hidden_dim * ffn_hidden * 2
        compute_time = flops / (tflops * 1e12)

        efficiency = compute_time / (compute_time + comm_time)

        results.append(
            {
                "num_devices": num_devices,
                "comm_time_ms": comm_time * 1000,
                "compute_time_ms": compute_time * 1000,
                "efficiency": efficiency,
            }
        )

    return results


scaling_results = analyze_scaling_efficiency(
    hidden_dim=4096,
    ffn_hidden=4096 * 4,
    tokens_per_device=4096,
    top_k=2,
    num_devices_list=[2, 4, 8, 16, 32, 64],
    bandwidth_gb_per_sec=25,  # InfiniBand cross-node bandwidth
)
Out[19]:
Console
Expert parallelism scaling efficiency:
 Devices    Comm (ms)   Compute (ms)   Efficiency
--------------------------------------------------
       2        2.684         14.660        84.5%
       4        4.027         14.660        78.5%
       8        4.698         14.660        75.7%
      16        5.033         14.660        74.4%
      32        5.201         14.660        73.8%
      64        5.285         14.660        73.5%
Out[20]:
Visualization
Stacked bar chart with device count on the x-axis and time in milliseconds on the y-axis. Blue bars (computation time) remain constant across device counts while orange bars (communication overhead) grow larger with more devices, illustrating how all-to-all communication becomes the bottleneck at scale.
Time breakdown per MoE layer as device count increases. Communication overhead (orange) grows with the number of devices while computation time (blue) remains constant, as cross-device traffic increases.
Out[21]:
Visualization
Line chart showing scaling efficiency (percentage) on the y-axis against device count on the x-axis. Efficiency starts near 100% for small device counts and curves downward, dropping below 80% at 32 devices, showing diminishing returns from communication overhead in expert parallelism.
Expert parallelism scaling efficiency. Efficiency degrades below 80% at 32 devices as the communication overhead from all-to-all operations begins to dominate the fixed computation time.

Several important insights emerge from this analysis. First, communication overhead grows with the number of devices because more tokens must cross device boundaries. With 2 devices, half the tokens (on average) route to local experts and require no network transfer. With 64 devices, only 1/64 of tokens stay local, meaning the large majority must travel across the network. The cross-device fraction converges to 1 as device count increases, meaning the communication overhead asymptotes at a value determined solely by the bandwidth and the per-token message size.

Second, efficiency remains high when computation dominates, but degrades as we scale to many devices. The efficiency percentages in the table show this degradation clearly: at small device counts the system is nearly compute-bound, but at 32 or 64 devices the communication overhead becomes a significant fraction of total step time. This suggests a practical limit to how far expert parallelism alone can scale before communication becomes the bottleneck. In practice, reaching 64-device expert parallelism with good efficiency requires either extremely fast interconnects (like NVLink at 600+ GB/s) or expert dimensions large enough that computation dominates.

Third, the choice of interconnect has an outsized impact on achievable scale. The analysis above assumes 25 GB/s cross-node InfiniBand bandwidth, which is representative of typical GPU clusters. Higher-bandwidth interconnects like NVLink (used for intra-node GPU communication at up to 600 GB/s on modern systems) can push the efficiency curves significantly upward, letting larger device counts before communication becomes a bottleneck. This is why researchers at organizations with access to tightly-coupled GPU clusters (connected by NVSwitch or similar high-bandwidth fabrics) can afford to use larger expert parallelism configurations than teams relying on commodity networking.