2026-06-12 回顾
再次决定写回顾
久违地留下回顾。之所以一直没有记录,并不是因为太忙,而是因为想留下完美的文字的心情更大。想等结果明确整理好后再记录,觉得失败或中途方向改变的过程留下来很尴尬。
但是回头看,恰恰是那个过程最有意义。过去的 10 天里完成的成果并不多,但为了制作 Godot 专用的编码模型,调查了哪些内容、在哪里卡住、做了哪些判断的改变,已经积累了相当多。因此今天决定把这些过程整理一下。
本地模型实验
一开始因为不想花 RunPod 的使用费,想把 Qwen 系列模型放到本地 PC 上。使用 RTX 3060,觉得 9B 左右的模型在 WSL 上应该还能跑。
但实际情况并不像预期那样。网络连接速度和响应延迟问题严重,甚至在收到一个回答之前,思考阶段就已经花了 5 分钟以上。这样实验速度太慢,且难以作为开发工具使用,于是立刻放弃了本地模型的运行。
这次实验得到的结论很明确:与其在本地强行运行大模型,不如现在先设计数据集结构和训练流水线更为重要。
Godot 数据集调查
要训练模型首先需要数据。于是寻找可用于 Godot 4 代码学习的数据集,发现了 Hugging Face 的 wallstoneai/godot-gdscript-dataset。
起初以为只是收集了大量 .gd 文件的数据集,但通过 Gemini 分析后发现结构更重要。关键不是从 GitHub 仓库里逐个文件抽取,而是把整个仓库展开,保留项目上下文的方式。
该数据集将仓库的 README.md、.gd 文件、目录结构合并为一段文本,并在其中以 Markdown 形式整理项目名称、Godot 版本、文件树、每个文件的内容。这样模型不仅看到单个代码片段,还能看到项目结构和文件之间的关系。
特别重要的部分是 Godot 3/4 版本的判别方式。Godot 并不像普通的 Web 项目有 package.json 或 requirements.txt。需要读取 project.godot 文件中的 config_version、config/features 等字段,或利用 GDScript 语法差异。
例如在 Godot 3 中使用 onready var、KinematicBody 等写法,而在 Godot 4 中使用 @onready、CharacterBody3D 等。通过正则或解析器捕获这些语法差异,就能在没有 JSON 版版本文件的非主流语言中进行一定程度的版本过滤,得到了这样的洞见。
仅靠数据集不足
随后在 YouTube 上看到针对 OPL 这门古老编程语言进行微调的视频。
但观看后仍未完全抓住要点。数据集的收集过程和微调过程需要衔接,“只有数据集的话,怎么学习?”这个问题一直悬而未决。
于是向 SSAFY 的教练请教,想收集特定版本的非主流语言数据,最有效的方法是什么。得到了关键的回答。
第一点是目前参考的数据集更像是 raw 代码数据集,而不是用于 assistant 训练的数据集。若想做聊天机器人,仅仅把 raw 代码直接放进去是不够的。
第二点是需要基于 raw 数据集让 LLM 生成问答对。听到这个答案后,我的任务变得更明确:不仅要收集 Godot 4 代码,还要生成问题数据和答案数据,制作成 instruction 数据集。
如果不经过这一步,“帮我设计地图”之类的请求,模型很可能会用 Python 而不是 Godot 来回答。因为现有模型大多已经大量学习了 Python 数据。若答案数据不明确,旧版 Godot 代码或其他语言混入的可能性也很大。
instruction 数据集与提示工程的思考
将 Magicoder-Evol-Instruct-110K 作为 instruction 数据集候选也查找了一下。
但大多数内容都是围绕 Python 编写的。直接使用的话,似乎不适合制作专用的 Godot 4 模型。
此时产生了“是否必须明确指出是 Godot?”的疑问。如果在数据中大量加入 Godot 内容,用户即使不说 Godot,模型也会倾向于用 Godot 代码回答吗?
在向学校的前辈请教后,方向稍有梳理。现在可能更适合精心设计提示工程或基于文档的检索结构,而不是单纯的 RAG。前辈建议先把 Markdown 文档做成向量索引,让模型能够查找所需数据,这种方式更为现实。
最终在当前阶段,我认为相比“帮我做地图”,更明确地说“用 Godot 做地图”更容易得到准确的回答。因为现有模型的 Python 权重较大,需要在提示的前端强力给出 Godot 这一条件。
架构重新设计
一开始对架构的设想相对简单。
数据集收集 → 问题/答案 数据集生成 → 模型训练但是很快我感觉到这种结构太危险了。如果在我对 Godot 3 到 4 的变化了解不足的情况下收集数据,错误的代码可能会被当作正确答案数据。即使是制作问答数据集,也可能混入 Python 代码或 Godot 3 代码。
于是我想到了先以官方文档为基准的结构。先爬取 Godot 3 到 4 的迁移文档和 Godot 4 官方文档,构建 RAG 聊天机器人,并把这个机器人放在前端,让它判断收集到的代码是 Godot 3 还是 4,是否使用了旧版 API,是否适合作为 Godot 4 代码。
附图是当时整理的流水线草案。

