تقرير فنّي CodeShell

Rui Xie, Zhengran Zeng, Zhuohao Yu, Chang Gao, Shikun Zhang, Wei Ye
National Engineering Research Center for Software Engineering, Peking University, China
{ruixie, wye}@pku.edu.cn
https://github.com/WisdomShell/codeshell

مُلخّص

تُمثّل النماذج اللغويّة الكبيرة المُخصَّصة للبرمجة نقطة تحوّل رئيسية في الذكاء الاصطناعي؛ إذ صُمِّمت لفهم لغات البرمجة وتوليدها، ما يُعزّز بوضوح كفاءة سير عمل تطوير البرمجيات. في هذا التقرير الفنّي، نُقدّم CodeShell-Base، وهو نموذج أساسي بحجم 7 مليارات مُعامِل وطول سياق 8K، يُظهر كفاءة ملحوظة في فهم الشِّفرة. بدمج انتباه الاستعلامات المُجمَّعة وترميز الموضع الدوّار ضمن بنية GPT-2، يجمع CodeShell-Base بين مزايا StarCoder وCodeLlama مع تصميم معماري فريد. بعد ذلك، أنشأنا خط معالجة بيانات شاملًا، يضم إزالة التكرار للمحتوى المتشابه، والترشيح وفق الحَيّرة، والترشيح القائم على النموذج. ومن خلاله جمعنا 100 مليار رمز تدريب مسبق عالية الجودة من GitHub. وبالاستناد إلى هذه البيانات، يتفوّق CodeShell-Base على CodeLlama في HumanEval بعد تدريب على 500 مليار رمز فقط (5 حِقَب). وقد أجرَينا تجارب واسعة عبر مجموعات بيانات متعدّدة اللغات، تشمل Python وJava وC++، وأظهرت النتائج امتلاك نموذجنا قدرات أساسية قويّة في فهم الشِّفرة وتوليدها.

مُقدّمة

أحدثت النماذج اللغويّة الكبيرة للبرمجة مثل CodeGen (codegen) وCodeLlama (codellama) وStarCoder (starcoder) ثورة في تطوير البرمجيات عبر أتمتة المهام، وتقليل الأخطاء، وتحسين الكفاءة (gpt4report). وبالاستفادة من التعلّم العميق ومجموعات البيانات الضخمة للشِّفرة (codegen,thestack)، تُعزّز هذه النماذج إنتاجية المطوّرين وتُيسّر تطوير البرمجيات لشريحة أوسع.

تُصنَّف النماذج الحالية إلى ثلاث فئات رئيسية: التدريب المسبق من الصفر (starcoder)، والتدريب المسبق انطلاقًا من نموذج لغوي كبير قائم (codex,codellama)، والضبط بالإرشاد (wizardcoder). تتطلّب النماذج المُدرَّبة من الصفر قدرًا هائلًا من البيانات وزمن تدريب طويلًا (starcoder,llama2). في المقابل، يُتيح الانطلاق من نموذج قائم تقليل زمن التدريب وتحسين الكفاءة باستخدام بيانات أقل (codex,codellama). أمّا الضبط بالإرشاد فيعني مواءمة نموذج كبير باستخدام بيانات إرشادية لتحسين الأداء (codellama,wizardcoder). ومع ذلك، يبقى تحدٍّ أساسي أن النماذج القائمة غالبًا ما دُرِّبت على مجموعات شيفرة ضخمة دون حَوْكَمة دقيقة، ما قد يفضي إلى شيفرة منخفضة الجودة. وبرغم اعتماد بعض استراتيجيات اختيار الشِّفرة (phi1)، يبقى خطر تدنّي الجودة قائمًا.

نُقدّم في هذا التقرير نموذج شِفرة كبيرًا جديدًا باسم CodeShell. يُدمج CodeShell ترميز الموضع الدوّار (rope) مع انتباه الاستعلامات المُجمَّعة (gqa) ضمن بنية GPT-2 لبناء تصميم معياري فعّال يدعم سياقات أطول. ثم طوّرنا خطًّا لانتقاء الشِّفرات عالية الجودة، أسفر عن تجميع 100 مليار رمز عالي الجودة. وعلى هذا الأساس، دُرِّب CodeShell لمدّة خمس حِقَب. تُظهر تجاربنا أن التدريب على 100 مليار رمز فريد فقط يُمكّن CodeShell من مضاهاة أو التفوّق على نماذج قائمة مُدرَّبة على نحو 250 مليار رمز فريد، مثل StarCoder وCodeLlama. ونظرًا لندرة الشِّفرة عالية الجودة مفتوحة المصدر، يبقى انتقاء الشيفرات المتينة محورًا أساسيًّا في تطوير نموذج فعّال. وفيما يلي مساهماتنا الرئيسية:

CodeShell

البيانات

لشرح بناء مجموعة تدريب CodeShell وخطوات الترشيح والتحسين، نستعرض المراحل التالية بإيجاز:

جمع البيانات: كان المصدر الأساسي GitHub (gharchive)؛ حيث زحفنا إلى نحو 15 تيرابايت من المستودعات لضمان تنوّع واتّساع مجموعة البيانات. كما أدمجنا مجموعتَي The Stack (thestack) وStarCoder لإثراء البيانات بأمثلة شيفرات ومناقشات برمجية.

ترشيح اللغات: استبعدنا اللغات التي تقل بياناتها عن 100 ميغابايت، وركّزنا على 7 فئات رئيسية تضمّ: Markdown للتوثيق، وgit commits لممارسات التطوير، وGitHub issues لمناقشات حلّ المشكلات، لتعزيز فهم النموذج لأنماط مختلفة من البرمجة.

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

إزالة التكرار: استخدمنا تجزئة MD5 لاكتشاف النُّسخ المكرّرة وإزالتها، وتقنية MinHash (minihash) لاكتشاف المحتويات شديدة التشابه وتنقيتها، بما يعزّز التنوّع والجودة.

ترشيح الحَيّرة (Perplexity): اعتمدنا درجات الحَيّرة (pplf) كمؤشّر على جودة الشِّفرة. باستبعاد المقاطع عالية الحَيّرة، ارتفع المستوى النوعي للأمثلة في المجموعة.

الترشيح القائم على القواعد: وظّفنا محلّلات وقواعد مخصّصة لانتقاء الشيفرات عالية الجودة؛ فحسبْنا مقاييس مثل عدد الأسطر، وحضور التعليقات وتغطيتها، ومتوسّط طول السطر. كما فضّلنا الشيفرات التي تستخدم مكتبات طرف ثالث معروفة، والتي تعكس ممارسات تطوير متقدّمة. وتحقّقنا من درجة التعقيد المنطقي عبر تحليل شجرة البُنية المُجرَّدة (AST) وتدفّق التحكّم، لضمان أن الأمثلة ليست وظيفية فحسب بل متقنة أيضًا، مع الالتزام بأفضل الممارسات القياسية.

نظرة عامّة على البيانات
css 30.09 5292.28 2.38% 0.13 23.58 0.28%

[tab:data_overview_1]

النموذج

مُحلِّل الرموز

لدعم المحتوى الصيني المرتبط بالبرمجة، عزّزنا مفردات StarCoder بإضافة كمّ معتبر من المفردات الصينية. على وجه التحديد، جمعنا مليون ملف شيفرة بالصينية وبيانات أسئلة/أجوبة برمجية بالصينية. وباستخدام مكتبة Tokenizer من Hugging Face، انتقينا 40,000 مفردة صينية عالية التكرار، و30,000 مفردة إنجليزية من مفردات StarCoder، ودمجناهُما لتكوين مفردات CodeShell الشاملة. وتُظهر النتائج التجريبية تفوّق مفردات CodeShell في كفاءة ترميز أسئلة/أجوبة البرمجة بالصينية مقارنة بمفردات StarCoder الأصلية.

