Generated banner for Hyperpod Nccl
Generated logo for Hyperpod Nccl

Hyperpod Nccl

AWS LabsOfficialPublished by AWS Labs

  • Skill
  • Review and audit
  • Software development
  • Apache-2.0
  • Low risk
  • Has scripts

From the author

Diagnose NCCL failures and adjacent training-pod failures on HyperPod GPU clusters (EKS or Slurm) — training hangs, AllReduce / collective-op timeouts, EFA or libfabric errors, rendezvous failures, EFA TCP fallback, /dev/shm or memlock issues, NCCL version mismatch across pods, container OOM / exit-137 / OOMKilled, GPU OOM (CUDA out of memory), CrashLoopBackOff / Pending pods, MASTER_ADDR DNS, NetworkPolicy blocking. Not for single-node hardware faults (→ hyperpod-node-debugger § G) or cluster-creation EFA / SSM failures (→ hyperpod-cluster-debugger § A / § F).
— the description by AWS Labs

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

The hyperpod-nccl skill provides a structured, read-only diagnostic workflow for identifying and resolving NCCL and training-pod failures on SageMaker HyperPod clusters (EKS or Slurm). It uses a diagnostic script to analyze infrastructure state, pod logs, and network configurations, mapping identified issues to specific remediation procedures in the provided documentation. The skill emphasizes safe, non-destructive investigation, requiring user approval for any suggested remediation commands.

What it does

  • Automates the collection of cluster, region, and job-specific diagnostic data.
  • Identifies common NCCL failures including timeouts, rendezvous issues, and EFA errors.
  • Detects pod-level issues such as OOMKilled, container crashes, and DNS resolution failures.
  • Maps detected failures to specific, actionable remediation sections in the documentation.
  • Provides a standardized process for escalating unresolved issues to AWS Support.
  • Supports both EKS and Slurm orchestrators with environment-specific diagnostic checks.

When to use it

  • When training jobs hang or experience collective-op timeouts.
  • When encountering EFA, libfabric, or network-related communication errors.
  • When pods fail to start or enter CrashLoopBackOff states.
  • When investigating GPU-related errors like CUDA out of memory or hardware faults.
  • When troubleshooting rendezvous or NCCL version mismatch issues across pods.

Advantages

  • Provides a systematic, read-only approach to complex distributed training debugging.
  • Reduces manual effort by automatically mapping log patterns to known fixes.
  • Ensures safe operations by requiring user approval for all suggested commands.
  • Integrates with existing HyperPod documentation for consistent troubleshooting.
  • Facilitates efficient escalation to AWS Support with pre-formatted diagnostic bundles.

Usage examples

“Run a diagnostic on my EKS HyperPod cluster named 'my-cluster' in 'us-west-2' for a specific job.”
The agent executes the diagnostic script scoped to the provided cluster, region, and job, outputting a list of findings with references to remediation guides.
“I am seeing NCCL timeouts on my Slurm cluster. How do I investigate?”
The agent guides you to run the diagnostic script with the --orchestrator slurm flag and provides instructions on how to interpret the [FAIL] results using the remediation index.

Install

  1. Download the skill as a ZIP:

    https://autogineer.com/agent-skills/awslabs/hyperpod-nccl/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip hyperpod-nccl.zip -d .agents/skills

Documentation by AWS Labs

HyperPod NCCL Debugger

Operating policy. Run read-only diagnostics yourself. Never run a command that changes cluster, node, or workload state — present each one as a Suggested command (run this yourself) block and wait for the customer. Destructive order: investigate → reboot → replace (replace destroys root + secondary volumes; not supported on Slurm controller nodes). Never discard training state on speculation.

Diagnose NCCL failures on SageMaker HyperPod (EKS and Slurm). scripts/nccl-diagnose.sh reads state via AWS APIs, kubectl, and SSM, then prints each issue as [FAIL] ... → references/<file>.md § <section>. Read-only.

Signal sourcing: list-cluster-events carries infrastructure-level state only (lifecycle, bootstrap, EFA health check, capacity, replacement, reboot, AMI rollback). It does not carry NCCL timeouts, GPU XID/ECC, or per-pod training signals — those come from pod logs, CloudWatch training streams, on-node SSM probes, and NCCL env audit. "No events" on a training-time NCCL issue is expected, not a clean bill of health.


Workflow

  1. Collect cluster name, region, namespace/job (EKS), exact NCCL error string.

  2. Run the diagnostic (always — the output drives everything else).

  3. For every [FAIL] line, Read the referenced section.

  4. Present finding, root cause, and the Suggested-command block with concrete values (instance IDs, SG IDs, namespaces) filled in from the script output. Wait for customer approval.

  5. Re-run the diagnostic to confirm.

If a finding has no matching section, report it as a bug — do not invent a fix.

Step 1: Authenticate kubectl (EKS)

EKS_ARN=$(aws sagemaker describe-cluster --cluster-name <HYPERPOD-NAME> --region <REGION> \
  --query 'Orchestrator.Eks.ClusterArn' --output text)
EKS_NAME=$(echo "$EKS_ARN" | awk -F'/' '{print $NF}')
aws eks update-kubeconfig --name "$EKS_NAME" --region <REGION>
kubectl get nodes

Step 2: Run the diagnostic

# Basic:
bash scripts/nccl-diagnose.sh --cluster <HYPERPOD-NAME> --region <REGION>

# Scope to an EKS job/namespace:
bash scripts/nccl-diagnose.sh --cluster <NAME> --region <REGION> --namespace <NS> --job <JOB>

# Force orchestrator:
bash scripts/nccl-diagnose.sh --cluster <NAME> --region <REGION> --orchestrator slurm

# Larger hardware sample (default 3):
bash scripts/nccl-diagnose.sh --cluster <NAME> --region <REGION> --sample-nodes 10

# Specific node only:
bash scripts/nccl-diagnose.sh --cluster <NAME> --region <REGION> --node i-0abc123def456

Tags: [PASS] · [FAIL] (counted in Issues Found, has reference pointer) · [WARN] · [INFO]. Priorities: P0 blocks training · P1 degraded · P2 informational.


Remediation index

Each [FAIL] line in the script already points directly at the right section. This table is a lookup for manual triage.

FindingSection
SG missing inbound/outbound self-referenceoperations.md § 8
Blocking NetworkPolicy / allow-all missingoperations.md § 8
Slurm node DOWN / DRAINING / RemoveIPCoperations.md § 7
GPU XID / SYSTEM_ERROR / hardware faulthyperpod-node-debugger § F / § G
GPU row-remap / DCGM Fail / silent NaNshyperpod-node-debugger § G.1.a/b
NCCL timeout / rendezvous / stragglerdebugging-guide.md § 1
EFA configuration / not useddebugging-guide.md § 6
EFA TCP fallback (NET/OFI Using TCP)debugging-guide.md § 13
NCCL version mismatch across podsdebugging-guide.md § 10
Container OOM (pod killed, exit 137)debugging-guide.md § 4
GPU OOM (CUDA out of memory)debugging-guide.md § 11
RDMA memlock / /dev/shm too smalldebugging-guide.md § 17
MASTER_ADDR DNS / headless Servicedebugging-guide.md § 12
NVLS / PXN / topology tuningdebugging-guide.md § 19
Any NCCL / EFA / rendezvous log patternerror-patterns-quick-ref.md
Performance / nccl-tests / bandwidthperformance-testing.md

