PostgreSQL码农集散地

数据库实验手册系列:16 植入通义千问大模型+文本向量化模型, 让数据库具备AI能力

文章开始前推荐2个学习环境: 

1、欢迎使用镜像快速体验PostgreSQL/DuckDB强大功能:《最好的PostgreSQL学习镜像》

2、欢迎使用云起实验室: 《免费体验PolarDB开源数据库》

3、PolarDB开源数据库内核、应用等学习图谱:  https://www.aliyun.com/database/openpolardb/activity 

标签

PostgreSQL , PolarDB , 数据库 , 教学


背景

欢迎数据库应用开发者参与贡献场景, 在此issue回复即可, 共同建设《沉浸式数据库学习教学素材库》, 帮助开发者用好数据库, 提升开发者职业竞争力, 同时为企业降本提效.

  • 系列课程的核心目标是教大家怎么用好数据库, 而不是怎么运维管理数据库、怎么开发数据库内核. 所以面向的对象是数据库的用户、应用开发者、应用架构师、数据库厂商的产品经理、售前售后专家等角色.

本文的实验可以使用永久免费的阿里云云起实验室来完成.

如果你本地有docker环境也可以把镜像拉到本地来做实验:

x86_64机器使用以下docker image:

  • 《amd64 image》

ARM机器使用以下docker image:

  • 《arm64 image》

业务场景1 介绍: 植入通义千问大模型+文本向量化模型, 让数据库具备AI能力

开源的大模型非常多, 但是都需要大的算力才能高效的发挥大模型的能力, 以及训练各领域专业的大模型. 普通个人甚至企业很难独自构建及训练大模型.

为了让大模型可以更加普惠企业及大众的需求, 阿里云推出了DashScope灵积. 可以理解为模型集市, 每个模型都有其独有的特点, 而且每一种模型都提供了API接口, 使得任何人都可以调用大模型的算力.

什么和大模型结合将发挥重大的价值? 毫无疑问是数据. 例如:

  • 1、通过数据来训练大模型.

  • 2、通过大模型分析数据, 帮助企业进行决策.

  • 3、通过大模型理解数据, 例如帮助企业解决客户和伙伴提出的问题, 提升产品体验.

这个实验将带领大家来体验一下如何将“千问大模型+文本向量化模型”植入到PG|PolarDB中, 让数据库具备AI能力.

通用大模型是使用大量高质量素材训练而成的AI大脑, 训练过程非常耗费硬件资源, 时间也非常漫长. AI的能力取决于训练素材(文本、视频、音频等), 虽然训练素材非常庞大, 可以说可以囊括目前已知的人类知识的巅峰. 但是模型是由“某家公司/某个社区”训练的, 它能触达的素材总有边界, 总有一些知识素材是无法被训练的, 例如私有(机密)素材. 因此通用大模型存在一些问题, 以chatGPT为例:

  • 在达模型训练完成后, 新发现的知识. 大模型不具备这些知识, 它的回答可能产生幻觉(胡编乱造)

  • 大模型没有训练过的私有知识. 大模型不具备这些知识, 它的回答可能产生幻觉(胡编乱造)

由于训练过程耗费大量资源且时间漫长, 为了解决幻觉问题, 不可能实时用未知知识去训练大模型, 向量数据库应运而生.

基本原理如下

  • 1、将新知识(在达模型训练完成后, 新发现的知识 + 大模型没有训练过的私有知识)分段

  • 2、将分段内容向量化, 生成对应的向量(浮点数组)

  • 3、将向量(浮点数组), 以及对应的分段内容(文本)存储在向量数据库中

  • 4、创建向量索引, 这是向量数据库的核心, 有了向量索引可以加速相似搜索. 例如: 1000万条向量中召回100条相似内容, 毫秒级别.

  • 5、当用户提问时, 将用户问题向量化, 生成对应的向量(浮点数组)

  • 6、到向量数据库中根据向量距离(向量相似性)进行搜索, 找到与用户问题相似度高于某个阈值的文本分段内容

  • 7、将找到的文本分段内容+用户问题发送给大模型

  • 8、大模型有了与用户提问问题相关新知识(分段文本内容)的加持, 可以更好的回答用户问题

实现和对照

1、模型服务灵积总览

DashScope灵积,旨在通过灵活、易用的模型API服务,让业界各个模态的模型能力,能方便触达AI开发者。

通过灵积API,丰富多样化的模型不仅能通过推理接口被集成,也能通过训练微调接口实现模型定制化,让AI应用开发更灵活,更简单!

https://dashscope.console.aliyun.com/overview

2、可以先在web界面体验各种模型

https://dashscope.aliyun.com/

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:

  • https://help.aliyun.com/zh/dashscope/developer-reference/install-dashscope-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.
}
}

传统方法 设计和实验

传统数据库的数据库内置编程语言的支持比较受限, 通常只支持SQL接口. 无法直接使用通义千问大模型+文本向量化模型的能力.

PolarDB|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

对照

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可以找到.

知识点

大模型

向量

向量索引

求2个向量的距离

数据库函数语言

jsonb

array

思考

1、数据库集成了各种编程语言之后, 优势是什么?

2、大模型和数据结合, 能干什么?

3、数据库中存储了哪些数据? 这些数据代表的业务含义是什么? 这些数据有什么价值?

4、高并发小事务业务场景和低并发大量数据分析计算场景, 这两种场景分别可以用大模型和embedding来干什么?

5、数据库中如何存储向量? 如何加速向量相似搜索?

参考

https://help.aliyun.com/zh/dashscope/api-reference

https://postgresml.org/

  • 《制作 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 自然语言处理》

欢迎关注我的github (https://github.com/digoal/blog) , 学习数据库不迷路.  

近期正在写公开课材料, 未来将通过视频号推出, 欢迎关注视频号:

Image

文章中的参考文档请点击阅读原文获得.