使用 Laf 一周内上线美术狮 AI 绘画小程序

“美术狮 AI 绘画”(以下简称“美术狮”),是我们小团队的一次尝试,定位是人人都可以上手的,充满创意的,理解中文和中国文化的图片生成工具。

在完善图像模型和论证核心问题之后,我们开始构建 MVP(最小化可行产品)。MVP 的构建需要:

  • 实现快,开发周期较短
  • 模式轻,产品重点突出
  • 成本低,只投入较少的人力、物力

这些目标,对于我们而言都是不小的挑战。得益于 Laf 的使用,从开发到第一个版本上线,只用了一周时间小程序功能精简、目标清晰;主体服务成本(杭州+新加坡)在 100 元 / 月以内(含有优化空间)。

下面会结合“美术狮”MVP 构建的全过程,和大家交流使用 Laf 这个平台(技术)的思考。

原文链接:https://forum.laf.run/d/984

技术选型过程

函数即服务,是目前我们对 Laf范式的思考和理解。也是“美术狮”选择 Laf 作为服务端的主要因素。

我在 2015 年就接触了“类似”的 BaaS 平台 LeanCloud,并做过两次实践。第一次是对爬取的小红书内容做维护,第二次是给一个中科院的朋友做化学试剂编号的管理。

LeanCloud,偏向于数据库即服务这种范式,对数据增删改查,提供基于数据的丰富的查询、聚合运算方法是这个范式的核心。

范式无优劣之分,取决于需要解决的问题场景、复杂度和规模。对于以数据库为中心的,包含简单鉴权的系统比如 CRM、甚至是 ERP,LeanCloud 都可以很好地适应和匹配。

我们还尝试和了解过主打实时性的野狗云(已下线),以及后来上线一段时间又被字节跳动下线的轻服务(已下线)。也尝试过跟着教程使用 Firebase

“美术狮”或者其他的 AI 应用的实际使用场景中,数据库的操作只是一个部分,复杂的内容生成逻辑、多平台资源调度、相对密集的计算是这类场景中的重心

小程序本身,虽然运行在客户端内拥有一定的计算能力,但是把它看作一个增强的 BS 结构通用性会更好,我们需要把大量地生成逻辑和计算处理流程剥离出来放在服务端由多平台协同完成;同时为了减小分发包的大小,当需要包含其他 SDK 文件时,我们也会格外谨慎

因此,数据库即服务,并不能很好地解决我们所面临的问题,可能并不是 AICG 应用优先会选择的范式。

腾讯云函数(Serverless)

接下来尝试了使用腾讯云函数,能满足了我们的一部分需求。

但是对于单次计算相对密集,调用资源繁多,访问量不稳定的应用而言。冷启动是可怕的,服务被冷却后,再一次被拉起来需要较长地等待时间。在并发和访问量不大时,云函数被频繁地冷却,对用户体验伤害较大,较为致命。这个对于每一个从 0 到 1 的独立开发者可能都是个头疼的问题。

对存储桶、数据库,腾讯云函数并没有做深度地整合,单独配置云数据库、存储桶,会在 MVP 阶段增加不必要的时间和费用的开销。

微信云开发

微信云开发可以通过微信开发者工具一键开通。在“美术狮”迁移的 Laf 之前,我们在微信云开发中做了大量的尝试。

放弃使用微信云开发,主要是下面一些原因:

  1. 基础库 Node 版本过低,对第三方包支持不好;
  2. IDE 开发体验不好,写代码像是看 PPT,本地调试不够方便直观;
  3. 计费系统诡异,虽然我们是腾讯云的老用户,小程序无法在原有账户中开通服务,必须以小程序的维度新开通账户,付费和管理维护不方便;
  4. 对跨区域、跨服务支持不佳;
  5. 冷启动延迟依然明显。

通过内置的鉴权机制快速获取 openid,是微信云开发宣称的优势。

在“美术狮”产品迁移后到 Laf 后,结合社区教程,也可以在“3 分钟”内,实现实现这些功能。

从 0 写一个微信小程序对接 Laf 云开发获取用户 openid - Sealos 开发者社区

Supabase、Vercel、Cloudflare

Verce、Cloudflare 是我特别喜欢的两个平台,这里一笔带过。主要原因是无法整合到国内的网络环境中。

最终我们选择了 Laf。在使用 Laf 的过程中,我们获得几乎等同于 Woker、EdgeFunction 的使用体验和开发效率。

为什么选择 Laf?

函数即服务

Laf 最吸引我们的,是通过云函数的构建应用的方式。

函数即服务在一定程度上,是可以包容(包含)数据库即服务这个范式的。

传统的 Server 端开发,通过 RouterController 去组织代码,利于管理和维护。但是,从另一个层面看,会在一定程度上,降低了 MVP 产品的开发效率,阻碍了创新的落地。

“美术狮”在第一个版本上线前半个小时,决定添加一个每日签到的功能。

通过云函数,我们更聚焦新特性、新功能,而不是困在这个签到功能应该放在哪个 Router 下,哪个 Controller 下这些工程管理的思考中。通过定义一个 task_user_daily_check_in,我们很快地实现了这个功能。

云函数调用云函数,是另外一个我喜欢的特性,我们定义了若干个“内部”云函数(同时关闭了所有 HTTP 方法),来为其他云函数服务。比如获取第三方服务的 access token 并在本地持久化。一方面,代码能够解耦和复用,另一方,安全性也大大提升。

例如这段代码,获取百度云服务的 access token ,关闭请求方法后,仅能被内部调用。

import cloud from '@lafjs/cloud'export default async function (ctx: FunctionContext) {const ret = await cloud.fetch({url: "https://aip.baidubce.com//oauth/2.0/token?",method: "get",params: {'grant_type': 'client_credentials','client_id': process.env.BAE_CLIENT_ID,'client_secret': process.env.BAE_CLIENT_SECRET},});cloud.shared.set('bae_access_tooen', ret.data.access_token)
}

当然,云函数过多后,仅能通过修改函数名去人为地调整云函数的排序,目录结构会显得凌乱,如果能按照 Tag(虚拟文件夹)去聚合、管理云函数,对我而言,会更清晰和直观。

技术栈友好

Laf 使用 TypescriptJavascript )进行开发,与 web 端、小程序开发属于同一技术栈。大大降低了全栈开发的难度,同时绝大多数代码可以在两端进行复用

在避免讨论“谁是世界上最好的编程语言”的前提下,仅从团队、成本、开发效率几个方面讨论,一致的技术栈是 MVP 开发的一个好选择。

良好地第三方支持

Laf 对 第三方 NPM 包的支持很好。我尝试过引用 moment 等这些第三方库处理时间数据,七牛等第三方服务处理图片资源,同时内置了大量常用的第三方库。

如同乐高拼图,云函数可以不断地、从不同维度地整合和丰富。存在大量第三方依赖的项目,迁移时成本较低。

实测,秒下各类第三方 NPM 包,精准版本控制,不需要“魔法”。

开箱即用的数据库

Laf 内置了对 Mongodb 的良好支持,提供了一个开箱即用的数据库。够用,好用

Laf 除了提供大量封装后的查询、聚合方法外,也提供了与原生 Mongo 交互的接口。

例如:通过与原生数据库交互创建索引。

import cloud from "@lafjs/cloud";
const db = cloud.database()export async function main(ctx: FunctionContext) {let res = await cloud.mongo.db.collection('users').createIndex({ "openid": 1})const resIndexs = await cloud.mongo.db.collection("users").indexes()return resIndexs
};

便利、直观的在线调试

在 Laf 中通过控制台、日志,可以完成绝大部分的调试工作。复杂一点的操作可以通过内置的极简的 Postman(接口调试)去完成。

这种极简、干练的风格贯穿 Laf 的功能(也包括上面提到的数据库设计)、UI,是我们 fancy Laf 的另一个重要原因。

实际的使用过程中,除了“存储”这个功能,其他所有的功能区,面板都能被我们高频地使用到。聚焦目标,专注效率,冗余度低

杭州、新加坡两地部署

在“美术狮”的开发过程中,我们在 laf.run(杭州)、laf.dev(新加坡)分别购买和部署了 Laf。多服务交融、跨区域的开发是一种奇妙的体验。

“美术狮”在图片的生成过程中,利用了腾讯云在新加坡的 GPU,图片的存储、优化又在国内完成,最终由七牛提供持久化和 CDN 服务。

Laf 在杭州与新加坡之间通信通畅,可用性高,与其他第三方平台能够完美地整合。

一键弹性伸缩

得益于同门的 Sealos 等项目和 Laf 在云计算方面的深耕,Laf 可以一键配置应用规格和弹性伸缩。

虽然,无数的产品默默地消失了,除非被 DDOS,很多产品很难触发弹性伸缩的条件(比如“美术狮”),但是梦想总是要有的。

短时间的高平发需要专业的运维,极快地做出水平拓展,对于小团队而言,在技术、资金方面都很难做到。Laf 很好地解决了这个后顾之忧,给我们提供了莫大的安全感,这个方面,我会在后面的部分继续补充。

开源、开放

Laf 与我使用过的其他 BaaS 不同,是一个开源项目。

之前有幸和 @ 马斯洛 有过一次对话,马老板是一个深邃、有远见的 Leader。

如果一个项目只隶属于一个公司,那么这个项目的命运大致会捆绑在这个公司的命运上。而一个项目属于社群,哪怕公司没有了,项目仍然能发展、完善。

开源的决定让 Laf 拥有了更长的生命周期和可靠性。用户再也不用担心像“轻服务”突然下线这种事情的发生,可以更放心地实践和使用平台和技术。

另外,不到万不得已,我不会去尝试部署 Laf 的服务。我有一堆自己的理由:

  1. 可靠和稳定能够节省更多的成本,自部署相当于自己承担服务的可靠性,很多人的专业性和运维能力并不足以完成这个工作;
  2. 项目的维护者们更了解项目,也能更好、更快地解决突发问题;
  3. Laf 的部分特性,是靠集群发挥的,购买和维护集群的成本会更高;
  4. 向开源项目付费、贡献代码,是对开发者很好地鼓励和支持。

良好用户运营和收费

在使用了 Laf 的过程中,曾遇到一个无法为文档创建索引的故障。@ 白夜 帮忙联系了 @ 马斯洛 后,很快解决了我的问题。绝大多数问题可以在文档和社区找到解答和代码片段

我们反馈过希望有一个“回收站”的功能。Laf 迭代更新后,回收站如期而至,作为用户,想法被倾听、尊重并实现真是一件开心的事情。

之前对 Laf 的配置缺乏了解,在后台调整了过高的配置。马老板 会把实际资源消耗情况和建议调整值告诉我,每一次沟通都能让我们感受到技术大牛的魅力和一颗为用户着想的心。

合计下来,价廉物美,比一台中等配置的云服务器性价比高很多,同时,我也不用担心可能会到来的流量高峰,我相信 Laf 专业的运维一定会解决“美术狮”未来会遇到的问题。

番外篇

我们是 Midjourney 和 SD 的忠实粉丝。“美术狮”这个名称是 GPT-4 出谋划策的,小程序 Logo 和部分图片资源也是由“美术狮”生成的。

在使用 Mid 和 SD 的过程中,我们发现两个问题:

  1. 准确的 Prompts 需要使用英文书写,特定的英文词汇需要记忆、积累(比如风格、镜头、视角等);
  2. Prompts 需要通过结构化排列,关键词的顺序也会影响出图质量,同时创作者需要具备一定的美术、摄影方面的专业素养。

身边能把 Mid 或者 SD 用好的人少之又少;一个是语言问题,一个是专业问题。

我们以 Dalle2 模型,作为训练起点,没错,就是画面惨不忍睹的 Dalle2,虽然如此,Dalle 是目前绘画模型中最懂自然语言的

Prompts 是文字,由图片 describe 出的 Tag 也是文字,语言文字是信息沟通最重要的媒介,大语言模型更是这次 AI 浪潮的基石。

我们通过 3 个多月,提升了“美术狮”对自然语言特别是中文的理解,让它更灵动、更懂你,尽管还有诸多不完美,过程中仍然带给我们许多惊喜。

我们团队在以后的实践中,会继续使用 Laf,使用 Laf 是快乐的事情。希望越来越多的人能够感受到 Laf 的魅力。也希望 Laf 明天会更好。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/119417.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在VSCode上画UML的三个插件

2023年9月2日,周六晚上 因为写代理模式的博客时需要画UML,所以就在网上找了半天, 最后觉得VSCode上的这三个插件比较好用 目录 三个画UML的VSCode插件PlantUMLDraw.io IntegrationUMLet我个人推荐使用PlantUML 三个画UML的VSCode插件 Pla…

肖sir__设计测试用例方法之场景法04_(黑盒测试)

设计测试用例方法之场景法 1、场景法主要是针对测试场景类型的,顾也称场景流程分析法。 2、流程分析是将软件系统的某个流程看成路径,用路径分析的方法来设计测试用例。根据流程的顺序依次进行组合,使得流程的各个分支能走到。 举例说明&…

Python开源项目月排行 2023年8月

#2023年8月2023年9月2日1facechain一款可以用于打造个人数字形象的深度学习模型工具。用户只需提供最低三张照片即可获得独属于自己的个人形象数字替身。FaceChain 支持在梯度的界面中使用模型训练和推理能力,也支持资深开发者使用 python 脚本进行训练推理。2Qwen-…

数学建模--二维插值函数模型的Python实现

目录 1.算法实现步骤 2.算法核心代码 3.算法效果展示 1.算法实现步骤 #二维插值函数的展示通过Axes3D函数来进行实现 #我们需要绘制出20*20的插值效果和500*500的插值效果,进行比较. 具体步骤如下所示: 1.将x-y分为20*20并且绘制网格图 2.进行20*20的插值计算并且绘制可视化图…

deque容器

1 deque容器基本概念 功能: 双端数组,可以对头端进行插入删除操作 deque与vector区别: vector对于头部的插入删除效率低,数据量越大,效率越低deque相对而言,对头部的插入删除速度回比vector快vector访问…

终端安全与端点保护:讨论保护终端设备免受恶意软件、恶意链接和其他威胁的方法,包括终端保护工具和实践

第一章:引言 在当今数字化世界中,终端设备如电脑、手机和平板成为我们生活与工作的不可或缺的一部分。然而,随着技术的进步,恶意软件、网络攻击和数据泄露等威胁也不断增加,对终端设备的安全提出了更高的要求。本文将…

Pinely Round 2 (Div. 1 + Div. 2) F. Divide, XOR, and Conquer(区间dp)

题目 给定长为n(n<1e4)的数组&#xff0c;第i个数为ai(0<ai<2的60次方) 初始时&#xff0c;区间为[1,n]&#xff0c;也即l1&#xff0c;rn&#xff0c; 你可以在[l,r)中指定一个k&#xff0c;将区间分成左半边[l,k]、右半边[k1,r] 1. 如果左半边异或和与异或和的异…

2023_Spark_实验三:基于IDEA开发Scala例子

一、创建一个空项目&#xff0c;作为整个项目的基本框架 二、创建SparkStudy模块&#xff0c;用于学习基本的Spark基础 三、创建项目结构 1、在SparkStudy模块下的pom.xml文件中加入对应的依赖&#xff0c;并等待依赖包下载完毕。 在pom.xml文件中加入对应的依赖 ​<!-- S…

CXL.cachemem 简介(背景通道)

&#x1f525;点击查看精选 CXL 系列文章&#x1f525; &#x1f525;点击进入【芯片设计验证】社区&#xff0c;查看更多精彩内容&#x1f525; &#x1f4e2; 声明&#xff1a; &#x1f96d; 作者主页&#xff1a;【MangoPapa的CSDN主页】。⚠️ 本文首发于CSDN&#xff0c…

4.0 Spring与Dubbo整合原理与源码分析

#Dubbo# 文章介绍 Dubbo中propertie文件解析以及处理原理Dubbo中@Service注解解析以及处理原理Dubbo中@Reference注解解析以及处理原理1.0 整体架构和流程 应用启动类与配置 public class Application {public static void main(String[] args) throws Exception {Annotation…

