4

在 iPhone 上运行 CLIP 搜索你的相册

 1 year ago
source link: https://sspai.com/post/77862
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

iPhone 相册支持用文字搜索,但搜索能力实在太弱了,于是我把 CLIP 做进了 iPhone 里。

去年和朋友玩 AI 绘画时,我接触到了 CLIP:它是 OpenAI 发布的一个连接图片和文字的模型,你可以使用它计算任意一句文本和一张图片间的相似度

1
图片源自 CLIP 官网:https://openai.com/blog/clip/

我觉得这太神奇了,第一次图片和文字具有了可比性。以 ViT-B-32 版本 CLIP 为例,它包含文本编码器(Text Encode)和 图像编码器(Image Encoder):

Text Encoder 可以将任意文本(长度 <77)编码成一个 1x512 维的向量

Image Encoder 可以将任意图像编码成一个 1X512 维的向量

只要通过计算两个向量的距离或余弦相似度,就可以比较某句文本和图像之间的相似性。

动手实现相册搜索

根据这个原理,我很快在服务器搭建了一个图像搜索工具,思路大致是:

将所有的照片经过 CLIP,得到全部的图像向量。对某一句搜索文本,计算它的 CLIP 文字向量,并将其与所有图像向量比较相似性,排序展示 Top K 结果。

我发现,它的搜图结果远远好于 Google:

1
搜索「lonely」,排第一的结果是孤独的背影,第二是这个。

把 CLIP 做到手机上?

惊叹一番后,我在想:有没有办法把 CLIP 做到手机上?毕竟我存放照片最多的地方,既不是 Macbook Air,也不是服务器,而是我的 iPhone 手机

想把一个运行在 GPU 上的大模型移植到 iPhone,算子支持运行效率是两个最关键的因素。

幸而上个月苹果亲自下场演示了将 Stable Diffusion 移植到 iOS 上的可行性,证明了 CLIP 里所需的深度学习算子在 iOS 16.0 上得到了支持。

1
https://github.com/apple/ml-stable-diffusion

即便算子支持,如果运行效率巨慢(例如,计算 10,000 张图的向量要半小时?或者搜一次要 1 分钟?),将 CLIP 移植到手机也变得没了意义。这些都需要亲自实验才知道。

我把 CLIP 分离,将 Text Encoder 和 Image Encoder 导出为两个模型:在构建相册索引的时候,只需要加载 Image Encoder,搜索时只需要加载 Text Encoder,错开加载以降低内存占用。

同时,我在计算相似度时做了多核并行使搜索速度大幅提高:对 <10,000 张图的单次检索耗时 <1s。这个过程流程图如下:

1
iOS 模型的一次搜索过程

OpenAI 提供的 CLIP 仅支持英文输入,如何让它支持中文呢?这个问题其实有如下解法:

  1. 直接将中文翻译成英文,再送入 CLIP。
  2. 在 Github 上找 MIT 开源的中文 CLIP 项目,例如 Chinese-CLIP,或者支持 90 多种语言的 Multilingual-CLIP

但它们对我都不太适用——

第一种方法需要调用翻译 API,所以 app 需要联网,仅此一点就让我放弃了这条路(之后会解释原因)。第二种方法的模型的体积太大了,Chinese-CLIP 提供的最小模型大小是700M,Multilingual-CLIP 最小的模型有 2.5G。谁会愿意下载这么大的工具 app 呢?

所以,最终我选择了自己训练一个 ViT-B-32 CLIP 的中文 Text Encoder:这个 CLIP 模型的 Text Encoder 及 Image Encoder 加起来也就 300M,是大部分用户能容忍的尺寸上限了。

1
思路:使用中英文平行语料,让中文文本向量接近它的英文版本

效果如何?

至少从我的体验上看,基于 CLIP 的相册搜索结果远远好于 iPhone 自带的相册搜索。我在 B 站制作了一期视频展示了它的威力,查看演示效果可以直接空降至 03:15

相册隐私怎么办

从上面流程图可知,在 iOS 上运行 CLIP,需要将你的相册全部照片经过 CLIP 计算图像向量。那么,凭什么让用户信任你不会偷偷存储、上传他的照片呢?所以我希望这个 app 完全离线。因此我在开发 app 的时候,摒弃了一切需要网络请求的场景,也就与翻译 API 无缘了。

但是,当用户的图片只存储在 iCloud 时,本地就必须使用网络来下载存储在 iCloud 上的高清图片。我在第一个版本拒绝妥协,选择提供了照片的拍摄日期:用户可以通过日期信息手动去相册定位到这张图,然后从 iCloud 下载。

但这样其实非常不方便,所以我在第二个版本提供了允许用户主动选择联网来从 iCloud 下载原图,这个入口非常深:只有当搜索结果的照片确实存储在 iCloud,并且你点击下载时,才会弹出联网请求,此时你仍然可以拒绝,仍可以继续流畅使用它。

我的 app 昨天上架了 App Store,在此打个「广告」,希望对你有帮助,也想看到更多反馈。

运行要求: iOS 16.0 以上系统,iPhone 11 或以上机型。受条件限制,目前还未在 Mac 或 iPad 上测试过效果,欢迎大家体验和反馈。

> 下载 少数派 2.0 客户端、关注 少数派公众号,解锁全新阅读体验 📰

> 实用、好用的 正版软件,少数派为你呈现 🚀


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK