Heim >Backend-Entwicklung >Python-Tutorial >Schritt-für-Schritt-Anleitung: Laden eines HuggingFace ControlNet-Datensatzes von einem lokalen Pfad

Schritt-für-Schritt-Anleitung: Laden eines HuggingFace ControlNet-Datensatzes von einem lokalen Pfad

PHPz
PHPzOriginal
2024-08-16 18:02:36897Durchsuche

Step-by-Step Guide: Loading a HuggingFace ControlNet Dataset from a Local Path

Huggingface bietet verschiedene Optionen zum Laden eines Datensatzes. Beim Laden eines lokalen Bilddatensatzes für Ihr ControlNet ist es wichtig, Aspekte wie Datensatzstruktur, Dateipfade und Kompatibilität mit den Datenverarbeitungstools von Huggingface zu berücksichtigen.


Angenommen, Sie haben Ihre Konditionierungsbilder bereits erstellt und verfügen über die folgende Ordnerstruktur:

my_dataset/
├── README.md
└──data/
   ├── captions.jsonl
   ├── conditioning_images
   │   ├── 00001.jpg
   │   └── 00002.jpg
   └── images
       ├── 00001.jpg
       └── 00002.jpg

In dieser Struktur speichert der Ordner „conditioning_images“ Ihre Konditionierungsbilder, während der Ordner „images“ die Zielbilder für Ihr ControlNet enthält. Die Datei captions.jsonl enthält die mit diesen Bildern verknüpften Bildunterschriften.

{"image": "images/00001.jpg", "text": "This is the caption of the first image."}
{"image": "images/00002.jpg", "text": "This is the caption of the second image."}

Hinweis
Die Untertiteldatei (oder die folgende Metadatendatei) kann auch eine CSV-Datei sein. Wenn Sie sich jedoch für CSV entscheiden, achten Sie auf das Werttrennzeichen, da der Text möglicherweise Kommas enthält, was zu Problemen beim Parsen führen kann.

Erstellen Sie eine Metadatendatei

Eine Metadatendatei ist eine gute Möglichkeit, zusätzliche Informationen zu Ihrem Datensatz bereitzustellen. Es kann verschiedene Arten von Daten enthalten, wie z. B. Begrenzungsrahmen, Kategorien, Text oder in unserem Fall einen Pfad zum Konditionierungsbild.

Lassen Sie uns die Datei metadata.jsonl erstellen:

import json
from pathlib import Path

def create_metadata(data_dir, output_file):
    metadata = []
    try:
        with open(f"{data_dir}/captions.jsonl", "r") as f:
            for line in f:
                data = json.loads(line)
                file_name = Path(data["image"]).name
                metadata.append(
                    {
                        "image": data["image"],
                        "conditioning_image": f"conditioning_images/{file_name}",
                        "text": data["text"],
                    }
                )

        with open(f"{data_dir}/metadata.jsonl", "w") as f:
            for line in metadata:
                f.write(json.dumps(line) + "\n")
    except (FileNotFoundError, json.JSONDecodeError) as e:
        print(f"Error processing data: {e}")

# Example usage:
data_dir = "my_dataset/data"
create_metadata(data_dir)

Dadurch wird eine metadata.jsonl erstellt, die alle Informationen enthält, die wir für unser ControlNet benötigen. Jede Zeile in der Datei entspricht einem Bild, einem Konditionierungsbild und der zugehörigen Textbeschriftung.

{"image": "images/00001.jpg", "conditioning_image": "conditioning_images/00001.jpg", "text": "This is the caption of the first image."}
{"image": "images/00002.jpg", "conditioning_image": "conditioning_images/00002.jpg", "text": "This is the caption of the second image."}

Sobald Sie die Datei metadata.jsonl erstellt haben, sollte Ihre Dateistruktur wie folgt aussehen:

my_dataset/
├── README.md
└──data/
   ├── captions.jsonl
   ├── metadata.jsonl
   ├── conditioning_images
   │   ├── 00001.jpg
   │   └── 00002.jpg
   └── images
       ├── 00001.jpg
       └── 00002.jpg

