跳至主要內容

咪咔相机分享 | 从零到上线一款 AI 相机小程序

Kevin 吴嘉文大约 31 分钟知识笔记Other创业

1. 背景

2023 年,妙鸭相机因其创意性的 AI 写真生成功能受到广泛关注,市场上也随之涌现了大量基于 Stable Diffusion(SD)模型的生图应用。作为一名技术爱好者,笔者在妙鸭相机发布后不久,进行了 Stable Diffusion + LoRA 的技术验证,并发现了搭建类似 AI 相机的可行性。

参考文章:妙鸭=SD + Lora? 对 SD+LoRA 的一些探索与验证open in new window

于是和几个朋友设计一款专门为宠物主人设计的微信小程序—— 咪咔相机 ,作为一个理论实践项目。

该系列文章中,笔者会分享咪咔相机项目的一些心得,以及对各个技术环节做分享包括了微信小程序开发,figma,产品设计,Stable Diffusion 训练与部署,API 开发,K8S 部署,消息队列,监控与报警,airflow 任务编,数据库管理等。

希望这些分享能对正在学习小程序开发的朋友有所帮助。

2. 功能介绍

咪咔相机和妙鸭相机功能很像,但针对宠物用户进行了优化和细化。用户可以通过平台为宠物生成多种风格的 AI 照片,比如:卡通化、写实风格等。

img
img

以下是一些咪咔相机的主要界面图,咪咔相机小程序包含了 5 个 tab 栏,包括主页、拍照、相册、宠物档案、以及我的。

(1) 首页

用户进入小程序后,会首先看到首页。首页设计包括:

  • 轮播图 :展示平台精选的宠物 AI 作品。
  • 热门风格推荐 :帮助用户快速了解热门风格。
image-20250105234357129
image-20250105234357129

(2) 宠物档案

用户可通过上传 12-16 张宠物照片 来生成“数字档案”(LoRA 权重)。宠物档案页面展示宠物的详细信息和生成记录,生成完成后,用户可随时使用档案生成 AI 风格照片。

创建档案流程:

  1. 填写宠物基本信息(如名称、品种)。
  2. 上传图片(系统将进行质量检查)。
  3. 启动档案生成(需稍作等待,系统后台完成训练)。
image-20250105142848652
image-20250105142848652

(3) 拍照和相册

拍照页面展示多种可选风格,用户只需选择风格并点击生成,即可完成照片制作。

  • 生成流程 :用户选择宠物档案并选择风格,点击生成后稍等数秒,即可获得高质量 AI 照片。
  • 结果展示 :支持用户直接分享照片至微信朋友圈等社交平台。

所有生成的 AI 照片会自动归档至用户的宝贝相册。用户可以浏览、下载或分享已生成的照片。

image-20250105144203883
image-20250105144203883

(5) 我的

该模块提供账户相关功能,包括:

  • 充值与余额管理 :用户可通过微信支付充值平台专用虚拟货币“小鱼干”。
  • 联系客服 :用户可通过微信内置的客服系统提交问题或建议。
  • 常见问题解答 :提供操作指引与 FAQ。
image-20250105145818466
image-20250105145818466

3. 走过的坑和技术分享

在这一章节中,笔者将分享从零开始开发“咪咔相机”小程序的整个过程,重点讲述项目筹备、开发中的挑战,以及遇到的一些坑。

3.0 项目可行性分析

妙鸭相机火了一段时间后,笔者对 stable diffusion + Lora 技术进行了初步验证open in new window,实验证明采用 sd+lora,是可以搭建一款类似于妙鸭一样的 AI 照相软件的。妙鸭相机是针对人物拍摄写真照片的,于是笔者便想着开发一款宠物 AI 相机,当做业余项目。

在简单构思了项目架构后,发现涉及到的技术并不复杂,并且当时 ai 生成图片也算挺有意思,于是便找了几个想学 ai 相机的伙伴一起参与这个业余项目。

简单和几个伙伴介绍了以下项目的“宏伟”计划,画了一下大饼后,项目便开始了。

3.1 市场分析及产品设计

  • 市场分析: 在开发“咪咔相机”之前,我们研究了市场上现有的宠物 AI 相机和真人 AI 相机产品。虽然大部分产品使用的技术相似,但在用户体验上存在很大差异。尤其是在收费机制方面,AI 相机的过程分为两个主要环节:数字分身的制作(Lora 训练)和照片生成(模型推理)。整个环节大概为:
  1. 用户提供照片->
  2. 相机制作数字分身(lora 训练)->
  3. 生成 ai 相片(sd+lora+prompt 进行风格推理)

训练 lora 的成本是模型推理成本的 6000 倍。对于 AI 相机,有 2 中较常见的收费方案:

  1. 按制作数字分身收费: 把制作宠物档案设置成收费项,用户需要支付一定费用制作数字分身,完成后可以免费使用所有 AI 模板生成照片。该方案与服务的成本比较匹配。
  2. 按生成照片收费 :用户可以免费制作数字分身,但在生成照片环节需要支付费用,该方案用户能够提前体验到拍照的乐趣。

咪咔采用了按生成照片收费,并且用户注册后会赠送一定量的“咪咔货币”(小鱼干),可以免费制作宠物档案并生成 AI 照片。

  • 功能、界面与原型设计

我们与几个小伙伴一起,筛选并设计了小程序的基本功能,包括注册、档案制作、图片生成、充值和分享等。在统一了基础功能后,由于“咪咔相机”并未使用复杂的动画效果,所有功能均通过简单的页面跳转来实现。为了高效设计界面,我使用 Figma 设计了各页面之间的跳转,并与伙伴们合作完成了界面的美术设计。

然而,作为第一次使用 Figma 进行设计,并且并非前端开发出身,我在过程中踩了不少坑,特别是在 Figma 设计与前端开发的配合上,导致后期开发中花费了不少时间进行调整。

Figma 的精细设计能够显著提高前端开发的效率。设计者不仅需要具备基础的前端开发知识,还应采用“优雅的设计方案”以确保设计的可实现性。例如,在设计登录界面时,如果要将用户头像居中,Figma 提供了多种实现方式,其中“自动居中”效果比手动设置位置更加适合开发需求。在 Figma 中,如果我们设计一个 480px 宽的界面,并希望将 40px 的头像居中,可以选择两种方式:

  1. 使用 Figma 的自动居中功能。
  2. 手动将头像设置为离画布左边 220px 的位置。

虽然这两种方法在 Figma 中的效果图看起来相同,但在实际开发中,只有第一种方法才能确保头像在所有设备上都居中。因为并非每个设备的屏幕宽度都与设计宽度一致,手动计算的方式可能导致在某些设备上位置偏移。

Figma 支持设计任意大小的画布,并且内置了多个手机型号的画布模板,如 iPhone 14、13 等。刚开始时,我使用了 iPhone 14 的画布设计所有界面和原型,但在开发微信小程序时才发现,这并不是最理想的选择。原因在于微信小程序使用rpx(响应式像素)来衡量尺寸,而不是pxem/remrpx可以根据屏幕宽度自适应,规定屏幕宽度为 750rpx。因此,在设计时,如果选择了 iPhone 14 的画布宽度(395px),会导致后期换算时需要手动调整每个元素的rpx值。而如果设计时直接选用 375px 宽度作为画布,则在开发时可以直接使用1rpx = 0.5px的规则,简化了开发过程。

另外,尽管 Figma 提供了多个插件来帮助生成前端代码,但大多数插件在实际应用中并不十分实用。例如,一款插件在将 Figma 设计转换为 HTML 时,会将整个页面保存为一张图片,而在代码中只生成一个<img>标签。其他插件虽然没有那么极端,但也不同程度地存在类似问题。最实用的还是 Figma 自带的开发者模式,它可以更准确地将设计转化为前端代码,且具备较好的适配性。

有时,产品经理希望实现的某些效果在 Figma 中无法完全体现,这时就需要设计师、前端开发人员以及产品经理之间的有效沟通与协调。通过及时的交流,可以确保设计需求得到准确理解和实现,避免开发过程中出现不必要的返工。

3.3.1 咪咔相机架构总览

咪咔相机可以大致分为 4 个部分:

  • 数据库: 咪咔相机使用阿里云的 PostgreSQL 数据库存储结构化数据,同时借助阿里云 OSS(对象存储服务)来存储非结构化数据,如图片、Lora 权重等。

  • UI: 作为一款微信小程序,咪咔相机的前端部署无需额外的服务器支持,所有前端服务均由微信平台提供支持,简化了基础设施的管理。

  • 咪咔基础 API: 微信小程序通过调用咪咔基础 API 服务来执行各种操作,包括获取用户数据、下单、充值、分享等。这些 API 服务部署在阿里云上,确保稳定性与可扩展性。

  • AI 生图服务 API: 由于 AI 图像生成需要大量 GPU 计算,咪咔相机选择在本地搭建 GPU 服务器来处理这一需求,而非使用云端 GPU 服务,主要考虑到成本因素。

用户在微信小程序中的操作会通过这些服务进行处理,整体运作流程如下图所示:

image-20250101192938270
image-20250101192938270

3.3.2 前端与微信小程序

1. 技术选择

在开发咪咔相机时,我们的目标是快速上线,但由于笔者在前端开发方面经验有限(熟悉 Vue,但主要有 AI 相关开发经验,对 React 的实际开发经验较少),我们经过调研后选择了 uniapp 来开发微信小程序。uniapp 上手简单,与 Vue 的语法类似,非常适合用来开发小型应用。通过 uniapp,我们可以轻松编译并生成适用于微信小程序的代码。

在决定使用 uniapp 后,笔者跟随黑马教育的“小兔仙教程”学习了 uniapp 的开发流程,并参考了该教程的项目文件夹架构及设置,建议大家也可以查看教程:

https://www.bilibili.com/video/BV1Bp4y1379L/?spm_id_from=333.337.search-card.all.click&vd_source=4418d5cd5be787be7e3ff4138eeb9b0a

2 小程序开发

uniapp 编写的代码可以直接编译为微信小程序所需的代码,开发语言包括 JavaScript、WXML 和 WXSS。这些语法与 HTML 和 CSS 类似,因此对于前端开发者来说,从网页开发迁移到小程序开发的成本相对较低,但二者之间仍有一些差异:

  • 一些常见的前端库,如 jQuery,在小程序中无法使用。
  • iOS 和 Android 小程序的运行环境存在一些小差异。

小程序开发需要使用 微信开发者工具open in new window。安装好微信开发者工具后,选择创建小程序,然后选择对应的 APPID(注册好小程序之后会给)

tu
tu

点击确认后进入编辑页面,官方会为你创建好程序的模板:

tu
tu

微信小程序开发使用 WXML,WXSS 等微信专用语法进行开发。语法类似 HTML 和 CSS。

微信小程序包含了不同的版本:

  • 开发版本 :开发人员在微信开发工具上开发完成后,,可将代码上传到开发版本中。 开发人员可以在手机微信上体验测试开发版本的微信小程序。开发版本只保留每人最新的一份上传的代码。 点击提交审核,可将代码提交审核。开发版本可删除,不影响线上版本和审核中版本的代码。

  • 体验版本 :当开发人员觉得开发版本可行后,可以选择某个开发版本作为体验版,并且选取一份体验版。(点击开发者小程序中的上传,然后让管理员将该版本设置为体验版本。)体验版本只有授权用户可以体验,我们当时邀请了约 30 人来体验我们的小程序,主要用于收集 bug 反馈。在 管理-版本管理 中,可以找到开发版本,并选择对应开发版本为体验版本。

  • 审核版本 :当团队觉得小程序没有问题后,可以把小程序上线,让所有用户使用,但那之前我们需要把代码提交给微信进行审核。只能有一份代码处于审核中。有审核结果后可以发布到线上,也可直接重新提交审核,覆盖原审核版本。在 管理-版本管理 中,可以找到开发版本,点击提交审核。提交审核规则需要符合 小程序平台运营规范 open in new windowopen in new window

  • 线上版本 :线上所有用户使用的代码版本,该版本代码在新版本代码发布后被覆盖更新。

3. 开发经验

前后端交互开发时,咪咔项目使用 Apifox 来生成 API 文档和 Mock API,从而简化开发过程。以下是前后端交互的主要流程:

  1. 定义好产品所需功能。(产品经理负责)
  2. 为产品的每一项功能确定好技术实现方案(产品经理与技术总监讨论)
  3. 编写好 mock api 和 API 文档(后端开发)
  4. 根据 API 文档开发前端,而后使用 mock api 做测试。(前端开发)
  5. 编写 API 文档以及 mock api 的优点在于:前端后端的开发可以同时进行开发。等后端开发好全部 API 后,前端只需要替换掉 mock api 地址就可以进行测试了。同时团队也可以通过 API 文档来初步检测产品逻辑是否存在漏洞等。
  6. 前后端人员开发好后,进行产品测试与发布。

