一个AI相册搜索应用的两年

诞生爆火开源抄袭沉寂一个产品的漂流

一篇长长长长的流水账

起源

故事起源于 2022 年 5 月的一个周末我坐在北京昌平区的书店里正在调试 Disco Diffusion 模型此时 AI 绘画时代初露端倪SD 尚未发布画一张图在一张性能良好的 V100 显卡上要 5 分钟

我将开源代码封装成可以只加载一遍模型暴露少数参数的接口花 2000/月租了张显卡并在朋友圈和社交媒体上发帖想玩 AI 绘画的人可以给我句子描述我在机器上跑完并把图发给他们

网友们玩得很开心

朋友要不搭建一个网站让大家自己玩于是就有了 6pen我们在很短时间内有了 100 万用户然后逐渐销声匿迹这次创业不太成功我自觉是我没有训练出差异化的模型占很大因素但这里不展开了如上所说SD 发布之前的 AI 绘画速度极慢我的大部分时间是在做模型加速其中一个优化项就是 关于 CLIP 模型

CLIP 是 OpenAI 2021 年发布的模型它能比较任意一张图片和一句文本之间的相似度在 Disco Diffusion 中模型用 CLIP 来计算生成图像与用户prompt之间的损失不断优化损失从而实现绘画(详细原理)使用越小的 CLIP 模型绘图速度越快但画面细节也会越差我当时正在调试以平衡绘图速度和画面细节

坐在书店里突然一个想法闯进了脑子既然可以比较图文相似度那么可以用它来搜照片吗 搜索后发现已经有人写了一个用 CLIP 搜图的工具原理是将图片上传到服务器统一提取特征输入英文并计算文本与每一张图的相似度排序就能实现搜图

https://github.com/kingyiusuen/clip-image-search
我开始尝试将我的 iPhone 相册上传到服务器试了一番下来我发现效果好得惊人特别是搜一些虚无缥缈的东西比如我输入"lonely"(孤独)它返回到前三张照片如下

输入'lonely'从照片库返回的结果

把照片放在服务器这不是个好想法我照片最多的地方就是 iPhone 本地相册能否做一个完全运行在本地的 CLIP 搜图 App 呢 我非常喜欢这个 idea几次和朋友讨论起但每次都无疾而终

我心里太没底了:

  • 我完全不懂 iOS 开发
  • Apple 底层可能不支持 CLIP 模型算子
  • 即使能跑起来如果索引速度慢到 1 秒/张或者搜一次 10 分钟这个产品也没有意义

直到 2024 年端侧模型才逐渐被大家所关注但在 2022 年我在 App 市场上没找到一个运行在端侧的语言模型应该…不太可行吧我终于忘了这件事继续投入到 6pen 的研发中

回响

转折点是 2022 年 12 月初因为一些变故我突然到了一个语言完全不通的陌生国家(🇰🇷)与 6pen 的缘分也走到尽头于是在空旷的咖啡店一台笔记本一杯冰拿铁坐一整天背景音乐放着 Kpop窗外是厚厚的积雪中午饿了吃店里的三明治我每天就这样度过

这里网速飞快没有核酸周围人的谈话因语言不通自动变成了白噪音我好像突然活在真空之中这种陌生的真空感让我兴奋像流放的逃犯一样我是谁我的过去不再重要在这里我能从头学习并完成任何事是时候开始做点真正让我兴奋的产品了——这个 idea 再次抓住了我

但这次我不再恐惧验证可行性我学习用 Swift 编写tokenizer研究应该如何计算并本地存储特征学习用多核加速索引对比不同相似度排序算法期间在 StackOverflow 提了许多愚蠢的问题有很多次挫败时刻但我脑海里一直浮现这个画面在手机输入"coffee and laptop"点击搜索旋转动画后这张照片从 3 万张相册中跳出来出现在我眼前

工作日的咖啡店,几乎没有人。

这个幻想支撑我废寝忘食地干了 2 个星期 —— 字面意思好几次忘记吃午饭一杯拿铁喝到傍晚饿到胃疼全身乏力有个重要的时间节点就是 ChatGPT 在那时刚刚发布但我在开发中陷入太深根本忽视了它的存在那可能是我这辈子最后几次在 StackOverflow 提问

总之在 12 月 27 日我终于完整做出了产品我把模型中的文本模型图像模型分拆成两个独立模型分开加载

为相册构建索引时只加载图像模型计算索引并保存搜索时只加载文本模型并逐一计算与保存的索引之间的余弦距离然后返回相似度最高的 topK 照片

错开加载模型可以有效降低软件的内存占用并且能加速构建索引构建索引时计算并保存所有照片的特征使得搜索过程只是进行特征比较而与图像无关同时用多核并行来加速这两个过程这一系列的优化下来可以做到在我的 iPhone 12 mini 上 以 2000 张/分钟速度为照片构建索引而 10,000 张照片搜一次只要不到 1s

实现原理

这表明算子是支持的速度是可用的我悬着的心终于落下了

定价

作为一个定价小天才我的设想是

用户可以免费下载并构建索引任意搜索当他未来有新照片想更新索引就要付费

这个策略妙处在于只有真正用上了喜欢这个产品的人才需要付费那些来尝鲜的或者试了下发现和预期不一样的人不需要也不会掏钱因而避免了用户花冤枉钱怒打差评

但很快在调试代码时我发现一个合理但又搞笑的事实App 内购买需要联网这简直是晴天霹雳因为我从一开始就下决心决不允许App在任何情形下弹出联网请求为什么因为这是一个相册搜索应用它会扫描你的整个相册没有人知道联网后你会不会将用户的照片上传到地球某处的服务器我知道可以在产品里解释为什么会弹窗请求联网权限但我不想陷入尴尬的自证境地

我只好将它变成付费产品用户必须购买之后从打开 App构建索引到完成搜索的过程中只弹出一次相册权限请求我知道这么做很蠢——后续的教训也验证了付费下载会带来大量差评因为模型太吃算力许多内存小的机型上构建索引会崩溃卡顿在 iPhone X 系列算子支持异常导致搜索结果全黑这些都会被骂 Ripoff(诈骗)并且用户根本不会在意不弹出联网请求这件事一旦出现以上异常他们就会删 App打差评质问我把他的相册偷偷上传到哪去了

总之最终我将其定价为 3.99 美元一次购买终身使用

推向市场

我给产品取了名字Queryable意为可查询的并发了条很中二的动态我觉得这个 app 可能会改变世界我对此信心满满甚至给 Tim Cook 写了一封邮件希望苹果能收购这个产品(笑)那时候我已经开始用 ChatGPT 了可能因为太激动我忘了替换掉自己的名字点击发送之后才看到邮件开头是"Dear Mr. Cook, My name is [Your Name]"

当然最终也没有收到回信

我又开始雄心勃勃地准备写篇产品介绍文章反复斟词酌句试图将它变成我心中 Hacker News 好文章的风格在 12 月 29 日App Store 审核通过的当天我立刻在 Hacker News 提交了我的文章链接但系统提示账号太新无法提交我给他们发邮件反馈了这个问题让朋友用他的账号帮我发帖

帖子很快沉了邮件也没收到回信

我很难过但由于收到许多用户请求支持中文输入我来不及悲伤便立即投入中文模型训练中得益于分离了 CLIP 中文本模型图像模型我只需要找到中英文双语平行语料训练一个中文文本模型将其输出结果与英文模型对齐即可这个过程本质上是蒸馏

很快2023 年 1 月 18 日我做好了中文版取名寻隐来源是贾岛古诗寻隐者不遇也暗含从相册中发现隐藏含义的意思毕竟我的初次震撼就是搜lonely时意识到那几张照片原来代表孤独

上线后我用中文在少数派写了一篇文章介绍此产品英文版不同除了讲述技术方案外我还完整记录了心路历程竟然进了当天的首页这带来了大量下载以及 1500 美元的收入

朋友告诉我上了少数派首页

2 月初我收到了 Hacker News 编辑的回信他说我的账户被系统误判为 SPAM鼓励我重新发帖说我的文章很符合社区精神(“the article is definitely fine HN material”)他将我的新帖子链接放在候选池(pool)池里的文章会随机进入首页底部如果用户点赞排名就会上升否则再次沉下去

Hacker News编辑Daniel将我的链接放在/pool下

我发现pool机制很有意思社区似乎希望在去中心化的机制下仍然维持黑客精神

This is our long-running experiment in story re-upping. Moderators and a small number of reviewer users comb the depths of /newest looking for stories that got overlooked but which the community might find interesting. Those go into a second-chance pool from which stories are randomly selected and lobbed onto the bottom part of the front page. This guarantees them a few minutes of attention. If they don’t interest the community they soon fall off, but if they do, they get upvoted and stay on the front page.

