Commit 8dcb8faf authored by AUTOMATIC1111's avatar AUTOMATIC1111 Committed by GitHub

Merge branch 'dev' into dora-weight-decompose

parents 199c51d6 bf35c661
...@@ -11,8 +11,8 @@ jobs: ...@@ -11,8 +11,8 @@ jobs:
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
steps: steps:
- name: Checkout Code - name: Checkout Code
uses: actions/checkout@v3 uses: actions/checkout@v4
- uses: actions/setup-python@v4 - uses: actions/setup-python@v5
with: with:
python-version: 3.11 python-version: 3.11
# NB: there's no cache: pip here since we're not installing anything # NB: there's no cache: pip here since we're not installing anything
...@@ -29,9 +29,9 @@ jobs: ...@@ -29,9 +29,9 @@ jobs:
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
steps: steps:
- name: Checkout Code - name: Checkout Code
uses: actions/checkout@v3 uses: actions/checkout@v4
- name: Install Node.js - name: Install Node.js
uses: actions/setup-node@v3 uses: actions/setup-node@v4
with: with:
node-version: 18 node-version: 18
- run: npm i --ci - run: npm i --ci
......
...@@ -11,9 +11,9 @@ jobs: ...@@ -11,9 +11,9 @@ jobs:
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
steps: steps:
- name: Checkout Code - name: Checkout Code
uses: actions/checkout@v3 uses: actions/checkout@v4
- name: Set up Python 3.10 - name: Set up Python 3.10
uses: actions/setup-python@v4 uses: actions/setup-python@v5
with: with:
python-version: 3.10.6 python-version: 3.10.6
cache: pip cache: pip
...@@ -22,7 +22,7 @@ jobs: ...@@ -22,7 +22,7 @@ jobs:
launch.py launch.py
- name: Cache models - name: Cache models
id: cache-models id: cache-models
uses: actions/cache@v3 uses: actions/cache@v4
with: with:
path: models path: models
key: "2023-12-30" key: "2023-12-30"
...@@ -68,13 +68,13 @@ jobs: ...@@ -68,13 +68,13 @@ jobs:
python -m coverage report -i python -m coverage report -i
python -m coverage html -i python -m coverage html -i
- name: Upload main app output - name: Upload main app output
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
if: always() if: always()
with: with:
name: output name: output
path: output.txt path: output.txt
- name: Upload coverage HTML - name: Upload coverage HTML
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
if: always() if: always()
with: with:
name: htmlcov name: htmlcov
......
...@@ -98,6 +98,7 @@ Make sure the required [dependencies](https://github.com/AUTOMATIC1111/stable-di ...@@ -98,6 +98,7 @@ Make sure the required [dependencies](https://github.com/AUTOMATIC1111/stable-di
- [NVidia](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Install-and-Run-on-NVidia-GPUs) (recommended) - [NVidia](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Install-and-Run-on-NVidia-GPUs) (recommended)
- [AMD](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Install-and-Run-on-AMD-GPUs) GPUs. - [AMD](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Install-and-Run-on-AMD-GPUs) GPUs.
- [Intel CPUs, Intel GPUs (both integrated and discrete)](https://github.com/openvinotoolkit/stable-diffusion-webui/wiki/Installation-on-Intel-Silicon) (external wiki page) - [Intel CPUs, Intel GPUs (both integrated and discrete)](https://github.com/openvinotoolkit/stable-diffusion-webui/wiki/Installation-on-Intel-Silicon) (external wiki page)
- [Ascend NPUs](https://github.com/wangshuai09/stable-diffusion-webui/wiki/Install-and-run-on-Ascend-NPUs) (external wiki page)
Alternatively, use online services (like Google Colab): Alternatively, use online services (like Google Colab):
......
...@@ -36,13 +36,6 @@ class NetworkModuleOFT(network.NetworkModule): ...@@ -36,13 +36,6 @@ class NetworkModuleOFT(network.NetworkModule):
# self.alpha is unused # self.alpha is unused
self.dim = self.oft_blocks.shape[1] # (num_blocks, block_size, block_size) self.dim = self.oft_blocks.shape[1] # (num_blocks, block_size, block_size)
# LyCORIS BOFT
if self.oft_blocks.dim() == 4:
self.is_boft = True
self.rescale = weights.w.get('rescale', None)
if self.rescale is not None:
self.rescale = self.rescale.reshape(-1, *[1]*(self.org_module[0].weight.dim() - 1))
is_linear = type(self.sd_module) in [torch.nn.Linear, torch.nn.modules.linear.NonDynamicallyQuantizableLinear] is_linear = type(self.sd_module) in [torch.nn.Linear, torch.nn.modules.linear.NonDynamicallyQuantizableLinear]
is_conv = type(self.sd_module) in [torch.nn.Conv2d] is_conv = type(self.sd_module) in [torch.nn.Conv2d]
is_other_linear = type(self.sd_module) in [torch.nn.MultiheadAttention] # unsupported is_other_linear = type(self.sd_module) in [torch.nn.MultiheadAttention] # unsupported
...@@ -54,6 +47,13 @@ class NetworkModuleOFT(network.NetworkModule): ...@@ -54,6 +47,13 @@ class NetworkModuleOFT(network.NetworkModule):
elif is_other_linear: elif is_other_linear:
self.out_dim = self.sd_module.embed_dim self.out_dim = self.sd_module.embed_dim
# LyCORIS BOFT
if self.oft_blocks.dim() == 4:
self.is_boft = True
self.rescale = weights.w.get('rescale', None)
if self.rescale is not None and not is_other_linear:
self.rescale = self.rescale.reshape(-1, *[1]*(self.org_module[0].weight.dim() - 1))
self.num_blocks = self.dim self.num_blocks = self.dim
self.block_size = self.out_dim // self.dim self.block_size = self.out_dim // self.dim
self.constraint = (0 if self.alpha is None else self.alpha) * self.out_dim self.constraint = (0 if self.alpha is None else self.alpha) * self.out_dim
......
...@@ -252,6 +252,7 @@ onUiLoaded(async() => { ...@@ -252,6 +252,7 @@ onUiLoaded(async() => {
let isMoving = false; let isMoving = false;
let mouseX, mouseY; let mouseX, mouseY;
let activeElement; let activeElement;
let interactedWithAltKey = false;
const elements = Object.fromEntries( const elements = Object.fromEntries(
Object.keys(elementIDs).map(id => [ Object.keys(elementIDs).map(id => [
...@@ -508,6 +509,10 @@ onUiLoaded(async() => { ...@@ -508,6 +509,10 @@ onUiLoaded(async() => {
if (isModifierKey(e, hotkeysConfig.canvas_hotkey_zoom)) { if (isModifierKey(e, hotkeysConfig.canvas_hotkey_zoom)) {
e.preventDefault(); e.preventDefault();
if(hotkeysConfig.canvas_hotkey_zoom === "Alt"){
interactedWithAltKey = true;
}
let zoomPosX, zoomPosY; let zoomPosX, zoomPosY;
let delta = 0.2; let delta = 0.2;
if (elemData[elemId].zoomLevel > 7) { if (elemData[elemId].zoomLevel > 7) {
...@@ -793,13 +798,17 @@ onUiLoaded(async() => { ...@@ -793,13 +798,17 @@ onUiLoaded(async() => {
targetElement.addEventListener("wheel", e => { targetElement.addEventListener("wheel", e => {
// change zoom level // change zoom level
const operation = e.deltaY > 0 ? "-" : "+"; const operation = (e.deltaY || -e.wheelDelta) > 0 ? "-" : "+";
changeZoomLevel(operation, e); changeZoomLevel(operation, e);
// Handle brush size adjustment with ctrl key pressed // Handle brush size adjustment with ctrl key pressed
if (isModifierKey(e, hotkeysConfig.canvas_hotkey_adjust)) { if (isModifierKey(e, hotkeysConfig.canvas_hotkey_adjust)) {
e.preventDefault(); e.preventDefault();
if(hotkeysConfig.canvas_hotkey_adjust === "Alt"){
interactedWithAltKey = true;
}
// Increase or decrease brush size based on scroll direction // Increase or decrease brush size based on scroll direction
adjustBrushSize(elemId, e.deltaY); adjustBrushSize(elemId, e.deltaY);
} }
...@@ -839,6 +848,20 @@ onUiLoaded(async() => { ...@@ -839,6 +848,20 @@ onUiLoaded(async() => {
document.addEventListener("keydown", handleMoveKeyDown); document.addEventListener("keydown", handleMoveKeyDown);
document.addEventListener("keyup", handleMoveKeyUp); document.addEventListener("keyup", handleMoveKeyUp);
// Prevent firefox from opening main menu when alt is used as a hotkey for zoom or brush size
function handleAltKeyUp(e) {
if (e.key !== "Alt" || !interactedWithAltKey) {
return;
}
e.preventDefault();
interactedWithAltKey = false;
}
document.addEventListener("keyup", handleAltKeyUp);
// Detect zoom level and update the pan speed. // Detect zoom level and update the pan speed.
function updatePanPosition(movementX, movementY) { function updatePanPosition(movementX, movementY) {
let panSpeed = 2; let panSpeed = 2;
......
<div class="extra-network-pane-content-dirs">
<div id='{tabname}_{extra_networks_tabname}_dirs' class='extra-network-dirs'>
{dirs_html}
</div>
<div id='{tabname}_{extra_networks_tabname}_cards' class='extra-network-cards'>
{items_html}
</div>
</div>
<div class="extra-network-pane-content-tree resize-handle-row">
<div id='{tabname}_{extra_networks_tabname}_tree' class='extra-network-tree' style='flex-basis: {extra_networks_tree_view_default_width}px'>
{tree_html}
</div>
<div id='{tabname}_{extra_networks_tabname}_cards' class='extra-network-cards' style='flex-grow: 1;'>
{items_html}
</div>
</div>
\ No newline at end of file
<div id='{tabname}_{extra_networks_tabname}_pane' class='extra-network-pane'> <div id='{tabname}_{extra_networks_tabname}_pane' class='extra-network-pane {tree_view_div_default_display_class}'>
<div class="extra-network-control" id="{tabname}_{extra_networks_tabname}_controls" style="display:none" > <div class="extra-network-control" id="{tabname}_{extra_networks_tabname}_controls" style="display:none" >
<div class="extra-network-control--search"> <div class="extra-network-control--search">
<input <input
id="{tabname}_{extra_networks_tabname}_extra_search" id="{tabname}_{extra_networks_tabname}_extra_search"
class="extra-network-control--search-text" class="extra-network-control--search-text"
type="search" type="search"
placeholder="Filter files" placeholder="Search"
> >
</div> </div>
<small>Sort: </small>
<div <div
id="{tabname}_{extra_networks_tabname}_extra_sort" id="{tabname}_{extra_networks_tabname}_extra_sort_path"
class="extra-network-control--sort" class="extra-network-control--sort{sort_path_active}"
data-sortmode="{data_sortmode}" data-sortkey="default"
data-sortkey="{data_sortkey}"
title="Sort by path" title="Sort by path"
onclick="extraNetworksControlSortOnClick(event, '{tabname}', '{extra_networks_tabname}');" onclick="extraNetworksControlSortOnClick(event, '{tabname}', '{extra_networks_tabname}');"
> >
<i class="extra-network-control--sort-icon"></i> <i class="extra-network-control--icon extra-network-control--sort-icon"></i>
</div> </div>
<div
id="{tabname}_{extra_networks_tabname}_extra_sort_name"
class="extra-network-control--sort{sort_name_active}"
data-sortkey="name"
title="Sort by name"
onclick="extraNetworksControlSortOnClick(event, '{tabname}', '{extra_networks_tabname}');"
>
<i class="extra-network-control--icon extra-network-control--sort-icon"></i>
</div>
<div
id="{tabname}_{extra_networks_tabname}_extra_sort_date_created"
class="extra-network-control--sort{sort_date_created_active}"
data-sortkey="date_created"
title="Sort by date created"
onclick="extraNetworksControlSortOnClick(event, '{tabname}', '{extra_networks_tabname}');"
>
<i class="extra-network-control--icon extra-network-control--sort-icon"></i>
</div>
<div
id="{tabname}_{extra_networks_tabname}_extra_sort_date_modified"
class="extra-network-control--sort{sort_date_modified_active}"
data-sortkey="date_modified"
title="Sort by date modified"
onclick="extraNetworksControlSortOnClick(event, '{tabname}', '{extra_networks_tabname}');"
>
<i class="extra-network-control--icon extra-network-control--sort-icon"></i>
</div>
<small> </small>
<div <div
id="{tabname}_{extra_networks_tabname}_extra_sort_dir" id="{tabname}_{extra_networks_tabname}_extra_sort_dir"
class="extra-network-control--sort-dir" class="extra-network-control--sort-dir"
...@@ -25,15 +55,18 @@ ...@@ -25,15 +55,18 @@
title="Sort ascending" title="Sort ascending"
onclick="extraNetworksControlSortDirOnClick(event, '{tabname}', '{extra_networks_tabname}');" onclick="extraNetworksControlSortDirOnClick(event, '{tabname}', '{extra_networks_tabname}');"
> >
<i class="extra-network-control--sort-dir-icon"></i> <i class="extra-network-control--icon extra-network-control--sort-dir-icon"></i>
</div> </div>
<small> </small>
<div <div
id="{tabname}_{extra_networks_tabname}_extra_tree_view" id="{tabname}_{extra_networks_tabname}_extra_tree_view"
class="extra-network-control--tree-view {tree_view_btn_extra_class}" class="extra-network-control--tree-view {tree_view_btn_extra_class}"
title="Enable Tree View" title="Enable Tree View"
onclick="extraNetworksControlTreeViewOnClick(event, '{tabname}', '{extra_networks_tabname}');" onclick="extraNetworksControlTreeViewOnClick(event, '{tabname}', '{extra_networks_tabname}');"
> >
<i class="extra-network-control--tree-view-icon"></i> <i class="extra-network-control--icon extra-network-control--tree-view-icon"></i>
</div> </div>
<div <div
id="{tabname}_{extra_networks_tabname}_extra_refresh" id="{tabname}_{extra_networks_tabname}_extra_refresh"
...@@ -41,15 +74,8 @@ ...@@ -41,15 +74,8 @@
title="Refresh page" title="Refresh page"
onclick="extraNetworksControlRefreshOnClick(event, '{tabname}', '{extra_networks_tabname}');" onclick="extraNetworksControlRefreshOnClick(event, '{tabname}', '{extra_networks_tabname}');"
> >
<i class="extra-network-control--refresh-icon"></i> <i class="extra-network-control--icon extra-network-control--refresh-icon"></i>
</div>
</div>
<div class="extra-network-pane-content resize-handle-row" style="display: {extra_network_pane_content_default_display};">
<div id='{tabname}_{extra_networks_tabname}_tree' class='extra-network-tree {tree_view_div_extra_class}' style='flex-basis: {extra_networks_tree_view_default_width}px; display: {tree_view_div_default_display};'>
{tree_html}
</div>
<div id='{tabname}_{extra_networks_tabname}_cards' class='extra-network-cards' style='flex-grow: 1;'>
{items_html}
</div> </div>
</div> </div>
{pane_content}
</div> </div>
...@@ -64,6 +64,14 @@ function keyupEditAttention(event) { ...@@ -64,6 +64,14 @@ function keyupEditAttention(event) {
selectionEnd++; selectionEnd++;
} }
// deselect surrounding whitespace
while (text[selectionStart] == " " && selectionStart < selectionEnd) {
selectionStart++;
}
while (text[selectionEnd - 1] == " " && selectionEnd > selectionStart) {
selectionEnd--;
}
target.setSelectionRange(selectionStart, selectionEnd); target.setSelectionRange(selectionStart, selectionEnd);
return true; return true;
} }
......
...@@ -39,12 +39,12 @@ function setupExtraNetworksForTab(tabname) { ...@@ -39,12 +39,12 @@ function setupExtraNetworksForTab(tabname) {
// tabname_full = {tabname}_{extra_networks_tabname} // tabname_full = {tabname}_{extra_networks_tabname}
var tabname_full = elem.id; var tabname_full = elem.id;
var search = gradioApp().querySelector("#" + tabname_full + "_extra_search"); var search = gradioApp().querySelector("#" + tabname_full + "_extra_search");
var sort_mode = gradioApp().querySelector("#" + tabname_full + "_extra_sort");
var sort_dir = gradioApp().querySelector("#" + tabname_full + "_extra_sort_dir"); var sort_dir = gradioApp().querySelector("#" + tabname_full + "_extra_sort_dir");
var refresh = gradioApp().querySelector("#" + tabname_full + "_extra_refresh"); var refresh = gradioApp().querySelector("#" + tabname_full + "_extra_refresh");
var currentSort = '';
// If any of the buttons above don't exist, we want to skip this iteration of the loop. // If any of the buttons above don't exist, we want to skip this iteration of the loop.
if (!search || !sort_mode || !sort_dir || !refresh) { if (!search || !sort_dir || !refresh) {
return; // `return` is equivalent of `continue` but for forEach loops. return; // `return` is equivalent of `continue` but for forEach loops.
} }
...@@ -52,7 +52,7 @@ function setupExtraNetworksForTab(tabname) { ...@@ -52,7 +52,7 @@ function setupExtraNetworksForTab(tabname) {
var searchTerm = search.value.toLowerCase(); var searchTerm = search.value.toLowerCase();
gradioApp().querySelectorAll('#' + tabname + '_extra_tabs div.card').forEach(function(elem) { gradioApp().querySelectorAll('#' + tabname + '_extra_tabs div.card').forEach(function(elem) {
var searchOnly = elem.querySelector('.search_only'); var searchOnly = elem.querySelector('.search_only');
var text = Array.prototype.map.call(elem.querySelectorAll('.search_terms'), function(t) { var text = Array.prototype.map.call(elem.querySelectorAll('.search_terms, .description'), function(t) {
return t.textContent.toLowerCase(); return t.textContent.toLowerCase();
}).join(" "); }).join(" ");
...@@ -71,42 +71,46 @@ function setupExtraNetworksForTab(tabname) { ...@@ -71,42 +71,46 @@ function setupExtraNetworksForTab(tabname) {
}; };
var applySort = function(force) { var applySort = function(force) {
var cards = gradioApp().querySelectorAll('#' + tabname + '_extra_tabs div.card'); var cards = gradioApp().querySelectorAll('#' + tabname_full + ' div.card');
var parent = gradioApp().querySelector('#' + tabname_full + "_cards");
var reverse = sort_dir.dataset.sortdir == "Descending"; var reverse = sort_dir.dataset.sortdir == "Descending";
var sortKey = sort_mode.dataset.sortmode.toLowerCase().replace("sort", "").replaceAll(" ", "_").replace(/_+$/, "").trim() || "name"; var activeSearchElem = gradioApp().querySelector('#' + tabname_full + "_controls .extra-network-control--sort.extra-network-control--enabled");
sortKey = "sort" + sortKey.charAt(0).toUpperCase() + sortKey.slice(1); var sortKey = activeSearchElem ? activeSearchElem.dataset.sortkey : "default";
var sortKeyStore = sortKey + "-" + (reverse ? "Descending" : "Ascending") + "-" + cards.length; var sortKeyDataField = "sort" + sortKey.charAt(0).toUpperCase() + sortKey.slice(1);
var sortKeyStore = sortKey + "-" + sort_dir.dataset.sortdir + "-" + cards.length;
if (sortKeyStore == sort_mode.dataset.sortkey && !force) { if (sortKeyStore == currentSort && !force) {
return; return;
} }
sort_mode.dataset.sortkey = sortKeyStore; currentSort = sortKeyStore;
cards.forEach(function(card) {
card.originalParentElement = card.parentElement;
});
var sortedCards = Array.from(cards); var sortedCards = Array.from(cards);
sortedCards.sort(function(cardA, cardB) { sortedCards.sort(function(cardA, cardB) {
var a = cardA.dataset[sortKey]; var a = cardA.dataset[sortKeyDataField];
var b = cardB.dataset[sortKey]; var b = cardB.dataset[sortKeyDataField];
if (!isNaN(a) && !isNaN(b)) { if (!isNaN(a) && !isNaN(b)) {
return parseInt(a) - parseInt(b); return parseInt(a) - parseInt(b);
} }
return (a < b ? -1 : (a > b ? 1 : 0)); return (a < b ? -1 : (a > b ? 1 : 0));
}); });
if (reverse) { if (reverse) {
sortedCards.reverse(); sortedCards.reverse();
} }
cards.forEach(function(card) {
card.remove(); parent.innerHTML = '';
});
var frag = document.createDocumentFragment();
sortedCards.forEach(function(card) { sortedCards.forEach(function(card) {
card.originalParentElement.appendChild(card); frag.appendChild(card);
}); });
parent.appendChild(frag);
}; };
search.addEventListener("input", applyFilter); search.addEventListener("input", function() {
applyFilter();
});
applySort(); applySort();
applyFilter(); applyFilter();
extraNetworksApplySort[tabname_full] = applySort; extraNetworksApplySort[tabname_full] = applySort;
...@@ -272,6 +276,15 @@ function saveCardPreview(event, tabname, filename) { ...@@ -272,6 +276,15 @@ function saveCardPreview(event, tabname, filename) {
event.preventDefault(); event.preventDefault();
} }
function extraNetworksSearchButton(tabname, extra_networks_tabname, event) {
var searchTextarea = gradioApp().querySelector("#" + tabname + "_" + extra_networks_tabname + "_extra_search");
var button = event.target;
var text = button.classList.contains("search-all") ? "" : button.textContent.trim();
searchTextarea.value = text;
updateInput(searchTextarea);
}
function extraNetworksTreeProcessFileClick(event, btn, tabname, extra_networks_tabname) { function extraNetworksTreeProcessFileClick(event, btn, tabname, extra_networks_tabname) {
/** /**
* Processes `onclick` events when user clicks on files in tree. * Processes `onclick` events when user clicks on files in tree.
...@@ -383,36 +396,17 @@ function extraNetworksTreeOnClick(event, tabname, extra_networks_tabname) { ...@@ -383,36 +396,17 @@ function extraNetworksTreeOnClick(event, tabname, extra_networks_tabname) {
} }
function extraNetworksControlSortOnClick(event, tabname, extra_networks_tabname) { function extraNetworksControlSortOnClick(event, tabname, extra_networks_tabname) {
/** /** Handles `onclick` events for Sort Mode buttons. */
* Handles `onclick` events for the Sort Mode button.
* var self = event.currentTarget;
* Modifies the data attributes of the Sort Mode button to cycle between var parent = event.currentTarget.parentElement;
* various sorting modes.
* parent.querySelectorAll('.extra-network-control--sort').forEach(function(x) {
* @param event The generated event. x.classList.remove('extra-network-control--enabled');
* @param tabname The name of the active tab in the sd webui. Ex: txt2img, img2img, etc. });
* @param extra_networks_tabname The id of the active extraNetworks tab. Ex: lora, checkpoints, etc.
*/ self.classList.add('extra-network-control--enabled');
var curr_mode = event.currentTarget.dataset.sortmode;
var el_sort_dir = gradioApp().querySelector("#" + tabname + "_" + extra_networks_tabname + "_extra_sort_dir");
var sort_dir = el_sort_dir.dataset.sortdir;
if (curr_mode == "path") {
event.currentTarget.dataset.sortmode = "name";
event.currentTarget.dataset.sortkey = "sortName-" + sort_dir + "-640";
event.currentTarget.setAttribute("title", "Sort by filename");
} else if (curr_mode == "name") {
event.currentTarget.dataset.sortmode = "date_created";
event.currentTarget.dataset.sortkey = "sortDate_created-" + sort_dir + "-640";
event.currentTarget.setAttribute("title", "Sort by date created");
} else if (curr_mode == "date_created") {
event.currentTarget.dataset.sortmode = "date_modified";
event.currentTarget.dataset.sortkey = "sortDate_modified-" + sort_dir + "-640";
event.currentTarget.setAttribute("title", "Sort by date modified");
} else {
event.currentTarget.dataset.sortmode = "path";
event.currentTarget.dataset.sortkey = "sortPath-" + sort_dir + "-640";
event.currentTarget.setAttribute("title", "Sort by path");
}
applyExtraNetworkSort(tabname + "_" + extra_networks_tabname); applyExtraNetworkSort(tabname + "_" + extra_networks_tabname);
} }
...@@ -447,27 +441,12 @@ function extraNetworksControlTreeViewOnClick(event, tabname, extra_networks_tabn ...@@ -447,27 +441,12 @@ function extraNetworksControlTreeViewOnClick(event, tabname, extra_networks_tabn
* @param tabname The name of the active tab in the sd webui. Ex: txt2img, img2img, etc. * @param tabname The name of the active tab in the sd webui. Ex: txt2img, img2img, etc.
* @param extra_networks_tabname The id of the active extraNetworks tab. Ex: lora, checkpoints, etc. * @param extra_networks_tabname The id of the active extraNetworks tab. Ex: lora, checkpoints, etc.
*/ */
const tree = gradioApp().getElementById(tabname + "_" + extra_networks_tabname + "_tree"); var button = event.currentTarget;
const parent = tree.parentElement; button.classList.toggle("extra-network-control--enabled");
let resizeHandle = parent.querySelector('.resize-handle'); var show = !button.classList.contains("extra-network-control--enabled");
tree.classList.toggle("hidden");
if (tree.classList.contains("hidden")) { var pane = gradioApp().getElementById(tabname + "_" + extra_networks_tabname + "_pane");
tree.style.display = 'none'; pane.classList.toggle("extra-network-dirs-hidden", show);
parent.style.display = 'flex';
if (resizeHandle) {
resizeHandle.style.display = 'none';
}
} else {
tree.style.display = 'block';
parent.style.display = 'grid';
if (!resizeHandle) {
setupResizeHandle(parent);
resizeHandle = parent.querySelector('.resize-handle');
}
resizeHandle.style.display = 'block';
}
event.currentTarget.classList.toggle("extra-network-control--enabled");
} }
function extraNetworksControlRefreshOnClick(event, tabname, extra_networks_tabname) { function extraNetworksControlRefreshOnClick(event, tabname, extra_networks_tabname) {
......
...@@ -131,19 +131,15 @@ function setupImageForLightbox(e) { ...@@ -131,19 +131,15 @@ function setupImageForLightbox(e) {
e.style.cursor = 'pointer'; e.style.cursor = 'pointer';
e.style.userSelect = 'none'; e.style.userSelect = 'none';
var isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1; e.addEventListener('mousedown', function(evt) {
// For Firefox, listening on click first switched to next image then shows the lightbox.
// If you know how to fix this without switching to mousedown event, please.
// For other browsers the event is click to make it possiblr to drag picture.
var event = isFirefox ? 'mousedown' : 'click';
e.addEventListener(event, function(evt) {
if (evt.button == 1) { if (evt.button == 1) {
open(evt.target.src); open(evt.target.src);
evt.preventDefault(); evt.preventDefault();
return; return;
} }
}, true);
e.addEventListener('click', function(evt) {
if (!opts.js_modal_lightbox || evt.button != 0) return; if (!opts.js_modal_lightbox || evt.button != 0) return;
modalZoomSet(gradioApp().getElementById('modalImage'), opts.js_modal_lightbox_initially_zoomed); modalZoomSet(gradioApp().getElementById('modalImage'), opts.js_modal_lightbox_initially_zoomed);
......
...@@ -79,6 +79,11 @@ ...@@ -79,6 +79,11 @@
parent.minRightColWidth = 0; parent.minRightColWidth = 0;
parent.needHideOnMoblie = false; parent.needHideOnMoblie = false;
} }
if (!leftColTemplate) {
leftColTemplate = '1fr';
}
const gridTemplateColumns = `${leftColTemplate} ${PAD}px ${parent.children[1].style.flexGrow}fr`; const gridTemplateColumns = `${leftColTemplate} ${PAD}px ${parent.children[1].style.flexGrow}fr`;
parent.style.gridTemplateColumns = gridTemplateColumns; parent.style.gridTemplateColumns = gridTemplateColumns;
parent.style.originalGridTemplateColumns = gridTemplateColumns; parent.style.originalGridTemplateColumns = gridTemplateColumns;
......
...@@ -136,8 +136,7 @@ function showSubmitInterruptingPlaceholder(tabname) { ...@@ -136,8 +136,7 @@ function showSubmitInterruptingPlaceholder(tabname) {
function showRestoreProgressButton(tabname, show) { function showRestoreProgressButton(tabname, show) {
var button = gradioApp().getElementById(tabname + "_restore_progress"); var button = gradioApp().getElementById(tabname + "_restore_progress");
if (!button) return; if (!button) return;
button.style.setProperty('display', show ? 'flex' : 'none', 'important');
button.style.display = show ? "flex" : "none";
} }
function submit() { function submit() {
...@@ -209,6 +208,7 @@ function restoreProgressTxt2img() { ...@@ -209,6 +208,7 @@ function restoreProgressTxt2img() {
var id = localGet("txt2img_task_id"); var id = localGet("txt2img_task_id");
if (id) { if (id) {
showSubmitInterruptingPlaceholder('txt2img');
requestProgress(id, gradioApp().getElementById('txt2img_gallery_container'), gradioApp().getElementById('txt2img_gallery'), function() { requestProgress(id, gradioApp().getElementById('txt2img_gallery_container'), gradioApp().getElementById('txt2img_gallery'), function() {
showSubmitButtons('txt2img', true); showSubmitButtons('txt2img', true);
}, null, 0); }, null, 0);
...@@ -223,6 +223,7 @@ function restoreProgressImg2img() { ...@@ -223,6 +223,7 @@ function restoreProgressImg2img() {
var id = localGet("img2img_task_id"); var id = localGet("img2img_task_id");
if (id) { if (id) {
showSubmitInterruptingPlaceholder('img2img');
requestProgress(id, gradioApp().getElementById('img2img_gallery_container'), gradioApp().getElementById('img2img_gallery'), function() { requestProgress(id, gradioApp().getElementById('img2img_gallery_container'), gradioApp().getElementById('img2img_gallery'), function() {
showSubmitButtons('img2img', true); showSubmitButtons('img2img', true);
}, null, 0); }, null, 0);
......
...@@ -124,3 +124,4 @@ parser.add_argument("--disable-extra-extensions", action='store_true', help="pre ...@@ -124,3 +124,4 @@ parser.add_argument("--disable-extra-extensions", action='store_true', help="pre
parser.add_argument("--skip-load-model-at-start", action='store_true', help="if load a model at web start, only take effect when --nowebui") parser.add_argument("--skip-load-model-at-start", action='store_true', help="if load a model at web start, only take effect when --nowebui")
parser.add_argument("--unix-filenames-sanitization", action='store_true', help="allow any symbols except '/' in filenames. May conflict with your browser and file system") parser.add_argument("--unix-filenames-sanitization", action='store_true', help="allow any symbols except '/' in filenames. May conflict with your browser and file system")
parser.add_argument("--filenames-max-length", type=int, default=128, help='maximal length of filenames of saved images. If you override it, it can conflict with your file system') parser.add_argument("--filenames-max-length", type=int, default=128, help='maximal length of filenames of saved images. If you override it, it can conflict with your file system')
parser.add_argument("--no-prompt-history", action='store_true', help="disable read prompt from last generation feature; settings this argument will not create '--data_path/params.txt' file")
from __future__ import annotations from __future__ import annotations
import configparser import configparser
import dataclasses
import os import os
import threading import threading
import re import re
...@@ -22,6 +23,13 @@ def active(): ...@@ -22,6 +23,13 @@ def active():
return [x for x in extensions if x.enabled] return [x for x in extensions if x.enabled]
@dataclasses.dataclass
class CallbackOrderInfo:
name: str
before: list
after: list
class ExtensionMetadata: class ExtensionMetadata:
filename = "metadata.ini" filename = "metadata.ini"
config: configparser.ConfigParser config: configparser.ConfigParser
...@@ -65,6 +73,22 @@ class ExtensionMetadata: ...@@ -65,6 +73,22 @@ class ExtensionMetadata:
# both "," and " " are accepted as separator # both "," and " " are accepted as separator
return [x for x in re.split(r"[,\s]+", text.strip()) if x] return [x for x in re.split(r"[,\s]+", text.strip()) if x]
def list_callback_order_instructions(self):
for section in self.config.sections():
if not section.startswith("callbacks/"):
continue
callback_name = section[10:]
if not callback_name.startswith(self.canonical_name):
errors.report(f"Callback order section for extension {self.canonical_name} is referencing the wrong extension: {section}")
continue
before = self.parse_list(self.config.get(section, 'Before', fallback=''))
after = self.parse_list(self.config.get(section, 'After', fallback=''))
yield CallbackOrderInfo(callback_name, before, after)
class Extension: class Extension:
lock = threading.Lock() lock = threading.Lock()
...@@ -156,6 +180,8 @@ class Extension: ...@@ -156,6 +180,8 @@ class Extension:
def check_updates(self): def check_updates(self):
repo = Repo(self.path) repo = Repo(self.path)
for fetch in repo.remote().fetch(dry_run=True): for fetch in repo.remote().fetch(dry_run=True):
if self.branch and fetch.name != f'{repo.remote().name}/{self.branch}':
continue
if fetch.flags != fetch.HEAD_UPTODATE: if fetch.flags != fetch.HEAD_UPTODATE:
self.can_update = True self.can_update = True
self.status = "new commits" self.status = "new commits"
...@@ -186,6 +212,7 @@ class Extension: ...@@ -186,6 +212,7 @@ class Extension:
def list_extensions(): def list_extensions():
extensions.clear() extensions.clear()
extension_paths.clear()
if shared.cmd_opts.disable_all_extensions: if shared.cmd_opts.disable_all_extensions:
print("*** \"--disable-all-extensions\" arg was used, will not load any extensions ***") print("*** \"--disable-all-extensions\" arg was used, will not load any extensions ***")
...@@ -220,6 +247,7 @@ def list_extensions(): ...@@ -220,6 +247,7 @@ def list_extensions():
is_builtin = dirname == extensions_builtin_dir is_builtin = dirname == extensions_builtin_dir
extension = Extension(name=extension_dirname, path=path, enabled=extension_dirname not in shared.opts.disabled_extensions, is_builtin=is_builtin, metadata=metadata) extension = Extension(name=extension_dirname, path=path, enabled=extension_dirname not in shared.opts.disabled_extensions, is_builtin=is_builtin, metadata=metadata)
extensions.append(extension) extensions.append(extension)
extension_paths[extension.path] = extension
loaded_extensions[canonical_name] = extension loaded_extensions[canonical_name] = extension
# check for requirements # check for requirements
...@@ -238,4 +266,19 @@ def list_extensions(): ...@@ -238,4 +266,19 @@ def list_extensions():
continue continue
def find_extension(filename):
parentdir = os.path.dirname(os.path.realpath(filename))
while parentdir != filename:
extension = extension_paths.get(parentdir)
if extension is not None:
return extension
filename = parentdir
parentdir = os.path.dirname(filename)
return None
extensions: list[Extension] = [] extensions: list[Extension] = []
extension_paths: dict[str, Extension] = {}
...@@ -265,17 +265,6 @@ Steps: 20, Sampler: Euler a, CFG scale: 7, Seed: 965400086, Size: 512x512, Model ...@@ -265,17 +265,6 @@ Steps: 20, Sampler: Euler a, CFG scale: 7, Seed: 965400086, Size: 512x512, Model
else: else:
prompt += ("" if prompt == "" else "\n") + line prompt += ("" if prompt == "" else "\n") + line
if shared.opts.infotext_styles != "Ignore":
found_styles, prompt, negative_prompt = shared.prompt_styles.extract_styles_from_prompt(prompt, negative_prompt)
if shared.opts.infotext_styles == "Apply":
res["Styles array"] = found_styles
elif shared.opts.infotext_styles == "Apply if any" and found_styles:
res["Styles array"] = found_styles
res["Prompt"] = prompt
res["Negative prompt"] = negative_prompt
for k, v in re_param.findall(lastline): for k, v in re_param.findall(lastline):
try: try:
if v[0] == '"' and v[-1] == '"': if v[0] == '"' and v[-1] == '"':
...@@ -290,6 +279,26 @@ Steps: 20, Sampler: Euler a, CFG scale: 7, Seed: 965400086, Size: 512x512, Model ...@@ -290,6 +279,26 @@ Steps: 20, Sampler: Euler a, CFG scale: 7, Seed: 965400086, Size: 512x512, Model
except Exception: except Exception:
print(f"Error parsing \"{k}: {v}\"") print(f"Error parsing \"{k}: {v}\"")
# Extract styles from prompt
if shared.opts.infotext_styles != "Ignore":
found_styles, prompt_no_styles, negative_prompt_no_styles = shared.prompt_styles.extract_styles_from_prompt(prompt, negative_prompt)
same_hr_styles = True
if ("Hires prompt" in res or "Hires negative prompt" in res) and (infotext_ver > infotext_versions.v180_hr_styles if (infotext_ver := infotext_versions.parse_version(res.get("Version"))) else True):
hr_prompt, hr_negative_prompt = res.get("Hires prompt", prompt), res.get("Hires negative prompt", negative_prompt)
hr_found_styles, hr_prompt_no_styles, hr_negative_prompt_no_styles = shared.prompt_styles.extract_styles_from_prompt(hr_prompt, hr_negative_prompt)
if same_hr_styles := found_styles == hr_found_styles:
res["Hires prompt"] = '' if hr_prompt_no_styles == prompt_no_styles else hr_prompt_no_styles
res['Hires negative prompt'] = '' if hr_negative_prompt_no_styles == negative_prompt_no_styles else hr_negative_prompt_no_styles
if same_hr_styles:
prompt, negative_prompt = prompt_no_styles, negative_prompt_no_styles
if (shared.opts.infotext_styles == "Apply if any" and found_styles) or shared.opts.infotext_styles == "Apply":
res['Styles array'] = found_styles
res["Prompt"] = prompt
res["Negative prompt"] = negative_prompt
# Missing CLIP skip means it was set to 1 (the default) # Missing CLIP skip means it was set to 1 (the default)
if "Clip skip" not in res: if "Clip skip" not in res:
res["Clip skip"] = "1" res["Clip skip"] = "1"
...@@ -462,7 +471,7 @@ def get_override_settings(params, *, skip_fields=None): ...@@ -462,7 +471,7 @@ def get_override_settings(params, *, skip_fields=None):
def connect_paste(button, paste_fields, input_comp, override_settings_component, tabname): def connect_paste(button, paste_fields, input_comp, override_settings_component, tabname):
def paste_func(prompt): def paste_func(prompt):
if not prompt and not shared.cmd_opts.hide_ui_dir_config: if not prompt and not shared.cmd_opts.hide_ui_dir_config and not shared.cmd_opts.no_prompt_history:
filename = os.path.join(data_path, "params.txt") filename = os.path.join(data_path, "params.txt")
try: try:
with open(filename, "r", encoding="utf8") as file: with open(filename, "r", encoding="utf8") as file:
......
...@@ -6,6 +6,7 @@ import re ...@@ -6,6 +6,7 @@ import re
v160 = version.parse("1.6.0") v160 = version.parse("1.6.0")
v170_tsnr = version.parse("v1.7.0-225") v170_tsnr = version.parse("v1.7.0-225")
v180 = version.parse("1.8.0") v180 = version.parse("1.8.0")
v180_hr_styles = version.parse("1.8.0-139")
def parse_version(text): def parse_version(text):
......
...@@ -240,6 +240,9 @@ class Options: ...@@ -240,6 +240,9 @@ class Options:
item_categories = {} item_categories = {}
for item in self.data_labels.values(): for item in self.data_labels.values():
if item.section[0] is None:
continue
category = categories.mapping.get(item.category_id) category = categories.mapping.get(item.category_id)
category = "Uncategorized" if category is None else category.label category = "Uncategorized" if category is None else category.label
if category not in item_categories: if category not in item_categories:
......
...@@ -702,7 +702,7 @@ def program_version(): ...@@ -702,7 +702,7 @@ def program_version():
return res return res
def create_infotext(p, all_prompts, all_seeds, all_subseeds, comments=None, iteration=0, position_in_batch=0, use_main_prompt=False, index=None, all_negative_prompts=None): def create_infotext(p, all_prompts, all_seeds, all_subseeds, comments=None, iteration=0, position_in_batch=0, use_main_prompt=False, index=None, all_negative_prompts=None, all_hr_prompts=None, all_hr_negative_prompts=None):
if index is None: if index is None:
index = position_in_batch + iteration * p.batch_size index = position_in_batch + iteration * p.batch_size
...@@ -745,11 +745,18 @@ def create_infotext(p, all_prompts, all_seeds, all_subseeds, comments=None, iter ...@@ -745,11 +745,18 @@ def create_infotext(p, all_prompts, all_seeds, all_subseeds, comments=None, iter
"RNG": opts.randn_source if opts.randn_source != "GPU" else None, "RNG": opts.randn_source if opts.randn_source != "GPU" else None,
"NGMS": None if p.s_min_uncond == 0 else p.s_min_uncond, "NGMS": None if p.s_min_uncond == 0 else p.s_min_uncond,
"Tiling": "True" if p.tiling else None, "Tiling": "True" if p.tiling else None,
"Hires prompt": None, # This is set later, insert here to keep order
"Hires negative prompt": None, # This is set later, insert here to keep order
**p.extra_generation_params, **p.extra_generation_params,
"Version": program_version() if opts.add_version_to_infotext else None, "Version": program_version() if opts.add_version_to_infotext else None,
"User": p.user if opts.add_user_name_to_info else None, "User": p.user if opts.add_user_name_to_info else None,
} }
if all_hr_prompts := all_hr_prompts or getattr(p, 'all_hr_prompts', None):
generation_params['Hires prompt'] = all_hr_prompts[index] if all_hr_prompts[index] != all_prompts[index] else None
if all_hr_negative_prompts := all_hr_negative_prompts or getattr(p, 'all_hr_negative_prompts', None):
generation_params['Hires negative prompt'] = all_hr_negative_prompts[index] if all_hr_negative_prompts[index] != all_negative_prompts[index] else None
generation_params_text = ", ".join([k if k == v else f'{k}: {infotext_utils.quote(v)}' for k, v in generation_params.items() if v is not None]) generation_params_text = ", ".join([k if k == v else f'{k}: {infotext_utils.quote(v)}' for k, v in generation_params.items() if v is not None])
prompt_text = p.main_prompt if use_main_prompt else all_prompts[index] prompt_text = p.main_prompt if use_main_prompt else all_prompts[index]
...@@ -904,7 +911,7 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed: ...@@ -904,7 +911,7 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
# infotext could be modified by that callback # infotext could be modified by that callback
# Example: a wildcard processed by process_batch sets an extra model # Example: a wildcard processed by process_batch sets an extra model
# strength, which is saved as "Model Strength: 1.0" in the infotext # strength, which is saved as "Model Strength: 1.0" in the infotext
if n == 0: if n == 0 and not cmd_opts.no_prompt_history:
with open(os.path.join(paths.data_path, "params.txt"), "w", encoding="utf8") as file: with open(os.path.join(paths.data_path, "params.txt"), "w", encoding="utf8") as file:
processed = Processed(p, []) processed = Processed(p, [])
file.write(processed.infotext(p, 0)) file.write(processed.infotext(p, 0))
...@@ -1194,12 +1201,6 @@ class StableDiffusionProcessingTxt2Img(StableDiffusionProcessing): ...@@ -1194,12 +1201,6 @@ class StableDiffusionProcessingTxt2Img(StableDiffusionProcessing):
if self.hr_sampler_name is not None and self.hr_sampler_name != self.sampler_name: if self.hr_sampler_name is not None and self.hr_sampler_name != self.sampler_name:
self.extra_generation_params["Hires sampler"] = self.hr_sampler_name self.extra_generation_params["Hires sampler"] = self.hr_sampler_name
if tuple(self.hr_prompt) != tuple(self.prompt):
self.extra_generation_params["Hires prompt"] = self.hr_prompt
if tuple(self.hr_negative_prompt) != tuple(self.negative_prompt):
self.extra_generation_params["Hires negative prompt"] = self.hr_negative_prompt
self.latent_scale_mode = shared.latent_upscale_modes.get(self.hr_upscaler, None) if self.hr_upscaler is not None else shared.latent_upscale_modes.get(shared.latent_upscale_default_mode, "nearest") self.latent_scale_mode = shared.latent_upscale_modes.get(self.hr_upscaler, None) if self.hr_upscaler is not None else shared.latent_upscale_modes.get(shared.latent_upscale_default_mode, "nearest")
if self.enable_hr and self.latent_scale_mode is None: if self.enable_hr and self.latent_scale_mode is None:
if not any(x.name == self.hr_upscaler for x in shared.sd_upscalers): if not any(x.name == self.hr_upscaler for x in shared.sd_upscalers):
......
...@@ -26,6 +26,13 @@ class ScriptStripComments(scripts.Script): ...@@ -26,6 +26,13 @@ class ScriptStripComments(scripts.Script):
p.main_prompt = strip_comments(p.main_prompt) p.main_prompt = strip_comments(p.main_prompt)
p.main_negative_prompt = strip_comments(p.main_negative_prompt) p.main_negative_prompt = strip_comments(p.main_negative_prompt)
if getattr(p, 'enable_hr', False):
p.all_hr_prompts = [strip_comments(x) for x in p.all_hr_prompts]
p.all_hr_negative_prompts = [strip_comments(x) for x in p.all_hr_negative_prompts]
p.hr_prompt = strip_comments(p.hr_prompt)
p.hr_negative_prompt = strip_comments(p.hr_negative_prompt)
def before_token_counter(params: script_callbacks.BeforeTokenCounterParams): def before_token_counter(params: script_callbacks.BeforeTokenCounterParams):
if not shared.opts.enable_prompt_comments: if not shared.opts.enable_prompt_comments:
......
This diff is collapsed.
This diff is collapsed.
...@@ -13,8 +13,8 @@ def get_learned_conditioning(self: sgm.models.diffusion.DiffusionEngine, batch: ...@@ -13,8 +13,8 @@ def get_learned_conditioning(self: sgm.models.diffusion.DiffusionEngine, batch:
for embedder in self.conditioner.embedders: for embedder in self.conditioner.embedders:
embedder.ucg_rate = 0.0 embedder.ucg_rate = 0.0
width = getattr(batch, 'width', 1024) width = getattr(batch, 'width', 1024) or 1024
height = getattr(batch, 'height', 1024) height = getattr(batch, 'height', 1024) or 1024
is_negative_prompt = getattr(batch, 'is_negative_prompt', False) is_negative_prompt = getattr(batch, 'is_negative_prompt', False)
aesthetic_score = shared.opts.sdxl_refiner_low_aesthetic_score if is_negative_prompt else shared.opts.sdxl_refiner_high_aesthetic_score aesthetic_score = shared.opts.sdxl_refiner_low_aesthetic_score if is_negative_prompt else shared.opts.sdxl_refiner_high_aesthetic_score
......
...@@ -6,6 +6,10 @@ import gradio as gr ...@@ -6,6 +6,10 @@ import gradio as gr
from modules import shared_cmd_options, shared_gradio_themes, options, shared_items, sd_models_types from modules import shared_cmd_options, shared_gradio_themes, options, shared_items, sd_models_types
from modules.paths_internal import models_path, script_path, data_path, sd_configs_path, sd_default_config, sd_model_file, default_sd_model_file, extensions_dir, extensions_builtin_dir # noqa: F401 from modules.paths_internal import models_path, script_path, data_path, sd_configs_path, sd_default_config, sd_model_file, default_sd_model_file, extensions_dir, extensions_builtin_dir # noqa: F401
from modules import util from modules import util
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from modules import shared_state, styles, interrogate, shared_total_tqdm, memmon
cmd_opts = shared_cmd_options.cmd_opts cmd_opts = shared_cmd_options.cmd_opts
parser = shared_cmd_options.parser parser = shared_cmd_options.parser
...@@ -16,11 +20,11 @@ styles_filename = cmd_opts.styles_file = cmd_opts.styles_file if len(cmd_opts.st ...@@ -16,11 +20,11 @@ styles_filename = cmd_opts.styles_file = cmd_opts.styles_file if len(cmd_opts.st
config_filename = cmd_opts.ui_settings_file config_filename = cmd_opts.ui_settings_file
hide_dirs = {"visible": not cmd_opts.hide_ui_dir_config} hide_dirs = {"visible": not cmd_opts.hide_ui_dir_config}
demo = None demo: gr.Blocks = None
device = None device: str = None
weight_load_location = None weight_load_location: str = None
xformers_available = False xformers_available = False
...@@ -28,21 +32,21 @@ hypernetworks = {} ...@@ -28,21 +32,21 @@ hypernetworks = {}
loaded_hypernetworks = [] loaded_hypernetworks = []
state = None state: 'shared_state.State' = None
prompt_styles = None prompt_styles: 'styles.StyleDatabase' = None
interrogator = None interrogator: 'interrogate.InterrogateModels' = None
face_restorers = [] face_restorers = []
options_templates = None options_templates: dict = None
opts = None opts: options.Options = None
restricted_opts = None restricted_opts: set[str] = None
sd_model: sd_models_types.WebuiSdModel = None sd_model: sd_models_types.WebuiSdModel = None
settings_components = None settings_components: dict = None
"""assigned from ui.py, a mapping on setting names to gradio components repsponsible for those settings""" """assigned from ui.py, a mapping on setting names to gradio components repsponsible for those settings"""
tab_names = [] tab_names = []
...@@ -65,9 +69,9 @@ progress_print_out = sys.stdout ...@@ -65,9 +69,9 @@ progress_print_out = sys.stdout
gradio_theme = gr.themes.Base() gradio_theme = gr.themes.Base()
total_tqdm = None total_tqdm: 'shared_total_tqdm.TotalTQDM' = None
mem_mon = None mem_mon: 'memmon.MemUsageMonitor' = None
options_section = options.options_section options_section = options.options_section
OptionInfo = options.OptionInfo OptionInfo = options.OptionInfo
......
import html
import sys import sys
from modules import script_callbacks, scripts, ui_components
from modules.options import OptionHTML, OptionInfo
from modules.shared_cmd_options import cmd_opts from modules.shared_cmd_options import cmd_opts
...@@ -118,6 +121,45 @@ def ui_reorder_categories(): ...@@ -118,6 +121,45 @@ def ui_reorder_categories():
yield "scripts" yield "scripts"
def callbacks_order_settings():
options = {
"sd_vae_explanation": OptionHTML("""
For categories below, callbacks added to dropdowns happen before others, in order listed.
"""),
}
callback_options = {}
for category, _ in script_callbacks.enumerate_callbacks():
callback_options[category] = script_callbacks.ordered_callbacks(category, enable_user_sort=False)
for method_name in scripts.scripts_txt2img.callback_names:
callback_options["script_" + method_name] = scripts.scripts_txt2img.create_ordered_callbacks_list(method_name, enable_user_sort=False)
for method_name in scripts.scripts_img2img.callback_names:
callbacks = callback_options.get("script_" + method_name, [])
for addition in scripts.scripts_img2img.create_ordered_callbacks_list(method_name, enable_user_sort=False):
if any(x.name == addition.name for x in callbacks):
continue
callbacks.append(addition)
callback_options["script_" + method_name] = callbacks
for category, callbacks in callback_options.items():
if not callbacks:
continue
option_info = OptionInfo([], f"{category} callback priority", ui_components.DropdownMulti, {"choices": [x.name for x in callbacks]})
option_info.needs_restart()
option_info.html("<div class='info'>Default order: <ol>" + "".join(f"<li>{html.escape(x.name)}</li>\n" for x in callbacks) + "</ol></div>")
options['prioritized_callbacks_' + category] = option_info
return options
class Shared(sys.modules[__name__].__class__): class Shared(sys.modules[__name__].__class__):
""" """
this class is here to provide sd_model field as a property, so that it can be created and loaded on demand rather than this class is here to provide sd_model field as a property, so that it can be created and loaded on demand rather than
......
...@@ -101,6 +101,7 @@ options_templates.update(options_section(('upscaling', "Upscaling", "postprocess ...@@ -101,6 +101,7 @@ options_templates.update(options_section(('upscaling', "Upscaling", "postprocess
"DAT_tile": OptionInfo(192, "Tile size for DAT upscalers.", gr.Slider, {"minimum": 0, "maximum": 512, "step": 16}).info("0 = no tiling"), "DAT_tile": OptionInfo(192, "Tile size for DAT upscalers.", gr.Slider, {"minimum": 0, "maximum": 512, "step": 16}).info("0 = no tiling"),
"DAT_tile_overlap": OptionInfo(8, "Tile overlap for DAT upscalers.", gr.Slider, {"minimum": 0, "maximum": 48, "step": 1}).info("Low values = visible seam"), "DAT_tile_overlap": OptionInfo(8, "Tile overlap for DAT upscalers.", gr.Slider, {"minimum": 0, "maximum": 48, "step": 1}).info("Low values = visible seam"),
"upscaler_for_img2img": OptionInfo(None, "Upscaler for img2img", gr.Dropdown, lambda: {"choices": [x.name for x in shared.sd_upscalers]}), "upscaler_for_img2img": OptionInfo(None, "Upscaler for img2img", gr.Dropdown, lambda: {"choices": [x.name for x in shared.sd_upscalers]}),
"set_scale_by_when_changing_upscaler": OptionInfo(False, "Automatically set the Scale by factor based on the name of the selected Upscaler."),
})) }))
options_templates.update(options_section(('face-restoration', "Face restoration", "postprocessing"), { options_templates.update(options_section(('face-restoration', "Face restoration", "postprocessing"), {
...@@ -258,7 +259,8 @@ options_templates.update(options_section(('extra_networks', "Extra Networks", "s ...@@ -258,7 +259,8 @@ options_templates.update(options_section(('extra_networks', "Extra Networks", "s
"extra_networks_card_description_is_html": OptionInfo(False, "Treat card description as HTML"), "extra_networks_card_description_is_html": OptionInfo(False, "Treat card description as HTML"),
"extra_networks_card_order_field": OptionInfo("Path", "Default order field for Extra Networks cards", gr.Dropdown, {"choices": ['Path', 'Name', 'Date Created', 'Date Modified']}).needs_reload_ui(), "extra_networks_card_order_field": OptionInfo("Path", "Default order field for Extra Networks cards", gr.Dropdown, {"choices": ['Path', 'Name', 'Date Created', 'Date Modified']}).needs_reload_ui(),
"extra_networks_card_order": OptionInfo("Ascending", "Default order for Extra Networks cards", gr.Dropdown, {"choices": ['Ascending', 'Descending']}).needs_reload_ui(), "extra_networks_card_order": OptionInfo("Ascending", "Default order for Extra Networks cards", gr.Dropdown, {"choices": ['Ascending', 'Descending']}).needs_reload_ui(),
"extra_networks_tree_view_default_enabled": OptionInfo(False, "Enables the Extra Networks directory tree view by default").needs_reload_ui(), "extra_networks_tree_view_style": OptionInfo("Dirs", "Extra Networks directory view style", gr.Radio, {"choices": ["Tree", "Dirs"]}).needs_reload_ui(),
"extra_networks_tree_view_default_enabled": OptionInfo(True, "Show the Extra Networks directory view by default").needs_reload_ui(),
"extra_networks_tree_view_default_width": OptionInfo(180, "Default width for the Extra Networks directory tree view", gr.Number).needs_reload_ui(), "extra_networks_tree_view_default_width": OptionInfo(180, "Default width for the Extra Networks directory tree view", gr.Number).needs_reload_ui(),
"extra_networks_add_text_separator": OptionInfo(" ", "Extra networks separator").info("extra text to add before <...> when adding extra network to prompt"), "extra_networks_add_text_separator": OptionInfo(" ", "Extra networks separator").info("extra text to add before <...> when adding extra network to prompt"),
"ui_extra_networks_tab_reorder": OptionInfo("", "Extra networks tab order").needs_reload_ui(), "ui_extra_networks_tab_reorder": OptionInfo("", "Extra networks tab order").needs_reload_ui(),
......
from __future__ import annotations
from pathlib import Path from pathlib import Path
from modules import errors from modules import errors
import csv import csv
......
...@@ -164,6 +164,8 @@ class ExtraNetworksPage: ...@@ -164,6 +164,8 @@ class ExtraNetworksPage:
self.lister = util.MassFileLister() self.lister = util.MassFileLister()
# HTML Templates # HTML Templates
self.pane_tpl = shared.html("extra-networks-pane.html") self.pane_tpl = shared.html("extra-networks-pane.html")
self.pane_content_tree_tpl = shared.html("extra-networks-pane-tree.html")
self.pane_content_dirs_tpl = shared.html("extra-networks-pane-dirs.html")
self.card_tpl = shared.html("extra-networks-card.html") self.card_tpl = shared.html("extra-networks-card.html")
self.btn_tree_tpl = shared.html("extra-networks-tree-button.html") self.btn_tree_tpl = shared.html("extra-networks-tree-button.html")
self.btn_copy_path_tpl = shared.html("extra-networks-copy-path-button.html") self.btn_copy_path_tpl = shared.html("extra-networks-copy-path-button.html")
...@@ -476,6 +478,47 @@ class ExtraNetworksPage: ...@@ -476,6 +478,47 @@ class ExtraNetworksPage:
return f"<ul class='tree-list tree-list--tree'>{res}</ul>" return f"<ul class='tree-list tree-list--tree'>{res}</ul>"
def create_dirs_view_html(self, tabname: str) -> str:
"""Generates HTML for displaying folders."""
subdirs = {}
for parentdir in [os.path.abspath(x) for x in self.allowed_directories_for_previews()]:
for root, dirs, _ in sorted(os.walk(parentdir, followlinks=True), key=lambda x: shared.natural_sort_key(x[0])):
for dirname in sorted(dirs, key=shared.natural_sort_key):
x = os.path.join(root, dirname)
if not os.path.isdir(x):
continue
subdir = os.path.abspath(x)[len(parentdir):]
if shared.opts.extra_networks_dir_button_function:
if not subdir.startswith(os.path.sep):
subdir = os.path.sep + subdir
else:
while subdir.startswith(os.path.sep):
subdir = subdir[1:]
is_empty = len(os.listdir(x)) == 0
if not is_empty and not subdir.endswith(os.path.sep):
subdir = subdir + os.path.sep
if (os.path.sep + "." in subdir or subdir.startswith(".")) and not shared.opts.extra_networks_show_hidden_directories:
continue
subdirs[subdir] = 1
if subdirs:
subdirs = {"": 1, **subdirs}
subdirs_html = "".join([f"""
<button class='lg secondary gradio-button custom-button{" search-all" if subdir == "" else ""}' onclick='extraNetworksSearchButton("{tabname}", "{self.extra_networks_tabname}", event)'>
{html.escape(subdir if subdir != "" else "all")}
</button>
""" for subdir in subdirs])
return subdirs_html
def create_card_view_html(self, tabname: str, *, none_message) -> str: def create_card_view_html(self, tabname: str, *, none_message) -> str:
"""Generates HTML for the network Card View section for a tab. """Generates HTML for the network Card View section for a tab.
...@@ -489,15 +532,15 @@ class ExtraNetworksPage: ...@@ -489,15 +532,15 @@ class ExtraNetworksPage:
Returns: Returns:
HTML formatted string. HTML formatted string.
""" """
res = "" res = []
for item in self.items.values(): for item in self.items.values():
res += self.create_item_html(tabname, item, self.card_tpl) res.append(self.create_item_html(tabname, item, self.card_tpl))
if res == "": if not res:
dirs = "".join([f"<li>{x}</li>" for x in self.allowed_directories_for_previews()]) dirs = "".join([f"<li>{x}</li>" for x in self.allowed_directories_for_previews()])
res = none_message or shared.html("extra-networks-no-cards.html").format(dirs=dirs) res = [none_message or shared.html("extra-networks-no-cards.html").format(dirs=dirs)]
return res return "".join(res)
def create_html(self, tabname, *, empty=False): def create_html(self, tabname, *, empty=False):
"""Generates an HTML string for the current pane. """Generates an HTML string for the current pane.
...@@ -526,35 +569,28 @@ class ExtraNetworksPage: ...@@ -526,35 +569,28 @@ class ExtraNetworksPage:
if "user_metadata" not in item: if "user_metadata" not in item:
self.read_user_metadata(item) self.read_user_metadata(item)
data_sortdir = shared.opts.extra_networks_card_order show_tree = shared.opts.extra_networks_tree_view_default_enabled
data_sortmode = shared.opts.extra_networks_card_order_field.lower().replace("sort", "").replace(" ", "_").rstrip("_").strip()
data_sortkey = f"{data_sortmode}-{data_sortdir}-{len(self.items)}" page_params = {
tree_view_btn_extra_class = ""
tree_view_div_extra_class = "hidden"
tree_view_div_default_display = "none"
extra_network_pane_content_default_display = "flex"
if shared.opts.extra_networks_tree_view_default_enabled:
tree_view_btn_extra_class = "extra-network-control--enabled"
tree_view_div_extra_class = ""
tree_view_div_default_display = "block"
extra_network_pane_content_default_display = "grid"
return self.pane_tpl.format(
**{
"tabname": tabname, "tabname": tabname,
"extra_networks_tabname": self.extra_networks_tabname, "extra_networks_tabname": self.extra_networks_tabname,
"data_sortmode": data_sortmode, "data_sortdir": shared.opts.extra_networks_card_order,
"data_sortkey": data_sortkey, "sort_path_active": ' extra-network-control--enabled' if shared.opts.extra_networks_card_order_field == 'Path' else '',
"data_sortdir": data_sortdir, "sort_name_active": ' extra-network-control--enabled' if shared.opts.extra_networks_card_order_field == 'Name' else '',
"tree_view_btn_extra_class": tree_view_btn_extra_class, "sort_date_created_active": ' extra-network-control--enabled' if shared.opts.extra_networks_card_order_field == 'Date Created' else '',
"tree_view_div_extra_class": tree_view_div_extra_class, "sort_date_modified_active": ' extra-network-control--enabled' if shared.opts.extra_networks_card_order_field == 'Date Modified' else '',
"tree_html": self.create_tree_view_html(tabname), "tree_view_btn_extra_class": "extra-network-control--enabled" if show_tree else "",
"items_html": self.create_card_view_html(tabname, none_message="Loading..." if empty else None), "items_html": self.create_card_view_html(tabname, none_message="Loading..." if empty else None),
"extra_networks_tree_view_default_width": shared.opts.extra_networks_tree_view_default_width, "extra_networks_tree_view_default_width": shared.opts.extra_networks_tree_view_default_width,
"tree_view_div_default_display": tree_view_div_default_display, "tree_view_div_default_display_class": "" if show_tree else "extra-network-dirs-hidden",
"extra_network_pane_content_default_display": extra_network_pane_content_default_display,
} }
)
if shared.opts.extra_networks_tree_view_style == "Tree":
pane_content = self.pane_content_tree_tpl.format(**page_params, tree_html=self.create_tree_view_html(tabname))
else:
pane_content = self.pane_content_dirs_tpl.format(**page_params, dirs_html=self.create_dirs_view_html(tabname))
return self.pane_tpl.format(**page_params, pane_content=pane_content)
def create_item(self, name, index=None): def create_item(self, name, index=None):
raise NotImplementedError() raise NotImplementedError()
......
...@@ -133,8 +133,10 @@ class UserMetadataEditor: ...@@ -133,8 +133,10 @@ class UserMetadataEditor:
filename = item.get("filename", None) filename = item.get("filename", None)
basename, ext = os.path.splitext(filename) basename, ext = os.path.splitext(filename)
with open(basename + '.json', "w", encoding="utf8") as file: metadata_path = basename + '.json'
with open(metadata_path, "w", encoding="utf8") as file:
json.dump(metadata, file, indent=4, ensure_ascii=False) json.dump(metadata, file, indent=4, ensure_ascii=False)
self.page.lister.update_file_entry(metadata_path)
def save_user_metadata(self, name, desc, notes): def save_user_metadata(self, name, desc, notes):
user_metadata = self.get_user_metadata(name) user_metadata = self.get_user_metadata(name)
...@@ -185,7 +187,8 @@ class UserMetadataEditor: ...@@ -185,7 +187,8 @@ class UserMetadataEditor:
geninfo, items = images.read_info_from_image(image) geninfo, items = images.read_info_from_image(image)
images.save_image_with_geninfo(image, geninfo, item["local_preview"]) images.save_image_with_geninfo(image, geninfo, item["local_preview"])
self.page.lister.update_file_entry(item["local_preview"])
item['preview'] = self.page.find_preview(item["local_preview"])
return self.get_card_html(name), '' return self.get_card_html(name), ''
def setup_ui(self, gallery): def setup_ui(self, gallery):
...@@ -200,6 +203,3 @@ class UserMetadataEditor: ...@@ -200,6 +203,3 @@ class UserMetadataEditor:
inputs=[self.edit_name_input], inputs=[self.edit_name_input],
outputs=[] outputs=[]
) )
...@@ -104,6 +104,8 @@ class UiLoadsave: ...@@ -104,6 +104,8 @@ class UiLoadsave:
apply_field(x, 'value', check_dropdown, getattr(x, 'init_field', None)) apply_field(x, 'value', check_dropdown, getattr(x, 'init_field', None))
if type(x) == InputAccordion: if type(x) == InputAccordion:
if hasattr(x, 'custom_script_source'):
x.accordion.custom_script_source = x.custom_script_source
if x.accordion.visible: if x.accordion.visible:
apply_field(x.accordion, 'visible') apply_field(x.accordion, 'visible')
apply_field(x, 'value') apply_field(x, 'value')
......
import gradio as gr import gradio as gr
from modules import ui_common, shared, script_callbacks, scripts, sd_models, sysinfo, timer from modules import ui_common, shared, script_callbacks, scripts, sd_models, sysinfo, timer, shared_items
from modules.call_queue import wrap_gradio_call from modules.call_queue import wrap_gradio_call
from modules.options import options_section
from modules.shared import opts from modules.shared import opts
from modules.ui_components import FormRow from modules.ui_components import FormRow
from modules.ui_gradio_extensions import reload_javascript from modules.ui_gradio_extensions import reload_javascript
...@@ -108,6 +109,11 @@ class UiSettings: ...@@ -108,6 +109,11 @@ class UiSettings:
shared.settings_components = self.component_dict shared.settings_components = self.component_dict
# we add this as late as possible so that scripts have already registered their callbacks
opts.data_labels.update(options_section(('callbacks', "Callbacks", "system"), {
**shared_items.callbacks_order_settings(),
}))
opts.reorder() opts.reorder()
with gr.Blocks(analytics_enabled=False) as settings_interface: with gr.Blocks(analytics_enabled=False) as settings_interface:
......
...@@ -20,7 +20,7 @@ class Upscaler: ...@@ -20,7 +20,7 @@ class Upscaler:
filter = None filter = None
model = None model = None
user_path = None user_path = None
scalers: [] scalers: list
tile = True tile = True
def __init__(self, create_dirs=False): def __init__(self, create_dirs=False):
......
...@@ -81,6 +81,17 @@ class MassFileListerCachedDir: ...@@ -81,6 +81,17 @@ class MassFileListerCachedDir:
self.files = {x[0].lower(): x for x in files} self.files = {x[0].lower(): x for x in files}
self.files_cased = {x[0]: x for x in files} self.files_cased = {x[0]: x for x in files}
def update_entry(self, filename):
"""Add a file to the cache"""
file_path = os.path.join(self.dirname, filename)
try:
stat = os.stat(file_path)
entry = (filename, stat.st_mtime, stat.st_ctime)
self.files[filename.lower()] = entry
self.files_cased[filename] = entry
except FileNotFoundError as e:
print(f'MassFileListerCachedDir.add_entry: "{file_path}" {e}')
class MassFileLister: class MassFileLister:
"""A class that provides a way to check for the existence and mtime/ctile of files without doing more than one stat call per file.""" """A class that provides a way to check for the existence and mtime/ctile of files without doing more than one stat call per file."""
...@@ -136,3 +147,27 @@ class MassFileLister: ...@@ -136,3 +147,27 @@ class MassFileLister:
def reset(self): def reset(self):
"""Clear the cache of all directories.""" """Clear the cache of all directories."""
self.cached_dirs.clear() self.cached_dirs.clear()
def topological_sort(dependencies):
"""Accepts a dictionary mapping name to its dependencies, returns a list of names ordered according to dependencies.
Ignores errors relating to missing dependeencies or circular dependencies
"""
visited = {}
result = []
def inner(name):
visited[name] = True
for dep in dependencies.get(name, []):
if dep in dependencies and dep not in visited:
inner(dep)
result.append(name)
for depname in dependencies:
if depname not in visited:
inner(depname)
return result
import re
from PIL import Image from PIL import Image
import numpy as np import numpy as np
from modules import scripts_postprocessing, shared from modules import scripts_postprocessing, shared
import gradio as gr import gradio as gr
from modules.ui_components import FormRow, ToolButton from modules.ui_components import FormRow, ToolButton, InputAccordion
from modules.ui import switch_values_symbol from modules.ui import switch_values_symbol
upscale_cache = {} upscale_cache = {}
...@@ -17,7 +19,14 @@ class ScriptPostprocessingUpscale(scripts_postprocessing.ScriptPostprocessing): ...@@ -17,7 +19,14 @@ class ScriptPostprocessingUpscale(scripts_postprocessing.ScriptPostprocessing):
def ui(self): def ui(self):
selected_tab = gr.Number(value=0, visible=False) selected_tab = gr.Number(value=0, visible=False)
with gr.Column(): with InputAccordion(True, label="Upscale", elem_id="extras_upscale") as upscale_enabled:
with FormRow():
extras_upscaler_1 = gr.Dropdown(label='Upscaler 1', elem_id="extras_upscaler_1", choices=[x.name for x in shared.sd_upscalers], value=shared.sd_upscalers[0].name)
with FormRow():
extras_upscaler_2 = gr.Dropdown(label='Upscaler 2', elem_id="extras_upscaler_2", choices=[x.name for x in shared.sd_upscalers], value=shared.sd_upscalers[0].name)
extras_upscaler_2_visibility = gr.Slider(minimum=0.0, maximum=1.0, step=0.001, label="Upscaler 2 visibility", value=0.0, elem_id="extras_upscaler_2_visibility")
with FormRow(): with FormRow():
with gr.Tabs(elem_id="extras_resize_mode"): with gr.Tabs(elem_id="extras_resize_mode"):
with gr.TabItem('Scale by', elem_id="extras_scale_by_tab") as tab_scale_by: with gr.TabItem('Scale by', elem_id="extras_scale_by_tab") as tab_scale_by:
...@@ -32,18 +41,24 @@ class ScriptPostprocessingUpscale(scripts_postprocessing.ScriptPostprocessing): ...@@ -32,18 +41,24 @@ class ScriptPostprocessingUpscale(scripts_postprocessing.ScriptPostprocessing):
upscaling_res_switch_btn = ToolButton(value=switch_values_symbol, elem_id="upscaling_res_switch_btn", tooltip="Switch width/height") upscaling_res_switch_btn = ToolButton(value=switch_values_symbol, elem_id="upscaling_res_switch_btn", tooltip="Switch width/height")
upscaling_crop = gr.Checkbox(label='Crop to fit', value=True, elem_id="extras_upscaling_crop") upscaling_crop = gr.Checkbox(label='Crop to fit', value=True, elem_id="extras_upscaling_crop")
with FormRow(): def on_selected_upscale_method(upscale_method):
extras_upscaler_1 = gr.Dropdown(label='Upscaler 1', elem_id="extras_upscaler_1", choices=[x.name for x in shared.sd_upscalers], value=shared.sd_upscalers[0].name) if not shared.opts.set_scale_by_when_changing_upscaler:
return gr.update()
with FormRow(): match = re.search(r'(\d)[xX]|[xX](\d)', upscale_method)
extras_upscaler_2 = gr.Dropdown(label='Upscaler 2', elem_id="extras_upscaler_2", choices=[x.name for x in shared.sd_upscalers], value=shared.sd_upscalers[0].name) if not match:
extras_upscaler_2_visibility = gr.Slider(minimum=0.0, maximum=1.0, step=0.001, label="Upscaler 2 visibility", value=0.0, elem_id="extras_upscaler_2_visibility") return gr.update()
return gr.update(value=int(match.group(1) or match.group(2)))
upscaling_res_switch_btn.click(lambda w, h: (h, w), inputs=[upscaling_resize_w, upscaling_resize_h], outputs=[upscaling_resize_w, upscaling_resize_h], show_progress=False) upscaling_res_switch_btn.click(lambda w, h: (h, w), inputs=[upscaling_resize_w, upscaling_resize_h], outputs=[upscaling_resize_w, upscaling_resize_h], show_progress=False)
tab_scale_by.select(fn=lambda: 0, inputs=[], outputs=[selected_tab]) tab_scale_by.select(fn=lambda: 0, inputs=[], outputs=[selected_tab])
tab_scale_to.select(fn=lambda: 1, inputs=[], outputs=[selected_tab]) tab_scale_to.select(fn=lambda: 1, inputs=[], outputs=[selected_tab])
extras_upscaler_1.change(on_selected_upscale_method, inputs=[extras_upscaler_1], outputs=[upscaling_resize], show_progress="hidden")
return { return {
"upscale_enabled": upscale_enabled,
"upscale_mode": selected_tab, "upscale_mode": selected_tab,
"upscale_by": upscaling_resize, "upscale_by": upscaling_resize,
"upscale_to_width": upscaling_resize_w, "upscale_to_width": upscaling_resize_w,
...@@ -81,7 +96,7 @@ class ScriptPostprocessingUpscale(scripts_postprocessing.ScriptPostprocessing): ...@@ -81,7 +96,7 @@ class ScriptPostprocessingUpscale(scripts_postprocessing.ScriptPostprocessing):
return image return image
def process_firstpass(self, pp: scripts_postprocessing.PostprocessedImage, upscale_mode=1, upscale_by=2.0, upscale_to_width=None, upscale_to_height=None, upscale_crop=False, upscaler_1_name=None, upscaler_2_name=None, upscaler_2_visibility=0.0): def process_firstpass(self, pp: scripts_postprocessing.PostprocessedImage, upscale_enabled=True, upscale_mode=1, upscale_by=2.0, upscale_to_width=None, upscale_to_height=None, upscale_crop=False, upscaler_1_name=None, upscaler_2_name=None, upscaler_2_visibility=0.0):
if upscale_mode == 1: if upscale_mode == 1:
pp.shared.target_width = upscale_to_width pp.shared.target_width = upscale_to_width
pp.shared.target_height = upscale_to_height pp.shared.target_height = upscale_to_height
...@@ -89,7 +104,10 @@ class ScriptPostprocessingUpscale(scripts_postprocessing.ScriptPostprocessing): ...@@ -89,7 +104,10 @@ class ScriptPostprocessingUpscale(scripts_postprocessing.ScriptPostprocessing):
pp.shared.target_width = int(pp.image.width * upscale_by) pp.shared.target_width = int(pp.image.width * upscale_by)
pp.shared.target_height = int(pp.image.height * upscale_by) pp.shared.target_height = int(pp.image.height * upscale_by)
def process(self, pp: scripts_postprocessing.PostprocessedImage, upscale_mode=1, upscale_by=2.0, upscale_to_width=None, upscale_to_height=None, upscale_crop=False, upscaler_1_name=None, upscaler_2_name=None, upscaler_2_visibility=0.0): def process(self, pp: scripts_postprocessing.PostprocessedImage, upscale_enabled=True, upscale_mode=1, upscale_by=2.0, upscale_to_width=None, upscale_to_height=None, upscale_crop=False, upscaler_1_name=None, upscaler_2_name=None, upscaler_2_visibility=0.0):
if not upscale_enabled:
return
if upscaler_1_name == "None": if upscaler_1_name == "None":
upscaler_1_name = None upscaler_1_name = None
......
/* temporary fix to load default gradio font in frontend instead of backend */ /* temporary fix to load default gradio font in frontend instead of backend */
@import url('webui-assets/css/sourcesanspro.css'); @import url('/webui-assets/css/sourcesanspro.css');
/* temporary fix to hide gradio crop tool until it's fixed https://github.com/gradio-app/gradio/issues/3810 */ /* temporary fix to hide gradio crop tool until it's fixed https://github.com/gradio-app/gradio/issues/3810 */
...@@ -528,6 +528,10 @@ table.popup-table .link{ ...@@ -528,6 +528,10 @@ table.popup-table .link{
opacity: 0.75; opacity: 0.75;
} }
.settings-comment .info ol{
margin: 0.4em 0 0.8em 1em;
}
#sysinfo_download a.sysinfo_big_link{ #sysinfo_download a.sysinfo_big_link{
font-size: 24pt; font-size: 24pt;
} }
...@@ -1205,12 +1209,24 @@ body.resizing .resize-handle { ...@@ -1205,12 +1209,24 @@ body.resizing .resize-handle {
overflow: hidden; overflow: hidden;
} }
.extra-network-pane .extra-network-pane-content { .extra-network-pane .extra-network-pane-content-dirs {
display: flex; display: flex;
flex: 1; flex: 1;
flex-direction: column;
overflow: hidden; overflow: hidden;
} }
.extra-network-pane .extra-network-pane-content-tree {
display: flex;
flex: 1;
overflow: hidden;
}
.extra-network-dirs-hidden .extra-network-dirs{ display: none; }
.extra-network-dirs-hidden .extra-network-tree{ display: none; }
.extra-network-dirs-hidden .resize-handle { display: none; }
.extra-network-dirs-hidden .resize-handle-row { display: flex !important; }
.extra-network-pane .extra-network-tree { .extra-network-pane .extra-network-tree {
flex: 1; flex: 1;
font-size: 1rem; font-size: 1rem;
...@@ -1260,7 +1276,7 @@ body.resizing .resize-handle { ...@@ -1260,7 +1276,7 @@ body.resizing .resize-handle {
.extra-network-control { .extra-network-control {
position: relative; position: relative;
display: grid; display: flex;
width: 100%; width: 100%;
padding: 0 !important; padding: 0 !important;
margin-top: 0 !important; margin-top: 0 !important;
...@@ -1277,6 +1293,12 @@ body.resizing .resize-handle { ...@@ -1277,6 +1293,12 @@ body.resizing .resize-handle {
align-items: start; align-items: start;
} }
.extra-network-control small{
color: var(--input-placeholder-color);
line-height: 2.2rem;
margin: 0 0.5rem 0 0.75rem;
}
.extra-network-tree .tree-list--tree {} .extra-network-tree .tree-list--tree {}
/* Remove auto indentation from tree. Will be overridden later. */ /* Remove auto indentation from tree. Will be overridden later. */
...@@ -1424,6 +1446,12 @@ body.resizing .resize-handle { ...@@ -1424,6 +1446,12 @@ body.resizing .resize-handle {
line-height: 1rem; line-height: 1rem;
} }
.extra-network-control .extra-network-control--search .extra-network-control--search-text::placeholder {
color: var(--input-placeholder-color);
}
/* <input> clear button (x on right side) styling */ /* <input> clear button (x on right side) styling */
.extra-network-control .extra-network-control--search .extra-network-control--search-text::-webkit-search-cancel-button { .extra-network-control .extra-network-control--search .extra-network-control--search-text::-webkit-search-cancel-button {
-webkit-appearance: none; -webkit-appearance: none;
...@@ -1456,19 +1484,19 @@ body.resizing .resize-handle { ...@@ -1456,19 +1484,19 @@ body.resizing .resize-handle {
background-color: var(--input-placeholder-color); background-color: var(--input-placeholder-color);
} }
.extra-network-control .extra-network-control--sort[data-sortmode="path"] .extra-network-control--sort-icon { .extra-network-control .extra-network-control--sort[data-sortkey="default"] .extra-network-control--sort-icon {
mask-image: url('data:image/svg+xml,<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"><path fill-rule="evenodd" clip-rule="evenodd" d="M1 5C1 3.34315 2.34315 2 4 2H8.43845C9.81505 2 11.015 2.93689 11.3489 4.27239L11.7808 6H13.5H20C21.6569 6 23 7.34315 23 9V11C23 11.5523 22.5523 12 22 12C21.4477 12 21 11.5523 21 11V9C21 8.44772 20.5523 8 20 8H13.5H11.7808H4C3.44772 8 3 8.44772 3 9V10V19C3 19.5523 3.44772 20 4 20H9C9.55228 20 10 20.4477 10 21C10 21.5523 9.55228 22 9 22H4C2.34315 22 1 20.6569 1 19V10V9V5ZM3 6.17071C3.31278 6.06015 3.64936 6 4 6H9.71922L9.40859 4.75746C9.2973 4.3123 8.89732 4 8.43845 4H4C3.44772 4 3 4.44772 3 5V6.17071ZM20.1716 18.7574C20.6951 17.967 21 17.0191 21 16C21 13.2386 18.7614 11 16 11C13.2386 11 11 13.2386 11 16C11 18.7614 13.2386 21 16 21C17.0191 21 17.967 20.6951 18.7574 20.1716L21.2929 22.7071C21.6834 23.0976 22.3166 23.0976 22.7071 22.7071C23.0976 22.3166 23.0976 21.6834 22.7071 21.2929L20.1716 18.7574ZM13 16C13 14.3431 14.3431 13 16 13C17.6569 13 19 14.3431 19 16C19 17.6569 17.6569 19 16 19C14.3431 19 13 17.6569 13 16Z" fill="%23000000"></path></g></svg>'); mask-image: url('data:image/svg+xml,<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"><path fill-rule="evenodd" clip-rule="evenodd" d="M1 5C1 3.34315 2.34315 2 4 2H8.43845C9.81505 2 11.015 2.93689 11.3489 4.27239L11.7808 6H13.5H20C21.6569 6 23 7.34315 23 9V11C23 11.5523 22.5523 12 22 12C21.4477 12 21 11.5523 21 11V9C21 8.44772 20.5523 8 20 8H13.5H11.7808H4C3.44772 8 3 8.44772 3 9V10V19C3 19.5523 3.44772 20 4 20H9C9.55228 20 10 20.4477 10 21C10 21.5523 9.55228 22 9 22H4C2.34315 22 1 20.6569 1 19V10V9V5ZM3 6.17071C3.31278 6.06015 3.64936 6 4 6H9.71922L9.40859 4.75746C9.2973 4.3123 8.89732 4 8.43845 4H4C3.44772 4 3 4.44772 3 5V6.17071ZM20.1716 18.7574C20.6951 17.967 21 17.0191 21 16C21 13.2386 18.7614 11 16 11C13.2386 11 11 13.2386 11 16C11 18.7614 13.2386 21 16 21C17.0191 21 17.967 20.6951 18.7574 20.1716L21.2929 22.7071C21.6834 23.0976 22.3166 23.0976 22.7071 22.7071C23.0976 22.3166 23.0976 21.6834 22.7071 21.2929L20.1716 18.7574ZM13 16C13 14.3431 14.3431 13 16 13C17.6569 13 19 14.3431 19 16C19 17.6569 17.6569 19 16 19C14.3431 19 13 17.6569 13 16Z" fill="%23000000"></path></g></svg>');
} }
.extra-network-control .extra-network-control--sort[data-sortmode="name"] .extra-network-control--sort-icon { .extra-network-control .extra-network-control--sort[data-sortkey="name"] .extra-network-control--sort-icon {
mask-image: url('data:image/svg+xml,<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"><path fill-rule="evenodd" clip-rule="evenodd" d="M17.1841 6.69223C17.063 6.42309 16.7953 6.25 16.5002 6.25C16.2051 6.25 15.9374 6.42309 15.8162 6.69223L11.3162 16.6922C11.1463 17.07 11.3147 17.514 11.6924 17.6839C12.0701 17.8539 12.5141 17.6855 12.6841 17.3078L14.1215 14.1136H18.8789L20.3162 17.3078C20.4862 17.6855 20.9302 17.8539 21.308 17.6839C21.6857 17.514 21.8541 17.07 21.6841 16.6922L17.1841 6.69223ZM16.5002 8.82764L14.7965 12.6136H18.2039L16.5002 8.82764Z" fill="%231C274C"></path><path opacity="0.5" fill-rule="evenodd" clip-rule="evenodd" d="M2.25 7C2.25 6.58579 2.58579 6.25 3 6.25H13C13.4142 6.25 13.75 6.58579 13.75 7C13.75 7.41421 13.4142 7.75 13 7.75H3C2.58579 7.75 2.25 7.41421 2.25 7Z" fill="%231C274C"></path><path opacity="0.5" d="M2.25 12C2.25 11.5858 2.58579 11.25 3 11.25H10C10.4142 11.25 10.75 11.5858 10.75 12C10.75 12.4142 10.4142 12.75 10 12.75H3C2.58579 12.75 2.25 12.4142 2.25 12Z" fill="%231C274C"></path><path opacity="0.5" d="M2.25 17C2.25 16.5858 2.58579 16.25 3 16.25H8C8.41421 16.25 8.75 16.5858 8.75 17C8.75 17.4142 8.41421 17.75 8 17.75H3C2.58579 17.75 2.25 17.4142 2.25 17Z" fill="%231C274C"></path></g></svg>'); mask-image: url('data:image/svg+xml,<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"><path fill-rule="evenodd" clip-rule="evenodd" d="M17.1841 6.69223C17.063 6.42309 16.7953 6.25 16.5002 6.25C16.2051 6.25 15.9374 6.42309 15.8162 6.69223L11.3162 16.6922C11.1463 17.07 11.3147 17.514 11.6924 17.6839C12.0701 17.8539 12.5141 17.6855 12.6841 17.3078L14.1215 14.1136H18.8789L20.3162 17.3078C20.4862 17.6855 20.9302 17.8539 21.308 17.6839C21.6857 17.514 21.8541 17.07 21.6841 16.6922L17.1841 6.69223ZM16.5002 8.82764L14.7965 12.6136H18.2039L16.5002 8.82764Z" fill="%231C274C"></path><path opacity="0.5" fill-rule="evenodd" clip-rule="evenodd" d="M2.25 7C2.25 6.58579 2.58579 6.25 3 6.25H13C13.4142 6.25 13.75 6.58579 13.75 7C13.75 7.41421 13.4142 7.75 13 7.75H3C2.58579 7.75 2.25 7.41421 2.25 7Z" fill="%231C274C"></path><path opacity="0.5" d="M2.25 12C2.25 11.5858 2.58579 11.25 3 11.25H10C10.4142 11.25 10.75 11.5858 10.75 12C10.75 12.4142 10.4142 12.75 10 12.75H3C2.58579 12.75 2.25 12.4142 2.25 12Z" fill="%231C274C"></path><path opacity="0.5" d="M2.25 17C2.25 16.5858 2.58579 16.25 3 16.25H8C8.41421 16.25 8.75 16.5858 8.75 17C8.75 17.4142 8.41421 17.75 8 17.75H3C2.58579 17.75 2.25 17.4142 2.25 17Z" fill="%231C274C"></path></g></svg>');
} }
.extra-network-control .extra-network-control--sort[data-sortmode="date_created"] .extra-network-control--sort-icon { .extra-network-control .extra-network-control--sort[data-sortkey="date_created"] .extra-network-control--sort-icon {
mask-image: url('data:image/svg+xml,<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"><path d="M17 11C14.2386 11 12 13.2386 12 16C12 18.7614 14.2386 21 17 21C19.7614 21 22 18.7614 22 16C22 13.2386 19.7614 11 17 11ZM17 11V9M2 9V15.8C2 16.9201 2 17.4802 2.21799 17.908C2.40973 18.2843 2.71569 18.5903 3.09202 18.782C3.51984 19 4.0799 19 5.2 19H13M2 9V8.2C2 7.0799 2 6.51984 2.21799 6.09202C2.40973 5.71569 2.71569 5.40973 3.09202 5.21799C3.51984 5 4.0799 5 5.2 5H13.8C14.9201 5 15.4802 5 15.908 5.21799C16.2843 5.40973 16.5903 5.71569 16.782 6.09202C17 6.51984 17 7.0799 17 8.2V9M2 9H17M5 3V5M14 3V5M15 16H17M17 16H19M17 16V14M17 16V18" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></g></svg>'); mask-image: url('data:image/svg+xml,<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"><path d="M17 11C14.2386 11 12 13.2386 12 16C12 18.7614 14.2386 21 17 21C19.7614 21 22 18.7614 22 16C22 13.2386 19.7614 11 17 11ZM17 11V9M2 9V15.8C2 16.9201 2 17.4802 2.21799 17.908C2.40973 18.2843 2.71569 18.5903 3.09202 18.782C3.51984 19 4.0799 19 5.2 19H13M2 9V8.2C2 7.0799 2 6.51984 2.21799 6.09202C2.40973 5.71569 2.71569 5.40973 3.09202 5.21799C3.51984 5 4.0799 5 5.2 5H13.8C14.9201 5 15.4802 5 15.908 5.21799C16.2843 5.40973 16.5903 5.71569 16.782 6.09202C17 6.51984 17 7.0799 17 8.2V9M2 9H17M5 3V5M14 3V5M15 16H17M17 16H19M17 16V14M17 16V18" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></g></svg>');
} }
.extra-network-control .extra-network-control--sort[data-sortmode="date_modified"] .extra-network-control--sort-icon { .extra-network-control .extra-network-control--sort[data-sortkey="date_modified"] .extra-network-control--sort-icon {
mask-image: url('data:image/svg+xml,<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"><path d="M10 21H6.2C5.0799 21 4.51984 21 4.09202 20.782C3.71569 20.5903 3.40973 20.2843 3.21799 19.908C3 19.4802 3 18.9201 3 17.8V8.2C3 7.0799 3 6.51984 3.21799 6.09202C3.40973 5.71569 3.71569 5.40973 4.09202 5.21799C4.51984 5 5.0799 5 6.2 5H17.8C18.9201 5 19.4802 5 19.908 5.21799C20.2843 5.40973 20.5903 5.71569 20.782 6.09202C21 6.51984 21 7.0799 21 8.2V10M7 3V5M17 3V5M3 9H21M13.5 13.0001L7 13M10 17.0001L7 17M14 21L16.025 20.595C16.2015 20.5597 16.2898 20.542 16.3721 20.5097C16.4452 20.4811 16.5147 20.4439 16.579 20.399C16.6516 20.3484 16.7152 20.2848 16.8426 20.1574L21 16C21.5523 15.4477 21.5523 14.5523 21 14C20.4477 13.4477 19.5523 13.4477 19 14L14.8426 18.1574C14.7152 18.2848 14.6516 18.3484 14.601 18.421C14.5561 18.4853 14.5189 18.5548 14.4903 18.6279C14.458 18.7102 14.4403 18.7985 14.405 18.975L14 21Z" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></g></svg>'); mask-image: url('data:image/svg+xml,<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"><path d="M10 21H6.2C5.0799 21 4.51984 21 4.09202 20.782C3.71569 20.5903 3.40973 20.2843 3.21799 19.908C3 19.4802 3 18.9201 3 17.8V8.2C3 7.0799 3 6.51984 3.21799 6.09202C3.40973 5.71569 3.71569 5.40973 4.09202 5.21799C4.51984 5 5.0799 5 6.2 5H17.8C18.9201 5 19.4802 5 19.908 5.21799C20.2843 5.40973 20.5903 5.71569 20.782 6.09202C21 6.51984 21 7.0799 21 8.2V10M7 3V5M17 3V5M3 9H21M13.5 13.0001L7 13M10 17.0001L7 17M14 21L16.025 20.595C16.2015 20.5597 16.2898 20.542 16.3721 20.5097C16.4452 20.4811 16.5147 20.4439 16.579 20.399C16.6516 20.3484 16.7152 20.2848 16.8426 20.1574L21 16C21.5523 15.4477 21.5523 14.5523 21 14C20.4477 13.4477 19.5523 13.4477 19 14L14.8426 18.1574C14.7152 18.2848 14.6516 18.3484 14.601 18.421C14.5561 18.4853 14.5189 18.5548 14.4903 18.6279C14.458 18.7102 14.4403 18.7985 14.405 18.975L14 21Z" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></g></svg>');
} }
...@@ -1518,13 +1546,18 @@ body.resizing .resize-handle { ...@@ -1518,13 +1546,18 @@ body.resizing .resize-handle {
} }
.extra-network-control .extra-network-control--enabled { .extra-network-control .extra-network-control--enabled {
background-color: rgba(0, 0, 0, 0.15); background-color: rgba(0, 0, 0, 0.1);
border-radius: 0.25rem;
} }
.dark .extra-network-control .extra-network-control--enabled { .dark .extra-network-control .extra-network-control--enabled {
background-color: rgba(255, 255, 255, 0.15); background-color: rgba(255, 255, 255, 0.15);
} }
.extra-network-control .extra-network-control--enabled .extra-network-control--icon{
background-color: var(--button-secondary-text-color);
}
/* ==== REFRESH ICON ACTIONS ==== */ /* ==== REFRESH ICON ACTIONS ==== */
.extra-network-control .extra-network-control--refresh { .extra-network-control .extra-network-control--refresh {
padding: 0.25rem; padding: 0.25rem;
......
...@@ -130,12 +130,18 @@ case "$gpu_info" in ...@@ -130,12 +130,18 @@ case "$gpu_info" in
if [[ -z "${TORCH_COMMAND}" ]] if [[ -z "${TORCH_COMMAND}" ]]
then then
pyv="$(${python_cmd} -c 'import sys; print(".".join(map(str, sys.version_info[0:2])))')" pyv="$(${python_cmd} -c 'import sys; print(".".join(map(str, sys.version_info[0:2])))')"
if [[ $(bc <<< "$pyv <= 3.10") -eq 1 ]] # Using an old nightly compiled against rocm 5.2 for Navi1, see https://github.com/pytorch/pytorch/issues/106728#issuecomment-1749511711
if [[ $pyv == "3.8" ]]
then then
# Navi users will still use torch 1.13 because 2.0 does not seem to work. export TORCH_COMMAND="pip install https://download.pytorch.org/whl/nightly/rocm5.2/torch-2.0.0.dev20230209%2Brocm5.2-cp38-cp38-linux_x86_64.whl https://download.pytorch.org/whl/nightly/rocm5.2/torchvision-0.15.0.dev20230209%2Brocm5.2-cp38-cp38-linux_x86_64.whl"
export TORCH_COMMAND="pip install --pre torch torchvision --index-url https://download.pytorch.org/whl/nightly/rocm5.6" elif [[ $pyv == "3.9" ]]
then
export TORCH_COMMAND="pip install https://download.pytorch.org/whl/nightly/rocm5.2/torch-2.0.0.dev20230209%2Brocm5.2-cp39-cp39-linux_x86_64.whl https://download.pytorch.org/whl/nightly/rocm5.2/torchvision-0.15.0.dev20230209%2Brocm5.2-cp39-cp39-linux_x86_64.whl"
elif [[ $pyv == "3.10" ]]
then
export TORCH_COMMAND="pip install https://download.pytorch.org/whl/nightly/rocm5.2/torch-2.0.0.dev20230209%2Brocm5.2-cp310-cp310-linux_x86_64.whl https://download.pytorch.org/whl/nightly/rocm5.2/torchvision-0.15.0.dev20230209%2Brocm5.2-cp310-cp310-linux_x86_64.whl"
else else
printf "\e[1m\e[31mERROR: RX 5000 series GPUs must be using at max python 3.10, aborting...\e[0m" printf "\e[1m\e[31mERROR: RX 5000 series GPUs python version must be between 3.8 and 3.10, aborting...\e[0m"
exit 1 exit 1
fi fi
fi fi
...@@ -143,7 +149,7 @@ case "$gpu_info" in ...@@ -143,7 +149,7 @@ case "$gpu_info" in
*"Navi 2"*) export HSA_OVERRIDE_GFX_VERSION=10.3.0 *"Navi 2"*) export HSA_OVERRIDE_GFX_VERSION=10.3.0
;; ;;
*"Navi 3"*) [[ -z "${TORCH_COMMAND}" ]] && \ *"Navi 3"*) [[ -z "${TORCH_COMMAND}" ]] && \
export TORCH_COMMAND="pip install --pre torch torchvision --index-url https://download.pytorch.org/whl/nightly/rocm5.7" export TORCH_COMMAND="pip install torch torchvision --index-url https://download.pytorch.org/whl/nightly/rocm5.7"
;; ;;
*"Renoir"*) export HSA_OVERRIDE_GFX_VERSION=9.0.0 *"Renoir"*) export HSA_OVERRIDE_GFX_VERSION=9.0.0
printf "\n%s\n" "${delimiter}" printf "\n%s\n" "${delimiter}"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment