650. Drawing with LLMs | drawing-with-llms
我尝试了多种解决方案来参加这次比赛,但先从我的选定提交开始。
首先,我尝试微调 SSD,包括 LoRA 和全量微调,但没能得到好的结果。然后我尝试了 ostris/Flex.1-alpha,这是一个基于 FLUX.1-schnell 的 8B 模型,并在 8.5k 光栅化 SVG 图像上进行了微调。我做了几次迭代,得到了不错的结果,但还不够好。而且模型又大又慢。
然后我微调了 Alpha-VLLM/Lumina-Image-2.0,这是一个类似 flux 的 2B DiT 模型。经过几次尝试,我开始得到想要的结果(完全扁平化图像,细节最少)。然而模型在 1024x1024 下不够快,且在 768x768 以下无法产生好的结果。所以我调整了数据集,训练模型从 256x256 及以上生成。
我使用多线程(我找到了避免 Kaggle 包中 多线程问题 的方法)在 2 个 GPU 上并行运行推理,每个生成 5 张 320x320 的图像,使用 VTracer 将图像转换为 SVG,并使用 Node.js 本地服务器优化 SVG。我重复 Vtracer + NodeJs 优化迭代,直到得到 <10K SVG 且 deterioration(退化)最小。然后使用 zhibinlan/LLaVE-2B 对 prompt 对齐进行评分,并使用 metric 代码中的 aesthetic scorer 挑选得分最高的输出。我还应用了一个小圆圈作为 OCR decoy(来自 @richolson 的 notebook)。以下是一些样本:







我尝试了许多不同方法,如即时生成 VQA 并使用 metric 代码评分,移除 OCR decoy(影响 aesthetic score),对于 OCR 得分为 1 的图像,对于得分 <0.99 的图像,将 decoy 放在不同角落并获取得分最高的图像.... 但都没帮助。
我还尝试了微调后的 Flux-dev,产生了极好的结果,比 lumina(上面的图像)更好,但出于某种原因我得到了更低的分数 🤷。
这里是 notebook,但代码非常混乱,你会注意到所有方法都定义在 __init__ 方法中,以避免我提到的多线程问题。
我尝试的第一个解决方案,老实说,也是我最享受的一个,是微调 qwen-2.5-VL-3B 模型。我从 starvector/text2svg-stack 的 2M+ 样本数据集开始,花几天时间清洗、简化和格式化 SVG,使用特定格式以促进 LLM 学习。但数据集太 noisy(噪声大),我没有时间、资源和经验去高效过滤。而且大多数 SVG 是图标和黑白,审美糟糕。所以我收集了 8.5k 个 SVG 数据集,审美水平 decent 且在 10Kb 或以下(这些是我 rasterize 用来训练扩散模型的 SVG)。我花了近 2 周尝试微调但没得到好结果。据我理解模型太小,训练初期每个 checkpoint 都能看到改进,但后来总是在差不多 step count 开始退化。
我打算当模型学会生成足够好的 SVG 时,再次微调它以教它用 GRPO“思考”,这样当初始 LLM 生成初始 SVG 时,我会将其 fed 给思考模型进行分析并在思考过程中迭代细化,直到得到好结果。
虽然视觉语言模型 (VLLM) 方法没有成功,但这让我觉得参加这个比赛值得,因为对于扩散解决方案,我花了更多时间寻找绕过 metric 问题的方法,而不是改进模型。
结果发现问题不仅仅是 OCR,当我在 public LB 卡在 730 分后,我故意通过 aggressively 优化来降低输出质量,直到形状几乎不可见,只有颜色清晰可见,但本地得分仍然相似,有些样本甚至更高,尽管所有 OCR 得分都是 1.0。
总之,恭喜所有获胜者,享受吧!
另外,恭喜 @ryanholbrook 制作了最平庸的比赛 metrics 并坚持到底,尽管许多人报告了问题(有些几乎是 2 个月前)。