Prerequisites

  • aws CLI v2.13+ authenticated (aws sts get-caller-identity)

  • jq, python3, bash 4.2+

  • unbuffer (from the expect package: yum install expect / apt install expect)

  • kubectl authenticated to the EKS cluster (K8s checks skipped if absent)

  • session-manager-plugin for on-node hardware checks

Defaults

  • Region — required: pass --region or set $AWS_DEFAULT_REGION.

  • Orchestrator — auto-detected; override with --orchestrator eks|slurm.

  • Namespace / job (EKS) — all namespaces; scope with --namespace <NS> --job <JOB>.

  • Hardware sampling — 3 nodes over SSM (capped at 50). --node <ID> for a specific node. Node probes run serially (180 s per node): --sample-nodes 10 can take ~30 min.

  • CloudWatch window — last 2 hours.

  • Colors — auto-disabled on non-TTY or TERM=dumb.

Error handling

FailureScriptTell the customer
aws sts get-caller-identity failsExit 1 with the AWS error"Fix AWS credentials and rerun."
describe-cluster AccessDeniedWarn, add Missing IAM for sagemaker:DescribeCluster"Grant sagemaker:DescribeCluster (operations.md § 2)."
Cluster not foundExit 1 after listing region's clusters"Confirm HyperPod cluster name and region."
kubectl absent / unauthenticatedWarn, skip K8s checks"aws eks update-kubeconfig --name <EKS> --region <R>."
SSM plugin absentWarn, skip on-node hardware checks"Install session-manager-plugin."
SSM times out (180s)Partial output, mark node unreachable"Rerun with --node <ID> --sample-nodes 1; check SSM agent on the node."
CloudWatch log group not foundSkip CloudWatch scan"Enable CloudWatch on the cluster (operations.md § 4)."
Cluster events API throttledWarn, continue with partial data"Rerun later — script is idempotent."

Exit codes: 0 diagnostic complete · 1 fatal prerequisite missing or cluster unreachable.

IAM permissions

Full policy + RBAC in operations.md § 2. SSM on HyperPod uses start-session against sagemaker-cluster:<cluster-id>_<group>-<iid> targets — grant ssm:StartSession / ssm:TerminateSession, not ssm:SendCommand.

Scale strategy

ScopeMethodCoverage
All nodessagemaker:ListClusterNodes (paginated)100% nodes
All K8s objectskubectl100% pods/nodes/policies
HardwareSSM --sample-nodes N (default 3)Sampled
Node logsCloudWatch100% nodes

Large clusters: the PyTorch NCCL backend defaults to a 10-minute collective-op timeout (per the PyTorch distributed docs). Large clusters routinely exceed that on first rendezvous; raise it via torch.distributed.init_process_group(timeout=timedelta(seconds=<N>)). HyperPod support has also observed NCCL topology-graph-search hangs on 256+ node clusters when memlock is unlimited; using a large fixed memlock (e.g. 8388608) in pod securityContext or /etc/security/limits.conf has cleared these in field cases. This memlock pattern is a field observation, not AWS- or NCCL-documented behavior.

For FSDP, DeepSpeed, or Megatron-LM tuning: debugging-guide.md § 18.

Skill delegation

NeedUse
Cluster creation / deployment failureshyperpod-cluster-debugger (§ A / B / C / H + --validate)
Post-deployment cluster-wide managementhyperpod-cluster-debugger
Per-node issues (disk, lifecycle, hardware)hyperpod-node-debugger
Trainium/Inferentia collective-comm (AWS Neuron Collectives, not NCCL)hyperpod-node-debugger § G.2
Shell on nodeshyperpod-ssm
Version comparison across nodeshyperpod-version-checker
Diagnostic bundle for AWS Supporthyperpod-issue-report
MFU / performance degradationhyperpod-mfu-debugger

Escalate to AWS Support

Escalate when:

  1. All SG rules correct, EFA verified on-node, but NCCL still times out.

  2. Hardware checks pass on all nodes but AllReduce still hangs.

  3. Issues Found: 0 but training still fails.

  4. GPU XID errors persist after node replacement.

  5. Collective-op timeout raised and memlock workaround applied but large-cluster rendezvous still hangs.

Before opening the case
# 1. Cluster identity + status
aws sagemaker describe-cluster --cluster-name <C> --region <R>

# 2. Full NCCL diagnostic (sample more nodes for escalation)
bash scripts/nccl-diagnose.sh --cluster <C> --region <R> --sample-nodes 10 > nccl-diag.txt

# 3. Per-node log/config bundle to S3 (delegates to hyperpod-issue-report)
#    See skills/hyperpod-issue-report/SKILL.md for the exact invocation.
Include in the case
  • Cluster name + ARN and AWS region

  • Orchestrator (EKS or Slurm) and EKS cluster name / Slurm controller node

  • Timestamp window (UTC start / end) of the failure

  • Exact NCCL / libfabric error strings (copy verbatim from pod logs or journalctl)

  • Affected instance IDs / node names / pod names / namespace / job name

  • nccl-diag.txt from step 2 above

  • S3 URI of the hyperpod-issue-report bundle from step 3

  • NCCL env vars in effect (printenv | grep -E '^NCCL|^FI_|^TORCH_' from one pod)

References

Files

references/debugging-guide.md

NCCL HyperPod — Detailed Debugging Guide

Detailed procedures for each failure type. See SKILL.md for the quick reference.

Table of Contents

#SectionKey Symptoms
1NCCL Timeout / Rendezvous HangTraining hangs, AllReduce stuck, rendezvous timeout
2Security Group Self-Reference RulesNCCL always times out, new cluster
3NCCL_SOCKET_IFNAME — Interface SelectionWrong NIC, binding to eth0 instead of EFA
4Container OOM (exit code 137)OOMKilled, exit code 137
5Wrong Results — Gradient SyncLoss not converging, inconsistent results
6EFA ConfigurationEFA not working, slow training, FI_PROVIDER
7Node Hardware FailuresXID errors, ECC, NVLink errors
8Slurm-Specific ProceduresSlurm batch script, node management, RemoveIPC
9NCCL RAS — Live Job HealthLive health query, straggler detection
10NCCL Version MismatchNCCL function not found, mixed images
11GPU OOM — CUDA out of memorycudaMalloc failed, VRAM exhausted
12DNS Resolution FailureName or service not known, headless service
13EFA TCP FallbackNET/OFI Using TCP, 10x slower
14GPU P2P Access Blocked (ACS)P2P not supported, intra-node slow
15Stale Shared Memory/dev/shm/nccl-* errors, RemoveIPC
16Host Firewall Blocking NCCLiptables DROP/REJECT
17RDMA Memory Registration Failureibv_reg_mr failed, memlock
18Distributed Training FrameworksFSDP, DeepSpeed, Megatron-LM tuning
19Advanced NCCL TuningNVLS, PXN, topology, cross-NIC
20Pending / CrashLoopBackOff / Init-Container FailuresPods stuck Pending, init containers failing
21GPU Row-Remap / DCGM HealthSilent NaNs, pending row-remap, DCGM false-Pass

