社会适老化建设,从一个 LLM 应用开始

devtools/2024/10/11 2:25:26/

引言

“变老很糟糕(Getting old sucks)”,这是电影《勇敢者的游戏》里的一句台词。变老会让人不再敏捷、健壮,会让人疲于跟上社会发展的脚步。据统计,截止 2023 年底,60 岁以上人口占全国总人口的 21.1%。若干年后,这个比重可能会更大,而我们自己也将成为构成这一比重的分子之一。如何帮助老年人活得更舒适一些?如何帮助若干年以后的我们自己?我最近在思考这些问题。

有一天下班路上,我刷到了一篇推文,宣布 Google 将举办以 ”科技向善” 为主题的黑客马拉松比赛,鼓励开发者基于 Gemma 模型技术来表达社会关怀。这几乎在一瞬间就激发了我的灵感 —— LLM 擅长处理大段文字,这不正适合用来帮老年人提升阅读体验吗?我有一些长辈,他们视力不好,还可能识字不全。当儿孙辈不在身边时,吃药之前读说明书往往是非常困难的事情。用大语言模型来处理药品说明书的文字内容,并以语音问答的形式来辅助理解,无论是从技术可行性还是用户友好性的角度来考虑,这似乎都非常通顺!

于是,在热爱编程和科技向善这双重精神动力的推动下,我和队友聆絮在 Google Gemma Hackathon 中完成了我们的作品 —— 药童,一个帮助爷爷奶奶们读懂药品说明书的 Web 应用。

如录屏视频所示,爷爷奶奶们只需要用手机拍下药品说明书,然后就可以像语音聊天一样了解药品的信息了。这样的极简交互,尽可能地降低了学习和操作成本,让用户可以即开即用。

接下来,我将会从技术实现层面拆解各个模块,希望其中的点滴也能激发你的灵感。你将会看到 OCR、RAG、ASR、TTS…… 啥啥啥?这都是些啥?别急,且听我娓娓道来。

技术实现

从用户上传照片,到回复用户的提问,其背后的处理流程是这样的:

在这里插入图片描述

  1. 从图片中提取文字内容;
  2. 将提取出的文本内容切分、向量化,存储到向量数据库中;
  3. 用户发送语音问题后,把语音转为文字格式;
  4. 将问题文本与向量数据库进行匹配,检索出高相关度的知识块;
  5. 将相关知识上下文与问题文本一起包装成提示词,发送给 LLM;
  6. LLM 根据提示词生成文本格式的回答内容;
  7. 将回答文本转化为语音,播放给用户听。

OCR:从图片提取文字

想要提取图片中的文字,有多种方式可以实现,我了解到的方向有两个:一个是经典的光学字符识别。处理过程的核心逻辑如下:

# 开启方向检测、设置语言
ocr = PaddleOCR(use_angle_cls=True, lang="ch")# 传入图片的文件路径
result = ocr.ocr(img, cls=True)# 逐行输出识别结果
for idx in range(len(result)):res = result[idx]for line in res:print('py_ocr_res', line[1][0])

得到识别结果后,将文本内容传递给向量化服务。

向量化存储

现在我们有了说明书文本内容,那么如何让 LLM 基于这些文本内容去回答用户的问题呢?

我们当然可以把说明书内容整个嵌在提示词里,要求 LLM 根据这些内容作答。但引发的问题就是,在每一轮对话中,LLM 都要处理全量的文本,会降低生成速度和质量,进而影响用户体验。因此,我们需要检索增强式生成(Retrieval-Augmented Generation,RAG),也就是把问题以及和问题相关度高的知识一起发送给 LLM,帮助 LLM 快速而准确地生成回答。

在这一环节,我们要先把通过 OCR 提取出来的文本进行处理,搭建一个知识库,以供后续问答时检索之用。我们借助 [LangChain] 框架来实现这一处理过程。

首先是切分文本。虽然一张照片内的说明书内容有限,篇幅不会过长,但是为了更快、更精准地匹配问题内容,我们还是要把整段文本切开成一个个小块。

