Hub documentation

DDUF

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

DDUF

نظرة عامة

DDUF (تنسيق DDUF الموحّد للأنماط Diffusion Unified Format) هو تنسيق ملف واحد لأنماط الانتشار يهدف إلى توحيد طرق توزيع الأنماط المختلفة وتنسيقات حفظ الأوزان من خلال حزم جميع مكونات النموذج في ملف واحد. وهو مستقل عن اللغة، ومصمم ليكون قابلاً للتفسير من موقع بعيد دون الحاجة إلى تنزيل الملف بأكمله.

يستلهم هذا العمل من صيغة GGUF.

اطّلع على منظمة DDUF لبدء استخدام بعض أكثر نماذج الانتشار شيوعًا في DDUF.

نرحب بالمساهمات من كل قلب!

لإنشاء صيغة ملفات واسعة الانتشار، نحتاج إلى ملاحظات مبكرة من المجتمع. لا شيء محسوم بعد، ونقدّر مساهمات الجميع. هل حالتك الخاصة غير مغطاة؟ يرجى إعلامنا في المناقشات الخاصة بمنظمة DDUF.

تشمل ميزاتها الرئيسية ما يلي.

  1. التغليف في ملف واحد.
  2. يعتمد على صيغة ملف ZIP للاستفادة من الأدوات الموجودة مسبقًا.
  3. بدون ضغط، مما يضمن توافق mmap للتحميل والحفظ السريعين.
  4. غير مرتبط بلغة معينة: يمكن تنفيذ الأدوات باستخدام Python أو JavaScript أو Rust أو C++ وغيرها.
  5. متوافق مع HTTP: يمكن جلب البيانات الوصفية وهيكل الملفات عن بُعد باستخدام طلبات HTTP Range.
  6. مرن: يُخزَّن كل مكوّن من مكوّنات النموذج في مجلده الخاص، بما يتوافق مع بنية Diffusers الحالية.
  7. آمن: يستخدم Safetensors كصيغة لحفظ الأوزان ويمنع المجلدات المتداخلة لمنع قنابل ZIP.

المواصفات التقنية

من الناحية التقنية، ملف .dduf هو أرشيف .zip. ومن خلال البناء على صيغة ملفات مدعومة عالمياً، نضمن وجود أدوات قوية بالفعل. ومع ذلك، يتم فرض بعض القيود لتلبية متطلبات نماذج الانتشار:

  • يجب تخزين البيانات دون ضغط (العلم 0)، مما يتيح التحميل الكسول باستخدام خرائط الذاكرة.
  • يجب تخزين البيانات باستخدام بروتوكول 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).
  • يُمنع استخدام المجلدات الفرعية.

هل تريد التحقق من صحة ملفك؟ يمكنك ذلك باستخدام هذا المساحة: 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 تعيد خرائط (mapping) حيث يتوافق كل عنصر مع ملف في أرشيف DDUF. يتم تمثيل الملف بواسطة كلاس بيانات DDUFEntry يحتوي على اسم الملف، والإزاحة (offset)، والطول للعنصر في ملف DDUF الأصلي. هذه المعلومات مفيدة لقراءة محتواه دون تحميل الملف بأكمله. عملياً، لن تحتاج إلى التعامل مع القراءة على المستوى المنخفض، بل ستعتمد على الدوال المساعدة (helpers) بدلاً من ذلك.

على سبيل المثال، إليك كيفية تحميل محتوى 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 في سياق مدير (context manager) للاستفادة من خصائص تعيين الذاكرة (memory-mapping).

كيف تكتب ملف 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 القيام بذلك من خلال توفير 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. فيما يلي مثال على كيفية تحميل خط أنابيب (pipeline) من نقطة تحقق (checkpoint) محفوظة على 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 يحتوي على فهرس محتويات في بداية الأرشيف؟

انظر إلى الشرح في هذا تعليق.

لماذا لا يوجد ضغط؟

  • يتيح تعيين ذاكرة مباشر للملفات الكبيرة
  • يضمن وصولاً متسقاً وقابلاً للتنبؤ إلى الملفات عن بُعد
  • يمنع الحمل على وحدة المعالجة المركزية أثناء قراءة الملفات
  • يحافظ على التوافق مع safetensors

هل يمكنني تعديل ملف DDUF؟

لا. في الوقت الحالي، صُممت ملفات DDUF لتكون غير قابلة للتعديل. لتحديث نموذج، أنشئ ملف DDUF جديدًا.

أيُّ الأطر/التطبيقات تدعم DDUFs؟

نحن نتواصل باستمرار مع مكتبات وإطارات عمل أخرى. إذا كنت مهتمًا بإضافة الدعم إلى مشروعك، فافتح نقاشًا في منظمة DDUF.

Update on GitHub