示例图片:咪咔相机 Airfox API 文档

image-20250103190949881
image-20250103190949881

4. 部分页面的实现逻辑分享

  1. 首页
image-20250105234357129
image-20250105234357129

当用户进入微信小程序时,首先会看到首页。首页展示咪咔相机生成的宠物 AI 照片,包含了两个主要模块:轮播图和下拉栏。

首页的实现逻辑如下:

  • 图片存储在阿里云 OSS 上,图片 URL 地址存储在 PostgreSQL 数据库中。
  • 前端通过调用 /api/v1/home/carousel 获取首页轮播图的链接,并展示给用户。
image-20250103193815655
image-20250103193815655
  1. 我的

我的页面中提供了充值,登录, 查看余额,联系客服等操作。

  • 充值功能 :使用微信小程序内置的微信支付功能。用户完成支付后,数据库会自动更新用户余额。微信小程序调用微信支付:https://antarina.tech/posts/notes/articles/%E7%AC%94%E8%AE%B0wxpay.html

  • 登录部分,咪咔基于微信自带的 wx.login 设置了登录方案。用户第一次登录时,小程序会将 openid 发送到 /api/v1/login/token API 上来获取 access_token (JWT 令牌,用户请求业务 API 时的凭证,前端需要将 token 保存在 localstorage 当中),用户余额等信息。后端负责创建用户数据,生成 JWT token。登录前,用户需要同意咪咔用户协议和微信隐私协议,用户协议全文由咪咔团队编写,隐私协议使用了微信提供的模板编写。

image-20250103194347640
image-20250103194347640
  • 联系客服方案,咪咔采用了微信自带的客服助手,前端上开启客服助手后,客服人员可以在客服小助手小程序上看到用户的留言。
  1. 拍照页面

用户可以选择不同的拍照风格,点击后进入对应的风格页面。用户在选择拍摄风格后,前端会请求 /api/v1/pet/generate_image API 生成宠物照片。照片生成后,用户可以查看并分享给微信好友。

用户点击某个风格后,会跳转到风格对应的页面,如点击口袋宝贝,会跳转到口袋宝贝页面,页面中包含了几张口袋宝贝的示例图片。

用户点击生成风格后,可以选择想要拍摄的宝贝,稍作等待后,一张口袋宝贝的 AI 相册就生成好了。

image-20250105144203883
image-20250105144203883

当用户点击生成风格后,前端会向 /api/v1/pet/generate_image API 发送请求,其中包含了宠物类别,宠物名称,宠物 ID,风格 ID,风格名称(如口袋宝贝)等。后端接收到请求后,会先验证用户的 JWT token,而后检测用户余额是否足够。余额足够的话,咪咔会将该生成图片的任务提交给消息队列,并在阿里云 postgres 上记录,该照片的状态为 queue,本地 GPU 服务器会处理这些消息,处理完毕后会将状态改为 successfail

image-20250103200315205
image-20250103200315205
  1. 相册

用户提交拍照订单后,可在相册页面查看订单进度。正在生成中的照片会显示等待中的标志。

  • 每隔一段时间,前端会检查图片状态并更新。
  • 用户可以分享生成的图片,并且每日首次分享可获得奖励。

咪咔后台处理用户订单时,会将信息记录在阿里云 postgres 上。相册页面每隔一段时间,会往咪咔 API 发送请求,来检查用户宠物的图片状态是否改变,如果有改变的话,会更新对应的图片。

image-20250103201003994
image-20250103201003994

每个订单中,咪咔会为用户生成 4 张该风格的图片,用户可以点击分享图片,来将图片分享给微信好友。咪咔采用了微信自带的分享 SDK 来实现了这个功能。一个比较特殊的设定是,用户每日首次分享,可以获得 150 个小鱼干, 用户点击了分享按钮后,咪咔后台会自动为用户添加这 150 个小鱼干,而后再触发分享功能。

  1. 宠物档案

宠物档案功能主要用于创建与宠物相关的 Lora 模型。用户可以在宠物档案页面通过左右滑动来浏览自己的宠物档案。

当用户点击“添加宠物”按钮时,会被引导至档案创建页面。在此页面,用户需填写宠物的基本信息,如名字和类型,同时上传 12 至 16 张宠物照片用于 Lora 训练。