1. NCCL Timeout / Rendezvous Hang

Always start minimal: Reproduce with 2 ranks and torch.ones(100) before debugging full training.

import os, torch, torch.distributed as dist, datetime
rank = int(os.environ.get('RANK', 0))
world_size = int(os.environ.get('WORLD_SIZE', 2))
master = os.environ.get('MASTER_ADDR', 'localhost')
port  = os.environ.get('MASTER_PORT', '29500')
dist.init_process_group('gloo',
    init_method=f'tcp://{master}:{port}',
    world_size=world_size, rank=rank,
    timeout=datetime.timedelta(seconds=120))
t = torch.ones(100) * rank
dist.all_reduce(t, op=dist.ReduceOp.SUM)
expected = sum(range(world_size))
assert t[0].item() == expected, f"Got {t[0].item()}, expected {expected}"
print(f"[Rank {rank}] [PASS] AllReduce PASSED", flush=True)
dist.destroy_process_group()

Debug env vars:

export NCCL_DEBUG=INFO              # verbose NCCL output
export NCCL_DEBUG_SUBSYS=ALL        # all subsystems
export TORCH_DISTRIBUTED_DEBUG=DETAIL
export TORCH_NCCL_ASYNC_ERROR_HANDLING=1    # surface NCCL timeouts as exceptions
export NCCL_DEBUG_FILE=/tmp/nccl_rank${RANK}.log
# Extend PyTorch collective timeout in training code:
#   dist.init_process_group("nccl", timeout=timedelta(seconds=1800))

Dump call stack of hung process:

# Inside the pod (EKS):
kubectl exec -n <ns> <pod> -- pip install py-spy -q
kubectl exec -n <ns> <pod> -- py-spy dump --pid $(pgrep -f python | head -1)

# On the node via SSM (both orchestrators):
aws ssm start-session --target sagemaker-cluster:<CLUSTER_ID>_<GROUP>-<INSTANCE_ID>
# On node:
py-spy dump --pid $(pgrep -f python | head -1)
py-spy record -o /tmp/profile.svg --pid <PID> --duration 30

Root cause matrix:

Timeout fires whenRoot causeFix
Before init completesSG missing self-ref / NetworkPolicyFix SG or remove blocking NetworkPolicy
Before init completesWrong MASTER_ADDR / DNS failureFix headless service; use <job>-0.<svc>.<ns>.svc.cluster.local
Before init completesWORLD_SIZE > actual podsMatch WORLD_SIZE to spec.completions
After init, during AllReduceOne rank crashed (OOM/CUDA)Check pod logs for exit code 137
After init, during AllReduceStraggler node (slow NIC)Run nccl-tests, drain slow node
On large cluster (128+ nodes)PyTorch collective timeout too low (default 10 min for NCCL)Raise via init_process_group(timeout=timedelta(seconds=<N>)); nodes*5+600 is a starting heuristic, not a guarantee

Slurm MASTER_ADDR setup (no headless service needed — Slurm resolves hostnames natively):

# In your sbatch script:
export MASTER_ADDR=$(scontrol show hostnames $SLURM_JOB_NODELIST | head -1)
export MASTER_PORT=29500
# Verify DNS works from all nodes:
srun --overlap bash -c "nslookup $MASTER_ADDR"

For 100+ node clusters — prioritized fix order:

  1. Extend the PyTorch collective timeout (default: 10 min for NCCL, per the PyTorch distributed docs). Example starting value: init_process_group(timeout=timedelta(seconds=<N>)) where N is tuned from your observed step time. nodes*5+600 is a starting heuristic only.

  2. Check memlock — see Section 17 (field-observed workaround for topology-search hangs on 256+ node clusters).

  3. Run straggler detection — see references/performance-testing.md pairwise bandwidth test.

  4. Check for NCCL version drift after rolling node replacements — see Section 10


2. Security Group Self-Reference Rules

Commands and verification are in operations.md § 8. Without inbound + outbound self-reference on the cluster SG, NCCL rendezvous and EFA RDMA traffic are dropped.


3. NCCL_SOCKET_IFNAME — Interface Selection

On EFA nodes (p4d/p5), always set explicitly:

# Correct for EFA nodes — exclude non-VPC interfaces:
export NCCL_SOCKET_IFNAME=^lo,docker,efa,veth,virbr

# Find the correct VPC interface name:
ip -br addr show | grep -vE "^lo|docker|br-|virbr|veth|efa" | grep UP | awk '{print $1}'

Validate the setting works (leaves at least one interface):

# After setting NCCL_SOCKET_IFNAME, verify it leaves interfaces:
PATTERN="${NCCL_SOCKET_IFNAME#^}"
ip -br addr show | grep UP | awk '{print $1}' | \
  grep -vE "$(echo "$PATTERN" | tr ',' '|')"
# Must show at least one interface (e.g., ens5)

Also set matching MPI variable:

export OMPI_MCA_btl_tcp_if_include=ens5   # match your VPC ENI
# OR:
export OMPI_MCA_btl_tcp_if_exclude=lo,docker0,virbr0

4. Container OOM — Pod Killed Mid-Training (exit code 137)

Symptom: Pod status = OOMKilled, exit code 137. The Linux kernel killed the process due to cgroup memory limit. This is different from GPU OOM (see section 11).

Detect:

# EKS: check container termination reason
kubectl describe pod <POD> -n <NS> | grep -A5 "Last State:"
# Shows: Reason: OOMKilled, Exit Code: 137

# On node via SSM:
dmesg | grep -i "oom\|killed process" | tail -10
free -h

Fix options (in order of impact):

# 1. Gradient checkpointing (most impact, slower backward pass)
model.gradient_checkpointing_enable()

# 2. FSDP (shard model across all GPUs in job)
from torch.distributed.fsdp import FullyShardedDataParallel as FSDP
model = FSDP(model, device_id=torch.cuda.current_device())

# 3. Mixed precision (halve activation memory)
from torch.cuda.amp import autocast, GradScaler
scaler = GradScaler()
with autocast():
    loss = model(inputs)

# 4. Reduce batch size
batch_size = batch_size // 2  # halve until OOM resolves
# Increase K8s memory limits:
resources:
  limits:
    memory: "64Gi"   # increase as needed
    nvidia.com/gpu: "8"

5. Wrong Results — Gradient Sync Issues

Verify AllReduce is actually happening:

