十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

第四次阶段性汇报 · 讲稿(SK2 Decompile 复现 · 模型/数据迁移与 CPU 评测)

第四次阶段性汇报 · 讲稿(SK2 Decompile 复现 · 模型/数据迁移与 CPU 评测) 第四次阶段性汇报 · 讲稿SK2 Decompile 复现 · 模型/数据迁移与 CPU 评测P1封面各位老师、同学好下面由我来做本次的阶段性汇报。汇报内容主要围绕 SK2 Decompile 两阶段反编译框架的复现展开重点是上一阶段之后这一段时间里我在「模型迁移到 → 服务器上拉取并评测」这条流水线上做的事情以及其中遇到的问题、定位过程和后续的规划。P2本期工作总览先给大家一个总览的视图。这一段时间我主要在做两件比较大的事情。第一件是把上一阶段已经在 CPU 上训练好的两阶段模型——也就是「结构恢复pseudo2norm」和「标识符命名norm2code」这两个 checkpoint——推到上然后在云服务器上拉下来做进一步的处理。之所以要走这一步是因为后续要进入评测环节时GPU 算力服务器的库存持续开不起来这一点我后面 P10 的截图会具体讲到所以只能先在 CPU 服务器上完成数据归一化和评测脚本的验证等 GPU 有库存的时候再切回去。第二件是 CPU 端的评测。在迁移完成之后我尝试直接按官方仓库的说明跑评测脚本但发现命令跑通之后输出是空的于是开始排查 JSON 字段和代码的对应关系。这两件工作最后都走完了主要环节但也都碰到了比较硬的环境/依赖问题因此本期汇报的最后我会给出下一步的规划主要思路是「先用 huggingface 上的开源模型权重跑通评测把评测流程先稳定下来」再去啃两阶段 RL 训练这条更难的路。下面按页面顺序展开。P3模型上传触发问题先说模型上传。这一页是「上传」这个动作第一次出现报错的状态。上一阶段结束后本地 CPU 服务器上的 saves 目录里已经存了训练好的两个 checkpoint分别是 pseudo2norm-example 和 norm2code-example每个 checkpoint 都包含 model-0000X-of-00006.safetensors 这六个分片以及一份 optimizer.pt。这一份资产大约 51G是后续评测的关键输入。我先按 Git LFS 的常规做法在仓库里配置好 LFS、track 了 *.safetensors然后 git push。但 push 的时候Git 报了 LFS 错误也就是说单个 LFS 对象超过了 5GB5120MB的限制直接拦截了这次推送。于是我先用 du -h 找出所有超过 5GB 的文件定位到大头主要是两处我注意到一件有意思的事情上面列出的 4.6GB 的 safetensors 文件单看大小是「低于」5GB 的按理说不应该被 LFS 拦截。但LFS 是按字节严格校验的safetensors 在 LFS 传输时会附带元数据和校验信息最后生成的 LFS 对象会刚好触到 5120MB 这个阈值所以也被拒了。这意味着光删 optimizer.pt 还不够分片文件本身也要处理。思路是先把不需要的 optimizer.pt 之类的大文件删除再用自己写的 Python 程序把 4.6GB 的分片文件切成更小的片段再走 LFS。P4模型上传旧仓库清理 自动化脚本在做切分之前我又发现了一个更棘手的问题哪怕我把上面那些大文件从工作区里删了旧 Git 历史里依然残留着 51G 的 LFS 对象记录。它们已经 commit 进历史了靠 git lfs prune、filter-branch 这些常规手段怎么清都清不干净最后会随着 push 一起被重新生成出来。权衡之下我决定彻底抛弃旧历史初始化一个全新的仓库。具体的做法是在原 saves 目录的同级新建一个空的 saves 文件夹重新 init 一个仓库只 track 我真正需要上传的那两个 checkpoint 目录和 LFS 配置其他一概不带。这样等于从源头上让历史里没有 51G 的大文件。命令大致是为了把 4.6GB 的分片文件压到允许的阈值以下我还写了一个自动化的拆分/上传脚本auto_push.py它会先把每个分片切到 LFS 单文件阈值以下再按照 .gitattributes 里登记的规则走 LFS 通道上传最后做一次 push 校验。这一步之后SK2 仓库里就有了两个干净可拉取的 checkpoint。P5服务器下载模型拉取 合并分片模型有了之后下一步就是到云服务器上把模型拉下来。我在 CPU 服务器上 git clone 了 SK2 仓库又用 git lfs pull 把 LFS 对象真正取到本地。因为在客户端这边为了规避阈值做了切分所以拉下来的 safetensors 是被拆成若干 .part1.safetensors、.part2.safetensors 这样的分片的没法直接用 HuggingFace 的 from_pretrained 加载。所以我又写了一个 merge_model.py 的小程序思路很简单用一个正则 (.*)\.part(\d)\.safetensors 匹配到所有分片文件按 part 号排序后用 shutil.copyfileobj 顺序拼回原始的 .safetensors 文件拼完再把分片删掉腾出空间。脚本是递归遍历子目录的所以不管是 pseudo2norm-example 根目录下的分片还是 checkpoint-2 下面的分片都能一次性合并干净。调用方式python merge_model.py ~/SK2/pseudo2norm-examplepython merge_model.py ~/SK2/norm2code-example合并完成之后模型权重就从「分片 备份」恢复成了 HuggingFace 标准格式下一步就可以走评测脚本了。P6服务器下载数据评测数据集的另一半模型下载完只是第一步评测还需要「输入」——也就是反编译的输入数据。这一页想跟大家分享一个比较尴尬的发现我在云 CPU 服务器上尝试拉评测用的 datasethumaneval 那一份反向数据拉了很久最后进度卡在 50% 就下不动了。进一步排查发现根本原因是这台服务器的内存不够。前面 merge_model.py 合并分片时六个分片大约 27G 已经被吃掉了optimizer.pt 之类的辅助文件虽然不参与推理但留在磁盘上也会争抢空间更要命的是评测需要的环境配置比如一些体积比较大的 wheel 依赖、huggingface 缓存等在内存/磁盘双双吃紧的情况下根本下载不下来。所以这一阶段的结论是CPU 服务器上只完成了「模型拉取合并」这一半的工作评测数据集和环境配置这一半因为存储和内存的限制没法和模型共存。这个 50% 的状态也直接决定了后面我必须先把评测数据集和环境问题解决掉再回来做模型推理。P7CPU 评测首次跑 normalize_pseudo 输出为空在模型合并完成、临时清理出一部分存储之后我先不急着跑模型而是按官方仓库的说明先把数据归一化这一关跑通——这一步对应的是论文里 IR 生成流程的反向过程需要把原始样本里的伪代码字段统一成一种格式供后续反编译使用。官方仓库里提供的样例是 reverse_sample.json按照文档给的命令直接跑python normalize_pseudo.py \--input_json reverse_sample.json \--output_json reverse_sample.json命令本身没有报错进程正常退出但打开 reverse_sample.json 一看——输出是空的是一个空数组。我立刻觉得不对劲于是没有急着换工具先看代码和样例 JSON 的实际字段。这件事在下一页定位。P8CPU 评测定位 key_name 后续依赖问题定位的过程分两步。第一步定位 key 不匹配。我把 normalize_pseudo.py 的关键读取逻辑和样例 JSON 一起看1) normalize_pseudo.py 在解析每条样本时会从命令行参数 --key_name 拿到一个字符串默认值是 pseudo。2) 代码里实际是 entry.get(pseudo, ) 来取伪代码字段如果该字段不存在或为空串下游处理就退化成空字符串最后被过滤掉。3) 而 reverse_sample.json 里伪代码字段的名字是 ida_pseudo不是 pseudo。也就是说文档里给出的「直接照搬命令」对这份样例 JSON 是不 work 的——它读到的是空字符串所以输出是空。于是我把运行命令改成了python normalize_pseudo.py \--input_json reverse_sample.json \--output_json reverse_sample_norm.json \--key_name ida_pseudo \--workers 8 \--remove 0重新跑后输出文件里就有了非空条目第一道工序算是正式跑通。这一步也让我意识到官方仓库的 quick start 文档对样例 JSON 的字段名是有一个隐含假设的不读代码是发现不了的。第二步定位后续依赖问题。数据归一化跑通之后我继续往后走评测流程先跑 inference按 huggingface 路径拉开源权重再跑 evaluate。但 inference 这边频繁报环境和库依赖的错——包括 vllm、transformers、numpy、scipy、pydantic 这一系列大版本的相互约束再加上一些 mock/fake tensor 相关的报错频繁修改 requirements 之后依然没法稳定复现。我自己也意识到这种修修补补的方式在 CPU 上很难做到「评测结果可以与论文原始数据对比」这种量级的可靠性因为版本组合稍微一变量化指标的数值就会有偏差。所以这一阶段的后期我把决策点提了一下· 把 CPU 上的 inference/evaluate 暂时挂起来不再继续死磕依赖· 后续评测统一切到 GPU 平台去做· 评测环境也以 huggingface 上的开源权重为基准保证与原论文的对比口径一致。这是这一页最后给出的方向也直接连到了下一页的「之后规划」。P9之后规划下面说一下后续的工作规划分三条线。第一条线清理 GPU 服务器。目前云 GPU 服务器里还残留着一些之前装的依赖和下载的中间数据pytorch、transformers、vllm 的历史版本以及一些失败的 evaluation 缓存这都占着宝贵的存储和内存。后面我会先做一次大扫除——conda 环境按需重建pip 缓存清空没用的 inference 结果、临时数据集都删掉——为下一步「跑评测」腾出干净的运行环境。第二条线评测优先本地训练延后。上一阶段卡壳的两阶段 RL 训练会对 GPU 算力、显存、存储都有比较高的要求论文中报告的训练资源是 8×100 GPU·年这种量级我们复现环境远远达不到。所以我打算把「评测」和「训练」拆开先把评测跑通、再去啃训练。本期汇报里 merge_model.py 和数据归一化这一关其实就是在为这一步铺路。第三条线用 humaneval 和 bringup-bench 两条评测线并行方便与论文做对比。具体来说· humaneval 走 normsrcpseudo 这一份调用 huggingface 上的 sk2decompile-struct-6.7b结构恢复和 sk2decompile-ident-6.7b标识符命名两个模型对应仓库里 sk2decompile_inf.py 的接口。命令大致是· bringup-bench 走另一份 binary-level 的样本对应仓库 evaluation/bringupbench/ 目录调用 eval_infer_out.py 做汇编级评估这两条线一份偏源代码级、一份偏二进制级覆盖了论文评估体系的主要维度。评测脚本如果能稳定跑通就可以和原论文里 humaneval 的 re-execution rate、bringup-bench 的 replacement_failed 比例等指标做直接对比。总结一下这一段规划用「huggingface 上的开源权重 官方评测脚本」作为基线先把评测流程跑通、跑稳等 GPU 服务器清理干净、环境一致性问题解决之后再回头去啃两阶段 RL 训练这条硬骨头。P10GPU 服务器开不起来这一页插一张截图是我们在上尝试开 GPU 算力服务器时弹出的提示。可以看到右上角的红色提示「指定实例类型的库存小于指定的购买数量」。这件事直接决定了为什么这一段时间评测主要在 CPU 上做、为什么在环境上要绕一些路。我也会持续盯一下库存看到有货就尽快把 GPU 拿下来把规划里的两条评测线在 GPU 上正式跑起来。P11汇报结束页最后做一个简单的收尾。本期主要做了三件事一是把上一阶段的 CPU 训练模型推到再在云服务器上拉下来合并二是按官方命令首次跑 normalize_pseudo 时定位了 ida_pseudo / pseudo 的字段不一致问题并把数据归一化这一关跑通三是给下一步评测工作画了路线图先清理 GPU 服务器、用 huggingface 开源权重跑通 humaneval 和 bringup-bench 的评测再回到两阶段 RL 训练。中间最值得复盘的一个经验是开源仓库的 quick start 文档对样例数据是有隐含假设的命令跑通 ≠ 正确第一次跑出「空结果」时一定要回去对代码而不是怀疑工具链。以上就是本期的汇报内容请各位老师和同学批评指正。
返回列表