介绍 ColQwen-Omni:在各种模态中进行检索

还记得 ColPali、ColQwen、DSE 吗?这些模型引入了视觉文档检索的概念:不再需要费力地从文档中提取文本进行处理,而是可以将文档页面视为一系列图像(屏幕截图),并训练视觉语言模型 (VLM) 直接将其内容表示为向量。ColPali 已证明,与替代方法相比,这种策略通常更快、更简单,并且能提供更好的检索性能。ColPali 和 ColQwen 模型系列自大约一年前发布以来,已被下载数百万次,被提及为2024 年顶级人工智能创新之一,并启发了许多后续工作!模型实际上变得如此优秀,以至于我们的第一个基准(Vidore v1)现在过于简单了!
VLM 的快速发展使得顶级模型能够处理更多模态。令人惊叹的 Qwen-Omni 系列通常能够在图像和文本之外处理音频和视频输入!看到这一点,我们立刻对是否能将 ColQwen 系列推广到不仅嵌入和检索文档图像,还能嵌入和检索音频片段和短视频产生了兴趣。在 VisionRAG 之后,AudioRAG 是否可能?介绍 ColQwen-Omni (3B),它是 ColQwen2 的扩展,基本上可以嵌入你扔给它的任何内容!
使用示例
让我们逐步了解如何使用它来检索音频片段!您可以在 Google Colab 中跟着操作。首先,让我们加载模型
# !pip install git+https://github.com/illuin-tech/colpali
from colpali_engine.models import ColQwen2_5Omni, ColQwen2_5OmniProcessor
model = ColQwen2_5Omni.from_pretrained(
"vidore/colqwen-omni-v0.1",
torch_dtype=torch.bfloat16,
device_map="cuda",
attn_implementation="flash_attention_2").eval()
processor = ColQwen2_5OmniProcessor.from_pretrained("vidore/colqwen-omni-v0.1")
假设我们的目标是能够查询一个 30 分钟长的播客。我们将播客分割成 30 秒的片段,并将每个片段以 WAV 格式存储在 Python 列表中。
from pydub import AudioSegment
audio = AudioSegment.from_wav("<my_legally_downloaded_podcast>.wav")
# Set target frame rate
target_rate = 16000
chunk_length_ms = 30 * 1000 # 30 seconds
audios = []
for i in range(0, len(audio), chunk_length_ms):
chunk = audio[i:i + chunk_length_ms]
# Convert stereo to mono, sample at 16k Hz
chunk = chunk.set_channels(1).set_frame_rate(target_rate)
# Export and convert to numpy array
buf = io.BytesIO()
chunk.export(buf, format="wav")
buf.seek(0)
rate, data = wavfile.read(buf)
audios.append(data)
现在我们已经准备好嵌入所有音频了。
from torch.utils.data import DataLoader
# Process the inputs by batches of 4
dataloader = DataLoader(
dataset=audios,
batch_size=4,
shuffle=False,
collate_fn=lambda x: processor.process_audios(x))
ds = []
for batch_doc in tqdm(dataloader):
with torch.no_grad():
batch_doc = {k: v.to(model.device) for k, v in batch_doc.items()}
embeddings_doc = model(**batch_doc)
ds.extend(list(torch.unbind(embeddings_doc.to("cpu"))))
在这里,一个 30 分钟的音频可以在 10 秒内嵌入,而 30 秒的音频我们得到了大约 800 个音频标记!让我们测试一下
def get_results(query: str, k=3):
batch_queries = processor.process_queries([query]).to(model.device)
# Forward pass
with torch.no_grad():
query_embeddings = model(**batch_queries)
scores = processor.score_multi_vector(query_embeddings, ds)
return scores[0].topk(k).indices.tolist()
res = get_results("<YOUR QUERY>")
print(f"The best audio chunks are: {res}")
#> The best audio chunks are: [102, 96, 35]
音频片段 #102 和 96 在我的情况下完美相关!甚至可以将最相关的音频片段发送给 GPT-4o 进行端到端 AudioRAG!
让我们用一段 30 分钟关于汉尼拔和布匿战争的音频来演示端到端的一切
完整的笔记本可以在这里找到。
何时适合检索音频?
许多用例可能需要音频检索。例如,您可能希望在教育视频、录制课堂或播客中查找特定信息。您可能需要从朋友的几十条语音备忘录中找到一条提及他们生日派对地址的语音备忘录。呼叫中心经理可能会尝试在数百万条录音中找到一些客户笑声或表达愤怒的实例。存在许多用例,尽管可以通过使用语音转文本 (STT) 系统将音频转录为文本,然后搜索转录,但直接检索音频要快几个数量级,并且直接音频检索能更好地捕捉情感、环境声音和语调等信息,从而开辟全新的可能性!
视频又如何?
视频也适用于 ColQwen-Omni。但是,请注意,视频处理非常占用内存,因此它最适合短片段。
batch_videos = processor.process_videos(videos).to(model.device)
# Forward pass
with torch.no_grad():
video_embeddings = model(**batch_videos)
这里有一个有趣的演示,展示了龙之母。
训练
该模型的第一代是科学实验的成果。我们探索了一个纯粹在视觉文档检索上训练的模型,在训练期间没有接触音频或视频,是否能有效地将其嵌入能力迁移到其他模态。结果是:相当不错!通过严格在 Vidore 训练集上训练,该模型在视觉文档检索方面与当前顶级模型的性能相匹配,虽然我们暂时不建议在生产中使用该模型,但它在音频检索方面也表现出强大的性能。
在未来的迭代中,我们计划将音频片段专门纳入对比训练集,以进一步优化音频检索模型,这可能会显著提升性能。当前模型在理解口语内容方面表现出色,但在理解口音、情感和环境声音方面存在一些限制。我们相信,有针对性的训练可以有效地解决这些问题,并欢迎对 v0.1 的任何反馈,以了解未来运行时要整合哪些数据!同时,colqwen-omni 的训练代码可在我们的 Github 上获取,并已准备好接收您的自定义数据集!我们的目标还将是改进模型在自然图像和文本检索方面的性能——为真正模态无关的检索器铺平道路!
一些链接
📝 论文
🗃️ HF 组织
👀 模型
💻 代码
@misc{faysse2024colpaliefficientdocumentretrieval,
title={ColPali: Efficient Document Retrieval with Vision Language Models},
author={Manuel Faysse and Hugues Sibille and Tony Wu and Bilel Omrani and Gautier Viaud and Céline Hudelot and Pierre Colombo},
year={2024},
eprint={2407.01449},
archivePrefix={arXiv},
primaryClass={cs.IR},
url={https://arxiv.org/abs/2407.01449},
}