Prompt Caching
تعيد ذاكرة التخزين المؤقت للمطالبات استخدام حالات المفاتيح والقيم التي حسبها نموذج اللغة الكبير لبادئة مطالبة متكررة، فتتجاوز الطلبات اللاحقة هذه العملية وتقل تكلفتها.
يخزّن التخزين المؤقت للتوجيهات، المعروف أيضًا باسم التخزين المؤقت للبادئة، النتائج الوسيطة التي يحسبها نموذج لغوي كبير (LLM) لبداية التوجيه، ويعيد استخدامها في الطلبات اللاحقة التي تبدأ بالنص نفسه تمامًا. وتشترك طلبات كثيرة في بادئة طويلة ثابتة، مثل توجيه النظام أو تعريفات الأدوات أو مجموعة أمثلة أو مستند طويل أو سجل المحادثة حتى تلك اللحظة، يتبعها جزء جديد قصير. وعند إصابة ذاكرة التخزين المؤقت، يعالج الخادم الرموز الجديدة فقط، ما يقلل زمن الوصول إلى رمز المخرجات الأول، ويخفض، في واجهات API المستضافة، سعر المدخلات المخزنة مؤقتًا إلى جزء من السعر المعتاد.
كيفية عمل التخزين المؤقت للتوجيهات#
يجيب نموذج LLM قائم على محوّل على مرحلتين. ففي مرحلة التهيئة المسبقة، تحسب كل طبقة متجه مفتاح ومتجه قيمة لكل رمز في التوجيه؛ وفي مرحلة فك الترميز، ينتبه كل رمز جديد إلى جميع تلك المفاتيح والقيم عبر آلية الانتباه. ويحتفظ المخزن المؤقت للمفاتيح والقيم (KV) بهذه الموترات ضمن الطلب الواحد، كي لا يعيد كل رمز مُولّد حساب التوجيه. أما التخزين المؤقت للتوجيهات فيحتفظ بها بين الطلبات. ولأن الانتباه في هذه النماذج سببي، تعتمد مفاتيح الرمز وقيمه على الرموز التي تسبقه فقط؛ لذا تتطابق المفاتيح والقيم للبادئة في توجيهين لهما البادئة نفسها، ويمكن للنسخة المخزنة أن تحل محل إعادة الحساب.
يوضح المثال التالي إعادة الاستخدام باستخدام GPT-2 من Hugging Face Transformers. يهيّئ مسبقًا توجيه نظام من 409 رموز مرة واحدة، ثم يجيب عن سؤالين عبر تمرير رموز كل سؤال وحدها فوق البادئة المخزنة مؤقتًا، ويقارن النتيجة بإعادة حساب كاملة:
import copy
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("gpt2")
model = AutoModelForCausalLM.from_pretrained("gpt2")
# A long system prompt shared by every request, followed by different user questions
system = "You answer questions about a camera store. " + "Returns are accepted within 30 days with a receipt. " * 40
questions = [" Question: Can I return a lens?", " Question: Do you ship abroad?"]
prefix_ids = tokenizer(system, return_tensors="pt").input_ids
with torch.no_grad():
# Prefill the shared prefix once and keep its key-value cache
prefix_cache = model(prefix_ids).past_key_values
for question in questions:
ids = tokenizer(question, return_tensors="pt").input_ids
# Cache hit: only the question's tokens run through the model
cached = model(ids, past_key_values=copy.deepcopy(prefix_cache)).logits[0, -1]
# No cache: the whole prompt is computed from scratch
full = model(torch.cat([prefix_ids, ids], dim=1)).logits[0, -1]
same = torch.allclose(cached, full, atol=1e-3)
print(f"Computed {ids.shape[1]} of {prefix_ids.shape[1] + ids.shape[1]} tokens, same next-token scores: {same}")يطبع Computed 8 of 417 tokens, same next-token scores: True وComputed 7 of 416 tokens, same next-token scores: True: مرّر كل طلب أقل من 2% من توجيهه عبر النموذج، وحصل على درجات الرمز التالي نفسها التي حصل عليها الحساب الكامل.
تطبّق محركات تقديم النماذج مفتوحة المصدر ذلك تلقائيًا. يحتفظ vLLM بالمخزن المؤقت للمفاتيح والقيم في كتل ثابتة الحجم، وهو تخطيط الذاكرة الخاص بـالانتباه المُقسّم إلى صفحات، ويعيد استخدام كتل أطول بادئة مطابقة لكل طلب جديد، ويحذف الكتل الأقل استخدامًا مؤخرًا عندما تنفد ذاكرة GPU. ويحتفظ RadixAttention في SGLang بالبادئات المخزنة مؤقتًا في شجرة جذرية، بحيث تعيد الطلبات التي تتشارك أي جزء أولي استخدامها، وتذكر ورقة SGLang أن الإنتاجية أعلى بما يصل إلى 6.4 مرة من محركات الاستدلال الحديثة الأخرى. وتوسّع ورقة Prompt Cache التي أعدها إن غيم وزملاؤه، وعُرضت في MLSys 2024، نطاق إعادة الاستخدام ليتجاوز البادئات المتطابقة ويشمل وحدات توجيه معلنة مثل القوالب والمستندات، وأفادت بخفض زمن الوصول إلى الرمز الأول بمقادير تتراوح بين 8 أضعاف على GPU و60 ضعفًا على CPU.
التخزين المؤقت للتوجيهات في واجهات API للنماذج اللغوية الكبيرة#
تتيح واجهات API المستضافة الآلية نفسها مقابل تكلفة. يكون التخزين المؤقت للتوجيهات من OpenAI مفعّلًا افتراضيًا للنماذج المدعومة، بينما يُفعّل التخزين المؤقت لتوجيهات Claude من Anthropic باستخدام الحقل cache_control، إما مرة واحدة لكل طلب أو على ما يصل إلى أربع كتل محتوى. وتحاسب Anthropic على قراءة ذاكرة التخزين المؤقت بعُشر سعر الإدخال الأساسي أو أقل، وعلى الكتابة إلى ذاكرة التخزين المؤقت الافتراضية ذات الدقائق الخمس بسعر يعادل 1.25 من السعر الأساسي، كما تعيد كل إصابة ضبط مدة الدقائق الخمس. ولا يطابق المزوّدان إلا بادئة مطابقة تمامًا: تقارن Anthropic الأدوات أولًا، ثم توجيه النظام، ثم الرسائل، لذا يؤدي تعديل تعريف أداة إلى إبطال كل ما خُزّن بعدها، بينما يوصي دليل OpenAI بوضع التعليمات الثابتة والمواد المرجعية أولًا وتفاصيل المستخدم في النهاية.
تحقق أعباء العمل ذات البادئات المشتركة الطويلة أكبر فائدة:
- وكلاء الذكاء الاصطناعي: تعيد كل خطوة إرسال تعريفات الأدوات والسجل الكامل، أي توجيه الخطوة السابقة مضافًا إليه أحدث إجراء ونتيجته.
- روبوتات المحادثة: تضيف كل جولة في المحادثة إلى مطالبة الجولة السابقة، لذا يُخزَّن سجل المحادثة مؤقتًا حتى وصول الرسالة الجديدة.
- الإجابة عن أسئلة المستندات: تتكرر أسئلة كثيرة حول عقد أو تقرير أو مستودع طويل واحد، فتُعاد الاستفادة من المستند المعالَج، كما تعيد خطوط استرجاع المعلومات استخدامه كلما استُرجعت المقاطع نفسها مجددًا.
- المطالبات قليلة الأمثلة: تُحتسب عشرات الأمثلة الثابتة مرة واحدة، ثم يُعاد استخدامها مع كل مُدخل.
تعيد نماذج الرؤية ذات المفردات المفتوحة استخدام حساب الموجّهات بطريقة مماثلة. يرمّز Ultralytics YOLOE موجّهات الفئات، مثل "رافعة شوكية"، باستخدام مُرمِّز النصوص من MobileCLIP لمرة واحدة عند استدعاء set_classes()، ويخزّن التضمينات الناتجة في النموذج، بحيث تتجاوز التنبؤات اللاحقة مُرمِّز النصوص تمامًا؛ ويكتب save_prompt_embeddings() التضمينات في ملف NPZ الذي تحمّل منه جلسة لاحقة التضمينات باستخدام load_prompt_embeddings() بدلًا من تشغيل المُرمِّز مرة أخرى.
التخزين المؤقت للمطالبات والمصطلحات ذات الصلة#
- ذاكرة التخزين المؤقت KV: تعيد استخدام المفاتيح والقيم عبر رموز عملية توليد واحدة. أما التخزين المؤقت للمطالبات فيعيد استخدامها عبر طلبات منفصلة.
- التخزين المؤقت الدلالي: يخزّن الاستجابات كاملة ويعيد إحداها عندما يحمل استعلام جديد المعنى نفسه لاستعلام سابق، متجاوزًا النموذج بالكامل. أما التخزين المؤقت للمطالبات، فيُشغّل النموذج على الجزء الجديد من المطالبة ويولّد إجابة جديدة.
- ضغط المطالبة: يختصر المطالبة نفسها، وهو مناسب للنص الذي يتغير مع كل طلب. ويمكن الجمع بين الأسلوبين بفاعلية، إذ يُخزَّن الجزء الثابت من المطالبة مؤقتًا ويُضغط الجزء المتغير.
- هندسة المطالبات: تحدد ما تقوله المطالبة. ولا يغيّر التخزين المؤقت سوى مقدار ما يعيد الخادم حسابه منها، كما أن إصابة ذاكرة التخزين المؤقت تترك درجات الرمز التالي من دون تغيير، باستثناء فروق التقريب بالفاصلة العائمة.