image-20250105142848652
image-20250105142848652

用户提交图片并点击“开始创建宠物档案”后,照片将被上传至阿里云 OSS,接着前端会向 api/v1/pet/train API 发送请求。咪咔 API 首先会验证用户的 JWT token。验证成功后,系统将按照以下步骤执行:

  1. 在阿里云 PostgreSQL 数据库中添加对应的宠物数据(如名字、ID 等),并将宠物档案的状态设置为“队列中”(queue)。
  2. 将宠物 Lora 训练任务提交至消息队列(使用 RabbitMQ)。同时,系统将向用户发送一个订阅通知,用户点击同意后,便能在 Lora 训练完成时,第一时间收到微信服务消息的提醒。
  3. 本地 GPU 服务器将处理消息队列中的任务,并在处理过程中不断更新 PostgreSQL 中的档案状态。一旦 Lora 训练完成,后台 GPU 服务器会向用户发送微信服务消息。
  4. 用户最终会收到微信服务消息通知:【您的宝贝档案已生成】。
image-20250103201729971
image-20250103201729971

3.3.3 后端开发

数据库

咪咔采用阿里云 PostgreSQL 数据库,这一选择不仅符合成本要求,还提供了多项配套服务,如用户界面(类似于 PostgreSQL 的 pgAdmin)、异常监控等。由于咪咔的后端 API 也基于阿里云设备,因此 API 与数据库之间的通信可以通过阿里云内网进行,这样有效减少了网络通信费用。

数据库包含以下表格:

image-20250105235000294
image-20250105235000294
  • 充值订单表 :记录用户充值金额和时间。
  • 公告表 :用于发布和更新公告内容。
  • 商品定价表 :储存各风格对应的价格。
  • 宠物证件照表 :存储展示宠物档案页面的宠物图片。
  • 训练示例图片表 :用户提交 Lora 训练时,需要上传 12-16 张宠物图片。咪咔提供合格图片和错误图片的示例。
  • 首页图片表 :存储首页轮播图的图片链接。
  • 首页风格图片表 :储存拍照页面所有风格的图片链接。
  • 鱼干结算表 :记录用户的鱼干消费历史。

后端 API

咪咔的后端 API 采用FastAPI框架来与前端进行交互,整体项目架构参考了FastAPI Full Stack 模板open in new window。API 与数据库的连接通过SQLAlchemy实现,数据库迁移采用Alembic,而 API 请求的头部验证则使用 JWT token。

部署流程如下:

  1. 注册域名并购买 SSL 证书。
  2. 将 API 服务打包为 Docker 镜像并部署在阿里云上。
  3. 配置域名解析到指定 IP 地址。
  4. 在微信小程序中,将域名添加到安全域名列表。

消息队列

