ui_edit_user_metadata.py 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. import html
  2. import json
  3. import random
  4. import gradio as gr
  5. import re
  6. from modules import ui_extra_networks_user_metadata
  7. def is_non_comma_tagset(tags):
  8. average_tag_length = sum(len(x) for x in tags.keys()) / len(tags)
  9. return average_tag_length >= 16
  10. re_word = re.compile(r"[-_\w']+")
  11. re_comma = re.compile(r" *, *")
  12. def build_tags(metadata):
  13. tags = {}
  14. for _, tags_dict in metadata.get("ss_tag_frequency", {}).items():
  15. for tag, tag_count in tags_dict.items():
  16. tag = tag.strip()
  17. tags[tag] = tags.get(tag, 0) + int(tag_count)
  18. if tags and is_non_comma_tagset(tags):
  19. new_tags = {}
  20. for text, text_count in tags.items():
  21. for word in re.findall(re_word, text):
  22. if len(word) < 3:
  23. continue
  24. new_tags[word] = new_tags.get(word, 0) + text_count
  25. tags = new_tags
  26. ordered_tags = sorted(tags.keys(), key=tags.get, reverse=True)
  27. return [(tag, tags[tag]) for tag in ordered_tags]
  28. class LoraUserMetadataEditor(ui_extra_networks_user_metadata.UserMetadataEditor):
  29. def __init__(self, ui, tabname, page):
  30. super().__init__(ui, tabname, page)
  31. self.taginfo = None
  32. self.edit_activation_text = None
  33. self.slider_preferred_weight = None
  34. self.edit_notes = None
  35. def save_lora_user_metadata(self, name, desc, activation_text, preferred_weight, notes):
  36. user_metadata = self.get_user_metadata(name)
  37. user_metadata["description"] = desc
  38. user_metadata["activation text"] = activation_text
  39. user_metadata["preferred weight"] = preferred_weight
  40. user_metadata["notes"] = notes
  41. self.write_user_metadata(name, user_metadata)
  42. def get_metadata_table(self, name):
  43. table = super().get_metadata_table(name)
  44. item = self.page.items.get(name, {})
  45. metadata = json.loads(item.get("metadata") or '{}')
  46. keys = [
  47. ('ss_sd_model_name', "Model:"),
  48. ('ss_resolution', "Resolution:"),
  49. ('ss_clip_skip', "Clip skip:"),
  50. ]
  51. for key, label in keys:
  52. value = metadata.get(key, None)
  53. if value is not None and str(value) != "None":
  54. table.append((label, html.escape(value)))
  55. image_count = 0
  56. for _, params in metadata.get("ss_dataset_dirs", {}).items():
  57. image_count += int(params.get("img_count", 0))
  58. if image_count:
  59. table.append(("Dataset size:", image_count))
  60. return table
  61. def put_values_into_components(self, name):
  62. user_metadata = self.get_user_metadata(name)
  63. values = super().put_values_into_components(name)
  64. item = self.page.items.get(name, {})
  65. metadata = json.loads(item.get("metadata") or '{}')
  66. tags = build_tags(metadata)
  67. gradio_tags = [(tag, str(count)) for tag, count in tags[0:24]]
  68. return [
  69. *values[0:4],
  70. gr.HighlightedText.update(value=gradio_tags, visible=True if tags else False),
  71. user_metadata.get('activation text', ''),
  72. float(user_metadata.get('preferred weight', 0.0)),
  73. user_metadata.get('notes', ''),
  74. gr.update(visible=True if tags else False),
  75. gr.update(value=self.generate_random_prompt_from_tags(tags), visible=True if tags else False),
  76. ]
  77. def generate_random_prompt(self, name):
  78. item = self.page.items.get(name, {})
  79. metadata = json.loads(item.get("metadata") or '{}')
  80. tags = build_tags(metadata)
  81. return self.generate_random_prompt_from_tags(tags)
  82. def generate_random_prompt_from_tags(self, tags):
  83. max_count = None
  84. res = []
  85. for tag, count in tags:
  86. if not max_count:
  87. max_count = count
  88. v = random.random() * max_count
  89. if count > v:
  90. res.append(tag)
  91. return ", ".join(sorted(res))
  92. def create_editor(self):
  93. self.create_default_editor_elems()
  94. self.taginfo = gr.HighlightedText(label="Tags")
  95. self.edit_activation_text = gr.Text(label='Activation text', info="Will be added to prompt along with Lora")
  96. self.slider_preferred_weight = gr.Slider(label='Preferred weight', info="Set to 0 to disable", minimum=0.0, maximum=2.0, step=0.01)
  97. with gr.Row() as row_random_prompt:
  98. with gr.Column(scale=8):
  99. random_prompt = gr.Textbox(label='Random prompt', lines=4, max_lines=4, interactive=False)
  100. with gr.Column(scale=1, min_width=120):
  101. generate_random_prompt = gr.Button('Generate').style(full_width=True, size="lg")
  102. self.edit_notes = gr.TextArea(label='Notes', lines=4)
  103. generate_random_prompt.click(fn=self.generate_random_prompt, inputs=[self.edit_name_input], outputs=[random_prompt])
  104. def select_tag(activation_text, evt: gr.SelectData):
  105. tag = evt.value[0]
  106. words = re.split(re_comma, activation_text)
  107. if tag in words:
  108. words = [x for x in words if x != tag and x.strip()]
  109. return ", ".join(words)
  110. return activation_text + ", " + tag if activation_text else tag
  111. self.taginfo.select(fn=select_tag, inputs=[self.edit_activation_text], outputs=[self.edit_activation_text], show_progress=False)
  112. self.create_default_buttons()
  113. viewed_components = [
  114. self.edit_name,
  115. self.edit_description,
  116. self.html_filedata,
  117. self.html_preview,
  118. self.taginfo,
  119. self.edit_activation_text,
  120. self.slider_preferred_weight,
  121. self.edit_notes,
  122. row_random_prompt,
  123. random_prompt,
  124. ]
  125. self.button_edit\
  126. .click(fn=self.put_values_into_components, inputs=[self.edit_name_input], outputs=viewed_components)\
  127. .then(fn=lambda: gr.update(visible=True), inputs=[], outputs=[self.box])
  128. edited_components = [
  129. self.edit_description,
  130. self.edit_activation_text,
  131. self.slider_preferred_weight,
  132. self.edit_notes,
  133. ]
  134. self.button_save\
  135. .click(fn=self.save_lora_user_metadata, inputs=[self.edit_name_input, *edited_components], outputs=[]) \
  136. .then(fn=None, _js="extraNetworksReloadAll")