[-1–>

Pham Hong Vinh's avatar
الصورة الرمزية سايك بول


يمكن لمحولات الانتشار الكبيرة إنشاء صور مذهلة (أو حتى مقاطع فيديو ومقتطفات صوتية، والآن نص)، ولكن تحميل نموذج حديث لتحويل النص إلى صورة بدقة BF16 غالبًا ما يتطلب 20-30 جيجابايت من VRAM، مما يجعل هذه النماذج بعيدًا عن متناول معظم وحدات معالجة الرسومات الاستهلاكية. يعد التكميم حلاً قويًا لهذه المشكلة، ويدمج Diffusers بالفعل العديد من الواجهات الخلفية للتكميم مثل bitsandbytes وGGUF وtorchao وQuanto، والتي تناولناها في استكشاف الواجهات الخلفية للتكميم في Diffusers.

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

SVDQuant، طريقة التكميم وراء محرك الاستدلال Nunchaku الشهير، تتبع نهجًا مختلفًا. فهو يقوم بتشغيل طبقات المحولات الرئيسية بأوزان وعمليات تنشيط 4 بت (W4A4)، مما يقلل الذاكرة مع تسريع حلقة تقليل الضوضاء أيضًا. يتم تناول التفاصيل أدناه، ولكن حتى الآن، يتطلب استخدام نقاط التفتيش هذه مكتبة استدلال منفصلة.

باستخدام أجهزة النشر الحالية، أصبح تحميل نقطة تفتيش الننشاكو أمرًا بسيطًا مثل الاتصال from_pretrained()، مع عدم الحاجة إلى تجميع CUDA المحلي بفضل kernels طَرد. بالإضافة إلى ذلك، تتيح لك مجموعة أدوات ضاغط النشر المصاحبة قياس البنى الجديدة بنفسك ونشرها كمستودعات ناشرين عادية.

مقارنة جودة الصورة والأداء في Nunchaku Lite

جدول المحتويات

البدء باستخدام Nunchaku Lite

أولا، تثبيت المتطلبات. أنت بحاجة إلى إصدار حديث من Diffusers and the Hugging Face kernels طَرد:

pip install -U diffusers transformers accelerate kernels bitsandbytes

ثم قم بتحميل خط أنابيب محدد مسبقًا مثل أي نموذج Diffusers آخر:

import torch
from diffusers import ErnieImagePipeline

pipe = ErnieImagePipeline.from_pretrained(
    "lite-infer/ERNIE-Image-Turbo-nunchaku-lite-nvfp4_r32-bnb4-text-encoder",
    torch_dtype=torch.bfloat16,
).to("cuda")

image = pipe(
    prompt="A cinematic portrait of a red fox in a misty forest at sunrise, "
           "detailed fur, volumetric light",
    height=1024,
    width=1024,
    num_inference_steps=8,
    guidance_scale=1.0,
    generator=torch.Generator("cuda").manual_seed(42),
).images[0]
image.save("output.png")
يتم إخراج BF16 وNunchaku Lite لمطالبة الثعلب الأحمر

ليست هناك حاجة إلى فئة خطوط أنابيب مخصصة أو محرك استدلال منفصل، ولا يوجد شيء لتجميعه محليًا. يتم تنزيل حبات NVFP4 من المركز من خلال صفحة حبات Nunchaku Lite عند استخدامها لأول مرة. تقوم نقطة التفتيش هذه بإقران محول Nunchaku NVFP4 مع برنامج تشفير النص bitsandbytes NF4، وتولد صورة بحجم 1024×1024 في حوالي 1.7 ثانية على RTX 5090 مع ذروة استخدام للذاكرة تبلغ حوالي 12 جيجابايت، مقارنة بحوالي 24 جيجابايت لخط أنابيب BF16. يمكنك العثور على مزيد من التفاصيل حول تنسيق نقطة تفتيش Nunchaku Lite في وثائق Diffusers الرسمية.

تتطلب نقاط فحص NVFP4 وحدة معالجة الرسومات NVIDIA Blackwell (سلسلة RTX 50 وRTX PRO 6000 وB200). بالنسبة للأجيال السابقة، استخدم متغيرات INT4. راجع جدول دعم الأجهزة أدناه للحصول على التفاصيل.

الخلفية: SVDQuant وNunchaku

SVDQuant هي طريقة التكميم وراء الننشاكو، محرك الاستدلال CUDA المرجعي. يعد التكميم القياسي ذو 4 بتات أمرًا صعبًا بالنسبة لمحولات الانتشار لأن كلاً من الأوزان والتنشيطات تحتوي على قيم متطرفة كبيرة. يتعامل SVDQuant مع هذا عن طريق نقل قيم التنشيط المتطرفة إلى الأوزان، مما يمثل الجزء الأصعب من كل مصفوفة وزن مع فرع صغير منخفض الرتبة 16 بت، وتكميم المتبقي إلى 4 بت. يجعل الننشاكو هذا الأمر سريعًا باستخدام حبات مدمجة لمسار 4 بت والفرع ذو الرتبة المنخفضة.

دمج نواة الننشاكو: يتم دمج الإسقاط ذو الرتبة المنخفضة مع تكميم المدخلات، ويتم دمج الإسقاط ذو الرتبة المنخفضة مع ماتمول 4 بت
يدمج الننشاكو الإسقاط ذو الرتبة المنخفضة مع نواة التكميم والإسقاط ذو الرتبة المنخفضة مع نواة حسابية 4 بت، مما يلغي عبء الوصول إلى الذاكرة للفرع 16 بت. الشكل من ورقة SVDQuant.

تقديم الننشاكو لايت

يحصل محرك الننشاكو الأصلي على الكثير من سرعته من مسارات التنفيذ المدمجة الخاصة بنموذج معين، مثل إسقاطات QKV المندمجة ونواة GELU/MLP المندمجة. ترتبط هذه التحسينات بتخطيط الوحدة النمطية لكل بنية وتنسيق نقطة التفتيش، لذا فإن دعم عائلة النماذج الجديدة يتطلب عادةً عمل تكامل خاص بالنموذج.

الننشاكو لايت هو مسار التكامل الجديد في Diffusers. باستخدامه، يمكن للناشرين تحميل نقاط التفتيش على نمط الننشاكو بدون مسار مخصص أو محرك استدلال منفصل. تحت الغطاء، يقوم Nunchaku Lite بتصحيح العناصر ذات الصلة nn.Linear وحدات نموذج الناشرين الأسهم مع الطبقات الخطية SVDQ/AWQ وقت التشغيل قبل تحميل نقطة التفتيش. تأتي حبات CUDA من المحور عبر kernels طَرد. يتم استخدام عائلتين من النواة:

  • svdq_w4a4: أوزان وتنشيطات 4 بت مع تصحيح الرتبة المنخفضة SVDQuant. يتم استخدام هذه الطبقة لانتباه المحول وإسقاطات MLP، حيث يتم إنفاق كل الحوسبة تقريبًا، وهي متوفرة في متغيرات INT4 وNVFP4.
  • awq_w4a16: أوزان 4 بت مع عمليات تنشيط 16 بت، تُستخدم للتطبيع التكيفي وإسقاطات التعديل مثل FLUX adanorm_single / adanorm_zero أو طبقات تعديل Qwen-Image. هذه الطبقات مرتبطة بالذاكرة وحساسة للدقة، مما يجعل AWQ مناسبًا جيدًا للحفاظ على الدقة مع الاستمرار في توفير الذاكرة والمساحة.

والمقايضة هي أنه بدون النواة والوحدات المدمجة الخاصة بالهندسة المعمارية، لا يمكن للننشاكو لايت أن يضاهي سرعة محرك الننشاكو الأصلي. ومع ذلك، فإن التنفيذ الأساسي لا يزال يحقق النجاح تسريع 30% مع الاحتفاظ بنفس المستوى تخفيض VRAM.

التحميل الأصلي في الناشرون

إذا كنت قد استخدمت وحدات البت ساندبايت أو الشعلة في الموزعات، فستشعر أن الآليات مألوفة. مستودع نماذج Nunchaku Lite هو مستودع عادي للناشرين. الجزء الخاص الوحيد هو أ quantization_config كتلة داخل المحولات config.json:

"quantization_config": {
    "quant_method": "nunchaku_lite",
    "compute_dtype": "bfloat16",
    "svdq_w4a4": {
        "precision": "nvfp4",
        "group_size": 16,
        "rank": 32,
        "targets": [
            "layers.0.self_attention.to_q",
            "layers.0.self_attention.to_k",
            "..."
        ]
    },
    "awq_w4a16": {
        "precision": "int4",
        "group_size": 64,
        "targets": [
            "adaLN_modulation.1",
            "..."
        ]
    }
}

يخبر هذا التكوين الناشرين بالوحدات التي تم تحديد كميتها، والمخطط الذي يستخدمونه، وطبقة وقت تشغيل Nunchaku Lite التي سيتم إنشاء مثيل لها (SVDQW4A4Linear أو AWQW4A16Linear).

لأن النموذج الكمي يحافظ على بنية الوحدة الدقيقة للنموذج الكثيف، كل شيء في اتجاه مجرى النهر (المجدولون، وخطافات تحميل LoRA، والتفريغ، torch.compile) يرى نموذج الناشرين العادي.

دعم الأجهزة

يستخدم Nunchaku Lite متغيرات مختلفة للنواة اعتمادًا على توليد وحدة معالجة الرسومات ودقة نقطة التفتيش:

مخطط دقة وحدات معالجة الرسومات المدعومة
svdq_w4a4 nvfp4 بلاكويل (سلسلة RTX 50، RTX PRO 6000، B200)
svdq_w4a4 int4 تورينج / أمبير / Ada (سلسلة RTX 30 و40، A100، L40S)
awq_w4a16 int4 تورينج / أمبير / Ada (سلسلة RTX 30 و40، A100، L40S)

وحدات معالجة الرسومات Volta وHopper غير مدعومة حاليًا بواسطة نواة 4 بت. يتحقق جهاز القياس من صحة قدرة CUDA الخاصة بوحدة معالجة الرسومات في وقت التحميل ويثير خطأ واضحًا بدلاً من إنتاج مخرجات غير صحيحة.

الحصول على سرعة أكبر وذاكرة أقل

يمكن دمج Nunchaku Lite مع ذاكرة Diffusers الأخرى وتحسينات السرعة.

torch.compile. يؤدي تجميع المحول إلى تحسين السرعة الشاملة من 1.35x إلى 1.8x:

pipe.transformer.compile(fullgraph=True)



pipe.transformer.compile_repeated_blocks(fullgraph=True)

ترميز النص الكمي. المحول ليس هو المكون الوحيد الذي له مساحة ذاكرة كبيرة. يمكن أن تشغل برامج تشفير النصوص مثل T5 أو Qwen3 عدة غيغابايت بمفردها. يؤدي إجراء المزيد من القياس الكمي لمشفر النص باستخدام وحدات البت ساندبايت NF4 إلى تقليل ذروة ذاكرة الفيديو VRAM بحوالي 22% في معيارنا.

التفريغ. الناشرون يفرغون المساعدين مثل enable_model_cpu_offload() و enable_sequential_cpu_offload() اعمل كالمعتاد إذا كنت بحاجة إلى تركيب خط الأنابيب على وحدة معالجة رسومات أصغر.

المعايير

تم قياس جميع الأرقام أدناه على NVIDIA RTX PRO 6000 (Blackwell) بدقة 1024×1024 باستخدام rootonchair/ERNIE-Image-Turbo-nunchaku-lite-int4-bnb4-text-encoder.

الكمون والذاكرة من النهاية إلى النهاية

إعدادات خط أنابيب كامل حلقة دينواز ذروة VRAM تسريع
خط الأساس BF16 3.00 ثانية 2.86 ثانية 31.1 جيجابايت 1.0x
الننشاكو لايت NVFP4 2.27 ثانية 2.13 ثانية 20.6 جيجابايت 1.35x
الننشاكو لايت NVFP4 + torch.compile 1.68 ثانية 1.53 ثانية 20.6 جيجابايت 1.8x
Nunchaku Lite NVFP4 + NF4 برنامج تشفير النص 2.29 ثانية 2.13 ثانية 16.0 جيجابايت 1.35x

كما هو موضح أعلاه، يعمل Nunchaku على تقليل ذروة VRAM بنسبة تصل إلى 50% مع الاستمرار في تحسين زمن الوصول بنسبة 30% تقريبًا. وتأتي النفقات العامة المتبقية إلى حد كبير من عمليات إطلاق النواة الإضافية، والتي torch.compile يمكن تخفيفه، مما يؤدي إلى خفض خط الأنابيب بالكامل إلى 1.68 ثانية، أو 1.8 مرة أسرع من خط الأساس BF16.

جودة الصورة

شبكة مقارنة الجودة
BF16 مقابل مخرجات 4 بت مع بذور وإعدادات متطابقة.

تكميم النموذج الخاص بك

دعم Nunchaku Lite في Diffusers لا يعتمد على البنية المعمارية، وتوفر مجموعة أدوات ضاغط الانتشار سير عمل SVDQuant شامل لنماذج Diffusers: المعايرة، والتكميم، والتعبئة، والنشر.

أدناه، نسير عبر تكميم FLUX.2 Klein 4B كمثال. ويغطي الخطوات الرئيسية: فحص النموذج، ومعايرة المحول وكميته، وتجميع النتيجة كخط أنابيب الناشرين، ثم التحقق منه ودفعه إلى المحور. يغطي البرنامج التعليمي الكامل كل علم بالتفصيل.

1. فحص ما سيتم كميته

يسير الماسح الضوئي العام في النموذج ويقرر ما يجب استهدافه: تصبح الخطوط الخطية المتوافقة داخل مجموعة كتل المحولات المتكررة أهدافًا SVDQ W4A4، وتصبح خطوط التعديل المعترف بها أهدافًا AWQ W4A16، ويظل كل شيء آخر كثيفًا.

python examples/text_to_image/quantize_hf.py black-forest-labs/FLUX.2-klein-4B \
  --precision int4 --rank 32 --inspect-config

اقرأ هذا التقرير دائمًا قبل القياس الكمي. بالنسبة لـ FLUX.2 Klein 4B، النتيجة المتوقعة هي 100 هدف SVDQ، و3 أهداف AWQ، و6 خطوط خطية خارجية كثيفة، مع عدم وجود أنماط مفقودة أو أسماء مكررة.

2. تشغيل التكميم

يقوم الأمر التالي بتشغيل SVDQuant على المحول ويكتب نقطة التحقق الكمية إليه outputs/checkpoints/svdq-int4_r32-flux-2-klein-4b.safetensors:

python examples/text_to_image/quantize_hf.py black-forest-labs/FLUX.2-klein-4B \
  --precision int4 \
  --output outputs/checkpoints/svdq-int4_r32-flux-2-klein-4b.safetensors

يستبدل --precision int4 مع nvfp4 لبناء أوزان بلاكويل الأصلية.

3. قم بتعبئة خط أنابيب الناشرين

يجمع المحول بين المحول الكمي والمكونات الأخرى لخط الأنابيب الأساسي، ويكتب الاتفاق nunchaku_lite التكوين في transformer/config.json، ويمكن اختياريًا تحويل برامج ترميز النص إلى NF4:

python examples/convert_nunchaku_lite_diffusers.py \
  --checkpoint outputs/checkpoints/svdq-int4_r32-flux-2-klein-4b.safetensors \
  --model-id black-forest-labs/FLUX.2-klein-4B \
  --bnb4-text-encoder text_encoder \
  --compute-dtype bfloat16 \
  --output-dir outputs/diffusers/FLUX.2-klein-4B-nunchaku-lite-int4-bnb4-text-encoder

4. قم بالتحميل والتحقق والدفع إلى المحور

import torch
from diffusers import DiffusionPipeline

pipe = DiffusionPipeline.from_pretrained(
    "outputs/diffusers/FLUX.2-klein-4B-nunchaku-lite-int4-bnb4-text-encoder",
    device_map="cuda",
)
image = pipe(
    "A glass robot in a greenhouse, cinematic lighting",
    num_inference_steps=4, guidance_scale=1.0,
    generator=torch.Generator("cuda").manual_seed(12345),
).images[0]

بمجرد أن تبدو المخرجات جيدة، قم بالتشغيل pipe.push_to_hub("your-name/your-model-nunchaku-lite-int4"). يمكن للمستخدمين الآخرين بعد ذلك تحميله بنفس الشيء from_pretrained() النمط الموضح أعلاه.

نماذج الكم مع إعادة الكتابة الهيكلية

لاحظ أن المسار العام يفترض أن البنية يمكن قياسها كميًا دون إعادة كتابة هيكلية. لمزيد من التسريع، يقوم محرك Nunchaku الأصلي بإعادة كتابة مجموعات من طبقات الموزعات كوحدات مدمجة. لا يمكن للمسار العام استنتاج هذه التغييرات من تلقاء نفسه، مثل دمج إسقاطات Q وK وV المنفصلة في وحدة نمطية واحدة أو تقسيم إسقاط مدمج عبر عدة وحدات.

يعد إسقاط QKV الخاص بـ FLUX.1-dev مثالًا ملموسًا. يحدد الناشرون ثلاث وحدات منفصلة:

self.to_q = torch.nn.Linear(query_dim, self.inner_dim, bias=bias)
self.to_k = torch.nn.Linear(query_dim, self.inner_dim, bias=bias)
self.to_v = torch.nn.Linear(query_dim, self.inner_dim, bias=bias)

تجمع وحدة Nunchaku FLUX بين هذه الطبقات في طبقة واحدة كمية to_qkv الوحدة النمطية:

to_qkv = fuse_linears([other.to_q, other.to_k, other.to_v])
self.to_qkv = SVDQW4A4Linear.from_linear(to_qkv, **kwargs)

هذه الوحدة المجمعة مطلوبة لأن مشغل الننشاكو المدمج يستهلك إسقاط QKV، وتطبيع Q/K، والتضمينات الدوارة معًا. بالمقارنة، فإن مسار Diffusers الافتراضي ينفذها بشكل منفصل:

query = attn.to_q(hidden_states)
key = attn.to_k(hidden_states)
value = attn.to_v(hidden_states)

query = query.unflatten(-1, (attn.heads, -1))
key = key.unflatten(-1, (attn.heads, -1))
value = value.unflatten(-1, (attn.heads, -1))

query = attn.norm_q(query)
key = attn.norm_k(key)

if image_rotary_emb is not None:
    query = apply_rotary_emb(query, image_rotary_emb, sequence_dim=1)
    key = apply_rotary_emb(key, image_rotary_emb, sequence_dim=1)

يوفر مسار الننشاكو الإسقاط المجمع ووحدات التطبيع والتضمين الدوار لمشغل واحد مدمج:

qkv = fused_qkv_norm_rottary(
    hidden_states, attn.to_qkv, attn.norm_q, attn.norm_k, image_rotary_emb
)

هذه هي إعادة الكتابة الهيكلية التي لا يمكن للمسار العام استنتاجها. يحتوي الناشرون على ثلاث وحدات وجهة مع to_q, to_k، و to_v بادئات المعلمات، بينما يحتوي الننشاكو على وحدة مجمعة واحدة ضمنها to_qkv. يجب أن يوضح التكوين أو المحول المستهدف الخاص بالنموذج أن معلمات Q وK وV يجب أن تكون متسلسلة على طول بُعد الإخراج، بهذا الترتيب، وتحميلها في to_qkv.

يتم وصف عمليات إعادة الكتابة الهيكلية مثل هذه من خلال تكوين هدف خاص بالنموذج أثناء القياس الكمي ويتم التعامل معها بواسطة محول وقت تشغيل صغير عند تحميل نقطة التحقق. يوفر البرنامج النصي للتكميم FLUX.2 Klein 4B مثالاً ملموسًا لتكوين الهدف لإنتاج نقطة تفتيش معاد كتابتها هيكليًا، بينما يوفر rootonchair/nunchaku-lite محولات وقت التشغيل اللازمة لتحميل موترات QKV المجمعة، والإسقاطات المندمجة المنفصلة، ​​وغيرها من العمليات المدمجة. للحصول على سير العمل الكامل، يمكنك التحقق من دليل إضافة نموذج جديد.

نقاط تفتيش جاهزة للاستخدام

للبدء على الفور، تحقق من المستودعات التالية:

خاتمة

تعد نواة SVDQuant الخاصة بـ Nunchaku واحدة من أكثر الطرق فعالية لتشغيل محولات الانتشار بكفاءة على الأجهزة الاستهلاكية، وهي الآن مدعومة محليًا في Diffusers. يتم تحميل نقاط التفتيش الكمية مسبقًا from_pretrained()، ومجموعة أدوات الضاغط المنتشر تجعل من الممكن قياس البنى الجديدة دون انتظار دعم المحرك. من خلال قياس كل من الأوزان وعمليات التنشيط، يقلل مسار W4A4 من استخدام الذاكرة مع تحسين زمن الوصول لتقليل الضوضاء، مما يحافظ على جودة الصورة قريبة من جودة BF16 الأصلية.

إذا قمت بقياس نموذج جديد ونشره، فإننا نود أن نسمع عنه. شاركها على المحور وأخبرنا بذلك! إذا كانت لديك أي أسئلة حول هذه الميزة، فلا تتردد في الانضمام إلى Discord الخاص بنا.

لمعرفة المزيد، راجع الموارد التالية:

شكر وتقدير

شكرًا لمشرفي Diffusers على المراجعات والتوجيه طوال عملية التكامل، ولفريق MIT HAN Lab / Nunchaku على عمل SVDQuant الأصلي. شكرًا لمارك صن لتقديم تعليقاته على مشاركة المدونة. شكرًا لألفارو سوموزا على تجربته nunchaku-lite ولتقديم ردود الفعل.

rootonchair كما يعرب عن امتنانه لـ SilverAI لدعم هذا العمل وتوفير البيئة التي حدث فيها الكثير من هذا التطوير.

شاركها.
اترك تعليقاً