Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 18 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ endif()

FetchContent_Declare(
stable-diffusion-cpp
GIT_REPOSITORY https://github.com/lmagder/stable-diffusion.cpp.git
GIT_TAG f974370e049da45866d70f45673c5453e089251b # fix-untyped-tensors
GIT_REPOSITORY https://github.com/leejet/stable-diffusion.cpp.git
GIT_TAG ac54e0076052a196b7df961eb1f792c9ff4d7f22 # sd 3.5 support
)

FetchContent_Declare(
Expand All @@ -30,8 +30,22 @@ FetchContent_Declare(
GIT_TAG f9ff166845a59327eda431af82ee85a9c7532c5d
)

find_package(Vulkan QUIET)
if(NOT WIN32 AND NOT Vulkan_FOUND)
if(EXISTS ${CMAKE_SYSROOT}/usr/lib/x86_64-linux-gnu/libvulkan.so)
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason to not try find_package(Vulkan) first and only do this if !Vulkan_FOUND or does find_package find the wrong thing? I know I had some weird issues on GH actions runners with CUDA.

set(Vulkan_INCLUDE_DIR ${CMAKE_SYSROOT}/usr/include)
set(Vulkan_LIBRARY ${CMAKE_SYSROOT}/usr/lib/x86_64-linux-gnu/libvulkan.so)
find_package(Vulkan)
endif()
endif()

if(Vulkan_FOUND)
set(SD_FLASH_ATTN ON)
set(SD_VULKAN ON)
endif()

set(IMPLIB_SOURCE_FILES "")
if (CUDAToolkit_FOUND)
if (CUDAToolkit_FOUND AND NOT Vulkan_FOUND)
set(SD_CUBLAS ON)
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need to check !Vulkan_FOUND to disable the CUDA paths here? I don't think one binary can support both in GGML currently.

Same for all the if (CUDAToolkit_FOUND)s

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right its either/or. I updated it like you suggested, so it will build with Vulkan if its installed and disable CUDA in that case.

set(SD_FLASH_ATTN ON)
set(GGML_CUDA_F16 ON)
Expand Down Expand Up @@ -87,7 +101,7 @@ target_compile_definitions(node-stable-diffusion-cpp PRIVATE NAPI_VERSION=9 NODE

target_link_libraries(node-stable-diffusion-cpp ${CMAKE_JS_LIB} stable-diffusion)

if (CUDAToolkit_FOUND)
if (CUDAToolkit_FOUND AND NOT Vulkan_FOUND)
file(GENERATE OUTPUT $<TARGET_FILE_DIR:node-stable-diffusion-cpp>/cuda_version.json INPUT ${CUDAToolkit_LIBRARY_ROOT}/version.json)
else()
file(GENERATE OUTPUT $<TARGET_FILE_DIR:node-stable-diffusion-cpp>/cuda_version.json CONTENT "{}")
Expand All @@ -98,5 +112,3 @@ if(MSVC AND CMAKE_JS_NODELIB_DEF AND CMAKE_JS_NODELIB_TARGET)
execute_process(COMMAND ${CMAKE_AR} /def:${CMAKE_JS_NODELIB_DEF} /out:${CMAKE_JS_NODELIB_TARGET} ${CMAKE_STATIC_LINKER_FLAGS})
target_link_options(node-stable-diffusion-cpp PRIVATE "/DELAYLOAD:nvcuda.dll")
endif()


4 changes: 3 additions & 1 deletion cudadeps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,10 @@ if (fs.existsSync(versionListPath) && process.env.npm_command !== "ci") {
const versionList = JSON.parse(fs.readFileSync(versionListPath, { encoding: "utf8" }));
const versionListHash = hasher({ sort: true }).hash(versionList) + "_" + cudaSubfolder;
const downloadMarkerPath = path.join(resolvedPath, downloadMarkerFile);
const componentCount = Object.keys(versionList).length;
const needsDownload = !fs.existsSync(downloadMarkerPath) || fs.readFileSync(downloadMarkerPath).toString() !== versionListHash;

if (!fs.existsSync(downloadMarkerPath) || fs.readFileSync(downloadMarkerPath).toString() !== versionListHash) {
if (componentCount > 0 && needsDownload) {
console.info(`Downloading components ${components} for ${arch} - ${platform}`);

for (const componentId of components) {
Expand Down
11 changes: 10 additions & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,16 @@ declare module "@lmagder/node-stable-diffusion-cpp" {
DPMPP2M,
DPMPP2Mv2,
LCM,
IPNDM,
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to add these new values to sampleMethodEnum.DefineProperties() also in the C++ code

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops missed that, thanks for catching.

IPNDM_V
}

declare enum Schedule {
Default,
Discrete,
Karras,
AYS,
GITS,
}

declare enum Type {
Expand Down Expand Up @@ -66,6 +69,7 @@ declare module "@lmagder/node-stable-diffusion-cpp" {
negativePrompt?: string;
clipSkip?: number;
cfgScale?: number;
guidance?: number;
width?: number;
height?: number;
sampleMethod?: SampleMethod;
Expand All @@ -84,6 +88,7 @@ declare module "@lmagder/node-stable-diffusion-cpp" {
negativePrompt?: string;
clipSkip?: number;
cfgScale?: number;
guidance?: number;
width?: number;
height?: number;
sampleMethod?: SampleMethod;
Expand Down Expand Up @@ -116,7 +121,11 @@ declare module "@lmagder/node-stable-diffusion-cpp" {

export const createContext: (
params: {
model: string;
model?: string;
clipL?: string;
clipG?: string;
t5xxl?: string;
diffusionModel?: string;
vae?: string;
taesd?: string;
controlNet?: string;
Expand Down
87 changes: 80 additions & 7 deletions src/NodeModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ namespace

return ret;
}

class NodeStableDiffusionCpp : public Napi::Addon<NodeStableDiffusionCpp>
{
public:
Expand All @@ -268,6 +268,8 @@ namespace
Napi::PropertyDescriptor::Value("DPMPP2M", Napi::Number::New(env, DPMPP2M)),
Napi::PropertyDescriptor::Value("DPMPP2Mv2", Napi::Number::New(env, DPMPP2Mv2)),
Napi::PropertyDescriptor::Value("LCM", Napi::Number::New(env, LCM)),
Napi::PropertyDescriptor::Value("IPNDM", Napi::Number::New(env, IPNDM)),
Napi::PropertyDescriptor::Value("IPNDM_V", Napi::Number::New(env, IPNDM_V)),
});
sampleMethodEnum.Freeze();

Expand All @@ -278,6 +280,7 @@ namespace
Napi::PropertyDescriptor::Value("Discrete", Napi::Number::New(env, DISCRETE)),
Napi::PropertyDescriptor::Value("Karras", Napi::Number::New(env, KARRAS)),
Napi::PropertyDescriptor::Value("AYS", Napi::Number::New(env, AYS)),
Napi::PropertyDescriptor::Value("GITS", Napi::Number::New(env, GITS)),
});
scheduleEnum.Freeze();

Expand Down Expand Up @@ -336,7 +339,11 @@ namespace
{
Napi::Value tmp;
const auto params = info[0].ToObject();
const auto model = params.Get("model").ToString().Utf8Value();
const auto model = (tmp = params.Get("model"), tmp.IsUndefined() ? "" : tmp.ToString().Utf8Value());
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it valid to pass a "" model to new_sd_ctx? I assumed no, which was why this was previously not an optional param but maybe I'm wrong?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It became optional in the flux PR here https://github.com/leejet/stable-diffusion.cpp/pull/356/files#diff-a8e875e8f7684a2f9e35212d88ee9574001952eb2c049385e73d5e24fd6e2a83L172-R205 - for flux inference need to set the diffusionModel instead of model.

const auto clipL = (tmp = params.Get("clipL"), tmp.IsUndefined() ? "" : tmp.ToString().Utf8Value());
const auto clipG = (tmp = params.Get("clipG"), tmp.IsUndefined() ? "" : tmp.ToString().Utf8Value());
const auto t5xxl = (tmp = params.Get("t5xxl"), tmp.IsUndefined() ? "" : tmp.ToString().Utf8Value());
const auto diffusionModel = (tmp = params.Get("diffusionModel"), tmp.IsUndefined() ? "" : tmp.ToString().Utf8Value());
const auto vae = (tmp = params.Get("vae"), tmp.IsUndefined() ? "" : tmp.ToString().Utf8Value());
const auto taesd = (tmp = params.Get("taesd"), tmp.IsUndefined() ? "" : tmp.ToString().Utf8Value());
const auto controlNet = (tmp = params.Get("controlNet"), tmp.IsUndefined() ? "" : tmp.ToString().Utf8Value());
Expand Down Expand Up @@ -375,9 +382,34 @@ namespace

return queueStableDiffusionWorker(info.Env(), cppContextData, [=](CPPContextData& ctx)
{
ctx.sdCtx = { new_sd_ctx(model.c_str(), vae.c_str(), taesd.c_str(), controlNet.c_str(), loraDir.c_str(),
embedDir.c_str(), stackedIdEmbedDir.c_str(), vaeDecodeOnly, vaeTiling, freeParamsImmediately, numThreads, weightType,
cudaRng ? CUDA_RNG : STD_DEFAULT_RNG, schedule, keepClipOnCpu, keepControlNetOnCpu, keepVaeOnCpu), [](sd_ctx_t* c) { if (c) free_sd_ctx(c); } };
ctx.sdCtx = {
new_sd_ctx(
model.c_str(),
clipL.c_str(),
clipG.c_str(),
t5xxl.c_str(),
diffusionModel.c_str(),
vae.c_str(),
taesd.c_str(),
controlNet.c_str(),
loraDir.c_str(),
embedDir.c_str(),
stackedIdEmbedDir.c_str(),
vaeDecodeOnly,
vaeTiling,
freeParamsImmediately,
numThreads,
weightType,
cudaRng ? CUDA_RNG : STD_DEFAULT_RNG,
schedule,
keepClipOnCpu,
keepControlNetOnCpu,
keepVaeOnCpu
),
[](sd_ctx_t* c) {
if (c) free_sd_ctx(c);
}
};

if (!ctx.sdCtx)
throw std::runtime_error("Context creation failed");
Expand Down Expand Up @@ -427,12 +459,32 @@ namespace
const auto styleRatio = (tmp = params.Get("styleRatio"), tmp.IsUndefined() ? 20.0f : tmp.ToNumber().FloatValue());
const auto normalizeInput = (tmp = params.Get("normalizeInput"), tmp.IsUndefined() ? false : tmp.ToBoolean().Value());
const auto inputIdImagesPath = (tmp = params.Get("inputIdImagesPath"), tmp.IsUndefined() ? "" : tmp.ToString().Utf8Value());
const auto guidance = (tmp = params.Get("guidance"), tmp.IsUndefined() ? 0.0f : tmp.ToNumber().FloatValue());

if (sampleMethod >= N_SAMPLE_METHODS)
throw Napi::Error::New(info.Env(), "Invalid sampleMethod");

return queueStableDiffusionWorker(info.Env(), cppContextData, [=, sdCtx = cppContextData->sdCtx, controlCond = std::move(controlCond)](CPPContextData& ctx)
{
return SdImageList(txt2img(sdCtx.get(), prompt.c_str(), negativePrompt.c_str(), clipSkip, cfgScale, width, height, sampleMethod, sampleSteps, seed, batchCount, controlCond.get(), controlStrength, styleRatio, normalizeInput, inputIdImagesPath.c_str()), batchCount);
return SdImageList(txt2img(
sdCtx.get(),
prompt.c_str(),
negativePrompt.c_str(),
clipSkip,
cfgScale,
guidance,
width,
height,
sampleMethod,
sampleSteps,
seed,
batchCount,
controlCond.get(),
controlStrength,
styleRatio,
normalizeInput,
inputIdImagesPath.c_str()
), batchCount);
},
[batchCount](Napi::Env env, SdImageList&& images)
{
Expand Down Expand Up @@ -468,12 +520,33 @@ namespace
const auto styleRatio = (tmp = params.Get("styleRatio"), tmp.IsUndefined() ? 20.0f : tmp.ToNumber().FloatValue());
const auto normalizeInput = (tmp = params.Get("normalizeInput"), tmp.IsUndefined() ? false : tmp.ToBoolean().Value());
const auto inputIdImagesPath = (tmp = params.Get("inputIdImagesPath"), tmp.IsUndefined() ? "" : tmp.ToString().Utf8Value());
const auto guidance = (tmp = params.Get("guidance"), tmp.IsUndefined() ? 0.0f : tmp.ToNumber().FloatValue());
if (sampleMethod >= N_SAMPLE_METHODS)
throw Napi::Error::New(info.Env(), "Invalid sampleMethod");

return queueStableDiffusionWorker(info.Env(), cppContextData, [=, sdCtx = cppContextData->sdCtx, initImage = std::move(initImage), controlCond = std::move(controlCond)](CPPContextData& ctx)
{
return SdImageList(img2img(sdCtx.get(), *initImage, prompt.c_str(), negativePrompt.c_str(), clipSkip, cfgScale, width, height, sampleMethod, sampleSteps, strength, seed, batchCount, controlCond.get(), controlStrength, styleRatio, normalizeInput, inputIdImagesPath.c_str()), batchCount);
return SdImageList(img2img(
sdCtx.get(),
*initImage,
prompt.c_str(),
negativePrompt.c_str(),
clipSkip,
cfgScale,
guidance,
width,
height,
sampleMethod,
sampleSteps,
strength,
seed,
batchCount,
controlCond.get(),
controlStrength,
styleRatio,
normalizeInput,
inputIdImagesPath.c_str()
), batchCount);
},
[batchCount](Napi::Env env, SdImageList&& images)
{
Expand Down