mirror of
https://github.com/leejet/stable-diffusion.cpp.git
synced 2026-09-21 13:38:01 -05:00
feat: support building with upstream ggml (#1999)
This commit is contained in:
+3
-12
@@ -95,6 +95,8 @@ option(SD_MUSA "sd: musa backend" OFF)
|
|||||||
option(SD_BUILD_SHARED_LIBS "sd: build shared libs" OFF)
|
option(SD_BUILD_SHARED_LIBS "sd: build shared libs" OFF)
|
||||||
option(SD_BUILD_SHARED_GGML_LIB "sd: build ggml as a separate shared lib" OFF)
|
option(SD_BUILD_SHARED_GGML_LIB "sd: build ggml as a separate shared lib" OFF)
|
||||||
option(SD_USE_SYSTEM_GGML "sd: use system-installed GGML library" OFF)
|
option(SD_USE_SYSTEM_GGML "sd: use system-installed GGML library" OFF)
|
||||||
|
option(SD_USE_UPSTREAM_GGML "sd: build with upstream GGML instead of the patched GGML extensions" OFF)
|
||||||
|
set(SD_GGML_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ggml" CACHE PATH "sd: ggml source directory (also supplies private headers for system ggml)")
|
||||||
#option(SD_BUILD_SERVER "sd: build server example" ON)
|
#option(SD_BUILD_SERVER "sd: build server example" ON)
|
||||||
|
|
||||||
set(CMAKE_C_STANDARD 11)
|
set(CMAKE_C_STANDARD 11)
|
||||||
@@ -325,18 +327,7 @@ if (NOT SD_USE_SYSTEM_GGML)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
# deps
|
# deps
|
||||||
# Only add ggml if it hasn't been added yet
|
include(cmake/ggml.cmake)
|
||||||
if (NOT TARGET ggml)
|
|
||||||
if (SD_USE_SYSTEM_GGML)
|
|
||||||
find_package(ggml REQUIRED)
|
|
||||||
if (NOT ggml_FOUND)
|
|
||||||
message(FATAL_ERROR "System-installed GGML library not found.")
|
|
||||||
endif()
|
|
||||||
add_library(ggml ALIAS ggml::ggml)
|
|
||||||
else()
|
|
||||||
add_subdirectory(ggml)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_subdirectory(thirdparty)
|
add_subdirectory(thirdparty)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
if(NOT TARGET ggml AND NOT TARGET ggml::ggml)
|
||||||
|
if(SD_USE_SYSTEM_GGML)
|
||||||
|
find_package(ggml REQUIRED)
|
||||||
|
else()
|
||||||
|
add_subdirectory("${SD_GGML_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/ggml")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
if(NOT TARGET ggml)
|
||||||
|
add_library(ggml ALIAS ggml::ggml)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
get_target_property(sd_ggml_imported ggml IMPORTED)
|
||||||
|
if(sd_ggml_imported)
|
||||||
|
set(sd_ggml_private_include "${SD_GGML_SOURCE_DIR}/src")
|
||||||
|
else()
|
||||||
|
get_target_property(sd_ggml_private_include ggml SOURCE_DIR)
|
||||||
|
endif()
|
||||||
|
if(NOT EXISTS "${sd_ggml_private_include}/ggml-impl.h")
|
||||||
|
message(FATAL_ERROR "Set SD_GGML_SOURCE_DIR to the source tree matching the selected ggml library (ggml-impl.h is required).")
|
||||||
|
endif()
|
||||||
|
target_include_directories(${SD_LIB} PRIVATE "${sd_ggml_private_include}")
|
||||||
|
set_property(TARGET ${SD_LIB} PROPERTY SD_GGML_PRIVATE_INCLUDE_DIR "${sd_ggml_private_include}")
|
||||||
|
|
||||||
|
if(SD_USE_UPSTREAM_GGML)
|
||||||
|
target_compile_definitions(${SD_LIB} PUBLIC SD_USE_UPSTREAM_GGML)
|
||||||
|
message(WARNING "Using upstream GGML: FP8 and INT8 tensorwise/convrot are disabled. Some operators may be unsupported and performance may be lower than with patched GGML.")
|
||||||
|
endif()
|
||||||
@@ -16,6 +16,38 @@ git submodule init
|
|||||||
git submodule update
|
git submodule update
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Selecting a GGML source tree
|
||||||
|
|
||||||
|
By default, sd.cpp builds the patched GGML submodule in `ggml/`. To build with
|
||||||
|
an upstream GGML checkout instead, enable `SD_USE_UPSTREAM_GGML` and set
|
||||||
|
`SD_GGML_SOURCE_DIR`:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cmake -S . -B build-upstream -DSD_USE_UPSTREAM_GGML=ON -DSD_GGML_SOURCE_DIR=../ggml-upstream
|
||||||
|
cmake --build build-upstream --config Release
|
||||||
|
```
|
||||||
|
|
||||||
|
The selected source tree supplies both the library and its private headers.
|
||||||
|
Backend options such as `-DSD_CUDA=ON` apply to the selected tree as usual.
|
||||||
|
|
||||||
|
`SD_USE_UPSTREAM_GGML` defaults to `OFF`, which enables the patched GGML
|
||||||
|
extensions. Set it to `ON` when using upstream GGML; it selects the compatibility
|
||||||
|
mode and does not download or replace the GGML source tree. Upstream mode
|
||||||
|
disables FP8 and INT8 tensorwise/convrot and rejects their model files with an
|
||||||
|
explicit error. FP8 weight type requests, tensor type rules and conversion
|
||||||
|
outputs are also rejected; no automatic conversion is performed.
|
||||||
|
|
||||||
|
Upstream GGML may lack some operators and performance optimizations provided by
|
||||||
|
the patched version. A warning is emitted during CMake configuration and when
|
||||||
|
creating an inference context. Ordinary floating-point and shared GGML
|
||||||
|
quantization types remain available, subject to backend operator support.
|
||||||
|
|
||||||
|
`SD_USE_SYSTEM_GGML=ON` instead links an installed GGML CMake package, located
|
||||||
|
with `ggml_DIR` or `CMAKE_PREFIX_PATH`. In that mode, `SD_GGML_SOURCE_DIR` must
|
||||||
|
point to the matching source tree for private headers. The installed library
|
||||||
|
must use the same ABI settings as sd.cpp, including `GGML_MAX_NAME`.
|
||||||
|
Set `SD_USE_UPSTREAM_GGML=ON` as well if the installed package is upstream GGML.
|
||||||
|
|
||||||
## WebP and WebM Support in Examples
|
## WebP and WebM Support in Examples
|
||||||
|
|
||||||
The example applications (`examples/cli` and `examples/server`) use `libwebp` to support WebP image I/O, and `examples/cli` can also use `libwebm` for `.webm` video output. Both are enabled by default. WebM output currently reuses `libwebp` to encode each frame as VP8 before muxing with `libwebm`.
|
The example applications (`examples/cli` and `examples/server`) use `libwebp` to support WebP image I/O, and `examples/cli` can also use `libwebm` for `.webm` video output. Both are enabled by default. WebM output currently reuses `libwebp` to encode each frame as VP8 before muxing with `libwebm`.
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
sd.cpp can load and execute ComfyUI `int8_tensorwise` safetensors with `convrot` metadata directly. The stored INT8 weights are not converted to another weight type at load time.
|
sd.cpp can load and execute ComfyUI `int8_tensorwise` safetensors with `convrot` metadata directly. The stored INT8 weights are not converted to another weight type at load time.
|
||||||
|
|
||||||
|
This requires the INT8 tensorwise/convrot extensions in the patched GGML.
|
||||||
|
Builds with `SD_USE_UPSTREAM_GGML=ON` reject these files during loading.
|
||||||
|
|
||||||
## Checkpoint format
|
## Checkpoint format
|
||||||
|
|
||||||
Each quantized linear module contains the following tensors:
|
Each quantized linear module contains the following tensors:
|
||||||
|
|||||||
@@ -362,6 +362,9 @@ bool convert_with_components(const char* model_path,
|
|||||||
const char* tensor_type_rules,
|
const char* tensor_type_rules,
|
||||||
bool convert_name,
|
bool convert_name,
|
||||||
int n_threads) {
|
int n_threads) {
|
||||||
|
if (!validate_tensor_types(output_type, tensor_type_rules)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
ModelLoader model_loader;
|
ModelLoader model_loader;
|
||||||
bool loaded_any = false;
|
bool loaded_any = false;
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
#include "core/ggml_graph_cut.h"
|
#include "core/ggml_graph_cut.h"
|
||||||
#include "core/util.h"
|
#include "core/util.h"
|
||||||
#include "ggml-cpu.h"
|
#include "ggml-cpu.h"
|
||||||
#include "ggml/src/ggml-impl.h"
|
#include "ggml-impl.h"
|
||||||
|
|
||||||
namespace sd {
|
namespace sd {
|
||||||
ComputeWorkspace::~ComputeWorkspace() {
|
ComputeWorkspace::~ComputeWorkspace() {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "core/ggml_extend.h"
|
#include "core/ggml_extend.h"
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <stdexcept>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "core/ggml_extend_backend.h"
|
#include "core/ggml_extend_backend.h"
|
||||||
@@ -247,6 +248,7 @@ ggml_tensor* ggml_ext_linear_i8_tensorwise(ggml_context* ctx,
|
|||||||
ggml_tensor* b,
|
ggml_tensor* b,
|
||||||
int convrot_group_size,
|
int convrot_group_size,
|
||||||
float scale) {
|
float scale) {
|
||||||
|
#ifndef SD_USE_UPSTREAM_GGML
|
||||||
GGML_ASSERT(x->type == GGML_TYPE_F32 || (x->type == GGML_TYPE_I8 && scale == 1.f));
|
GGML_ASSERT(x->type == GGML_TYPE_F32 || (x->type == GGML_TYPE_I8 && scale == 1.f));
|
||||||
if (scale != 1.f) {
|
if (scale != 1.f) {
|
||||||
x = ggml_ext_scale(ctx, x, scale);
|
x = ggml_ext_scale(ctx, x, scale);
|
||||||
@@ -270,6 +272,16 @@ ggml_tensor* ggml_ext_linear_i8_tensorwise(ggml_context* ctx,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return x;
|
return x;
|
||||||
|
#else
|
||||||
|
GGML_UNUSED(ctx);
|
||||||
|
GGML_UNUSED(x);
|
||||||
|
GGML_UNUSED(w);
|
||||||
|
GGML_UNUSED(weight_scale);
|
||||||
|
GGML_UNUSED(b);
|
||||||
|
GGML_UNUSED(convrot_group_size);
|
||||||
|
GGML_UNUSED(scale);
|
||||||
|
throw std::runtime_error("INT8 tensorwise/convrot is not supported by this ggml build");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ggml_tensor* ggml_ext_pad_ext(ggml_context* ctx,
|
ggml_tensor* ggml_ext_pad_ext(ggml_context* ctx,
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "core/util.h"
|
#include "core/util.h"
|
||||||
#include "ggml/src/ggml-impl.h"
|
#include "ggml-impl.h"
|
||||||
#include "stable-diffusion.h"
|
#include "stable-diffusion.h"
|
||||||
|
|
||||||
static std::string trim_copy(const std::string& value) {
|
static std::string trim_copy(const std::string& value) {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
#include "ggml-alloc.h"
|
#include "ggml-alloc.h"
|
||||||
#include "ggml-backend.h"
|
#include "ggml-backend.h"
|
||||||
|
|
||||||
#include "ggml/src/ggml-impl.h"
|
#include "ggml-impl.h"
|
||||||
|
|
||||||
namespace sd::ggml_graph_cut {
|
namespace sd::ggml_graph_cut {
|
||||||
|
|
||||||
|
|||||||
+30
-1
@@ -414,14 +414,43 @@ std::vector<std::string> split_string(const std::string& str, char delimiter) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ggml_type sd_type_to_ggml_type(sd_type_t sdtype) {
|
ggml_type sd_type_to_ggml_type(sd_type_t sdtype) {
|
||||||
|
if (sdtype == SD_TYPE_F8_E4M3 || sdtype == SD_TYPE_F8_E5M2) {
|
||||||
|
#ifndef SD_USE_UPSTREAM_GGML
|
||||||
|
return sdtype == SD_TYPE_F8_E4M3 ? GGML_TYPE_F8_E4M3 : GGML_TYPE_F8_E5M2;
|
||||||
|
#else
|
||||||
|
return GGML_TYPE_COUNT;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
const int type_value = static_cast<int>(sdtype);
|
const int type_value = static_cast<int>(sdtype);
|
||||||
if (type_value < std::min<int>(SD_TYPE_COUNT, GGML_TYPE_COUNT)) {
|
if (type_value >= 0 && type_value < std::min<int>(SD_TYPE_COUNT, GGML_TYPE_COUNT)) {
|
||||||
return static_cast<ggml_type>(type_value);
|
return static_cast<ggml_type>(type_value);
|
||||||
} else {
|
} else {
|
||||||
return GGML_TYPE_COUNT;
|
return GGML_TYPE_COUNT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool validate_tensor_types(sd_type_t type, const char* tensor_type_rules) {
|
||||||
|
if (type != SD_TYPE_COUNT && sd_type_to_ggml_type(type) == GGML_TYPE_COUNT) {
|
||||||
|
LOG_ERROR("weight type %s is not supported by this ggml build", sd_type_name(type));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#ifdef SD_USE_UPSTREAM_GGML
|
||||||
|
for (const auto& rule : split_string(SAFE_STR(tensor_type_rules), ',')) {
|
||||||
|
const auto pos = rule.find('=');
|
||||||
|
if (pos != std::string::npos) {
|
||||||
|
const auto name = rule.substr(pos + 1);
|
||||||
|
if (name == "f8_e4m3" || name == "f8_e5m2") {
|
||||||
|
LOG_ERROR("FP8 is not supported by this ggml build (tensor type rule '%s')", rule.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
GGML_UNUSED(tensor_type_rules);
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
KeyValueArgs parse_key_value_args(const char* args, const char* context) {
|
KeyValueArgs parse_key_value_args(const char* args, const char* context) {
|
||||||
KeyValueArgs pairs;
|
KeyValueArgs pairs;
|
||||||
|
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ void log_printf(sd_log_level_t level, const char* file, int line, const char* fo
|
|||||||
void sd_ggml_log_callback(ggml_log_level level, const char* text, void*);
|
void sd_ggml_log_callback(ggml_log_level level, const char* text, void*);
|
||||||
|
|
||||||
ggml_type sd_type_to_ggml_type(sd_type_t sdtype);
|
ggml_type sd_type_to_ggml_type(sd_type_t sdtype);
|
||||||
|
bool validate_tensor_types(sd_type_t type, const char* tensor_type_rules);
|
||||||
|
|
||||||
std::string trim(const std::string& s);
|
std::string trim(const std::string& s);
|
||||||
|
|
||||||
|
|||||||
@@ -208,6 +208,7 @@ public:
|
|||||||
ggml_tensor* w = params["weight"];
|
ggml_tensor* w = params["weight"];
|
||||||
const float scale = ctx->linear_scale > 0.f ? ctx->linear_scale : this->scale;
|
const float scale = ctx->linear_scale > 0.f ? ctx->linear_scale : this->scale;
|
||||||
ggml_tensor* weight_scale = has_weight_scale ? params["weight_scale"] : nullptr;
|
ggml_tensor* weight_scale = has_weight_scale ? params["weight_scale"] : nullptr;
|
||||||
|
#ifndef SD_USE_UPSTREAM_GGML
|
||||||
if (w->type == GGML_TYPE_F8_E4M3 || w->type == GGML_TYPE_F8_E5M2) {
|
if (w->type == GGML_TYPE_F8_E4M3 || w->type == GGML_TYPE_F8_E5M2) {
|
||||||
bool supports_fp8_matmul = false;
|
bool supports_fp8_matmul = false;
|
||||||
if (ctx->backend != nullptr) {
|
if (ctx->backend != nullptr) {
|
||||||
@@ -221,6 +222,7 @@ public:
|
|||||||
w = ggml_cast(ctx->ggml_ctx, w, GGML_TYPE_BF16);
|
w = ggml_cast(ctx->ggml_ctx, w, GGML_TYPE_BF16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
ggml_tensor* b = nullptr;
|
ggml_tensor* b = nullptr;
|
||||||
if (bias) {
|
if (bias) {
|
||||||
b = params["bias"];
|
b = params["bias"];
|
||||||
@@ -238,6 +240,7 @@ public:
|
|||||||
if (ctx->weight_adapter && b != nullptr) {
|
if (ctx->weight_adapter && b != nullptr) {
|
||||||
b = ctx->weight_adapter->patch_weight(ctx->ggml_ctx, ctx->backend, b, prefix + "bias");
|
b = ctx->weight_adapter->patch_weight(ctx->ggml_ctx, ctx->backend, b, prefix + "bias");
|
||||||
}
|
}
|
||||||
|
#ifndef SD_USE_UPSTREAM_GGML
|
||||||
if (int8_convrot && scale == 1.f) {
|
if (int8_convrot && scale == 1.f) {
|
||||||
const auto cache_key = std::make_pair(x, int8_convrot_group_size);
|
const auto cache_key = std::make_pair(x, int8_convrot_group_size);
|
||||||
auto cached = ctx->int8_convrot_cache.find(cache_key);
|
auto cached = ctx->int8_convrot_cache.find(cache_key);
|
||||||
@@ -248,6 +251,7 @@ public:
|
|||||||
x = cached->second;
|
x = cached->second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
out = ggml_ext_linear_i8_tensorwise(ctx->ggml_ctx,
|
out = ggml_ext_linear_i8_tensorwise(ctx->ggml_ctx,
|
||||||
x,
|
x,
|
||||||
w,
|
w,
|
||||||
|
|||||||
@@ -57,6 +57,18 @@ bool read_gguf_file(const std::string& file_path,
|
|||||||
|
|
||||||
size_t data_offset = gguf_reader.data_offset();
|
size_t data_offset = gguf_reader.data_offset();
|
||||||
for (const auto& gguf_tensor_info : gguf_reader.tensors()) {
|
for (const auto& gguf_tensor_info : gguf_reader.tensors()) {
|
||||||
|
#ifdef SD_USE_UPSTREAM_GGML
|
||||||
|
if (static_cast<int>(gguf_tensor_info.type) == SD_TYPE_F8_E4M3 ||
|
||||||
|
static_cast<int>(gguf_tensor_info.type) == SD_TYPE_F8_E5M2) {
|
||||||
|
set_error(error, "FP8 is not supported by this ggml build (tensor '" + gguf_tensor_info.name + "')");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (static_cast<unsigned>(gguf_tensor_info.type) >= GGML_TYPE_COUNT ||
|
||||||
|
ggml_get_type_traits(gguf_tensor_info.type)->type_size == 0) {
|
||||||
|
set_error(error, "unsupported GGUF tensor type (tensor '" + gguf_tensor_info.name + "')");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
TensorStorage tensor_storage(
|
TensorStorage tensor_storage(
|
||||||
gguf_tensor_info.name,
|
gguf_tensor_info.name,
|
||||||
gguf_tensor_info.type,
|
gguf_tensor_info.type,
|
||||||
|
|||||||
@@ -86,10 +86,12 @@ static ggml_type safetensors_dtype_to_ggml_type(const std::string& dtype) {
|
|||||||
ttype = GGML_TYPE_F32;
|
ttype = GGML_TYPE_F32;
|
||||||
} else if (dtype == "F64") {
|
} else if (dtype == "F64") {
|
||||||
ttype = GGML_TYPE_F32;
|
ttype = GGML_TYPE_F32;
|
||||||
|
#ifndef SD_USE_UPSTREAM_GGML
|
||||||
} else if (dtype == "F8_E4M3") {
|
} else if (dtype == "F8_E4M3") {
|
||||||
ttype = GGML_TYPE_F8_E4M3;
|
ttype = GGML_TYPE_F8_E4M3;
|
||||||
} else if (dtype == "F8_E5M2") {
|
} else if (dtype == "F8_E5M2") {
|
||||||
ttype = GGML_TYPE_F8_E5M2;
|
ttype = GGML_TYPE_F8_E5M2;
|
||||||
|
#endif
|
||||||
} else if (dtype == "I32") {
|
} else if (dtype == "I32") {
|
||||||
ttype = GGML_TYPE_I32;
|
ttype = GGML_TYPE_I32;
|
||||||
} else if (dtype == "I64") {
|
} else if (dtype == "I64") {
|
||||||
@@ -230,6 +232,12 @@ bool read_safetensors_file(const std::string& file_path,
|
|||||||
if (!read_comfy_quant_config(file, file_path, name, data_start + begin, end - begin, config, error)) {
|
if (!read_comfy_quant_config(file, file_path, name, data_start + begin, end - begin, config, error)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#ifdef SD_USE_UPSTREAM_GGML
|
||||||
|
if (config.format == "int8_tensorwise") {
|
||||||
|
set_error(error, "INT8 tensorwise/convrot is not supported by this ggml build (tensor '" + name + "')");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
const std::string module_name = name.substr(0, name.size() - std::string(".comfy_quant").size());
|
const std::string module_name = name.substr(0, name.size() - std::string(".comfy_quant").size());
|
||||||
comfy_quant_configs.emplace(module_name, std::move(config));
|
comfy_quant_configs.emplace(module_name, std::move(config));
|
||||||
}
|
}
|
||||||
@@ -279,6 +287,12 @@ bool read_safetensors_file(const std::string& file_path,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef SD_USE_UPSTREAM_GGML
|
||||||
|
if (dtype == "F8_E4M3" || dtype == "F8_E5M2") {
|
||||||
|
set_error(error, "FP8 is not supported by this ggml build (tensor '" + name + "')");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
ggml_type type = safetensors_dtype_to_ggml_type(dtype);
|
ggml_type type = safetensors_dtype_to_ggml_type(dtype);
|
||||||
if (type == GGML_TYPE_COUNT) {
|
if (type == GGML_TYPE_COUNT) {
|
||||||
set_error(error, "unsupported dtype '" + dtype + "' (tensor '" + name + "')");
|
set_error(error, "unsupported dtype '" + dtype + "' (tensor '" + name + "')");
|
||||||
|
|||||||
@@ -857,6 +857,14 @@ bool StableDiffusionGGML::init_model_loader(ModelLoader& model_loader, ModelConf
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool StableDiffusionGGML::init(const sd_ctx_params_t* sd_ctx_params) {
|
bool StableDiffusionGGML::init(const sd_ctx_params_t* sd_ctx_params) {
|
||||||
|
#ifdef SD_USE_UPSTREAM_GGML
|
||||||
|
LOG_WARN(
|
||||||
|
"Using upstream GGML: FP8 and INT8 tensorwise/convrot are disabled. "
|
||||||
|
"Some operators may be unsupported and performance may be lower than with patched GGML.");
|
||||||
|
#endif
|
||||||
|
if (!validate_tensor_types(sd_ctx_params->wtype, sd_ctx_params->tensor_type_rules)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
for (float scale : {sd_ctx_params->linear_scale, sd_ctx_params->attn_scale}) {
|
for (float scale : {sd_ctx_params->linear_scale, sd_ctx_params->attn_scale}) {
|
||||||
if (!std::isfinite(scale) || scale < 0.f || (scale > 0.f && !std::isfinite(1.f / scale))) {
|
if (!std::isfinite(scale) || scale < 0.f || (scale > 0.f && !std::isfinite(1.f / scale))) {
|
||||||
LOG_ERROR("scale overrides must be finite positive values, or 0 to keep model defaults");
|
LOG_ERROR("scale overrides must be finite positive values, or 0 to keep model defaults");
|
||||||
|
|||||||
@@ -26,13 +26,26 @@ static float get_cache_reuse_threshold(const sd_cache_params_t& params) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const char* sd_type_name(enum sd_type_t type) {
|
const char* sd_type_name(enum sd_type_t type) {
|
||||||
if ((int)type < std::min<int>(SD_TYPE_COUNT, GGML_TYPE_COUNT)) {
|
if (type == SD_TYPE_F8_E4M3) {
|
||||||
return ggml_type_name((ggml_type)type);
|
return "f8_e4m3";
|
||||||
|
}
|
||||||
|
if (type == SD_TYPE_F8_E5M2) {
|
||||||
|
return "f8_e5m2";
|
||||||
|
}
|
||||||
|
const auto ggml_type = sd_type_to_ggml_type(type);
|
||||||
|
if (ggml_type != GGML_TYPE_COUNT) {
|
||||||
|
return ggml_type_name(ggml_type);
|
||||||
}
|
}
|
||||||
return NONE_STR;
|
return NONE_STR;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum sd_type_t str_to_sd_type(const char* str) {
|
enum sd_type_t str_to_sd_type(const char* str) {
|
||||||
|
if (!strcmp(str, "f8_e4m3")) {
|
||||||
|
return SD_TYPE_F8_E4M3;
|
||||||
|
}
|
||||||
|
if (!strcmp(str, "f8_e5m2")) {
|
||||||
|
return SD_TYPE_F8_E5M2;
|
||||||
|
}
|
||||||
for (int i = 0; i < std::min<int>(SD_TYPE_COUNT, GGML_TYPE_COUNT); i++) {
|
for (int i = 0; i < std::min<int>(SD_TYPE_COUNT, GGML_TYPE_COUNT); i++) {
|
||||||
auto trait = ggml_get_type_traits((ggml_type)i);
|
auto trait = ggml_get_type_traits((ggml_type)i);
|
||||||
if (!strcmp(str, trait->type_name)) {
|
if (!strcmp(str, trait->type_name)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user