咪咔相机分享 | 从零到上线一款 AI 相机小程序
1. 背景
2023 年,妙鸭相机因其创意性的 AI 写真生成功能受到广泛关注,市场上也随之涌现了大量基于 Stable Diffusion(SD)模型的生图应用。作为一名技术爱好者,笔者在妙鸭相机发布后不久,进行了 Stable Diffusion + LoRA 的技术验证,并发现了搭建类似 AI 相机的可行性。
参考文章:妙鸭=SD + Lora? 对 SD+LoRA 的一些探索与验证
于是和几个朋友设计一款专门为宠物主人设计的微信小程序—— 咪咔相机 ,作为一个理论实践项目。
该系列文章中,笔者会分享咪咔相机项目的一些心得,以及对各个技术环节做分享包括了微信小程序开发,figma,产品设计,Stable Diffusion 训练与部署,API 开发,K8S 部署,消息队列,监控与报警,airflow 任务编,数据库管理等。
希望这些分享能对正在学习小程序开发的朋友有所帮助。
2. 功能介绍
咪咔相机和妙鸭相机功能很像,但针对宠物用户进行了优化和细化。用户可以通过平台为宠物生成多种风格的 AI 照片,比如:卡通化、写实风格等。

以下是一些咪咔相机的主要界面图,咪咔相机小程序包含了 5 个 tab 栏,包括主页、拍照、相册、宠物档案、以及我的。
(1) 首页
用户进入小程序后,会首先看到首页。首页设计包括:
- 轮播图 :展示平台精选的宠物 AI 作品。
- 热门风格推荐 :帮助用户快速了解热门风格。

(2) 宠物档案
用户可通过上传 12-16 张宠物照片 来生成“数字档案”(LoRA 权重)。宠物档案页面展示宠物的详细信息和生成记录,生成完成后,用户可随时使用档案生成 AI 风格照片。
创建档案流程:
- 填写宠物基本信息(如名称、品种)。
- 上传图片(系统将进行质量检查)。
- 启动档案生成(需稍作等待,系统后台完成训练)。

(3) 拍照和相册
拍照页面展示多种可选风格,用户只需选择风格并点击生成,即可完成照片制作。
- 生成流程 :用户选择宠物档案并选择风格,点击生成后稍等数秒,即可获得高质量 AI 照片。
- 结果展示 :支持用户直接分享照片至微信朋友圈等社交平台。
所有生成的 AI 照片会自动归档至用户的宝贝相册。用户可以浏览、下载或分享已生成的照片。

(5) 我的
该模块提供账户相关功能,包括:
- 充值与余额管理 :用户可通过微信支付充值平台专用虚拟货币“小鱼干”。
- 联系客服 :用户可通过微信内置的客服系统提交问题或建议。
- 常见问题解答 :提供操作指引与 FAQ。

3. 走过的坑和技术分享
在这一章节中,笔者将分享从零开始开发“咪咔相机”小程序的整个过程,重点讲述项目筹备、开发中的挑战,以及遇到的一些坑。
3.0 项目可行性分析
妙鸭相机火了一段时间后,笔者对 stable diffusion + Lora 技术进行了初步验证,实验证明采用 sd+lora,是可以搭建一款类似于妙鸭一样的 AI 照相软件的。妙鸭相机是针对人物拍摄写真照片的,于是笔者便想着开发一款宠物 AI 相机,当做业余项目。
在简单构思了项目架构后,发现涉及到的技术并不复杂,并且当时 ai 生成图片也算挺有意思,于是便找了几个想学 ai 相机的伙伴一起参与这个业余项目。
简单和几个伙伴介绍了以下项目的“宏伟”计划,画了一下大饼后,项目便开始了。
3.1 市场分析及产品设计 :
- 市场分析: 在开发“咪咔相机”之前,我们研究了市场上现有的宠物 AI 相机和真人 AI 相机产品。虽然大部分产品使用的技术相似,但在用户体验上存在很大差异。尤其是在收费机制方面,AI 相机的过程分为两个主要环节:数字分身的制作(Lora 训练)和照片生成(模型推理)。整个环节大概为:
- 用户提供照片->
- 相机制作数字分身(lora 训练)->
- 生成 ai 相片(sd+lora+prompt 进行风格推理)
训练 lora 的成本是模型推理成本的 6000 倍。对于 AI 相机,有 2 中较常见的收费方案:
- 按制作数字分身收费: 把制作宠物档案设置成收费项,用户需要支付一定费用制作数字分身,完成后可以免费使用所有 AI 模板生成照片。该方案与服务的成本比较匹配。
- 按生成照片收费 :用户可以免费制作数字分身,但在生成照片环节需要支付费用,该方案用户能够提前体验到拍照的乐趣。
咪咔采用了按生成照片收费,并且用户注册后会赠送一定量的“咪咔货币”(小鱼干),可以免费制作宠物档案并生成 AI 照片。
- 功能、界面与原型设计 :
我们与几个小伙伴一起,筛选并设计了小程序的基本功能,包括注册、档案制作、图片生成、充值和分享等。在统一了基础功能后,由于“咪咔相机”并未使用复杂的动画效果,所有功能均通过简单的页面跳转来实现。为了高效设计界面,我使用 Figma 设计了各页面之间的跳转,并与伙伴们合作完成了界面的美术设计。