الهندسة المعماريّة

يبني CodeShell على بنية GPT-2 (gpt2) ويستفيد من تقنيتين متقدّمتين: انتباه الاستعلامات المُجمَّعة (gqa) وترميز الموضع الدوّار (rope). تعمل آلية انتباه الاستعلامات المُجمَّعة على تجميع الاستعلامات المتقاربة لتقليل التكرار وتحسين الكفاءة الحوسبية، فيما يوفّر ترميز الموضع الدوّار تمثيلًا زاويًّا ديناميكيًّا لمواضع العناصر في التسلسل، ما يُعين النموذج على فهم البنية والترتيب بدقّة أعلى.

التدريب

التحسين

اعتمدنا AdamW مُحسِّنًا، مع ضبط معاملي \(\beta_1\) و\(\beta_2\) عند 0.9 و0.95 على التوالي. واستخدمنا جدولًا زمنيًّا للتعلّم يبدأ بتسخين لمدّة 1000 خطوة، ثم خفّضنا مُعدّل التعلّم من \(3 \times 10^{-4}\) إلى \(3 \times 10^{-5}\) عبر 127k تحديث. عالجنا دفعات بحجم فعّال قدره 4 ملايين رمز، مُقسّمة إلى تسلسلات بطول 2048 أو 8192 رمزًا لكل منها.

مرحلة التدريب المُسبق

للموازنة بين الكفاءة والحاجة إلى سياقات أطول، بدأنا بطول سياق 2048 في الحِقَب الأولى. وبعد تدريب على نحو 450 مليار رمز، زدنا طول السياق إلى 8192. وتراجع مُعدّل المعالجة على وحدة معالجة الرسوميات (GPU) من نحو 3200 رمز/ثانية إلى 2600 رمز/ثانية. وبرغم ذلك، حافظ النموذج على استقراره وتحسّن أداؤه قليلًا، مع انخفاض ملحوظ في الخسارة بفضل السياق الأطول، دون أي تراجع في مقاييس التقييم.


النتائج

نستعرض هنا أداء CodeShell مقارنةً بنماذج رائدة:

توليد الشِّفرة

توليد شيفرة بايثون

نُقارن هنا أداء CodeShell في Python مع نماذج مفتوحة ومغلقة. نبدأ بنتائج HumanEval (codex) وMBPP (mbpp). تتكوّن مجموعة HumanEval من 164 مهمة بايثون مُصمّمة يدويًّا مع حالات اختبار لتقييم الأداء دون أمثلة سابقة (zero-shot). أمّا معيار MBPP فيتضمّن 500 تحدٍّ مع أمثلة قليلة (few-shot).

تُظهر النتائج أنّ CodeShell-7B حقّق دقّة متوسّطة قدرها 34.3% على HumanEval و38.7% على MBPP، ليضعه ذلك في صدارة النماذج المماثلة حجمًا، متفوّقًا على CodeLlama-7B وStarCoder-Base-7B. كما يتفوّق CodeShell-7B على نماذج أكبر من حيث عدد المُعامِلات في بعض الإعدادات.

نُشير إلى أنّ انتقاء البيانات عالية الجودة والتدريب عبر حِقَب عدّة أتاحا لـCodeShell أداءً قويًّا في المهام الأساسية مثل HumanEval. ومع ذلك، قد يتطلّب الأداء على مهام أكثر تعقيدًا، مثل CoderUJB، تحسينًا إضافيًّا لخط انتقاء البيانات ومواءمته مع متطلّبات البُنى المنطقية المعقّدة.

توليد الشيفرة مُتعدّد اللغات

قيّمنا النموذج عبر مجموعة أوسع من اللغات باستخدام معيار MultiPL-E (Cassano et al., 2022). النتائج لمختلف اللغات، بما في ذلك JavaScript وJava وSwift وPHP وغيرها، موضّحة في الجدول [tb:results_multiple].