2023-9-3 筛质数

题目链接&#xff1a;筛质数 埃氏筛法 #include <iostream>using namespace std;const int N 1000010;int cnt; bool st[N];bool get_primes(int n) {for(int i 2; i < n; i ){if(!st[i]){cnt ;for(int j i i; j < n; j i) st[j] true;}} }int main() {int …

对Excel表中归类的文件夹进行自动分类

首先把excel表另存为.txt文件&#xff08;注意&#xff1a;刚开始可能是ANSI格式&#xff0c;需要转成UTF-8格式&#xff09;&#xff1b;再新建一个.txt文件&#xff0c;重命名成.bat文件(注意&#xff1a;直接创建的如果是是UTF-8格式&#xff0c;最好转成ANSI格式&#xff0…

AUTOSAR规范与ECU软件开发(实践篇)7.11 MCAL配置验证与代码生成

在配置完所需MCAL模块之后&#xff0c; 就可以进行配置验证与代码生成。MCAL配置工具的工具栏如图7.64所示。 其中&#xff0c; 右起第二个按钮为“Verify selected project”&#xff0c; 点击之后将进行配置验证。 右起第一个按钮为“Generate Code for the currently select…

二、Mycat2 相关概念及读写分离

第三章 Mycat2 相关概念 3.1 概念描述 1、分库分表 按照一定规则把数据库中的表拆分为多个带有数据库实例,物理库,物理表访问路 径的分表。 解读&#xff1a;分库&#xff1a;一个电商项目&#xff0c;分为用户库、订单库等等。 分表&#xff1a;一张订单表数据数百万&#xff…

ReactNative 井字游戏 实战

效果展示 需要的插件准备 此实战项目需要用到两个插件。 react-native-snackbar 底部信息提示组件。 react-native-vector-icons 图标组件。 安装组件&#xff1a; npm i react-native-snackbar npm i react-native-vector-icons npm i types/react-native-vector-icons /…

mysql:[Some non-transactional changed tables couldn‘t be rolled back]不支持事务

1. mysql创建表时默认引擎MyIsam&#xff0c;因此不支持事务的操作&#xff1b; 2. 修改mysql的默认引擎&#xff0c;可以使用show engine命令查看支持的引擎&#xff1a; 【my.conf详情说明】my.cnf配置文件注释详解_xiaolin01999的博客-CSDN博客 3. 原来使用MyIsam创建的表…

使用MDK5的一些偏僻使用方法和谋个功能的作用

程序下载后无法运行 需要勾选如下库&#xff0c;是优化后的库&#xff1b; MicroLib和标准C库之间的主要区别是: 1、MicroLib是专为深度嵌入式应用程序而设计的。 2、MicroLib经过优化&#xff0c;比使用ARM标准库使用更少的代码和数据内存。 3、MicroLib被设计成在没有操作…

stm32之28.ADC

须看原理图&#xff08;引脚、电压值、ADC几号通道&#xff09;配置 。 若对比值0~4096 模拟电压/参考电压4096/x 假设模拟电压2.1V&#xff0c;参考电压3.3v&#xff0c;4096/x3.3/2.1 ->3.3x2.1x4096 ->x2,606.5 也可反推出模拟电压 ADC转换时间 ADC时钟来源于…

【LeetCode每日一题合集】2023.8.14-2023.8.20(⭐切披萨3n块披萨)

文章目录 617. 合并二叉树833. 字符串中的查找与替换&#xff08;模拟&#xff09;2682. 找出转圈游戏输家&#xff08;模拟&#xff09;1444. 切披萨的方案数&#xff08;⭐⭐⭐⭐⭐&#xff09;解法——从递归到递推到优化&#xff08;二维前缀和记忆化搜索&#xff09; 1388…

【ag-grid-vue】列定义(Updating Column Definitions)

列定义一节解释了如何配置列。可以在初始设置列之后更改列的配置。本节介绍如何更新列定义。 添加和删除列 可以通过更新提供给网格的列定义列表来添加和删除列。当设置新列时&#xff0c;网格将与当前列进行比较&#xff0c;并计算出哪些列是旧的(要删除)、哪些列是新的(创建…