RAG——小参数模型也能有大作为

项目名称:AI-AGENT夏季训练营 — 基于RAG构建的城市旅游攻略智能助手(以武汉为例)

报告日期:2024年8月18日

项目负责人:Oswald


目录

项目概述

技术方案与实施步骤

模型选择

数据的构建

实施步骤

环境搭建

代码实现

项目成果与展示

问题与解决方案

项目总结与展望


项目概述

本项目借助英伟达NIM平台设计并实现了一个城市旅游攻略智能助手,项目利用较小参数的大语言模型实现,能够在资源受限的设备上高效运行,如移动设备、嵌入式系统等,并通过RAG技术解决大语言模型在“知识库不足”情况下出现的“幻觉”现象,实现了在垂直细分领域下得到更专业、更准确的回答。

技术方案与实施步骤

模型选择

  • llama-3.1-8b-instruct
  • ai-embed-qa-4

数据的构建

本次项目以武汉为例,在携程网上针对武汉的著名景点和美食进行了相关信息的收集,得到两个txt文件,用于后续外部知识库的构建

 文本原始数据预览

food.txt

热干面是武汉最出名的小吃之一,有多种做法,其采用碱水面,并以食油、芝麻酱、色拉油、香油、红油、细香葱、大蒜、萝卜丁、酸豆角、卤水汁、生抽、醋等为辅助材料。热干面色泽黄而油润,味道鲜美,由于热量高,也可以当作主食,营养早餐,补充人体所需的能量。

武汉蛋酒是武汉过早点单率非常高的饮品,蛋酒香浓可口,色淡而甘甜,口感尚佳,基本上是早上搭配油条,面窝食用。

武昌鱼是我国重要的草食性鱼类,具有味美、头小、含肉量高的特点。烹饪方法多样,清蒸、油焖、红烧、花酿等等。选用鲜活鱼,清蒸时辅以火腿、冬菇、冬笋和高汤,上笼清蒸,严格控制火候,使之恰到好处。成品鱼形完整、色白明亮、晶莹似玉,鱼身缀以红、白、黑配料,颜色非常好看。肉质细嫩,吃起来还有浓浓的香味扑鼻。

scenic.txt

黄鹤楼(Yellow Crane Tower),位于湖北武汉武昌长江南岸蛇山峰岭之上。始建于三国时代吴黄武二年(公元223年),历代屡建屡毁,今天看到的黄鹤楼,是1985年重建的。黄鹤楼是国家5A级景点,享有“天下绝景” 、“天下江山第一楼”之称,是武汉的城市地标之一,因唐代诗人崔颢“昔人已乘黄鹤去,此地空余黄鹤楼”的诗句而名扬天下,李白等都为黄鹤楼留下了诗词。登上黄鹤楼远眺,可以看到滚滚长江和武汉三镇风光。

黄鹤楼公园有东门、南门、西门3个入口,东门位于近首义广场一侧,有专门的停车场,停车较方便;南门位于长江大桥武昌侧引桥处,有专门的公交车站,公共交通较方便;西门位于长江大桥上,便于步行游览长江大桥及从户部巷上长江大桥的游客进入。

实施步骤

环境搭建

准备好anconda,创建虚拟环境,python版本大于等于3.8

需要的第三方库

  • langchain-nvidia-ai-endpoints
  • jupyterlab
  • langchain_core
  • langchain
  • matplotlib
  • numpy
  • faiss-cpu==1.7.2
  • openai

详细的安装过程可以参考文章

http://t.csdnimg.cn/NbcMn

代码实现

设置api_key

if os.environ.get("NVIDIA_API_KEY", "").startswith("nvapi-"):

    print("Valid NVIDIA_API_KEY already in environment. Delete to reset")

else:

    nvapi_key = getpass.getpass("NVAPI Key (starts with nvapi-): ")

    assert nvapi_key.startswith("nvapi-"), f"{nvapi_key[:5]}... is not a valid key"

    os.environ["NVIDIA_API_KEY"] = nvapi_key

外部知识库的构建

初始向量化模型

from langchain_nvidia_ai_endpoints import NVIDIAEmbeddings



embedder = NVIDIAEmbeddings(model="ai-embed-qa-4")

获取文本数据集并初步清洗

import os

from tqdm import tqdm

from pathlib import Path



# Here we read in the text data and prepare them into vectorstore

