[论文分享] How could Neural Networks understand Programs?

news2025/1/18 6:50:15

前言

读一篇 ICML 2021 的论文How could Neural Networks understand Programs?

程序语义理解是程序设计语言处理(PLP)的一个基本问题。最近基于NLP预训练技术学习代码表示的工作,推动了该方向的前沿。然而,PL和NL的语义有着本质的区别。忽略这些,我们认为很难建立一个模型来更好地理解程序,要么直接将现成的NLP预训练技术应用于源代码,要么通过启发式向模型添加特征。事实上,程序的语义可以严格地用PL理论中的形式语义来定义。例如,操作语义,描述了一个有效程序的意义,通过基本操作(如内存I/O和条件分支)更新环境(即内存地址值函数)。在此启发下,本文提出了一种新的程序语义学习范式,模型学习的信息包括:(1)与操作语义中基本操作一致的表示;(2)程序理解所必需的环境变迁信息。为验证该建议,本文提出一种基于分层transformer的预训练模型OSCAR,以更好地促进对程序的理解。OSCAR学习从静态分析中获得的中间表示(IR)和编码表示,分别用于表示基本操作和近似环境变迁。OSCAR在许多实际的软件工程任务中展示了卓越的程序语义理解能力。

一句话: 应用Transformer模型做程序理解
项目地址: https://github.com/pdlan/OSCAR

导论

现代软件通常包含大量的代码、功能和模块,具有极其复杂的结构或组织方案。这给此类程序的编写、维护和分析带来了巨大挑战。幸运的是,一系列基于深度学习的生产力工具被开发出来,通过分析程序自动帮助程序员执行安全审计代码检索等任务
受用于自然语言语义理解的预训练表示的成功启发,有许多尝试将传统的NLP预训练技术移植到源代码层面,其中代码表示通过从大量源代码文本中捕获上下文信息来获得,然后在微调后用于各种下游软件工程任务。例如,CuBERT利用强大的预训练上下文嵌入模型BERT在Python语料库上学习信息表示; CodeBERT通过对NL-PL对进行预训练来学习通用表示,以连接自然语言(NL)和高级编程语言(PL)。此外将专家设计的特征(如数据流图)添加到预训练模型中,旨在为程序语义理解提供额外的信息。
然而,编程语言与自然语言在本质上有许多基本差异。例如,同一个程序可能对其输入和内存状态表现出不同的行为,而在自然语言中没有这样明确的概念。目前试图直接从源代码中捕获语义特性的方法,无论是应用现成的NLP预训练技术,还是通过启发式向模型添加特征,都会限制对程序语义的理解。

受编程语言理论的启发,本文提出了一种代码表示学习范式,可以使模型更好地理解程序。代码表示应该从以下方面学习:(1)源代码文本的翻译要与操作语义中定义的基本操作保持一致; (2)环境变迁信息
为了验证该建议的有效性,进一步提出了一种新的基于分层Transformer的预训练模型,称为代码抽象表示的操作语义(Operational Semantics for Code Abstract Representation, OSCAR),旨在捕获长序列代码之间的上下文信息。一方面,OSCAR使用中间表示(intermediate representation, IR)来表示基本操作,由于中间表示是在具有有限指令集的抽象机器上建模的,几乎可以完美地映射到操作语义,因此相比高级编程语言更适合于学习代码表示
特别地,IR可以通过从目标程序的二进制代码或源代码翻译得到。另一方面,获取具体而精确的环境变迁信息需要大量的实际执行和计算,既不现实又存在风险。因此,OSCAR交替地使用抽象信息,这些抽象信息可以由抽象解释启发的静态程序分析轻易地获得。
抽象解释(Abstract interpretation)通过对程序可能行为的数学表征来描述程序语义,而不是对程序在许多实际执行轨迹之后的行为建模。此外,为了捕获目标程序或代码片段的控制结构,提出了一种新的位置条件编码(Position Condition Encoding, PCE),将控制流信息编码到模型中。

Contributions
(1) 提出一种新的学习范式,表明预训练模型可以从表面的指令和底层的环境变迁中学习代码表示,缓解了从操作语义理解程序语义的限制。
(2) 提出OSCAR来证明所提出的设计,一个层次化的Transformer,用IR表示基本操作,用从静态分析中导出的编码表示近似环境变迁。为OSCAR设计了高效的训练目标,以在很大程度上促进程序语义的理解。
(3) OSCAR在广泛的下游实际软件工程任务上显著提高了程序语义理解的性能。此外,与最先进的预训练方法相比,OSCAR显示了显著的零样本能力,即无需微调参数。

方法

提出一种新的学习范式, 让预训练可以学习到潜层的指令信息, 同时学习潜在的环境转移信息
在简化的抽象机上,赋值和组合的意义分别表示为
在这里插入图片描述

E、L、V分别表示表达式、内存位置和值,s∈S表示将所有内存位置映射到值的环境函数,C表示代码片段。
先看左边的表达式, 意思是如果上部分表达式成立, 环境s中的表达式E降为V,那么下部分表达式成立, 程序L:= E将用L = V更新环境函数s
再看右边表达式, 如果上部分表达式成立, 代码段 C 1 C_1 C1在环境s下执行得到s’, 那么下部分表达式成立, C 1 , C 2 C_1, C_2 C1,C2在环境s下执行, 等价于 C 2 C_2 C2在s’下执行

一个代码片段的语义依赖于两个部分:指令和抽象机上的环境转换信息。因此,本文提出从这两部分中充分学习到良好的代码表示,以更好地理解程序的语义。下面,我们将介绍OSCAR,它是一个分层模型,从这两个方面学习代码表示。

现有的程序理解方法已经广泛采用直接从高级PLs中学习表示法。然而,随着现代编程语言和编译器的发展,源代码或二进制代码的文本表示与实际计算意义之间的差距变得越来越大。这个不可忽略的差距增加了对现有模型的代码理解的难度。为了更好地分析和优化程序,现代编译器会在为目标体系结构生成机器码之前将源代码翻译成IR。IR是以抽象机器为模型的,这种抽象机器通常被设计成每条指令只代表一个基本操作。收集了大量真实世界程序的语料库,并将它们翻译成LLVM IR作为我们的预训练数据。

在这里插入图片描述

利用结构化操作语义来说明如何将环境转换信息编码到模型中。结构操作语义的归纳性需要一个适当定义的初始条件,初始条件用初始环境函数来描述。为了充分捕捉环境变迁的具体而精确的信息,必须迭代输入值和初始条件的多种可能组合,并根据顺序规则实际执行程序来推断变迁。这显然是不可行的,因为实际执行非常耗时且有风险,例如对大型软件项目或恶意软件的分析。因此,我们交替使用从静态程序分析中获得的抽象环境信息,而不是具体的环境信息。抽象的环境信息受到抽象解释的启发, 通过对程序可能的行为的数学表征来描述程序语义,而不是在许多实际执行轨迹之后对程序的行为建模。将这一思想应用到结构化操作语义中,每个表达式不仅可以归约为一个具体的值,而且可以归约为值空间中的一个关系或一个可能的范围。

从指令中提取了三种类型的环境关系约束:由静态单赋值(SSA)控制的约束、由内存读取控制的约束和由内存写入控制的约束。这些信息可以很容易地通过LLVM内置的分析功能获得,例如MemorySSA。

OSCAR的模型架构是一个分层的多层Transformer编码器,如下图所示。OSCAR由两级编码器组成。下层由两个token级编码器组成,分别用于处理IR和抽象环境信息。上层是一个指令级编码器,旨在根据下层的输出进一步提取特征。每个级别编码器的实现与BERT相同。我们将两个标记级编码器称为IR和Env编码器。编译时将源码编译为binary, 然后用retdec反编译出LLVM IR, 将编写的pass作用于IR, 生成LLVM Abstract Environment文件, 每一条IR指令对应一个environment.
在这里插入图片描述
由于Transformer是为解决自然语言中的序列转导问题而开发的,它不能很好地捕获编程语言中复杂的控制结构,如迭代逻辑和选择逻辑。然而,控制流信息对于理解程序的语义是不可或缺的。为了克服这个问题,在之前的工作中,将控制流图(CFG)纳入Transformer.
本文设计了一种更为简单有效的方法PCE (Positional Condition Encoding),通过位置编码将控制流信息编码到模型中。PCE为目标程序或代码片段中的每条指令的位置分配3个可学习的嵌入向量,分别表示指令的当前位置和条件跳转后的目标位置,分别为true和false。图2给出了该代码片段对应的PCE示意图和控制流图,其中 p i p_i pi p i 1 p^1_i pi1 p i 0 p^0_i pi0 分别表示位置 i i i 的指令在当前位置的可学习嵌入,真跳跃位置的可学习嵌入,假跳跃位置的可学习嵌入。
在这里插入图片描述

从图2中我们可以看到,PCE可以将CFG中节点的出边信息纳入注意力模块,而入边信息也会在公式2中计算位置相关性后被捕获。这表明OSCAR可以用PCE捕获CFG的所有信息,即使CFG没有显式地输入到模型中。
在这里插入图片描述

基于优化技术的对比学习如何在预训练期间有效地捕获程序或代码片段级的语义知识对于代码表示模型无疑是至关重要的。然而,之前的工作并没有很好地研究它。实际上,现代编译器支持多种编译选项以满足不同的优化需求,例如最小化执行时间、内存占用、存储大小等。使用不同的优化技术可以将单个源代码翻译成对比IR,但不会改变代码的含义。当然,多种优化的不同组合可以用作源代码的数据增强方法。受此启发,本文建议采用动量编码器对比学习的[CLS]标记的目标作为OSCAR的自监督任务,以更好地促进从程序层面的语义理解。

实验

对公开的开源GitHub存储库中的大量真实程序语料库进行了OSCAR的预训练,涵盖了从操作系统和编译器到机器学习系统和线性代数子程序的广泛学科.
在这里插入图片描述

在本节中,我们评估OSCAR在几个程序语义理解任务中的性能。我们首先在一个实际而重要的软件工程任务上执行我们的模型,即Binary Diffing. 然后,在算法分类任务上评估OSCAR对高层次PL理解的性能。此外,作为一种预训练方法,研究了OSCAR在零样本学习中的性能,其中OSCAR的参数是固定的。最后,对消融研究中模型的组成部分进行了分析。

Bin-diff

在这里插入图片描述如图所示,OSCAR在五个程序的所有优化级别上的召回率都远远超过BinDiff、Asm2vec和BinaryAI。例如,在最困难的匹配情况下,即O0和O3优化水平之间的差异,OSCAR提高了每个程序上所有基线技术的召回率。

Algorithm Classification

在这一小节中,我们将研究OSCAR在高级编程语言理解方面的性能。实验在包含104个算法问题的POJ-104数据集[1]上进行.
在这里插入图片描述

与之前的所有方法相比,该模型取得了很大的改进,这表明OSCAR可以很好地理解用高层PLs编写的源代码的语义。

Zero-Shot Learning

我们进一步研究了预训练OSCAR在零样本学习设置中的性能,即在不修改参数的情况下评估OSCAR。
在这里插入图片描述

如表3所示,在不进一步修改参数的情况下,与其他预训练模型相比,预训练的OSCAR和OSCAR1−6−1在代码相似性检测方面都表现出了良好的性能。这表明OSCAR在无需微调的情况下对下游任务具有可移植性的潜力。

Ablation Study

在本小节中,我们将使用BusyBox研究OSCAR中每个组件对Binary Diffing任务的影响.

在这里插入图片描述

表4 展示OSCAR两个组件 contrastive loss 和 PCE 的消融实验, 如图所示,所有组件都是有益的,提高了二进制diffing任务的召回率。同时,我们在IR语料库上进一步训练BERT,这与CuBERT类似 [2],因为它们共享完全相同的架构,唯一的区别是CuBERT是在Python语料库上预训练的。实验结果表明,CuBERT在IR的二进制diffing任务上表现不佳,这反映了OSCAR的层次结构显著有益。

总结

Related Works

[1] Mou, L., Li, G., Zhang, L., Wang, T., and Jin, Z. Convolutional neural networks over tree structures for programming language processing. In Proceedings of the AAAI Conference on Artificial Intelligence, volume 30, 2016.
[2] Kanade, A., Maniatis, P., Balakrishnan, G., and Shi, K. Learning and evaluating contextual embedding of source code. 2020.

Insights

(1) Model的作用并不显著, 应该更加关注数据的处理, 考虑使用IR或者伪代码(IDA反编译出的结果)
(2) 一般来说, 如果用IR或者反编译的伪代码, 应该更接近汇编的形式, 作为数据集进行模型训练可能会有更好的效果? 不过目前的难点在于IR的生成问题, 这个问题亟待研究.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/197840.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CPP----精选常识100例

1 静态全局变量的作用域 本文件 2 判断一个程序是C还是C编译的 #ifdef __cpluspluscout << "c"; #else cout << "c"; #endif3 C函数传递方式 值传递&#xff0c;引用传递&#xff0c;指针传递 4 虚函数定义及用法 虚函数是C中用于实现多态(p…

vue2 a-tree-select树形结构-懒加载(无限子级)---笔记

实现效果 思维导图 HTML代码&#xff1a;treeData是绑定的数组&#xff0c;onLoadData是懒加载函数 <a-tree-select style"width: 100%; margin-left: 20px" tree-data-simple-mode multiplelabelInValueplaceholder"请选择…" v-decorator"[lea…

史上最详细的KMP算法教程,看这一篇就够了

&#x1f9d1;‍&#x1f4bb; 文章作者&#xff1a;Iareges &#x1f517; 博客主页&#xff1a;https://blog.csdn.net/raelum ⚠️ 转载请注明出处 目录一、BF算法二、KMP算法2.1 字符串基础2.2 next数组2.3 KMP的实现2.4 next数组的生成三、改进的KMP算法3.1 nextval数组3.…

turf.js实现行政区(多边形)图形合并边界提取,掩膜等效果

在做前端行政区展示的时候,可能经常会遇到这样的需求,就是给定一个行政区比如杭州市各个区,县的行政区边界图形,但是我们现在需要一个杭州市的行政区边界,我们是否可以通过前端合并这些行政区,答案当然是可以的,我们可以使用turf.js来实现这个需求。 turf官网:Turf.js…

纯滞后系统的数字Smith预估控制-2

在纯滞后系统的数字Smith预估控制-1的基础上进行Simulink仿真。采用 Simulink 进行数字化仿真&#xff0c;按Smith算法设计Simulink模块。在PI控制中&#xff0c;kp0.5&#xff0c;ki0.01。其响应结果如图1和图2所示。图1 Smith阶跃响应结果图2 只采用PI控制时的阶跃响应结果初…

CDA Level Ⅱ 模拟题(一)

单选1 练习题 【单选题】1/20 一项针对某城市小微企业税收扶持和税收种类的调查&#xff0c;本打算调查500个企业&#xff0c;但忽然发现税务中心数据库中已存有这项调查数据&#xff0c;并且可以有权限获取这份数据&#xff0c;请问这是什么类型的调查方式&#xff1f; A.分层…

flask计算pin码

Flask debug模式算pin码_Ys3ter的博客-CSDN博客_flask pin码 可以参考这个链接 ctfshow801 然后这张图非常的重要 也就是我们需要上面的各个因素&#xff0c;然后获得ping码&#xff0c;也就是console的密码&#xff0c;就可以自己输出命令 然后会有两个脚本&#xff0c;一个…

原神私服搭建教程(3.0本地版)