整体流程如下。
- 爬取 Godot 官方文档和迁移文档,构建 RAG 知识库。
- 按仓库单位收集 GitHub 上的 Godot 项目。
- 将 README、文件结构、GDScript 代码合并为一个上下文。
- 通过
project.godot设置文件和 GDScript 语法差异进行第一轮版本过滤。 - 使用 RAG 聊天机器人进一步判断是 Godot 3/4 以及是否使用旧版 API。
- 仅将经过 Godot 4 整理的数据制成 instruction/response 数据集。
- 用 SFT 和 DPO/Preference 数据训练 Godot 4 编码模型。
SFT 与 DPO 方向
随后通过 ChatGPT 进一步提问,得到了意想不到的方向。最初只想“生成 Godot 4 代码的模型”,但可以把学习任务划分得更细。
在 SFT 中可以设置以下任务。
- Godot 3/4 代码分类
- 将 Godot 3 代码转换为 Godot 4 代码
- 生成 Godot 4 代码
- 修复 Godot 4 错误
- 拒绝或纠正 Godot 3 API
在 DPO/Preference 中可以明确区分好答案和坏答案。例如,把混有 Godot 3 语法的回答设为坏答案,把纯粹的 Godot 4 代码设为好答案。
有了这种视角,就不再是“随便收集大量数据”,而是先决定“什么算是好答案”。
Godot 官方文档爬取
为实际尝试这一方向,我找到了爬取工具,使用了 crawl4ai。
- https://github.com/unclecode/crawl4ai
- https://docs.godotengine.org/en/stable/tutorials/migrating/upgrading_to_godot_4.html
我爬取并文档化了包括 Godot 4 官方文档、Godot 3 → 4 迁移文档、Godot 4 类参考、Godot 4 教程在内的约 1500 页内容。
起初我担心爬取的量太大,但与整体模型上下文大小相比,仅占约 3%,如果不是一次性全部放入模型,而是作为 RAG 或文档检索结构使用,完全可以处理。
数据流水线与 I/O 考虑
重新设计架构时,磁盘 I/O 与学习时机也成了问题。数据收集、预处理、后处理、存储、重新索引、学习如果全部串联,必然会出现瓶颈。
我向学校的前辈请教,得到的答案是:与其实时进行微调,不如快速完成数据获取与加工,学习采用批处理方式更好。
比如只有当数据集累计到一定量时才执行强化学习或微调。像复制槽一样,超过阈值再处理可以降低 I/O 瓶颈,实时性重要的环节应侧重数据获取与加工,而不是学习本身。
重新索引的成本在结构上难以完全消除。因此,与其试图消除这部分成本,不如制定何时重新索引、何时学习的规则,更为现实。
今日总结
回顾过去 10 天的进展,最初只是模糊地想“要做一个 Godot 编码模型”。但现在已经形成了更具体的结构。
仅靠原始代码数据集不足。需要以 Godot 4 为基准的精炼代码数据、基于官方文档的判别结构、instruction/response 数据、SFT 任务、DPO/Preference 标准,缺一不可。
此外,以我目前的技术水平,若没有像 Qwen 这样的大模型,直接从零构建编码模型几乎不可能。通过比较本地小模型和 ChatGPT 的编码能力,我意识到模型规模和预训练量的差距不可忽视。
尽管如此,方向已经比之前清晰得多。可以先以 Godot 4 官方文档构建知识库,过滤收集的数据,设定好答案与坏答案的标准,进而生成训练数据。
回顾
在写这篇回顾时,我最深的感受是必须降低记录的门槛。若只记录完美的成果,真正重要的过程会丢失。失败的实验、模糊的判断、途中更改的架构都是下一步决策的材料,如果不留下来,事后就无法解释为何做出这些选择。
今后我会更频繁地记录过程,而不是只发布完成的结果。与其等到失败后才去回顾,不如把失败和思考一起记录,这才是更好的方向。
以今天为契机,我想持续、稳定地留下回顾。即使不是完美的文章,即使是中间过程,只要记录下我尝试了什么、学到了什么、下一步会依据什么标准行动,就已经足够。