تلخيص التعليمات البرمجية باستخدام Granite

تاريخ النشر 14 يناير 2026
تاريخ التحديث 17 يوليو 2026
تصميم ثلاثي الأبعاد لأقواس زجاجية
By Joshua Noble

مقدمة

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

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

قبل انتشار النماذج اللغوية الكبرى (LLMs)، كانت طرق تلخيص التعليمات البرمجية تتطلب تحليل دلالات التعليمات البرمجية وتوليد شجرة بناء جمل مجردة (AST) لكل معرف من التعليمات البرمجية والتي يمكن استخدامها بعد ذلك لإنشاء الوثائق.1،2 ومع ظهور التعلم العميق والشبكات العصبية، تم الاستغناء عن الأساليب المتجذرة في علوم الحاسوب لصالح أساليب تستعير المزيد من منهجية الترجمة الآلية العصبية3،4.

بالنسبة إلى نماذج المحولات، تؤدي نوافذ السياق الأكبر إلى نتائج أفضل. العديد من أحدث نماذج Granite™ Code مثل Granite-8B-Code-Instruct-128K تحتوي على نافذة سياق بحجم 128 ألف رمز. تسمح نافذة السياق الأكبر للنموذج بالاحتفاظ بمزيد من النصوص في ذاكرة العمل. ويساعد ذلك على مراقبة اللحظات والتفاصيل الرئيسية في محادثة مطولة أو مستند طويل أو قاعدة تعليمات برمجية كبيرة. تُمكِّن ذاكرة العمل هذه روبوتات المحادثة القائمة على النماذج اللغوية الكبرى من توليد ردود منطقية في اللحظة الراهنة وعلى مدى سياق أطول، ما يساعدها على التفوق على النماذج ذات نوافذ السياق الأصغر من خلال التقييم البشري ومقاييس التقييم.5

تتيح نوافذ السياق الأكبر للنماذج الاحتفاظ بمزيد من النصوص في ذاكرة عملها، ما يساعد على تتبع اللحظات والتفاصيل الرئيسية في المحادثات الطويلة أو المستندات الطويلة أو قواعد التعليمات البرمجية الكبيرة.

عندما طُرح ChatGPT لأول مرة، كانت نافذة السياق الخاصة به تبلغ 4000 رمز. وإذا تجاوزت محادثتك حد واجهة الدردشة البالغ 3000 كلمة، فمن المرجح أن يتعرض روبوت الدردشة للهلوسة وينحرف عن الموضوع. واليوم، أصبح المعيار هو 32000 رمز، مع تحول المجال إلى 128000 رمز. وهذا يعادل طول كتاب مكون من 250 صفحة. شركة IBM لديها الآن نموذجان من Granite بنافذة تضم 128000 رمز، والمزيد قادم.

تصميم ثلاثي الأبعاد لكرات تتدحرج على مسار

أحدث الأخبار والمعارف حول الذكاء الاصطناعي 


تتوفر معارف وأخبار منسقة بمهارة حول الذكاء الاصطناعي والسحابة وغيرها في نشرة Think الأسبوعية. 

الخطوة 1: إعداد البيئة.

في هذه الخطوة، سنرشدك خلال إنشاء حساب IBM للوصول إلى Jupyter Notebook.

1. سجِّل الدخول إلى ™watsonx.ai باستخدام حسابك على ®IBM Cloud.

2. انقر فوق + لإنشاء مشروع جديد.

أ. اختر “إنشاء مشروع فارغ”.

ب. أدخل اسم المشروع في حقل “الاسم”.

ج. أنشئ Cloud Object Storage لتخزين أصول مشروعك إذا لم تكن قد أُنشئت بالفعل.

د. حدد “إنشاء”.

3. أنشئ Jupyter Notebook.

أ. حدد علامة تبويب “الأصول” في بيئة مشروعك.

ب. انقر فوق “أصل جديد”.

ج. حدد خيار “العمل مع النماذج” من اللوحة اليسرى.

د. انقر فوق “العمل مع البيانات والنماذج” باستخدام دفاتر Python وR.

هـ. أدخل اسمًا لدفترك في حقل “الاسم”. اختر “Runtime 23.1 على Python (4 vCPU 16 جيجابايت RAM)” لتحديد التكوين.

و. حدد “إنشاء”.

4. اضبط مثيل watsonx.ai Runtime ومفتاح واجهة برمجة التطبيقات

أ. أنشئ مثيل خدمة watsonx.ai Runtime (اختَر المنطقة المناسبة لك، واختَر باقة Lite، وهي مثيل مجاني).

ب. أنشئ مفتاح واجهة برمجة التطبيقات.

ج. اربط مثيل خدمة watsonx.ai Runtime بالمشروع الذي أنشأته في watsonx.ai.

الخطوة 2: تحميل Granite Code Instruct

أولاً، سنثبت مكتبة Hugging Face Hub مفتوحة المصدر لتحميل النماذج:

!pip install huggingface_hub

الآن يمكننا تنزيل Granite-8B-Code-Instruct-128K:

from transformers import AutoTokenizer, AutoModelForCausalLM

tokenizer = AutoTokenizer.from_pretrained("ibm-granite/granite-8b-code-instruct-128k")
model = AutoModelForCausalLM.from_pretrained("ibm-granite/granite-8b-code-instruct-128k")

الآن يمكننا البدء في استخدام Granite Code Instruct.

الخطوة 3: الحصول على شرح بسيط

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