Erstellen Sie ein Ladeskript

Schließlich müssen wir ein Ladeskript erstellen, das alle Daten in der Datei metadata.jsonl verarbeitet. Das Skript sollte sich im selben Verzeichnis wie der Datensatz befinden und denselben Namen haben.

Ihre Verzeichnisstruktur sollte so aussehen:

my_dataset/
├── README.md
├── my_dataset.py
└──data/
   ├── captions.jsonl
   ├── metadata.jsonl
   ├── conditioning_images
   │   ├── 00001.jpg
   │   └── 00002.jpg
   └── images
       ├── 00001.jpg
       └── 00002.jpg

Für das Skript müssen wir eine Klasse implementieren, die von GeneratorBasedBuilder erbt und diese drei Methoden enthält:

  • _info speichert Informationen zu Ihrem Datensatz.
  • _split_generators definiert die Teilungen.
  • _generate_examples generiert die Bilder und Beschriftungen für jede Aufteilung.
import datasets

class MyDataset(datasets.GeneratorBasedBuilder):

    def _info(self):

    def _split_generators(self, dl_manager):

    def _generate_examples(self, metadata_path, images_dir, conditioning_images_dir):

Datensatz-Metadaten hinzufügen

Es gibt viele Möglichkeiten, Informationen zu Ihrem Datensatz anzugeben, aber die wichtigsten sind:

  • Features geben die Spaltentypen des Datensatzes an.
    • Bild ist eine Bildfunktion
    • conditioning_image ist eine Bildfunktion
    • text ist ein Zeichenfolgenwert
  • supervised_keys, die die Eingabefunktionen angeben.
# Global variables
_DESCRIPTION = "TODO"
_HOMEPAGE = "TODO"
_LICENSE = "TODO"
_CITATION = "TODO"

_FEATURES = datasets.Features(
    {
        "image": datasets.Image(),
        "conditioning_image": datasets.Image(),
        "text": datasets.Value("string"),
    },
)

Wie Sie oben sehen können, habe ich einige Variablen auf „TODO“ gesetzt. Diese Optionen dienen nur zu Informationszwecken und haben keinen Einfluss auf das Laden.

def _info(self):
    return datasets.DatasetInfo(
                description=_DESCRIPTION,
                features=_FEATURES,
                supervised_keys=("conditioning_image", "text"),
                homepage=_HOMEPAGE,
                license=_LICENSE,
                citation=_CITATION,
            )

Definieren Sie die Datensatzaufteilungen

dl_manager wird verwendet, um einen Datensatz aus einem Huggingface-Repo herunterzuladen, aber hier verwenden wir ihn, um den Datenverzeichnispfad abzurufen, der in der Funktion „load_dataset“ übergeben wird.

Hier definieren wir die lokalen Pfade zu unseren Daten

  • metadata_path Pfad der Datei metadata.jsonl
  • images_dir Pfad zu den Bildern
  • conditioning_images_dir Pfad zu den Konditionierungsbildern

Hinweis
Wenn Sie andere Namen für Ihre Ordnerstruktur gewählt haben, müssen Sie möglicherweise die Variablen metadata_path, images_dir undconditioning_images_dir anpassen.

def _split_generators(self, dl_manager):
    base_path = Path(dl_manager._base_path).resolve()
    metadata_path = base_path / "data" / "metadata.jsonl"
    images_dir = base_path / "data"
    conditioning_images_dir = base_path / "data"

    return [
        datasets.SplitGenerator(
            name=datasets.Split.TRAIN,
            # These kwargs will be passed to _generate_examples
            gen_kwargs={
                "metadata_path": str(metadata_path),
                "images_dir": str(images_dir),
                "conditioning_images_dir": str(conditioning_images_dir),
            },
        ),
    ]

Die letzte Methode lädt die Datei matadata.jsonl und generiert das Bild und das zugehörige Konditionierungsbild und den dazugehörigen Text.

