Hub documentation
DDUF
DDUF
Aperçu
DDUF (Diffusion Diffusion Unified Format) est un format de fichier unique pour les modèles de diffusion qui vise à unifier les différentes méthodes de distribution de modèles et les formats de sauvegarde des poids en regroupant tous les composants du modèle dans un seul fichier. Il est indépendant du langage et conçu pour être analysable à distance sans télécharger l’intégralité du fichier.
Ce travail s'inspire du format GGUF.
Découvrez l’organisation DDUF pour commencer à utiliser certains des modèles de diffusion les plus populaires dans DDUF.
Nous accueillons les contributions à bras ouverts !
Pour créer un format de fichier largement adopté, nous avons besoin d’un retour précoce de la communauté. Rien n’est gravé dans le marbre et nous valorisons la contribution de chacun. Votre cas d’usage n’est pas couvert ? Merci de nous en informer dans les discussions de l’organisation DDUF.
Ses principales fonctionnalités sont les suivantes.
- Emballage en fichier unique.
- Basé sur le format de fichier ZIP pour tirer parti des outils existants.
- Aucune compression, garantissant la compatibilité
mmappour un chargement et un enregistrement rapides. - Indépendant du langage : les outils peuvent être implémentés en Python, JavaScript, Rust, C++, etc.
- Compatible HTTP : les métadonnées et la structure des fichiers peuvent être récupérées à distance à l'aide de requêtes HTTP Range.
- Flexible : chaque composant du modèle est stocké dans son propre répertoire, conformément à la structure actuelle de Diffusers.
- Sûr : utilise Safetensors comme format de sauvegarde des poids et interdit les répertoires imbriqués pour prévenir les bombes ZIP.
Spécifications techniques
Techniquement, un fichier .dduf est une archive .zip. En s’appuyant sur un format de fichier universellement pris en charge, nous garantissons que des outils robustes existent déjà. Toutefois, certaines contraintes sont imposées pour répondre aux exigences des modèles de diffusion :
- Les données doivent être stockées non compressées (drapeau
0), permettant un chargement paresseux via la mémoire mappée. - Les données doivent être stockées en utilisant le protocole ZIP64, permettant l'enregistrement de fichiers de plus de 4 Go.
- L'archive ne peut contenir que des fichiers
.json,.safetensors,.modelet.txt. - Un fichier
model_index.jsondoit être présent à la racine de l'archive. Il doit contenir une correspondance clé-valeur avec les métadonnées du modèle et de ses composants. - Chaque composant doit être stocké dans son propre répertoire (par exemple,
vae/,text_encoder/). Les fichiers imbriqués doivent utiliser des séparateurs de chemin de style UNIX (/). - Chaque répertoire doit correspondre à un composant de l'index
model_index.json. - Chaque répertoire doit contenir un fichier de configuration json (l'un des
config.json,tokenizer_config.json,preprocessor_config.json,scheduler_config.json). - Les sous-répertoires sont interdits.
Vérifier si votre fichier est valide ? Utilisez cet espace : https://huggingface.co/spaces/DDUF/dduf-check.
Utilisation
huggingface_hub fournit des outils pour gérer les fichiers DDUF en Python. Il inclut des règles intégrées pour valider l’intégrité des fichiers ainsi que des utilitaires pour lire et exporter les fichiers DDUF. L’objectif est de voir cet outillage adopté dans l’écosystème Python, par exemple dans l’intégration diffusers. Des outils similaires peuvent être développés pour d’autres langages (JavaScript, Rust, C++, etc.).
Comment lire un fichier DDUF ?
Transmettez un chemin à read_dduf_file pour lire un fichier DDUF. Seules les métadonnées sont lues, ce qui en fait un appel léger qui n’explosera pas votre mémoire. Dans l’exemple ci-dessous, nous supposons que vous avez déjà téléchargé le fichier FLUX.1-dev.dduf localement.
>>> from huggingface_hub import read_dduf_file
# Read DDUF metadata
>>> dduf_entries = read_dduf_file("FLUX.1-dev.dduf")read_dduf_file renvoie un mapping où chaque entrée correspond à un fichier de l’archive DDUF. Un fichier est représenté par une dataclass DDUFEntry qui contient le nom du fichier, le décalage et la longueur de l’entrée dans le fichier DDUF d’origine. Ces informations sont utiles pour lire son contenu sans charger l’intégralité du fichier. En pratique, vous n’aurez pas à gérer la lecture de bas niveau, mais vous pourrez vous appuyer sur des fonctions d’aide.
Par exemple, voici comment charger le contenu de model_index.json :
>>> import json
>>> json.loads(dduf_entries["model_index.json"].read_text())
{'_class_name': 'FluxPipeline', '_diffusers_version': '0.32.0.dev0', '_name_or_path': 'black-forest-labs/FLUX.1-dev', ...Pour les fichiers binaires, vous souhaitez accéder aux octets bruts à l'aide de as_mmap. Cela renvoie les octets sous forme de mémoire mappée sur le fichier d'origine. La mémoire mappée vous permet de lire uniquement les octets dont vous avez besoin sans charger l'ensemble en mémoire. Par exemple, voici comment charger les poids safetensors :
>>> import safetensors.torch
>>> with dduf_entries["vae/diffusion_pytorch_model.safetensors"].as_mmap() as mm:
... state_dict = safetensors.torch.load(mm) # `mm` is a bytes object
as_mmapdoit être utilisé dans un gestionnaire de contexte pour bénéficier des propriétés de mappage mémoire.
Comment écrire un fichier DDUF ?
Transmettez un chemin de dossier à export_folder_as_dduf pour exporter un fichier DDUF.
# Export a folder as a DDUF file
>>> from huggingface_hub import export_folder_as_dduf
>>> export_folder_as_dduf("FLUX.1-dev.dduf", folder_path="path/to/FLUX.1-dev")Cet outil analyse le dossier, ajoute les entrées pertinentes et s’assure que le fichier exporté est valide. Si un problème survient au cours du processus, une DDUFExportError est levée.
Pour plus de flexibilité, utilisez [export_entries_as_dduf] pour spécifier explicitement une liste de fichiers à inclure dans le fichier DDUF final :
# Export specific files from the local disk.
>>> from huggingface_hub import export_entries_as_dduf
>>> export_entries_as_dduf(
... dduf_path="stable-diffusion-v1-4-FP16.dduf",
... entries=[ # List entries to add to the DDUF file (here, only FP16 weights)
... ("model_index.json", "path/to/model_index.json"),
... ("vae/config.json", "path/to/vae/config.json"),
... ("vae/diffusion_pytorch_model.fp16.safetensors", "path/to/vae/diffusion_pytorch_model.fp16.safetensors"),
... ("text_encoder/config.json", "path/to/text_encoder/config.json"),
... ("text_encoder/model.fp16.safetensors", "path/to/text_encoder/model.fp16.safetensors"),
... # ... add more entries here
... ]
... )export_entries_as_dduf fonctionne bien si vous avez déjà enregistré votre modèle sur le disque. Mais que faire si vous avez un modèle chargé en mémoire et que vous souhaitez le sérialiser directement dans un fichier DDUF ? export_entries_as_dduf vous le permet en fournissant un generator Python qui décrit comment sérialiser les données de manière itérative :
(...)
# Export state_dicts one by one from a loaded pipeline
>>> def as_entries(pipe: DiffusionPipeline) -> Generator[Tuple[str, bytes], None, None]:
... # Build a generator that yields the entries to add to the DDUF file.
... # The first element of the tuple is the filename in the DDUF archive. The second element is the content of the file.
... # Entries will be evaluated lazily when the DDUF file is created (only 1 entry is loaded in memory at a time)
... yield "vae/config.json", pipe.vae.to_json_string().encode()
... yield "vae/diffusion_pytorch_model.safetensors", safetensors.torch.save(pipe.vae.state_dict())
... yield "text_encoder/config.json", pipe.text_encoder.config.to_json_string().encode()
... yield "text_encoder/model.safetensors", safetensors.torch.save(pipe.text_encoder.state_dict())
... # ... add more entries here
>>> export_entries_as_dduf(dduf_path="my-cool-diffusion-model.dduf", entries=as_entries(pipe))Chargement d'un fichier DDUF avec Diffusers
Diffusers intègre nativement le support des fichiers DDUF. Voici un exemple de chargement d'un pipeline à partir d'un point de contrôle stocké sur le Hub :
from diffusers import DiffusionPipeline
import torch
pipe = DiffusionPipeline.from_pretrained(
"DDUF/FLUX.1-dev-DDUF", dduf_file="FLUX.1-dev.dduf", torch_dtype=torch.bfloat16
).to("cuda")
image = pipe(
"photo a cat holding a sign that says Diffusers", num_inference_steps=50, guidance_scale=3.5
).images[0]
image.save("cat.png")F.A.Q.
Pourquoi construire sur la base de ZIP ?
ZIP offre plusieurs avantages :
- Format de fichier universellement pris en charge
- Aucune dépendance supplémentaire pour la lecture
- Indexation de fichiers intégrée
- Large prise en charge des langues
Pourquoi ne pas utiliser un TAR avec une table des matières au début de l'archive ?
Voir l'explication dans ce commentaire.
Pourquoi pas de compression ?
- Active la correspondance directe en mémoire de fichiers volumineux
- Assure un accès aux fichiers distants cohérent et prévisible
- Prévient la surcharge du CPU lors de la lecture de fichiers
- Maintient la compatibilité avec safetensors
Puis-je modifier un fichier DDUF ?
Non. Pour le moment, les fichiers DDUF sont conçus pour être immuables. Pour mettre à jour un modèle, créez un nouveau fichier DDUF.
Quels frameworks/applications prennent en charge les DDUF ?
Nous contactons régulièrement d'autres bibliothèques et frameworks. Si vous souhaitez ajouter une prise en charge à votre projet, ouvrez une Discussion dans l'organisation DDUF.
Update on GitHub