Implement Context Parallelism with Kvax
mainKvax supports context parallelism to balance token loads across GPUs and reduce memory consumption. To use it, follow these steps:
- Permute Tokens: Use
permute_tokens_context_parallelismto redistribute input tokens (embeddings, positions, and segment IDs) across the mesh. - Compute Attention: Use the standard
flash_attentionandcreate_attention_maskoperations. - Unpermute Tokens: Use
unpermute_tokens_context_parallelismto restore the original token order for the outputs. - Configure Sharding: Use
attention_specswithin ajax.sharding.Meshcontext to define how query and KV tensors are sharded across the mesh axes.
from kvax.utils import (
permute_tokens_context_parallelism,
unpermute_tokens_context_parallelism,
attention_specs
)
import jax
# 1. Permute input
if self._should_permute_input_tokens:
embeddings, query_positions, query_segment_ids = permute_tokens_context_parallelism(
(embeddings, positions, segment_ids),
)
# ... perform attention operations ...
# 2. Unpermute output
if self._should_permute_input_tokens:
embeddings = unpermute_tokens_context_parallelism(embeddings)
# 3. Setup sharding context
mesh = jax.sharding.Mesh(mesh_devices, mesh_names)
with mesh, attention_specs(
query_specs=("data", "context", None, None),
kv_specs=("data", None, None, None),
):
# Run transformer call
logits = Transformer(...)(embeddings, positions, segment_ids)