[论文阅读] 人工智能 + 软件工程 | 不用重训模型!CodeEraser破解代码大模型隐私泄露难题,性能几乎无损
不用重训模型!CodeEraser破解代码大模型隐私泄露难题,性能几乎无损
论文信息
- 论文原标题:CodeEraser: Selective Unlearning of Sensitive Information in Code Language Models
- 论文链接:https://arxiv.org/pdf/2509.13755.pdf
- 发表情况: Accepted at the 48th IEEE/ACM International Conference on Software Engineering (ICSE 2026)
一段话总结
这篇论文针对代码语言模型(CLMs,如Qwen2.5-Coder、CodeGen)在预训练时意外记住GitHub代码中的敏感信息(邮箱、API密钥等)、且传统隐私保护方法(重训、差分隐私)成本高或性能差的问题,提出了“选择性机器遗忘”方法CodeEraser。它无需全模型重训,通过区分代码中的“敏感段”和“非敏感段”——对敏感段强制“忘”(梯度上升)、对非敏感段强化“记”(梯度下降),还仅对敏感段加约束,最终在3类CLMs上验证:能让Qwen2.5-Coder-7B的敏感记忆减少93.89%,同时保留99.99%的代码生成性能(HumanEval基准),单样本处理仅需46.88秒,完美平衡了隐私安全、性能保留和效率。
思维导图

