暂无图片
暂无图片
6
暂无图片
暂无图片
暂无图片

数据库管理-第270期 23ai:数据库实现RAG(20241211)

原创 胖头鱼的鱼缸 2024-12-11
247

数据库管理270期 2024-12-11

数据库管理-第270期 23ai:数据库实现RAG(20241211)

作者:胖头鱼的鱼缸(尹海文)
Oracle ACE Pro: Database
PostgreSQL ACE Partner
10年数据库行业经验
拥有OCM 11g/12c/19c、MySQL 8.0 OCP、Exadata、CDP等认证
墨天轮MVP,ITPUB认证专家,数盟会长老会成员,OCM讲师,PolarDB开源社区、青学会MOP社区技术顾问,HaloDB外聘技术顾问,OceanBase观察团成员
圈内拥有“总监”称号,非著名社恐(社交恐怖分子)
公众号、墨天轮:胖头鱼的鱼缸;CSDN:胖头鱼的鱼缸(尹海文);ITPUB:yhw1809。
除授权转载并标明出处外,均为“非法”抄袭

演示文稿1_01.png
众所周知,特别是最新版的Oracle数据库版本命名从23c(Converged)到了23ai,同时Oracle也将“以AI为中心的企业基础架构”作为核心战略目标。本期跟随总监,一起来看看如何在Oracle 23ai中实现RAG。
本次操作系统使用为OracleLinux 9.4(数据库)/8.10(LLM),数据库版本为单实例Oracle 23ai(23.5.0.24.07),LLM为通义千问2-7B(Qwen2-7B)(当然也可以使用其他的模型)。除sqlplus外,本篇文章部分展示使用最新版sqldeveloper。

1 数据库向量嵌入能力

1.1 导入向量嵌入模型

在开始基于Oracle 23ai的数据库RAG的演示之前,先演示Oracle Vector DB的库内向量嵌入能力,使用text2vec-large-chinese模型,需要将向量嵌入模型处理为标准的ONNX格式:bge-base-zh-v1.5.onnx(大小需控制在1G内),onnx文件放到oracle家目录中。

create or replace directory MODELS_DIR as '/home/oracle'; BEGIN DBMS_VECTOR.LOAD_ONNX_MODEL( directory => 'MODELS_DIR', file_name => 'bge-base-zh-v1.5.onnx', model_name => 'embedding_model' ); END; /

可以通过以下语句查看已导入的模型:

SELECT MODEL_NAME, MINING_FUNCTION, ALGORITHM, ALGORITHM_TYPE, MODEL_SIZE FROM USER_MINING_MODELS; SELECT MODEL_NAME, ATTRIBUTE_NAME, ATTRIBUTE_TYPE, DATA_TYPE,VECTOR_INFO FROM USER_MINING_MODEL_ATTRIBUTES WHERE MODEL_NAME = 'EMBEDDING_MODEL';

image.png
image.png

1.2 向量嵌入

SELECT VECTOR_EMBEDDING(embedding_model USING 'Hello, World' as data) AS embedding;

image.png
这里就可以看到在数据库内即可实现向量嵌入操作,当然数据库内没有GPU,其嵌入效率远不如外部使用GPU提供算力的模型。当然Oracle数据库也可以在库内直接调用外部大模型,这将在后面的RAG环境进行演示。

2 部署LLM

Ollama是一个大模型运行框架,可以非常快捷的使用无GPU环境运行大模型。这里使用Ollama来运行通义千问LLM(当然也可以直接使用Python或其他方式运行),机器IP地址为10.10.10.21。

1.1 安装Ollama

curl -fsSL https://ollama.com/install.sh | sh

image.png

1.2 启动Ollama

vim /etc/systemd/system/ollama.service #在[Service]中添加以下内容 Environment="OLLAMA_HOST=0.0.0.0:8098"

image.png

systemctl start ollama.service

image.png

1.3 启动Qwen2-7B

OLLAMA_HOST=0.0.0.0:8098 ollama run qwen2:7b-instruct

通过该命令会直接通过网络下载通义千问LLM,也可以离线下载大模型文件运行。
image.png

1.4 测试部署

image.png

curl http://10.10.10.21:8098/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "qwen2:7b-instruct", "messages": [ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": "Tell me something about large language models."} ] }'

image.png
由于没有GPU,响应略慢。

3 数据库配置

数据库基本连接信息为:10.10.10.31:1521/pdbprod1(PDB)。
使用最新版的sqldeveloper做演示。

2.1 安装APEX

APEX下载地址:https://www.oracle.com/tools/downloads/apex-downloads/

unzip apex_24.1.zip cd apex/ sqlplus / as sysdba
@apexins.sql SYSAUX SYSAUX TEMP /i/ @?/rdbms/admin/utlrp.sql

2.2 创建用户并赋权

create tablespace users datafile size 500m autoextend on next 500m maxsize unlimited; create user llm identified by llm; grant DB_DEVELOPER_ROLE to llm; alter user llm default tablespace users quota unlimited on users;

2.3 导入测试数据

CREATE TABLE lab_vecstore ( id VARCHAR2(50) DEFAULT SYS_GUID() PRIMARY KEY, dataset_name VARCHAR2(50) NOT NULL, document CLOB, cmetadata JSON, embedding VECTOR(*, FLOAT32) );

这里使用Oracle提供的一套数据以及基于Python的API WEB工具实现数据向量化与导入(不做操作展示)。
image.png

2.4 直接LLM对话

SET SERVEROUTPUT ON; declare l_question varchar2(500) := 'Oracle 23ai 新特性'; l_input CLOB; l_clob CLOB; j apex_json.t_values; l_embedding CLOB; l_context CLOB; l_rag_result CLOB; begin apex_web_service.g_request_headers(1).name := 'Content-Type'; apex_web_service.g_request_headers(1).value := 'application/json'; l_input := '{"text": "' || l_question || '"}'; -- 第一步:提示工程:给大语言模型明确的指示 l_input := '{ "model": "qwen2:7b-instruct", "messages": [ {"role": "system", "content": "你是一个诚实且专业的数据库知识问答助手,请回答用户提出的问题。"}, {"role": "user", "content": "' || l_question || '"} ] }'; -- 第二步:调用大语言模型,生成结果 l_clob := apex_web_service.make_rest_request( p_url => 'http://10.10.10.21:8098/v1/chat/completions', p_http_method => 'POST', p_body => l_input ); apex_json.parse(j, l_clob); l_rag_result := apex_json.get_varchar2(p_path => 'choices[%d].message.content', p0 => 1, p_values => j); dbms_output.put_line('*** Result: ' || chr(10) || l_rag_result); end; /

这里可能会出现以下报错:
image.png
需要在CDB执行以下命令:

BEGIN DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE( host => '*', ace => xs$ace_type(privilege_list => xs$name_list('connect', 'resolve'), principal_name => 'APEX_240100', principal_type => xs_acl.ptype_db ) ); END; /

然后会继续出现以下报错:
image.png
需要在CDB执行以下命令:

grant inherit privileges on user sys to APEX_240100;

然后可以正常出结果了:
image.png
但是这里我们可以看到未使用RAG方式,大模型给出的结果非常离谱。当然也可以多次执行,结果会有所不同,但总体来说结果都比较离谱。
image.png

2.5 RAG方式与LLM对话

这里先说明一下,在10.10.10.21服务器8099端口运行了另一套基于text2vec-large-chinese的向量嵌入程序,也就是前面导入数据使用的,在使用RAG方式与LLM对话过程中会先将提问向量化后与知识库进行关联匹配。

declare l_question varchar2(500) := 'Oracle 23ai 新特性'; l_input CLOB; l_clob CLOB; j apex_json.t_values; l_embedding CLOB; l_context CLOB; l_rag_result CLOB; begin apex_web_service.g_request_headers(1).name := 'Content-Type'; apex_web_service.g_request_headers(1).value := 'application/json'; l_input := '{"text": "' || l_question || '"}'; -- 第一步:向量化用户问题 l_clob := apex_web_service.make_rest_request( p_url => 'http://10.10.10.21:8099/workshop/embedding', p_http_method => 'POST', p_body => l_input ); apex_json.parse(j, l_clob); l_embedding := apex_json.get_varchar2(p_path => 'data.embedding', p_values => j); -- dbms_output.put_line('*** embedding: ' || l_embedding); -- 第二步:从向量数据库中检索出与问题相似的内容 for rec in (select document, json_value(cmetadata, '$.source') as src_file from lab_vecstore where dataset_name='oracledb_docs' order by VECTOR_DISTANCE(embedding, to_vector(l_embedding)) FETCH FIRST 3 ROWS ONLY) loop l_context := l_context || rec.document || chr(10); end loop; -- 第三步:提示工程:将相似内容和用户问题一起,组成大语言模型的输入 l_context := replace(replace(replace(l_context, '''', ''), '"', '\"'), chr(10), '\n'); l_input := '{ "model": "qwen2:7b-instruct", "messages": [ {"role": "system", "content": "你是一个诚实且专业的数据库知识问答助手,请根据提供的上下文内容,回答用户的问题。\n 以下是上下文内容:' || l_context || '"}, {"role": "user", "content": "' || l_question || '(请仅根据提供的上下文内容回答,不要试图编造答案)"} ] }'; -- 第四步:调用大语言模型,生成RAG结果 l_clob := apex_web_service.make_rest_request( p_url => 'http://10.10.10.21:8098/v1/chat/completions', p_http_method => 'POST', p_body => l_input ); apex_json.parse(j, l_clob); l_rag_result := apex_json.get_varchar2(p_path => 'choices[%d].message.content', p0 => 1, p_values => j); dbms_output.put_line('*** RAG Result: ' || chr(10) || l_rag_result); end; /

image.png
这时候我们可以看到使用RAG方式与LLM对话的结果就会准确很多。这里我们可以再执行一次:
image.png

总结

本期主要展示了Oracle 23ai的库内与库外向量嵌入能力,以及配合使用APEX可以在数据库中调用外部模型实现RAG。
老规矩,知道写了些啥。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论