Что не так с вашим кодом, сгенерированным большими языковыми моделями?

от автора

Китайские ученые провели обширное исследование на 7 популярных LLM, генерируя с помощью них код, а потом выявляя и анализируя ошибки. Им удалось не только выявить и категоризировать наиболее частые закономерности ошибок, но и предложить метод их устранения.

Под катом вольный краткий перевод с комментариями

Для исследования были выбраны 7 моделей

Обзор  LLM, использованных в исследовании. CW обозначает Context Window.

Обзор LLM, использованных в исследовании. CW обозначает Context Window.

Бенчмарк для оценки моделей включал все образцы из HumanEval+ и MBPP+, а также 600 образцов из APPS+, в общей сложности 1000 образцов. Кроме того, для оценки эффективности генерации кода LLM в реальных проектах ученые создали реальный эталонный тест RWPB из репозиториев GitHub, созданных в 2024 году.

В рамках ограничений эксперимента сгенерированный код считался правильным, если он проходил проверку компилятора, выполнялся без ошибок и выводил ожидаемый результат для предопределенных входных данных. Кроме того, правильный код должен был пройти все тестовые случаи в бенчмарке, поскольку различные тестовые случаи охватывают различную семантику. Только пройдя все тесты, сгенерированный код мог продемонстрировать полное выполнение всех требований.

Основные выводы такие:

  1. Код, сгенерированный моделями, обычно имеет меньше строк, но немного более высокую сложность, в то время как количество API аналогично количеству канонических решений. Примечательно, что код, сгенерированный Claude-3, имеет тенденцию включать меньше строк кода и более низкую сложность при использовании большего количества API, что, вероятно, связано с тем, что Claude-3 использует API для замены частей сложной реализации кода. 

    Различия в характеристиках кода между кодом, сгенерированным моделями, и каноническими решениями на HumanEval+. CC обозначает цикломатическую сложность.

    Различия в характеристиках кода между кодом, сгенерированным моделями, и каноническими решениями на HumanEval+. CC обозначает цикломатическую сложность.
  2. Неверный код содержит больше комментариев, чем верный код.

    Для HumanEval+ неправильный код, особенно от Claude-3 и Deepseek-Coder, имеет тенденцию иметь больше разнообразных комментариев, чем правильный код. Аналогично, в наборе данных APPS+ дополнительные модели имеют тенденцию включать комментарии как в правильный, так и в неправильный код, с тенденцией к получению более высокого медианного числа комментариев в неправильном коде. Это явление можно объяснить двумя потенциальными факторами. Во-первых, сложные проблемы, присутствующие в корпусах кода, используемых для обучения этих LLM, часто содержат больше комментариев. Следовательно, LLM могут научиться воспроизводить эту модель, что приведет к генерации большего количества комментариев при решении сложных задач. Во-вторых, LLM могут генерировать дополнительные комментарии как форму контекстного или пояснительного контента, когда они не уверены в правильности сгенерированного кода. Однако эти комментарии не значительно повышают точность LLM, поскольку уровень корректности остается низким.

  3. По мере того, как описания проблем в бенчмарках удлиняются и становятся более сложными, LLM испытывают трудности с выполнением требований формата ввода-вывода и с большей вероятностью генерируют неполные синтаксические структуры. Это связано с тем, что более длинные и сложные описания проблем затрудняют для LLM запоминание деталей, а длина сгенерированного кода может привести к ошибкам, таким как непарные скобки. 

  4. Неправильное использование API составляет наибольшую долю runtime ошибок в большинстве бенчмарков. Существует три основных ошибки, связанных с неправильным использованием API: AttributeError (20,9%), TypeError (50%) и ValueError (26,9%). AttributeError возникает, когда делается недопустимая ссылка на отсутствующий атрибут API. TypeError возникает, когда API применяется к объекту неправильного типа, в то время как ValueError возникает, когда предоставляется аргумент правильного типа, но неподходящее значение.

  5. Реализация алгоритма часто неоптимальна, как правило, с высокой временной сложностью, что не позволяет программе завершиться в установленные сроки. Для более сложных алгоритмических задач LLM, как правило, используют циклы или глубокий поиск без оптимизированных условий выхода. Кроме того, частое использование рекурсивных алгоритмов значительно увеличивает временную сложность.

  6. LLM с закрытым исходным кодом превосходят LLM с открытым исходным кодом по качеству генерации кода для реальных проектов, особенно превосходно сокращая синтаксические ошибки и ошибки во время выполнения. Что касается функциональных ошибок, разные LLM работают одинаково, при этом каждая модель сталкивается с ошибками по разным проблемам.