import { RecursiveCharacterTextSplitter } from 'langchain/text_splitter';const splitter = new RecursiveCharacterTextSplitter({chunkSize: 1000,chunkOverlap: 100,
});const docs = await splitter.splitDocuments(ocrText);

然后,我们把切分好的文本块进行向量化(Embedding)处理,并存到向量数据库中:

import { OllamaEmbeddings } from '@langchain/community/embeddings/ollama';
import { MemoryVectorStore } from 'langchain/vectorstores/memory';const embedder = new OllamaEmbeddings({model: 'gemma2’ // 使用本地模型
});const store = await MemoryVectorStore.fromDocuments(docs, embedder);
const retriever = store.asRetriever();

在上面的 Embedding 逻辑中,我们使用了本地模型。你需要提前安装并启动 [Ollama],然后把一个模型下载到本地,如 ollama pull gemma2,就像拉取一个 npm 包一样简单。

至此,我们就把用于检索的知识库准备好了,可以开门迎接用户的提问了。

ASR:语音转文字

当用户用语音提问后,我们需要把音频内容转为文字,你可能在 HuggingFace 上看到过 ASR(Automatic Speech Recognition) 或者 STT(Speech to Text),指的都是这个转换过程。以下是核心逻辑:

import torch
from transformers import AutoModelForSpeechSeq2Seq, AutoProcessor, pipeline# 加载模型
model_id = "openai/whisper-base"
model = AutoModelForSpeechSeq2Seq.from_pretrained( model_id)
processor = AutoProcessor.from_pretrained(model_id)pipe = pipeline("automatic-speech-recognition",model=model,tokenizer=processor.tokenizer,feature_extractor=processor.feature_extractor,
)# 传入音频文件路径,生成文本
result = pipe(audio)
print('py_asr_res', result["text"])

得到用户问题的文本内容后,接下来就要进入到一个 LLM 应用的核心流程了。

RAG:检索生成

在这个环节,我们要做的是拿用户的提问内容去之前准备好的向量知识库里做相似性匹配,再把检索到的相关文本块与问题一起传送给 LLM,LLM 会根据提示词生成回答。

首先是组织提示词模板。我们参考 [LangChain Hub] 中的提示词,编写模板:

import { ChatPromptTemplate } from '@langchain/core/prompts';const prompt = ChatPromptTemplate.fromMessages([['system', `你是一个问答任务助手。使用下面 context 中的检索上下文来回答问题。如果你不知道答案,就直接回答不知道。最多用三句话回答。`],['placeholder', '{context}'],['user', '{question}']
]);

接着,我们引入本地 LLM:

import { ChatOllama } from '@langchain/community/chat_models/ollama';const model = new ChatOllama({model: 'gemma2',
});

由于 LLM 自有其特定的输出格式,我们还需要一个工具来把模型给出的回答解析成字符串:

import { StringOutputParser } from '@langchain/core/output_parsers';const parser = new StringOutputParser();

最后,我们要用链条把 promptmodelparser 串起来。什么?你说还没把问题和知识库做检索匹配?放松,LangChain 框架会帮我们处理这些,这正是「链条(chain)」的奥义!

import { RunnablePassthrough, RunnableSequence } from '@langchain/core/runnables';
import { formatDocumentsAsString } from 'langchain/util/document’;const ragChain = RunnableSequence.from([{question: new RunnablePassthrough(),context: retriever.pipe(formatDocumentsAsString), // retriever 就是此前生成的知识库},prompt,model,parser,
]);

我们只需要执行这个链条,就可以坐等 LLM 输出答案了:

const output = await ragChain.invoke(userQuestionFromASR);

TTS:文本转语音

现在,我们只需要把文本格式的回答内容给转成语音,然后播放给用户听即可:

import ChatTTSchat = ChatTTS.Chat()if chat.load():pass
else:sys.exit(1)wavs = chat.infer(texts, use_decoder=True)# 保存音频为 .mp3 文件
for index, wav in enumerate(wavs):save_mp3_file(wav, index)

大功告成!!!

其他

我们使用了 [Nuxt] 搭建了这个 Web App 的前后端,上述的 OCR、ASR、TTS 都串联其中,非常方便!

GUI 方面,我们使用了 [LangUI]这个 TailwindCSS 组件库,找到想用的组件,直接复制粘贴代码就行了,非常方便 +1!

我和队友都是前端工程师,我们本着「应 JS 尽 JS」的信条,在作品中最大限度地用 Web 技术栈来实现功能。前端切图仔没在怕的,非常自豪!

规划和展望

「药童」这个作品,在 Gemma Hackathon 中得到了评委的认可,在故事性、创造性、实用性三个维度的总得分名列第二。这印证了我们的创意和理念确实有其价值。

人工智能能力突飞猛进的今天,我们很容易就能感受到 AI 技术的强大力量,也都在积极乐观地畅想它将在各个领域掀起变革。然而在这样的狂欢氛围中,我们也可能很容易就忽略了那些身处热潮之外的社会群体,忽略了一点点巧妙的技术应用就能给他们带来帮助。技术可以在高空中绽放出绚烂夺目的光芒,也同样可以在细微处散发温热,暖人心窝。作为驾驭技术的人,我们开发者的目光要投向哪里,这至关重要。

以现实的眼光来审视,「药童」也许不太能够产生商业价值。但我会把它从一个 demo 级别的比赛作品,逐步完善成一个完整可用的实际产品。而距离一个成熟产品,它还有些技术性问题需要解决、优化,比如提升响应速度、支持多轮对话、固定音色、云端部署等等。我会发挥 Web 技术的灵活优势,「药童」可以是微信小程序、网页或任何形态,可以读药品说明书、家电说明书或任何文字内容,我会送它到需要它的地方去。我会延续初心,尽我所能用技术提供帮助,哪怕用户群体再少、应用场景再窄。

科技向善,虽小亦可为之。

在这里插入图片描述

大模型&AI产品经理如何学习

求大家的点赞和收藏,我花2万买的大模型学习>大模型学习资料免费共享给你们,来看看有哪些东西。

1.学习路线图

在这里插入图片描述

第一阶段: 从大模型系统设计入手,讲解大模型的主要方法;

第二阶段: 在通过大模型提示词工程从Prompts角度入手更好发挥模型的作用;

第三阶段: 大模型平台应用开发借助阿里云PAI平台构建电商领域虚拟试衣系统;

第四阶段: 大模型知识库应用开发以LangChain框架为例,构建物流行业咨询智能问答系统;

第五阶段: 大模型微调开发借助以大健康、新零售、新媒体领域构建适合当前领域大模型

第六阶段: 以SD多模态大模型为主,搭建了文生图小程序案例;

第七阶段: 以大模型平台应用与开发为主,通过星火大模型,文心大模型等成熟大模型构建大模型行业应用。

2.视频教程

网上虽然也有很多的学习资源,但基本上都残缺不全的,这是我自己整理的大模型视频教程,上面路线图的每一个知识点,我都有配套的视频讲解。

在这里插入图片描述

在这里插入图片描述

(都打包成一块的了,不能一一展开,总共300多集)

因篇幅有限,仅展示部分资料,需要点击下方图片前往获取

3.技术文档和电子书

这里主要整理了大模型相关PDF书籍、行业报告、文档,有几百本,都是目前行业最新的。
在这里插入图片描述

4.LLM面试题和面经合集

这里主要整理了行业目前最新的大模型面试题和各种大厂offer面经合集。
在这里插入图片描述

👉学会后的收获:👈
• 基于大模型全栈工程实现(前端、后端、产品经理、设计、数据分析等),通过这门课可获得不同能力;

• 能够利用大模型解决相关实际项目需求: 大数据时代,越来越多的企业和机构需要处理海量数据,利用大模型技术可以更好地处理这些数据,提高数据分析和决策的准确性。因此,掌握大模型应用开发技能,可以让程序员更好地应对实际项目需求;

