【LLM 代码生成】论文分享:SVRC CoT Data Pipeline

论文名称:Think Like Human Developers: Harnessing Community Knowledge for Structured Code Reasoning

论文链接:https://arxiv.org/abs/2503.14838

机构:新加坡管理大学 + 悉尼大学

数据集链接:https://huggingface.co/SVRC-ICSE/SVRC

简介

在代码生成的领域,目前高质量的多步骤的推理数据仍然比较稀缺。现在业界为了提高LLM的推理能力,要么依赖强化学习(RL),要么依赖由LLM合成的容易出错的推理链数据,但都不是非常好的解法。

所以本篇论文提出了一个数据合成框架,叫SVRC(Structured and Validated Reasoning Chains),是从软件工程社区(LeetCode、Stack Overflow)的讨论数据挖掘、重组和丰富推理链。

数据源

为什么要从软件工程社区中收集数据呢,作者举了图1的Leetcode例子,这些讨论是真实的、经过同行评审后的见解,非常有价值。

在这里插入图片描述

但直接从其中取数据,是不行的,因为通常是非结构化的、分散的以及不完整的,需要做数据的处理,SVRC就是用来做这个事情的,当然该框架的重点是增强代码生成任务的推理能力

Data Pipeline(SVRC)

框架概述

在这里插入图片描述

图2展示了完整的数据构建Pipeline,有一个两阶段的构建过程。首先是 “Sample User Discussion”(用户讨论示例)部分,这里呈现了用户针对LeetCode问题(四叉树表示的二进制网格逻辑或)展开的讨论,涉及直觉(Intuition)、方法(Approach)、复杂度(Complexity)和代码解决方案(Code Solution)等方面,但部分内容缺失 。

接着是“Insight Completion”(见解补全)环节:先用AI识别缺失部分(Identify Missing Sections ),再用AI生成缺失内容(Generate Missing Sections ),比如补全直觉部分,像“通过递归和叶合并对四叉树进行逻辑或操作” 。

然后是“Code Perturbation”(代码扰动)部分:AI从结构扰动(Structure Perturbation)、输入扰动(Input Perturbation)、输出扰动(Output Perturbation)方面对代码进行处理,并更新代码格式的任务描述(Update Task Description for Code Format ) 。

在更新任务描述的过程中,按照软件开发生命周期展开的步骤进行描述:

  • Problem Understanding(问题理解):首先要理解四叉树是什么。

  • Planning(规划):一步步思考,明确要理解四叉树如何表示矩阵。

  • Design(设计):尝试勾勒方法,如判断四叉树是否为叶节点等情况。

  • Implementation(实现):尝试编写函数解决问题。

  • Iterative Refinement(迭代优化):思考边缘情况,确保函数能正确处理各种情形。

最终得到“Final Solution(最终解决方案)” 。整个流程通过这些步骤,利用社区讨论和AI技术,为棘手的代码问题生成推理链。下面仅对于两个阶段中的一些关键操作予以说明。

社区知识提取(Community Knowledge Extraction)

  • 补全讨论(Discussion Completion)

其实就是给不完整的数据,利用LLM进行补全,

① 第一阶段:参照 LeetCode 社区结构,用 LLM 对讨论内容分类,判断直觉、方法、复杂度等关键部分是否缺失,以二进制标签标识。

② 第二阶段:针对判定为缺失的部分,依据格式标准和讨论上下文(问题描述、已有讨论、代码解方案 ),利用 LLM 生成缺失内容。

  • 格式扰动(Format Perturbation)

通过引入格式扰动,用预定义算子生成代码结构、输入、输出格式变体,让 LLM 重写代码并控制扰动范围,再添加对应代码格式要求文本到问题描述中。

【举个例子】假设在 LeetCode 上有一道计算两个整数之和的题目,原本的 Python 代码解决方案是基于类的形式:

在这个例子中,进行格式扰动的操作如下:

  • 结构变化:将类形式的解决方案转换为函数形式。使用预定义的转换算子,把上述代码转换为:

  • 输入格式变化:从直接变量赋值改为标准用户输入机制。利用 LLM 将代码修改为:

  • 输出格式变化:调整为使用标准打印函数。再次借助 LLM 修改代码:

这样,就能通过多种格式的变化,既保持了代码的计算功能,又增加了代码格式的多样性,提升了模型的泛化性。

推理链增强(Reasoning Chain Enrichment)

其实主要是引入SDLC(Software Development Life Cycle,软件开发生命周期原则)这个工具,定义了推理链数据的理想态

① 问题理解(Problem Understanding):首先要全面阅读并分析任务描述,明确各项要求和限制条件。

② 规划(Planning):通过将任务分解为更小、可管理的子问题来制定解决方案策略。比较潜在的方法,并根据约束条件选择最有效的方法。

③设计(Design):概述实施所选方法所需的步骤。这可能包括伪代码、算法说明或识别边界情况。

④ 实现(Implementation):编写简洁、易读且文档完善的代码。使用有意义的变量名,并遵循最佳实践。

⑤ 测试(Testing):使用各种情况(包括边界情况)对代码进行测试,以确保其正确性和健壮性。

⑥ 迭代优化(Iterative Refinement):迭代优化从一个包含常见开发者错误的次优解决方案开始,这会导致失败。推理过程应在测试期间系统地识别问题,分析其根本原因,并迭代优化解决方案以优化代码。

贴上论文使用的Prompt模版,没给出具体的,说是在 replication 包里面:

但根据论文说明的内容,推测一个Prompt例子倒也不难,还是拿上面计算两个整数之和的例子说明吧:

在 SVRC 框架下,模型训练时会根据任务复杂度调整代码优化循环次数(比如简单-无需循环、中等-1次循环、困难:2次循环)。训练完成后,模型遇到新的未标注难度的问题,能凭借学习到的推理步骤,自动调整推理的深度和长度来应对。

概念验证实现(Proof-of-Concept Implementation)

论文做了一个前置实验,大概分四步:

  • 数据集创建(Dataset Creation)

按照 SVRC 方法从 LeetCode 平台收集以 Python 为主的推理数据集,用 DeepSeek V3 完成讨论补全和格式扰动,用 QWQ 重写和丰富讨论内容。收集 2024 年 1 月 1 日前的 2105 个 LeetCode 问题,筛选出 12444 个讨论帖,得到包含 12444 个数据样本的集合,每个样本平均含 5546 个标记。

  • 数据集质量评估(Dataset Quality Assessment)

从集合中选取 377 个样本评估扰动代码解决方案和推理链质量。

① 采用人工评估策略(Human Evaluation),由两名有经验的 Python 开发者进行人工评估,判断代码扰动正确性和推理链流畅度。

② 使用 GPT-4o 进行 LLM-as-Judge 评估,判断推理链逻辑正确性及与代码解决方案的一致性。结果显示推理链流畅度平均得分 5.0,扰动代码功能与原代码一致,但有 2 例格式要求与扰动代码不匹配,经扫描和人工修正解决;GPT-4o 评估推理链逻辑正确性平均得分 4.89/5,与最终解决方案一致性得分 4.93/5。

  • 模型训练(Model Training)

使用 SFT 对目标 LLMs 进行微调,以最大化生成正确推理和代码的可能性,微调后的模型称为 CodeThinker。

  • 模型推理(Model Inference)

CodeThinker 在推理时遵循与SFT过程中一样的Prompt。

实验结果

数据集

  • LiveCodeBench:

这个数据集持续从不同平台抓取新的代码问题,以避免训练数据污染。以论文的时间来说,LiveCodeBench 的最新版本包含了 2023 年 5 月至 2024 年 9 月来自力扣(LeetCode)、AtCoder 和 Codeforces 的 713 道编程问题。

由于模型仅在 2024 年之前发布的力扣问题上进行训练,作者选择 LiveCodeBench 的一个子集进行评估。该子集包括 2024 年 1 月 1 日之后发布的所有力扣问题,以及所有 AtCoder 和 Codeforces 的问题。

Baseline

  • SOTA LLMs

主要选取与 CodeThinker 参数规模相当的开源模型(如DeepSeekCoder-32B-Instruct、Qwen-2.5-32B-Instruct-Coder)和商业闭源模型(如GPT-4o-mini-2024-07-18、Gemini-Pro-1.5)。

  • CoT-based Approach

为所有开源LLM构建两个 CoT Baseline。

① 标准的无监督 CoT 方法,让模型在生成最终代码前逐步思考。

② CodeThinker 风格的提示方法,明确要求模型在生成最终代码前生成 SDLC 风格的推理步骤。

  • Reasoning-augmented LLMs

开源模型选择斯坦福发布的 S1,它在科学和数学数据集的难题上微调,且与 CodeThinker 基础模型相同便于比较;闭源模型选择 GPT-o1-preview。

评估指标

  • pass@1

为第一次尝试时通过所有给定测试用例的代码解决方案的百分比。

在这里插入图片描述

关键结论

  • RQ1:Comparison with Other LLMs

① 【表3】CodeThinker 在中等难度任务中表现突出,相比众多开源和闭源模型,其 pass@1 指标提升明显,在简单任务上表现与部分模型相当,整体性能出色。

② 【表4】CodeThinker 基于少量SFT数据集训练后,在简单任务上表现与 Qwen2.5-Coder 相近,在中、困难任务上远超 Qwen2.5-Coder,证明其能用较少数据实现更好的复杂任务处理效果。

在这里插入图片描述

  • RQ2:Generalization to Non-LeetCode Platforms

① 【图3】在不同难度代码任务上,Qwen2.5-Coder-32B-Instruct 与 CodeThinker 对比,简单任务中前者 pass@1 略高;中等难度任务 CodeThinker 优势显著,其 pass@1 远高于前者。

在这里插入图片描述

  • RQ3:Ablation Study

① 【图4】在不同阶段(S0 - S5),CodeThinker 在 LeetCode 数据集和非 LeetCode 数据集上表现有波动,总体在 LeetCode 数据集上提升明显,非 LeetCode 数据集从 S2 起逐步上升,反映不同阶段对不同数据集性能影响有差异。每个阶段的定义论文中有,不赘述了。

在这里插入图片描述

总结

这篇论文提出的SVRC框架,算是一个能从开源社区中,通过近乎自动化的手段抓取、生成高质量的代码生成推理链数据,并在具体的实验上得到了验证。但仔细想了一下,如果要落地到工业界,还是有几个难点:

  • 开源社区代码生成数据难度可能不够

在工业界,如果要在代码生成上体现真正的生产力,多半是复杂的工程项目级生成需求,而开源社区很少会涉及到这种项目级的需求,更多是单文件或者多文件的生成需求。

  • SDLC原则的普适性不足

虽然依赖SDLC构建了推理链数据的理想态确实有用,但不能对所有类型的代码生成需求都适用,这也是在工业界落地的一个困难点,可能对于特定的业务落地场景,这个原则就需要修改了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

依然易冷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值