Разница в количестве комментариев между правильным и неправильным кодом, сгенерированным LLM. SC2 обозначает StarCoder-2, DC обозначает DeepSeekCoder, LL3 обозначает Llama-3, а CL3 обозначает Claude-3.

Разница в количестве комментариев между правильным и неправильным кодом, сгенерированным LLM. SC2 обозначает StarCoder-2, DC обозначает DeepSeekCoder, LL3 обозначает Llama-3, а CL3 обозначает Claude-3.

Если интересна статистика эксперимента по отдельным моделям, она в табличке

Модальности трех распространенных тестов и производительность семи популярных LLM в генерации кода на этих тестах. CC обозначает цикломатическую сложность. Все значения указаны в %.

Модальности трех распространенных тестов и производительность семи популярных LLM в генерации кода на этих тестах. CC обозначает цикломатическую сложность. Все значения указаны в %.

Чтобы изучить основные причины неправильного кода, сгенерированного LLM, ученые провели всестороннее исследование таксономии ошибок в сгенерированном коде. В частности, этот анализ включал два ключевых шага:

1. На первом этапе скрипт собирал выходные данные интерпретатора Python во время выполнения кода и использовал регулярные выражения для первичной аннотации ошибок. Синтаксические ошибки идентифицируются путем сопоставления «Syntax Invalid» или «Syntax Error» в сообщениях об ошибках. Ошибки времени выполнения обнаруживаются путем сопоставления поля «Traceback». Функциональные ошибки распознаются фразой «AssertionError».

2. На втором этапе 22 эксперта с опытом работы в области разработки программного обеспечения рассмотрели некорректный код с основными типами ошибок и независимо создали таксономию для вторичных типов ошибок. Затем эксперты объединили каждую отдельную таксономию и обсудили свои выводы, чтобы установить окончательную таксономию. Наконец, разные эксперты дважды проверили аннотацию, чтобы убедиться, что все ошибки были правильно аннотированы.

В конечном итоге ученым удалось классифицировать ошибки на три основных типа ошибок и 12 вторичных типов ошибок.

Таксономия ошибок, возникших в коде, сгенерированном LLM.

Таксономия ошибок, возникших в коде, сгенерированном LLM.

Среди трех основных типов ошибок синтаксические ошибки составляют наименьшую долю, тогда как функциональные ошибки являются наиболее распространенными. По мере увеличения сложности набора данных частота функциональных ошибок также увеличивается. Большинство LLM имеют долю синтаксических ошибок менее 10%, тогда как DeepseekCoder, LLama-3, Phi-3 и GPT-3.5 имеют долю функциональных ошибок, превышающую 50% на APPS+. 

Распространение непонимания и логических ошибок в коде LLM

Распространение непонимания и логических ошибок в коде LLM
Распределение типов ошибок в зависимости от LLM

Распределение типов ошибок в зависимости от LLM
Описание типов ошибок:

Тип A: Синтаксическая ошибка.

Синтаксические ошибки нарушают грамматические правила используемого языка программирования. Эти ошибки обнаруживаются интерпретатором Python, когда он пытается выполнить синтаксический анализ перед выполнением кода. Существует три вторичных типа синтаксических ошибок: неполная структура синтаксиса , неверный отступ и ошибка импорта библиотеки .

