前言
在眾多大型企業(yè)中,數(shù)據(jù)資產(chǎn)龐大無比,因此它們紛紛構(gòu)建了多種大數(shù)據(jù)平臺。然而,關(guān)鍵在于如何高效地利用這些數(shù)據(jù),例如,將數(shù)據(jù)有效地提供給產(chǎn)品經(jīng)理或數(shù)據(jù)分析師以供他們進(jìn)行設(shè)計(jì)和分析。在傳統(tǒng)工作流程中,由于這些角色通常不是技術(shù)專家,他們往往無法直接使用和操控SQL,導(dǎo)致必須依賴技術(shù)人員來編寫SQL查詢并返回結(jié)果,然后才能由產(chǎn)品經(jīng)理、數(shù)據(jù)分析師或其他相關(guān)人員進(jìn)一步處理。
然而,隨著強(qiáng)大的大模型]的出現(xiàn),我們對自然語言的理解能力得到了極大的提升,同時(shí)通過支持的插件式擴(kuò)展(允許自主調(diào)用相關(guān)外部方法或API),為我們解決這一難題提供了全新的思路。這些大模型不僅能夠理解復(fù)雜的自然語言查詢,還能夠與現(xiàn)有的數(shù)據(jù)處理工具無縫集成,從而使得非技術(shù)用戶也能夠直接參與到數(shù)據(jù)分析的過程中,無需通過技術(shù)人員作為中介,極大地提高了工作效率和決策的速度。
一、技術(shù)架構(gòu)設(shè)計(jì)
用戶輸入說明要查詢的信息,LLM基于本地知識庫生成SQL,調(diào)用不同的Funcation Call,每個(gè)一個(gè)Funcation call中都封裝一個(gè)不同的數(shù)據(jù)服務(wù)的調(diào)用;比如Mysql、Hive、Spark、Flink。
二、本地知識庫準(zhǔn)備
大模型擅長將輸出轉(zhuǎn)化為不同格式,比如從一種語言翻譯成另一種語言,幫助拼寫、語法糾正以及編寫正則表達(dá)式;整個(gè)平臺有兩個(gè)基礎(chǔ)支持的部分,第一部分就是數(shù)據(jù)字典,我們先將所有需要查詢的數(shù)據(jù)庫、表、字段信息結(jié)構(gòu)化整理成數(shù)據(jù)字典,作為本地知識庫。
三、SQLServer服務(wù)
平臺中兩個(gè)核心支撐中另外一個(gè)就是數(shù)據(jù)服務(wù)的開發(fā),基于不同的數(shù)據(jù)庫類型,開發(fā)不同的數(shù)據(jù)服務(wù),用于支撐LLM的數(shù)據(jù)查詢;包括但不限于:MySQL數(shù)據(jù)服務(wù),Hive數(shù)據(jù)服務(wù)、Spark數(shù)據(jù)服務(wù)、Flink數(shù)據(jù)服務(wù)等;
1. 數(shù)據(jù)庫準(zhǔn)備
步驟1:安裝MySQL數(shù)據(jù)庫
sudo apt-get update
sudo apt-get install mysql-server
步驟2:啟動(dòng)MySQL數(shù)據(jù)庫
sudo service mysql start
sudo systemctl start mysqld
步驟3:登錄MySQL數(shù)據(jù)庫
mysql -u root -p
步驟4:創(chuàng)建數(shù)據(jù)庫用戶glm
CREATE USER 'glm'@'localhost' IDENTIFIED BY 'glm';
步驟5:給數(shù)據(jù)庫用戶賦權(quán)限
GRANT ALL PRIVILEGES ON *.* TO 'glm'@'localhost';
FLUSH PRIVILEGES;
步驟6:創(chuàng)建數(shù)據(jù)庫
CREATE DATABASE glm;
USE glm;
2. 數(shù)據(jù)準(zhǔn)備
CREATE TABLE user_info (
customerID VARCHAR(255),
gender VARCHAR(255),
SeniorCitizen INT,
Partner VARCHAR(255),
Dependents VARCHAR(255)
);
INSERT INTO user_info (customerID, gender, SeniorCitizen, Partner, Dependents)
VALUES
('1', 'Female', 0, 'Yes', 'No'),
('2', 'Male', 1, 'No', 'Yes'),
('3', 'Male', 0, 'No', 'No'),
('4', 'Female', 1, 'Yes', 'Yes'),
('5', 'Male', 0, 'No', 'No'),
('6', 'Female', 0, 'Yes', 'Yes'),
('7', 'Male', 1, 'Yes', 'No'),
('8', 'Female', 0, 'No', 'No'),
('9', 'Male', 1, 'Yes', 'Yes'),
('10', 'Female', 0, 'No', 'No'),
('11', 'Male', 0, 'Yes', 'Yes'),
('12', 'Female', 1, 'No', 'No'),
('13', 'Male', 0, 'No', 'Yes'),
('14', 'Female', 0, 'Yes', 'No'),
('15', 'Male', 1, 'Yes', 'Yes'),
('16', 'Female', 0, 'No', 'No'),
('17', 'Male', 0, 'No', 'Yes'),
('18', 'Female', 1, 'Yes', 'No'),
('19', 'Male', 0, 'No', 'No'),
('20', 'Female', 1, 'No', 'Yes');
3. SQL服務(wù)封裝
安裝依賴:! pip install pymysql
封裝SQL執(zhí)行函數(shù)(將傳入的SQL代碼傳輸至MySQL環(huán)境中進(jìn)行運(yùn)行,并最終返回SQL代碼運(yùn)行結(jié)果)。
import pymysql
import json
def sql_inter(sql_query):
"""
用于執(zhí)行一段SQL代碼,并最終獲取SQL代碼執(zhí)行結(jié)果,\
核心功能是將輸入的SQL代碼傳輸至MySQL環(huán)境中進(jìn)行運(yùn)行,\
并最終返回SQL代碼運(yùn)行結(jié)果。需要注意的是,本函數(shù)是借助pymysql來連接MySQL數(shù)據(jù)庫。
:param sql_query: 字符串形式的SQL查詢語句,用于執(zhí)行對MySQL中telco_db數(shù)據(jù)庫中各張表進(jìn)行查詢,并獲得各表中的各類相關(guān)信息
:return:sql_query在MySQL中的運(yùn)行結(jié)果。
"""
connection = pymysql.connect(
host="localhost", # 數(shù)據(jù)庫地址
user='glm', # 數(shù)據(jù)庫用戶名
passwd="glm", # 數(shù)據(jù)庫密碼
db=glm', # 數(shù)據(jù)庫名
charset='utf8' # 字符集選擇utf8
)
try:
with connection.cursor() as cursor:
# SQL查詢語句
sql = sql_query
cursor.execute(sql)
# 獲取查詢結(jié)果
results = cursor.fetchall()
finally:
connection.close()
return json.dumps(results)
#函數(shù)測試
sql_inter("select count(*) from user_info")
'[[20]]'
四、核心代碼落地
接收前端用戶的輸入信息,LLM基于本地知識庫,生成SQL;自主判斷(根據(jù)提示和描述信息的相關(guān)性)通過Funcation Call調(diào)用不同數(shù)據(jù)服務(wù);返回結(jié)果給到前端用戶;
1.模型加載
從huggingface拉取分詞器模型和基礎(chǔ)大模型,進(jìn)行加載運(yùn)行到本地服務(wù)器
##測試模型
from transformers import AutoTokenizer, AutoModel
tokenizer = AutoTokenizer.from_pretrained("THUDM/chatglm3-6b",
trust_remote_code=True)
#model = AutoModel.from_pretrained("THUDM/chatglm3-6b",trust_remote_code=True).quantize(8).cuda()
model = AutoModel.from_pretrained("THUDM/chatglm3-6b", trust_remote_code=True,device='cuda')
model = model.eval()
2.本地知識庫讀取
將數(shù)據(jù)庫、表、字段等數(shù)據(jù)字典信息,整理成一個(gè)Markdown文件
# 打開并讀取Markdown文件
with open('user_info.md', 'r', encoding='utf-8') as f:
data_dictionary = f.read()
## 定義一個(gè)簡單的數(shù)據(jù)庫測試服務(wù)
sql_inter(sql_query='SELECT COUNT(*) FROM user_info;')
3.function call函數(shù)封裝
sql_inter_function_info = [
{
'name': 'sql_inter',
'description': '用于執(zhí)行一段SQL代碼,并最終獲取SQL代碼執(zhí)行結(jié)果,核心功能是將輸入的SQL代碼傳輸至MySQL環(huán)境中進(jìn)行運(yùn)行,并最終返回SQL代碼運(yùn)行結(jié)果。',
'parameters': {
'type': 'object',
'properties': {
'sql_query': {
'type': 'string',
'description': '字符串形式的SQL代碼,可以在MySQL中運(yùn)行,并獲取運(yùn)行結(jié)果'
}
},
'required': ['sql_query']
}
}
]
4.工具函數(shù)封裝
def run_conv_glm(query,tokenizer, history, model,functions_list=None, functions=None, return_function_call=True):
"""
能夠自動(dòng)執(zhí)行外部函數(shù)調(diào)用的Chat對話模型
:param messages: 必要參數(shù),輸入到Chat模型的messages參數(shù)對象
:param functions_list: 可選參數(shù),默認(rèn)為None,可以設(shè)置為包含全部外部函數(shù)的列表對象
:param model: Chat模型,可選參數(shù),默認(rèn)模型為chatglm3-6b
:return:Chat模型輸出結(jié)果
"""
# 如果沒有外部函數(shù)庫,則執(zhí)行普通的對話任務(wù)
if functions_list == None:
response, history = model.chat(tokenizer, query, history=history)
final_response = response
# 若存在外部函數(shù)庫,則需要靈活選取外部函數(shù)并進(jìn)行回答
else:
# 創(chuàng)建調(diào)用外部函數(shù)的system_message
system_info = {
"role": "system",
"content": "Answer the following questions as best as you can. You have access to the following tools:",
"tools": functions,
}
# 創(chuàng)建外部函數(shù)庫字典
available_functions = {func.__name__: func for func in functions_list}
history=[system_info]
## 第一次調(diào)用,目的是獲取函數(shù)信息
response,history = model.chat(tokenizer, query, history=history)
print(response)
# 需要調(diào)用外部函數(shù)
function_call = response
# 獲取函數(shù)名
function_name = function_call["name"]
# 獲取函數(shù)對象
fuction_to_call = available_functions[function_name]
# 獲取函數(shù)參數(shù)
function_args = function_call['parameters']
# 將函數(shù)參數(shù)輸入到函數(shù)中,獲取函數(shù)計(jì)算結(jié)果
function_response = fuction_to_call(**function_args)
# print("答案")
# print(function_response)
# ## 第二次調(diào)用,帶入進(jìn)去函數(shù)
# history=[]
# history.append(
# {
# "role": "observation",
# "name": function_name,
# "content":function_response,
# }
# )
# print(history)
# query= "請幫我到查詢一下有多少電信用戶,并給出答案"
# response, history = model.chat(tokenizer, query, history=history)
final_response=function_response
return final_response,history
5. 調(diào)用查詢測試
query = data_dictionary + ",請幫我到查詢一下有多少電信用戶,并給出答案?"
history=[]
functions_list = [sql_inter]
functions=sql_inter_function_info
response,history = run_conv_glm(query=query,functions=functions,model=model,functions_list=functions_list,history=history,tokenizer=tokenizer)
第一次:執(zhí)行輸出如下: (結(jié)果很正確??)
{'name': 'sql_inter', 'parameters': {'sql_query': 'SELECT COUNT(*) FROM user_info'}}
打印:print(response) 輸出結(jié)果正確: [[20]]
第二次:執(zhí)行輸出如下:(結(jié)果也沒啥問題??)
{'name': 'sql_inter', 'parameters': {'sql_query': 'SELECT COUNT(*) FROM user_info WHERE gender IN("Male", "Female")'}}
第三次:執(zhí)行輸出如下:(條件中出現(xiàn)了未知字段 is_senior ,很明顯翻車了??)
{'name': 'sql_inter', 'parameters': {'sql_query': 'SELECT COUNT(*) FROM user_info WHERE is_senior = 0;'}}
第四次:執(zhí)行輸出如下:(不知道怎么查詢了,徹底蒙圈了??)
您好,我可以幫您查詢這個(gè)問題。請問您需要使用哪種編程語言進(jìn)行查詢?
第五次:執(zhí)行輸出如下:(還是回答錯(cuò)誤??)
{'name': 'sql_inter', 'parameters': {'sql_query': 'SELECT COUNT(*) FROM user_info WHERE gender = "Male"'}}
第五次:執(zhí)行輸出如下:(又回答對了??)
{'name': 'sql_inter', 'parameters': {'sql_query': 'SELECT COUNT(*) FROM user_info'}}
五、結(jié)束思考
1)大模型的問世,為我們帶來了前所未有的便捷性。眾多傳統(tǒng)應(yīng)用正從全新的角度,借助大模型的力量進(jìn)行著顛覆性的重構(gòu)。然而,大模型的穩(wěn)定性尚存變數(shù),這一點(diǎn)在功能設(shè)計(jì)時(shí)必須予以充分考慮。
2)對于本平臺的本地知識庫,如果采納微調(diào)的策略來豐富和優(yōu)化大模型,將顯得更為合理。鑒于知識庫涵蓋的內(nèi)容廣泛,數(shù)據(jù)字典信息繁多,這種微調(diào)方式有助于提升大模型的理解力和應(yīng)用效果。
??上一篇: AI大模型探索之路-應(yīng)用篇16:GLM大模型-ChatGLM3 API開發(fā)實(shí)踐
??更多專欄系列文章:AIGC-AI大模型探索之路文章來源:http://www.zghlxwxcb.cn/news/detail-855386.html
文章若有瑕疵,懇請不吝賜教;若有所觸動(dòng)或助益,還望各位老鐵多多關(guān)注并給予支持。文章來源地址http://www.zghlxwxcb.cn/news/detail-855386.html
到了這里,關(guān)于AI大模型探索之路-應(yīng)用篇17:GLM大模型-大數(shù)據(jù)自助查詢平臺架構(gòu)實(shí)踐的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!