这是我们长期进行的故事重演实验版主和少数审阅者用户会深入寻找被忽视但社区用户可能会感兴趣的故事这些故事会进入第二次机会池该池中的故事会被随机选择并放置到首页的底部这保证了它们获得了几分钟的注意力如果社区用户不感兴趣它们很快就会下沉消失但如果社区感兴趣它们就会得到支持(upvote)并留在首页

https://news.ycombinator.com/item?id=11662380

当晚 7 点我的帖子冲到了 Hacker News 首页第二名
文章上了Hacker News首页#2

那晚我抱着手机每 10 秒刷新一次兴奋感从十二点躺下持续到凌晨三点我一直在回复帖子下的讨论反馈 bug 的邮件有人教我用 LSH 来提高搜索速度有人给出如何在不联网的前提下将照片经纬度映射到城市有人讨论 iPhone X 上运行失败的原因

这种感觉好像和产品有多少下载赚多少钱无关你创造了一个东西得到了一大群同行的赞美兴奋地讨论给它出主意这是人生少有的经历一次就很知足了

其中有一条评论引起了我的注意
在地球上的另一处,有人在和我做一模一样的事

我阅读了作者的开发日志发现我们像地球上随机的两个脑子产生相同想法的人我甚至在 Testflight 试用了他还未上线的产品有种莫名惺惺相惜的感觉

Hacker News 是世界的公告牌

当晚我很兴奋地睡着了为自己产品被同行喜欢而激动事实证明我远远低估了 Hacker News 的影响力两天时间Queryable 几乎横扫了欧洲所有国家的工具榜#1美国 #2仅次于小火箭总收入是 2800 美元之后的几天我醒来第一件事就是看 Gmail德国法国西班牙美国各个国家都有有反馈 bug 的有德国杂志社想报道的有法国 iOS 社区的有油管博主测评的我的推特也会因为有人转发 Hacker News 热榜而不断收到通知

美区#2,法德西#1,我在兴奋地截图

甚至一位在 Apple Photos 组工作的朋友告诉我他们组里也知道 Queryable

以上这些都迫使我意识到某种世界性Hacker News 并非只属于美国它像世界中心区域一块虚拟的公告牌每个作品在上面短暂停留但总有来自各个国家无数双眼睛盯着 这个产品其实只支持英语但不妨碍它在欧洲几乎所有国家付费工具榜#1他们好像会天然接受一个只能用英语的产品在美国行得通的产品往往欧洲人也能接受

并不针对欧洲,却也在欧洲畅销

热度很快降了下来随即而来的是很多恶评

简单来说Hacker News 的用户质量极高我没看到任何令我感到不适的评论但经过各种网站YouTube 和社区的二次传播后不那么友好的用户就浮出水面了主要攻击的有两点

  1. 害怕我会窃取他的相册隐私
  2. 我是中国开发者

在他们看来第 2 点让第 1 点的情况变得更糟了在 Hacker News 接二连三的余热结束以后这个产品在欧美销量迅速变得惨淡每天个位数的下载几十块的收入

在我的想象中改变世界的东西是一骑绝尘的怎么会突然停下了呢我陷入了巨大的怀疑和悲观

免费 & 开源

所幸国内的差评果壳等公众号对寻隐的自来水曝光这让我从 1 月份开始每个月可以获得 1 万元左右的收入并且因为模型运行在手机端也就没有服务器成本

从 4 月份起没有任何流量曝光不做任何更新的情形下平均每月大概可以获得 3000 元的收入

但是我仍然觉得这是一个很有用的产品只是我没办法让很多人知道我进行过一次限时免费当天下载量超过过往日均的 100 倍我想与其维持这样每月 3000 块的收入可能阻止了 99%的人发现这个产品不如让所有人都可以使用它于是我决定让它一直免费

既然免费了源代码好像就并不是什么机密了我在思考要不要把源代码放出来最终在 2023 年 7 月 10 日我在 V2EX 发布的一条帖子决定免费&开源很多人一听到开源就觉得莫名高大上但对我而言开源动机很简单

  1. 我曾经收到过大量来自国内外开发者的邮件询问 Queryable/寻隐的技术细节我懒得解释开源能让他们直接从源码中了解模型导出加载计算加速存储排序等细节
  2. 开源能打消很多人对于相册隐私的顾虑
  3. 我不擅长 Swift 开发并且我认为这个产品中我最想做的部分已经完成了因此一直抗拒更新但我会持续收到用户的邮件希望增加多选删除左右滑Mac/NAS/Android 支持等等我想借助社区的力量让有能力的开发者打磨出更好的产品

开源后的确有人受此启发做出了 Android 版(#12)和Mac 版

开源后这个项目上了 Github Trending我也因此白嫖了一年 Github Copilot开心

有关抄袭

谈抄袭之前我想定义一下什么叫抄袭

抄袭是指未经授权或未给予适当信用的情况下直接或间接地使用他人的作品创意或内容将其作为自己的作品或创意发表

抄袭其实在开源前就出现了有人做了 Android 版发布在 Google Play名字和产品介绍完全照搬 Queryable我很生气但这其实需要同时掌握机器学习和 iOS 开发开源前我只遇到这样一个

但开源之后抄袭套壳的人就多了因为项目是 MIT 开源所以即使套壳换图标然后重新上架 App Store我虽然有点无语但也不会说什么这是我见过最多的形式开发者全是中文名

我其实很支持在原项目的基础上加上用户希望的功能比如多选删除按日期/地点筛选照片UI 比我做得好看的产品——这也是我开源的初衷但它们中也有让我感觉不爽的地方比如在社区宣传产品的时候不仅没有致谢被用户提问与寻隐有什么不同时还要踩一脚我比寻隐多了 xx

比较恶劣的是用 Queryable 名字套壳上架比如下面这个收费模式是免费+广告我很担心用户误以为这是 Queryable 的 Android 版后续出事了找我麻烦
友好沟通🐶

我最开始会伤心正如一位 v2er 在评论区预言得那样肯定会有人编译后上架市场的开源是好事情但是我不希望看到你看到李鬼后伤心但虱子多了不痒后来也就慢慢看淡了

重新变为付费

重新变成付费是在 2023 年 11 月份除了生存压力增加之外我发现

开源并不能帮助我的产品变得更好我原先希望借助开源+免费让专业的移动开发者贡献代码帮助寻隐/Queryable 打磨得更好但事实就是我看到一个一个新的套壳产品出现宣传自己交互和功能做得很精美但它们从不会提交 PR我的产品原地踏步甚至因为免费的缘故用户抱怨的邮件比过去更多

每当用户发邮件向我提反馈/bug/建议时我的第一反应是不耐烦(内心:免费给你用就不错了还挑三拣四)我发现这种想法导致产品越来越落后直到有天被淘汰

可一旦收费我就突然变得很心平气和了面对用户的意见产品反馈的第一反应是感激而不是厌烦这会倒逼我不得不花费心血优化产品最终让所有曾经付费的用户用上打磨更好的产品而不是疏于维护过几年死掉

我就这样不紧不慢偶尔抽空更新产品但其实只是修复 bug 以及提升模型效果功能上值得做的很少例如很多人希望可以搜人脸——这会引入人脸识别模型让 app 更慢所以没有加

尾声

Apple 在今年的 WWDC 终于宣布iOS 18 即将支持相册语义搜索了这比国内的厂商慢许多不过虽然我在 beta 版本还无法体验但有理由相信苹果会做得比寻隐/Queryable 好毕竟它禁了第三方 App 跳转到系统相册

我也没有闲着上周调研最新 paper并 重新设计训练了中文文本模型App 体积从原来的 232M 降低到 159M索引速度翻倍准确率更高训练过程花了 3 天 70 美元
原来的体积是232M,来源:扬帆出海 https://www.yfchuhai.com/article/11010.html

最近终于将订阅了一年的 GPT-4 切换成了 Claude 3.5 Sonnet它写代码能力过于逆天之前靠 GPT-4 搞不定的多选删除拖了一年半后终于在上周开发完成并上线了

从想法诞生产品上线到现在快两年了它陪伴我经历了人生的跌宕起伏见证了好几家咖啡店的倒闭我也陪它经历了诞生高峰和低潮并没有像最早幻想的那样赚到钱(100 万人下载每人给我 10 块钱我就…)生活依旧继续我还是挺喜欢这个平淡的结尾

俱往矣迫不及待开始下一个让我废寝忘食的 idea下一次流放到真空中