From 5fc570d6f74bcb43a4ce795c885288580cc3dfb8 Mon Sep 17 00:00:00 2001 From: Piotr Wilkin Date: Fri, 10 Jul 2026 17:08:22 +0200 Subject: [PATCH] fix: extend f32 matmul precision to ROCm for Qwen-Image, Krea2 and Boogu Same failure mechanism as the Z-Image fix: DiT activations exceed the f16 range, and on HIP for RDNA3.x ggml routes large-batch quantized matmuls to the hipBLAS path, which converts activations to f16 and saturates them to inf, ending in NaN latents and blank images. Widen the existing Vulkan-only force_prec_f32 gates on the attention out and FFN out projections to also cover ROCm. The shared FeedForward change also applies to the other DiTs that use it. Co-Authored-By: Claude Fable 5 --- src/model/common/block.hpp | 2 +- src/model/diffusion/boogu.hpp | 6 +++--- src/model/diffusion/krea2.hpp | 2 +- src/model/diffusion/qwen_image.hpp | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/model/common/block.hpp b/src/model/common/block.hpp index 15bfa3767..ec8f40d0b 100644 --- a/src/model/common/block.hpp +++ b/src/model/common/block.hpp @@ -294,7 +294,7 @@ class FeedForward : public GGMLBlock { auto net_0 = std::dynamic_pointer_cast(blocks["net.0"]); auto net_2 = std::dynamic_pointer_cast(blocks["net.2"]); - if (sd_backend_is(ctx->backend, "Vulkan")) { + if (sd_backend_is(ctx->backend, "Vulkan") || sd_backend_is(ctx->backend, "ROCm")) { net_2->set_force_prec_f32(true); } diff --git a/src/model/diffusion/boogu.hpp b/src/model/diffusion/boogu.hpp index 27e13aebd..9ab2dccbc 100644 --- a/src/model/diffusion/boogu.hpp +++ b/src/model/diffusion/boogu.hpp @@ -199,7 +199,7 @@ namespace Boogu { auto linear_2 = std::dynamic_pointer_cast(blocks["linear_2"]); auto linear_3 = std::dynamic_pointer_cast(blocks["linear_3"]); - if (sd_backend_is(ctx->backend, "Vulkan")) { + if (sd_backend_is(ctx->backend, "Vulkan") || sd_backend_is(ctx->backend, "ROCm")) { linear_2->set_force_prec_f32(true); } @@ -259,7 +259,7 @@ namespace Boogu { auto norm_k = std::dynamic_pointer_cast(blocks["norm_k"]); auto to_out_0 = std::dynamic_pointer_cast(blocks["to_out.0"]); - if (sd_backend_is(ctx->backend, "Vulkan")) { + if (sd_backend_is(ctx->backend, "Vulkan") || sd_backend_is(ctx->backend, "ROCm")) { to_out_0->set_force_prec_f32(true); } @@ -383,7 +383,7 @@ namespace Boogu { auto instruct_out = std::dynamic_pointer_cast(blocks["processor.instruct_out"]); auto img_out = std::dynamic_pointer_cast(blocks["processor.img_out"]); - if (sd_backend_is(ctx->backend, "Vulkan")) { + if (sd_backend_is(ctx->backend, "Vulkan") || sd_backend_is(ctx->backend, "ROCm")) { to_out_0->set_force_prec_f32(true); } diff --git a/src/model/diffusion/krea2.hpp b/src/model/diffusion/krea2.hpp index 02e655590..a4142fc91 100644 --- a/src/model/diffusion/krea2.hpp +++ b/src/model/diffusion/krea2.hpp @@ -267,7 +267,7 @@ namespace Krea2 { auto knorm = std::dynamic_pointer_cast(blocks["qknorm.knorm"]); auto wo = std::dynamic_pointer_cast(blocks["wo"]); - if (sd_backend_is(ctx->backend, "Vulkan")) { + if (sd_backend_is(ctx->backend, "Vulkan") || sd_backend_is(ctx->backend, "ROCm")) { wo->set_force_prec_f32(true); } diff --git a/src/model/diffusion/qwen_image.hpp b/src/model/diffusion/qwen_image.hpp index 52edc0d56..2d869e2c3 100644 --- a/src/model/diffusion/qwen_image.hpp +++ b/src/model/diffusion/qwen_image.hpp @@ -183,7 +183,7 @@ namespace Qwen { auto to_v = std::dynamic_pointer_cast(blocks["to_v"]); auto to_out_0 = std::dynamic_pointer_cast(blocks["to_out.0"]); - if (sd_backend_is(ctx->backend, "Vulkan")) { + if (sd_backend_is(ctx->backend, "Vulkan") || sd_backend_is(ctx->backend, "ROCm")) { to_out_0->set_force_prec_f32(true); }