CivArchive
    ← All articles
    Published June 1, 2024by mnemic

    LoRA Training - Dataset Creation - ChatGPT (GPT4 / Plus Account)

    4.1K views12 reactions9 comments on CivitAI56 collected
    data preptraining datalora training

    This is a small workflow guide on how to generate a dataset of images using ChatGPT! This requires a paid OpenAI account, but doesn't cost "per generation". It's still a fairly manual-labour intensive way of getting a high-quality generated dataset.

    This is part of a series on how to generate datasets with: ChatGPT API, ChatGPT, Bing, ComfyUI.

    The Workflow

    This is actually fairly straight-forward. I will give you a prompt that you can use with ChatGPT. You will need to customize the prompt to instruct it better and in the style that you want.

    After this, it will be "half-automatic". What I mean by this is that OpenAI keeps changing how it works. It used to be that it gave you 4 images each time you asked it to generate something. Then they changed the limits to 2 images, and now I think it may be 1 image each time? I'm not sure any more.

    ChatGPT Limits

    Additionally, there's a limit to the number of images you're allowed to generate. This is based on the traffic at OpenAI, so it's not in your control. It will warn you when you need to wait, and tell you for how long you are on cooldown. Sometimes you can start a bit earlier.

    The Prompt

    Hi!

    I need your help to generate a bunch of images. Please generate them in a square 1024x1024 resolution.

    I'm trying to create an art style LoRA (image generation model), using some images as a base, so I need the results to be stylishly consistent.

    I need the style to be consistent across the images. I want the subject itself to transformed / morphed into a version of that subject that matches the theme. Example: If I asked for a Batman-styled image, and the Subject was "car", I would expect a result like the batmobile.

    I would like you to use a shared prompt for all images, to maintain the same style. But I will need the [subject] to be replaced for each set of images. Please add 2 random words at the end of each generation that relates to the style I'm trying to achieve.

    Here's my prompt. The subject is in [brackets].

    Photo of a delicious-looking cinnamon-bun [SUBJECT]. The entire aircraft is constructed from fresh, golden-brown cinnamon bun material, with swirls of cinnamon and icing visible.

    For each subject below, please generate 4 images, and replace the [SUBJECT] with the following items:

    Send each 4 images in a separate message. Continue without asking for permission to continue until all subjects have 4 images each. Thank you very much!

    List of Subjects:

    majestic airplane soaring through the skies
    humanoid mechanical robotic cyborg character inside a spaceship
    battle mech on a battlefield
    bookshelf in a living room
    camera on a table in an office
    car driving on a road
    castle in the mountains
    city skyline, closeup daytime
    cloud in the skies, fluffy
    coffee machine in a kitchen
    combine harvester plowing the fields on the farm, planted harvest crops
    cube hovering in the air, artifact
    dirigible soaring the skies on a sunny day
    excavator working the construction site
    forest trees, close up of trees, stems and roots, branches in forest
    grass closeup blade of grass in grassy field
    industrial boiler, technical parts, pipes, gauges, in a warehouse
    lake in nature with water, ripples of a pond
    landscape with hills, terrain, nature
    light rays from a glowing center in space
    cells and molecules and macro photography
    magical energy swirling magic energies, glowing
    mystical runes and magic energies
    planet in space, detailed and realistic, stars and cosmos in the background
    pyramids in the desert
    recliner in a living room
    space station in outer space, ISS, hi-tech, starry cosmos background in space
    spaceship in outer space, millennium falcon, stars and cosmos background
    sphere with hi-tech details, alien artifact
    submarine deep under water
    tank panzer wagon, gun barrel, driving through the jungle and desert, tech
    toaster on a kitchen counter in a modern kitchen
    tree in the forest, detailed leaves
    truck driving in a city
    vintage TV in a living room
    water closeup of a liquid surface, wet, dripping puddle
    wooden chair in a living room

    The Base Prompt

    Photo of a delicious-looking cinnamon-bun [SUBJECT]. The entire aircraft is constructed from fresh, golden-brown cinnamon bun material, with swirls of cinnamon and icing visible.

    This part of the ChatGPT prompt, is what will actually be prompted by the image generator. ChatGPT should replace the word in the brackets [SUBJECT], with each line in the list of subjects.

    Common Problems

    At one point, this worked flawlessly. You got a list of 4 images for each subject, and then it moved on to the next subject and did 4 more there, until it hit the image generation limit.

    Now, you can run into all sorts of problems.

    • It only generates one of each image

      • You're gonna have to ask it in a different way, or just repeat the list once it's done and sort a lot of files manually

    • It generates "split" images, all images in one image, instead of multiple full images

    Essentially, you're gonna have to wrestle ChatGPT until you get it sorted. Good luck!

    File Name Issues

    There are 2 ways to download the image from ChatGPT.

    When you hover with the mouse over an image, you get a download-button in the top-left corner. I recommend using this method, it's the fastest, and you get the images in a PNG format.

    However, you will also get a file name from hell.

    "DALL·E 2023-12-11 01.36.17 - Create a 1024x1024 image of a blue tank on a dirt road, inspired by the Transformers movies. The tank should incorporate advanced mechanical and futur.PNG"

    You are gonna have to rename this manually, as it contains both bad characters, and it can be too long for even some file renaming tools to rename. I have written a script where it actually renames the images even though it's crazy long. You will need to download my "RenameScripter" to run the script, so it's a bit of a setup. Alternatively you can just rename them manually.

    Here's the script:

    import os
    import tkinter as tk
    from tkinterdnd2 import DND_FILES, TkinterDnD
    
    class RenamerApp:
        def __init__(self, root):
            self.root = root
            self.previous_state = []
            self.files = []
    
            root.title('File Renamer')
            root.geometry('1200x600')  # Make the window 50% wider by default
    
            self.create_widgets()
            self.configure_grid()
    
        def create_widgets(self):
            self.left_label = tk.Label(self.root, text="Drag / drop your files or folders here")
            self.left_label.grid(row=0, column=0, padx=10, pady=5)
    
            self.right_label = tk.Label(self.root, text="Rename previews")
            self.right_label.grid(row=0, column=1, padx=10, pady=5)
    
            self.file_list_var = tk.Variable(value=[])
            self.preview_list_var = tk.Variable(value=[])
    
            self.file_listbox = tk.Listbox(self.root, listvariable=self.file_list_var, width=90, height=15)
            self.file_listbox.grid(row=1, column=0, padx=10, pady=10, sticky='nsew')
    
            self.preview_listbox = tk.Listbox(self.root, listvariable=self.preview_list_var, width=45, height=15)
            self.preview_listbox.grid(row=1, column=1, padx=10, pady=10, sticky='nsew')
    
            self.rename_button = tk.Button(self.root, text='RENAME', command=self.on_rename)
            self.rename_button.grid(row=2, column=0, pady=5)
    
            self.undo_button = tk.Button(self.root, text='UNDO', command=self.on_undo)
            self.undo_button.grid(row=2, column=1, pady=5)
    
            self.status_label = tk.Label(self.root, text="", fg="green")
            self.status_label.grid(row=3, column=0, columnspan=2, pady=5)
    
            self.root.drop_target_register(DND_FILES)
            self.root.dnd_bind('<<Drop>>', self.on_drop)
    
        def configure_grid(self):
            self.root.grid_rowconfigure(1, weight=1)
            self.root.grid_columnconfigure(0, weight=3)  # Left column (file list) is 3 times wider
            self.root.grid_columnconfigure(1, weight=1)  # Right column (preview) is thinner
    
        def get_files_from_paths(self, paths):
            files = []
            for path in paths:
                if os.path.isfile(path):
                    files.append(path)
                elif os.path.isdir(path):
                    for root, _, filenames in os.walk(path):
                        for filename in filenames:
                            files.append(os.path.join(root, filename))
            return files
    
        def rename_files(self, files):
            folder_counts = {}
            self.previous_state = []  # Clear previous state before renaming
            for file_path in files:
                directory, file_name = os.path.split(file_path)
                folder_name = os.path.basename(directory)
                file_extension = os.path.splitext(file_name)[1]
                folder_counts[directory] = folder_counts.get(directory, 0) + 1
                count_str = str(folder_counts[directory]).zfill(3)
                new_name = f"{folder_name} {count_str}{file_extension}"
                new_path = os.path.join(directory, new_name)
                os.rename(file_path, new_path)
                self.previous_state.append((new_path, file_path))  # Store new and old names for undo
    
        def on_drop(self, event):
            paths = self.root.tk.splitlist(event.data)
            self.files = self.get_files_from_paths(paths)
            original_file_paths = [file for file in self.files]
            new_file_names = [self.get_new_name(file, i) for i, file in enumerate(self.files)]
            self.file_list_var.set(original_file_paths)
            self.preview_list_var.set(new_file_names)
            self.status_label.config(text="")
            self.previous_state = []  # Clear previous state on new drop
    
        def get_new_name(self, file_path, index):
            directory, file_name = os.path.split(file_path)
            folder_name = os.path.basename(directory)
            file_extension = os.path.splitext(file_name)[1]
            count_str = str(index + 1).zfill(3)
            return f"{folder_name} {count_str}{file_extension}"
    
        def on_rename(self):
            self.rename_files(self.files)
            original_file_paths = [file for file in self.files]
            new_file_names = [self.get_new_name(file, i) for i, file in enumerate(self.files)]
            self.file_list_var.set(original_file_paths)
            self.preview_list_var.set(new_file_names)
            self.status_label.config(text="Files renamed successfully", fg="green")
    
        def on_undo(self):
            if not self.previous_state:
                self.status_label.config(text="Nothing to undo", fg="red")
                return
            for new_name, old_name in self.previous_state:
                os.rename(new_name, old_name)
            self.previous_state = []
            self.status_label.config(text="Undo completed", fg="blue")
            original_file_paths = [file for file in self.files]
            new_file_names = [self.get_new_name(file, i) for i, file in enumerate(self.files)]
            self.file_list_var.set(original_file_paths)
            self.preview_list_var.set(new_file_names)
    
    if __name__ == '__main__':
        root = TkinterDnD.Tk()
        app = RenamerApp(root)
        root.mainloop()

    Save this as RenameScript.py and place it anywhere. Launch the script, and it will open a user interface. Then drag/drop the files or folders onto the left side of the program.

    Press RENAME and check out the renamed files. If you are not happy, press UNDO.

    Alternatively, you can just right-click on each image and choose "Save Image As", but you will get it in .webp format, for which you will then need to convert it into JPG/PNG.

    You can do this with a tool like Vovsoft WEBP Converter: https://vovsoft.com/software/webp-converter/

    Big thanks to Konicony for writing the original guide to this workflow, and for Navimixu for teaching me additional tips and tricks, and providing the core for the list of concepts below.