返回列表

3rd place solution: VQA/AES=0.81/0.64 Diffusion model + differentiable SVG optimization

650. Drawing with LLMs | drawing-with-llms

开始: 2025-02-25 结束: 2025-05-27 AIGC与多模态 AI大模型赛
第三名解决方案:VQA/AES=0.81/0.64 扩散模型 + 可微分 SVG 优化

第三名解决方案:VQA/AES=0.81/0.64 扩散模型 + 可微分 SVG 优化

作者: c-number, daiwakun

发布时间: 2025-05-28

竞赛排名: 第 3 名

得票: 98

我们(@cnumber@daiwakun)想要感谢主办方不断改进指标,使本次竞赛变得有趣且有意义。在进入本次竞赛之前,我们对图像生成知之甚少,但我们学到了很多。

[最终提交代码]
解决方案描述如下

各步骤图像

由 FLUX.1-schnell 生成的原始图像
由 FLUX.1-schnell 生成的原始图像

由 vtracer 生成的原始 SVG 图像
由 vtracer 生成的原始 SVG 图像

迭代优化后的 SVG 图像
迭代优化后的 SVG 图像

迭代优化后经 ImageProcessor 处理的 SVG 图像(用于 VQA 评估的最终图像)
迭代优化后经 ImageProcessor 处理的 SVG 图像

我们很高兴分享我们在"Drawing with LLMs"竞赛中获得第三名的方法。本次竞赛挑战我们根据文本提示生成可缩放矢量图形 (SVG),同时遵守严格的大小和内容约束,并最大化视觉保真度和美学吸引力。我们的解决方案是一个多阶段管道,结合了强大生成模型、矢量化工具和可微分图形渲染的优势。我们很自豪能够展示我们的解决方案,它没有利用文本嵌入来作弊欺骗 VQA 评估器!

整体流程

我们的核心思路是首先生成捕捉提示词本质的高质量位图图像,将其转换为初始 SVG,然后迭代优化此 SVG,以提高其对提示词的忠实度、美学质量以及对竞赛 VQA 指标的遵循度,同时尊重输出约束。

以下是各阶段的分解:

  1. 位图生成 (Flux):

    • 我们使用了 Flux 模型 (flux.1-schnell) 来生成候选位图图像。
    • 提示词工程: 为了增加多样性和质量,我们采用了一组提示词模板:
      • '{description}' (原始提示词)
      • 'Beautiful illustration of "{description}"'
      • 'Simple svg illustration of "{description}", with colorful background, beautiful background.'
      • 'Simple svg illustration of "{description}", with background of minimal flat vector illustration of "colorful layered big mountains"'
    • 我们为每个提示词模板生成了 2 张图像,因此每个输入描述共有 8 个初始候选位图。
  2. 初始 SVG 转换 (vtracer):

    • 每个生成的位图都使用 vtracer 转换为 SVG。我们发现 vtracer 能有效生成清晰的多边形矢量图形。
    • 由于 vtracer 不提供通过参数直接控制 SVG 大小的功能,我们实施了一种二分搜索方法,以找到最佳的输入 PNG 分辨率,从而使生成的 SVG 符合大小约束。
  3. 候选选择与预优化:

    • 初始 SVG 被渲染回 PNG。
    • 然后使用 SigLIP (google/siglip-so400m-patch14-384) 对这些 PNG 进行排名,以选择与原始文本提示最相似的图像;该模型与 VQA 评分器 PaliGemma2 使用的图像编码器相同。我们从最初的 8 个候选中选择了前 2 名。
    • 这前 2 个 (SVG, 原始位图) 对使用我们的 pydiffvg 基于优化器进行了简短优化 (iterations = 10) (详情见下文)。
    • 经过这次简短优化后获得最高美学分数的候选者被选中进入最终的、更密集的优化阶段。
  4. 主要 SVG 优化 (pydiffvg 与自定义损失函数):

    • 这是我们优化过程的核心。所选 SVG 的参数(路径控制点、填充颜色、描边颜色和描边宽度)使用 pydiffvg 进行优化。
    • 优化器: Adam 优化器。
    • 学习率调度: 带热身的余弦退火。
    • 损失函数: 总损失是以下内容的加权和:
      • 美学损失: 来自美学预测器的负分数。我们的目标是最大化该分数。
      • SigLIP 相似度损失: 渲染后的 SVG(经下文详述的可微分 ImageProcessor 处理后)的 SigLIP (google/siglip2-base-patch16-224) 嵌入与目标 png 图像的 SigLIP 嵌入之间的负余弦相似度。
      • MSE 损失: 渲染后的 SVG(经 ImageProcessorTorch 处理后)与目标位图图像(经具有相同随机种子进行裁剪的参考 ImageProcessor 处理后)之间的均方误差。这有助于保持与初始高质量位图的结构和颜色保真度。
    • 优化运行了 iterations = 200 次迭代。
  5. ImageProcessorTorch - 可微分预处理:

    • 为了 bridging 我们的优化过程与竞赛评估之间的差距,我们实施了 ImageProcessorTorch。该 PyTorch 模块应用了一系列类似于评估详情中描述的图像变换。
    • 关键在于,这些操作被实现为(大部分)可微分,或在必要时使用直通估计器 (straight-through estimators),允许梯度流回 SVG 参数。
    • 变换包括:随机裁剪和调整大小、JPEG 压缩(通过 diff_jpeg 模拟)、中值滤波、FFT 低通滤波和双边滤波。
    • 渲染后的 SVG 在损失计算前通过此处理器。MSE 损失的目标位图也使用该模块的随机裁剪和调整大小部分进行处理(使用同步的随机种子),以确保公平比较。
  6. 最终 SVG 压缩与格式化:

    • 优化后,SVG 经过 several 后处理步骤以满足 10KB 大小约束和其他格式要求。
    • 这包括:
      • 移除 opacity 属性。
      • 将 RGB 颜色转换为 hex。
      • 四舍五入数值。
      • 合并具有相同填充颜色的路径。
      • 优化路径命令(例如,使用更短的相对命令,H/V 线)。
      • 使用类似二分搜索的方法找到 pydiffvg 输出 / vtracer 输入的最佳渲染大小,以便压缩后符合 10KB 限制。如有必要, aggressively 修剪路径。
      • 按照解决方案中观察到的模式,在 SVG 中添加了一个小的、一致的水印式签名 (<path d="M167 200h20l-20 30h20"...)。
同比赛其他方案