ll_func_2 = """

    def call(
        self, data: torch.Tensor, weights: torch.Tensor
    ) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor]:

    assert (
        data.shape == weights.shape
    ), "data and observed_indicator must have same shape"

    with torch.no_grad():

        observed_data = torch.where(weights == 1, data, torch.nan)
        med = torch.nanmedian(observed_data, dim=self.dim, keepdim=True).values
        q1 = torch.nanquantile(observed_data, 0.25, dim=self.dim, keepdim=True)
        q3 = torch.nanquantile(observed_data, 0.75, dim=self.dim, keepdim=True)
        iqr = q3 - q1

        # if observed data is all zeros, nanmedian returns nan
        loc = torch.where(torch.isnan(med), torch.zeros_like(med), med)
        scale = torch.where(torch.isnan(iqr), torch.ones_like(iqr), iqr)
        scale = torch.maximum(scale, torch.full_like(iqr, self.minimum_scale))
        scaled_data = (data - loc) / scale

        if not self.keepdim:
            loc = torch.squeeze(loc, dim=self.dim)
            scale = torch.squeeze(scale, dim=self.dim)

        # assert no nans in scaled data, loc or scale
        assert not torch.any(torch.isnan(scaled_data))
        assert not torch.any(torch.isnan(loc))
        assert not torch.any(torch.isnan(scale))
        assert not torch.any(scale == 0)

        return scaled_data, loc, scaledef call(
            self, data: torch.Tensor, weights: torch.Tensor
        ) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor]:

        assert (
            data.shape == weights.shape
        ), "data and observed_indicator must have same shape"

 

الآن يمكننا طلب ملخص من Granite Code عن طريق ترميز محادثتنا ثم استدعاء callingmodel.generate()

chat = [
{ "role": "user", "content": "Explain what this function does" + ll_func_2 },
]
chat = tokenizer.apply_chat_template(chat, tokenize=False, add_generation_prompt=True)

# have the encoder turn text into output tokens
inputs = tokenizer(chat, return_tensors="pt").input_ids
start_index = inputs.shape[-1]

# generate output tokens
output = model.generate(inputs, max_new_tokens=1500)

# have the decoder turn output tokens into text
output = tokenizer.batch_decode(output[start_index:])

# loop over the batch to print, in this example the batch size is 1
print(output[0])

لنتحقق من الملخص المُنشأ:

الجواب:
تنفذ هذه الدالة تسوية البيانات باستخدام طريقة المدى الربعي (IQR). وهي تأخذ وسيطين: البيانات والأوزان. وسيط البيانات هو مصفوفة بأبعاد (batch_size، sequence_length، hidden_size)، حيث يمثل batch_size عدد العينات في دفعة، وsequence_length طول تسلسل الإدخال، وhidden_size أبعاد الحالة الخفية. أما وسيط الأوزان، فهو مصفوفة بأبعاد (batch_size، sequence_length)، حيث يكون كل عنصر إما 0 أو 1، ما يشير إلى ما إذا كان العنصر المقابل في مصفوفة البيانات موجودًا أم مفقودًا.

تتحقق الدالة أولاً من أن مصفوفتي البيانات والأوزان لهما الأبعاد نفسها. بعد ذلك، يحسب الوسيط والمدى الربعي لنقاط البيانات المرصودة (تلك التي يبلغ وزنها 1) باستخدام دالتَي torch.nanmedian وtorch.nanquantile. تحسب دالة torch.nanmedian الوسيط على طول البُعد المحدد ("self.dim")، بينما تحسب دالة torch.nanquantile النسب المئوية 25 و75.

بعد ذلك، تحسب الدالة معلمات الموقع ("loc") والقياس ("scale") للتوزيع المسوَّى. يتم تعيين الموقع إلى وسيط نقاط البيانات المرصودة، ويتم تعيين القياس إلى المدى الربعي لنقاط البيانات المرصودة. إذا كانت نقاط البيانات المرصودة كلها أصفارًا، فإن الدالة تعيِّن الموقع على صفر. كما تضمن الدالة أن يكون القياس على القيمة الدنيا الأقل ("self.minimum_scale") لتجنب القسمة على الصفر.

وأخيرًا، تحسب الدالة البيانات التي جرت تسويتها ("scaled_data") عن طريق طرح الموقع والقسمة على القياس. في حال تعيين الوسيط keepdim على False، تزيل الدالة البُعد المحدد من مصفوفتي الموقع والقياس. كما تنفذ الدالة عمليات تأكيد لضمان أن مصفوفات البيانات التي جرت تسويتها والموقع والقياس لا تحتوي على أي قيم NaN أو أصفار في القياس.

ترجع الدالة مجموعة تحتوي على مصفوفات البيانات التي جرت تسويتها والموقع والقياس.

الوصف مفصل للغاية ويصف بدقة الدالة التي مررناها والخوارزمية الأساسية.

الخطوة 4: إنشاء الوثائق

يُعد إنشاء الوثائق تطبيقًا قويًا لتلخيص التعليمات البرمجية لأنه لا يشرح فقط التعليمات البرمجية لأي مستخدم مستقبلي يقرأ التعليمات البرمجية، بل يمكن أن يساعد أيضًا على إنشاء الوثائق باستخدام أداة مثل pydoc.

نحن الآن يمكننا توجيه Granite Code لإنشاء سلاسل توثيقية لدالة ما. وبفضل نافذة السياق الأكبر، يمكننا تمرير دالة كاملة مع طلب لإنشاء سلسلة توثيقية. 

تُرجى كتابة سلسلة توثيق منسقة بشكل صحيح بلغة Python للدالة التالية:

def get_json_from_html(html: str, key: str, num_chars: int = 2, stop: str = '"') -> str:
    pos_begin = html.find(key) + len(key) + num_chars
    pos_end = html.find(stop, pos_begin)
    return html[pos_begin:pos_end]

يُرجع Granite Code توثيقًا ممتازًا بتنسيق Python:

يستخرج كائن JSON من سلسلة HTML المعطاة باستخدام المفتاح المحدد وحرف التوقف.
Args:

    html (str): سلسلة HTML المدخلة لاستخراج كائن JSON منها.

    key (str): المفتاح المستخدم لتحديد بداية كائن JSON في سلسلة HTML.

    num_chars (int, اختياري): عدد الأحرف بعد المفتاح المراد تضمينها في كائن JSON المستخرج. القيمة الافتراضية هي 2.

    stop (str, اختياري): الحرف الذي يميز نهاية كائن JSON في سلسلة HTML. القيمة الافتراضية هي '"'.

تُعيد:

    str: كائن JSON المستخرج كسلسلة نصية.

الآن إذا أردنا، يمكننا إعادة استخدام الموجِّه السابق الذي لا يزال موجودًا في نافذة السياق الكبيرة:

chat = "أعد كتابة الدالة السابقة لتكون دالة فئة، مع تضمين سلاسل توثيقية."

# have the encoder turn text into output tokens
inputs = tokenizer(chat, return_tensors="pt").input_ids
start_index = inputs.shape[-1]

# generate output tokens
output = model.generate(inputs, max_new_tokens=1500)

# have the decoder turn output tokens into text
output = tokenizer.batch_decode(output[start_index:])

# loop over the batch to print, in this example the batch size is 1
print(output[0])

وهذا يُعيد

class HtmlJsonExtractor:

    def init(self, html):

    """
    يهيئ كائن HtmlJsonExtractor باستخدام سلسلة HTML المعطاة.

    Args:

        html (str): سلسلة HTML المدخلة لاستخراج كائن JSON منها.
    """

        self.html = html

    @classmethod

    def extract(cls, html, key, num_chars=2, stop='"'):

    """
    يستخرج كائن JSON من سلسلة HTML المعطاة باستخدام المفتاح المحدد وحرف التوقف.

    Args:

        html (str): سلسلة HTML المدخلة لاستخراج كائن JSON منها.

        key (str): المفتاح المستخدم لتحديد بداية كائن JSON في سلسلة HTML.

        num_chars (int, اختياري): عدد الأحرف بعد المفتاح المراد تضمينها في كائن JSON المستخرج. القيمة الافتراضية هي 2.

             stop (str, اختياري): الحرف الذي يميز نهاية كائن JSON في سلسلة HTML. القيمة الافتراضية هي '"'.

    تُعيد:

        str: كائن JSON المستخرج كسلسلة نصية.
    """

        pos_begin = html.find(key) + len(key) + num_chars
        pos_end = html.find(stop, pos_begin)
        return html[pos_begin:pos_end]

لقد أنشأ النموذج الآن فئة تحمل اسمًا مناسبًا، وجعل التعليمات البرمجية السابقة دالة لتلك الفئة، وأدخل السلاسل التوثيقية الخاصة بنا.

الخطوة 5: الحصول على مراجعة للتعليمات البرمجية

لنطلب الآن من النموذج مساعدتنا على تحسين جزء من التعليمات البرمجية:

chat = """يُرجى تحسين التعليمات البرمجية التالية:

def fib(n):
    if (n < 2):
        return 1
    else:
        return fib(n-1) + fib(n-2)"""

يُرجع Granite Code ما يلي:

تحسب الدالة المعطاة fib(n) بلغة Python عدد Fibonacci رقم n باستخدام الاستدعاء الذاتي. ومع ذلك، فإن هذا التطبيق له تعقيد زمني بقيمة O(2^n)، وهو أمر غير فعال مع المدخلات الكبيرة. يمكننا

تحسينه باستخدام البرمجة الديناميكية أو التخزين المؤقت لتقليل التعقيد الزمني إلى O(n). إليك نسخة محسنة من الدالة:

```python

def fib_optimized(n, memo={}):
    if n < 2:
        return 1
    elif n not in memo:
        memo[n] = fib_optimized(n-1, memo) + fib_optimized(n-2, memo)
    return memo[n]
```

تستخدم هذه النسخة المحسنة مذكرة قاموس لتخزين أرقام Fibonacci المحسوبة سابقًا. عند حساب عدد Fibonacci رقم n، تتحقق أولاً مما إذا كان قد تم حسابه وتخزينه بالفعل في المذكرة. وإذا كان الأمر كذلك، فإنها تُعيد القيمة المخزنة بدلاً من إعادة حسابها، ما يوفر الوقت ويحسن الأداء.

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

الملخص

في هذا البرنامج التعليمي، تعلمت عن تلخيص التعليمات البرمجية واستخدمت نموذج Granite Code مع نافذة سياق موسعة بحجم 128 ألف رمز لتوليد شروحات للتعليمات البرمجية بلغة Python. كما استخدمنا التوجيهات لإنشاء الوثائق الجديدة، وإضافة فئة حول جزء من التعليمات البرمجية، واستخدام نافذة السياق الموسعة لإضافة تلك الوثائق إلى نافذة تعليمات برمجية جديدة. وأخيرًا، طلبنا من Granite Code تحليل وتلخيص جزء من التعليمات البرمجية وشرح سبل تحسينه.

مؤلف

Joshua Noble

Data Scientist

حلول ذات صلة
IBM Bob

تسريع تسليم البرمجيات مع IBM Bob، شريكك المدعوم بالذكاء الاصطناعي للتطوير الآمن والمدرك للنية.

استكشف IBM Bob®
حلول الذكاء الاصطناعي للمطورين.

تطوير تطبيقات الذكاء الاصطناعي ونشرها وإدارتها بوتيرة أسرع باستخدام أدوات جاهزة للمؤسسات.

استكشِف حلول الذكاء الاصطناعي للمطورين.
خدمات تحديث التطبيقات

إعادة تصوُّر الأنظمة القديمة من خلال التحديث الذكي بالذكاء الاصطناعي.

استكشِف خدمات تحديث التطبيقات.
اتخِذ الخطوة التالية

الاستفادة من الذكاء الاصطناعي التوليدي والأتمتة المتقدمة لتقديم تعليمات برمجية جاهزة للمؤسسات بسرعة واتساق أكبر. تعزز نماذج Bob مهارات المطورين، ما يؤدي إلى تبسيط مسارات عمل التحديث ويجعل مهام التطوير المعقدة أكثر سهولة.

  1. اكتشِف وكيل البرمجة المدعوم بالذكاء الاصطناعي.
  2. استكشِف حلول الذكاء الاصطناعي للمطورين.
المراجع

1 Sonia Haiduc، Jairo Aponte، Andrian Marcus، "دعم فهم البرامج من خلال تلخيص مصدر التعليمات البرمجية"، ICSE '10: وقائع مؤتمر ACM/IEEE الثاني والثلاثين الدولي لهندسة البرمجيات https://doi.org/10.1145/3377811.3380383.

2 Paul W. McBurney، Collin McMillan، "التلخيص التلقائي لمصدر التعليمات البرمجية للسياق لدوال Java "، https://ieeexplore.ieee.org/document/7181703.

3 Chen Lin، Zhichao Ouyang، Junqing Zhuang، Jianqiang Chen، Hui Li، Rongxin Wu، "تحسين تلخيص التعليمات البرمجية باستخدام تقسيم شجرة بناء الجمل المجردة على مستوى الكتل" مؤتمر IEEE/ACM، الدولي لفهم البرامج (ICPC 2021) https://arxiv.org/abs/2103.07845.

4 Jian Zhang، Xu Wang، Hongyu Zhang، Hailong Sun، Xudong Liu، "تلخيص مصدر التعليمات البرمجية العصبي المعتمد على الاسترجاع"، ICSE '10: وقائع مؤتمر ACM/IEEE الثاني والثلاثين الدولي لهندسة البرمجيات، https://doi.org/10.1145/1810295.1810335.

5 Xinyi Hou، Yanjie Zhao، Yue Huang، Zhou Yang، Kailong Wang، Li Li، Xiapu Luo، David Jin، John Grundy، Haoyu Wang، "النماذج اللغوية الكبرى لهندسة البرمجيات: مراجعة منهجية للأدبيات"، https://arxiv.org/abs/2308.10620.