|
<!DOCTYPE html> |
|
<html> |
|
<head> |
|
<title>WebSD | Home</title> |
|
<meta charset="utf-8" /> |
|
<meta |
|
name="viewport" |
|
content="width=device-width, initial-scale=1, shrink-to-fit=no" |
|
/> |
|
<link |
|
rel="stylesheet" |
|
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" |
|
integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb" |
|
crossorigin="anonymous" |
|
/> |
|
<link |
|
rel="stylesheet" |
|
href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" |
|
/> |
|
<link rel="stylesheet" href="/assets/css/main.css" /> |
|
<link rel="stylesheet" href="/assets/css/group.css" /> |
|
|
|
|
|
<meta |
|
http-equiv="origin-trial" |
|
content="Agx76XA0ITxMPF0Z8rbbcMllwuxsyp9qdtQaXlLqu1JUrdHB6FPonuyIKJ3CsBREUkeioJck4nn3KO0c0kkwqAMAAABJeyJvcmlnaW4iOiJodHRwOi8vbG9jYWxob3N0Ojg4ODgiLCJmZWF0dXJlIjoiV2ViR1BVIiwiZXhwaXJ5IjoxNjkxNzExOTk5fQ==" |
|
/> |
|
<meta |
|
http-equiv="origin-trial" |
|
content="AnmwqQ1dtYDQTYkZ5iMtHdINCaxjE94uWQBKp2yOz1wPTcjSRtOHUGQG+r2BxsEuM0qhxTVnuTjyh31HgTeA8gsAAABZeyJvcmlnaW4iOiJodHRwczovL21sYy5haTo0NDMiLCJmZWF0dXJlIjoiV2ViR1BVIiwiZXhwaXJ5IjoxNjkxNzExOTk5LCJpc1N1YmRvbWFpbiI6dHJ1ZX0=" |
|
/> |
|
<script src="dist/tvmjs_runtime.wasi.js"></script> |
|
<script src="dist/tvmjs.bundle.js"></script> |
|
</head> |
|
<body> |
|
<div class="container"> |
|
|
|
<div |
|
class="header d-flex flex-column flex-md-row justify-content-md-between" |
|
> |
|
<a href="/" id="navtitle"> |
|
<img |
|
src="/assets/img/logo/mlc-logo-with-text-landscape.svg" |
|
height="70px" |
|
alt="MLC" |
|
id="logo" |
|
/> |
|
</a> |
|
<ul id="topbar" class="nav nav-pills justify-content-center"> |
|
<li class="nav-item"> |
|
<a class="nav-link active" href="/"> Home </a> |
|
</li> |
|
|
|
<li class="nav-item"> |
|
<a |
|
class="nav-link" |
|
href="https://github.com/mlc-ai/web-stable-diffusion" |
|
> |
|
Github |
|
</a> |
|
</li> |
|
</ul> |
|
</div> |
|
|
|
|
|
|
|
|
|
<h1 id="web-stable-diffusion">Web Stable Diffusion </h1> |
|
|
|
<p> |
|
This project brings stable diffusion models to web browsers. |
|
<strong>Everything runs inside the browser with no need of server |
|
support.</strong> |
|
To our knowledge, this is the the world’s first stable diffusion |
|
completely running on the browser. Please check out our |
|
<a href="https://github.com/mlc-ai/web-stable-diffusion">GitHub repo</a> |
|
to see how we did it. There is also a |
|
<a href="#text-to-image-generation-demo">demo</a> which you can try out. |
|
</p> |
|
<li> |
|
WebGPU spec does comes with FP16 support already, but the |
|
implementation does not yet support this feature at this moment. As a |
|
result, the memory consumption of running the demo is about 7GB. For |
|
Apple silicon Mac with only 8GB of unified memory, it may take longer |
|
(a few minutes) to generate an image. This demo may also work for Mac |
|
with AMD GPU. |
|
</li> |
|
<h3 id="demo">Demo</h3> |
|
|
|
<script> |
|
var tvmjsGlobalEnv = tvmjsGlobalEnv || {}; |
|
</script> |
|
|
|
<script type="module"> |
|
import init, { |
|
TokenizerWasm, |
|
} from "./dist/tokenizers-wasm/tokenizers_wasm.js"; |
|
|
|
var initialized = false; |
|
async function getTokenizer(name) { |
|
if (!initialized) { |
|
await init(); |
|
} |
|
const jsonText = await ( |
|
await fetch( |
|
"https://huggingface.co/" + name + "/raw/main/tokenizer.json" |
|
) |
|
).text(); |
|
return new TokenizerWasm(jsonText); |
|
} |
|
|
|
tvmjsGlobalEnv.getTokenizer = getTokenizer; |
|
</script> |
|
<div> |
|
Select Model: <select name="model" id="modelId"> |
|
<option selected="selected">Stable-Diffusion-1.5</option> |
|
<option disabled>Stable-Diffusion-XL</option> |
|
</select> |
|
</div> |
|
<script src="dist/stable_diffusion.js"></script> |
|
|
|
<div> |
|
Input prompt: |
|
<input |
|
name="inputPrompt" |
|
id="inputPrompt" |
|
type="text" |
|
value="A photo of an astronaut riding a horse on mars" |
|
size="77" |
|
/> |
|
<br /> |
|
Negative prompt (optional): |
|
<input |
|
name="negativePrompt" |
|
id="negativePrompt" |
|
type="text" |
|
value="" |
|
size="77" |
|
/> |
|
</div> |
|
|
|
<div> |
|
Select scheduler - |
|
<select name="scheduler" id="schedulerId"> |
|
<option value="0">Multi-step DPM Solver (20 steps)</option> |
|
<option value="1">PNDM (50 steps)</option> |
|
</select> |
|
|
|
<br /> |
|
|
|
Render intermediate steps (may slow down execution) - |
|
<select name="vae-cycle" id="vaeCycle"> |
|
<option value="-1">No</option> |
|
<option value="2">Run VAE every two UNet steps after step 10</option> |
|
</select> |
|
|
|
<div id="progress"> |
|
<label id="gpu-tracker-label"></label><br /> |
|
<label id="progress-tracker-label"></label><br /> |
|
<progress |
|
id="progress-tracker-progress" |
|
max="100" |
|
value="100" |
|
></progress> |
|
</div> |
|
<button onclick="tvmjsGlobalEnv.asyncOnGenerate()">Generate</button> |
|
</div> |
|
<script> |
|
function updateSchedulerBasedOnModel() { |
|
var selectedModel = document.getElementById('modelId').value; |
|
var schedulerDropdown = document.getElementById('schedulerId'); |
|
|
|
if (selectedModel === 'Stable-Diffusion-XL') { |
|
schedulerDropdown.value = '2'; |
|
|
|
for (var i = 0; i < schedulerDropdown.options.length; i++) { |
|
schedulerDropdown.options[i].disabled = (schedulerDropdown.options[i].value !== '2'); |
|
} |
|
} else { |
|
schedulerDropdown.value = '0'; |
|
|
|
for (var i = 0; i < schedulerDropdown.options.length; i++) { |
|
schedulerDropdown.options[i].disabled = (schedulerDropdown.options[i].value !== '0' && schedulerDropdown.options[i].value !== '1'); |
|
} |
|
} |
|
} |
|
|
|
window.onload = function() { |
|
updateSchedulerBasedOnModel(); |
|
document.getElementById('modelId').addEventListener('change', updateSchedulerBasedOnModel); |
|
} |
|
</script> |
|
<div> |
|
<canvas id="canvas" width="512" height="512"></canvas> |
|
</div> |
|
<div id="log"></div> |
|
|
|
<p> |
|
This project brings stable diffusion models to web browsers. |
|
<strong |
|
>Everything runs inside the browser with no need of server |
|
support.</strong |
|
> |
|
To our knowledge, this is the the world’s first stable diffusion |
|
completely running on the browser. Please check out our |
|
<a href="https://github.com/mlc-ai/web-stable-diffusion">GitHub repo</a> |
|
to see how we did it. There is also a |
|
<a href="#text-to-image-generation-demo">demo</a> which you can try out. |
|
</p> |
|
|
|
<p> |
|
<img |
|
src="img/fig/browser-screenshot.png" |
|
alt="Browser screenshot" |
|
width="100%" |
|
/> |
|
</p> |
|
|
|
<p> |
|
We have been seeing amazing progress through AI models recently. Thanks |
|
to the open-source effort, developers can now easily compose open-source |
|
models together to produce amazing tasks. Stable diffusion enables the |
|
automatic creation of photorealistic images as well as images in various |
|
styles based on text input. These models are usually big and |
|
compute-heavy, which means we have to pipe through all computation |
|
requests to (GPU) servers when developing web applications based on |
|
these models. Additionally, most of the workloads have to run on a |
|
specific type of GPUs where popular deep-learning frameworks are readily |
|
available. |
|
</p> |
|
|
|
<p> |
|
This project takes a step to change that status quo and bring more |
|
diversity to the ecosystem. There are a lot of reasons to get some (or |
|
all) of the computation to the client side. There are many possible |
|
benefits, such as cost reduction on the service provider side, as well |
|
as an enhancement for personalization and privacy protection. The |
|
development of personal computers (even mobile devices) is going in the |
|
direction that enables such possibilities. The client side is getting |
|
pretty powerful. For example, the latest MacBook Pro can have up to 96GB |
|
of unified RAM that can be used to store the model weights and a |
|
reasonably powerful GPU to run many of the workloads. |
|
</p> |
|
|
|
<p> |
|
Wouldn’t it be fun to directly bring the ML models to the client, have |
|
the user open a browser tab, and instantly run the stable diffusion |
|
models on the browser? This project provides the first affirmative |
|
answer to this question. |
|
</p> |
|
|
|
<h2 id="text-to-image-generation-demo">Text to Image Generation Demo</h2> |
|
|
|
<p> |
|
Because WebGPU is not yet fully stable, nor have there ever been such |
|
large-scale AI models running on top of WebGPU, so we are testing the |
|
limit here. It may not work in your environment. So far, we have only |
|
tested it on Mac with M1/M2 GPUs in Chrome Canary (a nightly build of |
|
Chrome) because WebGPU is quite new. We have tested on Windows and it |
|
does not work at this moment due to possible driver issues. We |
|
anticipate the support broadens as WebGPU matures. Please check out the |
|
<a href="#instructions">use instructions</a> and |
|
<a href="#notes">notes</a> below. |
|
</p> |
|
|
|
<h3 id="instructions">Instructions</h3> |
|
|
|
<p> |
|
If you have a Mac computer with Apple silicon, here are the instructions |
|
for you to run stable diffusion on your browser locally: |
|
</p> |
|
|
|
<ul> |
|
<li> |
|
Install |
|
<a href="https://www.google.com/chrome/canary/">Chrome Canary</a>, a |
|
developer version of Chrome that enables the use of WebGPU. |
|
</li> |
|
<li> |
|
Launch Chrome Canary. |
|
<strong |
|
>You are recommended to launch from terminal with the following |
|
command:</strong |
|
> |
|
<div class="language-shell highlighter-rouge"> |
|
<div class="highlight"> |
|
<pre |
|
class="highlight" |
|
><code>/Applications/Google<span class="se">\ </span>Chrome<span class="se">\ </span>Canary.app/Contents/MacOS/Google<span class="se">\ </span>Chrome<span class="se">\ </span>Canary <span class="nt">--enable-dawn-features</span><span class="o">=</span>disable_robustness |
|
</code></pre> |
|
</div> |
|
</div> |
|
<p> |
|
This command turns off the robustness check from Chrome Canary that |
|
slows down image generation to times. It is not necessary, but we |
|
strongly recommend you to start Chrome with this command. |
|
</p> |
|
</li> |
|
<li> |
|
Enter your prompt, click “Generate” – we are ready to go! The image |
|
generation will start after downloading and fetching the model |
|
parameters to local cache. The download may take a few minutes, only |
|
for the first run. The subsequent refreshes and runs will be faster. |
|
</li> |
|
<li> |
|
Feel free to enter different prompts as well as negative prompts to |
|
generate the image you want. |
|
</li> |
|
<li> |
|
We provide an option to render images for the intermediate steps of |
|
UNet stage. Select “Run VAE every two UNet steps after step 10” for |
|
“Render intermediate steps” and click “Generate” again, and you will |
|
see how an image gets generated along the process. |
|
</li> |
|
</ul> |
|
|
|
|
|
|
|
<h3 id="notes">Notes</h3> |
|
|
|
<ul> |
|
|
|
<li> |
|
Please check out our |
|
<a href="https://github.com/mlc-ai/web-stable-diffusion" |
|
>GitHub repo</a |
|
> |
|
for running the same shader flow locally on your GPU device through |
|
the native driver. Right now, there are still gaps (e.g., without |
|
launching Chrome from command line, Chrome’s WebGPU implementation |
|
inserts bound clips for all array index access, such that |
|
<code class="language-plaintext highlighter-rouge">a[i]</code> becomes |
|
<code class="language-plaintext highlighter-rouge" |
|
>a[min(i, a.size)]</code |
|
>, which are not optimized out by the downstream shader compilers), |
|
but we believe it is feasible to close such gaps as WebGPU dispatches |
|
to these native drivers. |
|
</li> |
|
</ul> |
|
|
|
<h2 id="disclaimer">Disclaimer</h2> |
|
|
|
<p> |
|
This demo site is for research purposes only. Please conform to the |
|
<a href="https://huggingface.co/runwayml/stable-diffusion-v1-5#uses" |
|
>uses of stable diffusion models</a |
|
>. |
|
</p> |
|
</div> |
|
|
|
|
|
|
|
<script type="text/javascript" src="/assets/js/srcset-polyfill.js"></script> |
|
</body> |
|
</html> |
|
|