ps = os.listdir("./data/")

data = []

sources = []

for p in ps:

    if p.endswith('.txt'):

        path2file="./data/"+p

        with open(path2file,encoding="utf-8") as f:

            lines=f.readlines()

            for line in lines:

                if len(line)>=1:

                    data.append(line)

                    sources.append(path2file)



documents=[d for d in data if d != '\n']

用向量模型将文档处理到 faiss vectorstore 并将其保存

from operator import itemgetter

from langchain.vectorstores import FAISS

from langchain_core.output_parsers import StrOutputParser

from langchain_core.prompts import ChatPromptTemplate

from langchain_core.runnables import RunnablePassthrough

from langchain.text_splitter import CharacterTextSplitter

from langchain_nvidia_ai_endpoints import ChatNVIDIA

import faiss





# 只需要执行一次,后面可以重读已经保存的向量存储

text_splitter = CharacterTextSplitter(chunk_size=400, separator=" ")

docs = []

metadatas = []



for i, d in enumerate(documents):

    splits = text_splitter.split_text(d)

    #print(len(splits))

    docs.extend(splits)

    metadatas.extend([{"source": sources[i]}] * len(splits))



store = FAISS.from_texts(docs, embedder , metadatas=metadatas)

store.save_local('./data/nv_embedding')





# 重读之前处理并保存的 Faiss Vectore 存储

store = FAISS.load_local("./data/nv_embedding", embedder,allow_dangerous_deserialization=True)

提出问题并基于llama-3.1-8b-instruct模型进行RAG检索

llm = ChatNVIDIA(model="meta/llama-3.1-8b-instruct", nvidia_api_key=nvapi_key, max_tokens=512)

retriever = store.as_retriever()



prompt = ChatPromptTemplate.from_messages(

    [

        (

            "system",

            "Answer solely based on the following context:\n<Documents>\n{context}\n</Documents>",

        ),

        ("user", "{question}"),

    ]

)



chain = (

    {"context": retriever, "question": RunnablePassthrough()}

    | prompt

    | llm

    | StrOutputParser()

)



chain.invoke("帮我制定去武汉的旅游计划,去玩三天,一共两个人,出发地为长沙,其中我想去黄鹤楼")

项目成果与展示

我们可以看一看在没有利用RAG技术时,我们向模型提问,会得到怎样的回答

可以看到,由于我们使用的llama-3.1-8B模型是使用英文语料训练的,在回答中文问题上出现了严重的语言偏差。为此我们重新用英文再提问一次。

用英文提问后,模型虽然给出了回答,但回答中包含不少幻觉现象,出现了许多凭空捏造的武汉地区或景点。

如Er Dao Qiao area(二道桥区),实际上二道桥为乌鲁木齐市的地区。

Yellow Crane Mountain Park(黄鹤山公园),正确的表述应该是黄鹤楼公园。

QinChuan SinhPlace ( Wine Town ) ,百度翻译为秦川新地(酒乡),文心一言的翻译为秦川酒庄(酒镇),比较合理的解释是,模型混淆了武汉市的晴川桥(Qingchuan Bridge)。

现在,再让我们看看使用了RAG之后的回答。

可以看到,模型能够回答出如热干面,武汉通,锦江酒店等进一步更精确的回答,但是受限于外部知识库的数据不足(景点信息只收集了6条,美食信息只收集了10条),幻觉现象仍没有完全消失,但是在更完备的外部知识库下,模型的表现也一定会随之提升。

问题与解决方案

  1. 在部署环境时,不需要网络代理,避免在下载包时出现网络连接超时等问题。
  2. API_KEY需要在英伟达NIM平台申请Try NVIDIA NIM APIs

项目总结与展望

本次AI-AGENT夏季训练营项目——基于RAG构建的城市旅游攻略智能助手(以武汉为例),利用较小参数的大语言模型(llama-3.1-8b-instruct)和RAG(Retriever-Augmented Generation)技术,在垂直细分领域下得到更专业、更准确的回答。通过英伟达NIM平台及langchain框架的支持,结合外部知识库完成了RAG技术的复现并验证了其技术可行性。

同时,后续也可以往更加专业、精细的方向发展,如利用爬虫技术,扩大我们知识库数据量,来进一步提升小参数模型的表现,以及利用gradio等框架,构建前端页面,封装成一个完整的智能助手,提高用户体验,

  • 19
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值