<?xml version="1.0" encoding="utf-8" standalone="yes"?><feed version="2.0" xmlns="http://www.w3.org/2005/Atom"><title>Easy Diffusion:</title><link rel="alternate" type="text/html" language="en" href="/"/><link rel="self" type="application/octet-stream" href="/index.xml"/><subtitle>Recent content on Easy Diffusion</subtitle><author><uri>/</uri></author><id>/</id><generator>Hugo -- gohugo.io</generator><updated>2026-03-31T09:09:17Z</updated><entry><title>Post from Mar 31, 2026</title><link rel="alternate" type="text/html" href="/blog/1774948157/"/><published>2026-03-31T09:09:17Z</published><updated>2026-03-31T09:09:17Z</updated><summary>&lt;p&gt;Development update for Easy Diffusion: the &lt;code&gt;beta&lt;/code&gt; branch has been merged into &lt;code&gt;main&lt;/code&gt;, so this releases v3.5 (webui) and v4 to everyone. This shouldn&amp;rsquo;t affect existing users who&amp;rsquo;re on the main branch, i.e. people using the v3 engine will continue doing so. The two engines (v3.5 and v4) are marked as optional, so new users will continue to get and use v3 by default.&lt;/p&gt;
&lt;p&gt;The main purpose of this update is to merge the two forked codebases that we&amp;rsquo;ve had for over 1.5 years. Now the &lt;code&gt;main&lt;/code&gt; and &lt;code&gt;beta&lt;/code&gt; branches are back in sync. This brings back the streamlined release process that we had previously, where new changes would first land in &lt;code&gt;beta&lt;/code&gt;, and then get merged into &lt;code&gt;main&lt;/code&gt; after testing.&lt;/p&gt;</summary><id>/blog/1774948157/</id></entry><entry><title>Post from Mar 27, 2026</title><link rel="alternate" type="text/html" href="/blog/1774595493/"/><published>2026-03-27T07:11:33Z</published><updated>2026-03-27T07:11:33Z</updated><summary>&lt;p&gt;Got Easy Diffusion v4 working on Apple and Intel Macs. The performance difference ratio (vs ED v3) is similar to the ratio on Windows (with CUDA) and other deployment targets. So that indicates optimization opportunities in sd.cpp. It&amp;rsquo;s currently about 1.5x slower than diffusers-based Stable Diffusion.&lt;/p&gt;
&lt;p&gt;In other news, &lt;a href="https://github.com/cmdr2/easyinstaller"&gt;easyinstaller&lt;/a&gt; is also out with its first release, which means that Easy Diffusion can now start shipping AppImage, Flatpak, rpm, deb, pkg, dmg etc for the different platforms. Instead of requiring Linux and Mac users to use the terminal to install and start Easy Diffusion. Will work on this soon.&lt;/p&gt;</summary><id>/blog/1774595493/</id></entry><entry><title>Post from Jan 18, 2026</title><link rel="alternate" type="text/html" href="/blog/1768722210/"/><published>2026-01-18T07:43:30Z</published><updated>2026-01-18T07:43:30Z</updated><summary>&lt;p&gt;Started the long-pending rewrite of Easy Diffusion&amp;rsquo;s server code. v4 intends to replace the Python (and PyTorch) based server with a simple C++ version. The reason for rewriting the server in C++ is to achieve sub-second startup time for the UI, and to reduce the download size (won&amp;rsquo;t need to distribute Python along with Easy Diffusion) or mess with conda/venv etc. And it&amp;rsquo;s also something that I want to do for personal taste, i.e. de-bloating what doesn&amp;rsquo;t need to be bloated.&lt;/p&gt;</summary><id>/blog/1768722210/</id></entry><entry><title>Post from Jan 08, 2026</title><link rel="alternate" type="text/html" href="/blog/1767852707/"/><published>2026-01-08T06:11:47Z</published><updated>2026-01-08T06:11:47Z</updated><summary>&lt;p&gt;For Z-Image, the performance of the stock version of chromaForge is poorer than sd.cpp&amp;rsquo;s. Mainly because chromaForge isn&amp;rsquo;t able to run the smaller gguf quantized models that sd.cpp is able to run (chromaForge fails with the errors that I was fixing yesterday).&lt;/p&gt;
&lt;p&gt;If I really want to push through with this, it would be good to fix the remaining issues with gguf models in chromaForge. Only then can the performance be truly compared (in order to decide whether to release this into ED 3.5). I want to compare the performance of the smaller gguf models, because that&amp;rsquo;s what ED&amp;rsquo;s users will run typically.&lt;/p&gt;</summary><id>/blog/1767852707/</id></entry><entry><title>Post from Jan 07, 2026</title><link rel="alternate" type="text/html" href="/blog/1767809976/"/><published>2026-01-07T18:19:36Z</published><updated>2026-01-07T18:19:36Z</updated><summary>&lt;p&gt;Worked on fixing Z-Image support in ED&amp;rsquo;s fork of chromaForge (a fork of Forge WebUI). Fixed a number of integration issues. It&amp;rsquo;s now crashing on a matrix multiplication error, which looks like an incorrectly transposed matrix (mostly due to reading the weights in the wrong order).&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ll try to install a stock version of chromaForge to see its raw performance with Z-Image (and whether it&amp;rsquo;s worth pursuing the integration), and also use it to help investigate the matrix multiplication error (and any future errors).&lt;/p&gt;</summary><id>/blog/1767809976/</id></entry><entry><title>Post from Dec 25, 2025</title><link rel="alternate" type="text/html" href="/blog/1766652519/"/><published>2025-12-25T08:48:39Z</published><updated>2025-12-25T08:48:39Z</updated><summary>&lt;p&gt;Collecting the worklog over the past few weeks.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Enabled Flash-Attention and CPU offloading by default in sdkit3 (i.e. Easy Diffusion v4).&lt;/li&gt;
&lt;li&gt;Added optional VAE tiling (and VAE tile size configuration) via &lt;code&gt;config.yaml&lt;/code&gt; in Easy Diffusion v4.&lt;/li&gt;
&lt;li&gt;Created Easy Diffusion&amp;rsquo;s &lt;a href="https://github.com/easydiffusion/stable-diffusion-webui-forge"&gt;fork&lt;/a&gt; of Forge WebUI, in order to apply the patches required to run with ED. And also to try adding new features like Z-Image (which are missing in the seemingly-abandoned main Forge repo).&lt;/li&gt;
&lt;li&gt;Improved the heuristics used for killing and restarting the backend child process, since &lt;code&gt;/ping&lt;/code&gt; requests are unreliable if the backend is under heavy load.&lt;/li&gt;
&lt;li&gt;Merged a few PRs (&lt;a href="https://github.com/easydiffusion/torchruntime/pull/28"&gt;1&lt;/a&gt; &lt;a href="https://github.com/easydiffusion/torchruntime/pull/30"&gt;2&lt;/a&gt;) for &lt;code&gt;torchruntime&lt;/code&gt; that improve support for pinning pre-cu128 torch versions and fix the order of detection of DirectML and CUDA (prefers CUDA).&lt;/li&gt;
&lt;li&gt;Added progress bars when downloading v4 backend artifacts.&lt;/li&gt;
&lt;/ul&gt;</summary><id>/blog/1766652519/</id></entry><entry><title>Post from Dec 08, 2025</title><link rel="alternate" type="text/html" href="/blog/1765198531/"/><published>2025-12-08T12:55:31Z</published><updated>2025-12-08T12:55:31Z</updated><summary>&lt;p&gt;The new engine that&amp;rsquo;ll power Easy Diffusion&amp;rsquo;s upcoming v4 release (i.e. &lt;a href="https://github.com/easydiffusion/sdkit/tree/v3"&gt;sdkit3&lt;/a&gt;) has now been integrated into Easy Diffusion. It&amp;rsquo;s available to test by selecting &lt;strong&gt;v4 engine&lt;/strong&gt; in the &lt;code&gt;Settings&lt;/code&gt; tab (after enabling &lt;code&gt;Beta&lt;/code&gt;). Please press &lt;code&gt;Save&lt;/code&gt; and restart Easy Diffusion after selecting this.&lt;/p&gt;
&lt;p&gt;It uses &lt;a href="https://github.com/leejet/stable-diffusion.cpp"&gt;stable-diffusion.cpp&lt;/a&gt; and &lt;a href="https://github.com/ggml-org/ggml"&gt;ggml&lt;/a&gt; under-the-hood, and produces optimized, lightweight builds for the target hardware.&lt;/p&gt;
&lt;p&gt;The main benefits of Easy Diffusion&amp;rsquo;s new engine are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Very lightweight - Less than 100 MB install footprint, compared to 3 GB+ for Forge and other PyTorch-based engines.&lt;/li&gt;
&lt;li&gt;Much better for AMD/Intel/Integrated users - avoids the hot mess of ROCm and DirectML, by using a reliable Vulkan backend (that&amp;rsquo;s also used in &lt;code&gt;llama.cpp&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Opportunity for even faster image generation in the future - this currently uses stock sd.cpp, which has room for further optimization.&lt;/li&gt;
&lt;li&gt;Support for older GPUs - Vulkan supports older GPUs, especially older AMD GPUs unsupported by ROCm/PyTorch.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This supports:&lt;/p&gt;</summary><id>/blog/1765198531/</id></entry><entry><title>Post from Nov 27, 2025</title><link rel="alternate" type="text/html" href="/blog/1764237912/"/><published>2025-11-27T10:05:12Z</published><updated>2025-11-27T10:05:12Z</updated><summary>&lt;p&gt;Managed to get &lt;a href="https://github.com/leejet/stable-diffusion.cpp"&gt;stable-diffusion.cpp&lt;/a&gt; integrated into &lt;a href="https://github.com/easydiffusion/sdkit/tree/v3"&gt;sdkit v3&lt;/a&gt; and Easy Diffusion.&lt;/p&gt;
&lt;p&gt;sdkit v3 wraps &lt;code&gt;stable-diffusion.cpp&lt;/code&gt; with an API server. For now, the API server exposes an API compatible with Forge WebUI. This saves me time, and allows Easy Diffusion to work out-of-the-box with the new C++ based sdkit.&lt;/p&gt;
&lt;p&gt;It compiles and runs quite well. Ran it with Easy Diffusion&amp;rsquo;s UI. Tested with Vulkan and CUDA, on Windows.&lt;/p&gt;
&lt;p&gt;There are a few &lt;a href="https://github.com/users/cmdr2/projects/16/views/5"&gt;feature gaps&lt;/a&gt; (e.g. gfpgan, more controlnet models, more controlnet filters, more schedulers/samplers, reload specific models instead of everything), but &lt;code&gt;stable-diffusion.cpp&lt;/code&gt; has come a long way over the past year. The performance is reasonable. Not as fast as Forge or diffusers, but respectable. I haven&amp;rsquo;t spent any time on performance optimizations yet.&lt;/p&gt;</summary><id>/blog/1764237912/</id></entry><entry><title>Post from Nov 19, 2025</title><link rel="alternate" type="text/html" href="/blog/1763531042/"/><published>2025-11-19T05:44:02Z</published><updated>2025-11-19T05:44:02Z</updated><summary>&lt;p&gt;Following up to &lt;a href="https://cmdr2.github.io/notes/2025/11/1762336053/"&gt;the previous post&lt;/a&gt; on sdkit v3&amp;rsquo;s design:&lt;/p&gt;
&lt;p&gt;The initial experiments with &lt;a href="https://cmdr2.github.io/notes/2025/11/1763464399/"&gt;generating ggml from onnx models&lt;/a&gt; were promising, and it looks like a fairly solid path forward. It produces numerically-identical results, and there&amp;rsquo;s a clear path to reach performance-parity with &lt;a href="https://github.com/leejet/stable-diffusion.cpp"&gt;stable-diffusion.cpp&lt;/a&gt; with a few basic optimizations (since both will eventually generate the same underlying ggml graph).&lt;/p&gt;
&lt;p&gt;But I think it&amp;rsquo;s better to use the simpler option first, i.e. use &lt;code&gt;stable-diffusion.cpp&lt;/code&gt; directly. It mostly meets the &lt;a href="https://cmdr2.github.io/notes/2025/10/1760085894/"&gt;design goals for sdkit v3&lt;/a&gt; (after a bit of performance tuning). Everything else is premature optimization and scope bloat.&lt;/p&gt;</summary><id>/blog/1763531042/</id></entry><entry><title>Post from Nov 18, 2025</title><link rel="alternate" type="text/html" href="/blog/1763464399/"/><published>2025-11-18T11:13:19Z</published><updated>2025-11-18T11:13:19Z</updated><summary>&lt;p&gt;Successfully compiled the VAE of Stable Diffusion 1.5 using &lt;a href="https://github.com/cmdr2/graph-compiler"&gt;graph-compiler&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The compiled model is terribly slow because I haven&amp;rsquo;t written any performance optimizations, and it (conservatively) converts a lot of intermediate tensors to contiguous copies. But we don&amp;rsquo;t need any clever optimizations to get to decent performance, just basic ones.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s pretty exciting because I was able to bypass the need to port the model to C++ manually. Instead, I was able to just compile the exported ONNX model and get the same output values as the original PyTorch implementation (given the same input and weights). I could compile to any platform supported by ggml by just changing one flag (e.g. CPU, CUDA, ROCm, Vulkan, Metal etc).&lt;/p&gt;</summary><id>/blog/1763464399/</id></entry><entry><title>Post from Nov 13, 2025</title><link rel="alternate" type="text/html" href="/blog/1763027191/"/><published>2025-11-13T09:46:31Z</published><updated>2025-11-13T09:46:31Z</updated><summary>&lt;p&gt;&lt;a href="https://docs.polymagelabs.com/articles/polyblocks-quantization.html#polyblocks"&gt;PolyBlocks&lt;/a&gt; is another interesting ML compiler, written using MLIR. It&amp;rsquo;s a startup incubated in IISc Bangalore, run by someone (Uday Bondhugula) who co-authored a &lt;a href="https://www.ece.lsu.edu/jxr/Publications-pdf/ics08.pdf"&gt;paper on compiler optimizations for GPGPUs&lt;/a&gt; back in 2008 (17 years ago)!&lt;/p&gt;
&lt;p&gt;Some of the compiler passes to keep in mind:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;fusion&lt;/li&gt;
&lt;li&gt;tiling&lt;/li&gt;
&lt;li&gt;use hardware acceleration (like tensor cores)&lt;/li&gt;
&lt;li&gt;constant folding&lt;/li&gt;
&lt;li&gt;perform redundant computation to avoid global memory accesses where profitable&lt;/li&gt;
&lt;li&gt;pack into buffers&lt;/li&gt;
&lt;li&gt;loop transformation&lt;/li&gt;
&lt;li&gt;unroll-and-jam (register tiling?)&lt;/li&gt;
&lt;li&gt;vectorization&lt;/li&gt;
&lt;li&gt;reorder execution for better spatial, temporary and group reuse&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Scheduling approaches:&lt;/p&gt;</summary><id>/blog/1763027191/</id></entry><entry><title>Post from Nov 07, 2025</title><link rel="alternate" type="text/html" href="/blog/1762514507/"/><published>2025-11-07T11:21:47Z</published><updated>2025-11-07T11:21:47Z</updated><summary>&lt;p&gt;Wrote a simple script to convert ONNX to GGML. It auto-generates C++ code that calls the corresponding ggml functions (for each ONNX operator). This file can then be compiled and run like a normal C++ ggml program, and will produce the same results as the original model in PyTorch.&lt;/p&gt;
&lt;p&gt;The generated file can work on multiple backends: CPU, CUDA, ROCm, Vulkan, Metal etc, by providing the correct compiler flags during &lt;code&gt;cmake -B&lt;/code&gt;, e.g. &lt;code&gt;-D GGML_CUDA=1&lt;/code&gt; for CUDA.&lt;/p&gt;</summary><id>/blog/1762514507/</id></entry><entry><title>Post from Nov 05, 2025</title><link rel="alternate" type="text/html" href="/blog/1762336053/"/><published>2025-11-05T09:47:33Z</published><updated>2025-11-05T09:47:33Z</updated><summary>&lt;p&gt;Following up to the &lt;a href="https://cmdr2.github.io/notes/2025/11/1762335811/"&gt;deep-dive on ML compilers&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;sdkit v3 won&amp;rsquo;t use general-purpose ML compilers. They aren&amp;rsquo;t yet ready for sdkit&amp;rsquo;s target platforms, and need a lot of work (well beyond sdkit v3&amp;rsquo;s scope). But I&amp;rsquo;m quite certain that sdkit v4 will use them, and sdkit v3 will start making steps in that direction.&lt;/p&gt;
&lt;p&gt;For sdkit v3, I see two possible paths:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Use an array of vendor-specific compilers (like TensorRT-RTX, MiGraphX, OpenVINO etc), one for each target platform.&lt;/li&gt;
&lt;li&gt;Auto-generate ggml code from onnx (or pytorch), and beat it on the head until it meets sdkit v3&amp;rsquo;s &lt;a href="https://cmdr2.github.io/notes/2025/10/1760085894/"&gt;performance goals&lt;/a&gt;. Hand-tune kernels, contribute to ggml, and take advantage of ggml&amp;rsquo;s multi-backend kernels.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Both approaches provide a big step-up from sdkit v2 in terms of install size and performance. So it makes sense to tap into these first, and leave ML compilers for v4 (as another leap forward).&lt;/p&gt;</summary><id>/blog/1762336053/</id></entry><entry><title>Post from Nov 05, 2025</title><link rel="alternate" type="text/html" href="/blog/1762335811/"/><published>2025-11-05T09:43:31Z</published><updated>2025-11-05T09:43:31Z</updated><summary>&lt;p&gt;This post concludes (for now) my &lt;a href="https://cmdr2.github.io/notes/2025/10/1760088945/"&gt;ongoing deep-dive into ML compilers&lt;/a&gt;, while researching for &lt;a href="https://cmdr2.github.io/notes/2025/10/1760085894/"&gt;sdkit v3&lt;/a&gt;. I&amp;rsquo;ve linked (at the end) to some of the papers that I read related to graph execution on GPUs.&lt;/p&gt;
&lt;p&gt;Some final takeaways:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;ML compilers might break CUDA&amp;rsquo;s moat (and fix AMD&amp;rsquo;s ROCm support).&lt;/li&gt;
&lt;li&gt;A single compiler is unlikely to fit every scenario.&lt;/li&gt;
&lt;li&gt;The scheduler needs to be grounded in truth.&lt;/li&gt;
&lt;li&gt;Simulators might be worth exploring more.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="ml-compilers-might-break-cudas-moat-and-fix-amds-rocm-support"&gt;ML compilers might break CUDA&amp;rsquo;s moat (and fix AMD&amp;rsquo;s ROCm support)&lt;/h2&gt;
&lt;p&gt;It&amp;rsquo;s pretty clear that ML compilers are going to be a big deal. NVIDIA&amp;rsquo;s TensorRT is also an ML compiler, but it only targets their GPUs. Once the generated machine code (from cross-vendor ML compilers) is comparable in performance to hand-tuned kernels, these compilers are going to break the (in)famous moat of CUDA.&lt;/p&gt;</summary><id>/blog/1762335811/</id></entry><entry><title>Post from Oct 27, 2025</title><link rel="alternate" type="text/html" href="/blog/1761560082/"/><published>2025-10-27T10:14:42Z</published><updated>2025-10-27T10:14:42Z</updated><summary>&lt;p&gt;A possible intuition for understanding GPU memory hierarchy (and the performance penalty for data transfer between various layers) is to think of it like a manufacturing logistics problem:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;CPU (host) to GPU (device) is like travelling overnight between two cities. The CPU city is like the &amp;ldquo;headquarters&amp;rdquo;, and contains a mega-sized warehouse of parts (think football field sizes), also known as &amp;lsquo;Host memory&amp;rsquo;.&lt;/li&gt;
&lt;li&gt;Each GPU is like a different city, containing its own warehouse outside the city, also known as &amp;lsquo;Global Memory&amp;rsquo;. This warehouse stockpiles whatever it needs from the headquarters city (CPU).&lt;/li&gt;
&lt;li&gt;Each SM/Core/Tile is a factory located in different areas of the city. Each factory contains a small warehouse for stockpiling whatever inventory it needs, also known as &amp;lsquo;Shared Memory&amp;rsquo;.&lt;/li&gt;
&lt;li&gt;Each warp is a bulk stamping machine inside the factory, producing 32 items in one shot. There&amp;rsquo;s a tray next to each machine, also known as &amp;lsquo;Registers&amp;rsquo;. This tray is used for keeping stuff temporarily for each stamping process.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This analogy can help understand the scale and performance penalty for data transfers.&lt;/p&gt;</summary><id>/blog/1761560082/</id></entry><entry><title>Post from Oct 24, 2025</title><link rel="alternate" type="text/html" href="/blog/1761283271/"/><published>2025-10-24T05:21:11Z</published><updated>2025-10-24T05:21:11Z</updated><summary>&lt;p&gt;Good post on using MLIR for compiling ML models to GPUs. It gives a good broad overview of a GPU architecture, and how MLIR fits into that. The overall series looks pretty interesting too!&lt;/p&gt;
&lt;p&gt;Making a note here for future reference - &lt;a href="https://www.stephendiehl.com/posts/mlir_gpu/"&gt;https://www.stephendiehl.com/posts/mlir_gpu/&lt;/a&gt;&lt;/p&gt;</summary><id>/blog/1761283271/</id></entry><entry><title>Post from Oct 22, 2025</title><link rel="alternate" type="text/html" href="/blog/1761119134/"/><published>2025-10-22T07:45:34Z</published><updated>2025-10-22T07:45:34Z</updated><summary>&lt;p&gt;Wrote a fresh implementation of most of the popular samplers and schedulers used for image generation (Stable Diffusion and Flux) at &lt;a href="https://github.com/cmdr2/samplers.cpp"&gt;https://github.com/cmdr2/samplers.cpp&lt;/a&gt;. A few other schedulers (like &lt;code&gt;Align Your Steps&lt;/code&gt;) have been left out for now, but are pretty easy to implement.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s still work-in-progress, and is not ready for public use. The algorithmic port has been completed, and the next step is to test the output values against reference values (from another implementation, e.g. Forge WebUI). After that, I&amp;rsquo;ll translate it to C++.&lt;/p&gt;</summary><id>/blog/1761119134/</id></entry><entry><title>Post from Oct 10, 2025</title><link rel="alternate" type="text/html" href="/blog/1760088945/"/><published>2025-10-10T09:35:45Z</published><updated>2025-10-10T09:35:45Z</updated><summary>&lt;p&gt;Some notes on machine-learning compilers, gathered while researching tech for Easy Diffusion&amp;rsquo;s next engine (i.e. sdkit v3). For context, see the &lt;a href="https://cmdr2.github.io/notes/2025/10/1760085894/"&gt;design constraints&lt;/a&gt; of the new engine.&lt;/p&gt;
&lt;h2 id="tldr-summary"&gt;tl;dr summary&lt;/h2&gt;
&lt;p&gt;The current state is:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Vendor-specific compilers are the only performant options on consumer GPUs right now. For e.g. &lt;a href="https://docs.nvidia.com/deeplearning/tensorrt-rtx/latest/index.html"&gt;TensorRT-RTX&lt;/a&gt; for NVIDIA, &lt;a href="https://rocm.docs.amd.com/projects/AMDMIGraphX/en/latest/"&gt;MiGraphX&lt;/a&gt; for AMD, &lt;a href="https://github.com/openvinotoolkit/openvino"&gt;OpenVINO&lt;/a&gt; for Intel.&lt;/li&gt;
&lt;li&gt;Cross-vendor compilers are just not performant enough right now for Stable Diffusion-class workloads on consumer GPUs. For e.g. like &lt;a href="https://tvm.apache.org/"&gt;TVM&lt;/a&gt;, &lt;a href="https://iree.dev/"&gt;IREE&lt;/a&gt;, &lt;a href="https://openxla.org/xla"&gt;XLA&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The focus of cross-vendor compilers seems to be either on datacenter hardware, or embedded devices. The performance on desktops and laptops is pretty poor. Mojo doesn&amp;rsquo;t target this category (and doesn&amp;rsquo;t support Windows). Probably because datacenters and embedded devices are currently where the attention (and money) is.&lt;/p&gt;</summary><id>/blog/1760088945/</id></entry><entry><title>Post from Oct 10, 2025</title><link rel="alternate" type="text/html" href="/blog/1760085894/"/><published>2025-10-10T08:44:54Z</published><updated>2025-10-10T08:44:54Z</updated><summary>&lt;p&gt;The design constraints for Easy Diffusion&amp;rsquo;s next engine (i.e. sdkit v3) are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Lean: Install size of &amp;lt; 200 MB uncompressed (excluding models).&lt;/li&gt;
&lt;li&gt;Fast: Performance within 10% of the best-possible speed on that GPU for that model.&lt;/li&gt;
&lt;li&gt;Capable: Supports Stable Diffusion 1.x, 2.x, 3.x, XL, Flux, Chroma, ControlNet, LORA, Embedding, VAE. Supports loading custom model weights (from civitai etc), and memory offloading (for smaller GPUs).&lt;/li&gt;
&lt;li&gt;Targets: Desktops and Laptops, Windows/Linux/Mac, NVIDIA/AMD/Intel/Apple.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I think it&amp;rsquo;s possible, using ML compilers like TensorRT-RTX (and similar compilers for other platforms). See: &lt;a href="https://cmdr2.github.io/notes/2025/10/1760088945/"&gt;Some notes on ML compilers&lt;/a&gt;.&lt;/p&gt;</summary><id>/blog/1760085894/</id></entry><entry><title>Post from Sep 01, 2025</title><link rel="alternate" type="text/html" href="/blog/1756713805/"/><published>2025-09-01T08:03:25Z</published><updated>2025-09-01T08:03:25Z</updated><summary>&lt;p&gt;Cleared the backlog of stale issues on ED&amp;rsquo;s github repo. This brought down the number of open issues from ~350 to 74.&lt;/p&gt;
&lt;p&gt;A number of those suggestions and issues are already being tracked on my &lt;a href="https://github.com/users/cmdr2/projects/16/views/1"&gt;task board&lt;/a&gt;. The others had either been fixed, or were really old (i.e. not relevant to reply anymore).&lt;/p&gt;
&lt;p&gt;While I&amp;rsquo;d have genuinely wanted to solve all of those unresolved issues, I was on a break from this project for nearly 1.5 years, so unfortunately it is what it is.&lt;/p&gt;</summary><id>/blog/1756713805/</id></entry><entry><title>Post from Aug 25, 2025</title><link rel="alternate" type="text/html" href="/blog/1756113601/"/><published>2025-08-25T09:20:01Z</published><updated>2025-08-25T09:20:01Z</updated><summary>&lt;p&gt;Experimented with TensorRT-RTX (a new library offered by NVIDIA).&lt;/p&gt;
&lt;p&gt;The first step was a tiny toy model, just to get the build and test setup working.&lt;/p&gt;
&lt;p&gt;The reference model in PyTorch:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-py" data-lang="py"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; torch
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; torch.nn &lt;span style="color:#66d9ef"&gt;as&lt;/span&gt; nn
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;TinyCNN&lt;/span&gt;(nn&lt;span style="color:#f92672"&gt;.&lt;/span&gt;Module):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;__init__&lt;/span&gt;(self):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; super()&lt;span style="color:#f92672"&gt;.&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;__init__&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;conv &lt;span style="color:#f92672"&gt;=&lt;/span&gt; nn&lt;span style="color:#f92672"&gt;.&lt;/span&gt;Conv2d(&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;8&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;, stride&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, padding&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;relu &lt;span style="color:#f92672"&gt;=&lt;/span&gt; nn&lt;span style="color:#f92672"&gt;.&lt;/span&gt;ReLU()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pool &lt;span style="color:#f92672"&gt;=&lt;/span&gt; nn&lt;span style="color:#f92672"&gt;.&lt;/span&gt;AdaptiveAvgPool2d((&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;fc &lt;span style="color:#f92672"&gt;=&lt;/span&gt; nn&lt;span style="color:#f92672"&gt;.&lt;/span&gt;Linear(&lt;span style="color:#ae81ff"&gt;8&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;) &lt;span style="color:#75715e"&gt;# 4-class toy output&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;forward&lt;/span&gt;(self, x):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; x &lt;span style="color:#f92672"&gt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;relu(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;conv(x))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; x &lt;span style="color:#f92672"&gt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pool(x)&lt;span style="color:#f92672"&gt;.&lt;/span&gt;flatten(&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;fc(x)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I ran this on a NVIDIA 4060 8 GB (Laptop) for 10K iterations, on Windows and WSL-with-Ubuntu, with float32 data.&lt;/p&gt;</summary><id>/blog/1756113601/</id></entry><entry><title>Post from Jun 17, 2025</title><link rel="alternate" type="text/html" href="/blog/1750136474/"/><published>2025-06-17T05:01:14Z</published><updated>2025-06-17T05:01:14Z</updated><summary>&lt;p&gt;Development update for Easy Diffusion - It&amp;rsquo;s chugging along in starts and stops. Broadly, there are three tracks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Maintenance: The past few months have seen increased support for AMD, Intel and integrated GPUs. This includes AMD on Windows. Added support for the new AMD 9060/9070 cards last week, and the new NVIDIA 50xx cards in March.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Flux to the main branch / release v3.5 to stable: Right now, Flux / v3.5 still requires you to enable ED beta first. And then install Forge. Last week I got Flux working in our main engine (with decent rendering speed). It still needs more work to support all the different models formats for Flux. Using Forge was a temporary arrangement, until Flux worked in our main engine.&lt;/p&gt;</summary><id>/blog/1750136474/</id></entry><entry><title>Post from Mar 04, 2025</title><link rel="alternate" type="text/html" href="/blog/1741122446/"/><published>2025-03-04T21:07:26Z</published><updated>2025-03-04T21:07:26Z</updated><summary>&lt;p&gt;Upgraded the default version of Easy Diffusion to Python 3.9. Newer versions of torch don&amp;rsquo;t support Python 3.8, so this became urgent after the release of NVIDIA&amp;rsquo;s 50xx series GPUs.&lt;/p&gt;
&lt;p&gt;I choose 3.9 as a temporary fix (instead of a newer Python version), since it had the least amount of package conflicts. The future direction of Easy Diffusion&amp;rsquo;s backend is unclear right now - there are a bunch of possible paths. So I didn&amp;rsquo;t want to spend too much time on this. I also wanted to minimize the risk to existing users.&lt;/p&gt;</summary><id>/blog/1741122446/</id></entry><entry><title>Post from Feb 10, 2025</title><link rel="alternate" type="text/html" href="/blog/1739186837/"/><published>2025-02-10T11:27:17Z</published><updated>2025-02-10T11:27:17Z</updated><summary>&lt;p&gt;Easy Diffusion (and &lt;code&gt;sdkit&lt;/code&gt;) now also support AMD on Windows automatically (using DirectML), thanks to integrating with &lt;a href="https://github.com/easydiffusion/torchruntime/"&gt;torchruntime&lt;/a&gt;. It also supports integrated GPUs (Intel and AMD) on Windows, making Easy Diffusion faster on PCs without dedicated graphics cards.&lt;/p&gt;</summary><id>/blog/1739186837/</id></entry><entry><title>Post from Feb 10, 2025</title><link rel="alternate" type="text/html" href="/blog/1739186602/"/><published>2025-02-10T11:23:22Z</published><updated>2025-02-10T11:23:22Z</updated><summary>&lt;p&gt;Spent the last week or two getting &lt;a href="https://github.com/easydiffusion/torchruntime/"&gt;torchruntime&lt;/a&gt; fully integrated into Easy Diffusion, and making sure that it handles all the edge-cases.&lt;/p&gt;
&lt;p&gt;Easy Diffusion now uses &lt;code&gt;torchruntime&lt;/code&gt; to automatically install the best-possible version of &lt;code&gt;torch&lt;/code&gt; (on the users&amp;rsquo; computer) and support a wider variety of GPUs (as well as older GPUs). And it uses a GPU-agnostic device API, so Easy Diffusion will automatically support additional GPUs when they are supported by &lt;code&gt;torchruntime&lt;/code&gt;.&lt;/p&gt;</summary><id>/blog/1739186602/</id></entry><entry><title>Post from Jan 28, 2025</title><link rel="alternate" type="text/html" href="/blog/1738102652/"/><published>2025-01-28T22:17:32Z</published><updated>2025-01-28T22:17:32Z</updated><summary>&lt;p&gt;Continued to test and fix issues in sdkit, after the change to support DirectML. The change is fairly intrusive, since it removes direct references to &lt;code&gt;torch.cuda&lt;/code&gt; with a layer of abstraction.&lt;/p&gt;
&lt;p&gt;Fixed a few regressions, and it now passes all the regression tests for CPU and CUDA support (i.e. existing users). Will test for DirectML next, although it will fail (with out-of-memory) for anything but the simplest tests (since DirectML is quirky with memory allocation).&lt;/p&gt;</summary><id>/blog/1738102652/</id></entry><entry><title>Post from Jan 27, 2025</title><link rel="alternate" type="text/html" href="/blog/1738011692/"/><published>2025-01-27T21:01:32Z</published><updated>2025-01-27T21:01:32Z</updated><summary>&lt;p&gt;Worked on adding support for DirectML in sdkit. This allows AMD GPUs and Integrated GPUs to generate images on Windows.&lt;/p&gt;
&lt;p&gt;DirectML seems like it&amp;rsquo;s really inefficient with memory though. So for now it only manages to generate images using SD 1.5. XL and larger models fail to generate, even though I have a 12 GB of VRAM in my graphics card.&lt;/p&gt;</summary><id>/blog/1738011692/</id></entry><entry><title>Post from Jan 22, 2025</title><link rel="alternate" type="text/html" href="/blog/1737566382/"/><published>2025-01-22T17:19:42Z</published><updated>2025-01-22T17:19:42Z</updated><summary>&lt;p&gt;&lt;em&gt;Continued from &lt;a href="https://cmdr2.github.io/notes/2025/01/1737134382/"&gt;Part 1&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Spent a few days figuring out how to compile binary wheels of PyTorch and include all the necessary libraries (ROCm libs or CUDA libs).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt; - In Part 2, the compiled PyTorch wheels now include the required libraries (including ROCm). But this isn&amp;rsquo;t over yet. Torch starts now, but adding two numbers with it produces garbage values (on the GPU). There&amp;rsquo;s probably a bug in the included ROCBLAS version, might need to recompile ROCBLAS for gfx803 separately. Will tackle that in Part 3 (tbd).&lt;/p&gt;</summary><id>/blog/1737566382/</id></entry><entry><title>Post from Jan 17, 2025</title><link rel="alternate" type="text/html" href="/blog/1737134382/"/><published>2025-01-17T17:19:42Z</published><updated>2025-01-17T17:19:42Z</updated><summary>&lt;p&gt;&lt;em&gt;Continued in &lt;a href="https://cmdr2.github.io/notes/2025/01/1737566382/"&gt;Part 2&lt;/a&gt;, where I figured out how to include the required libraries in the wheel.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Spent all of yesterday trying to compile &lt;code&gt;pytorch&lt;/code&gt; with the compile-time &lt;code&gt;PYTORCH_ROCM_ARCH=gfx803&lt;/code&gt; environment variable.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt; - In Part 1, I compiled wheels for PyTorch with ROCm, in order to add support for older AMD cards like RX 480. I managed to compile the wheels, but the wheel doesn&amp;rsquo;t include the required ROCm libraries. I figured that out in &lt;a href="https://cmdr2.github.io/notes/2025/01/1737566382/"&gt;Part 2&lt;/a&gt;.&lt;/p&gt;</summary><id>/blog/1737134382/</id></entry><entry><title>Post from Jan 13, 2025</title><link rel="alternate" type="text/html" href="/blog/1736779606/"/><published>2025-01-13T14:46:46Z</published><updated>2025-01-13T14:46:46Z</updated><summary>&lt;p&gt;Spent the last few days writing &lt;a href="https://github.com/easydiffusion/torchruntime"&gt;torchruntime&lt;/a&gt;, which will automatically install the correct torch distribution based on the user&amp;rsquo;s OS and graphics card. This package was written by extracting this logic out of Easy Diffusion, and refactoring it into a cleaner implementation (with tests).&lt;/p&gt;
&lt;p&gt;It can be installed (on Win/Linux/Mac) using &lt;code&gt;pip install torchruntime&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The main intention is that it&amp;rsquo;ll be easier for developers to contribute updates (for e.g. for newer or older GPUs). It wasn&amp;rsquo;t easy to find or modify this code previously, since it was buried deep inside Easy Diffusion&amp;rsquo;s internals.&lt;/p&gt;</summary><id>/blog/1736779606/</id></entry><entry><title>Post from Jan 04, 2025</title><link rel="alternate" type="text/html" href="/blog/1736020626/"/><published>2025-01-04T19:57:06Z</published><updated>2025-01-04T19:57:06Z</updated><summary>&lt;p&gt;Spent most of the day doing some support work for Easy Diffusion, and experimenting with &lt;a href="https://pypi.org/project/torch-directml/"&gt;torch-directml&lt;/a&gt; for AMD support on Windows.&lt;/p&gt;
&lt;p&gt;From the initial experiments, torch-directml seems to work properly with Easy Diffusion. I ran it on my NVIDIA card, and another user ran it on their AMD Radeon RX 7700 XT.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s 7-10x faster than the CPU, so looks promising. It&amp;rsquo;s 2x slower than CUDA on my NVIDIA card, but users with NVIDIA cards are not the target audience of this change.&lt;/p&gt;</summary><id>/blog/1736020626/</id></entry><entry><title>Post from Jan 03, 2025</title><link rel="alternate" type="text/html" href="/blog/1735918711/"/><published>2025-01-03T15:38:31Z</published><updated>2025-01-03T15:38:31Z</updated><summary>&lt;p&gt;Spent a few days prototyping a UI for Easy Diffusion v4. Files are at &lt;a href="https://github.com/easydiffusion/files/blob/main/ED4-ui-design/prototype"&gt;this repo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The main focus was to get a simple but pluggable UI, that was backed by a reactive data model, and to allow splitting the codebase into individual components (with their own files). And require only a text editor and a browser to develop, i.e. no compilation or nodejs-based developer experiences.&lt;/p&gt;
&lt;p&gt;I really want something that is easy to understand - for an outside developer and for myself (for e.g. if I&amp;rsquo;m returning to a portion of the codebase after a while). And with very little friction to start developing for it.&lt;/p&gt;</summary><id>/blog/1735918711/</id></entry><entry><title>Post from Dec 17, 2024</title><link rel="alternate" type="text/html" href="/blog/1734433390/"/><published>2024-12-17T11:03:10Z</published><updated>2024-12-17T11:03:10Z</updated><summary>&lt;p&gt;Notes on two directions for ED4&amp;rsquo;s UI that I&amp;rsquo;m unlikely to continue on.&lt;/p&gt;
&lt;p&gt;One is to start a desktop app with a full-screen webview (for the app UI). The other is writing the tabbed browser-like shell of ED4 in a compiled language (like Go or C++) and loading the contents of the tabs as regular webpages (by using webviews). So it would load URLs like &lt;code&gt;http://localhost:9000/ui/image_editor&lt;/code&gt; and &lt;code&gt;http://localhost:9000/ui/settings&lt;/code&gt; etc.&lt;/p&gt;
&lt;p&gt;In the first approach, we would start an empty full-screen webview, and let the webpage draw the entire UI, including the tabbed shell. The only purpose of this would be to start a desktop app instead of opening a browser tab, while being very lightweight (compared to Electron/Tauri style implementations).&lt;/p&gt;</summary><id>/blog/1734433390/</id></entry><entry><title>Post from Dec 14, 2024</title><link rel="alternate" type="text/html" href="/blog/1734205658/"/><published>2024-12-14T19:47:38Z</published><updated>2024-12-14T19:47:38Z</updated><summary>&lt;p&gt;Worked on a few UI design ideas for Easy Diffusion v4. I&amp;rsquo;ve uploaded the work-in-progress mockups at &lt;a href="https://github.com/easydiffusion/files"&gt;https://github.com/easydiffusion/files&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So far, I&amp;rsquo;ve mocked out the design for the outer skeleton. That is, the new tabbed interface, the status bar, and the unified main menu. I also worked on how they would look like on mobile devices.&lt;/p&gt;
&lt;p&gt;It gives me a rough idea of the &lt;code&gt;Vue&lt;/code&gt; components that would need to be written, and the surface area that plugins can impact. For e.g. plugins can add a new menu entry only in the &lt;code&gt;Plugins&lt;/code&gt; sub-menu.&lt;/p&gt;</summary><id>/blog/1734205658/</id></entry><entry><title>Post from Nov 21, 2024</title><link rel="alternate" type="text/html" href="/blog/1732202276/"/><published>2024-11-21T15:17:56Z</published><updated>2024-11-21T15:17:56Z</updated><summary>&lt;p&gt;Spent some more time on the &lt;a href="https://github.com/cmdr2/easy-diffusion4"&gt;v4 experiments&lt;/a&gt; for Easy Diffusion (i.e. C++ based, fast-startup, lightweight). &lt;code&gt;stable-diffusion.cpp&lt;/code&gt; is missing a few features, which will be necessary for Easy Diffusion&amp;rsquo;s typical workflow. I wasn&amp;rsquo;t keen on forking stable-diffusion.cpp, but it&amp;rsquo;s probably faster to work on &lt;a href="https://github.com/cmdr2/stable-diffusion.cpp"&gt;a fork&lt;/a&gt; for now.&lt;/p&gt;
&lt;p&gt;For now, I&amp;rsquo;ve added live preview and per-step progress callbacks (based on a few pending pull-requests on sd.cpp). And protection from &lt;code&gt;GGML_ASSERT&lt;/code&gt; killing the entire process. I&amp;rsquo;ve been looking at the ability to load individual models (like the vae) without needing to reload the entire SD model.&lt;/p&gt;</summary><id>/blog/1732202276/</id></entry><entry><title>Post from Nov 19, 2024</title><link rel="alternate" type="text/html" href="/blog/1732043895/"/><published>2024-11-19T19:18:15Z</published><updated>2024-11-19T19:18:15Z</updated><summary>&lt;p&gt;Spent a few days getting a C++ based version of Easy Diffusion working, using stable-diffusion.cpp. I&amp;rsquo;m working with a fork of stable-diffusion.cpp &lt;a href="https://github.com/cmdr2/stable-diffusion.cpp"&gt;here&lt;/a&gt;, to add a few changes like per-step callbacks, live image previews etc.&lt;/p&gt;
&lt;p&gt;It doesn&amp;rsquo;t have a UI yet, and currently hardcodes a model path. It exposes a RESTful API server (written using the &lt;code&gt;Crow&lt;/code&gt; C++ library), and uses a simple task manager that runs image generation tasks on a thread. The generated images are available at an API endpoint, and it shows the binary JPEG/PNG image (instead of base64 encoding).&lt;/p&gt;</summary><id>/blog/1732043895/</id></entry><entry><title>Post from Oct 16, 2024</title><link rel="alternate" type="text/html" href="/blog/1729102225/"/><published>2024-10-16T18:10:25Z</published><updated>2024-10-16T18:10:25Z</updated><summary>&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt; - &lt;em&gt;Today, I worked on using stable-diffusion.cpp in a simple C++ program. As a linked library, as well as compiling sd.cpp from scratch (with and without CUDA). The intent was to get a tiny and fast-starting executable UI for Stable Diffusion working. Also, ChatGPT is very helpful!&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="part-1-using-sdcpp-as-a-library"&gt;Part 1: Using sd.cpp as a library&lt;/h2&gt;
&lt;p&gt;First, I tried calling the &lt;a href="https://github.com/leejet/stable-diffusion.cpp"&gt;stable-diffusion.cpp&lt;/a&gt; library from a simple C++ program (which just loads the model and renders an image). Via dynamic linking. That worked, and its performance was the same as the example &lt;code&gt;sd.exe&lt;/code&gt; CLI, and it detected and used the GPU correctly.&lt;/p&gt;</summary><id>/blog/1729102225/</id></entry><entry><title>Post from Sep 04, 2024</title><link rel="alternate" type="text/html" href="/blog/1725463249/"/><published>2024-09-04T15:20:49Z</published><updated>2024-09-04T15:20:49Z</updated><summary>&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt;: Explored a possible optimization for Flux with &lt;code&gt;diffusers&lt;/code&gt; when using &lt;code&gt;enable_sequential_cpu_offload()&lt;/code&gt;. It did not work.&lt;/p&gt;
&lt;p&gt;While trying to use Flux (nearly 22 GB of weights) with &lt;code&gt;diffusers&lt;/code&gt; on a 12 GB graphics card, I noticed that it barely used any GPU memory when using &lt;code&gt;enable_sequential_cpu_offload()&lt;/code&gt;. And it was super slow. It turns out that the largest module in Flux&amp;rsquo;s transformer model is around 108 MB, so because diffusers streams modules one-at-a-time, the peak VRAM usage never crossed above a few hundred MBs.&lt;/p&gt;</summary><id>/blog/1725463249/</id></entry></feed>