1. 项目概述与核心挑战组合图像检索Composed Image Retrieval, CIR这个领域最近几年随着视觉-语言预训练模型如CLIP、BLIP的爆发式发展热度一直居高不下。简单来说它的任务就是给你一张参考图片比如一件红色T恤再给你一段描述修改意图的文本比如“把颜色换成蓝色”然后让你从海量图库中精准地找到那张符合描述的目标图片一件蓝色的T恤。这比单纯的“以图搜图”或者“文搜图”要复杂得多因为它要求模型不仅要理解图片内容还要理解文本描述的“相对变化”并将两者结合起来进行跨模态推理。这个技术在电商“找同款但不同颜色”、创意设计“参考这个风格但主体换成猫”、乃至日常的互联网搜索中都有着非常直观且巨大的应用潜力。然而在实际研究和工程落地中我们这些从业者一直面临两个非常头疼的“老大难”问题。第一个是评估基准的“模糊性”。现有的主流基准比如FashionIQ、CIRR里面存在大量“不确定查询”。举个例子查询是“把图中的狗换成猫”但图库里可能有好几张不同品种、不同姿态的猫的图片它们都“满足”查询要求。这种模糊性导致评估结果“水分”很大模型可能只是蒙对了某一类而非真正理解了“替换”这个动作这严重干扰了我们判断模型真实能力强弱。第二个是评估场景的“静态化”。现实中的搜索往往是交互式的用户一次没搜到会调整描述再搜。但现有评估几乎全是“一锤子买卖”只测单轮检索性能完全忽略了模型在多轮对话、持续优化场景下的潜力。这就像只考学生一次答题却不看他会不会根据老师的提示修正答案显然无法全面衡量其能力。针对这两个核心痛点我们团队近期的工作提出了一套组合拳一个全新的、更干净的评估基准FISD以及一个自动化的多轮评估框架。FISD的核心思路是利用扩散模型生成数据从源头控制参考图和目标图的差异确保每个查询都有明确、唯一的答案从而对模型在“数量”、“否定”、“背景替换”等六类复杂语义上的能力进行精准“体检”。而多轮评估框架则模拟了真实的人机交互过程让模型在多次“提问-反馈”中迭代优化检索结果。实测下来这套方法不仅像“照妖镜”一样暴露了当前SOTA模型在“否定逻辑”如“不要有眼镜”和“数量逻辑”如“变成四只猫”上的严重短板更惊喜地发现只要给模型多几次交互机会其最终检索性能能有质的飞跃。下面我就结合我们构建FISD和实现多轮评估的实战经验拆解其中的关键设计、实现细节以及那些论文里不会写的“坑”。2. FISD基准构建一个更干净的“考场”2.1 为什么需要FISD——现有基准的“阿喀琉斯之踵”在深入FISD的构建细节前我们必须先搞清楚现有基准到底哪里出了问题。以我处理FashionIQ数据集的经历为例里面很多参考图修改文本目标图三元组存在严重的歧义。比如参考图是一件圆领衫文本说“变成V领”但目标图库中可能同时存在深V领、浅V领、材质不同、花纹不同的多件V领衫。模型检索出其中任何一件在RecallK的指标下都算“正确”。但这真的能说明模型理解了“变成V领”这个动作吗很可能它只是学到了“V领”这个关键词与某类图片的强关联对于“从圆领到V领”的“变化”关系理解是模糊的。这种“模糊正确答案”的存在使得评估信号变得嘈杂模型性能的上限被虚假地抬高同时也让我们难以诊断模型在特定语义推理能力上的真实缺陷。FISD的出发点就是要打造一个“信息完全、语义多样”的基准。“信息完全”指的是对于每一个查询在构建的数据集中有且仅有一张目标图是严格正确的答案排除了模糊匹配的可能。“语义多样”则是指我们系统性地覆盖了CIR任务中几种核心且困难的语义操作类型确保评估的全面性。我们最终确定了六个维度数量Cardinality改变图中物体的数量。如“将鸟的数量设置为三只”。添加Addition在场景中添加新物体。如“在草地上添加一个池塘”。否定Negation移除或否定图中的某些元素。如“移除人物戴的眼镜”。改变Change改变物体的属性如类别、颜色、状态。如“将汽车从红色变为蓝色”。背景Background改变图片的背景。如“将背景从街道换为海滩”。复杂指令Complex Instruction组合上述多种操作的复杂指令。如“将狮子替换为一条龙并且让龙张开嘴背景改为雪山”。2.2 数据构建流水线当LLM遇见扩散模型构建一个高质量、可控的CIR数据集传统的人工标注成本极高且难以保证在“否定”、“数量”等抽象逻辑上的精确性。我们的解决方案是构建一个LLM大语言模型 扩散模型的自动化流水线辅以关键环节的人工校验。整个流程分为两大阶段文本生成和图像生成。第一阶段高质量的文本三元组生成我们的目标是得到三个关键文本参考图描述、相对修改文本、目标图描述。例如参考图描述“一张餐桌上有一个苹果。”相对修改文本“再添加一个香蕉。”目标图描述“一张餐桌上有一个苹果和一个香蕉。”这里的一个核心技巧是我们不直接让LLM天马行空地想象而是从一个现有的高质量图像描述数据集如COCO、Flickr30k中采样“参考图描述”作为种子。这样做的好处是种子描述本身通顺、符合语法且描述了真实场景为后续生成提供了稳定的基础。接着我们设计了一套详细的提示词Prompt来引导LLM我们选用的是Mixtral-8x7B进行生成。提示词的核心是角色扮演和约束指定。我们会告诉LLM“你是一个专业的图像内容编辑。给定一个图像描述请根据{语义类别}的修改要求生成一个具体的修改文本相对描述和修改后的图像描述目标描述。确保修改是具体、可视觉化的且目标描述必须严格是参考描述应用修改后的结果。”对于“否定”这类难点提示词需要格外设计。不能只说“移除某物”因为扩散模型对“不存在”的概念生成效果不稳定。我们会要求LLM生成“替换性”或“描述缺失状态”的文本。例如对于“移除眼镜”相对文本可能是“人物没有戴眼镜”目标描述则是“一个没有戴眼镜的人物肖像”。通过这种方式将“否定”语义转化为模型更容易处理的“状态描述”语义。第二阶段可控的图像对生成有了精准的文本三元组下一步就是用扩散模型我们使用Stable Diffusion XL把目标图“画”出来。这里最大的挑战是保证参考图与目标图之间的高度一致性——除了文本指定的修改点其他内容应尽可能保持不变这样才能确保评估的是模型对“变化”的理解而不是对两幅无关图片的识别。我们摸索出的关键控制手段是种子控制。在生成参考图和目标图时我们使用相同的随机种子。扩散模型的生成具有随机性但相同的种子结合高度相似的目标描述仅在修改点有差异能极大地促使模型生成在布局、风格、未修改物体外观上高度一致的两张图。这相当于给模型一个强烈的“对齐”暗示。然而扩散模型不是万能的直接生成的结果可能包含卡通风格、逻辑错误如三只手的怪物或明显不真实的图片。因此人工校验环节必不可少。我们建立了一个简单的校验规则检查生成图像对是否1符合自然图像分布2严格遵循文本指令3两者之间仅在指定维度存在差异。对于每一类语义我们生成了远超过200对的数据然后通过人工筛选最终每类保留200对高质量三元组构成总计1200对3600张图的FISD基准。实操心得数据生成的“坑”与技巧种子不是银弹即使种子相同过于复杂的指令如“复杂指令”类仍可能导致画面构图发生较大改变。这时需要在提示词中增加“保持其他所有内容不变”、“保持同样构图和视角”等强调语句。硬负样本的构建为了增加检索难度避免模型仅靠图像相似度“作弊”我们为每个三元组手动构造了“硬负样本”。例如对于“将女孩的裤子从短裤换成长裤”硬负样本可能是“一个穿短裤的女孩”或“一个穿长裤的男孩”。这迫使模型必须同时理解参考图和修改文本才能做出正确判断。构造硬负样本时我们同样使用扩散模型但会微调描述文本使其在视觉上与目标图或修改意图的某个子集相似。人工校验的成本这是最耗时但价值最高的部分。我们建议至少两人背对背校验重点检查“否定”和“数量”类别这两类最容易出现模型“偷懒”如用其他物体遮挡来代替“移除”或数量计算错误。2.3 FISD揭示了什么——当前CIR模型的“能力边界”在FISD上测试主流CIR模型的结果像一面镜子清晰地照出了当前技术的天花板与短板。我们以Recall1排名第一的即正确作为核心指标发现了一些非常有意思且一致的结论模型在“否定”和“数量”逻辑上表现极其挣扎。即使是表现最好的模型在“否定”语义上的Recall1也仅在17.5左右在“数量”上约为58.5。这与它们在“改变”如换颜色Recall1可达77和“添加”Recall1约69.5上的表现形成了鲜明对比。这背后的原因很深刻主流的视觉-语言模型如CLIP的预训练数据大多是描述“存在什么”的正面语句对“不存在什么”的否定句以及精确的数量关系建模能力天生不足。模型更容易学习到“蓝色”和蓝色物体像素的关联但很难学习到“没有眼镜”这种缺失状态与像素模式的关联。“直接”语义处理尚可但远非完美。对于“添加一个物体”或“改变物体属性”这类相对直接的指令模型表现相对较好但平均Recall1也仅在55-77之间仍有很大提升空间。这说明即使对于看似简单的任务模型对跨模态细粒度对齐和关系推理的能力依然不够鲁棒。数据合成与真实图像的鸿沟影响有限。一个自然的质疑是FISD用的是合成图像其结论能推广到真实图像吗为此我们从CIRR数据集中手动筛选并标注了一批真实图像中的“否定”语义查询进行测试。结果发现模型在真实图像上的“否定”表现同样显著差于其他语义类别与FISD的结论一致。这证实了FISD揭示的模型缺陷是本质性的而非合成数据带来的偏差。同时不同模型在FISD上的性能排名与在CIRR、FashionIQ等真实数据集上的排名高度相关这说明FISD具有良好的判别效度能够有效区分不同模型的优劣。3. 多轮评估框架让CIR模型学会“对话”3.1 框架设计模拟真实的人机交互循环单轮检索就像一次闭卷考试而真实搜索是一个动态的、多轮的对话过程。用户不满意结果会给出更具体的反馈。我们的多轮评估框架就是为了模拟这个过程其核心由三个模块构成一个现成的CIR模型、一个排序器、一个用户模拟器。整个工作流程形成了一个闭环初始查询用户提供参考图I_ref和相对描述t。特征组合与检索CIR模型将参考图和文本融合生成一个组合查询特征q。排序器用这个特征在图像数据库中进行检索返回Top-K个候选图像。成功判断如果目标图像在Top-K中流程成功结束。反馈生成如果目标不在Top-K中用户模拟器介入。它接收排名第一的候选图像和目标图像分析两者的差异生成一段新的、更精确的相对描述文本t_new。例如初始查询是“找一件更正式的衬衫”返回的候选是一件黑色衬衫但用户想要的是白色。模拟器可能生成“颜色改为白色”作为新一轮的反馈。迭代优化将上一轮的候选图像作为新的参考图结合新生成的反馈文本t_new形成新一轮的查询(I_cand, t_new)跳回第2步。如此循环直至找到目标或达到最大轮次我们设为5轮。这个框架的精妙之处在于它无需重新训练任何CIR模型可以直接套用在现有的任何CIR模型上将其从一个单次查询工具升级为一个支持迭代优化的交互式系统。3.2 核心模块实现细节排序器的历史信息融合排序器的作用不仅仅是计算当前查询特征与图库的相似度。为了利用多轮交互中的历史信息我们维护一个历史列表H存储每一轮产生的组合查询特征[q1, q2, ..., qr]。在计算第r轮的综合查询特征时我们采用了一个简单却非常有效的策略对历史所有轮次的查询特征求平均得到q_avg mean(H)。然后用这个平均特征去计算与图库中所有图像特征的余弦相似度并选择最相似的作为下一轮的候选。为什么求平均有效这相当于把用户多轮反馈的意图进行了“平滑”与“融合”。早期轮次的查询可能比较宽泛后期轮次的反馈越来越精确。平均操作让系统同时兼顾了整体的搜索方向和最新的细化指令避免了被某一轮可能不准确的反馈带偏。在我们的消融实验中不使用历史信息即只用当前轮特征的性能显著下降证明了历史信息整合的必要性。用户模拟器的构建MLLM LLM的协同用户模拟器是这个框架的“大脑”它需要像真人一样能够比较两张图片并指出关键差异。我们探索了多种基于开源大模型的方案。最终采用的稳定方案是一个两阶段管道视觉理解MLLM使用一个多模态大语言模型如LLaVA-Next分别为候选图和目标图生成详细、细致的自然语言描述。例如对于候选图MLLM可能输出“一张黑色衬衫的图片材质是棉有纽扣”对于目标图输出“一张白色衬衫的图片材质是棉有纽扣”。差异推理LLM将这两段描述输入一个纯文本大语言模型如Llama3-8B-Instruct并设计提示词“你是一个挑剔的用户。当前系统返回的图片描述是[A]但你实际想要的图片描述是[B]。请用一句简短的话描述你需要对当前图片做出什么修改才能让它变成你想要的图片。只输出修改描述。” LLM会基于指令跟随能力输出如“将颜色从黑色改为白色”这样的精准反馈。我们也尝试了让更强大的MLLM如Qwen2-VL直接“看图说话”输出差异虽然也有效果但生成的结果有时不够稳定或过于冗长。两阶段方案虽然多了一步但得益于LLM强大的文本推理和指令遵循能力生成的反馈文本更加简洁、规范更符合CIR模型对输入文本的预期。避坑指南用户模拟器的调优描述详细度是关键MLLM生成的描述不能太笼统。如果只输出“一件衬衫”LLM将无法推断出具体差异。需要引导MLLM生成包含颜色、材质、款式、背景、物体数量、空间关系等细节的描述。LLM的指令遵循能力我们对比了Llama2-7B、Mistral-7B和Llama3-8B。发现Llama2-7B有时会“放飞自我”生成与差异无关的内容严重干扰检索。而Mistral-7B和Llama3-8B表现稳健。因此选择一个指令遵循能力强的LLM至关重要。反馈文本的“毒性”模拟器生成的反馈应基于“候选图与目标图的差异”而不是“参考图与目标图的差异”。在提示词中必须明确强调“基于当前系统返回的图片”否则LLM可能会混淆轮次导致反馈错误。3.3 多轮评估的惊人效果与洞见我们将这个框架应用到多个开源CIR模型上在FashionIQ、CIRR、CIRCO以及我们自己的FISD上进行了测试。结果令人振奋性能提升是普遍且显著的。无论模型单轮性能强弱经过多轮交互后其检索成功率HitsK都获得了巨大提升。以在CIRR数据集上为例一些单轮表现较弱的模型如Pic2Word经过3轮交互Hits1从23.25提升到了40.28提升幅度超过73%。即使是当前最强的模型如SPN4CIR其Hits5也从85.29提升到了98.76接近完美。“好学生进步更快”。一个有趣的发现是单轮性能越强的模型在多轮交互中能达到的最终性能天花板也越高。这说明强大的基础检索能力是多轮优化的良好基石。多轮交互并非“点石成金”而是能将模型潜力充分释放的“放大器”。收益递减规律。性能提升主要发生在前3轮从第3轮到第5轮提升幅度明显变小。这符合直觉最初的反馈能纠正最大的方向性错误后续反馈则是在做精细调整。这也为我们设定交互轮次上限如5轮提供了依据平衡了效果与用户体验等待时间。与真人用户的对比。我们邀请了真人用户对50个单轮检索失败的困难案例进行5轮交互测试。结果显示我们的自动化用户模拟器达到的性能与真人用户非常接近甚至在部分案例上因为能提供更持续、更详细的反馈而表现更好。这强有力地证明了我们框架的有效性和实用性它能够以可扩展、自动化的方式近似真实地评估CIR模型的交互能力。4. 实战从零搭建多轮CIR评估系统4.1 环境准备与依赖安装想要复现或基于此框架进行实验你需要一个配备现代GPU如A100显存40GB为宜的Linux环境。以下是核心的Python库依赖# 基础深度学习框架 pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 # 图像处理与加载 pip install Pillow opencv-python # 多模态模型加载以LLaVA为例 pip install transformers accelerate # 用于LLaVA等模型 pip install timm einops # 可选用于管理大型模型 pip install bitsandbytes对于CIR模型你需要根据所选模型如SPRC、CLIP4CIR、Pic2Word从其官方GitHub仓库克隆代码并安装特定依赖。通常这些模型都基于Hugging Face的transformers库。4.2 核心代码模块拆解下面我将勾勒出整个多轮评估框架的核心代码结构并解释关键函数。1. 初始化模块import torch from PIL import Image from transformers import AutoProcessor, AutoModelForVision2Seq, AutoTokenizer, AutoModel # 假设你已有一个CIR模型类这里用伪代码表示 from your_cir_model import YourCIRModel class MultiRoundCIREvaluator: def __init__(self, cir_model_path, mllm_namellava-hf/llava-v1.6-mistral-7b, llm_namemeta-llama/Llama-3.2-1B-Instruct): # 1. 加载CIR模型 self.cir_model YourCIRModel.from_pretrained(cir_model_path) self.cir_model.eval() # 2. 加载用户模拟器组件MLLM和LLM # MLLM用于生成图像描述 self.mllm_processor AutoProcessor.from_pretrained(mllm_name) self.mllm_model AutoModelForVision2Seq.from_pretrained(mllm_name, torch_dtypetorch.float16, device_mapauto) # LLM用于生成差异反馈 self.llm_tokenizer AutoTokenizer.from_pretrained(llm_name) self.llm_model AutoModel.from_pretrained(llm_name, torch_dtypetorch.float16, device_mapauto) # 注意实际使用LLM生成文本可能需要搭配专门的文本生成接口如vLLM或HuggingFace pipeline # 3. 初始化排序器历史记录 self.history_features [] # 存储每一轮的组合查询特征 # 4. 加载图像数据库特征预计算好的 self.database_features torch.load(database_features.pt) # 形状: [N, d] self.database_image_paths [...] # 对应的图像路径列表2. 单轮检索与特征融合这是CIR模型的核心功能。不同模型融合图像和文本特征的方式不同这里展示一个常见的组合方式def compose_and_retrieve(self, image_path, text): 执行单轮组合检索 # 预处理图像和文本 image Image.open(image_path).convert(RGB) inputs self.cir_model.preprocess(image, text) # 模型特定的预处理 with torch.no_grad(): # 提取视觉特征和文本特征 image_features self.cir_model.encode_image(inputs[image]) text_features self.cir_model.encode_text(inputs[text]) # 特征融合例如加权相加、Cross Attention等 # 这里以简单相加为例实际请参考对应模型的融合方式 composed_feature image_features text_features composed_feature torch.nn.functional.normalize(composed_feature, dim-1) # 计算与数据库所有特征的相似度 similarities torch.matmul(composed_feature, self.database_features.T) # [1, N] topk_scores, topk_indices torch.topk(similarities, k10, dim-1) # 保存本轮特征到历史 self.history_features.append(composed_feature) return topk_indices[0].tolist(), composed_feature # 返回top-k索引和本征特征3. 用户模拟器生成反馈这是实现多轮交互的“智能”所在。def generate_feedback(self, candidate_img_path, target_img_path): 比较候选图和目标图生成文本反馈 # 阶段1: 用MLLM生成详细描述 def describe_image_mllm(img_path): image Image.open(img_path).convert(RGB) prompt Describe this image in detail, including objects, colors, actions, background, and their relationships. inputs self.mllm_processor(imagesimage, textprompt, return_tensorspt).to(self.mllm_model.device) with torch.no_grad(): output_ids self.mllm_model.generate(**inputs, max_new_tokens150) description self.mllm_processor.batch_decode(output_ids, skip_special_tokensTrue)[0] # 清理描述文本移除重复的prompt部分 return description.replace(prompt, ).strip() desc_candidate describe_image_mllm(candidate_img_path) desc_target describe_image_mllm(target_img_path) # 阶段2: 用LLM基于描述生成差异反馈 llm_prompt fYou are a precise user. The current image from the system is described as: {desc_candidate} But the image I actually want is described as: {desc_target} Please generate a short, clear instruction that describes the modification needed to change the current image into the desired one. Focus only on the key differences. Output only the modification instruction. Example: Change the color from red to blue. or Add a tree on the left. Modification instruction: # 这里简化了LLM调用实际中可能需要使用其对话API或文本生成pipeline # 假设有一个调用LLM的函数 feedback_text self.call_llm(llm_prompt) return feedback_text.strip()4. 多轮评估主循环def multi_round_evaluation(self, reference_img_path, target_img_path, initial_text, max_rounds5, top_k10): 执行多轮评估返回是否成功及最终排名 current_img_path reference_img_path current_text initial_text success False final_rank None for round_idx in range(max_rounds): print(f--- Round {round_idx1} ---) print(fQuery: Image{current_img_path}, Text{current_text}) # 1. 检索 topk_indices, current_feature self.compose_and_retrieve(current_img_path, current_text) # 2. 检查是否成功 target_index self.get_image_index(target_img_path) # 假设有函数能根据路径获取索引 if target_index in topk_indices[:top_k]: success True final_rank topk_indices.index(target_index) 1 print(fSuccess! Target found at rank {final_rank} in round {round_idx1}.) break # 3. 未成功则生成反馈 candidate_img_path self.database_image_paths[topk_indices[0]] # 取Top-1作为候选 feedback self.generate_feedback(candidate_img_path, target_img_path) print(fFeedback generated: {feedback}) # 4. 为下一轮更新候选图作为新参考图反馈作为新文本 current_img_path candidate_img_path current_text feedback if not success: print(fFailed after {max_rounds} rounds.) # 可以计算目标在最后一轮检索结果中的排名 final_rank self.calculate_rank(target_index, topk_indices) if topk_indices in locals() else None # 重置历史为下一个查询做准备 self.history_features [] return success, final_rank4.3 性能优化与工程化考量在实际部署和大量实验时以下几点经验至关重要数据库特征预计算在循环开始前务必预计算好整个图像数据库中所有图片的视觉特征。对于CIR模型中的视觉编码器如CLIP的ViT对每张图做一次前向传播将得到的特征向量保存下来。这样在检索时只需要计算一次组合查询特征然后做一次大规模的矩阵乘法或余弦相似度计算即可避免在每轮中重复编码所有数据库图片这是性能瓶颈所在。历史特征融合策略我们采用了简单的平均法效果已经不错。你也可以尝试更复杂的策略如加权平均给近期轮次更高权重、或使用一个轻量级的网络如MLP来学习如何融合历史特征。但在初期建议从简单方法开始验证。用户模拟器的加速MLLM和LLM的推理是耗时大户。可以考虑以下优化量化使用4-bit或8-bit量化加载模型能大幅减少显存占用并提升推理速度对精度影响很小。批处理如果需要评估大量查询可以将多个查询的“生成描述”或“生成反馈”步骤批量进行。缓存对于固定的候选图目标图对其生成的反馈是确定的可以缓存起来避免重复计算。错误处理与鲁棒性LLM生成的反馈可能不符合预期如过长、包含无关信息。需要在后处理中加入简单的规则过滤比如限制反馈句子长度、剔除以“I think”等开头的句子。设定反馈生成的重试机制。如果生成的反馈与上一轮完全相同或极度相似可能意味着模拟器“卡住”了可以尝试重新生成或使用一个备用的通用反馈如“请提供更具体的修改”。5. 常见问题、排查与未来展望5.1 实战中遇到的典型问题与解决方案在开发和实验过程中我们踩过不少坑这里总结一下最常见的问题及其解决方法问题1多轮检索性能不升反降。现象进行到第二、三轮时返回的结果反而离目标更远了。可能原因与排查用户模拟器反馈质量差这是最常见的原因。检查MLLM生成的描述是否足够详细和准确。可以打印出desc_candidate和desc_target进行人工核对。如果描述过于笼统如“一张图片”需要优化给MLLM的提示词要求其输出更细致的细节。历史特征污染如果早期轮次的检索方向完全错误其组合特征可能会“带偏”后续的平均特征。可以尝试只保留最近N轮如N2的历史或者当相似度分数低于某个阈值时不将该轮特征加入历史。CIR模型融合能力有限某些CIR模型对于“候选图差异文本”这种非典型输入的处理能力较弱。可以尝试在FISD的“改变”类数据上专门测试一下模型用“错误候选图正确修改文本”进行检索的能力。问题2评估结果波动大难以复现。现象同一模型、同一查询多次运行结果差异较大。可能原因与排查LLM生成具有随机性大多数LLM在生成时存在随机性通过temperature参数控制。为了评估的公平性和可复现性必须将LLM的temperature设置为0以确保每次生成的反馈是确定性的。数据库特征未归一化在计算余弦相似度前必须确保组合查询特征和数据库特征都经过了L2归一化。检查你的composed_feature和database_features是否都通过了F.normalize(..., dim-1)。图像预处理不一致确保CIR模型、MLLM在预处理图像如resize、裁剪、归一化时使用的是完全相同的流程和参数。一个像素的差异都可能导致特征提取不同。问题3运行速度太慢无法进行大规模评估。现象评估一个查询就需要几分钟。优化方案特征预加载确保所有模型CIR视觉编码器、文本编码器、MLLM在初始化时就加载到GPU中避免每次推理时重复加载。关闭梯度计算在所有with torch.no_grad():上下文中进行推理。使用更小的模型对于用户模拟器可以尝试更小但能力尚可的MLLM和LLM如较小的LLaVA版本或Phi系列模型。在效果和速度间取得平衡。并行化如果评估多个独立的查询可以使用Python的multiprocessing或concurrent.futures进行并行处理。5.2 未来方向与个人思考通过构建FISD和实现多轮评估框架我们不仅提供了一套新的评估工具更打开了一系列新的研究方向1. 面向交互训练的CIR模型 当前所有CIR模型都是为单轮检索设计的。一个很自然的想法是能否训练一个专门用于多轮交互的CIR模型我们可以构建一个包含多轮对话的数据集其中每一轮都有参考图历史对话当前反馈目标图这样的四元组。模型的目标是学会理解整个对话上下文而不仅仅是最后一轮指令。这可能会催生新的模型架构例如引入类似于Transformer解码器的机制来建模历史交互。2. 更智能的用户模拟与主动查询 目前的用户模拟器是基于规则的总是对Top-1生成反馈。未来可以探索更智能的模拟策略例如让模拟器学会判断哪一张候选图与目标图的差异“最容易描述”或者主动提出澄清性问题“你指的是颜色不对还是款式不对”。这需要将用户模拟器升级为一个具备规划能力的智能体。3. 基准的扩展与细化 FISD的1200对数据只是一个起点。如何将其扩展到数万甚至数百万规模同时保持高质量和可控性一种思路是利用更强的文生图模型如DALL-E 3、Midjourney和更精细的提示工程来批量生成。此外还可以引入更多样的语义类别如空间关系“把左边的物体移到右边”、情感风格“让画面看起来更忧伤”等进一步挑战模型的极限。从我个人的实战经验来看CIR领域正在从静态的“检索”向动态的“对话”和“协作”演进。FISD基准告诉我们模型在理解复杂、抽象语义上还有很长的路要走这需要我们在模型架构和训练目标上进行更根本的创新。而多轮评估框架则为我们指明了一个更贴近实际的应用范式未来的图像搜索系统或许更像一个拥有视觉能力的“对话助手”通过与用户的多次交流逐步勾勒并锁定用户心中那个模糊的意象。这条路充满挑战但也正是其魅力所在。希望我们提出的这套工具和发现能为同行们提供一些有价值的参考和启发。
组合图像检索(CIR)新突破:FISD基准与多轮评估框架实战解析
发布时间:2026/5/28 5:25:28
1. 项目概述与核心挑战组合图像检索Composed Image Retrieval, CIR这个领域最近几年随着视觉-语言预训练模型如CLIP、BLIP的爆发式发展热度一直居高不下。简单来说它的任务就是给你一张参考图片比如一件红色T恤再给你一段描述修改意图的文本比如“把颜色换成蓝色”然后让你从海量图库中精准地找到那张符合描述的目标图片一件蓝色的T恤。这比单纯的“以图搜图”或者“文搜图”要复杂得多因为它要求模型不仅要理解图片内容还要理解文本描述的“相对变化”并将两者结合起来进行跨模态推理。这个技术在电商“找同款但不同颜色”、创意设计“参考这个风格但主体换成猫”、乃至日常的互联网搜索中都有着非常直观且巨大的应用潜力。然而在实际研究和工程落地中我们这些从业者一直面临两个非常头疼的“老大难”问题。第一个是评估基准的“模糊性”。现有的主流基准比如FashionIQ、CIRR里面存在大量“不确定查询”。举个例子查询是“把图中的狗换成猫”但图库里可能有好几张不同品种、不同姿态的猫的图片它们都“满足”查询要求。这种模糊性导致评估结果“水分”很大模型可能只是蒙对了某一类而非真正理解了“替换”这个动作这严重干扰了我们判断模型真实能力强弱。第二个是评估场景的“静态化”。现实中的搜索往往是交互式的用户一次没搜到会调整描述再搜。但现有评估几乎全是“一锤子买卖”只测单轮检索性能完全忽略了模型在多轮对话、持续优化场景下的潜力。这就像只考学生一次答题却不看他会不会根据老师的提示修正答案显然无法全面衡量其能力。针对这两个核心痛点我们团队近期的工作提出了一套组合拳一个全新的、更干净的评估基准FISD以及一个自动化的多轮评估框架。FISD的核心思路是利用扩散模型生成数据从源头控制参考图和目标图的差异确保每个查询都有明确、唯一的答案从而对模型在“数量”、“否定”、“背景替换”等六类复杂语义上的能力进行精准“体检”。而多轮评估框架则模拟了真实的人机交互过程让模型在多次“提问-反馈”中迭代优化检索结果。实测下来这套方法不仅像“照妖镜”一样暴露了当前SOTA模型在“否定逻辑”如“不要有眼镜”和“数量逻辑”如“变成四只猫”上的严重短板更惊喜地发现只要给模型多几次交互机会其最终检索性能能有质的飞跃。下面我就结合我们构建FISD和实现多轮评估的实战经验拆解其中的关键设计、实现细节以及那些论文里不会写的“坑”。2. FISD基准构建一个更干净的“考场”2.1 为什么需要FISD——现有基准的“阿喀琉斯之踵”在深入FISD的构建细节前我们必须先搞清楚现有基准到底哪里出了问题。以我处理FashionIQ数据集的经历为例里面很多参考图修改文本目标图三元组存在严重的歧义。比如参考图是一件圆领衫文本说“变成V领”但目标图库中可能同时存在深V领、浅V领、材质不同、花纹不同的多件V领衫。模型检索出其中任何一件在RecallK的指标下都算“正确”。但这真的能说明模型理解了“变成V领”这个动作吗很可能它只是学到了“V领”这个关键词与某类图片的强关联对于“从圆领到V领”的“变化”关系理解是模糊的。这种“模糊正确答案”的存在使得评估信号变得嘈杂模型性能的上限被虚假地抬高同时也让我们难以诊断模型在特定语义推理能力上的真实缺陷。FISD的出发点就是要打造一个“信息完全、语义多样”的基准。“信息完全”指的是对于每一个查询在构建的数据集中有且仅有一张目标图是严格正确的答案排除了模糊匹配的可能。“语义多样”则是指我们系统性地覆盖了CIR任务中几种核心且困难的语义操作类型确保评估的全面性。我们最终确定了六个维度数量Cardinality改变图中物体的数量。如“将鸟的数量设置为三只”。添加Addition在场景中添加新物体。如“在草地上添加一个池塘”。否定Negation移除或否定图中的某些元素。如“移除人物戴的眼镜”。改变Change改变物体的属性如类别、颜色、状态。如“将汽车从红色变为蓝色”。背景Background改变图片的背景。如“将背景从街道换为海滩”。复杂指令Complex Instruction组合上述多种操作的复杂指令。如“将狮子替换为一条龙并且让龙张开嘴背景改为雪山”。2.2 数据构建流水线当LLM遇见扩散模型构建一个高质量、可控的CIR数据集传统的人工标注成本极高且难以保证在“否定”、“数量”等抽象逻辑上的精确性。我们的解决方案是构建一个LLM大语言模型 扩散模型的自动化流水线辅以关键环节的人工校验。整个流程分为两大阶段文本生成和图像生成。第一阶段高质量的文本三元组生成我们的目标是得到三个关键文本参考图描述、相对修改文本、目标图描述。例如参考图描述“一张餐桌上有一个苹果。”相对修改文本“再添加一个香蕉。”目标图描述“一张餐桌上有一个苹果和一个香蕉。”这里的一个核心技巧是我们不直接让LLM天马行空地想象而是从一个现有的高质量图像描述数据集如COCO、Flickr30k中采样“参考图描述”作为种子。这样做的好处是种子描述本身通顺、符合语法且描述了真实场景为后续生成提供了稳定的基础。接着我们设计了一套详细的提示词Prompt来引导LLM我们选用的是Mixtral-8x7B进行生成。提示词的核心是角色扮演和约束指定。我们会告诉LLM“你是一个专业的图像内容编辑。给定一个图像描述请根据{语义类别}的修改要求生成一个具体的修改文本相对描述和修改后的图像描述目标描述。确保修改是具体、可视觉化的且目标描述必须严格是参考描述应用修改后的结果。”对于“否定”这类难点提示词需要格外设计。不能只说“移除某物”因为扩散模型对“不存在”的概念生成效果不稳定。我们会要求LLM生成“替换性”或“描述缺失状态”的文本。例如对于“移除眼镜”相对文本可能是“人物没有戴眼镜”目标描述则是“一个没有戴眼镜的人物肖像”。通过这种方式将“否定”语义转化为模型更容易处理的“状态描述”语义。第二阶段可控的图像对生成有了精准的文本三元组下一步就是用扩散模型我们使用Stable Diffusion XL把目标图“画”出来。这里最大的挑战是保证参考图与目标图之间的高度一致性——除了文本指定的修改点其他内容应尽可能保持不变这样才能确保评估的是模型对“变化”的理解而不是对两幅无关图片的识别。我们摸索出的关键控制手段是种子控制。在生成参考图和目标图时我们使用相同的随机种子。扩散模型的生成具有随机性但相同的种子结合高度相似的目标描述仅在修改点有差异能极大地促使模型生成在布局、风格、未修改物体外观上高度一致的两张图。这相当于给模型一个强烈的“对齐”暗示。然而扩散模型不是万能的直接生成的结果可能包含卡通风格、逻辑错误如三只手的怪物或明显不真实的图片。因此人工校验环节必不可少。我们建立了一个简单的校验规则检查生成图像对是否1符合自然图像分布2严格遵循文本指令3两者之间仅在指定维度存在差异。对于每一类语义我们生成了远超过200对的数据然后通过人工筛选最终每类保留200对高质量三元组构成总计1200对3600张图的FISD基准。实操心得数据生成的“坑”与技巧种子不是银弹即使种子相同过于复杂的指令如“复杂指令”类仍可能导致画面构图发生较大改变。这时需要在提示词中增加“保持其他所有内容不变”、“保持同样构图和视角”等强调语句。硬负样本的构建为了增加检索难度避免模型仅靠图像相似度“作弊”我们为每个三元组手动构造了“硬负样本”。例如对于“将女孩的裤子从短裤换成长裤”硬负样本可能是“一个穿短裤的女孩”或“一个穿长裤的男孩”。这迫使模型必须同时理解参考图和修改文本才能做出正确判断。构造硬负样本时我们同样使用扩散模型但会微调描述文本使其在视觉上与目标图或修改意图的某个子集相似。人工校验的成本这是最耗时但价值最高的部分。我们建议至少两人背对背校验重点检查“否定”和“数量”类别这两类最容易出现模型“偷懒”如用其他物体遮挡来代替“移除”或数量计算错误。2.3 FISD揭示了什么——当前CIR模型的“能力边界”在FISD上测试主流CIR模型的结果像一面镜子清晰地照出了当前技术的天花板与短板。我们以Recall1排名第一的即正确作为核心指标发现了一些非常有意思且一致的结论模型在“否定”和“数量”逻辑上表现极其挣扎。即使是表现最好的模型在“否定”语义上的Recall1也仅在17.5左右在“数量”上约为58.5。这与它们在“改变”如换颜色Recall1可达77和“添加”Recall1约69.5上的表现形成了鲜明对比。这背后的原因很深刻主流的视觉-语言模型如CLIP的预训练数据大多是描述“存在什么”的正面语句对“不存在什么”的否定句以及精确的数量关系建模能力天生不足。模型更容易学习到“蓝色”和蓝色物体像素的关联但很难学习到“没有眼镜”这种缺失状态与像素模式的关联。“直接”语义处理尚可但远非完美。对于“添加一个物体”或“改变物体属性”这类相对直接的指令模型表现相对较好但平均Recall1也仅在55-77之间仍有很大提升空间。这说明即使对于看似简单的任务模型对跨模态细粒度对齐和关系推理的能力依然不够鲁棒。数据合成与真实图像的鸿沟影响有限。一个自然的质疑是FISD用的是合成图像其结论能推广到真实图像吗为此我们从CIRR数据集中手动筛选并标注了一批真实图像中的“否定”语义查询进行测试。结果发现模型在真实图像上的“否定”表现同样显著差于其他语义类别与FISD的结论一致。这证实了FISD揭示的模型缺陷是本质性的而非合成数据带来的偏差。同时不同模型在FISD上的性能排名与在CIRR、FashionIQ等真实数据集上的排名高度相关这说明FISD具有良好的判别效度能够有效区分不同模型的优劣。3. 多轮评估框架让CIR模型学会“对话”3.1 框架设计模拟真实的人机交互循环单轮检索就像一次闭卷考试而真实搜索是一个动态的、多轮的对话过程。用户不满意结果会给出更具体的反馈。我们的多轮评估框架就是为了模拟这个过程其核心由三个模块构成一个现成的CIR模型、一个排序器、一个用户模拟器。整个工作流程形成了一个闭环初始查询用户提供参考图I_ref和相对描述t。特征组合与检索CIR模型将参考图和文本融合生成一个组合查询特征q。排序器用这个特征在图像数据库中进行检索返回Top-K个候选图像。成功判断如果目标图像在Top-K中流程成功结束。反馈生成如果目标不在Top-K中用户模拟器介入。它接收排名第一的候选图像和目标图像分析两者的差异生成一段新的、更精确的相对描述文本t_new。例如初始查询是“找一件更正式的衬衫”返回的候选是一件黑色衬衫但用户想要的是白色。模拟器可能生成“颜色改为白色”作为新一轮的反馈。迭代优化将上一轮的候选图像作为新的参考图结合新生成的反馈文本t_new形成新一轮的查询(I_cand, t_new)跳回第2步。如此循环直至找到目标或达到最大轮次我们设为5轮。这个框架的精妙之处在于它无需重新训练任何CIR模型可以直接套用在现有的任何CIR模型上将其从一个单次查询工具升级为一个支持迭代优化的交互式系统。3.2 核心模块实现细节排序器的历史信息融合排序器的作用不仅仅是计算当前查询特征与图库的相似度。为了利用多轮交互中的历史信息我们维护一个历史列表H存储每一轮产生的组合查询特征[q1, q2, ..., qr]。在计算第r轮的综合查询特征时我们采用了一个简单却非常有效的策略对历史所有轮次的查询特征求平均得到q_avg mean(H)。然后用这个平均特征去计算与图库中所有图像特征的余弦相似度并选择最相似的作为下一轮的候选。为什么求平均有效这相当于把用户多轮反馈的意图进行了“平滑”与“融合”。早期轮次的查询可能比较宽泛后期轮次的反馈越来越精确。平均操作让系统同时兼顾了整体的搜索方向和最新的细化指令避免了被某一轮可能不准确的反馈带偏。在我们的消融实验中不使用历史信息即只用当前轮特征的性能显著下降证明了历史信息整合的必要性。用户模拟器的构建MLLM LLM的协同用户模拟器是这个框架的“大脑”它需要像真人一样能够比较两张图片并指出关键差异。我们探索了多种基于开源大模型的方案。最终采用的稳定方案是一个两阶段管道视觉理解MLLM使用一个多模态大语言模型如LLaVA-Next分别为候选图和目标图生成详细、细致的自然语言描述。例如对于候选图MLLM可能输出“一张黑色衬衫的图片材质是棉有纽扣”对于目标图输出“一张白色衬衫的图片材质是棉有纽扣”。差异推理LLM将这两段描述输入一个纯文本大语言模型如Llama3-8B-Instruct并设计提示词“你是一个挑剔的用户。当前系统返回的图片描述是[A]但你实际想要的图片描述是[B]。请用一句简短的话描述你需要对当前图片做出什么修改才能让它变成你想要的图片。只输出修改描述。” LLM会基于指令跟随能力输出如“将颜色从黑色改为白色”这样的精准反馈。我们也尝试了让更强大的MLLM如Qwen2-VL直接“看图说话”输出差异虽然也有效果但生成的结果有时不够稳定或过于冗长。两阶段方案虽然多了一步但得益于LLM强大的文本推理和指令遵循能力生成的反馈文本更加简洁、规范更符合CIR模型对输入文本的预期。避坑指南用户模拟器的调优描述详细度是关键MLLM生成的描述不能太笼统。如果只输出“一件衬衫”LLM将无法推断出具体差异。需要引导MLLM生成包含颜色、材质、款式、背景、物体数量、空间关系等细节的描述。LLM的指令遵循能力我们对比了Llama2-7B、Mistral-7B和Llama3-8B。发现Llama2-7B有时会“放飞自我”生成与差异无关的内容严重干扰检索。而Mistral-7B和Llama3-8B表现稳健。因此选择一个指令遵循能力强的LLM至关重要。反馈文本的“毒性”模拟器生成的反馈应基于“候选图与目标图的差异”而不是“参考图与目标图的差异”。在提示词中必须明确强调“基于当前系统返回的图片”否则LLM可能会混淆轮次导致反馈错误。3.3 多轮评估的惊人效果与洞见我们将这个框架应用到多个开源CIR模型上在FashionIQ、CIRR、CIRCO以及我们自己的FISD上进行了测试。结果令人振奋性能提升是普遍且显著的。无论模型单轮性能强弱经过多轮交互后其检索成功率HitsK都获得了巨大提升。以在CIRR数据集上为例一些单轮表现较弱的模型如Pic2Word经过3轮交互Hits1从23.25提升到了40.28提升幅度超过73%。即使是当前最强的模型如SPN4CIR其Hits5也从85.29提升到了98.76接近完美。“好学生进步更快”。一个有趣的发现是单轮性能越强的模型在多轮交互中能达到的最终性能天花板也越高。这说明强大的基础检索能力是多轮优化的良好基石。多轮交互并非“点石成金”而是能将模型潜力充分释放的“放大器”。收益递减规律。性能提升主要发生在前3轮从第3轮到第5轮提升幅度明显变小。这符合直觉最初的反馈能纠正最大的方向性错误后续反馈则是在做精细调整。这也为我们设定交互轮次上限如5轮提供了依据平衡了效果与用户体验等待时间。与真人用户的对比。我们邀请了真人用户对50个单轮检索失败的困难案例进行5轮交互测试。结果显示我们的自动化用户模拟器达到的性能与真人用户非常接近甚至在部分案例上因为能提供更持续、更详细的反馈而表现更好。这强有力地证明了我们框架的有效性和实用性它能够以可扩展、自动化的方式近似真实地评估CIR模型的交互能力。4. 实战从零搭建多轮CIR评估系统4.1 环境准备与依赖安装想要复现或基于此框架进行实验你需要一个配备现代GPU如A100显存40GB为宜的Linux环境。以下是核心的Python库依赖# 基础深度学习框架 pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 # 图像处理与加载 pip install Pillow opencv-python # 多模态模型加载以LLaVA为例 pip install transformers accelerate # 用于LLaVA等模型 pip install timm einops # 可选用于管理大型模型 pip install bitsandbytes对于CIR模型你需要根据所选模型如SPRC、CLIP4CIR、Pic2Word从其官方GitHub仓库克隆代码并安装特定依赖。通常这些模型都基于Hugging Face的transformers库。4.2 核心代码模块拆解下面我将勾勒出整个多轮评估框架的核心代码结构并解释关键函数。1. 初始化模块import torch from PIL import Image from transformers import AutoProcessor, AutoModelForVision2Seq, AutoTokenizer, AutoModel # 假设你已有一个CIR模型类这里用伪代码表示 from your_cir_model import YourCIRModel class MultiRoundCIREvaluator: def __init__(self, cir_model_path, mllm_namellava-hf/llava-v1.6-mistral-7b, llm_namemeta-llama/Llama-3.2-1B-Instruct): # 1. 加载CIR模型 self.cir_model YourCIRModel.from_pretrained(cir_model_path) self.cir_model.eval() # 2. 加载用户模拟器组件MLLM和LLM # MLLM用于生成图像描述 self.mllm_processor AutoProcessor.from_pretrained(mllm_name) self.mllm_model AutoModelForVision2Seq.from_pretrained(mllm_name, torch_dtypetorch.float16, device_mapauto) # LLM用于生成差异反馈 self.llm_tokenizer AutoTokenizer.from_pretrained(llm_name) self.llm_model AutoModel.from_pretrained(llm_name, torch_dtypetorch.float16, device_mapauto) # 注意实际使用LLM生成文本可能需要搭配专门的文本生成接口如vLLM或HuggingFace pipeline # 3. 初始化排序器历史记录 self.history_features [] # 存储每一轮的组合查询特征 # 4. 加载图像数据库特征预计算好的 self.database_features torch.load(database_features.pt) # 形状: [N, d] self.database_image_paths [...] # 对应的图像路径列表2. 单轮检索与特征融合这是CIR模型的核心功能。不同模型融合图像和文本特征的方式不同这里展示一个常见的组合方式def compose_and_retrieve(self, image_path, text): 执行单轮组合检索 # 预处理图像和文本 image Image.open(image_path).convert(RGB) inputs self.cir_model.preprocess(image, text) # 模型特定的预处理 with torch.no_grad(): # 提取视觉特征和文本特征 image_features self.cir_model.encode_image(inputs[image]) text_features self.cir_model.encode_text(inputs[text]) # 特征融合例如加权相加、Cross Attention等 # 这里以简单相加为例实际请参考对应模型的融合方式 composed_feature image_features text_features composed_feature torch.nn.functional.normalize(composed_feature, dim-1) # 计算与数据库所有特征的相似度 similarities torch.matmul(composed_feature, self.database_features.T) # [1, N] topk_scores, topk_indices torch.topk(similarities, k10, dim-1) # 保存本轮特征到历史 self.history_features.append(composed_feature) return topk_indices[0].tolist(), composed_feature # 返回top-k索引和本征特征3. 用户模拟器生成反馈这是实现多轮交互的“智能”所在。def generate_feedback(self, candidate_img_path, target_img_path): 比较候选图和目标图生成文本反馈 # 阶段1: 用MLLM生成详细描述 def describe_image_mllm(img_path): image Image.open(img_path).convert(RGB) prompt Describe this image in detail, including objects, colors, actions, background, and their relationships. inputs self.mllm_processor(imagesimage, textprompt, return_tensorspt).to(self.mllm_model.device) with torch.no_grad(): output_ids self.mllm_model.generate(**inputs, max_new_tokens150) description self.mllm_processor.batch_decode(output_ids, skip_special_tokensTrue)[0] # 清理描述文本移除重复的prompt部分 return description.replace(prompt, ).strip() desc_candidate describe_image_mllm(candidate_img_path) desc_target describe_image_mllm(target_img_path) # 阶段2: 用LLM基于描述生成差异反馈 llm_prompt fYou are a precise user. The current image from the system is described as: {desc_candidate} But the image I actually want is described as: {desc_target} Please generate a short, clear instruction that describes the modification needed to change the current image into the desired one. Focus only on the key differences. Output only the modification instruction. Example: Change the color from red to blue. or Add a tree on the left. Modification instruction: # 这里简化了LLM调用实际中可能需要使用其对话API或文本生成pipeline # 假设有一个调用LLM的函数 feedback_text self.call_llm(llm_prompt) return feedback_text.strip()4. 多轮评估主循环def multi_round_evaluation(self, reference_img_path, target_img_path, initial_text, max_rounds5, top_k10): 执行多轮评估返回是否成功及最终排名 current_img_path reference_img_path current_text initial_text success False final_rank None for round_idx in range(max_rounds): print(f--- Round {round_idx1} ---) print(fQuery: Image{current_img_path}, Text{current_text}) # 1. 检索 topk_indices, current_feature self.compose_and_retrieve(current_img_path, current_text) # 2. 检查是否成功 target_index self.get_image_index(target_img_path) # 假设有函数能根据路径获取索引 if target_index in topk_indices[:top_k]: success True final_rank topk_indices.index(target_index) 1 print(fSuccess! Target found at rank {final_rank} in round {round_idx1}.) break # 3. 未成功则生成反馈 candidate_img_path self.database_image_paths[topk_indices[0]] # 取Top-1作为候选 feedback self.generate_feedback(candidate_img_path, target_img_path) print(fFeedback generated: {feedback}) # 4. 为下一轮更新候选图作为新参考图反馈作为新文本 current_img_path candidate_img_path current_text feedback if not success: print(fFailed after {max_rounds} rounds.) # 可以计算目标在最后一轮检索结果中的排名 final_rank self.calculate_rank(target_index, topk_indices) if topk_indices in locals() else None # 重置历史为下一个查询做准备 self.history_features [] return success, final_rank4.3 性能优化与工程化考量在实际部署和大量实验时以下几点经验至关重要数据库特征预计算在循环开始前务必预计算好整个图像数据库中所有图片的视觉特征。对于CIR模型中的视觉编码器如CLIP的ViT对每张图做一次前向传播将得到的特征向量保存下来。这样在检索时只需要计算一次组合查询特征然后做一次大规模的矩阵乘法或余弦相似度计算即可避免在每轮中重复编码所有数据库图片这是性能瓶颈所在。历史特征融合策略我们采用了简单的平均法效果已经不错。你也可以尝试更复杂的策略如加权平均给近期轮次更高权重、或使用一个轻量级的网络如MLP来学习如何融合历史特征。但在初期建议从简单方法开始验证。用户模拟器的加速MLLM和LLM的推理是耗时大户。可以考虑以下优化量化使用4-bit或8-bit量化加载模型能大幅减少显存占用并提升推理速度对精度影响很小。批处理如果需要评估大量查询可以将多个查询的“生成描述”或“生成反馈”步骤批量进行。缓存对于固定的候选图目标图对其生成的反馈是确定的可以缓存起来避免重复计算。错误处理与鲁棒性LLM生成的反馈可能不符合预期如过长、包含无关信息。需要在后处理中加入简单的规则过滤比如限制反馈句子长度、剔除以“I think”等开头的句子。设定反馈生成的重试机制。如果生成的反馈与上一轮完全相同或极度相似可能意味着模拟器“卡住”了可以尝试重新生成或使用一个备用的通用反馈如“请提供更具体的修改”。5. 常见问题、排查与未来展望5.1 实战中遇到的典型问题与解决方案在开发和实验过程中我们踩过不少坑这里总结一下最常见的问题及其解决方法问题1多轮检索性能不升反降。现象进行到第二、三轮时返回的结果反而离目标更远了。可能原因与排查用户模拟器反馈质量差这是最常见的原因。检查MLLM生成的描述是否足够详细和准确。可以打印出desc_candidate和desc_target进行人工核对。如果描述过于笼统如“一张图片”需要优化给MLLM的提示词要求其输出更细致的细节。历史特征污染如果早期轮次的检索方向完全错误其组合特征可能会“带偏”后续的平均特征。可以尝试只保留最近N轮如N2的历史或者当相似度分数低于某个阈值时不将该轮特征加入历史。CIR模型融合能力有限某些CIR模型对于“候选图差异文本”这种非典型输入的处理能力较弱。可以尝试在FISD的“改变”类数据上专门测试一下模型用“错误候选图正确修改文本”进行检索的能力。问题2评估结果波动大难以复现。现象同一模型、同一查询多次运行结果差异较大。可能原因与排查LLM生成具有随机性大多数LLM在生成时存在随机性通过temperature参数控制。为了评估的公平性和可复现性必须将LLM的temperature设置为0以确保每次生成的反馈是确定性的。数据库特征未归一化在计算余弦相似度前必须确保组合查询特征和数据库特征都经过了L2归一化。检查你的composed_feature和database_features是否都通过了F.normalize(..., dim-1)。图像预处理不一致确保CIR模型、MLLM在预处理图像如resize、裁剪、归一化时使用的是完全相同的流程和参数。一个像素的差异都可能导致特征提取不同。问题3运行速度太慢无法进行大规模评估。现象评估一个查询就需要几分钟。优化方案特征预加载确保所有模型CIR视觉编码器、文本编码器、MLLM在初始化时就加载到GPU中避免每次推理时重复加载。关闭梯度计算在所有with torch.no_grad():上下文中进行推理。使用更小的模型对于用户模拟器可以尝试更小但能力尚可的MLLM和LLM如较小的LLaVA版本或Phi系列模型。在效果和速度间取得平衡。并行化如果评估多个独立的查询可以使用Python的multiprocessing或concurrent.futures进行并行处理。5.2 未来方向与个人思考通过构建FISD和实现多轮评估框架我们不仅提供了一套新的评估工具更打开了一系列新的研究方向1. 面向交互训练的CIR模型 当前所有CIR模型都是为单轮检索设计的。一个很自然的想法是能否训练一个专门用于多轮交互的CIR模型我们可以构建一个包含多轮对话的数据集其中每一轮都有参考图历史对话当前反馈目标图这样的四元组。模型的目标是学会理解整个对话上下文而不仅仅是最后一轮指令。这可能会催生新的模型架构例如引入类似于Transformer解码器的机制来建模历史交互。2. 更智能的用户模拟与主动查询 目前的用户模拟器是基于规则的总是对Top-1生成反馈。未来可以探索更智能的模拟策略例如让模拟器学会判断哪一张候选图与目标图的差异“最容易描述”或者主动提出澄清性问题“你指的是颜色不对还是款式不对”。这需要将用户模拟器升级为一个具备规划能力的智能体。3. 基准的扩展与细化 FISD的1200对数据只是一个起点。如何将其扩展到数万甚至数百万规模同时保持高质量和可控性一种思路是利用更强的文生图模型如DALL-E 3、Midjourney和更精细的提示工程来批量生成。此外还可以引入更多样的语义类别如空间关系“把左边的物体移到右边”、情感风格“让画面看起来更忧伤”等进一步挑战模型的极限。从我个人的实战经验来看CIR领域正在从静态的“检索”向动态的“对话”和“协作”演进。FISD基准告诉我们模型在理解复杂、抽象语义上还有很长的路要走这需要我们在模型架构和训练目标上进行更根本的创新。而多轮评估框架则为我们指明了一个更贴近实际的应用范式未来的图像搜索系统或许更像一个拥有视觉能力的“对话助手”通过与用户的多次交流逐步勾勒并锁定用户心中那个模糊的意象。这条路充满挑战但也正是其魅力所在。希望我们提出的这套工具和发现能为同行们提供一些有价值的参考和启发。