Hyperpod Nccl
AWS LabsOfficialPublished by AWS Labs
- Skill
- Review and audit
- Software development
- Apache-2.0
- Low risk
- Has scripts
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
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/awslabs/hyperpod-nccl/downloadUnzip 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
Collect cluster name, region, namespace/job (EKS), exact NCCL error string.
Run the diagnostic (always — the output drives everything else).
For every
[FAIL]line,Readthe referenced section.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.
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 nodesStep 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-0abc123def456Tags: [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.
| Finding | Section |
|---|---|
| SG missing inbound/outbound self-reference | operations.md § 8 |
| Blocking NetworkPolicy / allow-all missing | operations.md § 8 |
| Slurm node DOWN / DRAINING / RemoveIPC | operations.md § 7 |
| GPU XID / SYSTEM_ERROR / hardware fault | hyperpod-node-debugger § F / § G |
| GPU row-remap / DCGM Fail / silent NaNs | hyperpod-node-debugger § G.1.a/b |
| NCCL timeout / rendezvous / straggler | debugging-guide.md § 1 |
| EFA configuration / not used | debugging-guide.md § 6 |
EFA TCP fallback (NET/OFI Using TCP) | debugging-guide.md § 13 |
| NCCL version mismatch across pods | debugging-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 small | debugging-guide.md § 17 |
| MASTER_ADDR DNS / headless Service | debugging-guide.md § 12 |
| NVLS / PXN / topology tuning | debugging-guide.md § 19 |
| Any NCCL / EFA / rendezvous log pattern | error-patterns-quick-ref.md |
| Performance / nccl-tests / bandwidth | performance-testing.md |
Prerequisites
awsCLI v2.13+ authenticated (aws sts get-caller-identity)jq,python3,bash4.2+unbuffer(from theexpectpackage:yum install expect/apt install expect)kubectlauthenticated to the EKS cluster (K8s checks skipped if absent)session-manager-pluginfor on-node hardware checks
Defaults
Region — required: pass
--regionor 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 10can take ~30 min.CloudWatch window — last 2 hours.
Colors — auto-disabled on non-TTY or
TERM=dumb.
Error handling
| Failure | Script | Tell the customer |
|---|---|---|
aws sts get-caller-identity fails | Exit 1 with the AWS error | "Fix AWS credentials and rerun." |
describe-cluster AccessDenied | Warn, add Missing IAM for sagemaker:DescribeCluster | "Grant sagemaker:DescribeCluster (operations.md § 2)." |
| Cluster not found | Exit 1 after listing region's clusters | "Confirm HyperPod cluster name and region." |
kubectl absent / unauthenticated | Warn, skip K8s checks | "aws eks update-kubeconfig --name <EKS> --region <R>." |
| SSM plugin absent | Warn, 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 found | Skip CloudWatch scan | "Enable CloudWatch on the cluster (operations.md § 4)." |
| Cluster events API throttled | Warn, 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
| Scope | Method | Coverage |
|---|---|---|
| All nodes | sagemaker:ListClusterNodes (paginated) | 100% nodes |
| All K8s objects | kubectl | 100% pods/nodes/policies |
| Hardware | SSM --sample-nodes N (default 3) | Sampled |
| Node logs | CloudWatch | 100% 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
| Need | Use |
|---|---|
| Cluster creation / deployment failures | hyperpod-cluster-debugger (§ A / B / C / H + --validate) |
| Post-deployment cluster-wide management | hyperpod-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 nodes | hyperpod-ssm |
| Version comparison across nodes | hyperpod-version-checker |
| Diagnostic bundle for AWS Support | hyperpod-issue-report |
| MFU / performance degradation | hyperpod-mfu-debugger |
Escalate to AWS Support
Escalate when:
All SG rules correct, EFA verified on-node, but NCCL still times out.
Hardware checks pass on all nodes but AllReduce still hangs.
Issues Found: 0but training still fails.GPU XID errors persist after node replacement.
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.txtfrom step 2 aboveS3 URI of the
hyperpod-issue-reportbundle from step 3NCCL env vars in effect (
printenv | grep -E '^NCCL|^FI_|^TORCH_'from one pod)
References
error-patterns-quick-ref.md — log pattern → code → fix table
debugging-guide.md — per-scenario procedures (21 sections incl. NVLS/PXN/topology)
performance-testing.md — nccl-tests, bandwidth thresholds, straggler detection
operations.md — IAM, SSM format, CloudWatch, env-var reference, node labels, Slurm ops, remediations
Files
- ATTRIBUTION.mdAdded by AutoGineer910 B
- LICENSELicence file added by AutoGineer9.9 KiB
- NOTICELicence file added by AutoGineer89 B
- SKILL.md13.4 KiB
- references/debugging-guide.md47.5 KiB
- references/error-patterns-quick-ref.md10.0 KiB
- references/operations.md18.0 KiB
- references/performance-testing.md9.9 KiB
- scripts/nccl-diagnose.shScript118.6 KiB
references/performance-testing.md
NCCL Performance Testing & Straggler Detection
Measure NCCL bandwidth and identify slow nodes.
Install nccl-tests (once per cluster)
# On each compute node (add to lifecycle script for persistence). Source: NVIDIA nccl-tests.
cd /opt && git clone <nccl-tests-source> nccl-tests
cd /opt/nccl-tests
make MPI=1 MPI_HOME=/usr/local/mpi NCCL_HOME=/usr/local/nccl CUDA_HOME=/usr/local/cuda
# Binary: /opt/nccl-tests/build/all_reduce_perfSingle-Node Baseline Test
Run first to confirm the node itself is healthy before multi-node tests.
# Single-GPU test (quick sanity check):
/opt/nccl-tests/build/all_reduce_perf -b 8 -e 8G -f 2 -g 1
# All-GPU test (p4d: 8 GPUs, p5: 8 GPUs):
/opt/nccl-tests/build/all_reduce_perf -b 8 -e 8G -f 2 -g 8
# Expected output column headers:
# size count type redop root time algbw busbw error time algbw busbwHow to identify stragglers: there is no single published GB/s threshold that applies across EFA generations, NCCL versions, and test message sizes. Run all_reduce_perf on every node against a known-good peer and compare the busbw (bus bandwidth) column. The outliers in the bottom quartile at the same message size are the stragglers. For reference workflow and exact test command, see the AWS EC2 EFA + NCCL getting-started doc. Also compare against the results of a recent known-good run on the same instance type and NCCL version — hardware generations differ widely and a static table rots quickly.
Multi-Node AllReduce Test
# With MPI (from head node):
mpirun -np <TOTAL_RANKS> \
--hostfile /etc/hosts \
-N <RANKS_PER_NODE> \
-x FI_PROVIDER=efa \
-x FI_EFA_USE_DEVICE_RDMA=1 \
-x NCCL_SOCKET_IFNAME=^lo,docker,efa,veth \
-x NCCL_DEBUG=WARN \
/opt/nccl-tests/build/all_reduce_perf -b 8 -e 8G -f 2 -g 1
# With Slurm:
srun --nodes=4 --ntasks-per-node=8 \
/opt/nccl-tests/build/all_reduce_perf -b 8 -e 8G -f 2 -g 1
# With kubectl (EKS, 2 nodes, 8 GPUs each):
# Deploy as a K8s Job with 2 pods, each requesting 8 GPUs.
# Use mpirun inside the container, or the Kubeflow MPI Operator.
kubectl exec -n <NS> <POD> -- mpirun -np 16 -N 8 \
--hostfile /etc/hosts \
-x FI_PROVIDER=efa -x FI_EFA_USE_DEVICE_RDMA=1 \
/opt/nccl-tests/build/all_reduce_perf -b 8 -e 8G -f 2 -g 1Pairwise Bandwidth Test (identify slow pairs)
# Test each node pair individually to find the outlier:
# From node A → node B:
fi_ping -p efa -I 100 <NODE_B_IP>
# From node B → node A:
fi_ping -p efa -I 100 <NODE_A_IP>
# Automate across all pairs (run on head node):
for node in $(scontrol show hostnames $SLURM_JOB_NODELIST); do
echo -n "Testing $node: "
fi_ping -p efa -I 10 "$node" 2>/dev/null | tail -1 || echo "FAILED"
doneInterpreting fi_ping output:
Normal: < 5 microseconds latency, consistent
Straggler: > 50 microseconds, or high variance across runs
NCCL_DEBUG_FILE Analysis
# Enable per-rank debug files:
export NCCL_DEBUG=INFO
export NCCL_DEBUG_FILE=/tmp/nccl_rank${RANK}.log
# After training (or timeout), check which rank was slow:
# Look for the last "AllReduce" timestamp before the timeout:
grep -h "AllReduce\|ring\|timeout" /tmp/nccl_rank*.log | sort -k1,1 | tail -30
# Compare timestamps across ranks — the one furthest behind is the straggler:
for f in /tmp/nccl_rank*.log; do
echo -n "$f: last line timestamp = "
tail -1 "$f" | awk '{print $1, $2}'
doneCollective-op timeout scaling
PyTorch's init_process_group default timeout for NCCL is 10 minutes (600 s). Too low for large clusters — a slow rank or straggler can blow past 10 min during warm-up or a large all-gather.
Scale up via the timeout argument (NOT via a NCCL_TIMEOUT env var — that is not a standard NCCL or PyTorch variable):
import datetime
import torch.distributed as dist
# nodes * 5 + 600 is a simple heuristic — tune against your actual step time:
nodes = int(os.environ.get("WORLD_SIZE", "1")) // 8 # GPUs per node
timeout_s = nodes * 5 + 600
dist.init_process_group(
backend="nccl",
timeout=datetime.timedelta(seconds=timeout_s),
)Field-observed starting points (not AWS- or PyTorch-prescribed; tune from your actual step time and slowest collective):
| Cluster size | Starting point |
|---|---|
| 2–16 GPUs | 600 s (PyTorch default for NCCL) |
| 17–64 GPUs | 1200 s |
| 65–256 GPUs | 1800 s |
| 257–1024 GPUs | 3600 s |
| 1024+ GPUs | 7200 s |
To surface hangs as Python exceptions instead of silently waiting, also set:
export TORCH_NCCL_ASYNC_ERROR_HANDLING=1
export TORCH_NCCL_BLOCKING_WAIT=1 # for debugging; has a perf cost at scaleNCCL_DEBUG=INFO Performance Impact
Never leave NCCL_DEBUG=INFO in production. The NCCL env-var reference describes TRACE as printing "replayable trace information on every call" but does not publish overhead percentages. Field experience on HyperPod is:
| Setting | Notes |
|---|---|
NCCL_DEBUG=WARN (default) | Negligible overhead |
NCCL_DEBUG=INFO | Measurable runtime overhead and verbose logs — disable in production |
NCCL_DEBUG=TRACE | Per-call trace; very large log volume, only for short debugging windows |
Use INFO / TRACE only for debugging, then set back to WARN. Measure your own overhead before and after if it matters for the workload.
EFA Performance Settings
# Full EFA performance configuration:
export FI_PROVIDER=efa
export FI_EFA_USE_DEVICE_RDMA=1 # GPU Direct RDMA
export NCCL_PROTO=Simple # large-message protocol (valid: LL, LL128, Simple)
export NCCL_SOCKET_IFNAME=^lo,docker,efa,veth
# Collective timeout goes in training code: init_process_group(timeout=timedelta(seconds=1800))
# Optional tuning for very large jobs:
export FI_EFA_FORK_SAFE=1 # safe for multiprocessing
export FI_EFA_ENABLE_SHM_TRANSFER=1 # intra-node shared memory
# Do NOT set in production:
# NCCL_DEBUG=INFO (verbose; runtime overhead — disable in production)
# CUDA_LAUNCH_BLOCKING=1 (disables GPU/CPU overlap, very slow)Straggler Node — Detection and Replacement
Detection workflow
Run nccl-tests across all nodes — compare algbw values
Check nvidia-smi nvlink -e for NVLink error counters
Check dmesg for XID errors, hardware failures
Compare fi_ping latency pairwise — outlier has degraded EFA port
Replacement workflow
Diagnose (read-only):
# Identify the bad node's instance ID:
kubectl get node <NODE_NAME> -o jsonpath='{.spec.providerID}' | cut -d'/' -f5
# OR for Slurm — list-cluster-nodes does NOT return PrivateDnsHostname (only describe-cluster-node does).
# Two-step: list candidate IDs, then describe each one until DNS matches the Slurm name.
SLURM_NODE="<SLURM_NODE_NAME>"
for IID in $(aws sagemaker list-cluster-nodes --cluster-name <C> --region <R> \
--query 'ClusterNodeSummaries[?InstanceStatus.Status==`Running`].InstanceId' --output text); do
DNS=$(aws sagemaker describe-cluster-node --cluster-name <C> --region <R> --node-id "$IID" \
--query 'NodeDetails.PrivateDnsHostname' --output text 2>/dev/null)
case "$DNS" in "$SLURM_NODE."*) echo "$SLURM_NODE → $IID"; break ;; esac
doneSuggested command — drain the straggler node before reboot/replace (run this yourself)
Preconditions: straggler behavior confirmed across multiple nccl-tests runs (single-run outliers can be transient — don't drain on one bad sample); customer accepts that pods using emptyDir volumes on this node will lose that data when evicted (EKS path); on Slurm, customer accepts that no new jobs will be scheduled to the node until state=resume runs after recovery; drain is preparation for reboot/replace, not a fix on its own.
Command:
# EKS — cordon prevents new pods; drain evicts existing pods (emptyDir data lost).
kubectl cordon <NODE_NAME>
kubectl drain <NODE_NAME> --ignore-daemonsets --delete-emptydir-data
# Slurm — on the controller via SSM; running jobs continue until they finish.
scontrol update nodename=<NODE> state=drain reason="low-bandwidth-$(date +%Y%m%d)"Blast radius: EKS — --delete-emptydir-data discards emptyDir scratch on this node; pods are rescheduled elsewhere if capacity exists, otherwise stay Pending. Slurm — running jobs finish on the node; pending jobs route around it. Drain is reversible (kubectl uncordon / scontrol update state=resume) only if you decide not to proceed with reboot/replace.
See hyperpod-cluster-debugger § G.2 for the reboot-before-replace ordering.
Suggested command — replace the node (run this yourself, only after reboot did not clear the fault)
Preconditions: reboot was tried first and did not clear the fault (see hyperpod-cluster-debugger § G.2). Data on root + secondary volumes is backed up. Not supported on Slurm controller nodes. NodeIds batch: 1-25 per call.
Command:
aws sagemaker batch-replace-cluster-nodes \
--cluster-name <C> --region <R> \
--node-ids '["<INSTANCE_ID>"]'
# Monitor replacement completion (read-only):
watch -n 10 "aws sagemaker list-cluster-nodes --cluster-name <C> --region <R> \
--query 'ClusterNodeSummaries[*].{ID:InstanceId,State:InstanceStatus.Status}' \
--output table"Blast radius: destroys root + secondary volumes on the replaced instance — all data permanently lost. New hardware is provisioned with the same AMI.
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