Skip to content

feat: add sort-by-confidence option to WD14 captioning#3506

Closed
bmaltais wants to merge 32 commits into
masterfrom
feat/3491-sort-tags-by-confidence
Closed

feat: add sort-by-confidence option to WD14 captioning#3506
bmaltais wants to merge 32 commits into
masterfrom
feat/3491-sort-tags-by-confidence

Conversation

@bmaltais
Copy link
Copy Markdown
Owner

@bmaltais bmaltais commented May 8, 2026

Summary

Adds a Sort tags by confidence checkbox to the WD14 Captioning tab. When enabled, output tags are sorted by their model confidence score (highest first) before being written to the caption file, matching the ordering produced by the WaifuDiffusion online tagger.

  • Default: unchecked (existing CSV-index ordering is preserved)
  • Works independently of --character_tags_first and --always_first_tags/prefix

Backend change required in sd-scripts

This PR wires the GUI flag. The --sort_tags_by_confidence argument also needs to be added to sd-scripts/finetune/tag_images_by_wd14_tagger.py. The required change is:

In setup_parser() — add after --character_tag_expand:

parser.add_argument(
    "--sort_tags_by_confidence",
    action="store_true",
    help="sort tags by confidence score in descending order before outputting / タグを確信度の高い順に並べ替えてから出力する",
)

In run_batch() — replace the tag collection loop (lines ~255–272) with:

filtered_general: list[tuple[str, float]] = []
filtered_character: list[tuple[str, float]] = []
for i, p in enumerate(prob[4:]):
    if i < len(general_tags) and p >= args.general_threshold:
        tag_name = general_tags[i]
        if tag_name not in undesired_tags:
            filtered_general.append((tag_name, p))
    elif i >= len(general_tags) and p >= args.character_threshold:
        tag_name = character_tags[i - len(general_tags)]
        if tag_name not in undesired_tags:
            filtered_character.append((tag_name, p))

if args.sort_tags_by_confidence:
    filtered_general.sort(key=lambda x: x[1], reverse=True)
    filtered_character.sort(key=lambda x: x[1], reverse=True)

for tag_name, _ in filtered_general:
    tag_freq[tag_name] = tag_freq.get(tag_name, 0) + 1
    general_tag_text += caption_separator + tag_name
    combined_tags.append(tag_name)

for tag_name, _ in filtered_character:
    tag_freq[tag_name] = tag_freq.get(tag_name, 0) + 1
    character_tag_text += caption_separator + tag_name
    if args.character_tags_first:
        combined_tags.insert(0, tag_name)
    else:
        combined_tags.append(tag_name)

Notes

  • No agent brief was written for this issue — implementation derived from triage analysis
  • The GUI's always_first_tags field uses add_pre_postfix (not --always_first_tags); this pre-existing behavior is unchanged

Closes #3491

google-labs-jules Bot and others added 30 commits June 23, 2025 00:23
Removed all usage of the `easygui` library.

- Replaced `easygui.msgbox` calls with Gradio notifications (`gr.Info`, `gr.Warning`, `gr.Error`) to display messages and errors directly in the UI.
- Replaced `easygui.ynbox` and `easygui.boolbox` confirmation dialogs with a default action of proceeding with the operation, accompanied by a notification. This affects:
    - Model saving: Will now overwrite existing models by default, notifying the user.
    - Dataset balancing: Enabling 'insecure folder renaming' will proceed without a second confirmation, with a warning displayed.
    - Manual captioning: Importing tags will overwrite existing quick tags by default, with a notification.
- Removed `easygui` from all Python import statements.
- Removed `easygui` from `requirements.txt` and `pyproject.toml`.

Note: The `uv.lock` file has not been modified as part of this commit. It should be regenerated using the `uv` tool to reflect the dependency changes in `pyproject.toml` and `requirements.txt`.
Centralize version information by reading it from the `[project.version]`
field in `pyproject.toml` instead of the separate `.release` file.

Changes:
- Modified `kohya_gui.py` to use the `toml` library to parse `pyproject.toml`
  and retrieve the version string.
