Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Use when adapting PyTorch training or evaluation code for distributed/multi-GPU, TPU, or mixed-precision runs with HuggingFace Accelerate: emit the current API idiom (Accelerator/prepare/backward, the mixed_precision kwarg, accumulate, gather_for_metrics, save_state, accelerate launch) — the exact calls cheaper models emit in wrong or outdated forms.
.claude/skills/huggingface-accelerate/SKILL.md| Model | Eval pass | Runs |
|---|---|---|
| gemini-3.6-flash | 100% | 1 |
| Model | Lift | Δ tokens | Δ turns | Cases | Verified |
|---|---|---|---|---|---|
| gemini-3.6-flashbest | 0% | +157% | 0% | 24 | 54d ago |
| gemini-3.5-flash | pending re-run | — | |||
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-09 | ✗→✓ | ▲ Improved | — | — |
| case-15 | ✗→✓ | ▲ Improved | — | — |
| case-19 | ✓→✓ | = Same ✓ | — | — |
| case-16 | ✓→✓ | = Same ✓ | — | — |
| case-01 | ✗→✗ | = Same ✗ | — | — |
Enforces the current HuggingFace Accelerate public API when you adapt a PyTorch training or evaluation script for distributed, multi-GPU, TPU, or mixed-precision execution. Apply whenever the task is to make PyTorch training run on more than one device, add mixed precision or gradient accumulation, do distributed evaluation, or write distributed-safe checkpoints with Accelerate.
from accelerate import Accelerator, then accelerator = Accelerator(). One instance drives the whole script; create it before you prepare anything.
prepare() wraps everything. Pass every training object — model, optimizer, eachdataloader (train and validation), and the LR scheduler — into a single accelerator.prepare(...) call, and unpack the return in the SAME order: model, optimizer, dataloader, scheduler = accelerator.prepare(model, optimizer, dataloader, scheduler). Do not reach for per-object helpers like prepare_model(...) / prepare_data_loader(...) in normal use — the single prepare() is the idiom.
prepare(), never call loss.backward(). Useaccelerator.backward(loss) — it scales gradients (for fp16) and picks the correct backend backward (DDP/DeepSpeed/Megatron).
.to("cuda"), .cuda(), and .to(device) on themodel and on batches — prepare() and the prepared dataloader place them for you. If you genuinely need a device handle, use accelerator.device, never the literal string "cuda" or torch.device("cuda").
Accelerator(mixed_precision="fp16") (or "bf16", or "fp8"). NOT Accelerator(fp16=True) (that argument was removed), and NOT a hand-built torch.cuda.amp.GradScaler + autocast. To cast a block computed OUTSIDE the model, wrap it in with accelerator.autocast():.
Accelerator(gradient_accumulation_steps=N), then wrap the per-step body in with accelerator.accumulate(model):. Do not hand-roll if (step + 1) % N == 0 with a manually divided loss.
gather_for_metrics. Before computing a metric acrossprocesses, collect with accelerator.gather_for_metrics((predictions, targets)) — not raw torch.distributed.all_gather / dist.gather (which also leaves padding duplicates in).
accelerator.save_state(dir) andaccelerator.load_state(dir).
accelerator.wait_for_everyone(), thenunwrapped = accelerator.unwrap_model(model) and save unwrapped, guarding the write with if accelerator.is_main_process:. Never torch.save(model.state_dict()) on every rank without unwrapping first.
prepare(), clip withaccelerator.clip_grad_norm_(...) (or clip_grad_value_), not torch.nn.utils.clip_grad_norm_.
from accelerate.utils import set_seed, then set_seed(42)— it seeds every process/backend consistently. torch.manual_seed alone does not.
accelerator.print(...) (or guard with accelerator.is_main_process) so aline is not duplicated once per process.
python. Run accelerate config once to generate the reusableconfig (a default_config.yaml), then accelerate launch train.py. When not using a saved config, pass flags: --multi_gpu, --num_processes=N, --num_machines=N, --machine_rank=R, --main_process_ip=IP, --mixed_precision=fp16, --config_file=PATH. Do NOT document python train.py or python -m torch.distributed.launch as the launch path.
BEFORE = the base model's wrong default → AFTER = the conforming Accelerate idiom.
Core migration.
python# BEFORE device = "cuda" model.to(device) for batch in dataloader: batch = batch.to(device) optimizer.zero_grad() loss = model(batch).mean() loss.backward() optimizer.step() # AFTER from accelerate import Accelerator accelerator = Accelerator() model, optimizer, dataloader = accelerator.prepare(model, optimizer, dataloader) for batch in dataloader: optimizer.zero_grad() loss = model(batch).mean() accelerator.backward(loss) optimizer.step()
Mixed precision.
python# BEFORE accelerator = Accelerator(fp16=True) # removed argument # BEFORE (hand-rolled) scaler = torch.cuda.amp.GradScaler() # AFTER accelerator = Accelerator(mixed_precision="fp16") # or "bf16" / "fp8"
Gradient accumulation.
python# BEFORE for i, batch in enumerate(dataloader): loss = model(batch).mean() / 4 loss.backward() if (i + 1) % 4 == 0: optimizer.step(); optimizer.zero_grad() # AFTER accelerator = Accelerator(gradient_accumulation_steps=4) for batch in dataloader: with accelerator.accumulate(model): loss = model(batch).mean() accelerator.backward(loss) optimizer.step(); optimizer.zero_grad()
Distributed metric gather.
python# BEFORE torch.distributed.all_gather(gathered, preds) # AFTER all_preds, all_targets = accelerator.gather_for_metrics((preds, targets))
Checkpointing.
python# BEFORE torch.save(model.state_dict(), "model.pt") # every rank, wrapped model # AFTER (resumable state) accelerator.save_state("ckpt/") # ... accelerator.load_state("ckpt/") # AFTER (final export) accelerator.wait_for_everyone() if accelerator.is_main_process: torch.save(accelerator.unwrap_model(model).state_dict(), "model.pt")
Launch.
bash# BEFORE torchrun --nproc_per_node=8 train.py # AFTER accelerate config # once, interactive accelerate launch --multi_gpu --num_processes=8 train.py
prepare() as well, soeach process gets its shard; then use gather_for_metrics when scoring.
save_state is called on ALL processes, not only the main one — it coordinates internally. Onlythe model-export write and human-facing logging are guarded by is_main_process.
accelerator.backward — you never builda GradScaler yourself.
autocast() is usually unnecessary because backward already handles the loss; usewith accelerator.autocast(): only for extra mixed-precision work outside the model.
prepare()and accelerator.backward(loss) stay identical; you select the backend via accelerate config (or a plugin passed to Accelerator), not by rewriting the training code.
torchrun still works, but the documented Accelerate path is accelerate launch; prefer it.loss.backward() after prepare(). ALWAYS call accelerator.backward(loss)..to("cuda") / .cuda() on model or batches. ALWAYS let prepare() place them (useaccelerator.device if you truly need one).
Accelerator(fp16=True). ALWAYS write Accelerator(mixed_precision="fp16").% N. ALWAYS use gradient_accumulation_steps +with accelerator.accumulate(model):.
torch.distributed.all_gather. ALWAYS use gather_for_metrics.torch.save(model.state_dict()) on every rank. ALWAYS unwrap_model + is_main_process, orsave_state/load_state.
python -m torch.distributed.launch. ALWAYS use accelerate launch (afteraccelerate config).
loss.backward() after wrapping the model.model.to("cuda") and batch.to("cuda") in the loop.fp16=True flag or a manual GradScaler.torch.distributed.all_gather for validation metrics.torch.save on all ranks.python train.py or python -m torch.distributed.launch.torch.manual_seed.from accelerate import Accelerator + accelerator = Accelerator() at the top.accelerator.prepare(...) for model, optimizer, all dataloaders, scheduler.accelerator.backward(loss) instead of loss.backward()..to("cuda")/.cuda(); use accelerator.device if needed.mixed_precision="fp16"|"bf16"|"fp8" kwarg (not fp16=True).gradient_accumulation_steps + with accelerator.accumulate(model):.gather_for_metrics for distributed eval.save_state/load_state, or unwrap_model + is_main_process for export.set_seed from accelerate.utils; accelerator.print for logs.accelerate config then accelerate launch (with --multi_gpu/--num_processes/…).| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-03 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-02 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-05 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-06 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-07 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-11 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-10 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-04 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-18 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-21 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-17 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-14 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-09 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-19 | pass→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-23 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-13 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-20 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-08 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-12 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-15 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-16 | pass→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-22 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-24 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 24 cases were attempted. The headline lift of 0 percentage points is the difference between those two pass rates over the 24 comparable cases. 2 cases got worse with the skill loaded, and they are included in that figure.
The per-case answers from this run were removed by the retention sweep, so the case table below shows the verdicts without the text either arm produced. The counts above were recorded at the time and are unaffected. Answers are now kept for 180 days.
| Model | Method | Date | Lift |
|---|---|---|---|
| gemini-3.5-flash | verified | 7/9/2026 | +21% |
Other measured skills in the registry, with their headline benchmark lift.