Commit b9d7176 for stable-diffusion.cpp
commit b9d7176bf88fe465576e0aafbe47ba253ffcfc2c
Author: leejet <leejet714@gmail.com>
Date: Fri Nov 13 00:23:54 2026 +0800
feat: unify text encoder selection across H3 variants (#2340)
diff --git a/docs/minimax_h3.md b/docs/minimax_h3.md
index 6b672ba..8f1444d 100644
--- a/docs/minimax_h3.md
+++ b/docs/minimax_h3.md
@@ -12,12 +12,31 @@ Pass the four MiniMax-H3 components separately:
- `--diffusion-model`: MiniMax-H3 diffusion transformer
- `--vae`: MiniMax-H3 video VAE
- `--audio-vae`: MiniMax-H3 audio VAE
-- `--llm`: the MiniMax-H3 Qwen3-VL-32B text encoder checkpoint
+- `--llm`: the MiniMax-H3 Qwen3-VL-32B text encoder, or Qwen3-VL-4B with the P-H3 text connector
-The text encoder must be the MiniMax-H3 variant: Qwen3-VL-32B truncated to 50
+For the 32B option, use the MiniMax-H3 variant: Qwen3-VL-32B truncated to 50
language layers and exported without the final language-model normalization.
-Its Qwen3-VL vision tower, including the three DeepStack mergers, must also be
-present. If the vision tower is stored separately, pass it with `--llm_vision`.
+
+For the smaller 4B option, pass the P-H3-Image text encoder, which bundles the
+connector, with `--llm`. Alternatively, pass Qwen3-VL-4B with `--llm` and the
+[separate P-H3 text connector](https://huggingface.co/PrunaAI/P-H3-Image/blob/main/text_connector/diffusion_pytorch_model.safetensors)
+with `--embeddings-connectors`. For example, replace the `--llm` argument in the
+commands below with either:
+
+```sh
+--llm ..\models\text_encoders\p-h3-image_text_encoder_int8_convrot.safetensors
+```
+
+or:
+
+```sh
+--llm ..\models\text_encoders\qwen3vl_4b.gguf --embeddings-connectors ..\models\text_encoders\p-h3-image_text_connector.safetensors
+```
+
+Reference-image and reference-video conditioning needs the matching encoder's
+Qwen3-VL vision tower, including the three DeepStack mergers. If stored
+separately, pass it with `--llm_vision`. Keep using the MiniMax-H3 video and audio
+VAEs with either text encoder.
Both the original time-embedder DiT and the smaller AdaLN curve-table variant
are detected from their weights.
@@ -30,6 +49,8 @@ are detected from their weights.
- Download qwen3vl_32b_minimax_h3
- safetensors: https://huggingface.co/Comfy-Org/MiniMax-H3/tree/main/text_encoders
- gguf: https://huggingface.co/leejet/MiniMax-H3-GGUF/tree/main
+- Or download the P-H3-Image text encoder (Qwen3-VL-4B with the text connector)
+ - safetensors: https://huggingface.co/PrunaAI/P-H3-Image-Comfy/tree/main/text_encoders
- Download vae
- safetensors: https://huggingface.co/Comfy-Org/MiniMax-H3/tree/main/vae
- Download audio vae
diff --git a/docs/p_h3_image.md b/docs/p_h3_image.md
index 20de6fb..b712f4b 100644
--- a/docs/p_h3_image.md
+++ b/docs/p_h3_image.md
@@ -1,6 +1,6 @@
# How to Use
-P-H3-Image supports text-to-image and reference-image editing. It uses a MiniMax-H3 diffusion transformer, a single-frame VAE, and Qwen3-VL-4B with a text connector. Prompt enhancement is not included.
+P-H3-Image supports text-to-image and reference-image editing. It uses a MiniMax-H3 diffusion transformer, a single-frame VAE, and either Qwen3-VL-4B with a text connector or the MiniMax-H3 Qwen3-VL-32B text encoder. Prompt enhancement is not included.
## Download weights
@@ -10,9 +10,22 @@ P-H3-Image supports text-to-image and reference-image editing. It uses a MiniMax
- safetensors: https://huggingface.co/PrunaAI/P-H3-Image-Comfy/tree/main/vae
- Download Qwen3-VL-4B with the text connector
- https://huggingface.co/PrunaAI/P-H3-Image-Comfy/tree/main/text_encoders
+- Or download the MiniMax-H3 Qwen3-VL-32B text encoder
+ - safetensors: https://huggingface.co/Comfy-Org/MiniMax-H3/tree/main/text_encoders
+ - gguf: https://huggingface.co/leejet/MiniMax-H3-GGUF/tree/main
Alternatively, reuse Qwen3-VL-4B, including its vision tower, with the [separate text connector](https://huggingface.co/PrunaAI/P-H3-Image/blob/main/text_connector/diffusion_pytorch_model.safetensors). Save the connector as `p-h3-image_text_connector.safetensors` and pass it with `--embeddings-connectors`.
+The MiniMax-H3 Qwen3-VL-32B encoder does not need a text connector. To use it in
+either example below, omit `--embeddings-connectors` and replace `--llm` with:
+
+```sh
+--llm ..\models\text_encoders\qwen3vl_32b_minimax_h3-Q4_K_M.gguf
+```
+
+Reference-image editing needs the matching encoder's vision tower. If stored
+separately, pass it with `--llm_vision`.
+
Use the P-H3 image VAE; the MiniMax-H3 video VAE is not compatible. No audio VAE is needed.
## Examples
diff --git a/examples/server/recipes/hyperflow-h3-flash-fl2va.json b/examples/server/recipes/hyperflow-h3-flash-fl2va.json
index 64e79d5..c8d9f74 100644
--- a/examples/server/recipes/hyperflow-h3-flash-fl2va.json
+++ b/examples/server/recipes/hyperflow-h3-flash-fl2va.json
@@ -3,7 +3,7 @@
"id": "hyperflow-h3-flash-fl2va",
"name": "HyperFlow H3 Flash FL2VA",
"size_multiple": 32,
- "description": "Generate video and audio from text, optionally with start/end images. Use the HyperFlow H3 Flash FL2VA transformer. Reuses MiniMax-H3 components with the HyperFlow 6-step schedule. Audio VAE is optional for silent video.",
+ "description": "Generate video and audio from text, optionally with start/end images. Use the HyperFlow H3 Flash FL2VA transformer. Reuses MiniMax-H3 components with either the MiniMax-H3 Qwen3-VL-32B text encoder or Qwen3-VL-4B with the P-H3 text connector and the HyperFlow 6-step schedule. Audio VAE is optional for silent video.",
"model_url": "https://huggingface.co/VideoRebirthAI/hyperflow-h3-flash",
"slots": [
{
@@ -14,7 +14,17 @@
{
"id": "llm",
"required": true,
- "label": "MiniMax-H3 Qwen 3 VL 32B Text Encoder"
+ "label": "MiniMax-H3 Qwen 3 VL 32B or P-H3 Qwen 3 VL 4B Text Encoder"
+ },
+ {
+ "id": "llm_vision",
+ "required": false,
+ "label": "Vision tower (when not included in the text encoder)"
+ },
+ {
+ "id": "embeddings_connectors",
+ "required": false,
+ "label": "P-H3 Text Connector (for Qwen 3 VL 4B, when not included in the text encoder)"
},
{
"id": "vae",
diff --git a/examples/server/recipes/hyperflow-h3-flash-ref2va.json b/examples/server/recipes/hyperflow-h3-flash-ref2va.json
index 871a690..bc7cde1 100644
--- a/examples/server/recipes/hyperflow-h3-flash-ref2va.json
+++ b/examples/server/recipes/hyperflow-h3-flash-ref2va.json
@@ -3,7 +3,7 @@
"id": "hyperflow-h3-flash-ref2va",
"name": "HyperFlow H3 Flash Ref2VA",
"size_multiple": 32,
- "description": "Generate video and audio with reference images. Use the HyperFlow H3 Flash Ref2VA transformer; video/audio references are not validated for these weights. Reuses MiniMax-H3 components with the HyperFlow 6-step schedule. Audio VAE is optional for silent video.",
+ "description": "Generate video and audio with reference images. Use the HyperFlow H3 Flash Ref2VA transformer; video/audio references are not validated for these weights. Reuses MiniMax-H3 components with either the MiniMax-H3 Qwen3-VL-32B text encoder or Qwen3-VL-4B with the P-H3 text connector and the HyperFlow 6-step schedule. Reference images need the matching vision tower. Audio VAE is optional for silent video.",
"model_url": "https://huggingface.co/VideoRebirthAI/hyperflow-h3-flash",
"slots": [
{
@@ -14,7 +14,17 @@
{
"id": "llm",
"required": true,
- "label": "MiniMax-H3 Qwen 3 VL 32B Text Encoder"
+ "label": "MiniMax-H3 Qwen 3 VL 32B or P-H3 Qwen 3 VL 4B Text Encoder"
+ },
+ {
+ "id": "llm_vision",
+ "required": false,
+ "label": "Vision tower (required for reference images when not included in the text encoder)"
+ },
+ {
+ "id": "embeddings_connectors",
+ "required": false,
+ "label": "P-H3 Text Connector (for Qwen 3 VL 4B, when not included in the text encoder)"
},
{
"id": "vae",
diff --git a/examples/server/recipes/minimax-h3-fl2va.json b/examples/server/recipes/minimax-h3-fl2va.json
index f0af22b..63f0319 100644
--- a/examples/server/recipes/minimax-h3-fl2va.json
+++ b/examples/server/recipes/minimax-h3-fl2va.json
@@ -3,7 +3,7 @@
"id": "minimax-h3-fl2va",
"name": "MiniMax H3 FL2VA",
"size_multiple": 32,
- "description": "Generate video and audio, optionally with start/end images. Supports full and pruned FL2VA weights. Audio VAE is optional for silent video.",
+ "description": "Generate video and audio, optionally with start/end images. Supports full and pruned FL2VA weights with either the MiniMax-H3 Qwen3-VL-32B text encoder or Qwen3-VL-4B with the P-H3 text connector. Audio VAE is optional for silent video.",
"model_url": "https://huggingface.co/MiniMaxAI/MiniMax-H3",
"slots": [
{
@@ -13,7 +13,17 @@
{
"id": "llm",
"required": true,
- "label": "MiniMax-H3 Qwen 3 VL 32B Text Encoder"
+ "label": "MiniMax-H3 Qwen 3 VL 32B or P-H3 Qwen 3 VL 4B Text Encoder"
+ },
+ {
+ "id": "llm_vision",
+ "required": false,
+ "label": "Vision tower (when not included in the text encoder)"
+ },
+ {
+ "id": "embeddings_connectors",
+ "required": false,
+ "label": "P-H3 Text Connector (for Qwen 3 VL 4B, when not included in the text encoder)"
},
{
"id": "vae",
diff --git a/examples/server/recipes/minimax-h3-ref2va.json b/examples/server/recipes/minimax-h3-ref2va.json
index 9ee5f63..61f29db 100644
--- a/examples/server/recipes/minimax-h3-ref2va.json
+++ b/examples/server/recipes/minimax-h3-ref2va.json
@@ -3,7 +3,7 @@
"id": "minimax-h3-ref2va",
"name": "MiniMax H3 Ref2VA",
"size_multiple": 32,
- "description": "Supply image, video or audio references with compatible Ref2VA weights. Audio VAE is optional for silent video.",
+ "description": "Supply image, video or audio references with compatible Ref2VA weights. Use either the MiniMax-H3 Qwen3-VL-32B text encoder or Qwen3-VL-4B with the P-H3 text connector. Image/video references need the matching vision tower. Audio VAE is optional for silent video.",
"model_url": "https://huggingface.co/MiniMaxAI/MiniMax-H3",
"slots": [
{
@@ -13,7 +13,17 @@
{
"id": "llm",
"required": true,
- "label": "MiniMax-H3 Qwen 3 VL 32B Text Encoder"
+ "label": "MiniMax-H3 Qwen 3 VL 32B or P-H3 Qwen 3 VL 4B Text Encoder"
+ },
+ {
+ "id": "llm_vision",
+ "required": false,
+ "label": "Vision tower (required for image/video references when not included in the text encoder)"
+ },
+ {
+ "id": "embeddings_connectors",
+ "required": false,
+ "label": "P-H3 Text Connector (for Qwen 3 VL 4B, when not included in the text encoder)"
},
{
"id": "vae",
diff --git a/examples/server/recipes/p-h3-image.json b/examples/server/recipes/p-h3-image.json
index 1098bab..a2b9e31 100644
--- a/examples/server/recipes/p-h3-image.json
+++ b/examples/server/recipes/p-h3-image.json
@@ -3,7 +3,7 @@
"id": "p-h3-image",
"name": "P-H3-Image",
"size_multiple": 32,
- "description": "Supports text-to-image and reference-image editing with the fixed 8-step schedule. Use the P-H3 single-frame VAE and Qwen3-VL-4B with its vision tower. Supply the P-H3 text connector separately unless it is included in the text encoder.",
+ "description": "Supports text-to-image and reference-image editing with the fixed 8-step schedule. Use the P-H3 single-frame VAE and either Qwen3-VL-4B with the P-H3 text connector or the MiniMax-H3 Qwen3-VL-32B text encoder. Reference images need the matching vision tower.",
"model_url": "https://huggingface.co/PrunaAI/P-H3-Image",
"slots": [
{
@@ -13,7 +13,7 @@
{
"id": "llm",
"required": true,
- "label": "Qwen 3 VL 4B Text Encoder"
+ "label": "MiniMax-H3 Qwen 3 VL 32B or P-H3 Qwen 3 VL 4B Text Encoder"
},
{
"id": "llm_vision",
@@ -23,7 +23,7 @@
{
"id": "embeddings_connectors",
"required": false,
- "label": "P-H3 Text Connector (required when not included in the text encoder)"
+ "label": "P-H3 Text Connector (for Qwen 3 VL 4B, when not included in the text encoder)"
},
{
"id": "vae",
diff --git a/src/conditioning/conditioner.hpp b/src/conditioning/conditioner.hpp
index babf98e..31aa493 100644
--- a/src/conditioning/conditioner.hpp
+++ b/src/conditioning/conditioner.hpp
@@ -2030,20 +2030,23 @@ struct LLMEmbedder : public Conditioner {
"text_encoders.llm",
enable_vision,
weight_manager);
- // MiniMax-H3-Image also accepts the P-H3-Image text encoder in place of the MiniMax-H3 Qwen3-VL-32B encoder.
- const bool has_ph3_connector = tensor_storage_map.find(std::string(PH3ImageTextConnectorRunner::prefix) + ".proj.weight") !=
- tensor_storage_map.end();
- if (version == VERSION_P_H3_IMAGE || (version == VERSION_MINIMAX_H3_IMAGE && has_ph3_connector)) {
- if (llm->config.num_layers != 36 || llm->config.hidden_size != 2560) {
- throw std::runtime_error(version == VERSION_P_H3_IMAGE
- ? "P-H3-Image requires the Qwen3-VL-4B text encoder"
- : "The P-H3-Image text connector requires the Qwen3-VL-4B text encoder");
- }
- ph3_connector = std::make_shared<PH3ImageTextConnectorRunner>(backend, tensor_storage_map, weight_manager);
- } else if (version == VERSION_MINIMAX_H3_IMAGE && llm->config.hidden_size == 2560) {
- throw std::runtime_error(
- "MiniMax-H3-Image with Qwen3-VL-4B requires the P-H3-Image text connector; "
- "pass it with --embeddings-connectors or use the MiniMax-H3 Qwen3-VL-32B text encoder");
+ if (sd_version_is_minimax_h3(version)) {
+ const bool has_ph3_connector = tensor_storage_map.count(std::string(PH3ImageTextConnectorRunner::prefix) + ".proj.weight") != 0;
+ if (has_ph3_connector) {
+ if (llm->config.num_layers != 36 || llm->config.hidden_size != 2560) {
+ throw std::runtime_error("The P-H3-Image text connector requires the Qwen3-VL-4B text encoder");
+ }
+ ph3_connector = std::make_shared<PH3ImageTextConnectorRunner>(backend, tensor_storage_map, weight_manager);
+ } else if (llm->config.hidden_size == 2560) {
+ throw std::runtime_error(
+ sd_format("%s with Qwen3-VL-4B requires the P-H3-Image text connector; "
+ "pass it with --embeddings-connectors or use the MiniMax-H3 Qwen3-VL-32B text encoder",
+ sd_version_name(version)));
+ } else if (llm->config.hidden_size != 5120 || (llm->config.num_layers != 50 && llm->config.num_layers != 64)) {
+ throw std::runtime_error(
+ sd_format("%s requires the MiniMax-H3 Qwen3-VL-32B text encoder or Qwen3-VL-4B with the P-H3-Image text connector",
+ sd_version_name(version)));
+ }
}
int pad_id = 151643;
if (arch == LLM::LLMArch::MISTRAL_SMALL_3_2 || arch == LLM::LLMArch::MINISTRAL_3_3B) {
diff --git a/src/model/diffusion/fibo2.hpp b/src/model/diffusion/fibo2.hpp
index 6f8ef09..091e74c 100644
--- a/src/model/diffusion/fibo2.hpp
+++ b/src/model/diffusion/fibo2.hpp
@@ -131,8 +131,8 @@ namespace Fibo2 {
v = reshape(project("to_v", kv));
}
}
- q = std::dynamic_pointer_cast<RMSNorm>(blocks["norm_q"])->forward(ctx, q);
- k = std::dynamic_pointer_cast<RMSNorm>(blocks["norm_k"])->forward(ctx, k);
+ q = std::dynamic_pointer_cast<RMSNorm>(blocks["norm_q"])->forward(ctx, q);
+ k = std::dynamic_pointer_cast<RMSNorm>(blocks["norm_k"])->forward(ctx, k);
auto prepare = [&](ggml_tensor* h) {
if (pe) {
return Rope::apply_rope(ctx, h, pe);
diff --git a/src/model/diffusion/iris.hpp b/src/model/diffusion/iris.hpp
index eb4c66b..7ab0cd5 100644
--- a/src/model/diffusion/iris.hpp
+++ b/src/model/diffusion/iris.hpp
@@ -91,10 +91,10 @@ namespace Iris {
}
ggml_tensor* forward(GGMLRunnerContext* ctx, ggml_tensor* x, ggml_tensor* pe = nullptr, ggml_tensor* mask = nullptr) {
- auto c = ctx->ggml_ctx;
- auto head_dim = dim / heads;
- auto qkv = std::dynamic_pointer_cast<Linear>(blocks["qkv"])->forward(ctx, x);
- auto qkv_dim = qkv->ne[0] / 3;
+ auto c = ctx->ggml_ctx;
+ auto head_dim = dim / heads;
+ auto qkv = std::dynamic_pointer_cast<Linear>(blocks["qkv"])->forward(ctx, x);
+ auto qkv_dim = qkv->ne[0] / 3;
auto split_qkv = [&](int i) {
return ggml_view_4d(c, qkv, head_dim, qkv_dim / head_dim, qkv->ne[1], qkv->ne[2] * qkv->ne[3],
head_dim * qkv->nb[0], qkv->nb[1], qkv->nb[2], i * qkv_dim * qkv->nb[0]);
diff --git a/src/model/diffusion/mmdit.hpp b/src/model/diffusion/mmdit.hpp
index 1f1fed4..250f5f3 100644
--- a/src/model/diffusion/mmdit.hpp
+++ b/src/model/diffusion/mmdit.hpp
@@ -373,7 +373,7 @@ public:
ggml_tensor* x) {
auto qkv = pre_attention(ctx, x);
x = ggml_ext_attention_ext(ctx, qkv[0], qkv[1], qkv[2], num_heads, nullptr, true, ctx->flash_attn_enabled); // [N, n_token, dim]
- x = post_attention(ctx, x); // [N, n_token, dim]
+ x = post_attention(ctx, x); // [N, n_token, dim]
return x;
}
};
diff --git a/src/model/diffusion/seedvr2.hpp b/src/model/diffusion/seedvr2.hpp
index 4cb93bd..dad1e7a 100644
--- a/src/model/diffusion/seedvr2.hpp
+++ b/src/model/diffusion/seedvr2.hpp
@@ -194,17 +194,17 @@ namespace SeedVR2 {
return x;
return std::dynamic_pointer_cast<AdaSingle>(blocks["ada." + branch(text)])->forward(ctx, x, emb, layer, gate);
};
- auto vqkv = linear("attn.proj_qkv", false, ada(ggml_rms_norm(c, vid, 1e-5f), false, "attn"));
- auto tqkv = linear("attn.proj_qkv", true, ada(ggml_rms_norm(c, txt, 1e-5f), true, "attn"));
- vqkv = ggml_get_rows(c, vqkv, inputs.input(ctx, plan.order));
- auto vpe = rotation(ctx, inputs.input(ctx, plan.positions));
- auto tpe = rotation(ctx, inputs.input(ctx, plan.text_positions));
+ auto vqkv = linear("attn.proj_qkv", false, ada(ggml_rms_norm(c, vid, 1e-5f), false, "attn"));
+ auto tqkv = linear("attn.proj_qkv", true, ada(ggml_rms_norm(c, txt, 1e-5f), true, "attn"));
+ vqkv = ggml_get_rows(c, vqkv, inputs.input(ctx, plan.order));
+ auto vpe = rotation(ctx, inputs.input(ctx, plan.positions));
+ auto tpe = rotation(ctx, inputs.input(ctx, plan.text_positions));
auto split_qkv = [&](ggml_tensor* x, int i) {
int64_t qkv_dim = x->ne[0] / 3;
return ggml_view_4d(c, x, 128, qkv_dim / 128, x->ne[1], x->ne[2] * x->ne[3],
128 * x->nb[0], x->nb[1], x->nb[2], i * qkv_dim * x->nb[0]);
};
- auto qkv = [&](ggml_tensor* x, bool text, ggml_tensor* pe) {
+ auto qkv = [&](ggml_tensor* x, bool text, ggml_tensor* pe) {
std::vector<ggml_tensor*> parts{nullptr, nullptr, nullptr};
for (int i = 0; i < 2; ++i) {
auto h = std::dynamic_pointer_cast<RMSNorm>(blocks[std::string(i == 0 ? "attn.norm_q." : "attn.norm_k.") + branch(text)])->forward(ctx, split_qkv(x, i));
@@ -212,8 +212,8 @@ namespace SeedVR2 {
parts[i] = VSR::apply_rope(ctx, h, pe, heads);
}
// v must stay 3-D [dim, L, N]: the window loop slices dim 1 as tokens.
- auto v = split_qkv(x, 2);
- parts[2] = ggml_view_3d(c, v, dim, x->ne[1], x->ne[2], v->nb[2], v->nb[3], 0);
+ auto v = split_qkv(x, 2);
+ parts[2] = ggml_view_3d(c, v, dim, x->ne[1], x->ne[2], v->nb[2], v->nb[3], 0);
return parts;
};
auto vp = qkv(vqkv, false, vpe), tp = qkv(tqkv, true, tpe);
diff --git a/src/model_loader.cpp b/src/model_loader.cpp
index 5987146..9e88711 100644
--- a/src/model_loader.cpp
+++ b/src/model_loader.cpp
@@ -581,7 +581,7 @@ SDVersion ModelLoader::get_sd_version() const {
if (tensor_storage_map.count("model.diffusion_model.audio_patch_proj.weight") == 0) {
return VERSION_MINIMAX_H3_IMAGE;
}
- // P-H3 uses the same DiT architecture as H3; its VAE or connector identifies the image pipeline.
+ // The connector is shared with H3 video; the single-frame VAE identifies P-H3.
auto decoder = tensor_storage_map.find("first_stage_model.decoder.proj_out.weight");
if (decoder == tensor_storage_map.end()) {
decoder = tensor_storage_map.find("vae.decoder.proj_out.weight");
@@ -589,17 +589,6 @@ SDVersion ModelLoader::get_sd_version() const {
if (decoder != tensor_storage_map.end() && decoder->second.ne[1] == 768) {
return VERSION_P_H3_IMAGE;
}
- for (const std::string prefix : {"", "embeddings_connectors."}) {
- if (tensor_storage_map.count(prefix + "text_encoders.ph3_image_connector.proj.weight") ||
- tensor_storage_map.count(prefix + "text_encoders.llm.text_connector.proj.weight")) {
- return VERSION_P_H3_IMAGE;
- }
- }
- auto connector = tensor_storage_map.find("embeddings_connectors.proj.weight");
- if (connector != tensor_storage_map.end() && connector->second.logical_ne0() == 12800 &&
- connector->second.ne[1] == 5120 && tensor_storage_map.count("embeddings_connectors.sink_embedding")) {
- return VERSION_P_H3_IMAGE;
- }
return VERSION_MINIMAX_H3;
}
if (name == "model.diffusion_model.y_embedder.layer_pool.weight" &&
diff --git a/src/name_conversion.cpp b/src/name_conversion.cpp
index d140a54..e791afc 100644
--- a/src/name_conversion.cpp
+++ b/src/name_conversion.cpp
@@ -1741,7 +1741,7 @@ std::string convert_tensor_name(std::string name, SDVersion version) {
const std::vector<std::pair<std::string, std::string>> connector_prefix_map = {
{"embeddings_connectors.text_encoders.", "text_encoders."},
- {"embeddings_connectors.", sd_version_is_minimax_h3_image(version) ? "text_encoders.ph3_image_connector." : ""},
+ {"embeddings_connectors.", sd_version_is_minimax_h3(version) ? "text_encoders.ph3_image_connector." : ""},
};
replace_with_prefix_map(name, connector_prefix_map);