def check_allreduce_consistency(tensor, name, rank, world_size):
    """Verify all ranks have same values after AllReduce."""
    dist.all_reduce(tensor, op=dist.ReduceOp.SUM)
    results = [None] * world_size
    dist.all_gather_object(results, tensor.sum().item())
    if rank == 0:
        if len(set(round(r, 4) for r in results)) > 1:
            print(f"[FAIL] INCONSISTENT '{name}': {results}", flush=True)
        else:
            print(f"[PASS] CONSISTENT '{name}': {results[0]:.4f}", flush=True)

Check FSDP/DTensor placements:

from torch.distributed.tensor import DTensor
for name, param in model.named_parameters():
    if isinstance(param, DTensor):
        print(f"[Rank {dist.get_rank()}] {name}: placements={param.placements}")
    else:
        print(f"[Rank {dist.get_rank()}] {name}: NOT sharded (unexpected for FSDP)")

Print from all ranks in order (debugging):

def print_all_ranks(msg):
    for r in range(dist.get_world_size()):
        if dist.get_rank() == r:
            print(f"[Rank {r}] {msg}", flush=True)
        dist.barrier()

6. EFA Configuration

Required for full performance on p4d/p5:

export FI_PROVIDER=efa
export FI_EFA_USE_DEVICE_RDMA=1     # GPU Direct RDMA
export NCCL_SOCKET_IFNAME=^lo,docker,efa,veth
export NCCL_PROTO=Simple            # large-message protocol (valid: LL, LL128, Simple)
# Collective timeout is a PyTorch arg — set via init_process_group(timeout=timedelta(seconds=1800))

K8s pod spec for EFA:

resources:
  limits:
    vpc.amazonaws.com/efa: <N>   # match EFA device count for the instance type
  requests:
    vpc.amazonaws.com/efa: <N>
Suggested command — install EFA K8s device plugin (run this yourself)

Preconditions: EKS orchestrator with GPU nodes (p4d / p5 / p5e / p5en / p6); node AMI already has EFA kernel modules (verify fi_info -p efa returns endpoints on one node); cluster admin has approved installing a daemonset into kube-system. If EFA is already allocated to pods (pod limits.vpc.amazonaws.com/efa > 0), the plugin is already installed — skip.

Command:

helm repo add eks <aws-eks-charts-helm-repo>
helm install aws-efa-k8s-device-plugin --namespace kube-system \
  eks/aws-efa-k8s-device-plugin

Blast radius: installs a daemonset on every node in kube-system (one pod per node) that advertises vpc.amazonaws.com/efa as a schedulable resource. Cannot be removed by a single command — requires helm uninstall. Interacts with every GPU-scheduling pod; misconfiguration can starve pods of EFA resources.

Verify EFA on node:

fi_info -p efa                              # lists EFA endpoints
cat /opt/amazon/efa_installed_packages      # EFA installer version
lsmod | grep efa                            # kernel module loaded
ls /dev/infiniband/uverbs*                  # device files exist
nvidia-smi nvlink --status                  # NVLink (p4d/p5)

7. Node Hardware Failures

NCCL errors caused by GPU / EFA hardware faults (Xid errors, ECC, NVLink, off-bus) are diagnosed and remediated in the node-debugger skill: hyperpod-node-debugger § G (GPU/Accelerator) and § F (Hardware / Auto-Repair).

Get the instance ID from a K8s node name:

kubectl get node <NODE_NAME> -o jsonpath='{.spec.providerID}' | cut -d'/' -f5
Suggested command — drain before reboot/replace (EKS) (run this yourself)

Preconditions: hardware fault confirmed on <NODE_NAME> (XID/ECC/NVLink/off-bus — see hyperpod-node-debugger § G); customer accepts that pods using emptyDir volumes on this node will lose that data when evicted; drain is preparation for batch-reboot-cluster-nodes (try first) or batch-replace-cluster-nodes — not a fix on its own. See hyperpod-cluster-debugger § G.2.

Command:

kubectl cordon <NODE_NAME>
kubectl drain <NODE_NAME> --ignore-daemonsets --delete-emptydir-data

