mirror of
https://github.com/easydiffusion/easydiffusion.git
synced 2025-04-30 22:34:32 +02:00
commit
0d13fe67b0
260
ui/index.html
260
ui/index.html
@ -25,7 +25,8 @@
|
|||||||
}
|
}
|
||||||
#prompt {
|
#prompt {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 50pt;
|
height: 65pt;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
@media screen and (max-width: 600px) {
|
@media screen and (max-width: 600px) {
|
||||||
#prompt {
|
#prompt {
|
||||||
@ -51,14 +52,14 @@
|
|||||||
font-family: Verdana;
|
font-family: Verdana;
|
||||||
font-size: 8pt;
|
font-size: 8pt;
|
||||||
}
|
}
|
||||||
#editor-settings-entries {
|
.settings-box ul {
|
||||||
font-size: 9pt;
|
font-size: 9pt;
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
}
|
}
|
||||||
#editor-settings-entries li {
|
.settings-box li {
|
||||||
padding-bottom: 3pt;
|
padding-bottom: 4pt;
|
||||||
}
|
}
|
||||||
.editor-slider {
|
.editor-slider {
|
||||||
transform: translateY(30%);
|
transform: translateY(30%);
|
||||||
@ -111,23 +112,26 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#container {
|
#container {
|
||||||
width: 75%;
|
width: 90%;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
}
|
}
|
||||||
@media screen and (max-width: 1400px) {
|
@media screen and (max-width: 1800px) {
|
||||||
#container {
|
#container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#meta small {
|
#logo small {
|
||||||
font-size: 11pt;
|
font-size: 11pt;
|
||||||
}
|
}
|
||||||
#editor {
|
#editor {
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
}
|
}
|
||||||
#editor label {
|
#editor label {
|
||||||
font-weight: bold;
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
.settings-box label small {
|
||||||
|
color: rgb(153, 153, 153);
|
||||||
}
|
}
|
||||||
#preview {
|
#preview {
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
@ -178,6 +182,9 @@
|
|||||||
.col-50 {
|
.col-50 {
|
||||||
flex: 50%;
|
flex: 50%;
|
||||||
}
|
}
|
||||||
|
.col-fixed-10 {
|
||||||
|
flex: 0 0 400pt;
|
||||||
|
}
|
||||||
.col-free {
|
.col-free {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
@ -256,16 +263,19 @@
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
#server-status {
|
#server-status {
|
||||||
|
display: inline;
|
||||||
float: right;
|
float: right;
|
||||||
|
transform: translateY(-5pt);
|
||||||
}
|
}
|
||||||
#server-status-color {
|
#server-status-color {
|
||||||
width: 8pt;
|
/* width: 8pt;
|
||||||
height: 8pt;
|
height: 8pt;
|
||||||
border-radius: 4pt;
|
border-radius: 4pt; */
|
||||||
background-color: rgb(128, 87, 0);
|
font-size: 14pt;
|
||||||
|
color: rgb(128, 87, 0);
|
||||||
/* background-color: rgb(197, 1, 1); */
|
/* background-color: rgb(197, 1, 1); */
|
||||||
float: left;
|
/* transform: translateY(15%); */
|
||||||
transform: translateY(15%);
|
display: inline;
|
||||||
}
|
}
|
||||||
#server-status-msg {
|
#server-status-msg {
|
||||||
color: rgb(128, 87, 0);
|
color: rgb(128, 87, 0);
|
||||||
@ -294,21 +304,141 @@
|
|||||||
#enable_mask {
|
#enable_mask {
|
||||||
margin-top: 8pt;
|
margin-top: 8pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#top-nav {
|
||||||
|
padding-top: 3pt;
|
||||||
|
padding-bottom: 15pt;
|
||||||
|
}
|
||||||
|
#top-nav .icon {
|
||||||
|
padding-right: 4pt;
|
||||||
|
font-size: 14pt;
|
||||||
|
transform: translateY(1pt);
|
||||||
|
}
|
||||||
|
#logo {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
#logo h1 {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
#top-nav-items {
|
||||||
|
list-style-type: none;
|
||||||
|
display: inline;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
#top-nav-items > li {
|
||||||
|
float: left;
|
||||||
|
display: inline;
|
||||||
|
padding-left: 20pt;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
#initial-text {
|
||||||
|
padding-top: 15pt;
|
||||||
|
padding-left: 4pt;
|
||||||
|
}
|
||||||
|
.settings-subheader {
|
||||||
|
font-size: 10pt;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.pl-5 {
|
||||||
|
padding-left: 5pt;
|
||||||
|
}
|
||||||
|
#system-settings {
|
||||||
|
width: 360pt;
|
||||||
|
transform: translateX(-100%) translateX(70pt);
|
||||||
|
|
||||||
|
padding-top: 10pt;
|
||||||
|
padding-bottom: 10pt;
|
||||||
|
}
|
||||||
|
#system-settings ul {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
#system-settings li {
|
||||||
|
padding-left: 5pt;
|
||||||
|
}
|
||||||
|
#community-links {
|
||||||
|
list-style-type: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 12pt;
|
||||||
|
padding-bottom: 0pt;
|
||||||
|
transform: translateX(-15%);
|
||||||
|
}
|
||||||
|
#community-links li {
|
||||||
|
padding-bottom: 12pt;
|
||||||
|
display: block;
|
||||||
|
font-size: 10pt;
|
||||||
|
}
|
||||||
|
#community-links li .fa-fw {
|
||||||
|
padding-right: 2pt;
|
||||||
|
}
|
||||||
|
#community-links li a {
|
||||||
|
color: white;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.dropdown {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.dropdown-content {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 2;
|
||||||
|
|
||||||
|
background: rgb(18, 18, 19);
|
||||||
|
border: 2px solid rgb(37, 38, 41);
|
||||||
|
border-radius: 7px;
|
||||||
|
padding: 5px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
box-shadow: 0 20px 28px 0 rgba(0, 0, 0, 0.15), 0 6px 20px 0 rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
.dropdown:hover .dropdown-content {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css">
|
||||||
<link rel="stylesheet" href="/media/drawingboard.min.css">
|
<link rel="stylesheet" href="/media/drawingboard.min.css">
|
||||||
<script src="/media/jquery-3.6.1.min.js"></script>
|
<script src="/media/jquery-3.6.1.min.js"></script>
|
||||||
<script src="/media/drawingboard.min.js"></script>
|
<script src="/media/drawingboard.min.js"></script>
|
||||||
</html>
|
</html>
|
||||||
<body>
|
<body>
|
||||||
<div id="container">
|
<div id="container">
|
||||||
<div class="flex-container">
|
<div id="top-nav">
|
||||||
<div id="editor" class="col-50">
|
<div id="logo">
|
||||||
<div id="meta">
|
<h1>Stable Diffusion UI <small>v2.16 <span id="updateBranchLabel"></span></small></h1>
|
||||||
<div id="server-status">
|
</div>
|
||||||
<div id="server-status-color"> </div>
|
<ul id="top-nav-items">
|
||||||
<span id="server-status-msg">Stable Diffusion is starting..</span>
|
<li class="dropdown">
|
||||||
|
<span><i class="fa fa-comments icon"></i> Help & Community</span>
|
||||||
|
<ul id="community-links" class="dropdown-content">
|
||||||
|
<li><a href="https://github.com/cmdr2/stable-diffusion-ui/blob/main/Troubleshooting.md" target="_blank"><i class="fa-solid fa-circle-question fa-fw"></i> Usual problems and solutions</a></li>
|
||||||
|
<li><a href="https://discord.com/invite/u9yhsFmEkB" target="_blank"><i class="fa-brands fa-discord fa-fw"></i> Discord user community</a></li>
|
||||||
|
<li><a href="https://github.com/cmdr2/stable-diffusion-ui" target="_blank"><i class="fa-brands fa-github fa-fw"></i> Source code on GitHub</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li class="dropdown">
|
||||||
|
<span><i class="fa fa-gear icon"></i> Settings</span>
|
||||||
|
<div id="system-settings" class="panel-box settings-box dropdown-content">
|
||||||
|
<ul id="system-settings-entries">
|
||||||
|
<li><b class="settings-subheader">System Settings</b></li>
|
||||||
|
<br/>
|
||||||
|
<li><input id="save_to_disk" name="save_to_disk" type="checkbox"> <label for="save_to_disk">Automatically save to <input id="diskPath" name="diskPath" size="40" disabled></label></li>
|
||||||
|
<li><input id="sound_toggle" name="sound_toggle" type="checkbox" checked> <label for="sound_toggle">Play sound on task completion</label></li>
|
||||||
|
<li><input id="turbo" name="turbo" type="checkbox" checked> <label for="turbo">Turbo mode <small>(generates images faster, but uses an additional 1 GB of GPU memory)</small></label></li>
|
||||||
|
<li><input id="use_cpu" name="use_cpu" type="checkbox"> <label for="use_cpu">Use CPU instead of GPU <small>(warning: this will be *very* slow)</small></label></li>
|
||||||
|
<li><input id="use_full_precision" name="use_full_precision" type="checkbox"> <label for="use_full_precision">Use full precision <small>(for GPU-only. warning: this will consume more VRAM)</small></label></li>
|
||||||
|
<!-- <li><input id="allow_nsfw" name="allow_nsfw" type="checkbox"> <label for="allow_nsfw">Allow NSFW Content (You confirm you are above 18 years of age)</label></li> -->
|
||||||
|
<br/>
|
||||||
|
<li><input id="use_beta_channel" name="use_beta_channel" type="checkbox"> <label for="use_beta_channel">🔥Beta channel. Get the latest features immediately (but could be less stable). Please restart the program after changing this.</label></li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<h1>Stable Diffusion UI <small>v2.14 <span id="updateBranchLabel"></span></small></h1>
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex-container">
|
||||||
|
<div id="editor" class="col-fixed-10">
|
||||||
|
<div id="server-status">
|
||||||
|
<div id="server-status-color">●</div>
|
||||||
|
<span id="server-status-msg">Stable Diffusion is starting..</span>
|
||||||
</div>
|
</div>
|
||||||
<div id="editor-inputs">
|
<div id="editor-inputs">
|
||||||
<div id="editor-inputs-prompt" class="row">
|
<div id="editor-inputs-prompt" class="row">
|
||||||
@ -341,23 +471,25 @@
|
|||||||
|
|
||||||
<div class="line-separator"> </div>
|
<div class="line-separator"> </div>
|
||||||
|
|
||||||
<div id="editor-settings" class="panel-box">
|
<div id="editor-settings" class="panel-box settings-box">
|
||||||
<h4 class="collapsible">Advanced Settings</h4>
|
<h4 class="collapsible">Image Settings</h4>
|
||||||
<ul id="editor-settings-entries" class="collapsible-content">
|
<ul id="editor-settings-entries" class="collapsible-content">
|
||||||
<li><input id="stream_image_progress" name="stream_image_progress" type="checkbox"> <label for="stream_image_progress">Show a live preview of the image (consumes more VRAM, slightly slower image generation)</label></li>
|
<li><b class="settings-subheader">Image Settings</b></li>
|
||||||
<li><input id="use_face_correction" name="use_face_correction" type="checkbox" checked> <label for="use_face_correction">Fix incorrect faces and eyes (uses GFPGAN)</label></li>
|
<li class="pl-5"><label for="seed">Seed:</label> <input id="seed" name="seed" size="10" value="30000"> <input id="random_seed" name="random_seed" type="checkbox" checked> <label for="random_seed">Random Image</label></li>
|
||||||
<li>
|
<li class="pl-5"><label for="num_outputs_total">Number of images to make:</label> <input id="num_outputs_total" name="num_outputs_total" value="1" size="1"> <label for="num_outputs_parallel">Generate in parallel:</label> <input id="num_outputs_parallel" name="num_outputs_parallel" value="1" size="1"> (images at once)</li>
|
||||||
<input id="use_upscale" name="use_upscale" type="checkbox"> <label for="use_upscale">Upscale the image to 4x resolution using </label>
|
<li id="samplerSelection" class="pl-5"><label for="sampler">Sampler:</label>
|
||||||
<select id="upscale_model" name="upscale_model">
|
<select id="sampler" name="sampler">
|
||||||
<option value="RealESRGAN_x4plus" selected>RealESRGAN_x4plus</option>
|
<option value="plms" selected>plms</option>
|
||||||
<option value="RealESRGAN_x4plus_anime_6B">RealESRGAN_x4plus_anime_6B</option>
|
<option value="ddim">ddim</option>
|
||||||
|
<option value="heun">heun</option>
|
||||||
|
<option value="euler">euler</option>
|
||||||
|
<option value="euler_a">euler_a</option>
|
||||||
|
<option value="dpm2">dpm2</option>
|
||||||
|
<option value="dpm2_a">dpm2_a</option>
|
||||||
|
<option value="lms">lms</option>
|
||||||
</select>
|
</select>
|
||||||
</li>
|
</li>
|
||||||
<li><input id="show_only_filtered_image" name="show_only_filtered_image" type="checkbox" checked> <label for="show_only_filtered_image">Show only the corrected/upscaled image</label></li>
|
<li class="pl-5"><label>Image Size: </label>
|
||||||
<br/>
|
|
||||||
<li><label for="seed">Seed:</label> <input id="seed" name="seed" size="10" value="30000"> <input id="random_seed" name="random_seed" type="checkbox" checked> <label for="random_seed">Random Image</label></li>
|
|
||||||
<li><label for="num_outputs_total">Number of images to make:</label> <input id="num_outputs_total" name="num_outputs_total" value="1" size="4"> <label for="num_outputs_parallel">Generate in parallel:</label> <input id="num_outputs_parallel" name="num_outputs_parallel" value="1" size="4"> (images at once)</li>
|
|
||||||
<li><label for="width">Width:</label>
|
|
||||||
<select id="width" name="width" value="512">
|
<select id="width" name="width" value="512">
|
||||||
<option value="128">128 (*)</option>
|
<option value="128">128 (*)</option>
|
||||||
<option value="192">192</option>
|
<option value="192">192</option>
|
||||||
@ -378,9 +510,7 @@
|
|||||||
<option value="1536">1536</option>
|
<option value="1536">1536</option>
|
||||||
<option value="1792">1792</option>
|
<option value="1792">1792</option>
|
||||||
<option value="2048">2048</option>
|
<option value="2048">2048</option>
|
||||||
</select>
|
</select> <label for="width"><small>(width)</small></label>
|
||||||
</li>
|
|
||||||
<li><label for="height">Height:</label>
|
|
||||||
<select id="height" name="height" value="512">
|
<select id="height" name="height" value="512">
|
||||||
<option value="128">128 (*)</option>
|
<option value="128">128 (*)</option>
|
||||||
<option value="192">192</option>
|
<option value="192">192</option>
|
||||||
@ -402,19 +532,27 @@
|
|||||||
<option value="1792">1792</option>
|
<option value="1792">1792</option>
|
||||||
<option value="2048">2048</option>
|
<option value="2048">2048</option>
|
||||||
</select>
|
</select>
|
||||||
|
<label for="height"><small>(height)</small></label>
|
||||||
</li>
|
</li>
|
||||||
<li><label for="num_inference_steps">Number of inference steps:</label> <input id="num_inference_steps" name="num_inference_steps" size="4" value="50"></li>
|
<li class="pl-5"><label for="num_inference_steps">Number of inference steps:</label> <input id="num_inference_steps" name="num_inference_steps" size="4" value="50"></li>
|
||||||
<li><label for="guidance_scale_slider">Guidance Scale:</label> <input id="guidance_scale_slider" name="guidance_scale_slider" class="editor-slider" value="75" type="range" min="10" max="200"> <input id="guidance_scale" name="guidance_scale" size="4"></li>
|
<li class="pl-5"><label for="guidance_scale_slider">Guidance Scale:</label> <input id="guidance_scale_slider" name="guidance_scale_slider" class="editor-slider" value="75" type="range" min="10" max="500"> <input id="guidance_scale" name="guidance_scale" size="4"></li>
|
||||||
<li><span id="prompt_strength_container"><label for="prompt_strength_slider">Prompt Strength:</label> <input id="prompt_strength_slider" name="prompt_strength_slider" class="editor-slider" value="80" type="range" min="0" max="99"> <input id="prompt_strength" name="prompt_strength" size="4"><br/></span></li>
|
<li class="pl-5"><span id="prompt_strength_container"><label for="prompt_strength_slider">Prompt Strength:</label> <input id="prompt_strength_slider" name="prompt_strength_slider" class="editor-slider" value="80" type="range" min="0" max="99"> <input id="prompt_strength" name="prompt_strength" size="4"><br/></span></li>
|
||||||
<li> </li>
|
|
||||||
<li><input id="save_to_disk" name="save_to_disk" type="checkbox"> <label for="save_to_disk">Automatically save to <input id="diskPath" name="diskPath" size="40" disabled></label></li>
|
|
||||||
<li><input id="sound_toggle" name="sound_toggle" type="checkbox" checked> <label for="sound_toggle">Play sound on task completion</label></li>
|
|
||||||
<li><input id="turbo" name="turbo" type="checkbox" checked> <label for="turbo">Turbo mode (generates images faster, but uses an additional 1 GB of GPU memory)</label></li>
|
|
||||||
<li><input id="use_cpu" name="use_cpu" type="checkbox"> <label for="use_cpu">Use CPU instead of GPU (warning: this will be *very* slow)</label></li>
|
|
||||||
<li><input id="use_full_precision" name="use_full_precision" type="checkbox"> <label for="use_full_precision">Use full precision (for GPU-only. warning: this will consume more VRAM)</label></li>
|
|
||||||
<!-- <li><input id="allow_nsfw" name="allow_nsfw" type="checkbox"> <label for="allow_nsfw">Allow NSFW Content (You confirm you are above 18 years of age)</label></li> -->
|
|
||||||
<br/>
|
<br/>
|
||||||
<li><input id="use_beta_channel" name="use_beta_channel" type="checkbox"> <label for="use_beta_channel">🔥Beta channel. Get the latest features immediately (but could be less stable). Please restart the program after changing this.</label></li>
|
|
||||||
|
<li><b class="settings-subheader">Render Settings</b></li>
|
||||||
|
<li class="pl-5"><input id="stream_image_progress" name="stream_image_progress" type="checkbox"> <label for="stream_image_progress">Show a live preview of the image <small>(consumes more VRAM, slightly slower image generation)</small></label></li>
|
||||||
|
<li class="pl-5"><input id="use_face_correction" name="use_face_correction" type="checkbox" checked> <label for="use_face_correction">Fix incorrect faces and eyes <small>(uses GFPGAN)</small></label></li>
|
||||||
|
<li class="pl-5">
|
||||||
|
<input id="use_upscale" name="use_upscale" type="checkbox"> <label for="use_upscale">Upscale the image to 4x resolution using </label>
|
||||||
|
<select id="upscale_model" name="upscale_model">
|
||||||
|
<option value="RealESRGAN_x4plus" selected>RealESRGAN_x4plus</option>
|
||||||
|
<option value="RealESRGAN_x4plus_anime_6B">RealESRGAN_x4plus_anime_6B</option>
|
||||||
|
</select>
|
||||||
|
</li>
|
||||||
|
<li class="pl-5"><input id="show_only_filtered_image" name="show_only_filtered_image" type="checkbox" checked> <label for="show_only_filtered_image">Show only the corrected/upscaled image</label></li>
|
||||||
|
<br/>
|
||||||
|
<li><small>The system-related settings have been moved to the top-right corner.</small></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -425,8 +563,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="preview" class="col-50">
|
<div id="preview" class="col-free">
|
||||||
<div id="preview-prompt">Type a prompt and press the "Make Image" button.<br/><br/>You can set an "Initial Image" if you want to guide the AI.<br/><br/>You can also add modifiers like "Realistic", "Pencil Sketch", "ArtStation" etc by browsing through the "Image Modifiers" section and selecting the desired modifiers.<br/><br/>Click "Advanced Settings" for additional settings like seed, image size, number of images to generate etc.<br/><br/>Enjoy! :)</div>
|
<div id="preview-prompt">
|
||||||
|
<div id="initial-text">
|
||||||
|
Type a prompt and press the "Make Image" button.<br/><br/>You can set an "Initial Image" if you want to guide the AI.<br/><br/>You can also add modifiers like "Realistic", "Pencil Sketch", "ArtStation" etc by browsing through the "Image Modifiers" section and selecting the desired modifiers.<br/><br/>Click "Advanced Settings" for additional settings like seed, image size, number of images to generate etc.<br/><br/>Enjoy! :)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="outputMsg"></div>
|
<div id="outputMsg"></div>
|
||||||
<div id="progressBar"></div>
|
<div id="progressBar"></div>
|
||||||
@ -492,6 +634,8 @@ let diskPathField = document.querySelector('#diskPath')
|
|||||||
let useBetaChannelField = document.querySelector("#use_beta_channel")
|
let useBetaChannelField = document.querySelector("#use_beta_channel")
|
||||||
let promptStrengthSlider = document.querySelector('#prompt_strength_slider')
|
let promptStrengthSlider = document.querySelector('#prompt_strength_slider')
|
||||||
let promptStrengthField = document.querySelector('#prompt_strength')
|
let promptStrengthField = document.querySelector('#prompt_strength')
|
||||||
|
let samplerField = document.querySelector('#sampler')
|
||||||
|
let samplerSelectionContainer = document.querySelector("#samplerSelection")
|
||||||
let useFaceCorrectionField = document.querySelector("#use_face_correction")
|
let useFaceCorrectionField = document.querySelector("#use_face_correction")
|
||||||
let useUpscalingField = document.querySelector("#use_upscale")
|
let useUpscalingField = document.querySelector("#use_upscale")
|
||||||
let upscaleModelField = document.querySelector("#upscale_model")
|
let upscaleModelField = document.querySelector("#upscale_model")
|
||||||
@ -645,12 +789,12 @@ function setStatus(statusType, msg, msgType) {
|
|||||||
|
|
||||||
if (msgType == 'error') {
|
if (msgType == 'error') {
|
||||||
// msg = '<span style="color: red">' + msg + '<span>'
|
// msg = '<span style="color: red">' + msg + '<span>'
|
||||||
serverStatusColor.style.backgroundColor = 'red'
|
serverStatusColor.style.color = 'red'
|
||||||
serverStatusMsg.style.color = 'red'
|
serverStatusMsg.style.color = 'red'
|
||||||
serverStatusMsg.innerHTML = 'Stable Diffusion has stopped'
|
serverStatusMsg.innerHTML = 'Stable Diffusion has stopped'
|
||||||
} else if (msgType == 'success') {
|
} else if (msgType == 'success') {
|
||||||
// msg = '<span style="color: green">' + msg + '<span>'
|
// msg = '<span style="color: green">' + msg + '<span>'
|
||||||
serverStatusColor.style.backgroundColor = 'green'
|
serverStatusColor.style.color = 'green'
|
||||||
serverStatusMsg.style.color = 'green'
|
serverStatusMsg.style.color = 'green'
|
||||||
serverStatusMsg.innerHTML = 'Stable Diffusion is ready'
|
serverStatusMsg.innerHTML = 'Stable Diffusion is ready'
|
||||||
serverStatus = 'online'
|
serverStatus = 'online'
|
||||||
@ -761,7 +905,7 @@ async function doMakeImage(reqBody, batchCount) {
|
|||||||
if (stepUpdate.step === undefined) {
|
if (stepUpdate.step === undefined) {
|
||||||
finalJSON += jsonStr
|
finalJSON += jsonStr
|
||||||
} else {
|
} else {
|
||||||
let batchSize = parseInt(reqBody['num_inference_steps'])
|
let batchSize = stepUpdate.total_steps
|
||||||
let overallStepCount = stepUpdate.step + batchesDone * batchSize
|
let overallStepCount = stepUpdate.step + batchesDone * batchSize
|
||||||
let totalSteps = batchCount * batchSize
|
let totalSteps = batchCount * batchSize
|
||||||
let percent = 100 * (overallStepCount / totalSteps)
|
let percent = 100 * (overallStepCount / totalSteps)
|
||||||
@ -1011,6 +1155,10 @@ async function makeImage() {
|
|||||||
if (maskSetting.checked) {
|
if (maskSetting.checked) {
|
||||||
reqBody['mask'] = inpaintingEditor.getImg()
|
reqBody['mask'] = inpaintingEditor.getImg()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reqBody['sampler'] = 'ddim'
|
||||||
|
} else {
|
||||||
|
reqBody['sampler'] = samplerField.value
|
||||||
}
|
}
|
||||||
|
|
||||||
if (saveToDiskField.checked && diskPathField.value.trim() !== '') {
|
if (saveToDiskField.checked && diskPathField.value.trim() !== '') {
|
||||||
@ -1177,8 +1325,8 @@ function updateGuidanceScale() {
|
|||||||
function updateGuidanceScaleSlider() {
|
function updateGuidanceScaleSlider() {
|
||||||
if (guidanceScaleField.value < 0) {
|
if (guidanceScaleField.value < 0) {
|
||||||
guidanceScaleField.value = 0
|
guidanceScaleField.value = 0
|
||||||
} else if (guidanceScaleField.value > 20) {
|
} else if (guidanceScaleField.value > 50) {
|
||||||
guidanceScaleField.value = 20
|
guidanceScaleField.value = 50
|
||||||
}
|
}
|
||||||
|
|
||||||
guidanceScaleSlider.value = guidanceScaleField.value * 10
|
guidanceScaleSlider.value = guidanceScaleField.value * 10
|
||||||
@ -1278,6 +1426,7 @@ function showInitImagePreview() {
|
|||||||
initImagePreviewContainer.style.display = 'block'
|
initImagePreviewContainer.style.display = 'block'
|
||||||
inpaintingEditorContainer.style.display = 'none'
|
inpaintingEditorContainer.style.display = 'none'
|
||||||
promptStrengthContainer.style.display = 'block'
|
promptStrengthContainer.style.display = 'block'
|
||||||
|
samplerSelectionContainer.style.display = 'none'
|
||||||
// maskSetting.checked = false
|
// maskSetting.checked = false
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -1309,6 +1458,7 @@ initImageClearBtn.addEventListener('click', function() {
|
|||||||
// maskSetting.style.display = 'none'
|
// maskSetting.style.display = 'none'
|
||||||
|
|
||||||
promptStrengthContainer.style.display = 'none'
|
promptStrengthContainer.style.display = 'none'
|
||||||
|
samplerSelectionContainer.style.display = 'block'
|
||||||
})
|
})
|
||||||
|
|
||||||
maskSetting.addEventListener('click', function() {
|
maskSetting.addEventListener('click', function() {
|
||||||
|
@ -12,6 +12,7 @@ class Request:
|
|||||||
height: int = 512
|
height: int = 512
|
||||||
seed: int = 42
|
seed: int = 42
|
||||||
prompt_strength: float = 0.8
|
prompt_strength: float = 0.8
|
||||||
|
sampler: str = None # "ddim", "plms", "heun", "euler", "euler_a", "dpm2", "dpm2_a", "lms"
|
||||||
# allow_nsfw: bool = False
|
# allow_nsfw: bool = False
|
||||||
precision: str = "autocast" # or "full"
|
precision: str = "autocast" # or "full"
|
||||||
save_to_disk_path: str = None
|
save_to_disk_path: str = None
|
||||||
@ -36,6 +37,7 @@ class Request:
|
|||||||
"height": self.height,
|
"height": self.height,
|
||||||
"seed": self.seed,
|
"seed": self.seed,
|
||||||
"prompt_strength": self.prompt_strength,
|
"prompt_strength": self.prompt_strength,
|
||||||
|
"sampler": self.sampler,
|
||||||
"use_face_correction": self.use_face_correction,
|
"use_face_correction": self.use_face_correction,
|
||||||
"use_upscale": self.use_upscale,
|
"use_upscale": self.use_upscale,
|
||||||
}
|
}
|
||||||
@ -46,6 +48,7 @@ class Request:
|
|||||||
prompt: {self.prompt}
|
prompt: {self.prompt}
|
||||||
seed: {self.seed}
|
seed: {self.seed}
|
||||||
num_inference_steps: {self.num_inference_steps}
|
num_inference_steps: {self.num_inference_steps}
|
||||||
|
sampler: {self.sampler}
|
||||||
guidance_scale: {self.guidance_scale}
|
guidance_scale: {self.guidance_scale}
|
||||||
w: {self.width}
|
w: {self.width}
|
||||||
h: {self.height}
|
h: {self.height}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
diff --git a/optimizedSD/ddpm.py b/optimizedSD/ddpm.py
|
diff --git a/optimizedSD/ddpm.py b/optimizedSD/ddpm.py
|
||||||
index b967b55..75ddd8b 100644
|
index b967b55..35ef520 100644
|
||||||
--- a/optimizedSD/ddpm.py
|
--- a/optimizedSD/ddpm.py
|
||||||
+++ b/optimizedSD/ddpm.py
|
+++ b/optimizedSD/ddpm.py
|
||||||
@@ -22,7 +22,7 @@ from ldm.util import exists, default, instantiate_from_config
|
@@ -22,7 +22,7 @@ from ldm.util import exists, default, instantiate_from_config
|
||||||
@ -11,122 +11,312 @@ index b967b55..75ddd8b 100644
|
|||||||
|
|
||||||
def disabled_train(self):
|
def disabled_train(self):
|
||||||
"""Overwrite model.train with this function to make sure train/eval mode
|
"""Overwrite model.train with this function to make sure train/eval mode
|
||||||
@@ -485,6 +485,7 @@ class UNet(DDPM):
|
@@ -506,6 +506,8 @@ class UNet(DDPM):
|
||||||
log_every_t=100,
|
|
||||||
unconditional_guidance_scale=1.,
|
x_latent = noise if x0 is None else x0
|
||||||
unconditional_conditioning=None,
|
# sampling
|
||||||
+ streaming_callbacks = False,
|
+ if sampler in ('ddim', 'dpm2', 'heun', 'dpm2_a', 'lms') and not hasattr(self, 'ddim_timesteps'):
|
||||||
):
|
+ self.make_schedule(ddim_num_steps=S, ddim_eta=eta, verbose=False)
|
||||||
|
|
||||||
|
if sampler == "plms":
|
||||||
@@ -523,12 +524,15 @@ class UNet(DDPM):
|
self.make_schedule(ddim_num_steps=S, ddim_eta=eta, verbose=False)
|
||||||
log_every_t=log_every_t,
|
@@ -528,39 +530,46 @@ class UNet(DDPM):
|
||||||
unconditional_guidance_scale=unconditional_guidance_scale,
|
|
||||||
unconditional_conditioning=unconditional_conditioning,
|
|
||||||
+ streaming_callbacks=streaming_callbacks
|
|
||||||
)
|
|
||||||
|
|
||||||
elif sampler == "ddim":
|
elif sampler == "ddim":
|
||||||
samples = self.ddim_sampling(x_latent, conditioning, S, unconditional_guidance_scale=unconditional_guidance_scale,
|
samples = self.ddim_sampling(x_latent, conditioning, S, unconditional_guidance_scale=unconditional_guidance_scale,
|
||||||
unconditional_conditioning=unconditional_conditioning,
|
unconditional_conditioning=unconditional_conditioning,
|
||||||
- mask = mask,init_latent=x_T,use_original_steps=False)
|
- mask = mask,init_latent=x_T,use_original_steps=False)
|
||||||
+ mask = mask,init_latent=x_T,use_original_steps=False,
|
+ mask = mask,init_latent=x_T,use_original_steps=False,
|
||||||
+ callback=callback, img_callback=img_callback,
|
+ callback=callback, img_callback=img_callback)
|
||||||
+ streaming_callbacks=streaming_callbacks)
|
|
||||||
|
|
||||||
elif sampler == "euler":
|
elif sampler == "euler":
|
||||||
self.make_schedule(ddim_num_steps=S, ddim_eta=eta, verbose=False)
|
self.make_schedule(ddim_num_steps=S, ddim_eta=eta, verbose=False)
|
||||||
@@ -555,11 +559,15 @@ class UNet(DDPM):
|
samples = self.euler_sampling(self.alphas_cumprod,x_latent, S, conditioning, unconditional_conditioning=unconditional_conditioning,
|
||||||
samples = self.lms_sampling(self.alphas_cumprod,x_latent, S, conditioning, unconditional_conditioning=unconditional_conditioning,
|
- unconditional_guidance_scale=unconditional_guidance_scale)
|
||||||
unconditional_guidance_scale=unconditional_guidance_scale)
|
+ unconditional_guidance_scale=unconditional_guidance_scale,
|
||||||
|
+ img_callback=img_callback)
|
||||||
|
elif sampler == "euler_a":
|
||||||
|
self.make_schedule(ddim_num_steps=S, ddim_eta=eta, verbose=False)
|
||||||
|
samples = self.euler_ancestral_sampling(self.alphas_cumprod,x_latent, S, conditioning, unconditional_conditioning=unconditional_conditioning,
|
||||||
|
- unconditional_guidance_scale=unconditional_guidance_scale)
|
||||||
|
+ unconditional_guidance_scale=unconditional_guidance_scale,
|
||||||
|
+ img_callback=img_callback)
|
||||||
|
|
||||||
+ if streaming_callbacks: # this line needs to be right after the sampling() call
|
elif sampler == "dpm2":
|
||||||
+ yield from samples
|
samples = self.dpm_2_sampling(self.alphas_cumprod,x_latent, S, conditioning, unconditional_conditioning=unconditional_conditioning,
|
||||||
|
- unconditional_guidance_scale=unconditional_guidance_scale)
|
||||||
|
+ unconditional_guidance_scale=unconditional_guidance_scale,
|
||||||
|
+ img_callback=img_callback)
|
||||||
|
elif sampler == "heun":
|
||||||
|
samples = self.heun_sampling(self.alphas_cumprod,x_latent, S, conditioning, unconditional_conditioning=unconditional_conditioning,
|
||||||
|
- unconditional_guidance_scale=unconditional_guidance_scale)
|
||||||
|
+ unconditional_guidance_scale=unconditional_guidance_scale,
|
||||||
|
+ img_callback=img_callback)
|
||||||
|
|
||||||
|
elif sampler == "dpm2_a":
|
||||||
|
samples = self.dpm_2_ancestral_sampling(self.alphas_cumprod,x_latent, S, conditioning, unconditional_conditioning=unconditional_conditioning,
|
||||||
|
- unconditional_guidance_scale=unconditional_guidance_scale)
|
||||||
|
+ unconditional_guidance_scale=unconditional_guidance_scale,
|
||||||
|
+ img_callback=img_callback)
|
||||||
|
|
||||||
|
|
||||||
|
elif sampler == "lms":
|
||||||
|
samples = self.lms_sampling(self.alphas_cumprod,x_latent, S, conditioning, unconditional_conditioning=unconditional_conditioning,
|
||||||
|
- unconditional_guidance_scale=unconditional_guidance_scale)
|
||||||
|
+ unconditional_guidance_scale=unconditional_guidance_scale,
|
||||||
|
+ img_callback=img_callback)
|
||||||
+
|
+
|
||||||
|
+ yield from samples
|
||||||
|
|
||||||
if(self.turbo):
|
if(self.turbo):
|
||||||
self.model1.to("cpu")
|
self.model1.to("cpu")
|
||||||
self.model2.to("cpu")
|
self.model2.to("cpu")
|
||||||
|
|
||||||
- return samples
|
- return samples
|
||||||
+ if not streaming_callbacks:
|
-
|
||||||
+ return samples
|
|
||||||
|
|
||||||
@torch.no_grad()
|
@torch.no_grad()
|
||||||
def plms_sampling(self, cond,b, img,
|
def plms_sampling(self, cond,b, img,
|
||||||
@@ -567,7 +575,8 @@ class UNet(DDPM):
|
ddim_use_original_steps=False,
|
||||||
callback=None, quantize_denoised=False,
|
@@ -599,10 +608,10 @@ class UNet(DDPM):
|
||||||
mask=None, x0=None, img_callback=None, log_every_t=100,
|
|
||||||
temperature=1., noise_dropout=0., score_corrector=None, corrector_kwargs=None,
|
|
||||||
- unconditional_guidance_scale=1., unconditional_conditioning=None,):
|
|
||||||
+ unconditional_guidance_scale=1., unconditional_conditioning=None,
|
|
||||||
+ streaming_callbacks=False):
|
|
||||||
|
|
||||||
device = self.betas.device
|
|
||||||
timesteps = self.ddim_timesteps
|
|
||||||
@@ -599,10 +608,21 @@ class UNet(DDPM):
|
|
||||||
old_eps.append(e_t)
|
old_eps.append(e_t)
|
||||||
if len(old_eps) >= 4:
|
if len(old_eps) >= 4:
|
||||||
old_eps.pop(0)
|
old_eps.pop(0)
|
||||||
- if callback: callback(i)
|
- if callback: callback(i)
|
||||||
- if img_callback: img_callback(pred_x0, i)
|
- if img_callback: img_callback(pred_x0, i)
|
||||||
-
|
+ if callback: yield from callback(i)
|
||||||
|
+ if img_callback: yield from img_callback(pred_x0, i)
|
||||||
|
|
||||||
- return img
|
- return img
|
||||||
+ if callback:
|
+ yield from img_callback(img, len(iterator)-1)
|
||||||
+ if streaming_callbacks:
|
|
||||||
+ yield from callback(i)
|
|
||||||
+ else:
|
|
||||||
+ callback(i)
|
|
||||||
+ if img_callback:
|
|
||||||
+ if streaming_callbacks:
|
|
||||||
+ yield from img_callback(pred_x0, i)
|
|
||||||
+ else:
|
|
||||||
+ img_callback(pred_x0, i)
|
|
||||||
+
|
|
||||||
+ if streaming_callbacks and img_callback:
|
|
||||||
+ yield from img_callback(img, len(iterator)-1)
|
|
||||||
+ else:
|
|
||||||
+ return img
|
|
||||||
|
|
||||||
@torch.no_grad()
|
@torch.no_grad()
|
||||||
def p_sample_plms(self, x, c, t, index, repeat_noise=False, use_original_steps=False, quantize_denoised=False,
|
def p_sample_plms(self, x, c, t, index, repeat_noise=False, use_original_steps=False, quantize_denoised=False,
|
||||||
@@ -706,7 +726,9 @@ class UNet(DDPM):
|
@@ -706,7 +715,8 @@ class UNet(DDPM):
|
||||||
|
|
||||||
@torch.no_grad()
|
@torch.no_grad()
|
||||||
def ddim_sampling(self, x_latent, cond, t_start, unconditional_guidance_scale=1.0, unconditional_conditioning=None,
|
def ddim_sampling(self, x_latent, cond, t_start, unconditional_guidance_scale=1.0, unconditional_conditioning=None,
|
||||||
- mask = None,init_latent=None,use_original_steps=False):
|
- mask = None,init_latent=None,use_original_steps=False):
|
||||||
+ mask = None,init_latent=None,use_original_steps=False,
|
+ mask = None,init_latent=None,use_original_steps=False,
|
||||||
+ callback=None, img_callback=None,
|
+ callback=None, img_callback=None):
|
||||||
+ streaming_callbacks=False):
|
|
||||||
|
|
||||||
timesteps = self.ddim_timesteps
|
timesteps = self.ddim_timesteps
|
||||||
timesteps = timesteps[:t_start]
|
timesteps = timesteps[:t_start]
|
||||||
@@ -730,10 +752,24 @@ class UNet(DDPM):
|
@@ -730,10 +740,13 @@ class UNet(DDPM):
|
||||||
unconditional_guidance_scale=unconditional_guidance_scale,
|
unconditional_guidance_scale=unconditional_guidance_scale,
|
||||||
unconditional_conditioning=unconditional_conditioning)
|
unconditional_conditioning=unconditional_conditioning)
|
||||||
|
|
||||||
+ if callback:
|
+ if callback: yield from callback(i)
|
||||||
+ if streaming_callbacks:
|
+ if img_callback: yield from img_callback(x_dec, i)
|
||||||
+ yield from callback(i)
|
|
||||||
+ else:
|
|
||||||
+ callback(i)
|
|
||||||
+ if img_callback:
|
|
||||||
+ if streaming_callbacks:
|
|
||||||
+ yield from img_callback(x_dec, i)
|
|
||||||
+ else:
|
|
||||||
+ img_callback(x_dec, i)
|
|
||||||
+
|
+
|
||||||
if mask is not None:
|
if mask is not None:
|
||||||
- return x0 * mask + (1. - mask) * x_dec
|
- return x0 * mask + (1. - mask) * x_dec
|
||||||
+ x_dec = x0 * mask + (1. - mask) * x_dec
|
+ x_dec = x0 * mask + (1. - mask) * x_dec
|
||||||
|
|
||||||
- return x_dec
|
- return x_dec
|
||||||
+ if streaming_callbacks and img_callback:
|
+ yield from img_callback(x_dec, len(iterator)-1)
|
||||||
+ yield from img_callback(x_dec, len(iterator)-1)
|
|
||||||
+ else:
|
|
||||||
+ return x_dec
|
|
||||||
|
|
||||||
|
|
||||||
@torch.no_grad()
|
@torch.no_grad()
|
||||||
|
@@ -779,13 +792,16 @@ class UNet(DDPM):
|
||||||
|
|
||||||
|
|
||||||
|
@torch.no_grad()
|
||||||
|
- def euler_sampling(self, ac, x, S, cond, unconditional_conditioning = None, unconditional_guidance_scale = 1,extra_args=None,callback=None, disable=None, s_churn=0., s_tmin=0., s_tmax=float('inf'), s_noise=1.):
|
||||||
|
+ def euler_sampling(self, ac, x, S, cond, unconditional_conditioning = None, unconditional_guidance_scale = 1,extra_args=None,callback=None, disable=None, s_churn=0., s_tmin=0., s_tmax=float('inf'), s_noise=1.,
|
||||||
|
+ img_callback=None):
|
||||||
|
"""Implements Algorithm 2 (Euler steps) from Karras et al. (2022)."""
|
||||||
|
extra_args = {} if extra_args is None else extra_args
|
||||||
|
cvd = CompVisDenoiser(ac)
|
||||||
|
sigmas = cvd.get_sigmas(S)
|
||||||
|
x = x*sigmas[0]
|
||||||
|
|
||||||
|
+ print(f"Running Euler Sampling with {len(sigmas) - 1} timesteps")
|
||||||
|
+
|
||||||
|
s_in = x.new_ones([x.shape[0]]).half()
|
||||||
|
for i in trange(len(sigmas) - 1, disable=disable):
|
||||||
|
gamma = min(s_churn / (len(sigmas) - 1), 2 ** 0.5 - 1) if s_tmin <= sigmas[i] <= s_tmax else 0.
|
||||||
|
@@ -807,13 +823,18 @@ class UNet(DDPM):
|
||||||
|
d = to_d(x, sigma_hat, denoised)
|
||||||
|
if callback is not None:
|
||||||
|
callback({'x': x, 'i': i, 'sigma': sigmas[i], 'sigma_hat': sigma_hat, 'denoised': denoised})
|
||||||
|
+
|
||||||
|
+ if img_callback: yield from img_callback(x, i)
|
||||||
|
+
|
||||||
|
dt = sigmas[i + 1] - sigma_hat
|
||||||
|
# Euler method
|
||||||
|
x = x + d * dt
|
||||||
|
- return x
|
||||||
|
+
|
||||||
|
+ yield from img_callback(x, len(sigmas)-1)
|
||||||
|
|
||||||
|
@torch.no_grad()
|
||||||
|
- def euler_ancestral_sampling(self,ac,x, S, cond, unconditional_conditioning = None, unconditional_guidance_scale = 1,extra_args=None, callback=None, disable=None):
|
||||||
|
+ def euler_ancestral_sampling(self,ac,x, S, cond, unconditional_conditioning = None, unconditional_guidance_scale = 1,extra_args=None, callback=None, disable=None,
|
||||||
|
+ img_callback=None):
|
||||||
|
"""Ancestral sampling with Euler method steps."""
|
||||||
|
extra_args = {} if extra_args is None else extra_args
|
||||||
|
|
||||||
|
@@ -822,6 +843,8 @@ class UNet(DDPM):
|
||||||
|
sigmas = cvd.get_sigmas(S)
|
||||||
|
x = x*sigmas[0]
|
||||||
|
|
||||||
|
+ print(f"Running Euler Ancestral Sampling with {len(sigmas) - 1} timesteps")
|
||||||
|
+
|
||||||
|
s_in = x.new_ones([x.shape[0]]).half()
|
||||||
|
for i in trange(len(sigmas) - 1, disable=disable):
|
||||||
|
|
||||||
|
@@ -837,17 +860,22 @@ class UNet(DDPM):
|
||||||
|
sigma_down, sigma_up = get_ancestral_step(sigmas[i], sigmas[i + 1])
|
||||||
|
if callback is not None:
|
||||||
|
callback({'x': x, 'i': i, 'sigma': sigmas[i], 'sigma_hat': sigmas[i], 'denoised': denoised})
|
||||||
|
+
|
||||||
|
+ if img_callback: yield from img_callback(x, i)
|
||||||
|
+
|
||||||
|
d = to_d(x, sigmas[i], denoised)
|
||||||
|
# Euler method
|
||||||
|
dt = sigma_down - sigmas[i]
|
||||||
|
x = x + d * dt
|
||||||
|
x = x + torch.randn_like(x) * sigma_up
|
||||||
|
- return x
|
||||||
|
+
|
||||||
|
+ yield from img_callback(x, len(sigmas)-1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@torch.no_grad()
|
||||||
|
- def heun_sampling(self, ac, x, S, cond, unconditional_conditioning = None, unconditional_guidance_scale = 1, extra_args=None, callback=None, disable=None, s_churn=0., s_tmin=0., s_tmax=float('inf'), s_noise=1.):
|
||||||
|
+ def heun_sampling(self, ac, x, S, cond, unconditional_conditioning = None, unconditional_guidance_scale = 1, extra_args=None, callback=None, disable=None, s_churn=0., s_tmin=0., s_tmax=float('inf'), s_noise=1.,
|
||||||
|
+ img_callback=None):
|
||||||
|
"""Implements Algorithm 2 (Heun steps) from Karras et al. (2022)."""
|
||||||
|
extra_args = {} if extra_args is None else extra_args
|
||||||
|
|
||||||
|
@@ -855,6 +883,8 @@ class UNet(DDPM):
|
||||||
|
sigmas = cvd.get_sigmas(S)
|
||||||
|
x = x*sigmas[0]
|
||||||
|
|
||||||
|
+ print(f"Running Heun Sampling with {len(sigmas) - 1} timesteps")
|
||||||
|
+
|
||||||
|
|
||||||
|
s_in = x.new_ones([x.shape[0]]).half()
|
||||||
|
for i in trange(len(sigmas) - 1, disable=disable):
|
||||||
|
@@ -876,6 +906,9 @@ class UNet(DDPM):
|
||||||
|
d = to_d(x, sigma_hat, denoised)
|
||||||
|
if callback is not None:
|
||||||
|
callback({'x': x, 'i': i, 'sigma': sigmas[i], 'sigma_hat': sigma_hat, 'denoised': denoised})
|
||||||
|
+
|
||||||
|
+ if img_callback: yield from img_callback(x, i)
|
||||||
|
+
|
||||||
|
dt = sigmas[i + 1] - sigma_hat
|
||||||
|
if sigmas[i + 1] == 0:
|
||||||
|
# Euler method
|
||||||
|
@@ -895,11 +928,13 @@ class UNet(DDPM):
|
||||||
|
d_2 = to_d(x_2, sigmas[i + 1], denoised_2)
|
||||||
|
d_prime = (d + d_2) / 2
|
||||||
|
x = x + d_prime * dt
|
||||||
|
- return x
|
||||||
|
+
|
||||||
|
+ yield from img_callback(x, len(sigmas)-1)
|
||||||
|
|
||||||
|
|
||||||
|
@torch.no_grad()
|
||||||
|
- def dpm_2_sampling(self,ac,x, S, cond, unconditional_conditioning = None, unconditional_guidance_scale = 1,extra_args=None, callback=None, disable=None, s_churn=0., s_tmin=0., s_tmax=float('inf'), s_noise=1.):
|
||||||
|
+ def dpm_2_sampling(self,ac,x, S, cond, unconditional_conditioning = None, unconditional_guidance_scale = 1,extra_args=None, callback=None, disable=None, s_churn=0., s_tmin=0., s_tmax=float('inf'), s_noise=1.,
|
||||||
|
+ img_callback=None):
|
||||||
|
"""A sampler inspired by DPM-Solver-2 and Algorithm 2 from Karras et al. (2022)."""
|
||||||
|
extra_args = {} if extra_args is None else extra_args
|
||||||
|
|
||||||
|
@@ -907,6 +942,8 @@ class UNet(DDPM):
|
||||||
|
sigmas = cvd.get_sigmas(S)
|
||||||
|
x = x*sigmas[0]
|
||||||
|
|
||||||
|
+ print(f"Running DPM2 Sampling with {len(sigmas) - 1} timesteps")
|
||||||
|
+
|
||||||
|
s_in = x.new_ones([x.shape[0]]).half()
|
||||||
|
for i in trange(len(sigmas) - 1, disable=disable):
|
||||||
|
gamma = min(s_churn / (len(sigmas) - 1), 2 ** 0.5 - 1) if s_tmin <= sigmas[i] <= s_tmax else 0.
|
||||||
|
@@ -924,7 +961,7 @@ class UNet(DDPM):
|
||||||
|
e_t_uncond, e_t = (x_in + eps * c_out).chunk(2)
|
||||||
|
denoised = e_t_uncond + unconditional_guidance_scale * (e_t - e_t_uncond)
|
||||||
|
|
||||||
|
-
|
||||||
|
+ if img_callback: yield from img_callback(x, i)
|
||||||
|
|
||||||
|
d = to_d(x, sigma_hat, denoised)
|
||||||
|
# Midpoint method, where the midpoint is chosen according to a rho=3 Karras schedule
|
||||||
|
@@ -945,11 +982,13 @@ class UNet(DDPM):
|
||||||
|
|
||||||
|
d_2 = to_d(x_2, sigma_mid, denoised_2)
|
||||||
|
x = x + d_2 * dt_2
|
||||||
|
- return x
|
||||||
|
+
|
||||||
|
+ yield from img_callback(x, len(sigmas)-1)
|
||||||
|
|
||||||
|
|
||||||
|
@torch.no_grad()
|
||||||
|
- def dpm_2_ancestral_sampling(self,ac,x, S, cond, unconditional_conditioning = None, unconditional_guidance_scale = 1, extra_args=None, callback=None, disable=None):
|
||||||
|
+ def dpm_2_ancestral_sampling(self,ac,x, S, cond, unconditional_conditioning = None, unconditional_guidance_scale = 1, extra_args=None, callback=None, disable=None,
|
||||||
|
+ img_callback=None):
|
||||||
|
"""Ancestral sampling with DPM-Solver inspired second-order steps."""
|
||||||
|
extra_args = {} if extra_args is None else extra_args
|
||||||
|
|
||||||
|
@@ -957,6 +996,8 @@ class UNet(DDPM):
|
||||||
|
sigmas = cvd.get_sigmas(S)
|
||||||
|
x = x*sigmas[0]
|
||||||
|
|
||||||
|
+ print(f"Running DPM2 Ancestral Sampling with {len(sigmas) - 1} timesteps")
|
||||||
|
+
|
||||||
|
s_in = x.new_ones([x.shape[0]]).half()
|
||||||
|
for i in trange(len(sigmas) - 1, disable=disable):
|
||||||
|
|
||||||
|
@@ -973,6 +1014,9 @@ class UNet(DDPM):
|
||||||
|
sigma_down, sigma_up = get_ancestral_step(sigmas[i], sigmas[i + 1])
|
||||||
|
if callback is not None:
|
||||||
|
callback({'x': x, 'i': i, 'sigma': sigmas[i], 'sigma_hat': sigmas[i], 'denoised': denoised})
|
||||||
|
+
|
||||||
|
+ if img_callback: yield from img_callback(x, i)
|
||||||
|
+
|
||||||
|
d = to_d(x, sigmas[i], denoised)
|
||||||
|
# Midpoint method, where the midpoint is chosen according to a rho=3 Karras schedule
|
||||||
|
sigma_mid = ((sigmas[i] ** (1 / 3) + sigma_down ** (1 / 3)) / 2) ** 3
|
||||||
|
@@ -993,11 +1037,13 @@ class UNet(DDPM):
|
||||||
|
d_2 = to_d(x_2, sigma_mid, denoised_2)
|
||||||
|
x = x + d_2 * dt_2
|
||||||
|
x = x + torch.randn_like(x) * sigma_up
|
||||||
|
- return x
|
||||||
|
+
|
||||||
|
+ yield from img_callback(x, len(sigmas)-1)
|
||||||
|
|
||||||
|
|
||||||
|
@torch.no_grad()
|
||||||
|
- def lms_sampling(self,ac,x, S, cond, unconditional_conditioning = None, unconditional_guidance_scale = 1, extra_args=None, callback=None, disable=None, order=4):
|
||||||
|
+ def lms_sampling(self,ac,x, S, cond, unconditional_conditioning = None, unconditional_guidance_scale = 1, extra_args=None, callback=None, disable=None, order=4,
|
||||||
|
+ img_callback=None):
|
||||||
|
extra_args = {} if extra_args is None else extra_args
|
||||||
|
s_in = x.new_ones([x.shape[0]])
|
||||||
|
|
||||||
|
@@ -1005,6 +1051,8 @@ class UNet(DDPM):
|
||||||
|
sigmas = cvd.get_sigmas(S)
|
||||||
|
x = x*sigmas[0]
|
||||||
|
|
||||||
|
+ print(f"Running LMS Sampling with {len(sigmas) - 1} timesteps")
|
||||||
|
+
|
||||||
|
ds = []
|
||||||
|
for i in trange(len(sigmas) - 1, disable=disable):
|
||||||
|
|
||||||
|
@@ -1017,6 +1065,7 @@ class UNet(DDPM):
|
||||||
|
e_t_uncond, e_t = (x_in + eps * c_out).chunk(2)
|
||||||
|
denoised = e_t_uncond + unconditional_guidance_scale * (e_t - e_t_uncond)
|
||||||
|
|
||||||
|
+ if img_callback: yield from img_callback(x, i)
|
||||||
|
|
||||||
|
d = to_d(x, sigmas[i], denoised)
|
||||||
|
ds.append(d)
|
||||||
|
@@ -1027,4 +1076,5 @@ class UNet(DDPM):
|
||||||
|
cur_order = min(i + 1, order)
|
||||||
|
coeffs = [linear_multistep_coeff(cur_order, sigmas.cpu(), i, j) for j in range(cur_order)]
|
||||||
|
x = x + sum(coeff * d for coeff, d in zip(coeffs, reversed(ds)))
|
||||||
|
- return x
|
||||||
|
+
|
||||||
|
+ yield from img_callback(x, len(sigmas)-1)
|
||||||
diff --git a/optimizedSD/openaimodelSplit.py b/optimizedSD/openaimodelSplit.py
|
diff --git a/optimizedSD/openaimodelSplit.py b/optimizedSD/openaimodelSplit.py
|
||||||
index abc3098..7a32ffe 100644
|
index abc3098..7a32ffe 100644
|
||||||
--- a/optimizedSD/openaimodelSplit.py
|
--- a/optimizedSD/openaimodelSplit.py
|
||||||
|
@ -275,6 +275,7 @@ def do_mk_img(req: Request):
|
|||||||
opt_use_upscale = req.use_upscale
|
opt_use_upscale = req.use_upscale
|
||||||
opt_show_only_filtered = req.show_only_filtered_image
|
opt_show_only_filtered = req.show_only_filtered_image
|
||||||
opt_format = 'png'
|
opt_format = 'png'
|
||||||
|
opt_sampler_name = req.sampler
|
||||||
|
|
||||||
print(req.to_string(), '\n device', device)
|
print(req.to_string(), '\n device', device)
|
||||||
|
|
||||||
@ -368,7 +369,8 @@ def do_mk_img(req: Request):
|
|||||||
partial_x_samples = x_samples
|
partial_x_samples = x_samples
|
||||||
|
|
||||||
if req.stream_progress_updates:
|
if req.stream_progress_updates:
|
||||||
progress = {"step": i, "total_steps": opt_ddim_steps}
|
n_steps = opt_ddim_steps if req.init_image is None else t_enc
|
||||||
|
progress = {"step": i, "total_steps": n_steps}
|
||||||
|
|
||||||
if req.stream_image_progress and i % 5 == 0:
|
if req.stream_image_progress and i % 5 == 0:
|
||||||
partial_images = []
|
partial_images = []
|
||||||
@ -399,12 +401,11 @@ def do_mk_img(req: Request):
|
|||||||
# run the handler
|
# run the handler
|
||||||
try:
|
try:
|
||||||
if handler == _txt2img:
|
if handler == _txt2img:
|
||||||
x_samples = _txt2img(opt_W, opt_H, opt_n_samples, opt_ddim_steps, opt_scale, None, opt_C, opt_f, opt_ddim_eta, c, uc, opt_seed, img_callback, req.stream_progress_updates, mask)
|
x_samples = _txt2img(opt_W, opt_H, opt_n_samples, opt_ddim_steps, opt_scale, None, opt_C, opt_f, opt_ddim_eta, c, uc, opt_seed, img_callback, mask, opt_sampler_name)
|
||||||
else:
|
else:
|
||||||
x_samples = _img2img(init_latent, t_enc, batch_size, opt_scale, c, uc, opt_ddim_steps, opt_ddim_eta, opt_seed, img_callback, req.stream_progress_updates, mask)
|
x_samples = _img2img(init_latent, t_enc, batch_size, opt_scale, c, uc, opt_ddim_steps, opt_ddim_eta, opt_seed, img_callback, mask)
|
||||||
|
|
||||||
if req.stream_progress_updates:
|
yield from x_samples
|
||||||
yield from x_samples
|
|
||||||
|
|
||||||
x_samples = partial_x_samples
|
x_samples = partial_x_samples
|
||||||
except UserInitiatedStop:
|
except UserInitiatedStop:
|
||||||
@ -443,7 +444,7 @@ def do_mk_img(req: Request):
|
|||||||
if return_orig_img:
|
if return_orig_img:
|
||||||
save_image(img, img_out_path)
|
save_image(img, img_out_path)
|
||||||
|
|
||||||
save_metadata(meta_out_path, prompts, opt_seed, opt_W, opt_H, opt_ddim_steps, opt_scale, opt_strength, opt_use_face_correction, opt_use_upscale)
|
save_metadata(meta_out_path, prompts, opt_seed, opt_W, opt_H, opt_ddim_steps, opt_scale, opt_strength, opt_use_face_correction, opt_use_upscale, opt_sampler_name)
|
||||||
|
|
||||||
if return_orig_img:
|
if return_orig_img:
|
||||||
img_data = img_to_base64_str(img)
|
img_data = img_to_base64_str(img)
|
||||||
@ -496,10 +497,7 @@ def do_mk_img(req: Request):
|
|||||||
|
|
||||||
print('Task completed')
|
print('Task completed')
|
||||||
|
|
||||||
if req.stream_progress_updates:
|
yield json.dumps(res.json())
|
||||||
yield json.dumps(res.json())
|
|
||||||
else:
|
|
||||||
return res
|
|
||||||
|
|
||||||
def save_image(img, img_out_path):
|
def save_image(img, img_out_path):
|
||||||
try:
|
try:
|
||||||
@ -507,8 +505,8 @@ def save_image(img, img_out_path):
|
|||||||
except:
|
except:
|
||||||
print('could not save the file', traceback.format_exc())
|
print('could not save the file', traceback.format_exc())
|
||||||
|
|
||||||
def save_metadata(meta_out_path, prompts, opt_seed, opt_W, opt_H, opt_ddim_steps, opt_scale, opt_prompt_strength, opt_correct_face, opt_upscale):
|
def save_metadata(meta_out_path, prompts, opt_seed, opt_W, opt_H, opt_ddim_steps, opt_scale, opt_prompt_strength, opt_correct_face, opt_upscale, sampler_name):
|
||||||
metadata = f"{prompts[0]}\nWidth: {opt_W}\nHeight: {opt_H}\nSeed: {opt_seed}\nSteps: {opt_ddim_steps}\nGuidance Scale: {opt_scale}\nPrompt Strength: {opt_prompt_strength}\nUse Face Correction: {opt_correct_face}\nUse Upscaling: {opt_upscale}"
|
metadata = f"{prompts[0]}\nWidth: {opt_W}\nHeight: {opt_H}\nSeed: {opt_seed}\nSteps: {opt_ddim_steps}\nGuidance Scale: {opt_scale}\nPrompt Strength: {opt_prompt_strength}\nUse Face Correction: {opt_correct_face}\nUse Upscaling: {opt_upscale}\nSampler: {sampler_name}"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(meta_out_path, 'w') as f:
|
with open(meta_out_path, 'w') as f:
|
||||||
@ -516,7 +514,7 @@ def save_metadata(meta_out_path, prompts, opt_seed, opt_W, opt_H, opt_ddim_steps
|
|||||||
except:
|
except:
|
||||||
print('could not save the file', traceback.format_exc())
|
print('could not save the file', traceback.format_exc())
|
||||||
|
|
||||||
def _txt2img(opt_W, opt_H, opt_n_samples, opt_ddim_steps, opt_scale, start_code, opt_C, opt_f, opt_ddim_eta, c, uc, opt_seed, img_callback, streaming_callbacks, mask):
|
def _txt2img(opt_W, opt_H, opt_n_samples, opt_ddim_steps, opt_scale, start_code, opt_C, opt_f, opt_ddim_eta, c, uc, opt_seed, img_callback, mask, sampler_name):
|
||||||
shape = [opt_n_samples, opt_C, opt_H // opt_f, opt_W // opt_f]
|
shape = [opt_n_samples, opt_C, opt_H // opt_f, opt_W // opt_f]
|
||||||
|
|
||||||
if device != "cpu":
|
if device != "cpu":
|
||||||
@ -536,17 +534,13 @@ def _txt2img(opt_W, opt_H, opt_n_samples, opt_ddim_steps, opt_scale, start_code,
|
|||||||
eta=opt_ddim_eta,
|
eta=opt_ddim_eta,
|
||||||
x_T=start_code,
|
x_T=start_code,
|
||||||
img_callback=img_callback,
|
img_callback=img_callback,
|
||||||
streaming_callbacks=streaming_callbacks,
|
|
||||||
mask=mask,
|
mask=mask,
|
||||||
sampler = 'plms',
|
sampler = sampler_name,
|
||||||
)
|
)
|
||||||
|
|
||||||
if streaming_callbacks:
|
yield from samples_ddim
|
||||||
yield from samples_ddim
|
|
||||||
else:
|
|
||||||
return samples_ddim
|
|
||||||
|
|
||||||
def _img2img(init_latent, t_enc, batch_size, opt_scale, c, uc, opt_ddim_steps, opt_ddim_eta, opt_seed, img_callback, streaming_callbacks, mask):
|
def _img2img(init_latent, t_enc, batch_size, opt_scale, c, uc, opt_ddim_steps, opt_ddim_eta, opt_seed, img_callback, mask):
|
||||||
# encode (scaled latent)
|
# encode (scaled latent)
|
||||||
z_enc = model.stochastic_encode(
|
z_enc = model.stochastic_encode(
|
||||||
init_latent,
|
init_latent,
|
||||||
@ -565,16 +559,12 @@ def _img2img(init_latent, t_enc, batch_size, opt_scale, c, uc, opt_ddim_steps, o
|
|||||||
unconditional_guidance_scale=opt_scale,
|
unconditional_guidance_scale=opt_scale,
|
||||||
unconditional_conditioning=uc,
|
unconditional_conditioning=uc,
|
||||||
img_callback=img_callback,
|
img_callback=img_callback,
|
||||||
streaming_callbacks=streaming_callbacks,
|
|
||||||
mask=mask,
|
mask=mask,
|
||||||
x_T=x_T,
|
x_T=x_T,
|
||||||
sampler = 'ddim'
|
sampler = 'ddim'
|
||||||
)
|
)
|
||||||
|
|
||||||
if streaming_callbacks:
|
yield from samples_ddim
|
||||||
yield from samples_ddim
|
|
||||||
else:
|
|
||||||
return samples_ddim
|
|
||||||
|
|
||||||
def move_fs_to_cpu():
|
def move_fs_to_cpu():
|
||||||
if device != "cpu":
|
if device != "cpu":
|
||||||
|
@ -57,6 +57,7 @@ class ImageRequest(BaseModel):
|
|||||||
height: int = 512
|
height: int = 512
|
||||||
seed: int = 42
|
seed: int = 42
|
||||||
prompt_strength: float = 0.8
|
prompt_strength: float = 0.8
|
||||||
|
sampler: str = None # "ddim", "plms", "heun", "euler", "euler_a", "dpm2", "dpm2_a", "lms"
|
||||||
# allow_nsfw: bool = False
|
# allow_nsfw: bool = False
|
||||||
save_to_disk_path: str = None
|
save_to_disk_path: str = None
|
||||||
turbo: bool = True
|
turbo: bool = True
|
||||||
@ -130,6 +131,7 @@ def image(req : ImageRequest):
|
|||||||
r.height = req.height
|
r.height = req.height
|
||||||
r.seed = req.seed
|
r.seed = req.seed
|
||||||
r.prompt_strength = req.prompt_strength
|
r.prompt_strength = req.prompt_strength
|
||||||
|
r.sampler = req.sampler
|
||||||
# r.allow_nsfw = req.allow_nsfw
|
# r.allow_nsfw = req.allow_nsfw
|
||||||
r.turbo = req.turbo
|
r.turbo = req.turbo
|
||||||
r.use_cpu = req.use_cpu
|
r.use_cpu = req.use_cpu
|
||||||
|
Loading…
Reference in New Issue
Block a user