لوحِظ أن CodeShell حقّق نتائج أفضل في لغات رئيسية مثل JavaScript وJava وC++ مقارنةً بـCodeLlama-7B وStarCoder-7B/15B. بينما كان الأداء أدنى في لغات أقل تمثيلًا كالـD وJulia وLua، بما يعكس توافُر بيانات عالية الجودة للغات الشائعة. ويجدر الذكر أنّ أداء CodeShell في بعض اللغات كان منافسًا لـStarCoder-15B، ما يُشير إلى فعالية التصميم المعياري للنموذج الأصغر.

إكمال الشِّفرة

خلال التدريب المسبق، استخدمنا تقنية Fill-In-the-Middle (fim) بنسبة 0.5 لتعزيز قدرة النموذج على ملء الفجوات في الشيفرة استنادًا إلى السياق المحيط. وقد أثبتت هذه التقنية فاعليتها في مهمة الإكمال، كما في نماذج مثل StarCoder-15B وCodeLlama-7B. ووفقًا لـSantaCoder، نُخفي سطرًا واحدًا داخل دالة ونطلب من النموذج إكماله، ثم نقيس المطابقة الدقيقة (Exact Match) كما في InCoder على معيار MultiPL-E لثلاث لغات برمجة.

تُظهر النتائج في الجدول [tab:results_code_completion] أنّ CodeShell-7B يتفوّق على StarCoder وCodeLlama في هذا الاختبار، مؤكِّدًا أهمية البيانات عالية الجودة وإستراتيجية التدريب المسبق التي تبدأ بطول سياق 2048 ثم تمتد إلى 8192 دون خسارة في الكفاءة النهائية.

انتباه متعدد الاستعلامات مقابل انتباه الاستعلامات المُجمَّعة

لتقييم أثر كلٍّ من انتباه متعدد الاستعلامات (MQA) وانتباه الاستعلامات المُجمَّعة (GQA) في الأداء، طوّرنا نسخة codeshell-small بواقع 24 طبقة، وحجم خفي 2048، وإجمالي نحو 1 مليار مُعامِل. نفّذنا كل نوع انتباه كوحدة مستقلّة، وسمّيناهما codeshell-small-mqa وcodeshell-small-gqa. تُشير النتائج إلى أنّ الأداء كان متقاربًا في البداية، لكن مع ازدياد حجم بيانات التدريب تدريجيًّا، تفوّق codeshell-small-gqa على codeshell-small-mqa في مقياس Top-1.

استبعاد البيانات

لاختبار فاعلية آلية ترشيح الشيفرات عالية الجودة، أعددنا مجموعتين: مجموعة عشوائية أخذنا منها 2 مليار رمز من البيانات غير المُكرّرة، ومجموعة مُصفّاة أخذنا منها 2 مليار رمز الأعلى تقييمًا من حيث الجودة. استخدمنا نموذج codeshell-small لتدريب كل مجموعة. وأظهرت النتائج (انظر الشكل المقابل) تفوّق النموذج المُصفّى باستمرار بنسبة تقارب 100% مقارنةً بالآخر، مؤكِّدة الدور الحاسم لجودة البيانات.


الخُلاصة

قدّمنا في هذا التقرير نموذج الشِّفرة الكبير CodeShell، واستعرضنا أثر التصميم المعماري وإستراتيجيات ترشيح البيانات في الأداء. وأظهرنا أنّ جودة البيانات تبقى العامل الأهم: فبفضل انتقاء بيانات عالية الجودة، حقّق CodeShell أداءً متميّزًا عبر لغات برمجة عدّة. إضافةً إلى ذلك، بيّنت طريقة الترشيح المقترَحة تحسينًا يقارب ~100% مقارنةً بالاختيار العشوائي، ما يؤكّد فاعلية منهجنا في تدريب النماذج الكبيرة.