尽管大型语言模型有能力生成有意义且语法正确的文本,但它们面临一个比较严重的问题:幻觉。
在大模型中,幻觉指的是它们倾向于自信地生成错误答案,制造出看似令人信服的虚假信息。这个问题自大模型问世以来就普遍存在,并经常导致不准确和事实错误的输出。
为了解决幻觉问题,事实检查至关重要。检查的方法包括三种方法:
-
提示工程
-
检索增强生成(RAG)
-
微调
在这种情况下,我们将利用RAG(检索增强生成)来缓解幻觉。
什么是 RAG?
RAG = 密集向量检索(R)+上下文学习(AG)
检索:为您的文档中提出的问题查找参考资料。
增强:将参考资料添加到您的提示中。
生成:改进对所提出的问题的回答。
在RAG中,我们通过将文本文档或文档片段的集合编码称为向量嵌入的数值表示来处理它们。每个向量嵌入对应于一个单独的文档片段,并存储在一个称为向量存储的数据库中。
负责将这些片段编码为嵌入的模型称为编码模型或双编码器。这些模型在广泛的数据集上进行了训练,使它们能够为文档片段创建强大的表示形式,即单个向量嵌入。
为了避免幻觉,RAG利用了与LLMs的推理能力分开保存的事实知识源。这些知识是外部存储的,可以轻松访问和更新。
有两种类型的知识源:
-
参数化知识:这种知识是在训练过程中获得的,并且隐含地存储在神经网络的权重中。
-
非参数化知识:这种类型的知识存储在外部源中,例如向量数据库。
为什么要在微调之前使用RAG?
-
便宜:无需额外的训练。
-
更容易更新最新信息。
-
更可信赖,因为有事实可核查的参考资料。
优化工作流程总结了基于以下两个因素可以使用的方法:
内容优化:模型需要知道什么。LLM优化:模型需要如何行动。
RAG 数据堆栈
📁 加载语言数据
� 处理语言数据
🤖 嵌入语言数据
🗂 将向量加载到数据库中
RAG 涉及的阶段
RAG涉及的阶段包括:
-
数据加载:这涉及从各种来源(如文本文件、PDF、网站、数据库或API)检索数据,并将其集成到您的管道中。Llama Hub提供了各种连接器来实现此目的。
-
索引:这个阶段侧重于为数据查询创建结构化格式。对于LLMs,索引通常涉及生成向量嵌入,这是数据含义的数值表示,以及其他元数据策略,以便促进准确和上下文相关的数据检索。
-
存储:在索引之后,通常的做法是存储索引和相关元数据,以避免将来需要重复索引。
-
查询:有多种方法可以利用LLMs和Llama-Index数据结构进行查询,包括子查询、多步查询和混合策略,具体取决于所选择的索引策略。
-
评估:这一步对于评估管道的有效性以比较替代策略或在实施更改时至关重要。评估提供了关于查询响应的准确性、保真度和速度的客观指标。
我们的 RAG 堆栈是使用Llama-Index、Qdrant和Llama 3构建的。
什么是 Llama-Index?
Llama-Index作为一个旨在为带有上下文丰富的LLM应用程序开发的框架。上下文增强涉及将LLMs与您的私有或领域特定数据结合使用。
该框架的一些流行应用包括:
-
问答聊天机器人(通常称为RAG系统,简称“检索增强生成”)
-
文档理解和提取
-
能够进行研究和采取行动的自治代理
Llama-Index提供了一套全面的工具,以促进这些应用程序的开发,从初始原型到生产就绪的解决方案。这些工具使数据摄取和处理成为可能,同时实现了与基于LLM的提示结合的复杂查询工作流的实施。
在这里,我们使用了 llama-index >= v0.10。
增强
每个 LlamaIndex 用户都熟悉ServiceContext,它逐渐变得过时且繁琐,用于管理LLMs、嵌入、块大小、回调以及其他功能。因此,我们完全将其弃用;现在您可以直接指定参数或设置默认值。
重新设计的文件结构:
-
llama-index-core:此文件夹包含所有核心Llama-Index抽象。
-
llama-index-integrations:该文件夹包括19个Llama-Index抽象的第三方集成,涵盖了数据加载器、LLMs、嵌入模型、向量存储等。
-
llama-index-packs:在这里,您将找到我们的50多个LlamaPacks集合,这些模板旨在启动用户的应用程序。
LlamaHub 将成为所有集成的中央枢纽。
Llama 3
Meta 的 Llama 3 是Llama系列的最新版本,可以通过Hugging Face访问。
Llama 3 有两种尺寸可供选择:8B适用于在消费级GPU上进行精简部署和开发,70B适用于广泛的AI应用。每种尺寸变体都提供基础版本和指令调整版本。
什么是 Qdrant?
Qdrant是一个向量相似度搜索引擎,通过易于使用的API提供了一个生产就绪的服务。它专门用于存储、搜索和管理点(向量)以及附加负载信息。
它经过优化,可以高效地存储和查询高维向量。像 Qdrant 这样的向量数据库利用了专门的数据结构和索引技术。
这些优化使得快速相似度和语义搜索成为可能,允许用户根据指定的距离度量找到与给定查询向量最接近的向量。Qdrant支持的常用距离度量包括欧几里得距离、余弦相似度和点积。
使用的技术栈
-
应用程序框架:Llama-index
-
嵌入模型:BAAI/bge-small-en-v1.5
-
LLM:Meta-Llama-3
-
向量存储:Qdrant
代码实现
安装所需库
%%writefile requirements.txt llama-index llama-index-llms-huggingface llama-index-embeddings-fastembed fastembed Unstructured[md] qdrant llama-index-vector-stores-qdrant einops accelerate sentence-transformers # !pip install -r requirements.txt
accelerate==0.29.3 einops==0.7.0 sentence-transformers==2.7.0 transformers==4.39.3 qdrant-client==1.9.0 llama-index==0.10.32 llama-index-agent-openai==0.2.3 llama-index-cli==0.1.12 llama-index-core==0.10.32 llama-index-embeddings-fastembed==0.1.4 llama-index-legacy==0.9.48 llama-index-llms-huggingface==0.1.4 llama-index-vector-stores-qdrant==0.2.8
下载数据集
!mkdir Data !wget "https://arxiv.org/pdf/1810.04805.pdf" -O Data/arxiv.pdf
加载文档
from llama_index.core import SimpleDirectoryReader documents = SimpleDirectoryReader("/content/Data").load_data()
实例化嵌入模型
from llama_index.embeddings.fastembed import FastEmbedEmbedding from llama_index.core import Settings embed_model = FastEmbedEmbedding(model_name="BAAI/bge-small-en-v1.5") Settings.embed_model = embed_model Settings.chunk_size = 512
定义系统提示
from llama_index.core import PromptTemplate system_prompt = "You are a Q&A assistant. Your goal is to answer questions as accurately as possible based on the instructions and context provided." # This will wrap the default prompts that are internal to llama-index query_wrapper_prompt = PromptTemplate("{query_str}")
实例化LLM
由于我们使用Llama 3作为LLM,我们需要执行以下操作:
-
生成HuggingFace访问令牌
-
请求使用该模型的访问权限
from huggingface_hub import notebook_login notebook_login() import torch from transformers import AutoModelForCausalLM, AutoTokenizer from llama_index.llms.huggingface import HuggingFaceLLM tokenizer = AutoTokenizer.from_pretrained("meta-llama/Meta-Llama-3-8B-Instruct") stopping_ids = [ tokenizer.eos_token_id, tokenizer.convert_tokens_to_ids(""), ] llm = HuggingFaceLLM( context_window=8192, max_new_tokens=256, generate_kwargs={"temperature": 0.7, "do_sample": False}, system_prompt=system_prompt, query_wrapper_prompt=query_wrapper_prompt, tokenizer_name="meta-llama/Meta-Llama-3-8B-Instruct", model_name="meta-llama/Meta-Llama-3-8B-Instruct", device_map="auto", stopping_ids=stopping_ids, tokenizer_kwargs={"max_length": 4096}, # uncomment this if using CUDA to reduce memory usage # model_kwargs={"torch_dtype": torch.float16} ) Settings.llm = llm Settings.chunk_size = 512
实例化向量存储并加载向量嵌入
from IPython.display import Markdown, display from llama_index.core import VectorStoreIndex from llama_index.core import StorageContext from llama_index.vector_stores.qdrant import QdrantVectorStore client = qdrant_client.QdrantClient( # you can use :memory: mode for fast and light-weight experiments, # it does not require to have Qdrant deployed anywhere # but requires qdrant-client >= 1.1.1 location=":memory:" # otherwise set Qdrant instance address with: # url="http://<host>:<port>" # otherwise set Qdrant instance with host and port: # host="localhost", # port=6333 # set API KEY for Qdrant Cloud # api_key=<YOUR API KEY> ) vector_store = QdrantVectorStore(client=client, collection_name="test") storage_context = StorageContext.from_defaults(vector_store=vector_store) index = VectorStoreIndex.from_documents(documents, storage_context=storage_context)
实例化重排序模块
检索模型根据查询的嵌入相似性检索前k个文档。埌用嵌入进行检索有许多好处:
-
它非常高效,特别是在计算点积时,因为在查询时不需要进行任何模型调用。
-
尽管不是完美的,但嵌入可以充分编码文档和查询的语义。这导致嵌入式检索提供高度相关结果的查询子集。
然而,尽管具有这些优点,基于嵌入的检索有时可能不太准确,并返回与查询无关的上下文。这反过来降低了RAG系统的整体质量,而不论LLM的质量如何。
在这种方法中,我们实施了一个两阶段检索过程。
第一阶段采用了基于嵌入的检索,具有较高的top-k值,以优先考虑召回率,即使以较低的精度为代价。
随后,第二阶段采用了略微更具计算密集性的过程,强调精度而不是召回率。该阶段旨在“重新排列”最初检索到的候选项,增强最终结果的质量。
实例化查询引擎
import time query_engine = index.as_query_engine(similarity_top_k=10, node_postprocessors=[rerank])
提问问题1
now = time.time() response = query_engine.query("What is instruction finetuning?") print(f"Response Generated: {response}") print(f"Elapsed: {round(time.time() - now, 2)}s")
提问问题2
now = time.time() response = query_engine.query("Describe the Feature-based Approach with BERT??") print(f"Response Generated: {response}") print(f"Elapsed: {round(time.time() - now, 2)}s")
提问问题3
now = time.time() response = query_engine.query("What is SQuADv2.0?") print(f"Response Generated: {response}") print(f"Elapsed: {round(time.time() - now, 2)}s")
结论
在这里,我们开发了一个基于私有数据运行的高级RAG问答系统。
我们将 LlamaIndex 重新排列概念纳入其中,以优先考虑从检索器检索到的上下文中最相关的上下文。这种方法确保了生成响应的事实准确性。
如何学习大模型 AI ?
由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。
但是具体到个人,只能说是:
“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。
这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。
我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。
我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。
第一阶段(10天):初阶应用
该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。
- 大模型 AI 能干什么?
- 大模型是怎样获得「智能」的?
- 用好 AI 的核心心法
- 大模型应用业务架构
- 大模型应用技术架构
- 代码示例:向 GPT-3.5 灌入新知识
- 提示工程的意义和核心思想
- Prompt 典型构成
- 指令调优方法论
- 思维链和思维树
- Prompt 攻击和防范
- …
第二阶段(30天):高阶应用
该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。
- 为什么要做 RAG
- 搭建一个简单的 ChatPDF
- 检索的基础概念
- 什么是向量表示(Embeddings)
- 向量数据库与向量检索
- 基于向量检索的 RAG
- 搭建 RAG 系统的扩展知识
- 混合检索与 RAG-Fusion 简介
- 向量模型本地部署
- …
第三阶段(30天):模型训练
恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。
到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?
- 为什么要做 RAG
- 什么是模型
- 什么是模型训练
- 求解器 & 损失函数简介
- 小实验2:手写一个简单的神经网络并训练它
- 什么是训练/预训练/微调/轻量化微调
- Transformer结构简介
- 轻量化微调
- 实验数据集的构建
- …
第四阶段(20天):商业闭环
对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。
- 硬件选型
- 带你了解全球大模型
- 使用国产大模型服务
- 搭建 OpenAI 代理
- 热身:基于阿里云 PAI 部署 Stable Diffusion
- 在本地计算机运行大模型
- 大模型的私有化部署
- 基于 vLLM 部署大模型
- 案例:如何优雅地在阿里云私有部署开源大模型
- 部署一套开源 LLM 项目
- 内容安全
- 互联网信息服务算法备案
- …
学习是一个过程,只要学习就会有挑战。天道酬勤,你越努力,就会成为越优秀的自己。
如果你能在15天内完成所有的任务,那你堪称天才。然而,如果你能完成 60-70% 的内容,你就已经开始具备成为一名大模型 AI 的正确特征了。