@staticmethod
def load_jsonl(path):
    """Generator to load jsonl file."""
    with open(path, "r") as f:
        for line in f:
            yield json.loads(line)

def _generate_examples(self, metadata_path, images_dir, conditioning_images_dir):
    for row in self.load_jsonl(metadata_path):
        text = row["text"]

        image_path = row["image"]
        image_path = os.path.join(images_dir, image_path)
        image = open(image_path, "rb").read()

        conditioning_image_path = row["conditioning_image"]
        conditioning_image_path = os.path.join(
            conditioning_images_dir, row["conditioning_image"]
        )
        conditioning_image = open(conditioning_image_path, "rb").read()
        yield row["image"], {
            "text": text,
            "image": {
                "path": image_path,
                "bytes": image,
            },
            "conditioning_image": {
                "path": conditioning_image_path,
                "bytes": conditioning_image,
            },
        }

Mit diesen Schritten können Sie einen ControlNet-Datensatz von einem lokalen Pfad laden.

# with the loading script, we can load the dataset
ds = load_dataset("my_dataset")

# (optional)
# pass trust_remote_code=True to avoid the warning about custom code
# ds = load_dataset("my_dataset", trust_remote_code=True)

Wenn Sie Fragen haben, können Sie unten gerne einen Kommentar hinterlassen.


Vollständiger Code für das Ladeskript:

import os
import json
import datasets
from pathlib import Path

_VERSION = datasets.Version("0.0.2")

_DESCRIPTION = "TODO"
_HOMEPAGE = "TODO"
_LICENSE = "TODO"
_CITATION = "TODO"

_FEATURES = datasets.Features(
    {
        "image": datasets.Image(),
        "conditioning_image": datasets.Image(),
        "text": datasets.Value("string"),
    },
)

_DEFAULT_CONFIG = datasets.BuilderConfig(name="default", version=_VERSION)

class MyDataset(datasets.GeneratorBasedBuilder):
    BUILDER_CONFIGS = [_DEFAULT_CONFIG]
    DEFAULT_CONFIG_NAME = "default"

    def _info(self):
        return datasets.DatasetInfo(
            description=_DESCRIPTION,
            features=_FEATURES,
            supervised_keys=("conditioning_image", "text"),
            homepage=_HOMEPAGE,
            license=_LICENSE,
            citation=_CITATION,
        )

    def _split_generators(self, dl_manager):
        base_path = Path(dl_manager._base_path)
        metadata_path = base_path / "data" / "metadata.jsonl"
        images_dir = base_path / "data"
        conditioning_images_dir = base_path / "data"

        return [
            datasets.SplitGenerator(
                name=datasets.Split.TRAIN,
                # These kwargs will be passed to _generate_examples
                gen_kwargs={
                    "metadata_path": metadata_path,
                    "images_dir": images_dir,
                    "conditioning_images_dir": conditioning_images_dir,
                },
            ),
        ]

    @staticmethod
    def load_jsonl(path):
        """Generator to load jsonl file."""
        with open(path, "r") as f:
            for line in f:
                yield json.loads(line)

    def _generate_examples(self, metadata_path, images_dir, conditioning_images_dir):
        for row in self.load_jsonl(metadata_path):
            text = row["text"]

            image_path = row["image"]
            image_path = os.path.join(images_dir, image_path)
            image = open(image_path, "rb").read()

            conditioning_image_path = row["conditioning_image"]
            conditioning_image_path = os.path.join(
                conditioning_images_dir, row["conditioning_image"]
            )
            conditioning_image = open(conditioning_image_path, "rb").read()
            yield row["image"], {
                "text": text,
                "image": {
                    "path": image_path,
                    "bytes": image,
                },
                "conditioning_image": {
                    "path": conditioning_image_path,
                    "bytes": conditioning_image,
                },
            }

Das obige ist der detaillierte Inhalt vonSchritt-für-Schritt-Anleitung: Laden eines HuggingFace ControlNet-Datensatzes von einem lokalen Pfad. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn