2 магистрант, e-mail: elli200314@gmail.com
Боднар А.В., Синяева Э.В. Разработка комбинированного подхода к обучению моделей исправления программ на основе синтетических и реальных данных. В работе рассматривается метод генерации синтетических программ для обучения моделей автоматического исправления кода. Предложен синтаксический генератор программ, основанный на представлении исходного кода в виде последовательностей правил грамматики и использовании рекуррентной сети LSTM. Подход обеспечивает создание синтаксически корректных и компилируемых программ, близких по структуре к реальным. Синтетические данные объединяются с исходным набором и применяются для обучения моделей локализации и исправления ошибок. Проведены эксперименты с моделями DrRepair и TransRepair, подтвердившие повышение точности исправления программ за счёт расширения обучающих данных.
Ключевые слова: генерация программ, синтетические данные, исправление кода, нейросетевые модели, машинное обучение.
Bodnar A.V., Sinyaeva E.V. Development of a combined approach to training program correction models based on synthetic and real data. The paper examines a method for generating synthetic programs for training automatic code correction models. A syntactic program generator is proposed based on representing source code as sequences of grammar rules and using an LSTM recurrent network. This approach enables the creation of syntactically correct and compilable programs with a structure similar to real programs. Synthetic data is combined with the original dataset and used to train error localization and correction models. Experiments with the DrRepair and TransRepair models were conducted, confirming an increase in program correction accuracy due to the expansion of training data.
Keywords: program generation, synthetic data, code correction, neural network models, machine learning.
Синтаксические ошибки представляют собой проблему как для начинающих программистов, так и для кода. Новичкам часто не хватает знаний для преодоления этих препятствий, и они не могут понять сообщения об ошибках компилятора, в то время как код, предлагаемый компиляторами, также не застрахован от синтаксических ошибок. Методы автоматического исправления программ направлены на решение этих проблем путём автоматического исправления синтаксических ошибок и предоставления обратной связи. Эти методы приносят пользу как начинающим программистам, так и системам искусственного интеллекта, повышая качество и надёжность кода.
В недавних исследованиях изучались различные методы глубокого обучения для автоматизированного исправления программ. Однако большинство работ сосредоточены на внедрении различных синтаксических ошибок в ограниченный набор корректных программ для обучения, главным образом из-за нехватки общедоступных наборов данных, специально разработанных для исправления синтаксических ошибок. В отличие от этого подхода, рассматриваем задачу расширения небольших и ограниченных наборов данных путём синтеза новых программ, что способствует развитию автоматического исправления программ.
Хотя современные языковые модели демонстрируют исключительную производительность при решении различных задач, предлагается два усовершенствования для повышения эффективности существующих моделей и достижения сопоставимых результатов при меньших требованиях к ресурсам. Подход включает разделение исходного набора обучающих данных на части и создание на их основе синтетических программ. Комбинация исходных и синтетических данных используется для обучения корректоров кода, которые затем агрегируются для генерации исправлений кода и устранения синтаксических ошибок.
Генератор кода на основе синтаксиса решает задачу обучения на синтетических данных, стремясь генерировать не только синтаксически правильные программы, но и программы, похожие на те, что создают люди, изучающие программирование. Этот аспект имеет решающее значение для того, чтобы модель глубокого обучения могла эффективно обслуживать предполагаемых пользователей.
Для этого предложен метод генерации синтаксически правильных программ с использованием заданного начального набора данных. Чтобы повысить синтаксическую корректность синтетического кода, программы представляются в виде последовательности правил грамматики в процессе генерации. Например, исходный код «i = i + 1» представлен как последовательность грамматических правил, полученных в результате обхода дерева синтаксического разбора в глубину. Для генерации кода используется структура кодер-декодер. Выбор правил синтаксиса для каждого шага зависит от входных переменных и результатов предыдущих генераций. Этот процесс принятия решений обучается на предоставленном наборе данных.
Хотя корректоры продемонстрировали эффективность в прогнозировании местоположения ошибок программирования, наблюдаются потенциальные преимущества использования альтернативных методов, основанных на необработанном коде или сообщениях компилятора. Основываясь на этом подходе, учитывается расположение операторов объявлений, которое является надежным и легко идентифицируемым источником для локализации ошибок. Это подчеркивает преимущества рассмотрения альтернативных источников информации для повышения точности методов локализации ошибок.
В задаче восстановления программы, если задана программа с L строками кода x=(x₁,...,xₗ), которая не проходит компиляцию, цель состоит в том, чтобы найти ошибочную строку L и предложить исправление xr, которое приведет к успешной компиляции или снизит серьёзность сообщений об ошибках. Этот итерационный процесс продолжается до тех пор, пока исправленная программа не будет успешно скомпилирована или не будет достигнуто максимально допустимое количество попыток восстановления.
Генератор кода на основе синтаксиса (SCG) использует существующий набор данных для генерации аналогичных программ. Исходные и синтетические наборы данных объединяются и используются в качестве обучающих данных для модели корректора, которая анализирует программы с ошибками и генерирует соответствующие исправления.
На этапе вывода прогнозы нескольких независимых моделей корректора и локализации ошибок агрегируются с использованием методов ансамблевого обучения для повышения общей производительности. Предлагаемый подход принимает только исправления, которые успешно проходят тесты компилятора как надёжные решения.
Выбор подходящего представления является важным начальным шагом в разработке генератора кода. Варианты включают n-граммы, последовательности токенов, абстрактные синтаксические деревья (AST) и другие. Последовательностные представления часто генерируют синтаксически некорректные программы. Чтобы устранить это ограничение, в подход включены синтаксические правила. Используется сериализованное представление на основе AST. Код изначально анализируется в AST на основе предопределенного набора грамматических правил.
После разбора AST числовая последовательность генерируется путем обхода дерева в глубину с учетом соответствующих правил грамматики. Например, фрагмент кода «i = i + 1» преобразуется в числовую последовательность «4 1 2 4 1 2 5 6». Каждое число в последовательности представляет собой правило грамматики, используемое на соответствующем этапе обхода AST. Для упрощения процесса генерации поддерживается стек действий, который отслеживает текущее состояние генерации. Выбранные правила помещаются в стек, а начальный нетерминальный символ удаляется во время генерации. Этот процесс продолжается до тех пор, пока стек не опустеет. В реализации используется 493 различных правила грамматики языка C.
Синтаксический подход к генерации синтетического кода позволяет создавать синтаксически правильные программы, но приводит к более длинным последовательностям представлений. Для решения этой проблемы программа делится на несколько частей на основе правил разбора. Корневой узел AST и поддеревья его листовых узлов сериализуются и используются для обучения. Для обучения генеративной модели используется двухслойная сеть LSTM. Модель получает предыдущее действие и родительское действие и предсказывает следующее действие. Родительское действие относится к действию родительского узла в дереве анализа относительно текущего узла. Такое включение позволяет модели получать дополнительные структурные знания.
Каждый шаг генерируется на основе изученного распределения из начального набора данных и предопределенных правил грамматики, что гарантирует выбор только грамматически правильных правил. Опишем алгоритм построения синтетического кода из набора операторов.
Входные данные:
- N – количество генерируемых операторов (строк кода, выражений или инструкций);
- S – множество доступных операторов;
Пошаговое описание:
- Цикл генерации операторов – для каждого шага i создаётся кодовый фрагмент (Ci) и множество переменных Vi. Итоговая программа (C) и множество переменных (V) постепенно пополняются.
- Проверка конфликтов переменных – для каждой переменной проверяется, не пересекается ли она по имени с другой переменной. При наличии конфликта выполняется переименование.
- Инициализация всех переменных – создаются начальные значения всех переменных для обеспечения корректности программы.
- Объединение инициализации и основного кода – объединяется часть инициализации и сгенерированный код.
- Проверка компиляции – финальная проверка, что программа успешно компилируется.
Генеративная модель создаёт короткие фрагменты кода, которые отличаются от реальных программ по длине и разнообразию символов. Для генерации более длинных программ используется стратегия объединения нескольких сгенерированных фрагментов кода. Количество операторов, определённых пользователями, обозначается как N. Эти операторы генерируются с использованием генеративной модели, что приводит к набору доступных операторов S. При генерации инициализирующей части программы фокусируется внимание на объявлении переменных без присвоения им значений, так как присвоение не влияет на компиляцию. Следуя алгоритму генерации, удаётся создавать компилируемые программы, демонстрирующие сходство с заданными, что устраняет разрыв между синтетическим и реальным кодом.
Для проверки эффективности проводятся эксперименты с использованием моделей DrRepair и TransRepair. DrRepair – двухэтапная модель: сначала предсказывает некорректную строку, затем предлагает исправления. TransRepair – модель на основе преобразователя, учитывающая контекст каждой строки кода и сообщения об ошибках для предсказания ошибок и исправлений. Используется набор программ DeepFix, включающий более 40000 программ на языке C. Программы делятся на 5 частей для проведения перекрёстной проверки. Для тестирования размер пучка составляет 100, максимальное число попыток исправления – 5. Также для проверки используется набор однострочных программ с ошибками из Tracer.
Синтетическая генерация кода использует двухслойную LSTM с коэффициентом отсева 0,5. Размерность вложений – 128, скрытых состояний – 512. Модель локализации ошибок – двухслойная архитектура преобразователя с теми же параметрами. Оптимизация осуществляется с помощью Adam, размер пакета – 128, скорость обучения – 0,001.
Для обучения моделей генерируются около 8 000 программ на каждый раздел, 40% добавляются в обучающий набор DrRepair, ещё 40% – в TransRepair. С помощью метода повреждения программ создаётся более 1 300 000 ошибочных программ на языке C.
Производительность сравнивается с моделями DeepFix, RLAssist, SampleFix, DrRepair, BIFI, MultiFix, PaLM и TransRepair. Точность определяется как отношение числа исправленных программ к общему числу ошибочных программ. Исправленные программы – это те, которые успешно компилируются без сообщений об ошибках.
В статье проведён анализ эффективности комбинированного подхода к обучению моделей автоматического исправления программ, основанного на интеграции синтетических и реальных данных. Предложен синтаксический генератор программ, использующий представление исходного кода в виде последовательностей правил грамматики и рекуррентную сеть LSTM, что позволяет создавать синтаксически корректные и компилируемые фрагменты кода, структурно приближённые к реальным программам, написанным обучающимися.
Эксперименты с моделями DrRepair и TransRepair на наборе данных DeepFix показали, что расширение обучающей выборки за счёт синтетически сгенерированных программ приводит к повышению точности локализации и исправления синтаксических ошибок. Предложенный подход позволяет частично преодолеть проблему дефицита размеченных данных для задачи автоматического исправления кода и демонстрирует перспективность использования синтетических данных в обучении нейросетевых моделей программного исправления.
В дальнейшем планируется исследовать применимость метода к другим языкам программирования и его интеграцию с современными архитектурами на основе трансформеров. Также представляется перспективным исследование комбинирования различных типов синтетических данных и разработка адаптивных методов генерации, учитывающих специфику конкретных доменов программирования.