A.1 Неполная структура синтаксиса. Неполная структура синтаксиса указывает на то, что сгенерированный код включает открытый или частично написанный элемент синтаксиса, который не был должным образом завершен. Этот тип ошибки включает неполные операторы, непарные скобки, незакрытые кавычки или пропущенные двоеточия.

A.2 Неправильный отступ Python использует отступы для определения области действия циклов, условных операторов, функций и других блоков кода. Неправильный отступ нарушает структуру синтаксиса, вызывая синтаксические ошибки или непоследовательную семантику. Как показано в следующем примере, уровень отступа второй строки не соответствует последующим строкам в том же блоке кода, что нарушает спецификацию Python.

A.3 Ошибка импорта библиотеки. Импорт библиотеки позволяет программам Python использовать внешний код, избегая избыточной разработки. К распространенным ошибкам импорта относятся отсутствующие операторы импорта и неверные уровни импорта. В следующем примере сгенерированный код неправильно импортирует все публичные функции из библиотеки heapq в теле функции. Однако эта операция разрешена только за пределами тела функции.

Тип B: Ошибка во время выполнения.

Ошибки времени выполнения относятся к ошибкам, которые возникают, когда код не соответствует спецификации времени выполнения, которая обнаруживается во время выполнения. Согласно таксономии, существует пять вторичных ошибок времени выполнения: API Misuse , Definition Missing , Incorrect Boundary Condition Check , Incorrect Argument и Minors .

B.1 Неправильное использование API. LLM используют API для повышения эффективности выполнения кода и достижения желаемых функций. Однако неправильная интерпретация атрибутов вызывающего, неправильное использование API или неправильная идентификация типа аргумента могут привести к неправильному использованию API, что приведет к ошибкам времени выполнения в сгенерированном коде. Следующий пример иллюстрирует ошибку атрибута, возникающую из-за неправильной интерпретации типа переменной tup .

B.2 Отсутствует определение. Python требует, чтобы переменные и функции были определены до их использования в программе. Однако иногда опускайте определение часто используемых переменных или простых функций. Как показано в коде ниже, LLM игнорирует определяющую переменную MOD , которая обычно используется в алгоритмических задачах.

B.3 Неправильная проверка граничных условий. Неправильная проверка граничных условий относится к неправильной реализации логики обработки краев или границ диапазона в программе. Как показано в коде ниже, программа не может проверить длину списка перед выполнением операции остатка, что приводит к ошибке ZeroDivisionError при обработке пустого списка.

B.4 Неправильный аргумент. LLM иногда игнорируют указанный формат ввода в описаниях задач, что приводит к несоответствиям в количестве или типе аргументов в сгенерированном коде. Как показано в коде ниже, задача включает два ввода: первый указывает количество элементов, а второй представляет элементы для обработки. Однако сгенерированный код устанавливает только один параметр для получения элементов.

B.5 Незначительные. Незначительные ошибки в ошибках времени выполнения включают ошибки тайм-аута и исключения, определяемые LLM . Программы, превышающие этот предел из-за высокой сложности алгоритма или чрезмерного количества итераций цикла, помечаются как содержащие ошибку тайм-аута. Исключения, определяемые LLM, относятся к исключениям, устанавливаемым LLM для условных ветвей в задаче, которые не имеют явно предоставленных решений.

Тип C: Функциональная ошибка.

Функциональные ошибки относятся к ошибкам в программе, которые заставляют ее вести себя неправильно или не так, как предполагалось в соответствии с ее функциональными требованиями ( т. е. код выполняется успешно, но не проходит все модульные тесты). Согласно таксономии, существует четыре вторичных функциональных ошибки: Непонимание и логическая ошибка , Галлюцинация , Ошибка формата ввода/вывода и Незначительные .

C.1 Непонимание и логическая ошибка. Задачи генерации кода включают алгоритмические проблемы, в которых LLM должны извлекать информацию из естественных языков и применять свои знания для понимания требований и установления правильной логики. Однако, сталкиваясь со сложными описаниями на естественном языке, модели часто испытывают трудности с полным пониманием концепций, ссылочных отношений и условных ветвей. Например, LLM могут неправильно интерпретировать конкатенацию целых чисел как числовое сложение. Как показано в коде ниже, LLM неправильно интерпретируют конкатенацию целых чисел как числовое сложение. Более того, даже если LLM полностью понимают описание задачи, преобразование этих знаний в правильную логику остается сложной задачей.

