You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
During Gemma‑4‑31B QLoRA training on an AMD R9700 (gfx1201 / RDNA4, ROCm 7.2), a reproducible GPU page fault ("page not present") occurs inside a rocBLAS Tensile GEMM in the QLoRA backward pass. The fault survives full kernel serialization (so it is not an async race), reproduces on a verified‑clean GPU (so it is not a dirty‑KFD cascade), and the faulting address lies in unmapped space ~1 GB from both operands of the faulting GEMM (so it is not an undersized operand descriptor or an OOM).
This issue is the internal system‑of‑record consolidating the diagnosis from PR #101. Its purpose is to seed an upstream bug report against the ISA1201 GEMM kernels, filed at ROCm/rocm-libraries — component rocBLAS (projects/rocblas/) / Tensile (shared/tensile/). (The standalone ROCm/rocBLAS and ROCm/Tensile repos are retired; rocm-libraries is the source of truth.) The ready‑to‑paste upstream draft is in the comments. See the canonical ablation tracker: docs/GFX1201_FAULT_ABLATION_LOG.md.
Related: #100 (gfx1201 training investigation), #101 (PR where this was diagnosed), #109 (gfx1201 field report).
Memory access fault by GPU node-1 on address 0x7f6459a00000.
Reason: Page not present or supervisor privilege.
The fault is a 2 MB‑aligned host‑VA address arising during the gradient‑checkpoint forward recompute inside the backward pass. The faulting op is a rocBLAS Tensile GEMM that consumes the NF4‑dequantized weight — not the bitsandbytes dequant kernel (kDequantizeBlockwise<float> / <hip_bfloat16> succeed in every cycle).
Faulting kernel name — confirmed identical in both directions
On a verified‑clean GPU at AMD_LOG_LEVEL=3, the faulting kernel — captured in both the backward pass (runs #4/#5) and the grad‑ckpt forward recompute (run #9) — is the same gfx1201‑native Tensile GEMM, macro‑tile 64×64×64, ISA1201. Full ShaderName (run #9):
The same tile succeeds elsewhere in the same pass, so the fault is specific to a particular call's operands/addresses, not a categorically broken kernel. Discriminating flags that point at the B‑operand path: DTVB1 (B non‑default dtype/layout), LBSPPB0 (no B LDS prefetch), NLCB2 (B double‑unrolled), VWA2_VWB1 — consistent with the column‑major stride=(1,21504) B operand computing the wild address.
Fault‑address vs. operand descriptors (forward recompute — probe‑3)
probe‑3 (commit dad8f4a) instrumented both forward‑GEMM operands — the activation A (via MatMul4Bit.forward) and the dequantized weight B (via dequantize_4bit). The pair immediately preceding the fault:
A full‑log scan finds 0 operands that bracket the fault address. Both operands of the faulting GEMM are present, valid, and contiguous; the fault sits in an unmapped gap ~1 GB from either cluster, not adjacent to any buffer boundary. The column‑major (stride=(1,N)) B operand is the prime suspect for a Tensile stride‑computation bug producing the wild address.
Why it is a strong upstream report
Property
Evidence
Reproducible
Faults across multiple runs / resume points (runs 4–7 in the ablation log).
Serialized — not a race
Persists under AMD_SERIALIZE_KERNEL=3 HIP_LAUNCH_BLOCKING=1 (run #3). Serialization kills races, not this fault.
Both directions, same tile
Backward fault (probe‑1) and forward‑recompute fault (probe‑3) resolve to the identicalMT64x64x64 … ISA1201 ShaderName (run #9).
Not bitsandbytes
NF4 dequant kernels succeed every cycle; the fault is in the GEMM consuming the dequant output (runs #5–7).
Not an undersized descriptor
Fault is ~1 GB from any operand boundary, not adjacent to end (probe‑1, probe‑3).
Not a dirty‑KFD cascade
Reproduces on a make gpu-preflight‑verified‑clean GPU (run #5).
Not OOM
VRAM at fault is within headroom (alloc ~21 GB / reserved ~28 GB of 32 GB).
What would go in the upstream (rocm-libraries) report
Forward tile name — CONFIRMED (run docs: rename resources/ to references/, add HuggingFace notes #9, AMD_LOG_LEVEL=3). The forward‑recompute faulting GEMM resolves to the same ShaderName as the backward kernel (see above). The earlier concern that they might be different tiles (the forward problem size (1,608,21504)@(21504,5376) differs) is settled by evidence: both dispatch the identical MT64x64x64 … ISA1201 tile. The upstream report can name the kernel directly for both directions.
Open / unconfirmed
Output buffer not instrumented. A page‑not‑present is formally consistent with an OOB write to the output rather than a wild read. Deemed implausible — the output (1,608,5376) bf16 is ~6 MB and the fault is ~1 GB from any logged buffer — but it was not ruled out by instrumentation. This is the sole residual ambiguity in the wild‑read characterization.
Tracked in docs/GFX1201_FAULT_ABLATION_LOG.md, scored on two axes (does it eliminate the fault / does it improve steps‑per‑resume):
TORCH_USE_HIPBLASLT=1 (Arm HLT1) — tried, not a fix (run feat: Ollama remote-access setup for M4 Mac Mini consultant #11). hipBLASLt has no kernel for this MT64x64x64 DTVB1 shape (logs Cannot find the function ×6) and falls back to the same Tensile kernel; fault persists. No userspace routing around the bug exists in ROCm 7.2.
expandable_segments:True (Arm D) — dead arm (run feat: plug-and-play WAVE HPC setup script #10): silently ignored on gfx1201/ROCm, so it only tested "no GC threshold." Fault persisted regardless → allocator placement cannot mask it.
HSA_ENABLE_SDMA=0 — cheap, stackable; folded into the pending production steps‑per‑resume measurement.
Both routing/placement arms are now exhausted. Remaining paths are the brute‑force checkpoint crawl (viability unmeasured) or relocating the SFT run to NVIDIA (see docs/SFT_NVIDIA_MIGRATION.md); the upstream fix is the only thing that unblocks gfx1201 itself.
Summary
During Gemma‑4‑31B QLoRA training on an AMD R9700 (gfx1201 / RDNA4, ROCm 7.2), a reproducible GPU page fault ("page not present") occurs inside a rocBLAS Tensile GEMM in the QLoRA backward pass. The fault survives full kernel serialization (so it is not an async race), reproduces on a verified‑clean GPU (so it is not a dirty‑KFD cascade), and the faulting address lies in unmapped space ~1 GB from both operands of the faulting GEMM (so it is not an undersized operand descriptor or an OOM).
This issue is the internal system‑of‑record consolidating the diagnosis from PR #101. Its purpose is to seed an upstream bug report against the ISA1201 GEMM kernels, filed at
ROCm/rocm-libraries— component rocBLAS (projects/rocblas/) / Tensile (shared/tensile/). (The standaloneROCm/rocBLASandROCm/Tensilerepos are retired; rocm-libraries is the source of truth.) The ready‑to‑paste upstream draft is in the comments. See the canonical ablation tracker:docs/GFX1201_FAULT_ABLATION_LOG.md.Related: #100 (gfx1201 training investigation), #101 (PR where this was diagnosed), #109 (gfx1201 field report).
Environment
TORCH_USE_HIPBLASLT=0)use_reentrant=False), seq 1280, bs 1×16, seed 42The fault
The fault is a 2 MB‑aligned host‑VA address arising during the gradient‑checkpoint forward recompute inside the backward pass. The faulting op is a rocBLAS Tensile GEMM that consumes the NF4‑dequantized weight — not the bitsandbytes dequant kernel (
kDequantizeBlockwise<float>/<hip_bfloat16>succeed in every cycle).Faulting kernel name — confirmed identical in both directions
On a verified‑clean GPU at
AMD_LOG_LEVEL=3, the faulting kernel — captured in both the backward pass (runs #4/#5) and the grad‑ckpt forward recompute (run #9) — is the same gfx1201‑native Tensile GEMM, macro‑tile 64×64×64, ISA1201. Full ShaderName (run #9):The same tile succeeds elsewhere in the same pass, so the fault is specific to a particular call's operands/addresses, not a categorically broken kernel. Discriminating flags that point at the B‑operand path:
DTVB1(B non‑default dtype/layout),LBSPPB0(no B LDS prefetch),NLCB2(B double‑unrolled),VWA2_VWB1— consistent with the column‑majorstride=(1,21504)B operand computing the wild address.Fault‑address vs. operand descriptors (forward recompute — probe‑3)
probe‑3 (commit
dad8f4a) instrumented both forward‑GEMM operands — the activationA(viaMatMul4Bit.forward) and the dequantized weightB(viadequantize_4bit). The pair immediately preceding the fault:A(1,608,21504)contig0x7f655ece80000x7f65605d8000ptrB(21504,5376)stride=(1,21504)0x7f63f01a00000x7f63fde20000endA full‑log scan finds 0 operands that bracket the fault address. Both operands of the faulting GEMM are present, valid, and contiguous; the fault sits in an unmapped gap ~1 GB from either cluster, not adjacent to any buffer boundary. The column‑major (
stride=(1,N))Boperand is the prime suspect for a Tensile stride‑computation bug producing the wild address.Why it is a strong upstream report
AMD_SERIALIZE_KERNEL=3 HIP_LAUNCH_BLOCKING=1(run #3). Serialization kills races, not this fault.MT64x64x64 … ISA1201ShaderName (run #9).end(probe‑1, probe‑3).make gpu-preflight‑verified‑clean GPU (run #5).What would go in the upstream (rocm-libraries) report
…_MT64x64x64_…_ISA1201_…).A (1,608,21504)row‑major contiguous;B (21504,5376)column‑majorstride=(1,21504); bf16.0x7f6459a00000lies outside both operand ranges (≥1 GB gap).Resolved since first filing
AMD_LOG_LEVEL=3). The forward‑recompute faulting GEMM resolves to the same ShaderName as the backward kernel (see above). The earlier concern that they might be different tiles (the forward problem size(1,608,21504)@(21504,5376)differs) is settled by evidence: both dispatch the identicalMT64x64x64 … ISA1201tile. The upstream report can name the kernel directly for both directions.Open / unconfirmed
(1,608,5376)bf16 is ~6 MB and the fault is ~1 GB from any logged buffer — but it was not ruled out by instrumentation. This is the sole residual ambiguity in the wild‑read characterization.Mitigations under evaluation (PR #101)
Tracked in
docs/GFX1201_FAULT_ABLATION_LOG.md, scored on two axes (does it eliminate the fault / does it improve steps‑per‑resume):— tried, not a fix (run feat: Ollama remote-access setup for M4 Mac Mini consultant #11). hipBLASLt has no kernel for thisTORCH_USE_HIPBLASLT=1(Arm HLT1)MT64x64x64 DTVB1shape (logsCannot find the function×6) and falls back to the same Tensile kernel; fault persists. No userspace routing around the bug exists in ROCm 7.2.— dead arm (run feat: plug-and-play WAVE HPC setup script #10): silently ignored on gfx1201/ROCm, so it only tested "no GC threshold." Fault persisted regardless → allocator placement cannot mask it.expandable_segments:True(Arm D)use_reentrant=Truegrad‑ckpt — de‑prioritized: targets the activation‑lifetime hypothesis (Bucket feat: add poetry run test and poetry run lint commands #1), which probe‑3 refuted (both operands valid; wild address ⇒ Bucket feat: add GitHub Actions CI with ruff linting and pytest #2).HSA_ENABLE_SDMA=0— cheap, stackable; folded into the pending production steps‑per‑resume measurement.Both routing/placement arms are now exhausted. Remaining paths are the brute‑force checkpoint crawl (viability unmeasured) or relocating the SFT run to NVIDIA (see
docs/SFT_NVIDIA_MIGRATION.md); the upstream fix is the only thing that unblocks gfx1201 itself.References
docs/GFX1201_FAULT_ABLATION_LOG.md— canonical run/ablation tracker.docs/GFX1201_RDNA4_TRAINING.md §6.1— original narrative (predates localization; the tracker supersedes its bnb‑side framing).81cebb4(probe‑1),1b752c2(probe‑2),dad8f4a(probe‑3). Run docs: rename resources/ to references/, add HuggingFace notes #9 (kernel-name.log,AMD_LOG_LEVEL=3) confirmed the forward ShaderName; run feat: plug-and-play WAVE HPC setup script #10 (11c13b6) closed Arm D.