Spaces:
Running
Running
Upload 6 files
Browse files- app.py +5 -9
- modules/booru.py +3 -8
- modules/classifyTags.py +156 -190
- modules/florence2.py +89 -96
- modules/tag_enhancer.py +52 -52
app.py
CHANGED
@@ -1,16 +1,14 @@
|
|
1 |
-
import os
|
2 |
-
import io,copy,requests,spaces,gradio as gr,numpy as np
|
3 |
-
from PIL import Image, ImageOps
|
4 |
import argparse,huggingface_hub,onnxruntime as rt,pandas as pd,traceback,tempfile,zipfile,re,ast,time
|
5 |
from datetime import datetime,timezone
|
6 |
from collections import defaultdict
|
|
|
|
|
7 |
from apscheduler.schedulers.background import BackgroundScheduler
|
8 |
-
import json
|
9 |
from modules.classifyTags import classify_tags,process_tags
|
10 |
-
from modules.florence2 import process_image,single_task_list,update_task_dropdown
|
11 |
from modules.reorganizer_model import reorganizer_list,reorganizer_class
|
12 |
from modules.tag_enhancer import prompt_enhancer
|
13 |
-
from modules.
|
14 |
|
15 |
os.environ['PYTORCH_ENABLE_MPS_FALLBACK']='1'
|
16 |
|
@@ -24,9 +22,7 @@ Multi-Tagger is a versatile application for advanced image analysis and captioni
|
|
24 |
- **Batch Support**: Upload and process multiple images simultaneously.
|
25 |
- **Downloadable Output**: Get almost all results as downloadable `.txt`, `.json`, and `.png` files in a `.zip` archive.
|
26 |
- **Image Fetcher**: Search for images from **Gelbooru** using flexible tag filters.
|
27 |
-
- CUDA
|
28 |
-
|
29 |
-
Example image by [me](https://huggingface.co/Werli).
|
30 |
"""
|
31 |
|
32 |
# Dataset v3 series of models:
|
|
|
1 |
+
import os,io,copy,json,requests,spaces,gradio as gr,numpy as np
|
|
|
|
|
2 |
import argparse,huggingface_hub,onnxruntime as rt,pandas as pd,traceback,tempfile,zipfile,re,ast,time
|
3 |
from datetime import datetime,timezone
|
4 |
from collections import defaultdict
|
5 |
+
from PIL import Image,ImageOps
|
6 |
+
from modules.booru import gelbooru_gradio,fetch_gelbooru_images,on_select
|
7 |
from apscheduler.schedulers.background import BackgroundScheduler
|
|
|
8 |
from modules.classifyTags import classify_tags,process_tags
|
|
|
9 |
from modules.reorganizer_model import reorganizer_list,reorganizer_class
|
10 |
from modules.tag_enhancer import prompt_enhancer
|
11 |
+
from modules.florence2 import process_image,single_task_list,update_task_dropdown
|
12 |
|
13 |
os.environ['PYTORCH_ENABLE_MPS_FALLBACK']='1'
|
14 |
|
|
|
22 |
- **Batch Support**: Upload and process multiple images simultaneously.
|
23 |
- **Downloadable Output**: Get almost all results as downloadable `.txt`, `.json`, and `.png` files in a `.zip` archive.
|
24 |
- **Image Fetcher**: Search for images from **Gelbooru** using flexible tag filters.
|
25 |
+
- **CUDA** and **CPU** support.
|
|
|
|
|
26 |
"""
|
27 |
|
28 |
# Dataset v3 series of models:
|
modules/booru.py
CHANGED
@@ -1,11 +1,6 @@
|
|
1 |
-
import requests
|
2 |
-
import
|
3 |
-
import
|
4 |
-
import io
|
5 |
-
import numpy as np
|
6 |
-
from PIL import Image, ImageOps
|
7 |
-
import torch
|
8 |
-
import gradio as gr
|
9 |
|
10 |
# Helper to load image from URL
|
11 |
def loadImageFromUrl(url):
|
|
|
1 |
+
import requests,re,base64,io,numpy as np
|
2 |
+
from PIL import Image,ImageOps
|
3 |
+
import torch,gradio as gr
|
|
|
|
|
|
|
|
|
|
|
4 |
|
5 |
# Helper to load image from URL
|
6 |
def loadImageFromUrl(url):
|
modules/classifyTags.py
CHANGED
@@ -1,191 +1,157 @@
|
|
1 |
-
from collections import defaultdict
|
2 |
-
import re
|
3 |
-
# Define grouping rules (categories and keywords)
|
4 |
-
# Provided categories and reversed_categories
|
5 |
-
categories
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
#
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
print(f"{unclassified_tags[:200]}") # Display some unclassified tags
|
158 |
-
|
159 |
-
return classified_tags, unclassified_tags
|
160 |
-
|
161 |
-
# Code for "Tag Categorizer" tab
|
162 |
-
def process_tags(input_tags: str):
|
163 |
-
# Split tags using regex to handle both commas and question marks
|
164 |
-
tags = []
|
165 |
-
for tag in re.split(r'\?|,|\n', input_tags):
|
166 |
-
tag = tag.strip()
|
167 |
-
if tag:
|
168 |
-
# Remove numbers at the end of tags
|
169 |
-
tag = re.sub(r'\b\d+\b', '', tag).strip()
|
170 |
-
|
171 |
-
# Replace underscores with spaces
|
172 |
-
tag = tag.replace('_', ' ')
|
173 |
-
|
174 |
-
# Escape parentheses (handle both escaped and unescaped)
|
175 |
-
if '(' in tag or ')' in tag:
|
176 |
-
# First, replace existing backslashes to handle properly
|
177 |
-
tag = tag.replace('\\', '')
|
178 |
-
# Replace parentheses with escaped versions
|
179 |
-
tag = tag.replace('(', r'\(').replace(')', r'\)')
|
180 |
-
|
181 |
-
if tag: # Only add if tag is not empty after processing
|
182 |
-
tags.append(tag)
|
183 |
-
|
184 |
-
# Classify the cleaned tags
|
185 |
-
classified_tags, unclassified_tags = classify_tags(tags)
|
186 |
-
|
187 |
-
# Create the outputs
|
188 |
-
categorized_string = ', '.join([tag for category in classified_tags.values() for tag in category])
|
189 |
-
categorized_json = {category: tags for category, tags in classified_tags.items()}
|
190 |
-
|
191 |
return categorized_string, categorized_json, "" # Initialize enhanced_prompt as empty
|
|
|
1 |
+
from collections import defaultdict
|
2 |
+
import re
|
3 |
+
# Define grouping rules (categories and keywords)
|
4 |
+
# Provided categories and reversed_categories
|
5 |
+
categories={
|
6 |
+
'Explicit':['sex', '69', 'paizuri', 'cum', 'precum', 'areola_slip', 'hetero', 'erection', 'oral', 'fellatio', 'yaoi', 'ejaculation', 'ejaculating', 'masturbation', 'handjob', 'bulge', 'rape', '_rape', 'doggystyle', 'threesome', 'missionary', 'object_insertion', 'nipple', 'nipples', 'pussy', 'anus', 'penis', 'groin', 'testicles', 'testicle', 'anal', 'cameltoe', 'areolae', 'dildo', 'clitoris', 'top-down_bottom-up', 'gag', 'groping', 'gagged', 'gangbang', 'orgasm', 'femdom', 'incest', 'bukkake', 'breast_out', 'vaginal', 'vagina', 'public_indecency', 'breast_sucking', 'folded', 'cunnilingus', '_cunnilingus', 'foreskin', 'bestiality', 'footjob', 'uterus', 'womb', 'flaccid', 'defloration', 'butt_plug', 'cowgirl_position', 'reverse_cowgirl_position', 'squatting_cowgirl_position', 'reverse_upright_straddle', 'irrumatio', 'deepthroat', 'pokephilia', 'gaping', 'orgy', 'cleft_of_venus', 'futanari', 'futasub', 'futa', 'cumdrip', 'fingering', 'vibrator', 'partially_visible_vulva', 'penetration', 'penetrated', 'cumshot', 'exhibitionism', 'breast_milk', 'grinding', 'clitoral', 'urethra', 'phimosis', 'cervix', 'impregnation', 'tribadism', 'molestation', 'pubic_hair', 'clothed_female_nude_male', 'clothed_male_nude_female', 'clothed_female_nude_female', 'clothed_male_nude_male', 'sex_machine', 'milking_machine', 'ovum', 'chikan', 'pussy_juice_drip_through_clothes', 'ejaculating_while_penetrated', 'suspended_congress', 'reverse_suspended_congress', 'spread_pussy_under_clothes', 'anilingus', 'reach-around', 'humping', 'consensual_tentacles', 'tentacle_pit', 'cum_in_'],
|
7 |
+
'Appearance Status':['backless', 'bandaged_neck', 'bleeding', 'blood', '_blood', 'blush', 'body_writing', 'bodypaint', 'bottomless', 'breath', 'bruise', 'butt_crack', 'cold', 'covered_mouth', 'crack', 'cross-section', 'crotchless', 'crying', 'curvy', 'cuts', 'dirty', 'dripping', 'drunk', 'from_mouth', 'glowing', 'hairy', 'halterneck', 'hot', 'injury', 'latex', 'leather', 'levitation', 'lipstick_mark', '_markings', 'makeup', 'mole', 'moles', 'no_bra', 'nosebleed', 'nude', 'outfit', 'pantylines', 'peeing', 'piercing', '_piercing', 'piercings', 'pregnant', 'public_nudity', 'reverse', '_skin', '_submerged', 'saliva', 'scar', 'scratches', 'see-through', 'shadow', 'shibari', 'sideless', 'skindentation', 'sleeping', 'tan', 'soap_bubbles', 'steam', 'steaming_body', 'stitches', 'sweat', 'sweatdrop', 'sweaty', 'tanlines', 'tattoo', 'tattoo', 'tears', 'topless', 'transparent', 'trefoil', 'trembling', 'veins', 'visible_air', 'wardrobe_malfunction', 'wet', 'x-ray', 'unconscious', 'handprint'],
|
8 |
+
'Action Pose':['afloat', 'afterimage', 'against_fourth_wall', 'against_wall', 'aiming', 'all_fours',"another's_mouth",'arm_', 'arm_support', 'arms_', 'arms_behind_back', 'asphyxiation', 'attack', 'back', 'ballet', 'bara', 'bathing', 'battle', 'bdsm', 'beckoning', 'bent_over', 'bite_mark', 'biting', 'bondage', 'breast_suppress', 'breathing', 'burning', 'bust_cup', 'carry', 'carrying', 'caught', 'chained', 'cheek_squash', 'chewing', 'cigarette', 'clapping', 'closed_eye', 'come_hither', 'cooking', 'covering', 'cuddling', 'dancing', '_docking', 'destruction', 'dorsiflexion', 'dreaming', 'dressing', 'drinking', 'driving', 'dropping', 'eating', 'exercise', 'expansion', 'exposure', 'facing', 'failure', 'fallen_down', 'falling', 'feeding', 'fetal_position', 'fighting', 'finger_on_trigger', 'finger_to_cheek', 'finger_to_mouth', 'firing', 'fishing', 'flashing', 'fleeing', 'flexible', 'flexing', 'floating', 'flying', 'fourth_wall', 'freediving', 'frogtie', '_grab', 'girl_on_top', 'giving', 'grabbing', 'grabbing_', 'gymnastics', '_hold', 'hadanugi_dousa', 'hairdressing', 'hand_', 'hand_on', 'hand_on_wall', 'hands_', 'headpat', 'hiding', 'holding', 'hug', 'hugging', 'imagining', 'in_container', 'in_mouth', 'in_palm', 'jealous', 'jumping', 'kabedon', 'kicking', 'kiss', 'kissing', 'kneeling', '_lift', 'lactation', 'laundry', 'licking', 'lifted_by_self', 'looking', 'lowleg', 'lying', 'melting', 'midair', 'moaning', '_open', 'on_back', 'on_bed', 'on_ground', 'on_lap', 'on_one_knee', 'one_eye_closed', 'open_', 'over_mouth', 'own_mouth', '_peek', '_pose', '_press', '_pull', 'padding', 'paint', 'painting_(action)', 'palms_together', 'pee', 'peeking', 'pervert', 'petting', 'pigeon-toed', 'piggyback', 'pinching', 'pinky_out', 'pinned', 'plantar_flexion', 'planted', 'playing', 'pocky', 'pointing', 'poke', 'poking', 'pouring', 'pov', 'praying', 'presenting', 'profanity', 'pulled_by_self', 'pulling', 'pump_action', 'punching', '_rest', 'raised', 'reaching', 'reading', 'reclining', 'reverse_grip', 'riding', 'running', '_slip', 'salute', 'screaming', 'seiza', 'selfie', 'sewing', 'shaking', 'shoe_dangle', 'shopping', 'shouting', 'showering', 'shushing', 'singing', 'sitting', 'slapping', 'smell', 'smelling', 'smoking', 'smother', 'solo', 'spanked', 'spill', 'spilling', 'spinning', 'splashing', 'split', 'squatting', 'squeezed', 'breasts_squeezed_together', 'standing', 'standing_on_', 'staring', 'straddling', 'strangling', 'stretching', 'surfing', 'suspension', 'swimming', 'talking', 'teardrop', 'tearing_clothes', 'throwing', 'tied_up', 'tiptoes', 'toe_scrunch', 'toothbrush', 'trigger_discipline', 'tripping', 'tsundere', 'turning_head', 'twitching', 'two-handed', 'tying', '_up', 'unbuttoned', 'undressed', 'undressing', 'unsheathed', 'unsheathing', 'unzipped', 'unzipping', 'upright_straddle', 'v', 'V', 'vore', '_wielding', 'wading', 'walk-in', 'walking', 'wariza', 'waving', 'wedgie', 'wrestling', 'writing', 'yawning', 'yokozuwari', '_conscious', 'massage', 'struggling', 'shrugging', 'drugged', 'tentacles_under_clothes', 'restrained_by_tentacles', 'tentacles_around_arms', 'tentacles_around_legs', 'restrained_legs', 'restrained_tail', 'restrained_arms', 'tentacles_on_female', 'archery', 'cleaning', 'tempura', 'facepalm', 'sadism'],
|
9 |
+
'Headwear':['antennae', 'antlers', 'aura', 'bandaged_head', 'bandana', 'bandeau', 'beanie', 'beanie', 'beret', 'bespectacled', 'blindfold', 'bonnet', '_cap', 'circlet', 'crown', '_drill', '_drills', 'diadem', '_eyewear', 'ear_covers', 'ear_ornament', 'ear_tag', 'earbuds', 'earclip', 'earmuffs', 'earphones', 'earpiece', 'earring', 'earrings', 'eyeliner', 'eyepatch', 'eyewear_on_head', 'facial', 'fedora', 'glasses', 'goggles', '_headwear', 'hachimaki', 'hair_bobbles', 'hair_ornament', 'hair_rings', 'hair_tie', 'hairband', 'hairclip', 'hairpin', 'hairpods', 'halo', 'hat', 'head-mounted_display', 'head_wreath', 'headband', 'headdress', 'headgear', 'headphones', 'headpiece', 'headset', 'helm', 'helmet', 'hood', 'kabuto_(helmet)', 'kanzashi', '_mask', 'maid_headdress', 'mask', 'mask', 'mechanical_ears', 'mechanical_eye', 'mechanical_horns', 'mob_cap', 'monocle', 'neck_ruff', 'nightcap', 'on_head', 'pince-nez', 'qingdai_guanmao', 'scarf_over_mouth', 'scrunchie', 'sunglasses',"tam_o'_shanter",'tate_eboshi', 'tiara', 'topknot', 'turban', 'veil', 'visor', 'wig', 'mitre', 'tricorne', 'bicorne'],
|
10 |
+
'Handwear':['arm_warmers', 'armband', 'armlet', 'bandaged_arm', 'bandaged_fingers', 'bandaged_hand', 'bandaged_wrist', 'bangle', 'bracelet', 'bracelets', 'bracer', 'cuffs', 'elbow_pads', '_gauntlets', '_glove', '_gloves', 'gauntlets', 'gloves', 'kote', 'kurokote', 'mechanical_arm', 'mechanical_arms', 'mechanical_hands', 'mittens', 'mitts', 'nail_polish', 'prosthetic_arm', 'wrist_cuffs', 'wrist_guards', 'wristband', 'yugake'],
|
11 |
+
'One-Piece Outfit':['bodystocking', 'bodysuit', 'dress', 'furisode', 'gown', 'hanfu', 'jumpsuit', 'kimono', 'leotard', 'microdress', 'one-piece', 'overalls', 'robe', 'spacesuit', 'sundress', 'yukata'],
|
12 |
+
'Upper Body Clothing':['aiguillette', 'apron', '_apron', 'armor', '_armor', 'ascot', 'babydoll', 'bikini', '_bikini', 'blazer', '_blazer', 'blouse', '_blouse', 'bowtie', '_bowtie', 'bra', '_bra', 'breast_curtain', 'breast_curtains', 'breast_pocket', 'breastplate', 'bustier', 'camisole', 'cape', 'capelet', 'cardigan', 'center_opening', 'chemise', 'chest_jewel', 'choker', 'cloak', 'coat', 'coattails', 'collar', '_collar', 'corset', 'criss-cross_halter', 'crop_top', 'dougi', 'feather_boa', 'gakuran', 'hagoromo', 'hanten_(clothes)', 'haori', 'harem_pants', 'harness', 'hoodie', 'jacket', '_jacket', 'japanese_clothes', 'kappougi', 'kariginu', 'lapels', 'lingerie', '_lingerie', 'maid', 'mechanical_wings', 'mizu_happi', 'muneate', 'neckerchief', 'necktie', 'negligee', 'nightgown', 'pajamas', '_pajamas', 'pauldron', 'pauldrons', 'plunging_neckline', 'raincoat', 'rei_no_himo', 'sailor_collar', 'sarashi', 'scarf', 'serafuku', 'shawl', 'shirt', 'shoulder_', 'sleepwear', 'sleeve', 'sleeveless', 'sleeves', '_sleeves', 'sode', 'spaghetti_strap', 'sportswear', 'strapless', 'suit', 'sundress', 'suspenders', 'sweater', 'swimsuit', '_top', '_torso', 't-shirt', 'tabard', 'tailcoat', 'tank_top', 'tasuki', 'tie_clip', 'tunic', 'turtleneck', 'tuxedo', '_uniform', 'undershirt', 'uniform', 'v-neck', 'vambraces', 'vest', 'waistcoat'],
|
13 |
+
'Lower Body Clothing':['bare_hips', 'bloomers', 'briefs', 'buruma', 'crotch_seam', 'cutoffs', 'denim', 'faulds', 'fundoshi', 'g-string', 'garter_straps', 'hakama', 'hip_vent', 'jeans', 'knee_pads', 'loincloth', 'mechanical_tail', 'microskirt', 'miniskirt', 'overskirt', 'panties', 'pants', 'pantsu', 'panty_straps', 'pelvic_curtain', 'petticoat', 'sarong', 'shorts', 'side_slit', 'skirt', 'sweatpants', 'swim_trunks', 'thong', 'underwear', 'waist_cape'],
|
14 |
+
'Foot & Legwear':['anklet', 'bandaged_leg', 'boot', 'boots', '_footwear', 'flats', 'flip-flops', 'geta', 'greaves', '_heels', 'kneehigh', 'kneehighs', '_legwear', 'leg_warmers', 'leggings', 'loafers', 'mary_janes', 'mechanical_legs', 'okobo', 'over-kneehighs', 'pantyhose', 'prosthetic_leg', 'pumps', '_shoe', '_sock', 'sandals', 'shoes', 'skates', 'slippers', 'sneakers', 'socks', 'spikes', 'tabi', 'tengu-geta', 'thigh_strap', 'thighhighs', 'uwabaki', 'zouri', 'legband', 'ankleband'],
|
15 |
+
'Other Accessories':['alternate_', 'anklet', 'badge', 'beads', 'belt', 'belts', 'bow', 'brooch', 'buckle', 'button', 'buttons', '_clothes', '_costume', '_cutout', 'casual', 'charm', 'clothes_writing', 'clothing_aside', 'costume', 'cow_print', 'cross', 'd-pad', 'double-breasted', 'drawstring', 'epaulettes', 'fabric', 'fishnets', 'floral_print', 'formal', 'frills', '_garter', 'gem', 'holster', 'jewelry', '_knot', 'lace', 'lanyard', 'leash', 'magatama', 'mechanical_parts', 'medal', 'medallion', 'naked_bandage', 'necklace', '_ornament', '(ornament)', 'o-ring', 'obi', 'obiage', 'obijime', '_pin', '_print', 'padlock', 'patterned_clothing', 'pendant', 'piercing', 'plaid', 'pocket', 'polka_dot', 'pom_pom_(clothes)', 'pom_pom_(clothes)', 'pouch', 'ribbon', '_ribbon', '_stripe', '_stripes', 'sash', 'shackles', 'shimenawa', 'shrug_(clothing)', 'skin_tight', 'spandex', 'strap', 'sweatband', '_trim', 'tassel', 'zettai_ryouiki', 'zipper'],
|
16 |
+
'Facial Expression':['ahegao', 'anger_vein', 'angry', 'annoyed', 'confused', 'drooling', 'embarrassed', 'expressionless', 'eye_contact', '_face', 'frown', 'fucked_silly', 'furrowed_brow', 'glaring', 'gloom_(expression)', 'grimace', 'grin', 'happy', 'jitome', 'laughing', '_mouth', 'nervous', 'notice_lines', 'o_o', 'parted_lips', 'pout', 'puff_of_air', 'restrained', 'sad', 'sanpaku', 'scared', 'scowl', 'serious', 'shaded_face', 'shy', 'sigh', 'sleepy', 'smile', 'smirk', 'smug', 'snot', 'spoken_ellipsis', 'spoken_exclamation_mark', 'spoken_interrobang', 'spoken_question_mark', 'squiggle', 'surprised', 'tareme', 'tearing_up', 'thinking', 'tongue', 'tongue_out', 'torogao', 'tsurime', 'turn_pale', 'wide-eyed', 'wince', 'worried', 'heartbeat'],
|
17 |
+
'Facial Emoji':['!!', '!', '!?', '+++', '+_+', '...', '...?', '._.', '03:00', '0_0', ':/', ':3', ':<', ':>', ':>=', ':d', ':i', ':o', ':p', ':q', ':t', ':x', ':|', ';(', ';)', ';3', ';d', ';o', ';p', ';q', '=_=', '>:(', '>:)', '>_<', '>_o', '>o<', '?', '??', '@_@', '\\m/', '\n/', '\\o/', '\\||/', '^^^', '^_^', 'c:', 'd:', 'o_o', 'o3o', 'u_u', 'w', 'x', 'x_x', 'xd', 'zzz', '|_|'],
|
18 |
+
'Head':['afro', 'ahoge', 'animal_ear_fluff', '_bangs', '_bun', 'bald', 'beard', 'blunt_bangs', 'blunt_ends', 'bob_cut', 'bowl_cut', 'braid', 'braids', 'buzz_cut', 'circle_cut', 'colored_tips', 'cowlick', 'dot_nose', 'dreadlocks', '_ear', '_ears', '_eye', '_eyes', 'enpera', 'eyeball', 'eyebrow', 'eyebrow_cut', 'eyebrows', 'eyelashes', 'eyeshadow', 'faceless', 'facepaint', 'facial_mark', 'fang', 'forehead', 'freckles', 'goatee', '_hair', '_horn', '_horns', 'hair_', 'hair_bun', 'hair_flaps', 'hair_intakes', 'hair_tubes', 'half_updo', 'head_tilt', 'heterochromia', 'hime_cut', 'hime_cut', 'horns', 'in_eye', 'inverted_bob', 'kemonomimi_mode', 'lips', 'mascara', 'mohawk', 'mouth_', 'mustache', 'nose', 'one-eyed', 'one_eye', 'one_side_up', '_pupils', 'parted_bangs', 'pompadour', 'ponytail', 'ringlets', '_sclera', 'sideburns', 'sidecut', 'sidelock', 'sidelocks', 'skull', 'snout', 'stubble', 'swept_bangs', 'tails', 'teeth', 'third_eye', 'twintails', 'two_side_up', 'undercut', 'updo', 'v-shaped_eyebrows', 'whiskers', 'tentacle_hair'],
|
19 |
+
'Hands':['_arm', '_arms', 'claws', '_finger', '_fingers', 'fingernails', '_hand', '_nail', '_nails', 'palms', 'rings', 'thumbs_up'],
|
20 |
+
'Upper Body':['abs', 'armpit', 'armpits', 'backboob', 'belly', 'biceps', 'breast_rest', 'breasts', 'button_gap', 'cleavage', 'collarbone', 'dimples_of_venus', 'downblouse', 'flat_chest', 'linea_alba', 'median_furrow', 'midriff', 'nape', 'navel', 'pectorals', 'ribs', '_shoulder', '_shoulders', 'shoulder_blades', 'sideboob', 'sidetail', 'spine', 'stomach', 'strap_gap', 'toned', 'underboob', 'underbust'],
|
21 |
+
'Lower Body':['ankles', 'ass', 'barefoot', 'crotch', 'feet', 'highleg', 'hip_bones', 'hooves', 'kneepits', 'knees', 'legs', 'soles', 'tail', 'thigh_gap', 'thighlet', 'thighs', 'toenail', 'toenails', 'toes', 'wide_hips'],
|
22 |
+
'Creature':['(animal)', 'anglerfish', 'animal', 'bear', 'bee', 'bird', 'bug', 'butterfly', 'cat', 'chick', 'chicken', 'chinese_zodiac', 'clownfish', 'coral', 'crab', 'creature', 'crow', 'dog', 'dove', 'dragon', 'duck', 'eagle', 'fish', 'fish', 'fox', 'fox', 'frog', 'frog', 'goldfish', 'hamster', 'horse', 'jellyfish', 'ladybug', 'lion', 'mouse', 'octopus', 'owl', 'panda', 'penguin', 'pig', 'pigeon', 'rabbit', 'rooster', 'seagull', 'shark', 'sheep', 'shrimp', 'snail', 'snake', 'squid', 'starfish', 'tanuki', 'tentacles', 'goo_tentacles', 'plant_tentacles', 'crotch_tentacles', 'mechanical_tentacles', 'squidward_tentacles', 'suction_tentacles', 'penis_tentacles', 'translucent_tentacles', 'back_tentacles', 'red_tentacles', 'green_tentacles', 'blue_tentacles', 'black_tentacles', 'pink_tentacles', 'purple_tentacles', 'face_tentacles', 'tentacles_everywhere', 'milking_tentacles', 'tiger', 'turtle', 'weasel', 'whale', 'wolf', 'parrot', 'sparrow', 'unicorn'],
|
23 |
+
'Plant':['bamboo', 'bouquet', 'branch', 'bush', 'cherry_blossoms', 'clover', 'daisy', '(flower)', 'flower', 'flower', 'gourd', 'hibiscus', 'holly', 'hydrangea', 'leaf', 'lily_pad', 'lotus', 'moss', 'palm_leaf', 'palm_tree', 'petals', 'plant', 'plum_blossoms', 'rose', 'spider_lily', 'sunflower', 'thorns', 'tree', 'tulip', 'vines', 'wisteria', 'acorn'],
|
24 |
+
'Food':['apple', 'baguette', 'banana', 'baozi', 'beans', 'bento', 'berry', 'blueberry', 'bread', 'broccoli', 'burger', 'cabbage', 'cake', 'candy', 'carrot', 'cheese', 'cherry', 'chili_pepper', 'chocolate', 'coconut', 'cookie', 'corn', 'cream', 'crepe', 'cucumber', 'cucumber', 'cupcake', 'curry', 'dango', 'dessert', 'doughnut', 'egg', 'eggplant', '_(food)', '_(fruit)', 'food', 'french_fries', 'fruit', 'grapes', 'ice_cream', 'icing', 'lemon', 'lettuce', 'lollipop', 'macaron', 'mandarin_orange', 'meat', 'melon', 'mochi', 'mushroom', 'noodles', 'omelet', 'omurice', 'onigiri', 'onion', 'pancake', 'parfait', 'pasties', 'pastry', 'peach', 'pineapple', 'pizza', 'popsicle', 'potato', 'pudding', 'pumpkin', 'radish', 'ramen', 'raspberry', 'rice', 'roasted_sweet_potato', 'sandwich', 'sausage', 'seaweed', 'skewer', 'spitroast', 'spring_onion', 'strawberry', 'sushi', 'sweet_potato', 'sweets', 'taiyaki', 'takoyaki', 'tamagoyaki', 'tempurakanbea', 'toast', 'tomato', 'vegetable', 'wagashi', 'wagashi', 'watermelon', 'jam', 'popcorn'],
|
25 |
+
'Beverage':['alcohol', 'beer', 'coffee', 'cola', 'drink', 'juice', 'juice_box', 'milk', 'sake', 'soda', 'tea', '_tea', 'whiskey', 'wine', 'cocktail'],
|
26 |
+
'Music':['band', 'baton_(conducting)', 'beamed', 'cello', 'concert', 'drum', 'drumsticks', 'eighth_note', 'flute', 'guitar', 'harp', 'horn', '(instrument)', 'idol', 'instrument', 'k-pop', 'lyre', '(music)', 'megaphone', 'microphone', 'music', 'musical_note', 'phonograph', 'piano', 'plectrum', 'quarter_note', 'recorder', 'sixteenth_note', 'sound_effects', 'trumpet', 'utaite', 'violin', 'whistle'],
|
27 |
+
'Weapons & Equipment':['ammunition', 'arrow_(projectile)', 'axe', 'bandolier', 'baseball_bat', 'beretta_92', 'bolt_action', 'bomb', 'bullet', 'bullpup', 'cannon', 'chainsaw', 'crossbow', 'dagger', 'energy_sword', 'explosive', 'fighter_jet', 'gohei', 'grenade', 'gun', 'hammer', 'handgun', 'holstered', 'jet', 'katana', 'knife', 'kunai', 'lance', 'mallet', 'nata_(tool)', 'polearm', 'quiver', 'rapier', 'revolver', 'rifle', 'rocket_launcher', 'scabbard', 'scope', 'scythe', 'sheath', 'sheathed', 'shield', 'shotgun', 'shuriken', 'spear', 'staff', 'suppressor', 'sword', 'tank', 'tantou', 'torpedo', 'trident', '(weapon)', 'wand', 'weapon', 'whip', 'yumi_(bow)', 'h&k_hk416', 'rocket_launcher', 'heckler_&_koch', '_weapon'],
|
28 |
+
'Vehicles':['aircraft', 'airplane', 'bicycle', 'boat', 'car', 'caterpillar_tracks', 'flight_deck', 'helicopter', 'motor_vehicle', 'motorcycle', 'ship', 'spacecraft', 'spoiler_(automobile)', 'train', 'truck', 'watercraft', 'wheel', 'wheelbarrow', 'wheelchair', 'inflatable_raft'],
|
29 |
+
'Buildings':['apartment', 'aquarium', 'architecture', 'balcony', 'building', 'cafe', 'castle', 'church', 'gym', 'hallway', 'hospital', 'house', 'library', '(place)', 'porch', 'restaurant', 'restroom', 'rooftop', 'shop', 'skyscraper', 'stadium', 'stage', 'temple', 'toilet', 'tower', 'train_station', 'veranda'],
|
30 |
+
'Indoor':['bath', 'bathroom', 'bathtub', 'bed', 'bed_sheet', 'bedroom', 'blanket', 'bookshelf', 'carpet', 'ceiling', 'chair', 'chalkboard', 'classroom', 'counter', 'cupboard', 'curtains', 'cushion', 'dakimakura', 'desk', 'door', 'doorway', 'drawer', '_floor', 'floor', 'futon', 'indoors', 'interior', 'kitchen', 'kotatsu', 'locker', 'mirror', 'pillow', 'room', 'rug', 'school_desk', 'shelf', 'shouji', 'sink', 'sliding_doors', 'stairs', 'stool', 'storeroom', 'table', 'tatami', 'throne', 'window', 'windowsill', 'bathhouse', 'chest_of_drawers'],
|
31 |
+
'Outdoor':['alley', 'arch', 'beach', 'bridge', 'bus_stop', 'bush', 'cave', '(city)', 'city', 'cliff', 'crescent', 'crosswalk', 'day', 'desert', 'fence', 'ferris_wheel', 'field', 'forest', 'grass', 'graveyard', 'hill', 'lake', 'lamppost', 'moon', 'mountain', 'night', 'ocean', 'onsen', 'outdoors', 'path', 'pool', 'poolside', 'railing', 'railroad', 'river', 'road', 'rock', 'sand', 'shore', 'sky', 'smokestack', 'snow', 'snowball', 'snowman', 'street', 'sun', 'sunlight', 'sunset', 'tent', 'torii', 'town', 'tree', 'turret', 'utility_pole', 'valley', 'village', 'waterfall'],
|
32 |
+
'Objects':['anchor', 'android', 'armchair', '(bottle)', 'backpack', 'bag', 'ball', 'balloon', 'bandages', 'bandaid', 'bandaids', 'banknote', 'banner', 'barcode', 'barrel', 'baseball', 'basket', 'basketball', 'beachball', 'bell', 'bench', 'binoculars', 'board_game', 'bone', 'book', 'bottle', 'bowl', 'box', 'box_art', 'briefcase', 'broom', 'bucket', '(chess)', '(computer)', '(computing)', '(container)', 'cage', 'calligraphy_brush', 'camera', 'can', 'candle', 'candlestand', 'cane', 'card', 'cartridge', 'cellphone', 'chain', 'chandelier', 'chess', 'chess_piece', 'choko_(cup)', 'chopsticks', 'cigar', 'clipboard', 'clock', 'clothesline', 'coin', 'comb', 'computer', 'condom', 'controller', 'cosmetics', 'couch', 'cowbell', 'crazy_straw', 'cup', 'cutting_board', 'dice', 'digital_media_player', 'doll', 'drawing_tablet', 'drinking_straw', 'easel', 'electric_fan', 'emblem', 'envelope', 'eraser', 'feathers', 'figure', 'fire', 'fishing_rod', 'flag', 'flask', 'folding_fan', 'fork', 'frying_pan', '(gemstone)', 'game_console', 'gears', 'gemstone', 'gift', 'glass', 'glowstick', 'gold', 'handbag', 'handcuffs', 'handheld_game_console', 'hose', 'id_card', 'innertube', 'iphone',"jack-o'-lantern",'jar', 'joystick', 'key', 'keychain', 'kiseru', 'ladder', 'ladle', 'lamp', 'lantern', 'laptop', 'letter', 'letterboxed', 'lifebuoy', 'lipstick', 'liquid', 'lock', 'lotion', '_machine', 'map', 'marker', 'model_kit', 'money', 'monitor', 'mop', 'mug', 'needle', 'newspaper', 'nintendo', 'nintendo_switch', 'notebook', '(object)', 'ofuda', 'orb', 'origami', '(playing_card)', 'pack', 'paddle', 'paintbrush', 'pan', 'paper', 'parasol', 'patch', 'pc', 'pen', 'pencil', 'pencil', 'pendant_watch', 'phone', 'pill', 'pinwheel', 'plate', 'playstation', 'pocket_watch', 'pointer', 'poke_ball', 'pole', 'quill', 'racket', 'randoseru', 'remote_control', 'ring', 'rope', 'sack', 'saddle', 'sakazuki', 'satchel', 'saucer', 'scissors', 'scroll', 'seashell', 'seatbelt', 'shell', 'shide', 'shopping_cart', 'shovel', 'shower_head', 'silk', 'sketchbook', 'smartphone', 'soap', 'sparkler', 'spatula', 'speaker', 'spoon', 'statue', 'stethoscope', 'stick', 'sticker', 'stopwatch', 'string', 'stuffed_', 'stylus', 'suction_cups', 'suitcase', 'surfboard', 'syringe', 'talisman', 'tanzaku', 'tape', 'teacup', 'teapot', 'teddy_bear', 'television', 'test_tube', 'tiles', 'tokkuri', 'tombstone', 'torch', 'towel', 'toy', 'traffic_cone', 'tray', 'treasure_chest', 'uchiwa', 'umbrella', 'vase', 'vial', 'video_game', 'viewfinder', 'volleyball', 'wallet', 'watch', 'watch', 'whisk', 'whiteboard', 'wreath', 'wrench', 'wristwatch', 'yunomi', 'ace_of_hearts', 'inkwell', 'compass', 'ipod', 'sunscreen', 'rocket', 'cobblestone'],
|
33 |
+
'Character Design':['+boys', '+girls', '1other', '39', '_boys', '_challenge', '_connection', '_female', '_fur', '_girls', '_interface', '_male', '_man', '_person', 'abyssal_ship', 'age_difference', 'aged_down', 'aged_up', 'albino', 'alien', 'alternate_muscle_size', 'ambiguous_gender', 'amputee', 'androgynous', 'angel', 'animalization', 'ass-to-ass', 'assault_visor', 'au_ra', 'baby', 'bartender', 'beak', 'bishounen', 'borrowed_character', 'boxers', 'boy', 'breast_envy', 'breathing_fire', 'bride', 'broken', 'brother_and_sister', 'brothers', 'camouflage', 'cheating_(relationship)', 'cheerleader', 'chibi', 'child', 'clone', 'command_spell', 'comparison', 'contemporary', 'corpse', 'corruption', 'cosplay', 'couple', 'creature_and_personification', 'crossdressing', 'crossover', 'cyberpunk', 'cyborg', 'cyclops', 'damaged', 'dancer', 'danmaku', 'darkness', 'death', 'defeat', 'demon', 'disembodied_', 'draph', 'drone', 'duel', 'dwarf', 'egyptian', 'electricity', 'elezen', 'elf', 'enmaided', 'erune', 'everyone', 'evolutionary_line', 'expressions', 'fairy', 'family', 'fangs', 'fantasy', 'fashion', 'fat', 'father_and_daughter', 'father_and_son', 'fewer_digits', 'fins', 'flashback', 'fluffy', 'fumo_(doll)', 'furry', 'fusion', 'fuuin_no_tsue', 'gameplay_mechanics', 'genderswap', 'ghost', 'giant', 'giantess', 'gibson_les_paul', 'girl', 'goblin', 'groom', 'guro', 'gyaru', 'habit', 'harem', 'harpy', 'harvin', 'heads_together', 'health_bar', 'height_difference', 'hitodama', 'horror_(theme)', 'humanization', 'husband_and_wife', 'hydrokinesis', 'hypnosis', 'hyur', 'idol', 'insignia', 'instant_loss', 'interracial', 'interspecies', 'japari_bun', 'jeweled_branch_of_hourai', 'jiangshi', 'jirai_kei', 'joints', 'karakasa_obake', 'keyhole', 'kitsune', 'knight', 'kodona', 'kogal', 'kyuubi', 'lamia', 'left-handed', 'loli', 'lolita', 'look-alike', 'machinery', 'magic', 'male_focus', 'manly', 'matching_outfits', 'mature_female', 'mecha', 'mermaid', 'meta', 'miko', 'milestone_celebration', 'military', 'mind_control', 'miniboy', 'minigirl',"miqo'te",'monster', 'monsterification', 'mother_and_daughter', 'mother_and_son', 'multiple_others', 'muscular', 'nanodesu_(phrase)', 'narrow_waist', 'nekomata', 'netorare', 'ninja', 'no_humans', 'nontraditional', 'nun', 'nurse', 'object_namesake', 'obliques', 'office_lady', 'old', 'on_body', 'onee-shota', 'oni', 'orc', 'others', 'otoko_no_ko', 'oversized_object', 'paint_splatter', 'pantyshot', 'pawpads', 'persona', 'personality', 'personification', 'pet_play', 'petite', 'pirate', 'playboy_bunny', 'player_2', 'plugsuit', 'plump', 'poi', 'pokemon', 'police', 'policewoman', 'pom_pom_(cheerleading)', 'princess', 'prosthesis', 'pun', 'puppet', 'race_queen', 'radio_antenna', 'real_life_insert', 'redesign', 'reverse_trap', 'rigging', 'robot', 'rod_of_remorse', 'sailor', 'salaryman', 'samurai', 'sangvis_ferri', 'scales', 'scene_reference', 'school', 'sheikah', 'shota', 'shrine', 'siblings', 'side-by-side', 'sidesaddle', 'sisters', 'size_difference', 'skeleton', 'skinny', 'slave', 'slime_(substance)', 'soldier', 'spiked_shell', 'spokencharacter', 'steampunk', 'streetwear', 'striker_unit', 'strongman', 'submerged', 'suggestive', 'super_saiyan', 'superhero', 'surreal', 'take_your_pick', 'tall', 'talons', 'taur', 'teacher', 'team_rocket', 'three-dimensional_maneuver_gear', 'time_paradox', 'tomboy', 'traditional_youkai', 'transformation', 'trick_or_treat', 'tusks', 'twins', 'ufo', 'under_covers', 'v-fin', 'v-fin', 'vampire', 'virtual_youtuber', 'waitress', 'watching_television', 'wedding', 'what', 'when_you_see_it', 'wife_and_wife', 'wing', 'wings', 'witch', 'world_war_ii', 'yandere', 'year_of', 'yes', 'yin_yang', 'yordle',"you're_doing_it_wrong",'you_gonna_get_raped', 'yukkuri_shiteitte_ne', 'yuri', 'zombie', '(alice_in_wonderland)', '(arknights)', '(blue_archive)', '(cosplay)', '(creature)', '(emblem)', '(evangelion)', '(fate)', '(fate/stay_night)', '(ff11)', '(fire_emblem)', '(genshin_impact)', '(grimm)', '(houseki_no_kuni)', '(hyouka)', '(idolmaster)', '(jojo)', '(kancolle)', '(kantai_collection)', '(kill_la_kill)', '(league_of_legends)', '(legends)', '(lyomsnpmp)', '(machimazo)', '(madoka_magica)', '(mecha)', '(meme)', '(nier:automata)', '(organ)', '(overwatch)', '(pokemon)', '(project_moon)', '(project_sekai)', '(sao)', '(senran_kagura)', '(splatoon)', '(touhou)', '(tsukumo_sana)', '(youkai_watch)', '(yu-gi-oh!_gx)', '(zelda)', 'sextuplets', 'imperial_japanese_army', 'extra_faces', '_miku'],
|
34 |
+
'Composition':['abstract', 'anime_coloring', 'animification', 'back-to-back', 'bad_anatomy', 'blurry', 'border', 'bound', 'cameo', 'cheek-to-cheek', 'chromatic_aberration', 'close-up', 'collage', 'color_guide', 'colorful', 'comic', 'contrapposto', 'cover', 'cowboy_shot', 'crosshatching', 'depth_of_field', 'dominatrix', 'dutch_angle', '_focus', 'face-to-face', 'fake_screenshot', 'film_grain', 'fisheye', 'flat_color', 'foreshortening', 'from_above', 'from_behind', 'from_below', 'from_side', 'full_body', 'glitch', 'greyscale', 'halftone', 'head_only', 'heads-up_display', 'high_contrast', 'horizon', '_inset', 'inset', 'jaggy_lines', '1koma', '2koma', '3koma', '4koma', '5koma', 'leaning', 'leaning_forward', 'leaning_to_the_side', 'left-to-right_manga', 'lens_flare', 'limited_palette', 'lineart', 'lineup', 'lower_body', '(medium)', 'marker_(medium)', 'meme', 'mixed_media', 'monochrome', 'multiple_views', 'muted_color', 'oekaki', 'on_side', 'out_of_frame', 'outline', 'painting', 'parody', 'partially_colored', 'partially_underwater_shot', 'perspective', 'photorealistic', 'picture_frame', 'pillarboxed', 'portrait', 'poster_(object)', 'product_placement', 'profile', 'realistic', 'recording', 'retro_artstyle', '(style)', '_style', 'sandwiched', 'science_fiction', 'sepia', 'shikishi', 'side-by-side', 'sideways', 'sideways_glance', 'silhouette', 'sketch', 'spot_color', 'still_life', 'straight-on', 'symmetry', '(texture)', 'tachi-e', 'taking_picture', 'tegaki', 'too_many', 'traditional_media', 'turnaround', 'underwater', 'upper_body', 'upside-down', 'upskirt', 'variations', 'wide_shot', '_design', 'symbolism', 'rounded_corners', 'surrounded'],
|
35 |
+
'Season':['akeome', 'anniversary', 'autumn', 'birthday', 'christmas', '_day', 'festival', 'halloween', 'kotoyoro', 'nengajou', 'new_year', 'spring_(season)', 'summer', 'tanabata', 'valentine', 'winter'],
|
36 |
+
'Background':['_background', 'backlighting', 'bloom', 'bokeh', 'brick_wall', 'bubble', 'cable', 'caustics', 'cityscape', 'cloud', 'confetti', 'constellation', 'contrail', 'crowd', 'crystal', 'dark', 'debris', 'dusk', 'dust', 'egasumi', 'embers', 'emphasis_lines', 'energy', 'evening', 'explosion', 'fireworks', 'fog', 'footprints', 'glint', 'graffiti', 'ice', 'industrial_pipe', 'landscape', 'light', 'light_particles', 'light_rays', 'lightning', 'lights', 'moonlight', 'motion_blur', 'motion_lines', 'mountainous_horizon', 'nature', '(planet)', 'pagoda', 'people', 'pillar', 'planet', 'power_lines', 'puddle', 'rain', 'rainbow', 'reflection', 'ripples', 'rubble', 'ruins', 'scenery', 'shade', 'shooting_star', 'sidelighting', 'smoke', 'snowflakes', 'snowing', 'space', 'sparkle', 'sparks', 'speed_lines', 'spider_web', 'spotlight', 'star_(sky)', 'stone_wall', 'sunbeam', 'sunburst', 'sunrise', '_theme', 'tile_wall', 'twilight', 'wall_clock', 'wall_of_text', 'water', 'waves', 'wind', 'wire', 'wooden_wall', 'lighthouse'],
|
37 |
+
'Patterns':['arrow', 'bass_clef', 'blank_censor', 'circle', 'cube', 'heart', 'hexagon', 'hexagram', 'light_censor', '(pattern)', 'pattern', 'pentagram', 'roman_numeral', '(shape)', '(symbol)', 'shape', 'sign', 'symbol', 'tally', 'treble_clef', 'triangle', 'tube', 'yagasuri'],
|
38 |
+
'Censorship':['blur_censor', '_censor', '_censoring', 'censored', 'character_censor', 'convenient', 'hair_censor', 'heart_censor', 'identity_censor', 'maebari', 'novelty_censor', 'soap_censor', 'steam_censor', 'tail_censor', 'uncensored'],
|
39 |
+
'Others':['2007', '2008', '2009', '2010', '2011', '2012', '2013', '2014', '2015', '2016', '2017', '2018', '2019', '2020', '2021', '2022', '2023', '2024', 'artist', 'artist_name', 'artistic_error', 'asian', '(company)', 'character_name', 'content_rating', 'copyright', 'cover_page', 'dated', 'english_text', 'japan', 'layer', 'logo', 'name', 'numbered', 'page_number', 'pixiv_id', 'ranguage', 'reference_sheet', 'signature', 'speech_bubble', 'subtitled', 'text', 'thank_you', 'typo', 'username', 'wallpaper', 'watermark', 'web_address', 'screwdriver', 'translated'],
|
40 |
+
'Quality Tags':['masterpiece', '_quality', 'highres', 'absurdres', 'ultra-detailed', 'lowres']}
|
41 |
+
|
42 |
+
reversed_categories = {value: key for key, values in categories.items() for value in values}
|
43 |
+
|
44 |
+
# Precompute keyword lengths
|
45 |
+
keyword_lengths = {keyword: len(keyword) for keyword in reversed_categories}
|
46 |
+
|
47 |
+
# Trie for efficient keyword matching
|
48 |
+
class TrieNode:
|
49 |
+
def __init__(self):
|
50 |
+
self.children = {}
|
51 |
+
self.category = None
|
52 |
+
|
53 |
+
def build_trie(keywords):
|
54 |
+
root = TrieNode()
|
55 |
+
for keyword, category in reversed_categories.items():
|
56 |
+
node = root
|
57 |
+
for char in keyword:
|
58 |
+
if char not in node.children:
|
59 |
+
node.children[char] = TrieNode()
|
60 |
+
node = node.children[char]
|
61 |
+
node.category = category
|
62 |
+
return root
|
63 |
+
|
64 |
+
trie_root = build_trie(reversed_categories)
|
65 |
+
|
66 |
+
def find_category(trie_root, tag):
|
67 |
+
node = trie_root
|
68 |
+
for char in tag:
|
69 |
+
if char in node.children:
|
70 |
+
node = node.children[char]
|
71 |
+
if node.category:
|
72 |
+
return node.category
|
73 |
+
else:
|
74 |
+
break
|
75 |
+
return None
|
76 |
+
|
77 |
+
def classify_tags(tags: list[str], local_test: bool = False):
|
78 |
+
# Dictionary for automatic classification
|
79 |
+
classified_tags: defaultdict[str, list] = defaultdict(list)
|
80 |
+
fuzzy_match_tags: defaultdict[str, list] = defaultdict(list)
|
81 |
+
unclassified_tags: list[str] = []
|
82 |
+
|
83 |
+
# Logic for automatic grouping
|
84 |
+
for tag in tags:
|
85 |
+
classified = False
|
86 |
+
tag_new = tag.replace(" ", "_").replace("-", "_").replace("\\(", "(").replace("\\)", ")") # Replace spaces in source tags with underscores
|
87 |
+
|
88 |
+
# Exact match using the trie
|
89 |
+
category = find_category(trie_root, tag_new)
|
90 |
+
if category:
|
91 |
+
classified = True
|
92 |
+
else:
|
93 |
+
# Fuzzy match
|
94 |
+
tag_parts = tag_new.split("_")
|
95 |
+
for keyword, keyword_length in keyword_lengths.items():
|
96 |
+
if keyword in tag_new and keyword_length > 3: # Adjust the threshold if needed
|
97 |
+
classified = True
|
98 |
+
category = reversed_categories[keyword]
|
99 |
+
break
|
100 |
+
|
101 |
+
if classified and tag not in classified_tags[category]: # Avoid duplicates
|
102 |
+
classified_tags[category].append(tag)
|
103 |
+
elif not classified and tag not in unclassified_tags:
|
104 |
+
unclassified_tags.append(tag) # Unclassified tags
|
105 |
+
|
106 |
+
if local_test:
|
107 |
+
# Output the grouping result
|
108 |
+
for category, tags in classified_tags.items():
|
109 |
+
print(f"{category}:")
|
110 |
+
print(", ".join(tags))
|
111 |
+
print()
|
112 |
+
|
113 |
+
print()
|
114 |
+
print("Fuzzy match:")
|
115 |
+
for category, tags in fuzzy_match_tags.items():
|
116 |
+
print(f"{category}:")
|
117 |
+
print(", ".join(tags))
|
118 |
+
print()
|
119 |
+
print()
|
120 |
+
|
121 |
+
if len(unclassified_tags) > 0:
|
122 |
+
print(f"\nUnclassified tags: {len(unclassified_tags)}")
|
123 |
+
print(f"{unclassified_tags[:200]}") # Display some unclassified tags
|
124 |
+
|
125 |
+
return classified_tags, unclassified_tags
|
126 |
+
|
127 |
+
# Code for "Tag Categorizer" tab
|
128 |
+
def process_tags(input_tags: str):
|
129 |
+
# Split tags using regex to handle both commas and question marks
|
130 |
+
tags = []
|
131 |
+
for tag in re.split(r'\?|,|\n', input_tags):
|
132 |
+
tag = tag.strip()
|
133 |
+
if tag:
|
134 |
+
# Remove numbers at the end of tags
|
135 |
+
tag = re.sub(r'\b\d+\b', '', tag).strip()
|
136 |
+
|
137 |
+
# Replace underscores with spaces
|
138 |
+
tag = tag.replace('_', ' ')
|
139 |
+
|
140 |
+
# Escape parentheses (handle both escaped and unescaped)
|
141 |
+
if '(' in tag or ')' in tag:
|
142 |
+
# First, replace existing backslashes to handle properly
|
143 |
+
tag = tag.replace('\\', '')
|
144 |
+
# Replace parentheses with escaped versions
|
145 |
+
tag = tag.replace('(', r'$').replace(')', r'$')
|
146 |
+
|
147 |
+
if tag: # Only add if tag is not empty after processing
|
148 |
+
tags.append(tag)
|
149 |
+
|
150 |
+
# Classify the cleaned tags
|
151 |
+
classified_tags, unclassified_tags = classify_tags(tags)
|
152 |
+
|
153 |
+
# Create the outputs
|
154 |
+
categorized_string = ', '.join([tag for category in classified_tags.values() for tag in category])
|
155 |
+
categorized_json = {category: tags for category, tags in classified_tags.items()}
|
156 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
157 |
return categorized_string, categorized_json, "" # Initialize enhanced_prompt as empty
|
modules/florence2.py
CHANGED
@@ -1,97 +1,90 @@
|
|
1 |
-
import os
|
2 |
-
from
|
3 |
-
import
|
4 |
-
from
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
return
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
elif task_prompt=='
|
73 |
-
elif task_prompt=='
|
74 |
-
elif task_prompt=='
|
75 |
-
elif task_prompt=='
|
76 |
-
elif task_prompt=='
|
77 |
-
elif task_prompt=='
|
78 |
-
elif task_prompt=='
|
79 |
-
elif task_prompt=='
|
80 |
-
elif task_prompt=='
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
single_task_list=['Caption','Detailed Caption','More Detailed Caption','Object Detection','Dense Region Caption','Region Proposal','Caption to Phrase Grounding','Referring Expression Segmentation','Region to Segmentation','Open Vocabulary Detection','Region to Category','Region to Description','OCR','OCR with Region']
|
91 |
-
cascaded_task_list=['Caption + Grounding','Detailed Caption + Grounding','More Detailed Caption + Grounding']
|
92 |
-
|
93 |
-
def update_task_dropdown(choice):
|
94 |
-
if choice == 'Cascaded task':
|
95 |
-
return gr.Dropdown(choices=cascaded_task_list, value='Caption + Grounding')
|
96 |
-
else:
|
97 |
return gr.Dropdown(choices=single_task_list, value='Caption')
|
|
|
1 |
+
import os,io,copy,subprocess,spaces,matplotlib.pyplot as plt,matplotlib.patches as patches,random,numpy as np
|
2 |
+
from PIL import Image,ImageDraw,ImageFont
|
3 |
+
from unittest.mock import patch
|
4 |
+
from transformers.dynamic_module_utils import get_imports
|
5 |
+
from transformers import AutoProcessor,AutoModelForCausalLM
|
6 |
+
|
7 |
+
def fixed_get_imports(filename:str|os.PathLike)->list[str]:
|
8 |
+
if not str(filename).endswith('/modeling_florence2.py'):return get_imports(filename)
|
9 |
+
imports=get_imports(filename)
|
10 |
+
if'flash_attn'in imports:imports.remove('flash_attn')
|
11 |
+
return imports
|
12 |
+
@spaces.GPU
|
13 |
+
def get_device_type():
|
14 |
+
import torch
|
15 |
+
if torch.cuda.is_available():return'cuda'
|
16 |
+
elif torch.backends.mps.is_available()and torch.backends.mps.is_built():return'mps'
|
17 |
+
else:return'cpu'
|
18 |
+
device = get_device_type()
|
19 |
+
if (device == "cuda"):
|
20 |
+
subprocess.run('pip install flash-attn --no-build-isolation', env={'FLASH_ATTENTION_SKIP_CUDA_BUILD': "TRUE"}, shell=True)
|
21 |
+
model = AutoModelForCausalLM.from_pretrained("MiaoshouAI/Florence-2-base-PromptGen-v2.0", trust_remote_code=True)
|
22 |
+
processor = AutoProcessor.from_pretrained("MiaoshouAI/Florence-2-base-PromptGen-v2.0", trust_remote_code=True)
|
23 |
+
model.to(device)
|
24 |
+
else:
|
25 |
+
with patch("transformers.dynamic_module_utils.get_imports", fixed_get_imports):
|
26 |
+
model = AutoModelForCausalLM.from_pretrained("MiaoshouAI/Florence-2-base-PromptGen-v2.0", trust_remote_code=True)
|
27 |
+
processor = AutoProcessor.from_pretrained("MiaoshouAI/Florence-2-base-PromptGen-v2.0", trust_remote_code=True)
|
28 |
+
model.to(device)
|
29 |
+
|
30 |
+
colormap=['blue','orange','green','purple','brown','pink','gray','olive','cyan','red','lime','indigo','violet','aqua','magenta','coral','gold','tan','skyblue']
|
31 |
+
|
32 |
+
def fig_to_pil(fig):buf=io.BytesIO();fig.savefig(buf,format='png');buf.seek(0);return Image.open(buf)
|
33 |
+
@spaces.GPU
|
34 |
+
def run_example(task_prompt,image,text_input=None):
|
35 |
+
if text_input is None:prompt=task_prompt
|
36 |
+
else:prompt=task_prompt+text_input
|
37 |
+
inputs=processor(text=prompt,images=image,return_tensors='pt').to(device);generated_ids=model.generate(input_ids=inputs['input_ids'],pixel_values=inputs['pixel_values'],max_new_tokens=1024,early_stopping=False,do_sample=False,num_beams=3);generated_text=processor.batch_decode(generated_ids,skip_special_tokens=False)[0];parsed_answer=processor.post_process_generation(generated_text,task=task_prompt,image_size=(image.width,image.height));return parsed_answer
|
38 |
+
def plot_bbox(image,data):
|
39 |
+
fig,ax=plt.subplots();ax.imshow(image)
|
40 |
+
for(bbox,label)in zip(data['bboxes'],data['labels']):x1,y1,x2,y2=bbox;rect=patches.Rectangle((x1,y1),x2-x1,y2-y1,linewidth=1,edgecolor='r',facecolor='none');ax.add_patch(rect);plt.text(x1,y1,label,color='white',fontsize=8,bbox=dict(facecolor='red',alpha=.5))
|
41 |
+
ax.axis('off');return fig
|
42 |
+
def draw_polygons(image,prediction,fill_mask=False):
|
43 |
+
draw=ImageDraw.Draw(image);scale=1
|
44 |
+
for(polygons,label)in zip(prediction['polygons'],prediction['labels']):
|
45 |
+
color=random.choice(colormap);fill_color=random.choice(colormap)if fill_mask else None
|
46 |
+
for _polygon in polygons:
|
47 |
+
_polygon=np.array(_polygon).reshape(-1,2)
|
48 |
+
if len(_polygon)<3:print('Invalid polygon:',_polygon);continue
|
49 |
+
_polygon=(_polygon*scale).reshape(-1).tolist()
|
50 |
+
if fill_mask:draw.polygon(_polygon,outline=color,fill=fill_color)
|
51 |
+
else:draw.polygon(_polygon,outline=color)
|
52 |
+
draw.text((_polygon[0]+8,_polygon[1]+2),label,fill=color)
|
53 |
+
return image
|
54 |
+
|
55 |
+
def draw_ocr_bboxes(image,prediction):
|
56 |
+
scale=1;draw=ImageDraw.Draw(image);bboxes,labels=prediction['quad_boxes'],prediction['labels']
|
57 |
+
for(box,label)in zip(bboxes,labels):color=random.choice(colormap);new_box=(np.array(box)*scale).tolist();draw.polygon(new_box,width=3,outline=color);draw.text((new_box[0]+8,new_box[1]+2),'{}'.format(label),align='right',fill=color)
|
58 |
+
return image
|
59 |
+
def convert_to_od_format(data):bboxes=data.get('bboxes',[]);labels=data.get('bboxes_labels',[]);od_results={'bboxes':bboxes,'labels':labels};return od_results
|
60 |
+
|
61 |
+
def process_image(image,task_prompt,text_input=None):
|
62 |
+
if isinstance(image,str):image=Image.open(image)
|
63 |
+
else:image=Image.fromarray(image)
|
64 |
+
if task_prompt=='Caption':task_prompt='<CAPTION>';results=run_example(task_prompt,image);return results[task_prompt],None
|
65 |
+
elif task_prompt=='Detailed Caption':task_prompt='<DETAILED_CAPTION>';results=run_example(task_prompt,image);return results[task_prompt],None
|
66 |
+
elif task_prompt=='More Detailed Caption':task_prompt='<MORE_DETAILED_CAPTION>';results=run_example(task_prompt,image);return results,None
|
67 |
+
elif task_prompt=='Caption + Grounding':task_prompt='<CAPTION>';results=run_example(task_prompt,image);text_input=results[task_prompt];task_prompt='<CAPTION_TO_PHRASE_GROUNDING>';results=run_example(task_prompt,image,text_input);results['<CAPTION>']=text_input;fig=plot_bbox(image,results['<CAPTION_TO_PHRASE_GROUNDING>']);return results,fig_to_pil(fig)
|
68 |
+
elif task_prompt=='Detailed Caption + Grounding':task_prompt='<DETAILED_CAPTION>';results=run_example(task_prompt,image);text_input=results[task_prompt];task_prompt='<CAPTION_TO_PHRASE_GROUNDING>';results=run_example(task_prompt,image,text_input);results['<DETAILED_CAPTION>']=text_input;fig=plot_bbox(image,results['<CAPTION_TO_PHRASE_GROUNDING>']);return results,fig_to_pil(fig)
|
69 |
+
elif task_prompt=='More Detailed Caption + Grounding':task_prompt='<MORE_DETAILED_CAPTION>';results=run_example(task_prompt,image);text_input=results[task_prompt];task_prompt='<CAPTION_TO_PHRASE_GROUNDING>';results=run_example(task_prompt,image,text_input);results['<MORE_DETAILED_CAPTION>']=text_input;fig=plot_bbox(image,results['<CAPTION_TO_PHRASE_GROUNDING>']);return results,fig_to_pil(fig)
|
70 |
+
elif task_prompt=='Object Detection':task_prompt='<OD>';results=run_example(task_prompt,image);fig=plot_bbox(image,results['<OD>']);return results,fig_to_pil(fig)
|
71 |
+
elif task_prompt=='Dense Region Caption':task_prompt='<DENSE_REGION_CAPTION>';results=run_example(task_prompt,image);fig=plot_bbox(image,results['<DENSE_REGION_CAPTION>']);return results,fig_to_pil(fig)
|
72 |
+
elif task_prompt=='Region Proposal':task_prompt='<REGION_PROPOSAL>';results=run_example(task_prompt,image);fig=plot_bbox(image,results['<REGION_PROPOSAL>']);return results,fig_to_pil(fig)
|
73 |
+
elif task_prompt=='Caption to Phrase Grounding':task_prompt='<CAPTION_TO_PHRASE_GROUNDING>';results=run_example(task_prompt,image,text_input);fig=plot_bbox(image,results['<CAPTION_TO_PHRASE_GROUNDING>']);return results,fig_to_pil(fig)
|
74 |
+
elif task_prompt=='Referring Expression Segmentation':task_prompt='<REFERRING_EXPRESSION_SEGMENTATION>';results=run_example(task_prompt,image,text_input);output_image=copy.deepcopy(image);output_image=draw_polygons(output_image,results['<REFERRING_EXPRESSION_SEGMENTATION>'],fill_mask=True);return results,output_image
|
75 |
+
elif task_prompt=='Region to Segmentation':task_prompt='<REGION_TO_SEGMENTATION>';results=run_example(task_prompt,image,text_input);output_image=copy.deepcopy(image);output_image=draw_polygons(output_image,results['<REGION_TO_SEGMENTATION>'],fill_mask=True);return results,output_image
|
76 |
+
elif task_prompt=='Open Vocabulary Detection':task_prompt='<OPEN_VOCABULARY_DETECTION>';results=run_example(task_prompt,image,text_input);bbox_results=convert_to_od_format(results['<OPEN_VOCABULARY_DETECTION>']);fig=plot_bbox(image,bbox_results);return results,fig_to_pil(fig)
|
77 |
+
elif task_prompt=='Region to Category':task_prompt='<REGION_TO_CATEGORY>';results=run_example(task_prompt,image,text_input);return results,None
|
78 |
+
elif task_prompt=='Region to Description':task_prompt='<REGION_TO_DESCRIPTION>';results=run_example(task_prompt,image,text_input);return results,None
|
79 |
+
elif task_prompt=='OCR':task_prompt='<OCR>';results=run_example(task_prompt,image);return results,None
|
80 |
+
elif task_prompt=='OCR with Region':task_prompt='<OCR_WITH_REGION>';results=run_example(task_prompt,image);output_image=copy.deepcopy(image);output_image=draw_ocr_bboxes(output_image,results['<OCR_WITH_REGION>']);return results,output_image
|
81 |
+
else:return'',None # Return empty string and None for unknown task prompts
|
82 |
+
|
83 |
+
single_task_list=['Caption','Detailed Caption','More Detailed Caption','Object Detection','Dense Region Caption','Region Proposal','Caption to Phrase Grounding','Referring Expression Segmentation','Region to Segmentation','Open Vocabulary Detection','Region to Category','Region to Description','OCR','OCR with Region']
|
84 |
+
cascaded_task_list=['Caption + Grounding','Detailed Caption + Grounding','More Detailed Caption + Grounding']
|
85 |
+
|
86 |
+
def update_task_dropdown(choice):
|
87 |
+
if choice == 'Cascaded task':
|
88 |
+
return gr.Dropdown(choices=cascaded_task_list, value='Caption + Grounding')
|
89 |
+
else:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
90 |
return gr.Dropdown(choices=single_task_list, value='Caption')
|
modules/tag_enhancer.py
CHANGED
@@ -1,53 +1,53 @@
|
|
1 |
-
import gradio as gr
|
2 |
-
|
3 |
-
import
|
4 |
-
|
5 |
-
device = "cuda" if torch.cuda.is_available() else "cpu"
|
6 |
-
|
7 |
-
def load_models():
|
8 |
-
try:
|
9 |
-
enhancer_medium = pipeline("summarization", model="gokaygokay/Lamini-Prompt-Enchance", device=device)
|
10 |
-
enhancer_long = pipeline("summarization", model="gokaygokay/Lamini-Prompt-Enchance-Long", device=device)
|
11 |
-
model_checkpoint = "gokaygokay/Flux-Prompt-Enhance"
|
12 |
-
tokenizer = AutoTokenizer.from_pretrained(model_checkpoint)
|
13 |
-
model = AutoModelForSeq2SeqLM.from_pretrained(model_checkpoint).eval().to(device=device)
|
14 |
-
enhancer_flux = pipeline('text2text-generation', model=model, tokenizer=tokenizer, repetition_penalty=1.5, device=device)
|
15 |
-
except Exception as e:
|
16 |
-
print(e)
|
17 |
-
enhancer_medium = enhancer_long = enhancer_flux = None
|
18 |
-
return enhancer_medium, enhancer_long, enhancer_flux
|
19 |
-
|
20 |
-
enhancer_medium, enhancer_long, enhancer_flux = load_models()
|
21 |
-
|
22 |
-
def enhance_prompt(input_prompt, model_choice):
|
23 |
-
if model_choice == "Medium":
|
24 |
-
result = enhancer_medium("Enhance the description: " + input_prompt)
|
25 |
-
enhanced_text = result[0]['summary_text']
|
26 |
-
|
27 |
-
pattern = r'^.*?of\s+(.*?(?:\.|$))'
|
28 |
-
match = re.match(pattern, enhanced_text, re.IGNORECASE | re.DOTALL)
|
29 |
-
|
30 |
-
if match:
|
31 |
-
remaining_text = enhanced_text[match.end():].strip()
|
32 |
-
modified_sentence = match.group(1).capitalize()
|
33 |
-
enhanced_text = modified_sentence + ' ' + remaining_text
|
34 |
-
elif model_choice == "Flux":
|
35 |
-
result = enhancer_flux("enhance prompt: " + input_prompt, max_length=256)
|
36 |
-
enhanced_text = result[0]['generated_text']
|
37 |
-
else: # Long
|
38 |
-
result = enhancer_long("Enhance the description: " + input_prompt)
|
39 |
-
enhanced_text = result[0]['summary_text']
|
40 |
-
|
41 |
-
return enhanced_text
|
42 |
-
|
43 |
-
def prompt_enhancer(character: str, series: str, general: str, model_choice: str):
|
44 |
-
characters = character.split(",") if character else []
|
45 |
-
serieses = series.split(",") if series else []
|
46 |
-
generals = general.split(",") if general else []
|
47 |
-
tags = characters + serieses + generals
|
48 |
-
cprompt = ",".join(tags) if tags else ""
|
49 |
-
|
50 |
-
output = enhance_prompt(cprompt, model_choice)
|
51 |
-
prompt = cprompt + ", " + output
|
52 |
-
|
53 |
return prompt, gr.update(interactive=True), gr.update(interactive=True)
|
|
|
1 |
+
import gradio as gr
|
2 |
+
import re,torch
|
3 |
+
from transformers import pipeline,AutoTokenizer,AutoModelForSeq2SeqLM
|
4 |
+
|
5 |
+
device = "cuda" if torch.cuda.is_available() else "cpu"
|
6 |
+
|
7 |
+
def load_models():
|
8 |
+
try:
|
9 |
+
enhancer_medium = pipeline("summarization", model="gokaygokay/Lamini-Prompt-Enchance", device=device)
|
10 |
+
enhancer_long = pipeline("summarization", model="gokaygokay/Lamini-Prompt-Enchance-Long", device=device)
|
11 |
+
model_checkpoint = "gokaygokay/Flux-Prompt-Enhance"
|
12 |
+
tokenizer = AutoTokenizer.from_pretrained(model_checkpoint)
|
13 |
+
model = AutoModelForSeq2SeqLM.from_pretrained(model_checkpoint).eval().to(device=device)
|
14 |
+
enhancer_flux = pipeline('text2text-generation', model=model, tokenizer=tokenizer, repetition_penalty=1.5, device=device)
|
15 |
+
except Exception as e:
|
16 |
+
print(e)
|
17 |
+
enhancer_medium = enhancer_long = enhancer_flux = None
|
18 |
+
return enhancer_medium, enhancer_long, enhancer_flux
|
19 |
+
|
20 |
+
enhancer_medium, enhancer_long, enhancer_flux = load_models()
|
21 |
+
|
22 |
+
def enhance_prompt(input_prompt, model_choice):
|
23 |
+
if model_choice == "Medium":
|
24 |
+
result = enhancer_medium("Enhance the description: " + input_prompt)
|
25 |
+
enhanced_text = result[0]['summary_text']
|
26 |
+
|
27 |
+
pattern = r'^.*?of\s+(.*?(?:\.|$))'
|
28 |
+
match = re.match(pattern, enhanced_text, re.IGNORECASE | re.DOTALL)
|
29 |
+
|
30 |
+
if match:
|
31 |
+
remaining_text = enhanced_text[match.end():].strip()
|
32 |
+
modified_sentence = match.group(1).capitalize()
|
33 |
+
enhanced_text = modified_sentence + ' ' + remaining_text
|
34 |
+
elif model_choice == "Flux":
|
35 |
+
result = enhancer_flux("enhance prompt: " + input_prompt, max_length=256)
|
36 |
+
enhanced_text = result[0]['generated_text']
|
37 |
+
else: # Long
|
38 |
+
result = enhancer_long("Enhance the description: " + input_prompt)
|
39 |
+
enhanced_text = result[0]['summary_text']
|
40 |
+
|
41 |
+
return enhanced_text
|
42 |
+
|
43 |
+
def prompt_enhancer(character: str, series: str, general: str, model_choice: str):
|
44 |
+
characters = character.split(",") if character else []
|
45 |
+
serieses = series.split(",") if series else []
|
46 |
+
generals = general.split(",") if general else []
|
47 |
+
tags = characters + serieses + generals
|
48 |
+
cprompt = ",".join(tags) if tags else ""
|
49 |
+
|
50 |
+
output = enhance_prompt(cprompt, model_choice)
|
51 |
+
prompt = cprompt + ", " + output
|
52 |
+
|
53 |
return prompt, gr.update(interactive=True), gr.update(interactive=True)
|