Skip to content

Cookbook — Distributed

1. Initialize a process group

Intent: Set up NCCL communication across ranks.

from SneppX_ALG import init_process_group, destroy_process_group, get_world_size, get_rank

init_process_group(backend="nccl")      # reads WORLD_SIZE/RANK env vars
print(get_rank(), "/", get_world_size())
# ... train ...
destroy_process_group()

Notes: With WORLD_SIZE=1, init_process_group is a no-op. Needs libnccl on PATH/LD_LIBRARY_PATH. CPU-safe as a pass-through.

2. Launch multi-GPU from a single script

Intent: One process per GPU, no torchrun.

from SneppX_ALG import launch

def main():
    # your training function
    ...

if __name__ == "__main__":
    launch(main, num_nodes=1, num_gpus=2)

Notes: launch spawns torch.distributed.run under the hood when num_nodes * num_gpus > 1; otherwise it calls main() directly.

3. Wrap a model for DDP

Intent: Gradient-sync data parallelism.

from SneppX_ALG import Transformer, DistributedWrapper

model = Transformer(vocab_size=1000, dim=256, num_heads=4, num_layers=4, ffn_dim=1024, max_seq_len=128)
model = DistributedWrapper(model, device="cuda", sync_bn=False)
for x, y in loader:
    loss = model(x)
    loss.backward()
    model.sync_gradients()      # all-reduce grads / world_size
    opt.step()

Notes: DistributedWrapper keeps the inner .module accessible. CPU-safe: sync_gradients is a no-op when world_size <= 1.

4. Shard data with DistributedSampler

Intent: Each rank sees a disjoint slice of the dataset.

from SneppX_ALG import TensorDataset, DistributedSampler
from SneppX_ALG.interface_bindings.data_loader import DataLoader

sampler = DistributedSampler(dataset, num_replicas=get_world_size(), rank=get_rank(), shuffle=True)
loader  = DataLoader(dataset, batch_size=32, sampler=sampler)
sampler.set_epoch(epoch)      # re-shuffle each epoch

Notes: DataLoader itself is in interface_bindings.data_loader (not re-exported via *). CPU-safe.

5. ZeRO with FSDP (shard optimizer + grad + params)

Intent: Fit a 7B model on 4× GPUs by sharding everything.

from SneppX_ALG import FullyShardedDataParallel, FSDPConfig, ShardingStrategy, MixedPrecision

cfg  = FSDPConfig(
    sharding=ShardingStrategy.FULL_SHARD,           # ZeRO-3 equivalent
    mixed_precision=MixedPrecision(param="bf16", reduce="fp32"),
)
model = FullyShardedDataParallel(base_transformer, cfg)

Notes: ShardingStrategy options: FULL_SHARD (ZeRO-3), SHARD_GRAD_OS (ZeRO-2), NO_SHARD (ZeRO-0). The C core mirror is kernel/distributed/zero.c.

6. Barrier + all-reduce

Intent: Synchronize or reduce across ranks.

from SneppX_ALG import barrier, all_reduce, Tensor

barrier()                                   # all ranks rendezvous
acc = all_reduce(loss_tensor, op="sum")    # sum across ranks

7. Expert parallelism (MoE dispatch)

Intent: Route tokens to experts across devices.

from SneppX_ALG import SERModel, SERConfig

cfg = SERConfig(); cfg.num_experts = 32; cfg.num_active = 2
# With EP, experts are sharded across the expert-parallel group; see
# algorithms/ser/core/ + net/distributed/nccl.c for the all-to-all dispatch.
moe = SERModel(cfg, seed=0, num_layers=1)

Notes: EP size is derived as num_experts / tp_size. The all-to-all is handled by SNEPPX_alltoall in the NCCL layer. GPU + NCCL required.

8. Elastic training (node joins/leaves)

Intent: Elastic fault tolerance.

from SneppX_ALG import ElasticTrainer

trainer = ElasticTrainer(max_restarts=3, restart_delay=5)
trainer.fit(train_fn, num_nodes=2, num_gpus=4)
# on a node failure: ranks re-shard, checkpoints roll forward