C.2 Галлюцинация. Галлюцинация относится к случаям, когда LLM генерирует код, который синтаксически правдоподобен, но фактически неверен или семантически бессмыслен. Как показано в коде ниже, код, сгенерированный LLM, вообще не соответствует требованиям задачи.

C.3 Ошибка формата ввода/вывода. В отличие от ошибки типа B.4 ( т.е. неверный аргумент), ошибка формата ввода/вывода относится к неправильному порядку входов и выходов, а также к неправильной точности выходных данных. Как показано в коде ниже, LLM неправильно преобразует вывод с плавающей точкой в ​​целое число.

C.4 Незначительные ошибки. Незначительные ошибки в функциональных ошибках включают неверную инициализацию , неоптимальный код и бесконечный цикл . Неправильная инициализация указывает на то, что логика кода верна, но неверные значения инициализации для некоторых переменных не позволяют коду проходить модульные тесты. Как показано в коде ниже, переменная max_sum неправильно инициализируется значением 0. Неоптимальный код относится к случаям, когда LLM генерирует код с использованием неоптимальных алгоритмов ( например, жадных алгоритмов) для решения проблемы, в результате чего код может пройти только некоторые модульные тесты, но не все. Бесконечный цикл относится к коду, который не соответствует условиям выхода из цикла при определенных входных данных, что приводит к бесконечному выполнению кода.

Как защититься от ошибок?

Авторы исследования предложили свой шаблон промпта для исправления ошибок

Промпт для исправления ошибок

Промпт для исправления ошибок

DOC_STRING и INCORRECT_CODE обозначают исходную проблему программирования и неверный код, сгенерированный LLM. BUG_CATEGORY содержит категорию и тип ошибок. COMPILER_FEEDBACK — результат выполнения компилятора. Если результат относится к типу A (т.е. синтаксическая ошибка) и типу B (т.е. ошибка времени выполнения), предоставляем журнал ошибок; если компилятор не возвращает ошибку, но код не проходит модульные тесты (т.е. функциональная ошибка), предоставляем сообщение «Функциональность кода неверна»; и если выполнение кода превышает ограничение по времени, предлагаем сообщение «Выполнение кода превысило ограничение по времени». CAUSE_AND_CODE обозначает основные причины и местоположения ошибок, а также повторно исправленный код, сгенерированный LLM.

Повторно исправленный код из $CAUSE_AND_CODE проверяется и если все еще не проходит модульные тесты,нужно обновить шаблон промпта последним некорректным кодом и результатом компилятора для проведения следующей повторной итерации исправления.

Чтобы оценить эффективность метода исправления ошибок для каждого LLM исследователи случайным образом выбрали 120 неверных кодов, сгенерированных соответствующими моделями и провели две итерации исправления ошибок в каждом неверном коде.

Результаты исправления ошибок GPT-4 с использованием  подхода, основанного на самокритике.

Результаты исправления ошибок GPT-4 с использованием подхода, основанного на самокритике.

В начальной итерации GPT-4 исправляет 24,1% (29 из 120) неправильного самогенерируемого кода с помощью предложенного метода. Еще 6,6% (6 из 91) кодов исправляются во второй итерации. Синтаксические ошибки полностью исправляются в первой итерации. Для runtime ошибок 23% кодов ошибок исправляются в первой итерации и 16% во второй итерации. Для функциональных ошибок 23% исправляются в первой итерации и 3% во второй итерации.

Оригинал

Если вам интересны новости про генеративный ИИ, LLM, мультиагентов, я рассказываю об этом в своем Телеграм канале https://t.me/generative_ai_ru


ссылка на оригинал статьи https://habr.com/ru/articles/827800/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *