Multi-GPU Mastery

Soup v0.27.0 turns multi-GPU training from a research paper into a CLI flag. --gpus detects the topology and re-launches under accelerate, ZeRO++ lands quantized weights and grads, FSDP2 can opt into torch.compile, and a pipeline-parallelism setting is validated but not yet executed (see below).

One-flag launch

bash
soup train --gpus auto
soup train --gpus 8

--gpus resolves the GPU count (an integer or auto) and detects the interconnect (NVLink vs PCIe). With more than one GPU it then re-launches the same soup train command under accelerate launch --num_processes N, carrying your flags with it. It does not pick a sharding strategy for you: choose one with --deepspeed or --fsdp (or in the config). Pass --no-reexec to print the accelerate launch command instead of running it; Soup then exits 1 so a script does not carry on as if training had started.

The exit code after a launch depends on the platform. Soup hands over with os.execvp. On Linux and macOS that replaces Soup's own process with accelerate, so the code your shell or CI sees is the launcher's. On Windows the same call returns immediately: in a check with a stand-in launcher that ran for five seconds and exited 7, soup train --gpus 2 still exited 0 after about three seconds, the launcher kept running in the background, and its exit code was lost. Do not gate a script on the exit code of soup train --gpus N on Windows; read the run's own output instead.

ZeRO++

yaml
base: meta-llama/Llama-3.1-70B
task: sft

data:
  train: ./data/train.jsonl

training:
  quantization: 4bit
  lora:
    r: 16
    alpha: 32
bash
soup train --gpus 8 --deepspeed zero++
# aliases: zero_pp

ZeRO++ cuts inter-GPU communication by quantizing the broadcasted weights and gradients. Integer fields (sub_group_size, stage3_max_live_parameters, stage3_max_reuse_distance) are written as int(1e9) so DeepSpeed's strict JSON validator accepts them.

FSDP2 + torch.compile

yaml
training:
  use_fsdp2_compile: true
bash
soup train --gpus 4 --fsdp full_shard

The validator requires an FSDP preset, CUDA, backend=transformers, and torch>=2.2 + accelerate>=0.27. DeepSpeed + torch.compile is explicitly rejected — the two own their own compile paths and mixing them produces a cryptic runtime crash.

Pipeline parallelism

yaml
training:
  parallelism: pipeline
  pipeline_stages: 4

The validator requires pipeline_stages >= 2, CUDA, and gpu_count >= pipeline_stages. pipeline_stages is bounded [1, 16].

Validation only. At v0.75.2 parallelism: pipeline is checked and then the run executes data-parallel: soup train prints a yellow "Pipeline parallelism (deferred execution)" panel saying the config is validated and the trainer runs in data-parallel mode. No pipeline stages are executed, so setting it does not split the model across GPUs.

DeepSpeed-MII backend

bash
soup serve --backend mii --model ./output

Registered in v0.27.0, live since v0.33.0. A misconfigured --backend mii always exits non-zero (never silently accepts).

v0.74.0 repaired the prompt and the finish reason. Until then this backend hand-rolled a System:/User:/Assistant: prompt and hardcoded finish_reason to stop, so a served model saw a format it was never trained on and a client could not tell a truncated answer from a completed one. It now applies the model's own chat template through the shared builder and reports the engine's real finish reason. Behaviour is unchanged for a model that ships no chat template. That is the third backend to have carried this same pair, after vLLM in v0.73.0 and SGLang in v0.74.0.

Multi-GPU recipes

  • llama3-70b-fsdp2 — 70B SFT on 8×A100 via FSDP2 + compile
  • qwen3-32b-zeropp — Qwen 3 32B SFT via DeepSpeed ZeRO++
  • deepseek-v3-pipeline — DeepSeek V3 SFT scaffold (the pipeline setting is validated; training runs data-parallel)
bash
soup recipes use llama3-70b-fsdp2
soup train --gpus 8 --fsdp full_shard

Sharding is a launch flag, not a recipe key. The llama3-70b-fsdp2 recipe sets use_fsdp2_compile: true, and soup train refuses that (exit 1, "use_fsdp2_compile requires FSDP to be enabled") unless --fsdp is passed, so soup train --gpus 8 alone fails. The ZeRO++ recipe takes --deepspeed zero++ in the same position. See Before you run one.

Security & guardrails

  • --gpus rejects bool, negatives, zero, non-digits, and values above MAX_GPU_COUNT=128
  • --gpus auto on a CPU-only host prints an explicit yellow warning instead of silently single-processing
  • The accelerate launch argv is built via shlex.quote so copy-pasted commands can't inject via a crafted config path
  • NCCL env hints are applied via os.environ.setdefault — user / launcher overrides always win
  • Rich markup on --config paths is escaped before embedding in advice panels

See also

Soup is free and Apache-2.0. If it saved you a training run, starring the repo costs nothing and helps most. You can also fund the GPU time behind the work a 4 GB laptop cannot reach.