然而,作为第一次使用 Figma 进行设计,并且并非前端开发出身,我在过程中踩了不少坑,特别是在 Figma 设计与前端开发的配合上,导致后期开发中花费了不少时间进行调整。
Figma 的精细设计能够显著提高前端开发的效率。设计者不仅需要具备基础的前端开发知识,还应采用“优雅的设计方案”以确保设计的可实现性。例如,在设计登录界面时,如果要将用户头像居中,Figma 提供了多种实现方式,其中“自动居中”效果比手动设置位置更加适合开发需求。在 Figma 中,如果我们设计一个 480px 宽的界面,并希望将 40px 的头像居中,可以选择两种方式:
- 使用 Figma 的自动居中功能。
- 手动将头像设置为离画布左边 220px 的位置。
虽然这两种方法在 Figma 中的效果图看起来相同,但在实际开发中,只有第一种方法才能确保头像在所有设备上都居中。因为并非每个设备的屏幕宽度都与设计宽度一致,手动计算的方式可能导致在某些设备上位置偏移。
Figma 支持设计任意大小的画布,并且内置了多个手机型号的画布模板,如 iPhone 14、13 等。刚开始时,我使用了 iPhone 14 的画布设计所有界面和原型,但在开发微信小程序时才发现,这并不是最理想的选择。原因在于微信小程序使用rpx
(响应式像素)来衡量尺寸,而不是px
或em/rem
。rpx
可以根据屏幕宽度自适应,规定屏幕宽度为 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 服务,主要考虑到成本因素。
用户在微信小程序中的操作会通过这些服务进行处理,整体运作流程如下图所示:

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 小程序的运行环境存在一些小差异。
小程序开发需要使用 微信开发者工具。安装好微信开发者工具后,选择创建小程序,然后选择对应的 APPID(注册好小程序之后会给)

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

微信小程序开发使用 WXML,WXSS 等微信专用语法进行开发。语法类似 HTML 和 CSS。
微信小程序包含了不同的版本:
开发版本 :开发人员在微信开发工具上开发完成后,,可将代码上传到开发版本中。 开发人员可以在手机微信上体验测试开发版本的微信小程序。开发版本只保留每人最新的一份上传的代码。 点击提交审核,可将代码提交审核。开发版本可删除,不影响线上版本和审核中版本的代码。
体验版本 :当开发人员觉得开发版本可行后,可以选择某个开发版本作为体验版,并且选取一份体验版。(点击开发者小程序中的上传,然后让管理员将该版本设置为体验版本。)体验版本只有授权用户可以体验,我们当时邀请了约 30 人来体验我们的小程序,主要用于收集 bug 反馈。在 管理-版本管理 中,可以找到开发版本,并选择对应开发版本为体验版本。
审核版本 :当团队觉得小程序没有问题后,可以把小程序上线,让所有用户使用,但那之前我们需要把代码提交给微信进行审核。只能有一份代码处于审核中。有审核结果后可以发布到线上,也可直接重新提交审核,覆盖原审核版本。在 管理-版本管理 中,可以找到开发版本,点击提交审核。提交审核规则需要符合 小程序平台运营规范 open in new window。
线上版本 :线上所有用户使用的代码版本,该版本代码在新版本代码发布后被覆盖更新。
3. 开发经验
前后端交互开发时,咪咔项目使用 Apifox 来生成 API 文档和 Mock API,从而简化开发过程。以下是前后端交互的主要流程:
- 定义好产品所需功能。(产品经理负责)
- 为产品的每一项功能确定好技术实现方案(产品经理与技术总监讨论)
- 编写好 mock api 和 API 文档(后端开发)
- 根据 API 文档开发前端,而后使用 mock api 做测试。(前端开发)
- 编写 API 文档以及 mock api 的优点在于:前端后端的开发可以同时进行开发。等后端开发好全部 API 后,前端只需要替换掉 mock api 地址就可以进行测试了。同时团队也可以通过 API 文档来初步检测产品逻辑是否存在漏洞等。
- 前后端人员开发好后,进行产品测试与发布。
示例图片:咪咔相机 Airfox API 文档

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

当用户进入微信小程序时,首先会看到首页。首页展示咪咔相机生成的宠物 AI 照片,包含了两个主要模块:轮播图和下拉栏。
首页的实现逻辑如下:
- 图片存储在阿里云 OSS 上,图片 URL 地址存储在 PostgreSQL 数据库中。
- 前端通过调用
/api/v1/home/carousel
获取首页轮播图的链接,并展示给用户。

- 我的
我的页面中提供了充值,登录, 查看余额,联系客服等操作。
充值功能 :使用微信小程序内置的微信支付功能。用户完成支付后,数据库会自动更新用户余额。微信小程序调用微信支付: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。登录前,用户需要同意咪咔用户协议和微信隐私协议,用户协议全文由咪咔团队编写,隐私协议使用了微信提供的模板编写。

- 联系客服方案,咪咔采用了微信自带的客服助手,前端上开启客服助手后,客服人员可以在客服小助手小程序上看到用户的留言。
- 拍照页面
用户可以选择不同的拍照风格,点击后进入对应的风格页面。用户在选择拍摄风格后,前端会请求 /api/v1/pet/generate_image
API 生成宠物照片。照片生成后,用户可以查看并分享给微信好友。
用户点击某个风格后,会跳转到风格对应的页面,如点击口袋宝贝,会跳转到口袋宝贝页面,页面中包含了几张口袋宝贝的示例图片。
用户点击生成风格后,可以选择想要拍摄的宝贝,稍作等待后,一张口袋宝贝的 AI 相册就生成好了。

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

- 相册
用户提交拍照订单后,可在相册页面查看订单进度。正在生成中的照片会显示等待中的标志。
- 每隔一段时间,前端会检查图片状态并更新。
- 用户可以分享生成的图片,并且每日首次分享可获得奖励。
咪咔后台处理用户订单时,会将信息记录在阿里云 postgres 上。相册页面每隔一段时间,会往咪咔 API 发送请求,来检查用户宠物的图片状态是否改变,如果有改变的话,会更新对应的图片。

每个订单中,咪咔会为用户生成 4 张该风格的图片,用户可以点击分享图片,来将图片分享给微信好友。咪咔采用了微信自带的分享 SDK 来实现了这个功能。一个比较特殊的设定是,用户每日首次分享,可以获得 150 个小鱼干, 用户点击了分享按钮后,咪咔后台会自动为用户添加这 150 个小鱼干,而后再触发分享功能。
- 宠物档案
宠物档案功能主要用于创建与宠物相关的 Lora 模型。用户可以在宠物档案页面通过左右滑动来浏览自己的宠物档案。
当用户点击“添加宠物”按钮时,会被引导至档案创建页面。在此页面,用户需填写宠物的基本信息,如名字和类型,同时上传 12 至 16 张宠物照片用于 Lora 训练。

用户提交图片并点击“开始创建宠物档案”后,照片将被上传至阿里云 OSS,接着前端会向 api/v1/pet/train
API 发送请求。咪咔 API 首先会验证用户的 JWT token。验证成功后,系统将按照以下步骤执行:
- 在阿里云 PostgreSQL 数据库中添加对应的宠物数据(如名字、ID 等),并将宠物档案的状态设置为“队列中”(queue)。
- 将宠物 Lora 训练任务提交至消息队列(使用 RabbitMQ)。同时,系统将向用户发送一个订阅通知,用户点击同意后,便能在 Lora 训练完成时,第一时间收到微信服务消息的提醒。
- 本地 GPU 服务器将处理消息队列中的任务,并在处理过程中不断更新 PostgreSQL 中的档案状态。一旦 Lora 训练完成,后台 GPU 服务器会向用户发送微信服务消息。
- 用户最终会收到微信服务消息通知:【您的宝贝档案已生成】。

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

