Performance tuning guide#
This guide covers AMD-focused performance work in Primus: HipBLASLt autotuning for GEMMs, Primus-Turbo optional kernels, mixed precision, activation recomputation, communication overlap, memory settings, and MoE-specific flags. It references Primus examples and Megatron module YAMLs.
1. HipBLASLt autotuning#
Transformer Engine and GEMM-heavy training benefit from HipBLASLt kernel selection. Primus integrates a three-stage workflow controlled by PRIMUS_HIPBLASLT_TUNING_STAGE (see examples/README.md and runner/helpers/hooks/train/pretrain/prepare_experiment.sh).
Activate tuning first. The stage variable is only honored when the master switch
PRIMUS_HIPBLASLT_TUNING=1is set (andPRIMUS_DETERMINISTICis not1). WithoutPRIMUS_HIPBLASLT_TUNING=1, the CLI hookrunner/helpers/hooks/train/pretrain/prepare_experiment.shskips tuning entirely and forcesTE_HIPBLASLT_TUNING_RUN_COUNT=0/TE_HIPBLASLT_TUNING_ALGO_COUNT=0. ExportPRIMUS_HIPBLASLT_TUNING=1alongside the stage in every command below.
Stage 0 (default)#
No tuning:
export PRIMUS_HIPBLASLT_TUNING_STAGE=0 # default
Stage 1: Dump GEMM shapes#
Run a short training job so shapes are collected during real forward/backward passes. Reduce train_iters (or equivalent) for faster shape collection.
export PRIMUS_HIPBLASLT_TUNING=1
export PRIMUS_HIPBLASLT_TUNING_STAGE=1
./primus-cli direct -- train pretrain \
--config examples/megatron/configs/MI300X/llama2_7B-BF16-pretrain.yaml
Output layout (from examples/README.md):
./output/tune_hipblaslt/${PRIMUS_MODEL}/gemm_shape
Stage 2: Offline tuning#
Runs offline tuning from dumped shapes (often 10–30 minutes depending on model and shapes):
export PRIMUS_HIPBLASLT_TUNING=1
export PRIMUS_HIPBLASLT_TUNING_STAGE=2
./primus-cli direct -- train pretrain \
--config examples/megatron/configs/MI300X/llama2_7B-BF16-pretrain.yaml
Expected output:
./output/tune_hipblaslt/${PRIMUS_MODEL}/gemm_tune/tune_hipblas_gemm_results.txt
Stage 3: Train with tuned kernels#
Point the runtime at the tuned override file:
export PRIMUS_HIPBLASLT_TUNING=1
export PRIMUS_HIPBLASLT_TUNING_STAGE=3
export HIPBLASLT_TUNING_OVERRIDE_FILE=/path/to/tune_hipblas_gemm_results.txt
./primus-cli direct -- train pretrain \
--config examples/megatron/configs/MI300X/llama2_7B-BF16-pretrain.yaml
Standalone offline tool#
For manual HipBLASLt bench workflows, see examples/offline_tune/offline_tune_gemm.py and examples/offline_tune/README.md (hipblaslt-bench integration and HIPBLASLT_TUNING_OVERRIDE_FILE usage).
2. Primus-Turbo optimization#
Primus-Turbo is a separate package of optimized AMD GPU kernels used by Primus Megatron and TorchTitan integrations. It is controlled by the master flag enable_primus_turbo in Megatron configs (primus/configs/modules/megatron/primus_turbo.yaml extends into trainer/model as needed). You must install the external primus_turbo package for these paths to be available.
Master flag (Megatron)#
enable_primus_turbo: true
Feature flags (Megatron)#
Defaults in primus/configs/modules/megatron/primus_turbo.yaml are mostly false until enabled.
Flag |
Purpose |
|---|---|
|
Optimized attention kernels. |
|
Optimized tensor-parallel linear layers. |
|
Optimized grouped GEMM for MoE. |
|
Removed—use |
|
Optimized RMSNorm. |
|
Fused MoE router (requires Primus-Turbo backend; see Backend Patch Notes). |
|
DeepEP token dispatcher; set with |
|
Compute units for DeepEP (patch notes suggest practices such as 64 or 80 for EP8, 32 for EP16–64). |
|
Sync-free MoE stages ( |
|
Fused activation with probabilities to reduce redundant work. |
Feature flags (TorchTitan)#
TorchTitan presets include primus_turbo in primus/configs/modules/torchtitan/pre_trainer.yaml
Example keys:
primus_turbo:
enable_primus_turbo: true
use_turbo_attention: true
use_turbo_async_tp: true
use_turbo_float8_linear: true
use_turbo_grouped_gemm: false
Documentation#
Extended Megatron arguments and Turbo-related behavior are summarized in Backend Patch Notes.
3. Mixed precision training#
Megatron (trainer_base.yaml patterns)#
Setting |
Description |
|---|---|
|
BFloat16 training (default |
|
FP16 training (optional). |
|
FP8 recipe control ( |
|
FP8 scaling behavior. |
|
Experimental FP4 paths. |
|
Keep first/last layers in BF16 for stability ( |
TorchTitan#
Setting |
Location |
|---|---|
|
|
|
Reduce precision |
FP8 / quantization |
|
Loss fusion (Megatron model)#
From primus/configs/models/megatron/language_model.yaml:
Default:
cross_entropy_loss_fusion: falsewithcross_entropy_fusion_impl: "native".To use Transformer Engine fused cross entropy where supported, enable the fusion explicitly and set
cross_entropy_fusion_impl: "te".
4. Activation recomputation#
Megatron#
Parameter |
Typical values |
Notes |
|---|---|---|
|
|
|
|
|
How recomputation is distributed. |
|
integer |
Layers to recompute when using selective or uniform strategies. |
|
list or null |
Primus extension: global layer indices (the patch resolves block-local indices to global ids via |
TorchTitan#
Parameter |
Location |
|---|---|
|
|
|
Selective AC options |
5. Communication overlap#
Megatron#
From trainer_base.yaml and model settings:
Setting |
Purpose |
|---|---|
|
Overlap gradient reduction with backward. |
|
Overlap parameter gather with forward. |
|
Pipeline P2P overlap. |
|
Async TP all-reduce (model config). |
TorchTitan#
Setting |
Purpose |
|---|---|
|
Async tensor parallelism. |
Environment#
CUDA_DEVICE_MAX_CONNECTIONS=1 is commonly required for correct overlap behavior in TP/PP stacks (see docs/03-configuration-reference/environment-variables.md and Megatron tests). Primus launch scripts or your cluster setup might set this.
6. Memory optimization#
Megatron#
Parameter |
Purpose |
|---|---|
|
Offload optimizer state to CPU. |
|
Fraction to offload ( |
|
Shards optimizer state across DP ranks (when enabled). |
|
Aggressive emptying of unused memory ( |
|
Increase global batch via gradient accumulation without increasing per-step activation memory. |
TorchTitan#
Parameter |
Purpose |
|---|---|
|
CPU offload path in |
7. MoE-specific optimization#
Megatron (model + turbo)#
Setting |
Purpose |
|---|---|
|
Fuse permutation / unpermutation ( |
|
Fused router + aux loss (Primus-Turbo). |
|
DeepEP dispatcher ( |
|
Recommended stage for sync-free MoE (per patch notes). |
|
Overlap expert parallel communication ( |
8. Known ROCm correctness workarounds#
The AMD Triton backend can emit a buffer_store_dwordx4 whose data registers are redefined by a
later instruction with no s_waitcnt vmcnt in between, so the store writes whatever the
clobbering instruction left behind. Nothing faults and nothing warns; a few percent of the
kernel’s output elements simply hold garbage. Inductor’s SwiGLU backward fusion trips it and
poisons the MLP weight gradients, which diverges TorchTitan training. Megatron is exposed to the
same kernels, since its fused activations are inductor-generated as well (megatron/core/jit.py
sets jit_fuser = torch.compile on torch 2.2+).
primus/core/patches/triton_bufops_war_patches.py handles this automatically on ROCm: every
kernel compiles normally, and only those whose emitted AMDGCN contains the hazard are recompiled
with buffer ops disabled. It has no switch: the recompile is a correctness fix, and a kernel that
does not need one is left alone anyway.
Two things about the design are deliberate. It selects per kernel rather than setting
AMDGCN_USE_BUFFER_OPS=0 globally, because the hazardous kernels lose nothing without buffer
addressing while the Primus-Turbo grouped-GEMM kernels spill without it and carry no hazard — the
global switch costs ~18% on MoE recipes for kernels that never needed fixing. And it decides from
the emitted machine code rather than from a list of affected architectures, so a newly shipped
architecture cannot silently fall out of coverage.
It also appends to TORCH_COMPILE_CACHE_KEY_TAG, because on an FX graph cache hit inductor never
calls triton.compile; without that, a cache filled before the patch existed would keep serving
hazardous binaries. Note that every Triton build tried so far still emits the pattern, so this is
not something an image upgrade removes.
Quick checklist#
GEMMs: run HipBLASLt stages 1–3 or use
offline_tune_gemm.pyfor custom workflows.Kernels: enable
primus_turboafter installingprimus_turbo; turn on attention/MoE flags as needed.Precision: BF16 by default; add FP8/FP4 only with recipe testing.
Memory: recomputation + distributed optimizer + CPU offload + accumulation before buying more GPUs.
MoE: fusion + DeepEP + sync-free stages + EP comm overlap when supported.