Hub documentation
DDUF
DDUF
Обзор
DDUF (DDDUF’s Diffusion Unified Format) — это формат в виде одного файла для диффузионных моделей, призванный объединить различные способы распространения моделей и форматы сохранения весов, упаковывая все компоненты модели в единый файл. Он не зависит от языка программирования и разработан так, чтобы его можно было анализировать из удалённого расположения без загрузки всего файла.
Эта работа вдохновлена форматом GGUF.
Ознакомьтесь с организацией DDUF, чтобы начать использовать одни из самых популярных диффузионных моделей в DDUF.
Мы с радостью принимаем вклады!
Чтобы создать широко используемый формат файлов, нам нужна ранняя обратная связь от сообщества. Ничего не является окончательным, и мы ценим вклад каждого. Ваш сценарий использования не описан? Пожалуйста, сообщите нам об этом в обсуждениях организации DDUF discussions.
К его ключевым особенностям относятся следующие.
- Упаковка в один файл.
- Основан на формате файлов ZIP для использования существующих инструментов.
- Без сжатия, что обеспечивает совместимость с
mmapдля быстрого загрузки и сохранения. - Независимость от языка: инструменты могут быть реализованы на Python, JavaScript, Rust, C++ и т. д.
- Совместимость с HTTP: метаданные и структуру файлов можно получить удалённо с помощью HTTP Range-запросов.
- Гибкость: каждый компонент модели хранится в собственном каталоге, в соответствии с текущей структурой Diffusers.
- Safe: использует Safetensors в качестве формата сохранения весов и запрещает вложенные каталоги, чтобы предотвратить атаки ZIP-бомбами.
Технические характеристики
С технической точки зрения файл .dduf является архивом .zip. Использование универсально поддерживаемого формата файлов гарантирует наличие надежных инструментов. Однако для удовлетворения требований диффузионных моделей накладываются определенные ограничения:
- Данные должны храниться без сжатия (флаг
0), что позволяет использовать ленивую загрузку с помощью отображения в память (memory-mapping). - Данные должны храниться с использованием протокола ZIP64, что позволяет сохранять файлы размером более 4 ГБ.
- Архив может содержать только файлы
.json,.safetensors,.modelи.txt. - В корне архива должен присутствовать файл
model_index.json. Он должен содержать отображение «ключ-значение» с метаданными о модели и её компонентах. - Каждый компонент должен храниться в собственной директории (например,
vae/,text_encoder/). Вложенные файлы должны использовать разделители путей в стиле UNIX (/). - Каждая директория должна соответствовать компоненту в индексе
model_index.json. - Каждая директория должна содержать json-файл конфигурации (один из
config.json,tokenizer_config.json,preprocessor_config.json,scheduler_config.json). - Подкаталоги запрещены.
Хотите проверить, является ли ваш файл корректным? Воспользуйтесь этим Space: https://huggingface.co/spaces/DDUF/dduf-check.
Использование
Библиотека huggingface_hub предоставляет инструменты для работы с файлами DDUF в Python. Она включает встроенные правила для проверки целостности файлов и вспомогательные функции для чтения и экспорта файлов DDUF. Цель состоит в том, чтобы эти инструменты получили широкое распространение в экосистеме Python, например, в интеграции с diffusers. Аналогичные инструменты могут быть разработаны и для других языков (JavaScript, Rust, C++ и т. д.).
Как прочитать файл DDUF?
Передайте путь в read_dduf_file, чтобы прочитать файл DDUF. Читается только метаданные, то есть это легковесный вызов, который не приведет к переполнению памяти. В примере ниже предполагается, что вы уже скачали файл FLUX.1-dev.dduf локально.
>>> from huggingface_hub import read_dduf_file
# Read DDUF metadata
>>> dduf_entries = read_dduf_file("FLUX.1-dev.dduf")read_dduf_file возвращает отображение, в котором каждая запись соответствует файлу в архиве DDUF. Файл представлен датаклассом DDUFEntry, содержащим имя файла, смещение и длину записи в исходном файле DDUF. Эта информация полезна для чтения содержимого без загрузки всего файла. На практике вам не придётся заниматься низкоуровневым чтением, достаточно использовать вспомогательные функции.
Например, вот как загрузить содержимое 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', ...Для двоичных файлов для доступа к сырым байтам следует использовать as_mmap. Этот метод возвращает байты в виде отображения в память (memory-mapping) исходного файла. Благодаря отображению в память можно читать только необходимые байты, не загружая весь файл в оперативную память. Например, вот как загрузить веса 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_mmapнеобходимо использовать в контекстном менеджере, чтобы воспользоваться свойствами отображения в память.
Как создать файл DDUF?
Передайте путь к папке в export_folder_as_dduf, чтобы экспортировать файл 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")Этот инструмент сканирует папку, добавляет соответствующие записи и обеспечивает валидность экспортированного файла. Если в процессе что-то пойдёт не так, будет выброшено исключение DDUFExportError.
Для большей гибкости используйте [export_entries_as_dduf], чтобы явно указать список файлов, которые нужно включить в итоговый файл DDUF:
# 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 хорошо работает, если модель уже сохранена на диске. Но что делать, если модель загружена в память и вы хотите сериализовать её напрямую в файл DDUF? export_entries_as_dduf позволяет сделать это, передав Python-generator, который описывает, как сериализовать данные итеративно:
(...)
# 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))Загрузка файла DDUF с помощью Diffusers
Diffusers имеет встроенную интеграцию для файлов DDUF. Ниже приведен пример загрузки пайплайна из сохраненного чекпоинта на 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.
Зачем строить на базе ZIP?
ZIP обеспечивает несколько преимуществ:
- Универсально поддерживаемый формат файлов
- Нет дополнительных зависимостей для чтения
- Встроенный индекс файлов
- Широкая поддержка языков
Почему бы не использовать TAR с оглавлением в начале архива?
См. объяснение в этом комментарии.
Почему нет сжатия?
- Включает прямое отображение больших файлов в память
- Обеспечивает согласованный и предсказуемый доступ к удалённым файлам
- Предотвращает нагрузку на CPU при чтении файлов
- Поддерживает совместимость с safetensors
Можно ли изменить файл DDUF?
Нет. На данный момент файлы DDUF спроектированы как неизменяемые. Для обновления модели создайте новый файл DDUF.
Какие фреймворки/приложения поддерживают DDUF?
Мы постоянно выходим на связь с другими библиотеками и фреймворками. Если вы заинтересованы в добавлении поддержки в ваш проект, создайте Discussion в организации DDUF.
Update on GitHub