549. Stable Diffusion - Image to Prompts | stable-diffusion-image-to-prompts
感谢主办方举办这次比赛,也祝贺所有获奖者。今天错失奖项时我曾感到沮丧,但很高兴最终获得了金牌奖牌。
比赛初期我尝试了多种方法,但最终解决方案却相当简洁:从图像/视频字幕数据集的字幕生成887万张SD2图像,经过去重和预处理后,使用timm最新的骨干网络(如eva、convnext、swin)训练生成的图像。最终提交的推理笔记本在此。
比赛初期,我也像公开笔记本一样尝试了多种图像字幕模型。经过测试,结合4种字幕模型(在MS COCO上训练的GIT / CoCa / IC3的Socratic模型 / CLIP Interrogator)和@shoheiazuma的ViT训练模型在Public LB上达到了0.5568分。当结合4种图像字幕模型并使用@shoheiazuma的训练笔记本训练的ViT&Swin模型时,分数提高到0.57439 Public LB。
因此,最初我考虑创建两种方案(即图像字幕模型和直接优化模型)来生成最终提交,但图像字幕模型的推理时间过长,所以我放弃了对最佳图像字幕模型的搜索,转而专注于创建直接优化模型。对于直接优化模型,关键是尽快创建SD2数据集,因此我开始调研图像/视频字幕数据集。
我调研了图像字幕/视频字幕数据集,并选择以下数据集来创建SD2图像:

对于训练数据集,丰富词汇量和适中长度的文本字幕似乎很重要,因此我基于这两个因素选择数据集。我还使用了@tomokihirose的faiss脚本,仅对Diffusion14M DB和WebVid10M去除余弦相似度高于0.9的重复字幕。作为数据预处理,我还移除了非英语、少于5个单词或超过70个单词的字幕。
为了增强深度效果(如此贴讨论),我还添加了diffusion2M DB的224x224调整大小数据集[15]以及从diffusion2M DB字幕创建的另外722K(180.5K字幕 × 4个不同种子)数据到上述训练数据集。深度带来的增益很好(+0.005~0.010 Public LB),如后文结果所示,我应该更深入挖掘深度方面以进一步提升性能。
为创建SD2数据集,我使用diffusers库(权重来自stabilityai/stable-diffusion-2)的默认设置。为加速生成,我还使用以下代码片段应用了torch.compile模式和xformers:
stable_model.unet = torch.compile(stable_model.unet)
stable_model.enable_xformers_memory_efficient_attention()
为进一步加速,考虑过应用Token Merging或使用SD2中的DPMSolver++,但无法确认这些方法不会降低整体性能,且由于时间资源限制难以重新创建数据集,因此决定不使用这些技术。
创建887万数据集大约花了2个月时间,使用5-10台V100和1-5台A100。按我的配置,V100/A100每周可分别生成约10万/20万张图像,因此创建887万数据集大约消耗600个V100天或300个A100天。
我选择了3种骨干网络(eva-large 336尺寸、convnext-large 384尺寸、swin-large 384尺寸),每种模型训练5个epoch。训练每模型在单台A100上耗时约3-7天。所有模型在验证集上约4个epoch收敛(训练/验证集分割比例为0.9/0.1)。
实验中eva 196尺寸、deit3和efficientnet变体的性能低于上述3种模型,因此未采用。
训练脚本与@shoheiazuma笔记本基本相同,主要差异如下:
在重训练阶段,我将CosineEmbeddingLoss()改为CosineEmbeddingLoss(margin=-0.5) + 0.01 × MSELoss,并使用全部数据集进行训练。
最终提交时,将附图中标亮的14个模型与不同resize分辨率的TTA(460x460和512x512)进行等权重集成。
各训练模型的性能如下。Split1(502万)和Split2(650万)是从创建的887万SD2数据集中选取的,排除了来自DiffusionDB2M的722K(180.5K × 4个不同种子)数据:
衷心感谢日立公司(Hitachi Ltd.),我在本方案中使用了公司的资源来创建数据集和训练模型。