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://mp-staging.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.

Download ZIP

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