环境准备安装Java SE – 17 注意: 如果想仅运行服务端, 只下载 jre 即可MongoDB (推荐 4.0)代理程序: mitmproxy (仅需 mitmdump&#xff1b;推荐使用), Fiddler Classic 等校验win r &#xff0c;输入cmd 呼出控制台java&#xff1a;输入java -version 查看版本&#xff0c;正…

嵌入式Linux从入门到精通之第十二节:线程

线程类比于人得大脑,进程来实现具体操作 每个进程都拥有自己的数据段、代码段和堆栈段,这就造成进程在进行创建、切换、撤销操作时,需要较大的系统开销。 为了减少系统开销,从进程中演化出了线程。 线程存在于进程中,共享进程的资源。 线程是进程中的独立控制流,由…

【C++】C++ 入门(三)

目录 一、内联函数 1、前置知识 2、内联函数概念 3、内联函数特性 4、补充内容 4.1、宏的优缺点 4.2、C有哪些技术替代宏 二、auto关键字(C11) 1、概念 2、使用场景 3、使用细则 3.1、auto与指针和引用结合起来使用 3.2、 在同一行定义多个变量 3.3、auto不能作为…

Java安全基础(二)Servlet核心技术

因为在实习中&#xff0c;文章更新速度可能有点慢&#xff0c;初学JAVA安全&#xff0c;内容如有不恰当的地方&#xff0c;欢迎各位大佬指正。 今天写一下Servlet的一些核心技术&#xff0c;后面更新完Filter之后我会对这两个进行一个总结。 了解Servlet知识对后续的框架审计…

自媒体人绝对要知道的6款软件工具!免费文案、配音不在话下

NO.1丨喵盐配音&#xff08;小程序&#xff09; 喵盐配音&#xff0c;它是我近期使用次数较多的配音小程序。这是一款专注于文字转语音的智能语音合成小程序&#xff0c;不需要下载&#xff0c;v小橙序搜索在线使用。其拥有200多个抖音热门发音人&#xff0c;支持普通话、英语、…

更安全的ftp服务器Pure-FTP搭建(4)

实验简介 实验所属系列&#xff1a;Linux服务器搭建 实验对象&#xff1a; 本科/专科信息安全专业 相关课程及专业&#xff1a;计算机基础&#xff0c;计算机网络 实验时数&#xff08;学分&#xff09;&#xff1a;2学时 实验类别&#xff1a;实践类预备知识 本实验要求实验者…

【JVM】Java类加载机制详解

【JVM】Java类加载机制详解 文章目录【JVM】Java类加载机制详解一&#xff1a;类加载子系统1&#xff1a;类加载器子系统的作用2&#xff1a;加载器 ClassLoader 的角色二&#xff1a;类的加载过程1&#xff1a;加载阶段2&#xff1a;验证阶段&#xff1a;确保被加载的类的正确…

[leetcode 215] 数组中的第K个最大元素

题目 题目&#xff1a;https://leetcode.cn/problems/kth-largest-element-in-an-array/description/ 解法 这道题目目前快排可以直接过&#xff0c;但是时间复杂度是 O(nlogn)O(nlogn)O(nlogn)。 想要 O(n)O(n)O(n)&#xff0c;这就涉及到408考研知识点了&#x1f602;&…

Java高手速成 | 使用TCP进行手机文件传输

由于TCP是面向流的&#xff0c;这意味着接收端有可能会在一次接收动作中接收两个或者多个数据包&#xff0c;那么当发送方需要把一个大文件分批连续发送时&#xff0c;如何保证接收方能够正确地接收并重修组会成一个完整的文件显得十分重要&#xff0c;本节通过一个端到端的手机…

每天10个前端小知识 【Day 4】

前端面试基础知识题 1. js中如何判断一个值是否是数组类型&#xff1f; instanceof const arr []; arr instanceof Array; // true Array.isArray const arr []; Array.isArray(arr) // true const obj {}; Array.isArray(obj) // false Object.prototype.isPrototype…

拉伯证券|A股延续强势格局 北向资金开年以来净买入超1500亿元

周四&#xff0c;A股商场整体延续强势格局&#xff0c;沪指贴合5日均线震动向上。科技板块仍是干流热点&#xff0c;半导体板块大面积飘红&#xff0c;创新药、CRO等生长赛道均涨势杰出。 到收盘&#xff0c;上证综指报3285.67点&#xff0c;涨0.02%&#xff1b;深证成指报1213…

初识SpringSecurity

初识SpringSecurity spring-security在spring的官网即可找到 spring-security spring-security官方文档的地址 https://docs.spring.io/spring-security/site/docs/ spring-security是Spring系列的关于安全的框架&#xff0c;还有一套安全的框架是Shiro 环境的搭建 项目使…

Android 播放base64音频

需求描述&#xff1a; 做一个Android扫码验证入场的程序&#xff1a; 如果验证通过&#xff0c;则播放一段“验证通过&#xff0c;请放行”的语音&#xff0c; 如果验证不通过&#xff0c;则播放其他的语音提示。 实现步骤&#xff1a; 1.要播放语音提示&#xff0c;先要有…