هذا المشروع لا يزال قيد التطوير. قد لا يتم تنفيذ بعض الميزات بعد، وقد تكون الوثائق غير كاملة.
نظام استدلال LLM صغير ولكنه قوي مصمم لأغراض البحث.
أداء مكافئ لـ vLLM مع 2 ألف سطر فقط من التعليمات البرمجية (2% من vLLM).
هناك الكثير من أطر العمل مفتوحة المصدر لخدمة LLM، بما في ذلك HuggingFace Transformers، وvLLM، وLightLLM، وDistServe، وDeepSpeed-MII. لماذا سويفت إل إل إم؟
والسبب هو أن هذه الأطر مصممة للإنتاج بدلاً من البحث . وهي مجهزة بالعديد من الميزات، مثل دعم أكثر من 100 نموذج، ودعم الأجهزة المختلفة، وLoRA، والتكميم، والوسائط المتعددة، والتخزين المؤقت للبادئة، والبحث عن الشعاع، وما إلى ذلك. على الرغم من كونها حلاً شاملاً للإنتاج، إلا أن قاعدة التعليمات البرمجية الخاصة بها كبيرة جدًا ومعقدة بحيث لا يمكن فهمها وتعديلها (على سبيل المثال، يحتوي vLLM على أكثر من 100 ألف سطر من التعليمات البرمجية)، مما يجعل من الصعب استخدامها لأغراض البحث. كما أن عبئهم التاريخي يمثل أيضًا مشكلة.
تم تصميم SwiftLLM ليكون نظامًا صغيرًا ولكنه قويًا لاستدلال LLM مصممًا لأغراض البحث . "صغير" يعني أنه يحتفظ فقط بالميزات الضرورية للبحث، و"قوي" يعني أنه ليس لديه أي تنازلات بشأن الأداء، وأخيرًا "سريع" يعني أنه من السهل فهمه وتعديله. أثناء دعم الميزات الأساسية (انظر القائمة أدناه) والقدرة على تحقيق أداء مكافئ لـ vLLM، فإن قاعدة التعليمات البرمجية لـ SwiftLLM أقل من 2 ألف سطر من التعليمات البرمجية (~ 2% من vLLM)، مكتوبة بلغة Python وOpenAI Triton (خط DSL للكتابة CUDA kernels)، مما يجعل من السهل القراءة والتعديل والتصحيح والاختبار والتوسيع، ويمكن دمجها بسهولة مع أفكارك البحثية الجديدة والرائعة.
حاليًا، يدعم SwiftLLM الميزات التالية:
ونخطط لإضافة دعم للميزات التالية في المستقبل:
للحفاظ على قاعدة التعليمات البرمجية صغيرة، لن ندعم الميزات التالية. إذا كنت ترغب في استخدامها في مشروعك البحثي، فقد تحتاج إلى تنفيذها بنفسك:
تذكر أن SwiftLLM ليس حلاً شاملاً للإنتاج. يُنصح باعتبار ذلك "أساسًا" لمشروعك البحثي، وقد تحتاج إلى تنفيذ بعض الميزات بنفسك. ونحن نشجعك عزيزي الباحث على قراءة الكود وفهمه وتعديله وتوسيع نطاقه ليناسب احتياجاتك البحثية.
يمكن تقسيم بنية SwiftLLM إلى قسمين رئيسيين: مستوى التحكم ومستوى البيانات .
باختصار، يقرر مستوى التحكم "ما يجب حسابه" أو "كيفية جدولته"، بينما يقرر مستوى البيانات "كيفية الحساب" أو "كيفية التنفيذ" ويقوم بإجراء الحساب الملموس. إنهم يعملون بطريقة العامل الرئيسي: يعمل مستوى التحكم مثل السيد، الذي يقوم بالجدولة والتنسيق عالي المستوى ويرسل المهام إلى مستوى البيانات، الذي يعمل مثل العامل، الذي يقوم بإجراء العمليات الحسابية ذات المستوى المنخفض.
يوجد رمز مستوى التحكم في دليل swiftllm/server
، بما في ذلك مكونات مثل Engine
و Scheduler
وخادم API و TokenizationEngine
. يوجد رمز مستوى البيانات في دليل swiftllm/worker
، بما في ذلك أوصاف الرسم البياني الحسابي (في swiftllm/worker/model.py
)، وتنفيذ الطبقات في النموذج (في swiftllm/layers
)، ونواة OpenAI Triton ( يمكنك تخيل "النوى" كوظائف يتم تنفيذها على وحدة معالجة الرسومات) (في swiftllm/kernels
).
لنأخذ خادم واجهة برمجة تطبيقات اللعبة (الموجود في swiftllm/server/api_server.py
) كمثال:
EngineConfig
لإنشاء Engine
.Engine.initialize
، حيث يقوم بإنشاء Scheduler
، و TokenizationEngine
، ومجموعة من العمال (حاليًا واحدًا فقط نظرًا لعدم دعم Tensor Parallelism). ثم يأمر العامل بتنفيذ profile_num_blocks
لحساب عدد كتل وحدة معالجة الرسومات، وبعد ذلك يأمر المحرك جميع العمال بتخصيص ذاكرة التخزين المؤقت KV ومبادلة KV الخاصة بهم.Engine.start_all_event_loops
. في كل خطوة من الحلقة، يستعلم المحرك من المجدول عن الدفعة التالية من طلبات الحوسبة، ويأمر العامل بإجراء المبادلة للداخل/الخارج، ثم يرسل الدُفعة إلى العامل للحساب. يوجد حاليًا مستوى التحكم ( Engine
) ومستوى البيانات ( LlamaModel
) على نفس العقدة. بعد تنفيذ Tensor Parallelism / Pipeline Parallelism، يمكن توزيع مستوى البيانات على عقد متعددة.
نحن نقدم طريقتين لاستخدام SwiftLLM: استخدام مستوى التحكم ومستوى البيانات، أو استخدام مستوى البيانات فقط.
إذا كانت فكرتك بسيطة أو أنيقة بما يكفي بحيث يمكن دمجها بسلاسة في مستوى التحكم الحالي، فيمكنك استخدام كل من مستوى التحكم ومستوى البيانات. في حالة أخرى، عندما ترغب في تنفيذ فكرة رائعة، يمكنك فقط الاستفادة من مستوى البيانات وتنفيذ مستوى تحكم جديد بنفسك.
لنقم أولاً بإعداد البيئة:
packaging
عبر pip install packaging
وبعد ذلك يأتي التثبيت:
git clone https://github.com/interestingLSY/swiftLLM.git
cd
في الريبو ( cd swiftLLM
) وقم بتثبيت التبعيات الأخرى عبر pip install -r requirements.txt
.pip install -e .
لتثبيت SwiftLLM في بيئتك.pip install -e csrc
فيما يلي بعض الأمثلة:
.bin
وتنسيق .safetensors
. افترض أنه تم تخزين وزن النموذج الخاص بك في /data/to/weight/
.python3 examples/offline.py --model-path /data/to/weight
. يستخدم هذا المثال مستوى البيانات فقط. إذا كنت تخطط لاستخدام SwiftLLM بدون مستوى التحكم، فهذه نقطة بداية جيدة.Engine
، يمكنك تجربة python3 examples/online.py --model-path /data/to/weight
. يعد هذا مثالًا رائعًا إذا كنت تخطط لاستخدام كل من مستوى التحكم ومستوى البيانات.swiftllm/server/api_server.py
. يطلق خادم API ويوفر واجهة تشبه vLLM للخدمة عبر الإنترنت. على الرغم من كونها صغيرة الحجم (يمكن للأشياء الصغيرة أن تكون رائعة أيضًا!)، إلا أن SwiftLLM ليس لديها أي تنازلات بشأن الأداء. لقد قمنا بتقييم SwiftLLM في عدة سيناريوهات، وأثبتنا أن SwiftLLM يمكنه تحقيق أداء مكافئ، أو حتى أفضل، مقارنة بـ vLLM.
السيناريو الأول هو "عملية أمامية واحدة"، حيث نقوم بتغذية النموذج بمجموعة من المدخلات ونسمح له بإنشاء رمز إخراج واحد (أي ما يعادل عملية "أمامية" واحدة). هذه هي العملية الأساسية لاستدلال LLM (سواء عبر الإنترنت أو دون الاتصال بالإنترنت) لذا فإن أدائها أمر بالغ الأهمية.
نستخدم هنا طراز LLaMA-3 7B مع وحدة معالجة الرسومات NVIDIA A100 80G PCIE / RTX 4090 بدقة FP16. النتائج موضحة أدناه (الأقل هو الأفضل):
يمكن ملاحظة أن SwiftLLM يمكنه تحقيق أداء مكافئ (أو حتى التفوق) على vLLM تحت نفس الإعدادات.
السيناريو الثاني هو "الخدمة عبر الإنترنت"، حيث نبدأ خادم واجهة برمجة التطبيقات (API)، ونأخذ عينات من مجموعة بيانات حقيقية، ونترك النموذج ينشئ عمليات إكمال. هذا هو السيناريو الذي يتم فيه استخدام LLM في تطبيقات العالم الحقيقي مثل برامج الدردشة الآلية أو إكمال التعليمات البرمجية.
نستخدم هنا مجموعة بيانات ShareGPT لأخذ عينات من المطالبات، ونستخدم عملية بواسون مع لامدا مختلفة لمحاكاة معدلات وصول الطلبات المختلفة. النتائج موضحة أدناه (الأقل هو الأفضل):
يمكن ملاحظة أنه في A100 80G PCIE، يمكن لـ SwiftLLM تحقيق أداء مكافئ لـ vLLM، بينما في RTX 4090، يتفوق SwiftLLM بشكل كبير على vLLM (ويرجع ذلك أساسًا إلى أن مستوى التحكم الخاص بنا لديه حمل أقل).