#科大讯飞 #Datawhale #RAG #检索增强生成
CSDN和datawhale的朋友们大家好呀!经过几日颠簸,小虢也是成功搬进了研究生的新宿舍!而datawhale夏令营也随着暑假的结束暂时告一段落了。暂时还不知道datawhale官方后续有没有其他的学习活动,但咱们对数据科学的探索不能断,本次为大家带来科大讯飞大模型RAG智能问答挑战赛的baseline精读!
声明:baseline代码版权归属datawhale社区、coggle社区所属,本文仅对baseline代码进行解读
coggle社区 baseline代码
RAG的定义与作用
(1)什么是RAG?
RAG(检索增强生成)是一种结合了检索模型和生成模型的技术,它通过检索大量外部知识来辅助文本生成,从而提高大型语言模型(LLMs)的准确度和可靠性。而要想了解RAG具体是怎么工作的,则要从一幅原理图说起。
引用:https://challenge.xfyun.cn/topic/info?type=RAG-quiz&option=ssgy
具体来说,RAG是这样一种“中间件”,它接受用户的语义搜索,通过由原始内容和新增内容产生的向量数据库,产生上下文数据(contextual data),再将上下文数据与Prompt结合作为大语言模型的输入,通过大语言模型输出到框架内,经过处理后再返回给用户!
(2)rag有什么意义与作用?
RAG特别适合于需要不断更新知识的知识密集型场景或特定领域应用,它通过引入外部信息源,有效缓解了大语言模型在领域知识缺乏、信息准确性问题以及生成虚假内容等方面的挑战。
可以说,RAG使得大模型向人类学习的能力迈上了一个新台阶,而步子能迈多大,则取决于你我设计出的RAG架构的性能。
baseline代码详解
1.导入第三方包
sentence_transformers是一个用于句子和文本嵌入的库,它提供了多种预训练模型,可以将文本转换为高维向量,这些向量可以用于各种NLP任务,如句子相似度计算、文本搜索等。
import pandas as pd
import numpy as np
import os
os.environ['HF_ENDPOINT'] = 'https://hf-mirror.com'
from sentence_transformers import SentenceTransformer
sentences_1 = ["样例数据-1", "样例数据-2"]
model = SentenceTransformer('BAAI/bge-small-zh-v1.5')
embeddings_1 = model.encode(sentences_1, normalize_embeddings=True, show_progress_bar=True)
这里选用百度的一个embedding模型,计算较快且在中文上表现良好,朋友们也可以选用其他的embedding模型。
2.数据处理
我们先看一下官方给的数据的基本结构
以换行符为分割将知识库划分为文档,我们要做的就是首先找到最相关的文档,将最相关的文档作为上下文信息给到大模型生成输出。
corpus = open('corpus.txt').readlines()
query = pd.read_csv('test_question.csv')['question'].values
查询就简单读取即可
3.将语义文本转为向量
query_feat = model.encode(query, normalize_embeddings=True, show_progress_bar=True)
corpus_feat = model.encode(corpus, normalize_embeddings=True, show_progress_bar=True)
调用之前定义的embedding模型将语义文本转变为向量,方便后面的计算。这里既包括了资料库的语义文本也包括了查询的语义文本。
4.定义大语言模型
glm-flash是清华大学推出的一个免费大语言模型,我们在此定义其输入输出,以便后续作为函数调用。
import time
import jwt
import requests
# 实际KEY,过期时间
def generate_token(apikey: str, exp_seconds: int):
try:
id, secret = apikey.split(".")
except Exception as e:
raise Exception("invalid apikey", e)
payload = {
"api_key": id,
"exp": int(round(time.time() * 1000)) + exp_seconds * 1000,
"timestamp": int(round(time.time() * 1000)),
}
return jwt.encode(
payload,
secret,
algorithm="HS256",
headers={"alg": "HS256", "sign_type": "SIGN"},
)
def glm4air(prompt):
url = "https://open.bigmodel.cn/api/paas/v4/chat/completions"
headers = {
'Content-Type': 'application/json',
'Authorization': generate_token("填入你的 key", 1000)
}
data = {
"model": "glm-4-air",
"messages": [{"role": "user", "content": prompt }]
}
response = requests.post(url, headers=headers, json=data, timeout=200)
return response.json()['choices'][0]['message']['content']
glm4air('早上好')
5.计算相似度,检索支撑材料
接下来,我们就要做两件事,首先,在多个文档当中找到最接近问题需求的那个文档,然后,我们在最接近问题需求的文档找到支撑问题的资料,与prompt一起作为大模型输入以获取答案!
from tqdm import tqdm
test_answer = []
for q, qtext in tqdm(zip(query_feat, query)):
top1_content = corpus[np.dot(q, corpus_feat.T).argsort()[-1]]
prompt_text = f'''请结合下面的资料,回答给定的问题:
提问:{qtext}
相关资料:{top1_content}
'''
try:
answer = glm4air(prompt_text)
answer = answer.replace('\n', '')
test_answer.append(answer)
except:
test_answer.append('无法回答。')
5.生成竞赛所需的txt文件
test_answer = pd.DataFrame(test_answer)
test_answer.columns = ['answer']
test_answer.to_csv('submit.csv', index=None)
最终的竞赛评分为0.3左右,效果还算不错的,基本达到了预期目标。
在baseline的基础上,各位大佬也可以八仙过海、各显神通,不断提升自己的分数,不断突破rag能力的边界!
本篇文章主要讨论了RAG的基本概念和简单实现
参考文献:
coggle社区 baseline代码
大模型RAG智能问答挑战赛
笔者水平有限,欢迎各位大佬批判指正!