- Added a "v" prefix to the version for display consistency.
- Included a fallback to "vUNKNOWN" if `pyproject.toml` is missing or the
  version cannot be read.
- Deleted the now-unused `.release` file.

Note: Full runtime testing was prevented by an out-of-disk-space error
in the test environment when installing dependencies. The core code change
for version sourcing has been implemented as requested.
Refactor: Read version from pyproject.toml
Refactor: Remove easygui and replace dialogs with notifications
* Aligned config.toml with gradio elements

* Align Gradio UI elements with config.toml

Ensured that all relevant Gradio UI elements in Dreambooth, Finetune,
LoRA, and Textual Inversion GUIs, along with their supporting classes,
load their default values from `config.toml`.

- Added missing keys to `config example.toml` for newly configurable elements.
- Modified Python files to use `config.get()` for these elements,
  preserving original default behaviors if keys are not in `config.toml`.
- Corrected minor inconsistencies in existing `config.get()` usage.

* Update alignment

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
- Added and updated comments for better understanding of parameters.
- Improved formatting and alignment for readability.
- Corrected misleading comments regarding `cpu_offload_checkpointing` and the purpose of the final `[dataset_preparation]` section.
- Ensured all key names and TOML structure used by the GUI remain unchanged.

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Bumps [crate-ci/typos](https://github.com/crate-ci/typos) from 1.32.0 to 1.34.0.
- [Release notes](https://github.com/crate-ci/typos/releases)
- [Changelog](https://github.com/crate-ci/typos/blob/master/CHANGELOG.md)
- [Commits](crate-ci/typos@v1.32.0...v1.34.0)

---
updated-dependencies:
- dependency-name: crate-ci/typos
  dependency-version: 1.34.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: bmaltais <bernard@ducourier.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
The `libsycl.so.7` error was caused by an incompatibility with the installed oneAPI version. This commit updates the following packages to their latest versions to resolve the issue:
- intel-extension-for-tensorflow[xpu]
- mkl
- mkl-dpcpp
- oneccl-devel
- impi-devel

Co-authored-by: bmaltais <bernard@ducourier.com>
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
* docs: Add documentation for allowed_paths

This change adds documentation for the `allowed_paths` config option to the `README.md` file.

* docs: Add server section to config example

This change adds the `[server]` section to the `config example.toml` file, including the `allowed_paths` option.

---------

Co-authored-by: bmaltais <bernard@ducourier.com>
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: bmaltais <bernard@ducourier.com>
* Fix(tensorboard): Add cross-platform AVX check

I replaced the Linux-specific AVX check with a cross-platform solution using the `py-cpuinfo` library. This ensures that the TensorBoard feature is only enabled on systems with AVX support, regardless of the operating system.

The new implementation provides a more robust solution that prevents crashes on incompatible hardware while maintaining a consistent user experience across different platforms.

* Update pyproject

---------

Co-authored-by: bmaltais <bernard@ducourier.com>
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
* feat: Apply Gradio GUI improvements to manual_caption_gui.py

This commit applies the same Gradio GUI improvements that were done in `kintext_manual_caption_gui.py` to `manual_caption_gui.py`.

The changes include:
- Better user feedback for status updates.
- Safer return values from functions to avoid clearing user input on errors.
- A more organized layout with better-labeled components.
- Clearer pagination controls.

* refactor: Align manual_caption_gui.py with new standards

This commit refactors the `manual_caption_gui.py` file to align with the new standards set by the `kontext_manual_caption_gui.py` file.

The changes include:
- Performance and Efficiency: Use of `os.path.basename`, `os.scandir`, and `gr.State` to improve performance.
- Code Quality and Readability: Case-insensitive tag matching, sorted tags, and improved variable names.
- UI and User Experience: Refined UI layout, consolidated pagination logic, and improved error handling.

* fix: Correct pagination display issue

This commit fixes a bug in the pagination logic that was causing the incorrect page count to be displayed. The `page.change` event handler has been updated to correctly update the `page_count` component when the page number or the total number of pages changes.

* fix: Correct pagination and resolve ValueError

This commit fixes a bug in the pagination logic that was causing the incorrect page count to be displayed. The `page.change` event handler has been updated to correctly update the `page_count` component when the page number or the total number of pages changes.

This commit also resolves a `ValueError` that was occurring in the `render_pagination_with_logic` function. The `page.change` event handler has been updated to return a tuple of two `gr.Text` components, which resolves the error.

* fix: Correct pagination on initial load

This commit fixes a bug where the pagination would not display the correct number of pages on the initial load. A `max_page.change` event handler has been added to both `manual_caption_gui.py` and `kontext_manual_caption_gui.py` to ensure the page count is updated correctly.

* Update gui layout

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
* feat: Suggest target folder in kontext manual caption GUI

* feat: Suggest target folder in kontext manual caption GUI

- The suggested path for the target folder is now the full path.
- The target folder is only updated if it's empty.

* feat: Suggest target folder in kontext manual caption GUI

- The suggested path for the target folder is now the full path.
- The target folder is only updated if it's empty.

* feat: Suggest target folder in kontext manual caption GUI

- The suggested path for the target folder is now the full path.
- The target folder is only updated if it's empty.
- The logic for deriving the target folder has been updated.

* feat: Suggest target folder in kontext manual caption GUI

- The suggested path for the target folder is now the full path.
- The target folder is only updated if it's empty.
- The logic for deriving the target folder has been updated.
- Tags are now automatically imported from captions when images are loaded.

* Sort tags

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
* feat: Add Flux manual captioning GUI

* This looks good. I have corrected the output values for `update_images` in the Flux captioning GUI.

* feat: Add Kontext manual captioning GUI

* Swap control and target position

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
* fix pagitation

* fix pagitation, fix page numbering
* feat: Update gui-uv.sh for Colab parity and add local scripts

This commit introduces changes to align the local setup via `gui-uv.sh`
more closely with the procedures in the reference Colab notebook,
particularly concerning `bitsandbytes` compilation.

Changes:
- Added `kohya_ss_colab.ipynb` to the repository for reference.
- Created `local_train.py`, a Python script adapted from the Colab
  notebook, providing an alternative setup and launch method.
- Modified `gui-uv.sh` to include a documented, optional section
  for users to build `bitsandbytes` from source if the `uv`-installed
  version is insufficient. This enhances flexibility and aids in
  troubleshooting CUDA/GPU-specific issues.

The primary goal is to make the local experience with `gui-uv.sh`
more robust and provide users with options similar to the Colab
environment's setup for critical dependencies like `bitsandbytes`.

* Update collab

* Update colab script

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: bmaltais <bernard@ducourier.com>
This commit adds the ability to delete a pair of images and their corresponding caption file from the kontext manual captioning tool.

A "Delete" button has been added to the UI for each image pair. When clicked, this button triggers the deletion of the control image, the target image, and the caption file. The UI is then refreshed to reflect the changes.

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
* upgraded the versions of some dependencies

* added onnxruntime to requirements_linux_ipex.txt

* upgraded the versions of torch and torchvision

* downgraded the torch version to match the official image
Bumps [crate-ci/typos](https://github.com/crate-ci/typos) from 1.32.0 to 1.34.0.
- [Release notes](https://github.com/crate-ci/typos/releases)
- [Changelog](https://github.com/crate-ci/typos/blob/master/CHANGELOG.md)
- [Commits](crate-ci/typos@v1.32.0...v1.34.0)

---
updated-dependencies:
- dependency-name: crate-ci/typos
  dependency-version: 1.34.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: bmaltais <bernard@ducourier.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 8, 2026 01:57
Copy link
Copy Markdown

@github-advanced-security github-advanced-security AI left a comment

Choose a reason for hiding this comment

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

CodeQL found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.

Adds a "Sort tags by confidence" checkbox to the WD14 Captioning tab.
When enabled, the --sort_tags_by_confidence flag is passed to the
tagger script, which sorts general and character tags by their
probability score (highest first) before writing the caption file.

This matches the tag ordering produced by the WaifuDiffusion online
tagger, where high-confidence subjects (2girls, 1boy, etc.) naturally
appear first.

Default is unchecked, preserving existing CSV-index ordering behavior.

Closes #3491
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a WD14 Captioning GUI option to sort output tags by model confidence (to match WaifuDiffusion’s online tagger ordering), and also includes several additional changes across captioning utilities, server launch configuration, TensorBoard detection, docs, and dependency/config updates.

Changes:

  • Add a “Sort tags by confidence” checkbox to the WD14 captioning tab and forward it as a CLI flag.
  • Add Gradio server allowed_paths support via config.toml, and document it.
  • Refactor manual captioning UI and add a new “Kontext Manual Captioning” tab, plus related dependency/tests/scripts updates.

Reviewed changes

Copilot reviewed 19 out of 21 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
uv.lock Adds py-cpuinfo to the locked dependency set.
requirements.txt Adds py-cpuinfo dependency.
requirements_macos_arm64.txt Adjusts pip options / removes an entry to align macOS ARM requirements.
requirements_linux_ipex.txt Updates IPEX/XPU package pins and indexes.
README.md Updates docs links/TOC and documents allowed_paths under “Server Options”.
pyproject.toml Adds py-cpuinfo dependency.
local_train.py Adds a local training/setup helper script.
kohya_ss_colab.ipynb Adds a Colab notebook for launching via gui-uv.sh.
kohya_gui/wd14_caption_gui.py Adds the “sort by confidence” checkbox and forwards --sort_tags_by_confidence.
kohya_gui/utilities.py Registers the new “Kontext Manual Captioning” tab in Utilities → Captioning.
kohya_gui/manual_caption_gui.py Refactors manual captioning UI/state handling and import logic.
kohya_gui/kontext_manual_caption_gui.py Adds a new manual captioning workflow for paired control/target images.
kohya_gui/class_tensorboard.py Changes TensorBoard visibility detection to depend on tensorboard binary + AVX CPU support.
kohya_gui/class_gui_config.py Adds allowed_paths config extraction and stores it on the config object.
kohya_gui.py Passes allowed_paths into gradio.Blocks.launch().
gui-uv.sh Adds commented guidance for optional bitsandbytes source builds.
config example.toml Documents new [server].allowed_paths configuration key.
tests/test_tensorboard_visibility.py Adds unit tests for TensorBoard visibility/AVX detection logic.
test/test_allowed_paths.py Adds an integration-style test attempting to validate allowed_paths.
.github/workflows/typos.yaml Bumps crate-ci/typos GitHub Action version.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 113 to 121
if use_rating_tags:
run_cmd.append("--use_rating_tags")
if use_rating_tags_as_last_tag:
run_cmd.append("--use_rating_tags_as_last_tag")
if sort_tags_by_confidence:
run_cmd.append("--sort_tags_by_confidence")

# Add the directory containing the training data
run_cmd.append(rf"{train_data_dir}")
Comment on lines 99 to 106
@@ -100,7 +105,7 @@ def update_image_tags(
]
caption = ", ".join(output_tags)
Comment on lines +183 to 185
empty_row = gr.Row(visible=False)
return [empty_row] * (IMAGES_TO_SHOW * 4 + 2)

Comment on lines +151 to +154
selected_tags_set = set(selected_tags)

output_tags = [t for t in quick_tags if t in selected_tags_set] + [
t for t in selected_tags if t not in quick_tags_set
Comment on lines +288 to +291
# Return empty updates if state is not ready
empty_row = gr.Row(visible=False)
return [empty_row] * (IMAGES_TO_SHOW * 5 + 2)

Comment on lines +5 to +31
# Since we are modifying an existing file, we need to reload it
import kohya_gui.class_tensorboard
importlib.reload(kohya_gui.class_tensorboard)

class TestTensorboardVisibility(unittest.TestCase):

@patch('shutil.which', return_value='/usr/bin/tensorboard')
@patch('cpuinfo.get_cpu_info', return_value={'flags': ['avx']})
def test_tensorboard_visibility_when_tensorboard_and_avx_are_present(self, mock_cpuinfo, mock_which):
importlib.reload(kohya_gui.class_tensorboard)
self.assertTrue(kohya_gui.class_tensorboard.visibility)

@patch('shutil.which', return_value=None)
@patch('cpuinfo.get_cpu_info', return_value={'flags': ['avx']})
def test_tensorboard_visibility_when_tensorboard_is_absent(self, mock_cpuinfo, mock_which):
importlib.reload(kohya_gui.class_tensorboard)
self.assertFalse(kohya_gui.class_tensorboard.visibility)

@patch('shutil.which', return_value='/usr/bin/tensorboard')
@patch('cpuinfo.get_cpu_info', return_value={'flags': ['sse']})
def test_tensorboard_visibility_when_avx_is_absent(self, mock_cpuinfo, mock_which):
importlib.reload(kohya_gui.class_tensorboard)
self.assertFalse(kohya_gui.class_tensorboard.visibility)

@patch('cpuinfo.get_cpu_info', side_effect=Exception)
def test_check_avx_support_exception(self, mock_cpuinfo):
self.assertFalse(kohya_gui.class_tensorboard.check_avx_support())
Comment on lines +29 to +56
def test_allowed_paths(self):
print("Running test_allowed_paths...")
# Run the gui with the new config and check if it can access the dummy file
process = subprocess.Popen(
[
"python",
"kohya_gui.py",
"--config",
str(self.config_file),
"--headless",
],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)

print("Process started.")
# Give the server some time to start
try:
stdout, stderr = process.communicate(timeout=10)
except subprocess.TimeoutExpired:
process.kill()
stdout, stderr = process.communicate()

print(f"Stdout: {stdout.decode()}")
print(f"Stderr: {stderr.decode()}")
# Check if there are any errors in the stderr
self.assertNotIn("InvalidPathError", stderr.decode())
print("Test complete.")
Comment thread kohya_ss_colab.ipynb
"id": "view-in-github"
},
"source": [
"[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/bmaltais/kohya_ss/blob/feature/update-gui-uv-for-colab-parity/kohya_ss_colab.ipynb)"
Comment thread local_train.py
Comment on lines +4 to +12
def run_command(command):
"""Runs a shell command and prints its output."""
print(f"Running command: {command}")
process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
for line in process.stdout:
print(line, end="")
process.wait()
if process.returncode != 0:
raise Exception(f"Command failed with return code {process.returncode}: {command}")
Comment on lines 223 to +260
# Gradio UI
def gradio_manual_caption_gui_tab(headless=False, default_images_dir=None):
from .common_gui import create_refresh_button

default_images_dir = (
default_images_dir
if default_images_dir is not None
else os.path.join(scriptdir, "data")
)
current_images_dir = default_images_dir
default_images_dir = default_images_dir or os.path.join(scriptdir, "data")

def update_dir_list(path):
return gr.Dropdown(choices=[""] + list(list_dirs(path)))

# Function to list directories
def list_images_dirs(path):
# Allows list_images_dirs to modify current_images_dir outside of this function
nonlocal current_images_dir
current_images_dir = path
return list(list_dirs(path))
def render_pagination_with_logic(page, max_page):
with gr.Row(visible=False) as pagination_row:
gr.Button("◀ Prev").click(paginate, inputs=[page, max_page, gr.Number(-1, visible=False)], outputs=[page])
page_count = gr.Text("Page 1 / 1", show_label=False, interactive=False, text_align="center")
page_goto_text = gr.Textbox(show_label=False, placeholder="Go to page...", container=False, scale=1)
gr.Button("Next ▶").click(paginate, inputs=[page, max_page, gr.Number(1, visible=False)], outputs=[page])
page_goto_text.submit(paginate_go, inputs=[page_goto_text, max_page], outputs=[page])
return pagination_row, page_count

with gr.Tab("Manual Captioning"):
gr.Markdown("This utility allows quick captioning and tagging of images.")
page = gr.Number(value=-1, visible=False)

image_files_state = gr.State([])

info_box = gr.Markdown(visible=False)
page = gr.State(value=1)
max_page = gr.Number(value=1, visible=False)
loaded_images_dir = gr.Text(visible=False)
with gr.Group(), gr.Row():
images_dir = gr.Dropdown(
label="Image folder to caption (containing the images to caption)",
choices=[""] + list_images_dirs(default_images_dir),
value="",
interactive=True,
allow_custom_value=True,
)
create_refresh_button(
images_dir,
lambda: None,
lambda: {"choices": list_images_dirs(current_images_dir)},
"open_folder_small",
)
folder_button = gr.Button(
"📂",
elem_id="open_folder_small",
elem_classes=["tool"],
visible=(not headless),
)
folder_button.click(
get_folder_path,
outputs=images_dir,
show_progress=False,
)
load_images_button = gr.Button("Load", elem_id="open_folder")
caption_ext = gr.Dropdown(
label="Caption file extension",
choices=[".cap", ".caption", ".txt"],
value=".txt",
interactive=True,
allow_custom_value=True,
)
auto_save = gr.Checkbox(
label="Autosave", info="Options", value=True, interactive=True
)

images_dir.change(
fn=lambda path: gr.Dropdown(choices=[""] + list_images_dirs(path)),
inputs=images_dir,
outputs=images_dir,
show_progress=False,
)

# Caption Section
with gr.Group(), gr.Row():
quick_tags_text = gr.Textbox(
label="Quick Tags",
placeholder="Comma separated list of tags",
interactive=True,
)
import_tags_button = gr.Button("Import", elem_id="open_folder")
ignore_load_tags_word_count = gr.Slider(
minimum=1,
maximum=100,
value=3,
step=1,
label="Ignore Imported Tags Above Word Count",
interactive=True,
)

# Next/Prev section generator
def render_pagination():
gr.Button("< Prev", elem_id="open_folder").click(
paginate,
inputs=[page, max_page, gr.Number(value=-1, visible=False)],
outputs=[page],
)
page_count = gr.Label("Page 1", label="Page")
page_goto_text = gr.Textbox(
label="Goto page",
placeholder="Page Number",
interactive=True,
)
gr.Button("Go >", elem_id="open_folder").click(
paginate_go,
inputs=[page_goto_text, max_page],
outputs=[page],
)
gr.Button("Next >", elem_id="open_folder").click(
paginate,
inputs=[page, max_page, gr.Number(value=1, visible=False)],
outputs=[page],
)
return page_count

with gr.Row(visible=False) as pagination_row1:
page_count1 = render_pagination()

# Images section
image_rows = []
image_files = []
image_images = []
image_caption_texts = []
image_tag_checks = []
save_buttons = []
for _ in range(IMAGES_TO_SHOW):

with gr.Group():
with gr.Row():
images_dir = gr.Dropdown(label="Image folder to caption", choices=[""] + list(list_dirs(default_images_dir)), value="", interactive=True, allow_custom_value=True)
create_refresh_button(images_dir, lambda: None, lambda: {"choices": list(list_dirs(images_dir.value or default_images_dir))}, "open_folder_small")
gr.Button("📂", elem_id="open_folder_small", elem_classes=["tool"], visible=not headless).click(get_folder_path, outputs=images_dir, show_progress=False)


with gr.Row():
caption_ext = gr.Dropdown(label="Caption file extension", choices=[".cap", ".caption", ".txt"], value=".txt", interactive=True, allow_custom_value=True)
auto_save = gr.Checkbox(label="Autosave", value=True, interactive=True)
@bmaltais
Copy link
Copy Markdown
Owner Author

bmaltais commented May 8, 2026

Closing — the GUI change alone is insufficient since the --sort_tags_by_confidence flag doesn't exist in sd-scripts yet. The required backend and GUI code is documented here for reference if this is picked up in sd-scripts in the future.

@bmaltais bmaltais closed this May 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Sorting Weight of WD14 Captioning

9 participants