• 基于大模型和企业数据AI应用开发,实现大模型理论、掌握GPU算力、硬件、LangChain开发框架和项目实战技能, 学会Fine-tuning垂直训练大模型(数据准备、数据蒸馏、大模型部署)一站式掌握;

• 能够完成时下热门大模型垂直领域模型训练能力,提高程序员的编码能力: 大模型应用开发需要掌握机器学习算法、深度学习框架等技术,这些技术的掌握可以提高程序员的编码能力和分析能力,让程序员更加熟练地编写高质量的代码。
在这里插入图片描述

1.AI大模型学习>大模型学习路线图
2.100套AI大模型商业化落地方案
3.100集大模型视频教程
4.200本大模型PDF书籍
5.LLM面试题合集
6.AI产品经理资源合集

👉获取方式:
😝有需要的小伙伴,可以保存图片到wx扫描二v码免费领取【保证100%免费】🆓

在这里插入图片描述


http://www.ppmy.cn/devtools/110067.html

相关文章

【Redis】redis5种数据类型(string)

目录 redis5种数据类型和内部编码方式 redis单线程模型 string字符串类型相关命令 SET GET MSET MGET SETNX SETEX ​编辑PSETEX value值为整数,进行加减操作 INCR INCRBY DECR DECRBY INCRBYFLOAT APPEND GETRANGE SETRANGE STRLEN string的…

在stable diffussion中完美修复AI图片

无论您的提示和模型有多好,一次性获得完美图像的情况很少见。 修复小缺陷的不可或缺的方法是图像修复(inpainting)。在这篇文章中,我将通过一些基本示例来介绍如何使用图像修复来修复缺陷。 需要的软件 我们将使用 AUTOMATIC11…

【JAVA】第五天

【JAVA】第五天 一、Math类二、System类三、Runtime类四、BigDecimal类五、JDK8之前传统的日期、时间(不推荐)1.Date类2.SimpleDateFormat类3.Calendar类 六、JDK8之后新增的日期、时间1.LocalDateTime类2.ZoneId类3.ZonedDateTime类4.Instant类5.DateTi…

Leetcode面试经典150题-55.跳跃游戏

解法都在代码里,不懂就留言或者私信 class Solution {public boolean canJump(int[] nums) {/**如果就一个位置,你本来就在这,肯定可以跳到*/if(nums.length 1) {return true;}/**这个题的解题思路是遍历数组,如果当前位置不在之…

【SRC】某次众测绕过限制注册用户+敏感信息泄露漏洞

吉祥知识星球http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247485367&idx1&sn837891059c360ad60db7e9ac980a3321&chksmc0e47eebf793f7fdb8fcd7eed8ce29160cf79ba303b59858ba3a6660c6dac536774afb2a6330&scene21#wechat_redirect 《网安面试指南》…

再见Java 8,请掌握最新LTS

简介 在Java开发中,Java 8曾经是无可争议的主流,凭借其稳定性和广泛的社区支持,陪伴了无数开发者走过多年辉煌时刻。然而,随着时间的推移,技术不断革新,企业和开发者们逐渐把目光投向了更新的LTS&#xff0…

磁盘映射(C语言)

目录 一、背景介绍 二、磁盘映射技术概述 1.磁盘映射原理 2.磁盘映射的优势 三、C语言实现磁盘映射 磁盘映射技术在C语言中的应用能够极大地提高文件操作的效率。本文将详细介绍磁盘映射的概念、如何在C语言中实现磁盘映射,并通过实际案例展示其在文件读写、数据…

Leetcode面试经典150题-76.最小覆盖子串

解法都在代码里&#xff0c;不懂就留言或者私信 理论上提交这个就是最优解 class Solution {public String minWindow(String s, String t) {if(s.length() < t.length()) {return "";}/**转成字符数组 */char[] sArr s.toCharArray();char[] tArr t.toCharAr…