كل بطاقة نموذج محلية تتباهى الآن بنافذة سياق 128k. على سطح المكتب، هذا الرقم عقد إيجار وقّعته الرام لديك دون قراءة. ما يحدد إلى أين تدفع وثيقة طويلة ليس الأوزان — بل ذاكرة KV، وهي تتوسع مع السياق كضريبة اتفقوا عليها بعملة غير عملتك.
نافذة السياق ليست ميزة تشغّلها وتطفئها. إنها إيجار ذاكرة تدفعه في كل ثانية يعمل فيها الخادم.
كم تستهلك نافذة 128k من الرام فعلياً؟
الحسابات معلنة وقصيرة. كما يشرح Transformer Inference Arithmetic، تحفظ ذاكرة KV موترَين — المفاتيح والقيم — لكل طبقة، ولكل رأس KV، ولكل رمز:
cache_bytes = 2 × الطبقات × السياق × رؤوس_KV × head_dim × بايتات_العنصر خذ Llama 3.1 8B: 32 طبقة، 8 رؤوس KV، وhead_dim بقيمة 128 — مباشرة من config.json على Hugging Face. عند 131,072 رمزاً بدقة fp16 (بايتان):
2 × 32 × 131072 × 8 × 128 × 2 = 17,179,869,184 بايت ≈ 16 GiB أوزان النموذج نفسه بدقة fp16 تزن نحو 16 GiB. عند أقصى سياق، تكون الذاكرة بحجم النموذج الذي تنتمي إليه. «نموذج 8B يتسع في 16 GiB» يتحول بهدوء إلى مشكلة بحجم 32 GiB لحظة ما ترفع num_ctx إلى 128k.
لماذا تنمو الذاكرة مع النافذة؟
لأن الانتباه مضطر لمقارنة كل رمز بكل ما قبله، والاستدلال ذاتي التغذية — لا يُعاد حساب شيء، ويُتذكر كل شيء. هذا هو كامل الحيلة التي تجعل التوليد سريعاً: تُحسب مفاتيح وقيم كل رمز مرة واحدة ثم تُخزَّن. التخزين لكل رمز ثابت، فيكون الإجمالي خطياً مع السياق. 128k ليست «رقماً أكبر» — إنها 128 ضعفاً من ذاكرة نافذة 1k، محجوزة طوال الجلسة.
تقنية grouped-query attention (GQA) هي خصم من جهة النموذج: رؤوس KV أقل، وذاكرة أنحف. يستخدم Qwen2.5 7B لديه 28 طبقة بـ4 رؤوس KV فقط (config هنا)، فتكلّف النافذة ذاتها نحو 7 GiB بدقة fp16 — تخفيف حقيقي، وسبب من يجعل هذه النماذج تبدو لطيفة على الأجهزة المتواضعة.
| النموذج (fp16) | طبقات × رؤوس KV | ذاكرة KV عند 128k | الأوزان | الذاكرة مقابل الأوزان |
|---|---|---|---|---|
| Llama 3.1 8B | 32 × 8 | ~16 GiB | ~16 GiB | ~100% |
| Qwen2.5 7B | 28 × 4 | ~7 GiB | ~15 GiB | ~47% |
احسبها بنفسك — كل التحقق هنا:
def kv_cache_gib(layers, kv_heads, head_dim, ctx, bytes_per=2):
return 2 * layers * ctx * kv_heads * head_dim * bytes_per / 2**30
print(kv_cache_gib(32, 8, 128, 131_072)) # Llama 3.1 8B -> 16.0
print(kv_cache_gib(28, 4, 128, 131_072)) # Qwen2.5 7B -> 7.0 ما الذي يغفل عنه الرقم التسويقي؟
هذا هو السجل الأمين لهذه الحجة — بما في ذلك مواضع انحنائها:
- التمهيد (prefill) فاتورة ثانية. قبل أول رمز إجابة، تُعالج التوجيهات كلها دفعة واحدة. توجيه من 100k رمز يعني مضغ 100k رمز قبل أول حرف. على بطاقة 3060، تلك دقائق لا ميلي ثوانٍ.
- نماذج sliding-window تكسر الحساب — لصالحك. معماريات أسلوب Mistral تحصر الانتباه في نافذة ثابتة لكل طبقة، فتتوقف الذاكرة عن النمو. الصيغة البسيطة تبالغ في تقديرها. هذه التدوينة عن المحولات ذات الانتباه الكامل — وهي معظم ما يشغّله الناس.
- ضغط ذاكرة KV حقيقي لكن جزئي. يمكن لـllama.cpp حفظ KV بترميز q8_0، فينخفض الحجم نحو النصف مقابل قدر من مخاطر الجودة. نصف 16 GiB يبقى 8 GiB.
- المواصفات نادراً ما تذكر رؤوس KV. ستفتش config.json لتجدها — وهذا بذاته يخبرك كيف أريدوا قراءة ذلك الرقم.
لا شيء من هذا يجعل السياق الطويل بلا فائدة. تقنية RAG موجودة تحديداً لأن ملء النافذة هو الطريقة المكلفة لقول «اقرأ القسم الرابع». لكن بطاقة تطبع «128k» دون طباعة فاتورة الذاكرة تبيع سيارة بأقصى سرعة ولا تذكر خزان الوقود أبداً.
لا أحد يقرأ 128,000 رمزاً. ومع ذلك تدفع الرام لديك ثمنها كله.
العلاج ممل: اضبط السياق على ما يستخدمه عملك فعلاً. نافذة 32k تكلّف ربع ذاكرة الـ128k وتغطي تقريباً كل توجيه يرسله مطوّر منفرد فعلاً. هذا هو نفس انضباط السجل في حسابات الرام للنماذج المحلية — حجم النموذج نصف الميزانية فقط، ومستويات الضغط تصغّر الأوزان ولا تمس حساب الذاكرة.
إذا كانت الذاكرة هي الثمن الحقيقي للسياق، فلماذا تبيع البطاقات النافذة ولا تبيع الفاتورة أبداً؟ وجولة الاعتراف: ما أكبر سياق ملأته فعلاً حتى آخر رمز — وهل عوّضت المخرجات تلك الجيغابايتات؟ التعليقات مفتوحة؛ ستنحاز القطعة التالية من السلسلة إلى الطرف الخاسر.
FAQ
كم من الرام تستهلك نافذة سياق 128k؟
في Llama 3.1 8B بدقة fp16، تزن ذاكرة KV وحدها نحو 16 GiB عند 131,072 رمزاً — أي بحجم أوزان النموذج تقريباً. الصيغة: 2 × الطبقات × السياق × رؤوس KV × head_dim × البايتات.
لماذا يستهلك السياق الطويل ذاكرة أكبر؟
كل رمز في الذاكرة يحفظ موتري المفاتيح والقيم لكل طبقة انتباه. ضاعف السياق تتضاعف الذاكرة. الحجز موجود حتى لو لم تملأ النافذة أبداً.
كيف أقلل ذاكرة KV في النماذج المحلية؟
اضبط السياق على ما تستخدمه فعلاً، واختر نماذج grouped-query attention (رؤوس KV أقل)، وكمّم ذاكرة KV إلى q8 حيث يدعمها محرك التشغيل، أو استخدم معماريات sliding-window والهجينة.
— mrsaynothing
— mrsaynothing
آراء تُختبر تحت الحمل قبل النشر. غالبًا.
احصل على الطرح التالي بالبريد
رسالة واحدة لكل مقال. وافق أو حطّمها.
ما هذا؟git stash: ملف واحد دون إثارة الباقي
أعجبتك هذه الكتابات؟ بناء مثل هذا هو عملي. وظّفني