咪咔采用 RabbitMQ 搭建消息队列服务,详细操作可参考[笔者的 RabbitMQ 博客文章](https://antarina.tech/posts/notes/articles/笔记 mq.html)。

咪咔设置了四个消息队列:

  • default :处理普通任务。
  • preprocess :处理图片预处理任务,如目标识别、像素优化(超分辨率)、图片拆分等。
  • train :用于宠物档案制作(Lora 训练)。
  • inference :用于 AI 照片生成(SD + Lora 推理)。

由于traininference分布在不同设备上,Lora 训练任务完成后,训练好的 Lora 会上传到 OSS,inference设备获取任务后,从 OSS 下载 Lora 进行推理。

在处理流程中,preprocesstraininference通常运行在不同设备上,因此preprocess会先从 OSS 下载用户上传的图片,进行目标检测(识别猫狗)、像素优化、生成图片描述等操作,处理好的图片会重新上传至 OSS,描述信息通过消息存入队列中。

GPU 服务器

GPU 服务器主要用于 Lora 训练和图片生成。Lora 训练流程包括图片下载、数据库更新、目标检测、生成图片描述、Lora 训练、宠物档案照片生成等操作。咪咔使用 Airflow 对任务进行管理和调度:

image-20250103223401650
image-20250103223401650

在 Airflow 中,咪咔使用CeleryRabbitMQ来管理消息队列,PostgreSQL用于 Airflow 的数据管理。同时,咪咔还集成了阿里云提供的 Airflow SDK,以便与阿里云 OSS 进行数据交互。

Lora 训练

当 GPU 服务器接收到 Lora 训练任务时,后台会依次触发以下任务:

  • 图片预处理:image_preprocess 是一个 Airflow Task Group,负责处理用户上传的图片。假设用户上传了 12 张图片,Airflow 会将目标检测任务和图片描述生成任务分配给消息队列,由多个 worker 并行处理。咪咔配置了 4 个 worker 同时处理这些任务。
  • 图片目标检测: 为了确保训练效果,咪咔使用 YoloV5 对图片进行目标检测,并裁剪图片,使宠物占据图片的大部分区域。目标检测任务资源消耗较低且执行快速,4 个 worker 足以处理。
  • 图片描述生成: 为了生成 Lora 训练所需的描述(如 “cat”, “cute”, “on a beach” 等),咪咔将描述生成转化为多分类任务,通过模型自动选择与图片相匹配的描述词。此过程仅消耗 CPU 资源,且推理速度较快。相较于 GPT2 等大型模型,使用该方法能更有效地生成符合 SD 要求的描述。
  • lora 训练:train 任务是整个流程中最耗时的部分。咪咔采用 SDXL 架构进行 Lora 微调,训练时使用以下配置:在一台 4090 上训练的话,只需要花费 6 分钟就可以完成训练了。关于 sd + lora 方案的验证,欢迎查看笔者这篇文章:妙鸭=SD + Lora? 对 SD+LoRA 的一些探索与验证open in new window
accelerate launch --num_cpu_threads_per_process=2 "/workspace/sdxl_train.py" \
    --enable_bucket \
    --pretrained_model_name_or_path="/models/kevinng/sdxl-train-base/sd_xl_base_1.0.safetensors"  \
    --train_data_dir="${TRAIN_DATA_DIR}" \
    --resolution="1024,1024" \
    --output_dir="${OUTPUT_LORA_FOLDER}" \
    --logging_dir="/workspace/logs" --network_alpha="8" --network_dim=8 \
    --save_model_as=safetensors --network_module=networks.lora   \
    --unet_lr=0.0004 --output_name="${OUTPUT_LORA_NAME}"             \
    --lr_scheduler_num_cycles="1" --no_half_vae --learning_rate="0.0004"        \
    --lr_scheduler="constant" --train_batch_size="2"        \
    --max_train_steps="${NUM_TRAIN_STEPS}"  --save_every_n_epochs="1" --mixed_precision="bf16"    \
    --save_precision="bf16" --seed="1234" --caption_extension=".txt" --cache_latents     \
    --optimizer_type="Adafactor" --max_data_loader_n_workers="4" --clip_skip=2     \
    --bucket_reso_steps=64 --xformers --bucket_no_upscale --noise_offset=0.0 \
    --tokenizer_cache_dir="/models/kevinng/sdxl-train-base" \
    --optimizer_args scale_parameter=False relative_step=False warmup_init=False \
    --gradient_checkpointing --cache_latents_to_disk --cache_text_encoder_outputs \
    --network_train_unet_only 

在单台 4090 GPU 上训练需要约 6 分钟。关于 SD + Lora 的验证,欢迎查看笔者的详细分析【添加链接】。

每当一个用户创建宠物档案时,咪咔根据当前队列任务数量计算预计等待时间,公式为:等待时间 = 15 分钟 * 任务个数。当订单数量超过 100 时,系统会自动启用第二个 GPU worker。

  • 生成宠物 ID 图片:宠物 ID 图片(带蝴蝶结或领带的证件照)通过 Lora 训练后生成。每个 Lora 都需要生成一个宠物 ID 图片,因此此任务与 Lora 训练任务共用同一容器。当 Lora 训练完成后,GPU 会加载 Lora 资源并进行 ID 图片生成。
  • 上传数据:这部分的任务会被添加到 default 队列中,因为他们只涉及到了基础的数据库和通讯操作, 对性能的要求是微乎其微的(相比于其他任务来说)。当 lora 和宠物 ID 图片就绪后,这部分的任务会被触发,生成的 Lora 和宠物 ID 图片会上传到阿里云 OSS,相关资源链接会存入 PostgreSQL 数据库。
  • 通知用户:当以上所有操作都成功后,这个 task 会发送一条微信服务通知给用户。即使用户关闭了小程序,他们也可以在微信服务中接受到这个通知。
  • 失败报警:如果有任意一个环节出错了,airflow 会往企业微信机器人发送错误报警。根据经验,1000 个订单中大约出现 1 次错误,通常是网络或通讯问题(如 OSS 资源下载失败)。出错后,可以在 Airflow 上重新尝试该任务。

总体而言,Lora 训练服务相当稳定。截至文章发布前,已经成功完成了 13,278 个任务,约有 1,100+ 个宠物档案顺利创建。

image-20250103230757897
image-20250103230757897
AI 相片生成

图片生成的操作比较简单:

  1. 下载 Lora: 从 OSS 上下载用户对应的 Lora。
  2. 下载风格参数: 从数据库获取用户所选风格的相关 prompt 和推理参数。
  3. 使用 SDXL + Lora 进行推理: 通过 SDXL 和 Lora 模型生成图片。
  4. 上传图片: 将生成的图片上传到 OSS,并在数据库中更新图片状态。

咪咔提供约 70 种风格,所有风格的推理参数(包括 prompt 和 Lora 模型)都存储在数据库中。某些风格除了使用用户的宠物 Lora,还会使用咪咔自训练的风格 Lora,以提高生成图片的质量。

一般生成的图片尺寸为 1024x1024,咪咔会将原图和缩略图同时上传至阿里云 OSS。用户浏览相册时,显示的是约 70KB 的缩略图,而原图则在 1MB 到 2MB 之间。

SDXL + Lora 的推理速度较快,一台 4090 GPU 每生成一张图片大约需要 1 秒钟,包含了模型加载、推理和卸载的时间。不同风格可能会选择不同的 SDXL 模型,如户外野营风格可能使用 SDXL base 1.0,而夏日星空风格则使用更加动漫化的 SDXL 模型(如 Bluepencil)。频繁加载卸载不同的模型可能导致较大的时间开销,并且对显卡显存造成一定压力。

日志和监控

咪咔的日志和监控系统由 Airflow、Grafana 和阿里云平台提供的日志系统构成。

Airflow :Airflow Web 界面用于监控每个任务的执行情况,包括任务参数、运行的具体代码日志等。使用 Airflow 作为日志系统时,确保日志和数据存储在相同的 OSS 和 PostgreSQL 平台上,否则可能会出现数据和日志无法匹配的情况,导致无法查看日志。

image-20250105115542156
image-20250105115542156

Grafana + Prometheus :这两个工具主要用于监控消息队列的状态。咪咔使用 Celery 与 Grafana 和 Prometheus 配合,搭建了监控系统,实时追踪消息队列中的任务数量、消息处理速度等指标。当出现异常时,系统会自动向企业微信机器人发送警报。

阿里云平台监控 :阿里云为平台提供了报警和监控功能,特别是针对阿里云 PostgreSQL 异常等问题。这些监控可以在阿里云平台上直接配置,当发生异常时,系统同样支持将警报发送至企业微信机器人。

开发与更新

代码仓库 :咪咔选择了 Gitee 作为代码托管平台,主要因为 GitHub 在国内访问速度较慢,且某些云平台在拉取 GitHub 代码时可能会有延迟。Docker 镜像仓库则采用了阿里云镜像服务,因其适合咪咔的需求。相比之下,Docker.io 服务不稳定,因此不推荐使用。

SD 模型仓库 :咪咔使用 ModelScope 存储和共享训练好的模型,这样不同地区的 GPU 服务器可以更方便地拉取模型进行推理和训练。与此相比,Hugging Face 的服务经常出现下载不稳定的问题。

CI/CD 流程 :最初,咪咔使用微软的 Azure Pipeline 进行 CI/CD,因其提供免费的使用时间。在 Azure Pipeline 上配置了自动化流程,每当上传代码到 GitHub 时,自动构建 Docker 镜像并推送到镜像仓库,同时更新阿里云服务。但随着免费时间的结束,咪咔停止使用自动化流程,改为手动更新代码、Docker 镜像和服务版本。

3. 收获

咪咔相机作为笔者个人组织开发的第一个上线项目,也算是顺利完成了。从最初的灵感构思,到代码实现,再到上线运营,每一步都承载着咪咔的汗水与期待。几个月前,当小程序第一次上线时,我们迎来了第一位用户,那一刻百感交集。

最感动的瞬间,是看到用户用我们咪咔生产的图片当作微信头像,一直特具咪咔风格的卡通小猫,坐在一个盒子里,她一定很高兴,也很爱她的宠物宝贝吧。

另外有一次加班到晚上 11 点多,才匆匆登录微信客服助手,回复了用户的消息。本以为对方会感到不满,但用户却反过来劝我们不要太辛苦,说“明天再弄也可以”, “你们不要为了这个加班啊”。(泪目!)

体会到了 GM 的快乐,有些朋友特别喜欢我们生成的照片,时不时发来夸奖。作为管理员,我偷偷改了数据库,给这些朋友的账户充值了无限量的“小鱼干”(虚拟货币),让他们可以随意生成照片。

产品成功的思考

在开发小程序的过程中,我也开始思考,什么才是“好产品”的标准。这个时代,开发一个能运行的产品并不难,但要创造一个真正打动人心的好产品,却需要极大的智慧与耐心。

用户的需求定位 是第一要素。产品是否能够精准捕捉用户的痛点?能否解决他们最迫切的问题?

价格的合理性 也至关重要。我们是否为用户提供了物有所值的体验?过高或过低的定价,都可能让产品失去竞争力。

功能与用户体验的超预期表现 ,则是吸引用户、留住用户的关键。功能不仅要运行顺畅,更要给用户带来惊喜和独特的体验,带给用户超出预期的体验。

此外 产品形象传递的情绪价值 等,也是产品成功的关键。

咪咖相机不是一款好的产品,我们把所有精力花费在了开发任务上,涉及到营销和推广的工作却微乎其微。尽管咪咔生成图片的质量的确不错,他里成功产品还有很大的距离。

产品创造者

作为程序员,曾经痴迷于从 0 到 1,独自把一个产品完整打造出来的过程。然而,完成咪咔之后,我发现,真正推动产品成功的,不仅仅是技术的实现,更是功能设计、营销推广、数据分析与运营管理的综合结果。技术是基础,但产品的灵魂在于如何通过设计和运营,让用户感受到价值与温度。

代码之外的世界更广阔,也更复杂。程序员可以成为优秀的产品创造者,但只有当他们开始理解市场、用户和情感,才能真正参与到好产品的创造中去。

领导者

“与一支出色的团队携手,打造一款卓越的产品。” 这令人向往的事,需要一个领导者带领。

领导者是能够激发他人、整合资源并引导团队实现共同目标的人。他们的职责不仅是完成任务,更重要的是塑造团队的整体方向和价值观,包括:

  • 设定方向 :为团队提供清晰的愿景和战略。
  • 影响他人 :通过个人魅力、信任和专业能力影响团队成员的行为。为团队提供一个积极、安全的工作氛围,让每个成员都能贡献自己的独特优势。
  • 创造价值 :不仅关注目标结果,还注重实现过程中的学习、成长和可持续发展。

理想的领导者不仅仅是指挥者,更是激励者、倾听者和支持者。他们通过明确的愿景、以身作则和有效的沟通,帮助团队成员实现个人成长,同时推动集体的成功。

要成为一名优秀的领导者,需要具备多方面的能力,并不断反思与学习:

  1. 培养战略思维 优秀的领导者能够从整体上把握局势,设定清晰的目标和可行的计划。他们善于分析问题、评估风险,并为团队制定创新的解决方案。
  2. 提升人际沟通与情感智能 开放沟通和倾听能力是建立团队信任的基础。领导者需要通过同理心理解团队成员的需求,塑造支持性和包容性的工作环境。此外,学会用清晰的语言表达愿景和目标,让团队成员明确方向。
  3. 增强凝聚力与号召力 领导者应激励团队成员,为他们赋予归属感和共同愿景。同时,通过以身作则和榜样作用,激发团队的信心和动力。
  4. 优化组织与执行能力 将复杂任务合理分解,分配到合适的团队成员,并建立持续反馈机制,确保目标按时达成。同时,优秀的领导者具备很强的应急能力,在变化中快速调整策略,保证行动不脱轨。
  5. 坚持学习与自我提升 成为优秀的领导者需要持续的学习和反思。他们在实践中不断积累经验,并通过失败中汲取教训,持续优化自己的领导风格。

通过全面的能力发展和对团队价值的深刻理解,领导者可以不仅带领团队走向成功,还能创造一个鼓舞人心、充满信任和合作的工作环境,为团队成员的成长提供无限可能。

上次编辑于:
贡献者: kevinng77