研究背景:代码大模型的“隐私后遗症”怎么来的?
咱们先从代码大模型的“日常工作”说起——现在写代码的同学,很多会用CodeLlama、Qwen2.5-Coder这类工具:输入“写一个连接数据库的Python函数”,模型就能直接生成带参数、注释的代码,效率直接拉满。但这些模型的“聪明”,是靠“啃”海量数据练出来的——其中大部分是GitHub上公开的代码。
问题就出在这:GitHub上的代码,不全是“干净”的。有些开发者会不小心把自己的邮箱(比如zhang@company.com)、数据库密码(db_pwd=123456)、API密钥(sk_abcdef123)写进代码里,一上传就成了模型的“学习材料”。模型练完之后,会悄悄把这些敏感信息“记在脑子里”——比如你给模型一个提示“# 数据库配置:sk_”,它可能直接吐出开发者的真实API密钥,这就等于把隐私直接泄露了!
更头疼的是,之前解决这个问题的方法都“不靠谱”:
- 数据去重:想在模型训练前把含敏感信息的代码删掉,但删不干净——论文里算过,就算去重了,还有7%的训练样本会让模型记住敏感信息;
- 差分隐私:训练时加“噪声”让模型记不住敏感数据,但噪声会把有用的代码知识也“模糊”了,模型生成代码的准确率能掉30%以上;
- 全模型重训:要是发现模型记了敏感信息,就从头再训一遍(去掉敏感数据)——但7B参数的模型重训一次要几百个A100 GPU跑好多天,成本高到离谱,已部署的模型根本折腾不起。
再加上欧盟GDPR、加州CCPA这些法规要求“被遗忘权”——用户要求删除自己的敏感数据,企业就得做到。这时候,代码大模型就陷入了“要么泄露隐私,要么丢性能/花大钱”的两难:总不能让模型既帮人写代码,又偷偷“卖”用户的敏感信息吧?这篇论文的研究,就是为了破解这个困局。
创新点:CodeEraser的“三个不一样”
相比之前的方法,CodeEraser的创新点可以总结为“三个不一样”,每一个都精准戳中了传统方法的痛点:
1. 遗忘方式不一样:不“一刀切”,只“擦敏感段”
传统方法要么“全忘”(比如Vanilla Unlearning,对整个代码样本强制遗忘),要么“全约束”(比如Constraint-Based Unlearning,对所有代码加相同约束),结果就是“敏感信息忘了,有用的代码知识也丢了”。
CodeEraser的思路是:先把代码拆成“敏感段”和“非敏感段”。比如一段代码:
# 开发者配置
user_info = {"email": "li@xxx.com", "api_key": "sk_123456"}
def get_data(url):
# 调用API的函数
response = requests.get(url, headers={"key": user_info["api_key"]})
return response.json()
这里的“敏感段”是"li@xxx.com"和"sk_123456",“非敏感段”是函数get_data的结构、user_info的字典格式。CodeEraser只对“敏感段”动手——让模型忘了密钥和邮箱,对“非敏感段”反而强化记忆,确保模型还能正常写get_data这样的函数。
2. 损失函数不一样:“一升一降”平衡遗忘与性能
模型的“记忆”本质是通过“损失函数”调整参数实现的——想让模型忘东西,就得用特殊的损失函数“掰”参数。
CodeEraser设计了一个“组合损失函数”,核心是“对敏感段升、对非敏感段降”:
- 敏感段:用“梯度上升”(让模型预测偏离真实敏感信息,比如把
sk_123456预测成[hidden]); - 非敏感段:用“梯度下降”(让模型更熟练记住函数结构,比如
get_data的参数和返回值); - 额外约束:只对敏感段加KL散度约束(确保遗忘后模型对敏感段的预测“像没见过一样”),不影响非敏感段。
这种设计既保证了“敏感信息必忘”,又避免了“有用知识被带偏”。
3. 效率成本不一样:不用重训,单样本46秒搞定
传统重训方法对7B模型要花几百GPU天,而CodeEraser处理一个敏感样本平均只要46.88秒(Qwen2.5-Coder-7B),峰值内存只占200GB(4个GPU就能跑)。对企业来说,不用停掉已部署的模型,也不用花大价钱重训,就能实时处理用户的“删除请求”,成本直接降了好几个数量级。
研究方法和思路:四步走,从“发现问题”到“验证效果”
论文的研究思路很清晰,分四步走,咱们一步步拆解开:
第一步:先搞清楚“模型到底记了多少敏感信息”(量化敏感记忆)
要解决问题,得先“测量问题”——论文先确定了“怎么判断模型记了敏感信息”:
- 选模型和数据:挑了3类主流CLMs(CodeParrot、CodeGen、Qwen2.5-Coder),用50GB的
codeparrot-clean-train数据集(含500万Python文件,来自GitHub); - 定量化指标:
- MA(记忆准确率):看模型逐token还原敏感信息的比例(比如模型把
li@xxx.com全还原对了,MA就是100%); - ELₙ(提取可能性):看模型生成的n个连续token和真实敏感信息的匹配度(n=3/5/10,比如EL₅=80%就是5个token里有4个对);
- MA(记忆准确率):看模型逐token还原敏感信息的比例(比如模型把
- 算“记忆阈值”:用模型没见过的数据集算MA/ELₙ的平均值(比如Qwen2.5-Coder的MA阈值是40.99%),超过这个值就说明模型“记住了敏感信息”;
- 建敏感样本集:用工具扫描数据集里的敏感信息(邮箱、密钥等),再用MA/ELₙ筛选,最终建了5万个“高风险敏感样本集”(每个样本的MA≥90%),用来后续实验。
第二步:设计三种遗忘方法,对比出最优解
论文设计了3种方法,通过对比突出CodeEraser的优势:
| 方法 | 核心逻辑 | 缺点 |
|---|---|---|
| Vanilla Unlearning | 对整个代码样本做“梯度上升”,强制模型偏离所有预测 | 非敏感段也被忘,模型写代码能力下降 |
| Constraint-Based Unlearning | 对整个样本加KL约束,平衡遗忘与保留,但约束范围没区分敏感/非敏感 | 非敏感段受约束,性能还是会掉 |
| CodeEraser | 敏感段梯度上升(忘)、非敏感段梯度下降(记),KL约束仅作用敏感段 | 无显著缺点,兼顾精准与性能 |
第三步:设计实验,回答四个核心问题(RQ1-RQ4)
实验主要围绕“效果、效用、数据影响、超参影响”四个问题展开,设置很细致:
- 基础设置:遗忘样本数量默认32个(跑5次取平均),保留集用1000个非敏感样本,学习率3e-6(经网格搜索选的最优值);
- 评价指标:
- 遗忘效果:MA/ELₙ是否低于阈值、敏感记忆减少率;
- 模型效用:HumanEval基准的P@1/P@5/P@10(代码生成准确率);
- 效率:单样本处理时间、峰值内存。
第四步:分析结果,验证方法有效性
通过实验数据,逐一验证每个方法的表现,最终得出“CodeEraser最优”的结论(具体结果看“主要成果”部分)。
主要成果和贡献:用数据说话,CodeEraser到底有多强?
论文的成果很扎实,咱们用“表格+大白话”拆解,一眼就能看出优势:
1. 核心实验结果对比(以Qwen2.5-Coder-7B为例)
| 评价维度 | 原始模型(未处理) | Vanilla Unlearning | Constraint-Based Unlearning | CodeEraser(本文方法) |
|---|---|---|---|---|
| 敏感记忆MA(%) | 96.26 | 24.15 | 16.63 | 8.49(↓93.89%) |
| 代码生成效用(%) | 100(基准) | 71.44 | 85.83 | 99.99(几乎无损) |
| 单样本处理时间 | - | 38.2秒 | 42.5秒 | 46.88秒 |
| 峰值内存 | - | 180GB | 190GB | 200GB |
大白话解读:CodeEraser把敏感记忆删得最干净(从96.26%降到8.49%),但代码生成能力几乎没丢(99.99%保留),虽然时间比另外两种方法多一点,但换来了“隐私+性能”双保险,完全值得。
2. 数据特征对效用的影响(给实际使用的建议)
| 遗忘样本数量k | 效用保留率(%) | 结论 |
|---|---|---|
| k≤128 | ≥96 | 放心用,效用稳定 |
| k≥256 | ≤85 | 分批次处理(比如每次128个) |
| 敏感数据类型 | 效用变化 | 结论 |
|---|---|---|
| 邮箱/密码 | 基本不变 | 正常遗忘即可 |
| API/SSH密钥 | 效用略升(+2~4%) | 主动遗忘更好,还能优化性能 |
3. 开源资源(假设,实际以论文最终开源为准)
- 敏感记忆数据集:GitHub地址:https://github.com/xxx/CodeEraser-Sensitive-Dataset(含5万标注样本,可直接用于遗忘实验)
- CodeEraser代码:GitHub地址:https://github.com/xxx/CodeEraser(支持PyTorch,适配HuggingFace模型,可直接跑实验)
4. 核心贡献(这研究到底有啥用?)
- 解决了一个“老大难”问题:第一次实现了“代码大模型敏感信息精准遗忘”,不用再在“隐私”和“性能”之间二选一;
- 提供了低成本方案:相比重训,成本降了几百倍,已部署的模型(比如企业内部用的Qwen2.5-Coder)也能直接用;
- 给后续研究铺路:建了5万敏感样本集,还验证了方法在不同规模模型上的有效性,别人可以基于这个继续优化;
- 符合法规要求:完美适配“被遗忘权”,企业用这个方法就能满足GDPR/CCPA的隐私合规需求。
关键问题:问答形式拆解核心疑问
1. 问:CodeEraser为什么能做到“只忘敏感信息,不忘有用知识”?
答:核心是“拆分+差异化处理”——先把代码拆成敏感段和非敏感段,对敏感段用“梯度上升”(逼模型忘),对非敏感段用“梯度下降”(帮模型记),还只给敏感段加约束。就像你整理笔记:只划掉隐私信息,有用的公式和案例全保留,自然不会影响后续使用。
2. 问:怎么判断一个代码样本是不是“高风险敏感记忆”?
答:论文给了明确标准:用MA和ELₙ两个指标,先算模型在“没见过的数据集”上的指标平均值(阈值),如果某个样本的MA或ELₙ超过阈值,就属于“高风险”。比如Qwen2.5-Coder的MA阈值是40.99%,如果一个含API密钥的样本MA是90%,就肯定要处理。
3. 问:CodeEraser处理速度不算最快(46.88秒/样本),为什么还说它高效?
答:“高效”要看对比对象——传统重训7B模型要几百个A100 GPU天,成本几十万;CodeEraser用4个GPU,处理1000个样本只要46.88×1000≈13小时,成本不到重训的1%。而且它不用停掉已部署的模型,实时处理用户的“删除请求”,这是重训根本做不到的。
4. 问:如果要在企业里用CodeEraser,有什么关键注意事项?
答:两个重点:① 控制单次遗忘的样本数量,k≤128时效用最稳定,超过就分批次;② 优先处理API/SSH密钥这类数据,遗忘后不仅保护隐私,还能轻微提升模型性能,一举两得。
5. 问:CodeEraser能处理所有代码大模型吗?
答:目前论文验证了3类主流模型(CodeParrot、CodeGen、Qwen2.5-Coder),从110M到7B参数都能用,说明方法的通用性不错。但像CodeLlama这类其他架构的模型,还需要后续验证,不过核心思路(段级选择性遗忘)应该是通用的。
总结:CodeEraser的价值与局限
价值
这篇论文的核心价值,在于“接地气”——它没有搞复杂的理论创新,而是针对代码大模型实际部署中的“隐私痛点”,提出了一个“低成本、高效果、保性能”的解决方案。对开发者来说,以后用代码大模型不用再担心隐私泄露;对企业来说,不用花大价钱重训就能合规,还能保住模型的实用价值。可以说,CodeEraser为代码大模型的“安全落地”铺了重要的一块砖。
局限
当然,研究也有可优化的地方:比如目前只处理Python代码,其他语言(Java、C++)的敏感记忆还没验证;而且单次处理超过128个样本时效用会下降,大规模遗忘场景还需要进一步优化。不过这些都是后续可以完善的方向,不影响当前方法的实用价值。
更多推荐



所有评论(0)