1.背景
欢迎数据库应用开发者参与贡献场景, 在此issue回复即可, 共同建设《沉浸式数据库学习教学素材库》, 帮助开发者用好数据库, 提升开发者职业竞争力, 同时为企业降本提效.
- 系列课程的核心目标是教大家怎么用好数据库, 而不是怎么运维管理数据库、怎么开发数据库内核. 所以面向的对象是数据库的用户、应用开发者、应用架构师、数据库厂商的产品经理、售前售后专家等角色.
本文的实验可以使用永久免费的阿里云云起实验室来完成.
如果你本地有docker环境也可以把镜像拉到本地来做实验:
x86_64机器使用以下docker image:
ARM机器使用以下docker image:
2.业务场景1 介绍: 植入通义千问大模型+文本向量化模型, 让数据库具备AI能力
开源的大模型非常多, 但是都需要大的算力才能高效的发挥大模型的能力, 以及训练各领域专业的大模型. 普通个人甚至企业很难独自构建及训练大模型.
为了让大模型可以更加普惠企业及大众的需求, 阿里云推出了DashScope灵积. 可以理解为模型集市, 每个模型都有其独有的特点, 而且每一种模型都提供了API接口, 使得任何人都可以调用大模型的算力.
什么和大模型结合将发挥重大的价值? 毫无疑问是数据. 例如:
- 1、通过数据来训练大模型.
- 2、通过大模型分析数据, 帮助企业进行决策.
- 3、通过大模型理解数据, 例如帮助企业解决客户和伙伴提出的问题, 提升产品体验.
这个实验将带领大家来体验一下如何将“千问大模型+文本向量化模型”植入到PG|PolarDB中, 让数据库具备AI能力.
2.1实现和对照
1、模型服务灵积总览
DashScope灵积,旨在通过灵活、易用的模型API服务,让业界各个模态的模型能力,能方便触达AI开发者。
通过灵积API,丰富多样化的模型不仅能通过推理接口被集成,也能通过训练微调接口实现模型定制化,让AI应用开发更灵活,更简单!
https://dashscope.console.aliyun.com/overview
2、可以先在web界面体验各种模型
3、进入控制台, 开通通义千问大模型+文本向量化模型
https://dashscope.console.aliyun.com/overview
4、创建API-KEY, 调用api需要用到key. 调用非常便宜, 一次调用不到1分钱, 学习几乎是0投入.
https://dashscope.console.aliyun.com/apiKey
5、因为灵积是个模型集市, 我们可以看到这个集市当前支持的所有模型:
https://dashscope.console.aliyun.com/model
支持大部分开源模型, 以及通义自有的模型. 分为三类: aigc, embeddings, audio.
5.1、aigc 模型
通义千问:
- 通义千问是一个专门响应人类指令的大模型,是一个灵活多变的全能型选手,能够写邮件、周报、提纲,创作诗歌、小说、剧本、coding、制表、甚至角色扮演。
Llama2大语言模型:
- Llama2系列是来自Meta开发并公开发布的的大型语言模型(LLMs)。该系列模型提供了多种参数大小(7B、13B和70B等),并同时提供了预训练和针对对话场景的微调版本。
百川开源大语言模型:
- 百川开源大语言模型来自百川智能,基于Transformer结构,在大约1.2万亿tokens上训练的70亿参数模型,支持中英双语。
通义万相系列:
- 通义万相是基于自研的Composer组合生成框架的AI绘画创作大模型,提供了一系列的图像生成能力。支持根据用户输入的文字内容,生成符合语义描述的不同风格的图像,或者根据用户输入的图像,生成不同用途的图像结果。通过知识重组与可变维度扩散模型,加速收敛并提升最终生成图片的效果。图像结果贴合语义,构图自然、细节丰富。支持中英文双语输入。当前包括通义万相-文生图,和通义万相-人像风格重绘模型。
StableDiffusion文生图模型:
- StableDiffusion文生图模型将开源社区stable-diffusion-v1.5版本进行了服务化支持。该模型通过clip模型能够将文本的embedding和图片embedding映射到相同空间,从而通过输入文本并结合unet的稳定扩散预测噪声的能力,生成图片。
ChatGLM开源双语对话语言模型:
- ChatGLM开源双语对话语言模型来自智谱AI,在数理逻辑、知识推理、长文档理解上均有支持。
智海三乐教育大模型:
- 智海三乐教育大模型由浙江大学联合高等教育出版社、阿里云和华院计算等单位共同研制。该模型是以阿里云通义千问70亿参数与训练模型为基座,通过继续预训练和微调等技术手段,利用核心教材、领域论文和学位论文等教科书级高质量语料,结合专业指令数据集,训练出的一款专注于人工智能专业领域教育的大模型,实现了教育领域的知识强化和教育场景中的能力升级。
姜子牙通用大模型:
- 姜子牙通用大模型由IDEA研究院认知计算与自然语言研究中心主导开源,具备翻译、编程、文本分类、信息抽取、摘要、文案生成、常识问答和数学计算等能力。
Dolly开源大语言模型:
- Dolly开源大语言模型来自Databricks,支持脑暴、分类、问答、生成、信息提取、总结等能力。
BELLE开源中文对话大模型:
- BELLE是一个基于LLaMA二次预训练和调优的中文大语言模型,由链家开发。
MOSS开源对话语言模型:
- MOSS开源对话语言模型来自复旦大学OpenLMLab项目,具有指令遵循能力、多轮对话能力、规避有害请求能力。
元语功能型对话大模型V2:
- 元语功能型对话大模型V2是一个支持中英双语的功能型对话语言大模型,由元语智能提供。V2版本使用了和V1版本相同的技术方案,在微调数据、人类反馈强化学习、思维链等方面进行了优化。
BiLLa开源推理能力增强模型:
- BiLLa是一种改良的开源LLaMA模型,特色在于增强中文推理能力。
5.2、embeddings,
通用文本向量:
- 基于LLM底座的统一向量化模型,面向全球多个主流语种,提供高水准的向量服务,帮助用户将文本数据快速转换为高质量的向量数据。
ONE-PEACE多模态向量表征:
- ONE-PEACE是一个通用的图文音多模态向量表征模型,支持将图像,语音等多模态数据高效转换成Embedding向量。在语义分割、音文检索、音频分类和视觉定位几个任务都达到了新SOTA表现,在视频分类、图像分类图文检索、以及多模态经典benchmark也都取得了比较领先的结果。
5.3、audio,
Sambert语音合成:
- 提供SAMBERT+NSFGAN深度神经网络算法与传统领域知识深度结合的文字转语音服务,兼具读音准确,韵律自然,声音还原度高,表现力强的特点。
Paraformer语音识别;
- 达摩院新一代非自回归端到端语音识别框架,可支持音频文件、实时音频流的识别,具有高精度和高效率的优势,可用于客服通话、会议记录、直播字幕等场景。
6、通义千问模型的API:
https://help.aliyun.com/zh/dashscope/developer-reference/api-details
调用举例:
6.1、通过curl调用api. 请把以下API-KEY代替成你申请的api-key.
curl --location 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation' --header 'Authorization: Bearer API-KEY' --header 'Content-Type: application/json' --data '{ "model": "qwen-turbo", "input":{ "messages":[ { "role": "system", "content": "你是达摩院的生活助手机器人。" }, { "role": "user", "content": "请将这句话翻译成英文: 你好,哪个公园距离我最近?" } ] }, "parameters": { } }'
{"output":{"finish_reason":"stop","text":"Hello, which park is closest to me?"},"usage":{"output_tokens":9,"input_tokens":50},"request_id":"697063a4-a144-9c17-8b6c-bc26895c1ea4"}
curl --location 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation' --header 'Authorization: Bearer API-KEY' --header 'Content-Type: application/json' --data '{ "model": "qwen-turbo", "input":{ "messages":[ { "role": "system", "content": "你是达摩院的生活助手机器人。" }, { "role": "user", "content": "你好,哪个公园距离我最近?" } ] }, "parameters": { } }'
{"output":{"finish_reason":"stop","text":"你好!你可以查看你的地图,或者我可以为你提供附近公园的信息。你想查看哪个地区的公园?"},"usage":{"output_tokens":39,"input_tokens":39},"request_id":"c877aa58-883b-9942-97a5-576d3098e697"}
6.2、通过python调用api:
安装python sdk:
pip install dashscope
创建一个保存api key的文件:
请把以下API-KEY代替成你申请的api-key.
su - postgres mkdir ~/.dashscope echo "API-KEY" > ~/.dashscope/api_key chmod 500 ~/.dashscope/api_key
然后编辑一个python文件
vi a.py
#coding:utf-8 from http import HTTPStatus from dashscope import Generation def call_with_messages(): messages = [{'role': 'system', 'content': '你是达摩院的生活助手机器人。'}, {'role': 'user', 'content': '如何做西红柿鸡蛋?'}] gen = Generation() response = gen.call( Generation.Models.qwen_turbo, messages=messages, result_format='message', # set the result is message format. ) if response.status_code == HTTPStatus.OK: print(response) else: print('Request id: %s, Status code: %s, error code: %s, error message: %s'%( response.request_id, response.status_code, response.code, response.message )) if __name__ == '__main__': call_with_messages()
调用结果如下:
root@c4012a5576b6:~# python3 a.py {"status_code": 200, "request_id": "00a5f4f2-d05b-9829-b938-de6e6376ef51", "code": "", "message": "", "output": {"text": null, "finish_reason": null, "choices": [{"finish_reason": "stop", "message": {"role": "assistant", "content": "做西红柿鸡蛋的步骤如下:\n\n材料:\n- 西红柿 2 个\n- 鸡蛋 3 个\n- 葱 适量\n- 蒜 适量\n- 盐 适量\n- 生抽 适量\n- 白胡椒粉 适量\n- 糖 适量\n- 水淀粉 适量\n\n步骤:\n1. 西红柿去皮,切成小块,鸡蛋打散,葱切末,蒜切片。\n2. 锅中放油,倒入葱末和蒜片炒香。\n3. 加入西红柿块,翻炒至软烂。\n4. 加入适量的盐、生抽、白胡椒粉和糖,继续翻炒均匀。\n5. 倒入适量的水,煮开后转小火炖煮 10 分钟左右。\n6. 鸡蛋液倒入锅中,煮至凝固后翻面,再煮至另一面凝固即可。\n7. 最后加入适量的水淀粉,翻炒均匀即可出锅。\n\n注意事项:\n- 西红柿去皮时可以用刀划十字,然后放入开水中烫一下,皮就很容易去掉了。\n- 煮西红柿鸡蛋时,要注意小火慢炖,以免西红柿的营养成分流失。\n- 鸡蛋液倒入锅中时要快速翻面,以免蛋液凝固后不易翻面。"}}]}, "usage": {"input_tokens": 35, "output_tokens": 328}}
7、通用文本向量的API:
https://help.aliyun.com/zh/dashscope/developer-reference/text-embedding-quick-start
调用举例:
vi b.py
#coding:utf-8 import dashscope from http import HTTPStatus from dashscope import TextEmbedding def embed_with_list_of_str(): resp = TextEmbedding.call( model=TextEmbedding.Models.text_embedding_v1, # 最多支持25条,每条最长支持2048tokens input=['风急天高猿啸哀', '渚清沙白鸟飞回', '无边落木萧萧下', '不尽长江滚滚来']) if resp.status_code == HTTPStatus.OK: print(resp) else: print(resp) if __name__ == '__main__': embed_with_list_of_str()
调用结果如下:
# python3 b.py { "status_code": 200, // 200 indicate success otherwise failed. "request_id": "fd564688-43f7-9595-b986-737c38874a40", // The request id. "code": "", // If failed, the error code. "message": "", // If failed, the error message. "output": { "embeddings": [ // embeddings { "embedding": [ // one embedding output -3.8450357913970947, ..., 3.2640624046325684 ], "text_index": 0 // the input index. } ] }, "usage": { "total_tokens": 3 // the request tokens. } }
2.2传统方法 设计和实验
传统数据库的数据库内置编程语言的支持比较受限, 通常只支持SQL接口. 无法直接使用通义千问大模型+文本向量化模型的能力.
2.3PolarDB|PG新方法1 设计和实验
PG|PolarDB 数据库内置支持开放的编程语言接口, 例如python, lua, rust, go, java, perl, tcl, c, ... 等等.
PG|PolarDB 通过内置的编程接口, 可以实现数据库端算法能力的升级, 将算法和数据尽量靠近, 避免了大数据分析场景move data(移动数据)带来的性能损耗.
连接到数据库shell, 创建plpython3u插件, 让你的PG|PolarDB支持python3编写数据库函数和存储过程.
psql create extension plpython3u;
1、创建aigc函数, 让数据库具备了ai能力.
create or replace function aigc (sys text, u text) returns jsonb as $$ #coding:utf-8 from http import HTTPStatus from dashscope import Generation messages = [{'role': 'system', 'content': sys}, {'role': 'user', 'content': u}] gen = Generation() response = gen.call( Generation.Models.qwen_turbo, messages=messages, result_format='message', # set the result is message format. ) if response.status_code == HTTPStatus.OK: return (response) else: return('Request id: %s, Status code: %s, error code: %s, error message: %s'%( response.request_id, response.status_code, response.code, response.message )) $$ language plpython3u strict;
调用举例
postgres=# select * from aigc ('你是达摩院的AI机器人', '请介绍一下PolarDB数据库'); -[ RECORD 1 ]----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- aigc | {"code": "", "usage": {"input_tokens": 27, "output_tokens": 107}, "output": {"text": null, "choices": [{"message": {"role": "assistant", "content": "PolarDB是阿里巴巴达摩院自主研发的大规模分布式数据库,具有高性能、高可用、高安全等特点。它采用了多种技术手段,如分布式存储、分布式计算、数据分片、熔断和降级策略等,可以支持大规模的互联网应用场景,如搜索引擎、推荐系统、金融服务等。"}, "finish_reason": "stop"}], "finish_reason": null}, "message": "", "request_id": "fd9cce79-6c48-9a9d-85f3-ff1a75bdd480", "status_code": 200} postgres=# select * from aigc ('你是达摩院的AI机器人', '请介绍一下PolarDB数据库'); -[ RECORD 1 ]-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- aigc | {"code": "", "usage": {"input_tokens": 32, "output_tokens": 89}, "output": {"text": null, "choices": [{"message": {"role": "assistant", "content": "PolarDB是阿里巴巴达摩院自主研发的大规模分布式数据库,具有高性能、高可用、高安全和高性价比等特点。它提供了基于存储引擎的分布式数据库服务,支持大规模数据处理和存储,并具有灵活的数据模型和可视化工具。"}, "finish_reason": "stop"}], "finish_reason": null}, "message": "", "request_id": "89c1944f-8af3-98b3-b29c-be6365f93be0", "status_code": 200}
2、创建embeddings函数, 将文本转换为高维向量.
create or replace function embeddings (v text[]) returns jsonb as $$ #coding:utf-8 import dashscope from http import HTTPStatus from dashscope import TextEmbedding resp = TextEmbedding.call( model=TextEmbedding.Models.text_embedding_v1, # 最多支持25条,每条最长支持2048tokens input=v) if resp.status_code == HTTPStatus.OK: return(resp) else: return(resp) $$ language plpython3u strict;
调用举例
select * from embeddings(array['风急天高猿啸哀', '渚清沙白鸟飞回', '无边落木萧萧下', '不尽长江滚滚来']);
embeddings | {"code": "", "usage": {"total_tokens": 26}, "output": {"embeddings": [{"embedding": [1.5536729097366333, -2.237586736679077, 1.5397623777389526, -2.3466579914093018, 3.8610622882843018, -3.7406601905822754, 5.18358850479126, -3.510655403137207, -1.6014689207077026, 1.427549958229065, -0.2841898500919342, 1.5892903804779053, 2.501269578933716, -1.3760199546813965, 1.7949544191360474, 4.667146682739258, 1.3320773839950562, 0.9477484822273254, -0.5237250328063965, 0.39169108867645264, 2.19018292427063, -0.728808581829071, -4.056122303009033, -0.9941840171813965, 0.17097677290439606, 0.9370659589767456, 3.515345573425293, 1.594552993774414, -2.249598503112793, -2.8828775882720947, -0.4107910096645355, 1.3968369960784912, -0.9533745646476746, 0.5825737714767456, -2.484375, -0.8761881589889526, 0.23088650405406952, -0.679530143737793, -0.1066826730966568, 0.5604587197303772, -1.9553602933883667, 2.2253689765930176, -1.8178277015686035, 1.239439606666565, -2.509045362472534, 4.812849998474121, -0.9741482138633728, -1.5405707359313965, 1.9682672023773193, 1.456263542175293, -0.8751180171966553, -0.24127332866191864, -0.06615668535232544, -1.5475884675979614, 2.104649543762207, -0.7037163376808167, -1.1802300214767456, 1.0072576999664307, 1.4229166507720947, 0.2779161334037781, 1.5448310375213623, -1.4548231363296509, 0.3061252236366272, 1.1501736640930176, -1.4284504652023315, -0.03127169981598854, ... , -2.3609619140625, -5.0784735679626465, -0.7559727430343628, -2.1915957927703857, -0.9280264973640442, 0.3727504312992096, 1.1043483018875122, -2.7951748371124268, -0.4858747124671936, -1.2777355909347534, -2.6889126300811768, 1.2386366128921509, 0.8004150390625, 2.154628276824951, -1.7855726480484009, -1.9051687717437744], "text_index": 3}]}, "message": "", "request_id": "8c45f0ab-366b-9941-9358-063e46009929", "status_code": 200}
获取第一条即"风急天高猿啸哀"的向量:
select x->'output'->'embeddings'->0->>'embedding' from embeddings(array['风急天高猿啸哀', '渚清沙白鸟飞回', '无边落木萧萧下', '不尽长江滚滚来']) x;
第二条向量:
select x->'output'->'embeddings'->1->>'embedding' from embeddings(array['风急天高猿啸哀', '渚清沙白鸟飞回', '无边落木萧萧下', '不尽长江滚滚来']) x;
现在你在数据库中直接通过SQL就可以获得AI能力.
更多用法请参考通义千问和通用文本向量模型相应api.
- https://help.aliyun.com/zh/dashscope/developer-reference/api-details
- https://help.aliyun.com/zh/dashscope/developer-reference/text-embedding-quick-start
2.4对照
1、传统数据库的数据库内置编程语言的支持比较受限, 通常只支持SQL接口.
2、PG|PolarDB 数据库内置支持开放的编程语言接口, 例如python, lua, rust, go, java, perl, tcl, c, ... 等等.
3、PG|PolarDB 通过内置的编程接口, 可以实现数据库端算法能力的升级, 将算法和数据尽量靠近, 避免了大数据分析场景move data(移动数据)带来的性能损耗.
例如postgresml, madlib等插件, 都是通过plpython来集成大量python的数据分析函数库, 提升数据库端的算法能力.
还有大量c, rust写的PG|PolarDB开源插件, 在github可以找到.
3.知识点
大模型
向量
向量索引
求2个向量的距离
数据库函数语言
jsonb
array
4.思考
1、数据库集成了各种编程语言之后, 优势是什么?
2、大模型和数据结合, 能干什么?
3、数据库中存储了哪些数据? 这些数据代表的业务含义是什么? 这些数据有什么价值?
4、高并发小事务业务场景和低并发大量数据分析计算场景, 这两种场景分别可以用大模型和embedding来干什么?
5、数据库中如何存储向量? 如何加速向量相似搜索?
5.参考
https://help.aliyun.com/zh/dashscope/api-reference
- 《制作 PostgresML docker 镜像》
- 《PostgresML=模型集市+向量数据库+自定义模型 : 用postgresml体验AI应用(图像搜索、推荐系统和自然语言处理)与向量检索》
- 《postgresML - end-to-end machine learning system》
- 《沉浸式学习PostgreSQL|PolarDB 9: AI大模型+向量数据库, 提升AI通用机器人在专业领域的精准度, 完美诠释柏拉图提出的“知识是回忆而不是知觉”》
- 《沉浸式学习PostgreSQL|PolarDB 8: 电商|短视频|新闻|内容推荐业务(根据用户行为推荐相似内容)、监控预测报警系统(基于相似指标预判告警)、音视图文多媒体相似搜索、人脸|指纹识别|比对 - 向量搜索应用》
- 《标准知识库 + PostgreSQL或PolarDB + 向量插件 + openai(或其他大模型) 提升通用ai机器人在专业领域的精准度》
- 《PostgreSQL 或PolarDB 使用插件pg_tiktoken - 使用 OpenAI tiktoken库文本向量化(tokenization) - 使用分词算法BPE - NLP 自然语言处理》