Blast radius: --delete-emptydir-data discards emptyDir scratch on this node (training caches, ephemeral checkpoints not persisted to PVC//opt/sagemaker); pods are rescheduled elsewhere if capacity exists, otherwise stay Pending. Drain is reversible (kubectl uncordon) only if you decide not to proceed with reboot/replace.


8. Slurm-Specific Procedures

NCCL batch script template:

#!/bin/bash
#SBATCH --nodes=4
#SBATCH --ntasks-per-node=1
#SBATCH --gpus-per-node=8
#SBATCH --job-name=nccl-training

# EFA settings (p4d/p5):
export FI_PROVIDER=efa
export FI_EFA_USE_DEVICE_RDMA=1
export NCCL_SOCKET_IFNAME=^lo,docker,efa,veth
export NCCL_DEBUG=WARN
# Set the PyTorch collective timeout in training code, not via env:
#   dist.init_process_group("nccl", timeout=timedelta(seconds=1800))

# Rendezvous (torchrun manages RANK/WORLD_SIZE automatically):
export MASTER_ADDR=$(scontrol show hostnames $SLURM_JOB_NODELIST | head -1)
export MASTER_PORT=29500

srun torchrun \
  --nnodes=$SLURM_NNODES \
  --nproc_per_node=8 \
  --rdzv_backend=c10d \
  --rdzv_endpoint=$MASTER_ADDR:$MASTER_PORT \
  train.py

Slurm node management and the RemoveIPC=no requirement are in operations.md § 7.


9. NCCL RAS — Live Job Health

NCCL's RAS (Reliability, Availability, Serviceability) subsystem lets you query the state of a running NCCL job without attaching a debugger. Per the NCCL env-var reference, RAS is available since NCCL 2.24 and is enabled by default (NCCL_RAS_ENABLE=1); the listen address is configured via NCCL_RAS_ADDR. Confirm the actual port your build uses (it can be overridden by env or NCCL config) before assuming the example port number below.

# Find the RAS port for the running NCCL process (configurable via NCCL_RAS_ADDR):
#   - Check the env of the training process:
#       cat /proc/$(pgrep -f python | head -1)/environ | tr '\0' '\n' | grep NCCL_RAS_ADDR
#   - Or check what's listening locally:
#       ss -ltnp | grep -i nccl

# Example (replace <PORT> with the actual RAS port for your build):
echo "verbose status" | nc -w 3 localhost <PORT>

# With the ncclras binary :
ncclras -v
ncclras -f json | python3 -m json.tool   
ncclras -m                              

# Inside a K8s pod:
kubectl exec -n <NS> <POD> -- sh -c "echo 'verbose status' | nc -w 3 localhost <PORT>"

Interpret status:

  • RUNNING OK — all ranks alive, progressing normally

  • MISMATCH — some ranks behind → possible straggler

  • INCOMPLETE — missing rank data → one rank unresponsive

  • DEAD / PEER_DEAD — a rank process is confirmed dead → this is the rank that hung the collective


10. NCCL Version Mismatch (NCCL function not found)

Symptom: NCCL function not found or Incompatible NCCL version at job startup. Cause: Different NCCL builds across nodes — mixed container images or manual installs.

Diagnose:

# Check NCCL version per running pod:
for pod in $(kubectl get pods -n <NS> -l job-name=<JOB> --no-headers | awk '{print $1}'); do
    echo -n "$pod: "
    kubectl exec -n <NS> "$pod" -- \
        python3 -c "import torch; print(torch.cuda.nccl.version())" 2>/dev/null \
        || echo "unavailable"
done

# Check via library file:
kubectl exec -n <NS> <POD> -- \
    find /usr/local/cuda/lib64 /usr/lib -name "libnccl.so*" 2>/dev/null | head -3

# Check CUDA driver version per node:
kubectl get nodes -o custom-columns=\
'NAME:.metadata.name,DRIVER:.metadata.labels.nvidia\.com/cuda\.driver-version' \
2>/dev/null || kubectl get nodes -o wide

Fix:

# All pods in a job MUST use identical container images.
# Verify your job spec uses the same image for all replicas:
kubectl get pod -n <NS> -l job-name=<JOB> \
    -o jsonpath='{range .items[*]}{.metadata.name}: {.spec.containers[0].image}{"\n"}{end}'
# Every line must show the same image:tag

# If different, update your job spec to pin every replica to the same image:
# spec.template.spec.containers[0].image: <AWS DLC image URI from your region's DLC account>
# e.g. an AWS Deep Learning Container pytorch-training image tagged for your CUDA + Python + OS combo

Common cause on HyperPod: Rolling node replacement installs a new AMI with a different NCCL version while old nodes are still in the cluster. Use lifecycle scripts to pin NCCL versions.


11. GPU OOM — CUDA out of memory / cudaMalloc failed

Symptom: CUDA out of memory, cudaMalloc failed, or RuntimeError: CUDA error: out of memory. This is GPU VRAM exhaustion — distinct from container OOMKill (section 4). The process does NOT get killed by the kernel; PyTorch raises a Python exception.

Diagnose:

# Check GPU memory usage on all GPUs:
kubectl exec -n <NS> <POD> -- \
    nvidia-smi --query-gpu=index,name,memory.used,memory.total,utilization.gpu \
    --format=csv,noheader

# In training script — add before suspected OOM:
import torch
for i in range(torch.cuda.device_count()):
    used = torch.cuda.memory_allocated(i) / 1e9
    reserved = torch.cuda.memory_reserved(i) / 1e9
    total = torch.cuda.get_device_properties(i).total_memory / 1e9
    print(f"GPU {i}: allocated={used:.1f}GB reserved={reserved:.1f}GB total={total:.1f}GB")
    print(torch.cuda.memory_summary(i))

Fix options (in order of impact):

# 1. Gradient checkpointing — trade compute for memory (most impactful)
model.gradient_checkpointing_enable()

# 2. ZeRO optimizer — shard optimizer states across ranks (DeepSpeed)
# In deepspeed config:
# "zero_optimization": {"stage": 3}   # ZeRO-3: shards params, grads, optimizer states

# 3. FSDP — shard model weights across all GPUs
from torch.distributed.fsdp import FullyShardedDataParallel as FSDP
model = FSDP(model)

# 4. Mixed precision — halve activation memory
from torch.cuda.amp import autocast
with autocast(dtype=torch.bfloat16):
    loss = model(inputs)

# 5. Reduce batch size — simplest fix
batch_size = batch_size // 2

# 6. Clear cache between steps (if fragmentation is the issue)
torch.cuda.empty_cache()

Memory fragmentation fix:

# If OOM happens after many steps (fragmentation):
import gc
gc.collect()
torch.cuda.empty_cache()
# Or: set PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True

12. DNS Resolution Failure (Name or service not known)

Symptom: Name or service not known, getaddrinfo failed, or rendezvous hangs forever. Cause: MASTER_ADDR hostname cannot be resolved. Common on EKS when no headless Service is in place to give pods a stable DNS name.

Diagnose:

# Check DNS from inside a pod:
kubectl exec -n <NS> <POD> -- nslookup $MASTER_ADDR
kubectl exec -n <NS> <POD> -- getent hosts $MASTER_ADDR

# Check if headless service exists:
kubectl get svc -n <NS> -o wide | grep None
# Should show: ClusterIP: None with selector matching training pods

# Check CoreDNS is healthy:
kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl logs -n kube-system -l k8s-app=kube-dns --tail=20

Fix:

# Create headless service for training job DNS:
apiVersion: v1
kind: Service
metadata:
  name: my-training-svc
  namespace: <NS>
spec:
  clusterIP: None
  selector:
    app: my-training-job   # must match training pod labels
  ports:
  - port: 29500
    name: nccl-rendezvous
# Set MASTER_ADDR using the service DNS:
export MASTER_ADDR="<job-name>-0.<service-name>.<namespace>.svc.cluster.local"

13. EFA TCP Fallback (NET/OFI Using TCP)

Symptom: In NCCL_DEBUG=INFO output, you see NET/OFI Using TCP instead of NET/OFI Using EFA. Training runs but at 10-100x lower bandwidth than expected.

Diagnose:

# Check if EFA device plugin is installed:
kubectl get daemonset -A | grep -i efa

# Check if pod requests EFA:
kubectl get pod <POD> -n <NS> -o jsonpath='{.spec.containers[0].resources.limits}'
# Must include: vpc.amazonaws.com/efa

# Check EFA env vars:
kubectl exec -n <NS> <POD> -- env | grep FI_

# Check on node via SSM:
fi_info -p efa  # Must list EFA endpoints

Fix checklist:

  1. Install the EFA K8s device plugin — see the Suggested-command block earlier in this file (§ EFA device plugin).

  2. Request EFA in pod spec:

    resources:
      limits:
        vpc.amazonaws.com/efa: <N>   # match EFA device count for the instance type
  3. Set EFA env vars in the pod:

    export FI_PROVIDER=efa
    export FI_EFA_USE_DEVICE_RDMA=1
    export NCCL_SOCKET_IFNAME=^lo,docker,efa,veth
  4. Ensure the aws-ofi-nccl plugin is in the container image (find /opt/amazon -name "libnccl-net.so" 2>/dev/null).


14. GPU P2P Access Blocked (ACS/IOMMU)

Symptom: NCCL WARN P2P not supported between dev X and dev Y or peer access is not supported. Intra-node AllReduce is 10-50x slower because GPU Direct P2P transfers are blocked by PCI ACS.

Diagnose:

# Check ACS on node via SSM:
lspci -vvv 2>/dev/null | grep -A20 "PCI bridge" | grep "ACSCtl:"
# If "SrcValid+" appears → ACS is enabled → P2P blocked

# Check IOMMU:
dmesg | grep -i iommu
grep -oE "intel_iommu=[^ ]+" /proc/cmdline

# Check P2P topology:
nvidia-smi topo -m
# NV# = NVLink (fast), PIX/PXB/PHB = PCIe (slow)
Suggested command — disable ACS on NVIDIA GPU bridges (last resort; run this yourself)

Preconditions: P2P GPU traffic confirmed to fall back to CPU hops via nvidia-smi topo -m; GPU peer-to-peer blocked by PCIe ACS (ACSCtl: SrcValid+ observed via lspci -vvv); confirmed the node is single-tenant (training workload only); you have reviewed that this weakens IOMMU isolation for the affected PCI bridges. Do NOT apply to multi-tenant or security-sensitive hosts.

Command:

# Disable ACS on NVIDIA GPU upstream bridges only — scoping to 10de: avoids
# weakening IOMMU isolation on unrelated PCI devices.
for BDF in $(lspci -D -d 10de: | awk '{print $1}'); do
  sudo setpci -s "$BDF" ECAP_ACS+0x6.w=0000 2>/dev/null
done

# For persistence, add the same NVIDIA-only scope to the lifecycle script:
echo 'for BDF in $(lspci -D -d 10de: | awk "{print \$1}"); do setpci -s $BDF ECAP_ACS+0x6.w=0000 2>/dev/null; done' \
  >> /opt/ml/scripts/on_create.sh

Blast radius: host-wide PCIe change for every NVIDIA GPU bridge on the node — takes effect immediately and persists for the life of the OS (or until the lifecycle script is re-run after a reboot). IOMMU isolation for those bridges is reduced, which is acceptable on a dedicated training host but NOT acceptable on multi-tenant hosts. If applied incorrectly, reboot restores the default ACS state unless the lifecycle-script change was made.


Symptom: unlink shared memory /dev/shm/nccl-* failed: No such file or new training job fails with File exists on /dev/shm/nccl-* files left by a previous crash.

Cause: Either systemd RemoveIPC=yes (default on RHEL/Amazon Linux) deletes NCCL shm mid-training, or a crashed training process left orphaned shm files.

Diagnose:

# Check on node:
ls -la /dev/shm/nccl-*
grep RemoveIPC /etc/systemd/logind.conf
Suggested command — clean stale shm and disable RemoveIPC (run this yourself)

Preconditions: no NCCL training job is currently running on this node (ps aux | grep -E 'python.*torchrun|mpirun' returns empty); RemoveIPC=yes confirmed in /etc/systemd/logind.conf; brief systemd-logind restart is acceptable on this node.

Command:

# 1. Clean up stale files
rm -f /dev/shm/nccl-*

# 2. Prevent systemd from deleting shm mid-training
echo "RemoveIPC=no" >> /etc/systemd/logind.conf
sudo systemctl restart systemd-logind

# 3. For persistence across replacements, add to the lifecycle script:
echo 'echo "RemoveIPC=no" >> /etc/systemd/logind.conf && systemctl restart systemd-logind' \
  >> /opt/ml/scripts/on_create.sh

Blast radius: rm -f /dev/shm/nccl-* silently destroys any active NCCL shared-memory segments — running a collective at the same time will fail. RemoveIPC=no is a persistent systemd change; the systemctl restart logs out anyone in a systemd user session. Lifecycle-script edit persists across node replacements.


16. Host Firewall Blocking NCCL (iptables/nftables)

Symptom: NCCL timeout even though SG rules and NetworkPolicy are correct. Root cause: host-level iptables or nftables DROP/REJECT rules blocking NCCL ports.

Diagnose:

# On node via SSM:
iptables -L -n | grep -E "DROP|REJECT"
nft list ruleset 2>/dev/null | grep -E "drop|reject"
Suggested command — adjust host firewall to allow NCCL traffic (run this yourself)

Preconditions: identified a specific iptables/nftables rule blocking NCCL traffic via iptables -L -n --line-numbers; confirmed the rule is not managed by kube-proxy (those typically appear in the KUBE-* chains — never delete those) or the VPC CNI; customer has approved either deleting the specific rule or adding an explicit ACCEPT rule for NCCL ports.

Command (preferred — add explicit allow rather than touch existing rules):

# Allow NCCL rendezvous port range:
iptables -I INPUT -p tcp --dport 29400:29500 -j ACCEPT
# Allow the NCCL RAS port if RAS is enabled and used (read your NCCL_RAS_ADDR setting):
# iptables -I INPUT -p tcp --dport <NCCL_RAS_PORT> -j ACCEPT

Command (alternative — delete a specific custom rule by line number):

iptables -L -n --line-numbers   # confirm the line number first
iptables -D INPUT <rule_number>

Blast radius: iptables -I INPUT ... -j ACCEPT adds a rule at the top of the INPUT chain — host-wide effect, cleared on reboot unless persisted via iptables-save. Deleting a rule by line number is precise but irreversible without the original rule definition; capture iptables-save first if you may need to roll back. Never run iptables -F on an EKS worker — it flushes kube-proxy's service rules and VPC CNI NetworkPolicy enforcement, breaking pod networking cluster-wide.


17. RDMA Memory Registration Failure (ibv_reg_mr failed)

Symptom: NCCL WARN Call to ibv_reg_mr failed followed by EFA falling back to TCP — training continues but at 10-100x lower bandwidth.

Cause: The Linux memlock limit prevents the EFA driver from pinning memory for RDMA DMA transfers. With memlock=0 or very low values, EFA cannot register any memory buffers.

Diagnose:

# Check current memlock limit:
ulimit -l
# Should be: unlimited or ≥8388608 (8GB in KB)
# If 0 or 64 → FAIL

# Check on the actual node via SSM:
aws ssm start-session --target sagemaker-cluster:<CLUSTER_ID>_<GROUP>-<INSTANCE_ID>
# On node:
ulimit -l
cat /proc/$(pgrep -f python | head -1)/limits | grep "Max locked"

# In NCCL debug output (NCCL_DEBUG=INFO):
# "NCCL WARN Call to ibv_reg_mr failed, got error (12)" → errno 12 = ENOMEM (memlock)
Suggested command — raise memlock for EFA RDMA (run this yourself)

Preconditions: ulimit -l confirmed at 0 / 64 / very low on the affected node; Call to ibv_reg_mr failed confirmed in NCCL/EFA logs; customer accepts a session/login change (immediate path) or a persistent change to /etc/security/limits.conf (permanent path); for K8s pods the change must be applied in the pod spec, not on the node.

Command — immediate (session only, lost on logout):

ulimit -l 8388608       # 8 GB in KB

Command — permanent (system-wide):

echo "* soft memlock 8388608" >> /etc/security/limits.conf
echo "* hard memlock 8388608" >> /etc/security/limits.conf
# Requires re-login to take effect.

# For Slurm:
echo "ulimit -l 8388608" >> /etc/slurm/prolog.sh

Pod spec (K8s) — required for containerized training:

securityContext:
  capabilities:
    add: ["IPC_LOCK"]
# A high memlock limit on the host is not visible inside the container without
# IPC_LOCK; without this capability, the pod still hits memlock=0 / very low.

Blast radius: session ulimit affects only the current login shell. /etc/security/limits.conf change persists across reboots and applies to every user who logs in afterwards. Slurm prolog change applies to every job step launched after the edit. K8s pod-spec change is per-pod. For HyperPod, replication across replacement nodes requires baking the limits.conf change into the lifecycle script.

Note — field observation on large clusters (not NCCL- or AWS-documented): HyperPod support has seen NCCL topology-graph-search failures on 256+ node clusters when memlock is set to unlimited. Using a large fixed value (e.g. 8388608) instead of unlimited has cleared these in field cases. If you hit this, engage AWS Support with the NCCL topology-search failure output.

Verify fix worked:

# After fix, NCCL_DEBUG=INFO should show:
# "NCCL INFO NET/OFI Using EFA RDMA" (not TCP fallback)
# No more "ibv_reg_mr failed" warnings

# Check effective bandwidth after fix:
/opt/nccl-tests/build/all_reduce_perf -b 1G -e 8G -f 2 -g 1
# Should match expected algbw for your instance type

18. Distributed Training Frameworks — NCCL Tuning

NCCL issues often surface differently depending on the distributed training framework. Framework-specific guidance:

FSDP (Fully Sharded Data Parallel — PyTorch native)

Common NCCL issues with FSDP:

SymptomCauseFix
Hang at _init_intra_and_inter_node_groupsNCCL can't form process groupsCheck MASTER_ADDR, MASTER_PORT, firewall rules, and headless service (EKS)
OOM during FSDP wrappingAll-gather materializes full paramsUse sharding_strategy=FULL_SHARD, enable cpu_offload if needed
Slow FSDP training vs DDPExcessive all-gather/reduce-scatterTune limit_all_gathers=True, increase forward_prefetch=True
NCCL watchdog timeout during checkpointingDistributed checkpoint blocks NCCLUse StateDictType.SHARDED_STATE_DICT for async checkpoint save

Recommended NCCL env vars for FSDP on HyperPod:

export NCCL_SOCKET_IFNAME=^lo,docker
export FI_PROVIDER=efa
export FI_EFA_USE_DEVICE_RDMA=1
export NCCL_ALGO=Ring           # Ring is generally better for FSDP all-gather patterns
export NCCL_PROTO=Simple        # Simple protocol for large-message FSDP comms
# FSDP checkpoint can be slow at scale — extend the PyTorch collective timeout:
#   dist.init_process_group("nccl", timeout=timedelta(seconds=1800))
DeepSpeed

Common NCCL issues with DeepSpeed:

SymptomCauseFix
RuntimeError: NCCL communicator was abortedTimeout during ZeRO all-gatherExtend PyTorch collective timeout via init_process_group(timeout=...); check for straggler nodes
OOM with ZeRO Stage 3Parameter partitioning + NCCL buffersReduce stage3_max_live_parameters, enable offload_optimizer
Slow DeepSpeed init on 100+ nodesSequential NCCL group creationSet TORCH_NCCL_ASYNC_ERROR_HANDLING=1 (the older NCCL_ASYNC_ERROR_HANDLING was renamed to the TORCH_NCCL_* namespace in recent PyTorch; check your PyTorch's torch.distributed env-var docs); increase init_timeout in ds_config
ncclInternalError with pipeline parallelismCross-node P2P failsEnsure NCCL_P2P_LEVEL=NVL for intra-node, check EFA for inter-node

DeepSpeed config tuning for HyperPod:

{
  "comms_config": {
    "comms_backend": "nccl",
    "timeout": 1800
  },
  "zero_optimization": {
    "stage": 3,
    "stage3_max_live_parameters": 1e8,
    "stage3_prefetch_bucket_size": 5e7,
    "reduce_bucket_size": 5e8
  }
}
Megatron-LM

Common NCCL issues with Megatron-LM:

SymptomCauseFix
Hang at initialize_model_parallelNCCL group creation fails across nodesVerify world size = TP * PP * DP, check network connectivity
Slow tensor-parallel matmulNCCL all-reduce on small tensors is inefficientIncrease TP group size to stay intra-node (TP ≤ GPUs/node)
Pipeline bubble > 40%PP schedule inefficiencyReduce PP stages, increase micro-batches, try interleaved schedule
ncclGroupEnd failed during 3D parallelismToo many simultaneous NCCL groupsCap NCCL channel count for memory-constrained setups — use NCCL_MAX_CTAS=2 (replaces the older NCCL_MAX_NCHANNELS, deprecated in NCCL 2.17)

Megatron-LM parallelism mapping for HyperPod:

Rule of thumb:
  TP (tensor parallel) = within a single node (8 GPUs on p5)
  PP (pipeline parallel) = across nodes (minimizes cross-node comms volume)
  DP (data parallel) = remaining nodes

  World size = TP × PP × DP
  Example: 32 p5.48xlarge (256 GPUs)
    TP=8, PP=4, DP=8 → 8×4×8 = 256

19. Advanced NCCL Tuning (NVLS, PXN, Topology, Cross-NIC)

NVLS is NVIDIA's in-network aggregation over NVLink. Per the NCCL env-var reference, NCCL_NVLS_ENABLE defaults to 2 (since NCCL 2.17), meaning NVLS is enabled when supported. It speeds up small-message AllReduce on H100/H200 nodes but requires matching driver and container versions — driver/container mismatch is a common cause of NVLS-related hangs in field cases.

Symptoms:

  • Hang inside ncclAllReduce on p5/p5e/p5en

  • NCCL INFO ... NVLS ... failed

  • Fine on 1 node, hang on 2+ nodes

Diagnosis:

# Check NCCL version (container side)
python3 -c "import torch; print(torch.cuda.nccl.version())"
# Check driver version (node side, via SSM)
nvidia-smi --query-gpu=driver_version --format=csv

Mitigations:

  1. Disable NVLS temporarily to isolate:

    export NCCL_NVLS_ENABLE=0
  2. Pin NCCL version across all pods/jobs (match container image digest, not tag).

  3. Upgrade the NVIDIA driver on the AMI via UpdateClusterSoftware if the container expects a newer driver.

PXN — P2P Cross-NUMA (p5.48xlarge optimal config)

PXN lets NCCL route inter-node traffic via an intermediary GPU on a different NUMA node to maximize NIC utilization. The documented PXN env var is NCCL_P2P_PXN_LEVEL (since NCCL 2.12), which controls PXN usage for send/receive — default is 2 (always use PXN); set 0 to disable. There are also NCCL_PXN_DISABLE and NCCL_PXN_C2C knobs; consult the NCCL env-var reference for the version in use.

NCCL_CROSS_NIC defaults to 2 (per the NCCL docs: "Try to use the same NIC for the same ring/tree, but still allow for the use of different NICs if it would result in a better performance") — leave at default unless you've measured a regression.

# Tuning knobs — measure before/after with nccl-tests:
export NCCL_P2P_PXN_LEVEL=2     # default; 0 disables PXN

# Channel count: NCCL_MIN_NCHANNELS / NCCL_MAX_NCHANNELS were deprecated in
# NCCL 2.17 in favor of NCCL_MIN_CTAS / NCCL_MAX_CTAS (per NCCL env-var docs).
# Both names still work on recent versions.
export NCCL_MIN_CTAS=4

If these cause regressions on smaller jobs (< 16 nodes), unset and re-measure with the defaults.

NCCL_TOPO_FILE — Custom Topology

NCCL auto-discovers topology on p-family instances and usually picks the right plan. Use a custom topology file only when:

  • Running in containers that hide the PCIe topology from NCCL

  • Using an instance type NCCL doesn't recognize

  • Debugging suboptimal ring/tree selection

To export the topology NCCL sees for manual inspection:

export NCCL_TOPO_DUMP_FILE=/tmp/nccl-topo.xml
# Run any NCCL op (e.g., all_reduce_perf), then inspect /tmp/nccl-topo.xml

Do not ship a hand-edited topology file unless you've confirmed the default is wrong — this is an advanced-user escape hatch.

NCCL_SOCKET_FAMILY — IPv4 Forcing

Dual-stack environments (IPv6 enabled on the VPC but IPv4 intended for NCCL) can cause silent TCP fallback. Force IPv4:

export NCCL_SOCKET_FAMILY=AF_INET
Mixed instance families

Mixing different P-family generations in a single NCCL communicator (e.g. p4d + p5) is risky — the topology and EFA adapter counts differ, which can cause NCCL algorithm-selection issues. If you need to do this, measure carefully with nccl-tests first; otherwise launch separate jobs per instance family.

NCCL_COLLNET_ENABLE on EFA

NCCL_COLLNET_ENABLE=1 enables NVIDIA's Collective Network (CollNet) protocol, used with SHARP on InfiniBand fabrics. EFA is not InfiniBand and does not provide a SHARP-compatible CollNet provider, so leaving CollNet enabled on EFA can lead to wasted init time or fallback. If a job script sets NCCL_COLLNET_ENABLE=1, set it to 0 for HyperPod EFA clusters:

export NCCL_COLLNET_ENABLE=0
Instance family EFA counts (reference)

Counts from authoritative AWS sources where available. Always confirm live with ls /dev/infiniband/uverbs* | wc -l on the node — instance counts vary across firmware revisions.

Instance typeExpected EFA count
p5.48xlarge32
p5e.48xlarge32
p5en.48xlarge16
p4d.24xlarge4

For other EFA-supported types (p4de, p5.4xlarge, trn1, trn1n, trn2, etc.), check the current EC2 instance-types doc rather than hard-coding a value here. Mismatch with the live count → EFA driver not loaded, or a subset of NICs didn't attach at boot. Reboot via batch-reboot-cluster-nodes first; replace if reboot doesn't recover.


20. Pending / CrashLoopBackOff / Init-Container Failures

Pod lifecycle failures surface as Pending, CrashLoopBackOff, or stuck in an init container. These are NOT NCCL bugs per se — they block the NCCL job from starting. Diagnose in this order:

Pending pods
# Why is it pending?
kubectl describe pod <POD> -n <NS> | sed -n '/Events:/,$p' | head -40

Common reasons and where to fix:

Event messageRoot causeWhere to fix
0/N nodes are available: N Insufficient <resource>Not enough CPU/mem/GPU freeWait for other jobs, or scale the cluster
0/N nodes are available: N node(s) didn't match Pod's node affinity/selectorAffinity/selector too strictFix nodeSelector / nodeAffinity in the pod spec
0/N nodes are available: N node(s) had untolerated taintTaints on HyperPod nodes (check kubectl describe node <N> for the exact taint key)Add matching tolerations to the pod spec
failed to create pod sandbox: ... CNIVPC CNI problemDelegate to hyperpod-node-debugger § O
MountVolume.SetUp failed for volumePVC binding issueCheck PVC status, StorageClass, EBS/FSx availability
ImagePullBackOff / ErrImagePullContainer image pull failedCheck ECR pull permissions on the node role; check image URI; confirm VPC endpoint for ECR if in private subnet
(no events; just stuck)Scheduler starved or no matching poolkubectl get events -A --sort-by=.lastTimestamp | tail -50 for cluster-wide scheduler state
CrashLoopBackOff
kubectl logs <POD> -n <NS> --previous | tail -100   # logs from the crashed container
kubectl describe pod <POD> -n <NS>                   # last termination state + exit code

Map the exit code to the guide section:

Exit codeMeaningSection
137 (OOMKilled)Container OOM§ 4 Container OOM
143 (SIGTERM)Liveness probe failed or graceful terminationCheck liveness probe; check preceding SIGTERM in logs
139 (SIGSEGV)Segfault — often CUDA / driver mismatch§ 10 NCCL Version Mismatch
1 / 2 / otherApplication errorRead kubectl logs --previous for the app-level error
Stuck in init container
kubectl get pod <POD> -n <NS> -o jsonpath='{.status.initContainerStatuses}' | python3 -m json.tool
kubectl logs <POD> -n <NS> -c <INIT_CONTAINER_NAME>

Common init-container failures:

  • Fetching model weights from S3 — check IAM, VPC endpoint, bucket policy.

  • Downloading dataset — DNS / network / auth.

  • Running a chown/chmod on a large volume — timeout.

  • Waiting for another pod (headless service / init-container-as-gate pattern) — the dependency pod never became Ready.

Remediation is always customer-driven

None of these states have a one-command fix. Walk the customer through the diagnosis above, identify the specific cause, then apply the targeted fix. Do not kubectl delete pods without understanding why.


21. GPU Row-Remap / DCGM Health (Marginal Memory Silent Degrader)

When NCCL aborts or training accuracy regresses without matching Xid/ECC counts — sporadic NaNs, intermittent AllReduce hangs, DCGM default medium,memtest passes but a GPU is silently returning bad data — the cause is usually a pending row-remap or a marginal GPU that DCGM's combined-run is masking.

Diagnosis procedure, remap state table, DCGM split-run workaround, and escalation bundle (nvidia-bug-report.sh + /var/log/nvidia-dcgm/) are in the node-debugger skill: hyperpod-node-debugger § G.1.a/b.

Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Needs: Needs a command-line tool, Needs Python, Needs Node.js

Security

What our scanner noticed· Low risk

  • Instructions that use the network
  • Scripts that your agent may run

This skill includes scripts that your agent may run. Read them before you use it.

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Published by
AWS Labs
Publisher
AWS Labs (Official)
Source
awslabs/agent-plugins · plugins/sagemaker-ai/skills/hyperpod-nccl · commit fbefb37
Licence
Apache License 2.0 (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE)
  • NOTICE (added by AutoGineer from NOTICE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by AWS Labs or AWS Labs.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download hyperpod-nccl.zip