Megatron Internals II: Column/Row Parallel Linear and Vocab Parallel Embedding
Tensor parallelism is not “split every tensor somehow.” In Megatron, it is a small set of layer contracts: which dimension is local, which collective completes the dense math, and which gradient path communicates.
The original Megatron-LM paper is still the cleanest starting point: split transformer matrix multiplies so each GPU does useful dense GEMM, then communicate only where the algebra requires it.
This post walks the implementation-level contracts behind ColumnParallelLinear, RowParallelLinear, VocabParallelEmbedding, and parallel cross entropy.
TL;DR
ColumnParallelLinearsplits output features. Forward can leave output shards local; backward all-reduces input gradients.RowParallelLinearsplits input features. Forward all-reduces partial outputs; backward can keep input-gradient shards local.- The common
fandgoperators are identity in one direction and all-reduce in the other direction. - Attention uses column-parallel QKV, local heads, and a row-parallel output projection.
- The MLP uses column-parallel expansion, local activation, and row-parallel contraction.
VocabParallelEmbeddingshards vocabulary rows and all-reduces embeddings, so no rank stores the full table.- Vocab-parallel cross entropy reduces max, denominator, and target logit instead of all-gathering full logits.
- For the rank groups underneath these layers, start with Megatron Internals I. For the broader tensor-parallel overview, see Tensor Parallelism in Megatron.
1. Why tensor parallelism lives inside layers
A transformer block is mostly matrix multiplication, but different matrix dimensions have different meanings. For a linear layer:
| |
you can split W two obvious ways:
- split columns: each rank owns different output features;
- split rows: each rank owns different input features and computes a partial sum.
Both are useful. Neither works as a generic wrapper around arbitrary modules because the next layer must know whether it receives a full tensor or a shard. That is why Megatron implements tensor parallelism in custom modules rather than trying to shard an already-built dense model.
2. The two autograd operators
Megatron papers describe two conceptual operators:
They are not magic math. They are custom autograd communication placements whose job is to avoid gather-scatter noise between adjacent layers. If a tensor is already sharded in the layout the next operation wants, keep it sharded. If the algebra needs a sum across shards, all-reduce exactly there.
3. ColumnParallelLinear
Column parallelism splits the output dimension:
Every TP rank receives the full input X.
Each rank owns one column shard of W.
Each rank computes one output-feature shard.
A minimal sketch:
The forward mode depends on the consumer.
If the next operation can consume sharded activations, Megatron leaves Y_i local.
If a non-parallel consumer needs the full hidden dimension, it all-gathers.
Backward needs the sum:
| |
Each rank can compute one partial dX. The full input gradient is the all-reduce of those partials. That is the backward side of f.
4. RowParallelLinear
Row parallelism splits the input dimension:
Each rank receives or creates one input-feature shard. It computes a partial output with the full output dimension. Then the TP group all-reduces those partial outputs.
A minimal sketch:
The communication moved from backward to forward. That is g: forward all-reduce, backward identity.
5. Why the column/row pair is efficient
The transformer MLP has an expansion and a contraction:
Megatron computes the dense-equivalent result as:
No approximation is introduced.
The intermediate Z_i stays sharded.
That matters because Z is usually several times wider than the hidden state.
Gathering it between the two MLP projections would burn memory and bandwidth for no algebraic reason.
This is the pattern you should look for in tensor-parallel code:
- split where independent work exists;
- keep the large intermediate local;
- reduce when the math becomes a sum.
6. Parallel self-attention
Attention uses the same contracts. A typical attention block computes:
Megatron makes the QKV projection column-parallel. Each rank owns a subset of attention heads. Those heads can run attention locally because heads are independent once Q, K, and V are formed. The output projection is row-parallel and all-reduces the head contributions back into the hidden dimension.
The sequence is:
- full hidden state enters the block;
- column-parallel QKV creates local head shards;
- attention runs locally on those heads;
- row-parallel output projection all-reduces partial hidden states.
This is why head counts must divide cleanly by TP size. Grouped-query attention changes how K/V heads are shared, but the same question remains: which heads are local, and where does the hidden dimension need a sum?
7. VocabParallelEmbedding
The embedding table can be one of the largest tensors in a language model:
| |
Megatron shards it by vocabulary rows. Each TP rank owns a contiguous token-id range. Every rank receives the token ids, masks out ids outside its range, looks up local rows, zeros the non-owned positions, and all-reduces the result.
Sketch:
Only the rank that owns a token contributes a non-zero vector. The all-reduce is cheaper than keeping the full embedding table and optimizer state on every TP rank.
8. Vocab-parallel cross entropy
The output projection mirrors the input embedding. Each rank produces logits for its vocabulary shard. The naive move is to all-gather logits and run ordinary cross entropy. That is usually the wrong move.
Cross entropy needs only three global quantities per token:
- the global maximum logit for numerical stability;
- the global sum of exponentials;
- the target logit for the true token id.
The stable algorithm is:
- compute local max over local vocab logits;
- all-reduce max across TP ranks;
- subtract global max and exponentiate local logits;
- all-reduce the denominator;
- pick the target logit only on the rank that owns the target token;
- reduce that target logit;
- compute loss and local vocab gradients.
This avoids a batch * sequence * vocab all-gather.
For large vocabularies, that is the difference between a normal output layer and a memory wall.
9. Backward-pass audit table
When reviewing a tensor-parallel module, write the forward and backward communication down explicitly:
| Module | Forward communication | Backward communication |
|---|---|---|
ColumnParallelLinear | Optional all-gather | All-reduce dX |
RowParallelLinear | All-reduce output | Usually none for sharded dX |
VocabParallelEmbedding | All-reduce embeddings | Gradients stay with owned vocab rows |
VocabParallelCrossEntropy | Max, denominator, target-logit reductions | Local vocab gradients plus small reductions |
This table also explains why activation checkpointing with TP must restore both RNG state and tensor layout. The recomputed forward pass must produce the same shard shapes as the original forward pass. Otherwise backward collectives run on the wrong tensors.
10. The useful mental model
Megatron tensor parallelism is dense math with local shards. It works because the split dimensions match the algebra:
- column split means independent output features;
- row split means partial sums over input features;
- vocab split means independent token-id rows;
- parallel cross entropy means reducing the few global scalars the loss actually needs.
The code looks complicated because it must handle sequence parallelism, async communication, fused kernels, and initialization. The core idea is still small: keep tensors sharded while the next operation can consume the shard, and communicate only when the dense equation requires a concat or a sum.
Code
- Megatron tensor-parallel layers:
megatron/core/tensor_parallel/layers.py. - Tensor-parallel communication mappings and custom autograd functions:
megatron/core/tensor_parallel/mappings.py. - Vocab-parallel cross entropy:
megatron/core/tensor_parallel/cross_entropy.py. - Full tensor-parallel package:
megatron/core/tensor_parallel/. - Megatron process groups used by these layers:
megatron/core/parallel_state.py.
References
- Shoeybi et al., Megatron-LM: Training Multi-Billion Parameter Language Models Using Model Parallelism, 2019.
- Narayanan et al., Efficient Large-Scale Language Model Training on GPU Clusters Using Megatron-LM, 2021.
- Vaswani et al., Attention Is All You Need, NeurIPS 2017.
- Korthikanti et al., Reducing Activation Recomputation in Large Transformer Models, 2022.