mirror of
https://github.com/LostRuins/koboldcpp.git
synced 2026-09-19 17:25:07 +02:00
sd: sync with master-690-3a54597 (#2270)
* sd: sync with master-690-3a54597 * sd: drop Chroma workaround for Flash Attention Fixed in master-686-1b702a5 . * sd: skip setting cpu flags (soon to be removed)
This commit is contained in:
@@ -491,6 +491,10 @@ SD_API bool preprocess_canny(sd_image_t image,
|
||||
SD_API const char* sd_commit(void);
|
||||
SD_API const char* sd_version(void);
|
||||
|
||||
// for C API, caller needs to call free_sd_images to free the memory after use
|
||||
// This helps avoid CRT problems on Windows when memory is allocated in the library but freed in the caller, which may use a different CRT.
|
||||
SD_API void free_sd_images(sd_image_t* result_images, int num_images);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -124,8 +124,6 @@ struct SDParams {
|
||||
bool diffusion_conv_direct = false;
|
||||
bool vae_conv_direct = false;
|
||||
|
||||
bool chroma_use_dit_mask = true;
|
||||
|
||||
LoraMap lora_map;
|
||||
bool lora_dynamic = false;
|
||||
|
||||
@@ -481,17 +479,12 @@ bool sdtype_load_model(const sd_load_model_inputs inputs) {
|
||||
params.diffusion_flash_attn = sd_params->diffusion_flash_attn;
|
||||
params.diffusion_conv_direct = sd_params->diffusion_conv_direct;
|
||||
params.vae_conv_direct = sd_params->vae_conv_direct;
|
||||
params.chroma_use_dit_mask = sd_params->chroma_use_dit_mask;
|
||||
params.chroma_use_dit_mask = true;
|
||||
params.max_vram = inputs.max_vram;
|
||||
params.stream_layers = inputs.stream_layers;
|
||||
params.enable_mmap = inputs.use_mmap;
|
||||
// the _cpu flags are only used if the backend string is empty, but
|
||||
// we always set both for consistency
|
||||
params.offload_params_to_cpu = inputs.offload_cpu;
|
||||
params.params_backend = inputs.offload_cpu ? "CPU" : "";
|
||||
params.keep_vae_on_cpu = (inputs.kcpp_vae_device <= -2);
|
||||
backends += get_device_override(inputs.kcpp_vae_device, "VAE");
|
||||
params.keep_clip_on_cpu = (inputs.kcpp_clip_device <= -2);
|
||||
backends += get_device_override(inputs.kcpp_clip_device, "CLIP");
|
||||
if (backends.rfind(",", 0) == 0) {
|
||||
backends = "auto" + backends;
|
||||
@@ -505,11 +498,6 @@ bool sdtype_load_model(const sd_load_model_inputs inputs) {
|
||||
// also switches flash attn for the vae and conditioner
|
||||
params.flash_attn = params.diffusion_flash_attn;
|
||||
|
||||
if (params.chroma_use_dit_mask && params.diffusion_flash_attn) {
|
||||
// note we don't know yet if it's a Chroma model
|
||||
params.chroma_use_dit_mask = false;
|
||||
}
|
||||
|
||||
if(inputs.debugmode==1)
|
||||
{
|
||||
char* buf = sd_ctx_params_to_str(¶ms);
|
||||
@@ -529,14 +517,6 @@ bool sdtype_load_model(const sd_load_model_inputs inputs) {
|
||||
|
||||
auto info = get_model_info(sd_ctx);
|
||||
|
||||
if (!sd_is_quiet) {
|
||||
if (info.is_chroma && sd_params->diffusion_flash_attn && sd_params->chroma_use_dit_mask)
|
||||
{
|
||||
printf("Chroma: flash attention is on, disabling DiT mask (this will lower image quality)\n");
|
||||
// disabled before loading
|
||||
}
|
||||
}
|
||||
|
||||
if (info.is_wan || info.is_ltx)
|
||||
{
|
||||
printf("\nSetting to Video Generation Mode!\n");
|
||||
@@ -559,7 +539,7 @@ bool sdtype_load_model(const sd_load_model_inputs inputs) {
|
||||
if (upscaler_filename!="") {
|
||||
const int upscale_tile_size = 128;
|
||||
upscaler_ctx = new_upscaler_ctx(upscaler_filename.c_str(),
|
||||
params.offload_params_to_cpu,
|
||||
inputs.offload_cpu,
|
||||
params.diffusion_conv_direct,
|
||||
params.n_threads,
|
||||
upscale_tile_size,
|
||||
|
||||
@@ -853,7 +853,7 @@ struct SD3CLIPEmbedder : public Conditioner {
|
||||
} else {
|
||||
chunk_hidden_states_l = sd::Tensor<float>::zeros({768, static_cast<int64_t>(chunk_len), 1});
|
||||
if (chunk_idx == 0) {
|
||||
pooled = sd::Tensor<float>::zeros({768, 1});
|
||||
pooled_l = sd::Tensor<float>::zeros({768, 1});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1346,10 +1346,18 @@ __STATIC_INLINE__ ggml_tensor* ggml_ext_attention_ext(ggml_context* ctx,
|
||||
v_in = ggml_cast(ctx, v_in, GGML_TYPE_F16);
|
||||
|
||||
if (mask_in != nullptr) {
|
||||
mask_in = ggml_transpose(ctx, mask_in);
|
||||
}
|
||||
|
||||
if (mask_in != nullptr) {
|
||||
// ggml_flash_attn_ext expects the mask as a contiguous F16 tensor shaped
|
||||
// [n_kv, n_q, (heads), (batch)] (ne0 = key length, ne1 = query length) and,
|
||||
// unlike the manual-attention path, does not broadcast the query dimension.
|
||||
// Some callers (e.g. Chroma/T5) pass a per-key padding mask broadcast over
|
||||
// queries ([n_kv, 1, ...]); materialize the query dimension to L_q so the
|
||||
// kernel indexes it correctly. (A bare ggml_transpose here produced a
|
||||
// [1, n_kv, ...] mask that the kernel silently misreads, yielding NaN/blank
|
||||
// output for masked flash attention.)
|
||||
if (mask_in->ne[1] != L_q) {
|
||||
mask_in = ggml_repeat(ctx, mask_in,
|
||||
ggml_new_tensor_4d(ctx, mask_in->type, mask_in->ne[0], L_q, mask_in->ne[2], mask_in->ne[3]));
|
||||
}
|
||||
mask_in = ggml_cast(ctx, mask_in, GGML_TYPE_F16);
|
||||
}
|
||||
|
||||
|
||||
@@ -253,7 +253,8 @@ namespace Rope {
|
||||
int bs,
|
||||
float theta,
|
||||
int head_dim,
|
||||
const std::vector<int>& mrope_section) {
|
||||
const std::vector<int>& mrope_section,
|
||||
const std::vector<std::vector<int>>& axis_wrap_dims = {}) {
|
||||
GGML_ASSERT(bs > 0);
|
||||
GGML_ASSERT(head_dim % 2 == 0);
|
||||
GGML_ASSERT(mrope_section.size() >= 3);
|
||||
@@ -265,7 +266,11 @@ namespace Rope {
|
||||
std::vector<std::vector<std::vector<float>>> axis_embs;
|
||||
axis_embs.reserve(3);
|
||||
for (int axis = 0; axis < 3; ++axis) {
|
||||
axis_embs.push_back(rope(trans_ids[axis], head_dim, theta));
|
||||
std::vector<int> axis_wrap;
|
||||
if (axis < static_cast<int>(axis_wrap_dims.size())) {
|
||||
axis_wrap = axis_wrap_dims[axis];
|
||||
}
|
||||
axis_embs.push_back(rope(trans_ids[axis], head_dim, theta, axis_wrap));
|
||||
}
|
||||
|
||||
std::vector<std::vector<float>> emb = axis_embs[0];
|
||||
|
||||
@@ -151,7 +151,9 @@ namespace Ideogram4 {
|
||||
int context_len,
|
||||
int head_dim,
|
||||
int rope_theta,
|
||||
const std::vector<int>& mrope_section) {
|
||||
const std::vector<int>& mrope_section,
|
||||
bool circular_x = false,
|
||||
bool circular_y = false) {
|
||||
GGML_ASSERT(bs == 1);
|
||||
std::vector<std::vector<float>> ids(static_cast<size_t>(bs) * (context_len + grid_h * grid_w),
|
||||
std::vector<float>(3, 0.f));
|
||||
@@ -169,7 +171,29 @@ namespace Ideogram4 {
|
||||
}
|
||||
}
|
||||
|
||||
return Rope::embed_interleaved_mrope(ids, bs, static_cast<float>(rope_theta), head_dim, mrope_section);
|
||||
std::vector<std::vector<int>> axis_wrap_dims(3);
|
||||
if (circular_y || circular_x) {
|
||||
size_t total_len = static_cast<size_t>(bs) * (context_len + grid_h * grid_w);
|
||||
axis_wrap_dims[1].assign(total_len, 0);
|
||||
axis_wrap_dims[2].assign(total_len, 0);
|
||||
if (circular_y) {
|
||||
for (size_t idx = static_cast<size_t>(context_len); idx < total_len; ++idx) {
|
||||
axis_wrap_dims[1][idx] = grid_h;
|
||||
}
|
||||
}
|
||||
if (circular_x) {
|
||||
for (size_t idx = static_cast<size_t>(context_len); idx < total_len; ++idx) {
|
||||
axis_wrap_dims[2][idx] = grid_w;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Rope::embed_interleaved_mrope(ids,
|
||||
bs,
|
||||
static_cast<float>(rope_theta),
|
||||
head_dim,
|
||||
mrope_section,
|
||||
axis_wrap_dims);
|
||||
}
|
||||
|
||||
class Ideogram4Attention : public GGMLBlock {
|
||||
@@ -480,13 +504,16 @@ namespace Ideogram4 {
|
||||
int64_t pos_len = context_len + grid_h * grid_w;
|
||||
int64_t head_dim = config.emb_dim / config.num_heads;
|
||||
|
||||
auto runner_ctx = get_context();
|
||||
pe_vec = gen_ideogram4_pe(static_cast<int>(grid_h),
|
||||
static_cast<int>(grid_w),
|
||||
static_cast<int>(x->ne[3]),
|
||||
static_cast<int>(context_len),
|
||||
static_cast<int>(head_dim),
|
||||
static_cast<int>(config.rope_theta),
|
||||
config.mrope_section);
|
||||
config.mrope_section,
|
||||
runner_ctx.circular_x_enabled,
|
||||
runner_ctx.circular_y_enabled);
|
||||
auto pe = ggml_new_tensor_4d(compute_ctx, GGML_TYPE_F32, 2, 2, head_dim / 2, pos_len);
|
||||
set_backend_tensor_data(pe, pe_vec.data());
|
||||
|
||||
@@ -497,7 +524,6 @@ namespace Ideogram4 {
|
||||
auto indicator = ggml_new_tensor_2d(compute_ctx, GGML_TYPE_I32, pos_len, x->ne[3]);
|
||||
set_backend_tensor_data(indicator, image_indicator_vec.data());
|
||||
|
||||
auto runner_ctx = get_context();
|
||||
ggml_tensor* out = active_model.forward(&runner_ctx, x, timesteps, context, pe, indicator);
|
||||
ggml_build_forward_expand(gf, out);
|
||||
return gf;
|
||||
|
||||
@@ -813,15 +813,6 @@ public:
|
||||
}
|
||||
}
|
||||
if (is_chroma) {
|
||||
if ((sd_ctx_params->flash_attn || sd_ctx_params->diffusion_flash_attn) && sd_ctx_params->chroma_use_dit_mask) {
|
||||
LOG_WARN(
|
||||
"!!!It looks like you are using Chroma with flash attention. "
|
||||
"This is currently unsupported. "
|
||||
"If you find that the generated images are broken, "
|
||||
"try either disabling flash attention or specifying "
|
||||
"--chroma-disable-dit-mask as a workaround.");
|
||||
}
|
||||
|
||||
cond_stage_model = std::make_shared<T5CLIPEmbedder>(backend_for(SDBackendModule::TE),
|
||||
params_backend_for(SDBackendModule::TE),
|
||||
tensor_storage_map,
|
||||
@@ -5848,6 +5839,20 @@ SD_API bool generate_video(sd_ctx_t* sd_ctx,
|
||||
return true;
|
||||
}
|
||||
|
||||
SD_API void free_sd_images(sd_image_t* result_images, int num_images) {
|
||||
if (result_images == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < num_images; ++i) {
|
||||
if (result_images[i].data != nullptr) {
|
||||
free(result_images[i].data);
|
||||
result_images[i].data = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
free(result_images);
|
||||
}
|
||||
|
||||
#include "kcpp_sd_extensions.h"
|
||||
|
||||
@@ -5909,4 +5914,3 @@ namespace kcpp_sd {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user