ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于两阶段大模型训练的代码反编译(SK2Decompile)工作进度汇报

基于两阶段大模型训练的代码反编译(SK2Decompile)工作进度汇报 第1页封面 — 工作进度汇报【开场白】面带微笑语速适中目光扫视全场各位老师、同学们大家好今天我向大家汇报的是我们课题组在「基于两阶段大模型训练的代码反编译SK2Decompile」这一方向上的最新工作进展。本次是第二次正式汇报主要围绕数据预处理流程的梳理、SFT监督微调阶段的环境适配与训练进展以及强化学习RL阶段的初步启动情况展开。下面我将逐页为大家详细讲解。【过渡提示】切换到下一页手势指向屏幕右侧或使用翻页笔首先让我们来看一下整体的工作进度总览明确哪些任务已经完成、哪些正在进行中。第2页两阶段模型训练 — 进度总览【本页要点】用手指或激光笔依次点出三个模块的状态这一页是我们当前工作的整体进度一览表。整个项目分为三大核心模块【已完成】数据预处理与 IR 过程梳理清晰第一块是数据预处理和 IR中间表示流程的梳理。经过这段时间的努力我们已经把从原始伪代码到标准化 IR 的完整预处理管线跑通并梳理清楚包括四个关键步骤伪代码归一化、源代码混淆生成 IR、clang-format 格式化、以及类型推断。这部分工作已经完成。【进行中】两阶段 SFT 训练第二块是两阶段的 SFT监督微调训练。这是目前工作的重心所在。第一阶段是结构提取Skeleton/Structure Extraction第二阶段是标识符恢复Identifier Recovery/Skin。我们在环境搭建过程中遇到了一系列硬件适配问题——原论文使用的是 NVIDIA H800-80GB GPU 集群而我们的服务器只有单卡 V100显存仅约 32GB。因此需要做大量的参数调整和适配工作包括精度从 bf16 改为 fp16、禁用 DeepSpeed 分布式训练、以及考虑引入 LoRA 等低秩适配技术来缓解显存压力。目前两个 SFT 阶段已在 CPU 上成功跑通。【刚启动】两阶段强化学习 RL第三块是强化学习RL阶段。根据原论文的设计在 SFT 完成之后还需要利用编译器反馈的奖励信号对模型进行进一步微调以提升反编译结果的正确性。这个阶段我们刚刚开始配置 VERLVersatile Reinforcement Learning框架目前处于初步探索阶段。【过渡】稍作停顿给听众消化时间接下来我先详细介绍一下 IR 预处理的具体流程这是整个训练 pipeline 的基础。第3页IR 预处理流程【本页要点】配合流程图讲解从左到右、从上到下这一页展示的是我们项目的核心 Pipeline——两阶段反编译流程以及前置的数据预处理步骤。【整体架构】如屏幕上的流程图所示整个反编译过程分为两大阶段• Phase 1Skeleton骨架/结构提取——输入是二进制文件或伪代码Pseudo-code输出是标准化的中间表示Normalized IR。这一步的目标是恢复程序的控制流结构比如循环、条件分支、函数调用关系等但不关心变量名和函数名等标识符信息。• Phase 2Skin皮肤/标识符恢复——输入是 Phase 1 输出的标准化 IR输出是最终的源代码Source Code。这一步负责将有意义的变量名、函数名、类型名等标识符恢复回去让反编译结果具备可读性。【Phase 0数据预处理Data Preprocessing】在进入两阶段训练之前我们需要先对原始数据进行预处理将其转换为适合模型训练的标准化表示。预处理包含四个步骤1. Step 1 — 伪代码归一化Normalize Pseudo-code使用 normalize_pseudo.py 脚本按照 R2I 标准将原始伪代码转换为统一的格式。输入是 exebench_c.json包含原始 C 代码和对应的伪代码输出是 exebench_pseudonorm.json。2. Step 2 — 源代码混淆生成 IRObfuscate Source → IR使用 normalize_src_basedonpseudo.py 脚本对原始源代码进行混淆处理后生成对应的 IR。输入是上一步的归一化伪代码输出是 exebench_norm_top0.json。这里需要注意的是实际程序的参数和仓库 README 中描述的命令有所不同——具体问题我会在后面详细说明。3. Step 3 — 代码格式化Format with clang-format使用 format.py 脚本调用 clang-format 工具对生成的代码进行格式化确保代码风格统一。输入是 exebench_norm_top0.json输出是 exebench_format_top0.json。4. Step 4 — 类型推断Infer Types使用 inf_type.py 脚本结合 psycheC/psycheCgen 和 psycheCsolver 工具对混淆后的 IR 进行类型推断。这一步生成的类型信息将用于后续 RL 阶段的编译器奖励计算。【强调】语气加重突出预处理的重要性这四步预处理是整个训练 pipeline 的基石。只有数据预处理做得足够规范和干净后续的 SFT 和 RL 训练才能取得好的效果。目前我们已经完整地跑通了这四步并对每一步的输入输出做了详细的验证。第4页关于上次汇报中仓库代码的澄清【本页要点】语气诚恳解释之前的误解这一页是对上次汇报中一个遗留问题的补充说明和澄清。在上次汇报的交流中有老师指出我们展示的仓库代码看起来像是 IR 生成相关的代码而不是最终的反编译结果。经过我们后续的仔细核实和代码阅读可以确认上次展示的仓库代码确实属于 IR 生成的范畴也确实是在做预处理阶段的工作只不过当时还没有经过 Phase 1结构恢复阶段的完整 IR 处理。换句话说当时展示的代码处于预处理管线的中间环节——它生成的是初步的 IR但还不是经过第一阶段结构恢复后的标准化 IR。现在这部分复现工作已经全部完成我们可以确认从原始伪代码到最终标准化 IR 的全链路已经打通。【过渡】自然过渡到下一个问题在梳理预处理流程的过程中我们还发现了一个比较棘手的问题下面我来详细说明。第5-6页Step 2 遇到的参数不一致问题【本页要点】展示两张截图对比语气认真这是我们在执行预处理 Step 2 时遇到的一个实际问题也是复现过程中常见的「文档与代码不一致」的典型情况。【问题描述】仓库 README 中给出的命令行参数和实际程序代码中定义的参数并不完全对应。【具体表现】通过阅读 normalize_src_basedonpseudo.py 对应的实际源代码位于 hparams/parser.py 和相关文件中我们发现• 实际程序接受的参数包括--input_json输入 JSON 文件路径、--output_json输出 JSON 文件路径、--key_name键名默认值为 pseudo、--workers进程数默认 52用于并行处理、--remove移除失败案例的数量默认 1等。• 而在实际运行时命令中还出现了 --top 0、--pseudo pseudo_ 等 README 中未明确说明的参数。这些参数的含义需要通过阅读源码中的 argparse 定义来理解。【我们的处理方式】面对这种情况我们的做法是以实际代码为准。我们仔细阅读了 parser.py 中的 ArgumentParser 定义以及 training_args.py 中的参数解析逻辑逐一确认了每个参数的含义和默认值然后根据服务器的实际情况调整了运行命令。这也是开源项目复现中的一个重要经验——文档可能滞后或不完整源代码才是最权威的参考。【过渡】引出环境配置话题解决了预处理的问题后我们进入了最耗时的环节——SFT 训练环境的搭建与硬件适配。第7页两阶段 SFT — 环境配置与硬件差异【本页要点】列出每个版本号强调适配工作的细致性这一页汇总了我们在搭建 SFT 训练环境时所做的主要配置工作和硬件适配。【硬件差异】原论文使用的训练环境是 NVIDIA H800-80GB GPU 集群拥有大显存和多卡分布式训练能力。而我们所使用的服务器配置为 单卡 NVIDIA V100显存约为 32GB。这个硬件差距带来了以下几个需要解决的问题【精度适配bf16 → fp16】原论文使用 bf16BFloat16精度进行训练这需要 Ampere 架构及以上如 H100/H800 系列的 GPU 支持。V100 属于 Volta 架构原生不支持 bf16。当我们尝试使用 bf16 启动训练时系统报出了明确的错误Your setup doesnt support bf16/gpu. You need torch1.10, using Ampere GPU with cuda11.0。因此我们将训练精度从 bf16 改为了 fp16Float16V100 对 fp16 有良好的硬件支持。【依赖包版本锁定】经过多次调试我们敲定了以下环境配置这些版本号是经过验证可以稳定运行的组合• accelerate 1.3.0 Hugging Face 的分布式训练加速库• peft 0.14.0 Parameter-Efficient Fine-Tuning高效微调库• transformers 4.49.0 Hugging Face Transformers 模型库• trl 0.8.6 Transformer Reinforcement Learning用于后续 RL 阶段【提示】说明版本兼容性的重要性这里需要特别注意的是这些包之间存在严格的版本依赖关系。例如trl 0.8.6 要求特定版本的 transformers 和 peft 配合使用版本不匹配会导致各种隐晦的运行时错误。我们在环境搭建过程中花了相当多的时间来解决这类依赖冲突问题。第8页单卡适配 — 禁用 DeepSpeed【本页要点】解释为什么需要禁用 DeepSpeed原仓库的训练脚本是为多卡分布式训练设计的默认使用 DeepSpeed 作为分布式训练后端。【问题】当我们在单卡 V100 上直接运行原始训练命令时系统报错ValueError: Please use FORCE_TORCHRUN1 to launch DeepSpeed training. 这是因为 DeepSpeed 在启动时会检查是否有多卡环境单卡情况下需要特殊配置才能运行。【解决方案】考虑到我们的服务器只有一张 GPU 卡使用 DeepSpeed 的多卡通信功能不仅没有意义还会增加不必要的开销和复杂度。因此我们选择直接禁用 DeepSpeed改用 PyTorch 原生的单卡训练模式。具体做法是在配置中将 DeepSpeed 相关的选项关闭让训练流程走 Accelerate 的单设备路径。【过渡】引出更严重的显存问题禁用 DeepSpeed 之后训练脚本可以正常启动了但我们很快遇到了一个更严峻的问题——GPU 显存不足。第9页GPU 显存不足 — 引入 LoRA 的考量【本页要点】展示 OOM 错误截图和参数调整对比这一页展示了我们遇到的 GPU 显存溢出OOM问题以及相应的应对策略。【OOM 错误详情】即使在前面的所有适配工作完成之后训练仍然无法在 GPU 上正常运行。错误信息非常明确torch.cuda.OutOfMemoryError: CUDA out of memory. Tried to allocate 1.79 GiB. GPU 0 has a total capacity of 31.73 GiB of which 1.43 GiB is free. Including non-PyTorch memory, this process has 30.30 GiB memory in use.也就是说V100 的 32GB 显存几乎被完全占满连分配 1.79 GB 的空间都做不到。对于 LLaMA 这样的大语言模型来说即使是单卡全量微调Full Fine-Tuning32GB 显存确实捉襟见肘。【参数调整尝试】我们首先尝试通过调整训练参数来降低显存占用• 将 per_device_train_batch_size 从 8 降低到 1• 将 gradient_accumulation_steps 从 8 提升到 16以保持等效 batch size 不变• 其他参数保持不变learning_rate 3.0e-6num_train_epochs 2.0lr_scheduler_type cosine_with_min_lr然而即使将 batch size 降到最低的 1显存依然不够用。【LoRA 方案】在这种情况下我们开始认真考虑引入 LoRALow-Rank Adaptation技术。LoRA 的核心思想是冻结预训练模型的大部分参数只在注意力层注入低秩分解矩阵进行训练。这样可以将可训练参数量减少到原来的 1%~10%同时保持接近全量微调的效果。对于我们的 32GB V100 来说LoRA 几乎是唯一可行的 GPU 训练方案。【过渡】引出 CPU 训练方案在 LoRA 方案还在调研和配置的同时我们也探索了另一条路——直接在 CPU 上进行训练。下面是 CPU 训练的情况。第10页GPU OOM 错误截图【本页要点】让听众看清错误信息的细节这一页是 GPU 显存溢出的完整错误截图。大家可以清楚地看到• 错误发生在 PyTorch 的 CUDA 内存分配环节• 模型在 forward 过程中具体是在 attention_forward 和 softmax 操作时试图分配内存• V100 总共 31.73 GB 显存其中已用 30.30 GB剩余可用仅 1.43 GB• 即使是 1.79 GB 的分配请求也无法满足这张截图也印证了我们前面的分析在全量微调模式下LLaMA 模型的参数量加上优化器状态、激活值等轻松超过了 V100 的 32GB 显存上限。这也坚定了我们采用 LoRA 或 CPU 训练方案的决心。第11页CPU 训练 — 成功完成两阶段 SFT【本页要点】语气积极展示成果虽然 GPU 训练遇到了困难但我们没有停滞不前。我们转而在 CPU 上进行了训练并且取得了实质性的进展。【CPU 训练配置】• 训练设备CPU无 GPU 加速• 精度设置既不使用 bf16 也不使用 fp16直接禁用了混合精度训练• 原因CPU 不支持 CUDA 的半精度加速且禁用混合精度可以避免数值精度问题【训练结果】在 CPU 上我们成功完成了两个阶段的 SFT 训练• Phase 1 SFT结构提取训练完成模型已学会从伪代码/二进制到标准化 IR 的映射• Phase 2 SFT标识符恢复训练完成模型已学会从标准化 IR 到带标识符的源代码的映射【训练速度】诚然CPU 训练的速度远不如 GPU。由于没有硬件加速且禁用了混合精度训练速度较慢。但这至少证明了我们的数据管道、训练脚本、配置参数都是正确的——整个训练流程是可以端到端跑通的。这为我们后续在 GPU 上无论是通过 LoRA 还是申请更多资源重新训练打下了坚实的基础。【过渡】进入 RL 阶段SFT 阶段在 CPU 上完成后我们紧接着开始了 RL强化学习阶段的准备工作。第12页强化学习RL阶段 — 初步启动【本页要点】介绍 VERL 框架说明当前状态这一页介绍的是项目的第二大部分——强化学习RL阶段的进展情况。【RL 阶段的目标】根据原论文 SK2Decompile 的设计SFT 之后还需要进行 RL 微调。RL 阶段的核心思想是利用编译器作为奖励信号源——将模型生成的反编译代码送入编译器如 GCC/Clang根据能否成功编译、编译警告数量、以及运行时行为等指标给出奖励然后通过 PPO 或 GRPO 等算法进一步优化模型。这样可以显著提升反编译结果的正确性和可编译性。【VERL 框架】原项目使用的是 VERLVersatile Reinforcement Learning框架来实现 RL 训练。VERL 是一个专门为大语言模型强化学习设计的训练框架支持 PPO、GRPO 等多种算法并且对多卡分布式训练有良好的支持。【当前进展】目前 RL 阶段刚刚开始我们在 CPU 上完成了 VERL 的基础配置工作• 已进入 verl 目录阅读了安装文档verl/README.md• 已了解 RL 训练的启动方式bash verl/SK2DECOMPILE/train/sk2decompile-rl.sh• 已确认 RL 训练数据路径verl/SK2DECOMPILE/data/sk2decompile-rl-examples...• 正在进行环境依赖的安装和配置【说明】诚实说明当前状态需要说明的是RL 阶段比 SFT 阶段更加复杂——它需要同时运行多个模型Actor、Critic、Reward Model对计算资源的要求更高。目前在 CPU 上的配置还处于初步阶段完整的 RL 训练预计需要更多的计算资源支持。第13页关于 GPU 资源的说明【本页要点】实事求是不抱怨客观陈述这一页是一个简要的说明关于我们目前对 GPU 资源的使用情况。目前我们暂无权限查看 GPU 的使用情况和剩余额度。这意味着我们无法实时监控 GPU 资源的消耗也无法确切知道还有多少配额可以使用。这在一定程度上限制了我们对训练资源的规划和调度能力。如果后续能够获得更多的 GPU 资源特别是显存更大的 GPU 如 A100 或 H800或者获得 GPU 使用情况的查看权限我们将能够• 在 GPU 上重新进行 SFT 训练结合 LoRA 技术或全量微调• 开展完整的 RL 训练RL 对 GPU 资源的需求比 SFT 更高• 进行更多的消融实验和超参数搜索【过渡】准备结束以上就是本次汇报的全部技术内容。最后做一个简单的总结。第14页汇报完毕【结束语】真诚感谢欢迎提问各位老师、同学以上就是我今天要汇报的全部内容。让我做一个简短的总结【已完成】✅ IR 预处理四步流程完整跑通并梳理清晰✅ 澄清了上次汇报中关于仓库代码的疑问✅ 发现并解决了 Step 2 参数不一致问题✅ 完成了 SFT 环境配置bf16→fp16、依赖版本锁定、DeepSpeed 禁用✅ 在 CPU 上成功完成两阶段 SFT 训练✅ RL 阶段 VERL 框架初步配置完成【进行中 / 待解决】 GPU 显存不足问题——正在调研 LoRA 方案 RL 阶段完整训练——等待更多计算资源 GPU 资源查看权限——需协调申请感谢各位老师和同学的聆听欢迎大家提出问题和建议。—— 汇报结束 ——
返回列表