- 充值订单表 :记录用户充值金额和时间。
- 公告表 :用于发布和更新公告内容。
- 商品定价表 :储存各风格对应的价格。
- 宠物证件照表 :存储展示宠物档案页面的宠物图片。
- 训练示例图片表 :用户提交 Lora 训练时,需要上传 12-16 张宠物图片。咪咔提供合格图片和错误图片的示例。
- 首页图片表 :存储首页轮播图的图片链接。
- 首页风格图片表 :储存拍照页面所有风格的图片链接。
- 鱼干结算表 :记录用户的鱼干消费历史。
后端 API
咪咔的后端 API 采用FastAPI
框架来与前端进行交互,整体项目架构参考了FastAPI Full Stack 模板。API 与数据库的连接通过SQLAlchemy
实现,数据库迁移采用Alembic
,而 API 请求的头部验证则使用 JWT token。
部署流程如下:
- 注册域名并购买 SSL 证书。
- 将 API 服务打包为 Docker 镜像并部署在阿里云上。
- 配置域名解析到指定 IP 地址。
- 在微信小程序中,将域名添加到安全域名列表。
消息队列
咪咔采用 RabbitMQ 搭建消息队列服务,详细操作可参考[笔者的 RabbitMQ 博客文章](https://antarina.tech/posts/notes/articles/笔记 mq.html)。
咪咔设置了四个消息队列:
- default :处理普通任务。
- preprocess :处理图片预处理任务,如目标识别、像素优化(超分辨率)、图片拆分等。
- train :用于宠物档案制作(Lora 训练)。
- inference :用于 AI 照片生成(SD + Lora 推理)。
由于train
和inference
分布在不同设备上,Lora 训练任务完成后,训练好的 Lora 会上传到 OSS,inference
设备获取任务后,从 OSS 下载 Lora 进行推理。
在处理流程中,preprocess
、train
和inference
通常运行在不同设备上,因此preprocess
会先从 OSS 下载用户上传的图片,进行目标检测(识别猫狗)、像素优化、生成图片描述等操作,处理好的图片会重新上传至 OSS,描述信息通过消息存入队列中。
GPU 服务器
GPU 服务器主要用于 Lora 训练和图片生成。Lora 训练流程包括图片下载、数据库更新、目标检测、生成图片描述、Lora 训练、宠物档案照片生成等操作。咪咔使用 Airflow 对任务进行管理和调度:

在 Airflow 中,咪咔使用Celery
和RabbitMQ
来管理消息队列,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 的一些探索与验证。
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+ 个宠物档案顺利创建。

AI 相片生成
图片生成的操作比较简单:
- 下载 Lora: 从 OSS 上下载用户对应的 Lora。
- 下载风格参数: 从数据库获取用户所选风格的相关 prompt 和推理参数。
- 使用 SDXL + Lora 进行推理: 通过 SDXL 和 Lora 模型生成图片。
- 上传图片: 将生成的图片上传到 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 平台上,否则可能会出现数据和日志无法匹配的情况,导致无法查看日志。

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,独自把一个产品完整打造出来的过程。然而,完成咪咔之后,我发现,真正推动产品成功的,不仅仅是技术的实现,更是功能设计、营销推广、数据分析与运营管理的综合结果。技术是基础,但产品的灵魂在于如何通过设计和运营,让用户感受到价值与温度。
代码之外的世界更广阔,也更复杂。程序员可以成为优秀的产品创造者,但只有当他们开始理解市场、用户和情感,才能真正参与到好产品的创造中去。
领导者
“与一支出色的团队携手,打造一款卓越的产品。” 这令人向往的事,需要一个领导者带领。
领导者是能够激发他人、整合资源并引导团队实现共同目标的人。他们的职责不仅是完成任务,更重要的是塑造团队的整体方向和价值观,包括:
- 设定方向 :为团队提供清晰的愿景和战略。
- 影响他人 :通过个人魅力、信任和专业能力影响团队成员的行为。为团队提供一个积极、安全的工作氛围,让每个成员都能贡献自己的独特优势。
- 创造价值 :不仅关注目标结果,还注重实现过程中的学习、成长和可持续发展。
理想的领导者不仅仅是指挥者,更是激励者、倾听者和支持者。他们通过明确的愿景、以身作则和有效的沟通,帮助团队成员实现个人成长,同时推动集体的成功。
要成为一名优秀的领导者,需要具备多方面的能力,并不断反思与学习:
- 培养战略思维 优秀的领导者能够从整体上把握局势,设定清晰的目标和可行的计划。他们善于分析问题、评估风险,并为团队制定创新的解决方案。
- 提升人际沟通与情感智能 开放沟通和倾听能力是建立团队信任的基础。领导者需要通过同理心理解团队成员的需求,塑造支持性和包容性的工作环境。此外,学会用清晰的语言表达愿景和目标,让团队成员明确方向。
- 增强凝聚力与号召力 领导者应激励团队成员,为他们赋予归属感和共同愿景。同时,通过以身作则和榜样作用,激发团队的信心和动力。
- 优化组织与执行能力 将复杂任务合理分解,分配到合适的团队成员,并建立持续反馈机制,确保目标按时达成。同时,优秀的领导者具备很强的应急能力,在变化中快速调整策略,保证行动不脱轨。
- 坚持学习与自我提升 成为优秀的领导者需要持续的学习和反思。他们在实践中不断积累经验,并通过失败中汲取教训,持续优化自己的领导风格。
通过全面的能力发展和对团队价值的深刻理解,领导者可以不仅带领团队走向成功,还能创造一个鼓舞人心、充满信任和合作的工作环境,为团队成员的成长提供无限可能。