第一章:为什么要给大模型喂"额外营养"?
构想一下,你有一个超级自动的AI助手,它简直一无所知。但当你问它"当天的股市行情如何?"或许"最新的新冠病毒变种有哪些症状?",它却一脸茫然。这就是大言语模型(LLM)的现状 - 常识博大但不够新颖。
这就是为什么咱们须要给LLM喂点"额外营养",也就是外部数据。这个环节,专业点说叫"检索增强生成"(RAG)。
首先,让咱们聊聊为什么要这么做:
1.1 让AI变得更"专业"
LLM只管懂得多,但在专业畛域或许还不如一个刚毕业的在校生。构想你在开发一个法律AI助手,假设它连最新的法律订正都不知道,那不就成了法庭上的笑话吗?
举个例子:假定有一个新的环保法规**。传统LLM或许齐全不知道,但经常使用RAG的系统可以迅速学习并运行这个新规则。这就是外部数据的威力 - 它能让AI极速成为各行各业的"专家"。
1.2 坚持AI的"时兴度"
AI环球开展太快了,昨天的资讯当天就成了旧闻。假设你的AI还在议论2020年的事件,那就真的out了。
比如,假设你问AI:"最新的AI打破是什么?",传统LLM或许还在谈GPT-3,而经常使用RAG的系统曾经能讨论GPT-4、DALL-E 3等最新停顿。
1.3 缩小AI的"空想症"
LLM有时刻会自信满满地胡言乱语,这在AI圈叫"幻觉"。给它喂点靠谱的外部数据,就能大大缩小这种状况。
假设你在做医疗诊断,AI胡乱猜想症状可是会出人命的。经常使用RAG,AI可以基于最新的医学钻研来给出倡导,大大提高了牢靠性。
听起来很美妙,对吧?然而,成功起来可没那么容易。这就像是给大象装上显微镜 - 既要坚持大象的力气,又要施展显微镜的精准。
首先,你得预备海量的高品质数据。咱们说的不是几个 word,而是至少笼罩业务场景的数据量。数据从哪来?爬虫、购置、协作失掉,方法多得是。但要小心,爬虫爬着爬着,搞不好律师函就来了。所以,找专业的数据团队来处置这事儿准没错。
而后,你得建设一个超级高效的检索系统。这就像是给AI配了个24小时不睡觉的图书治理员,随时预备找出最相关的消息。
最后,还得想方法让AI"了解"这些新消息。这可不是便捷的复制粘贴,而是要让AI真正排汇这些常识,并在回答疑问时能灵敏运用。
听起来很难?确实如此。在各个专业畛域部署这样的系统,面临的应战可不少:
给LLM喂"额外营养"的后劲是渺小的,但应战也不小。谁能处置这些疑问,谁就或许成为下一个AI畛域的巨头。
第二章:RAG不是一刀切 - 四个档次的查问分类
在下面,咱们了解了为什么要给大模型喂"额外营养"。然而,就像人类的饮食须要依据不同状况调整一样,RAG系统也须要依据不同类型的查问来调整其战略。
假设你正在开发一个全能型AI助手。有时刻用户或许会问"2023年诺贝尔文学奖得主是谁?",有时刻或许会问"为什么量子计算机比传统计算机快?"。这两种疑问显然须要不同的处置形式,对吧。
基于这种思索,论文将用户查问分为四个档次。让咱们逐个深化讨论:
2.1 显式理想查问
这是最间接的查问类型。用户问的是明白的、可以间接在数据中找到答案的疑问。
例如:"东京奥运会是哪一年举行的?"
关于这类查问,RAG系统的义务相对便捷:
成功这类查问的关键在于高效的消息检索系统。你或许须要经常使用倒排索引、向量检索等技术来减速查找环节。
2.2 隐式理想查问
这类查问只管也是关于理想的,但答案并不能间接在繁多数据点中找到,须要综合多个消息。
例如:"哪个国度在过去十年的奥运会上取得的金牌总数最多?"
处置这类查问的应战在于:
这就须要RAG系统具有必定的数据处置和便捷推理才干。你或许须要成功一些轻量级的数据剖析配置,如聚合、排序等。
2.3 可解释推理查问
这类查问不只须要理想,还须要解释或推理。答案通常须要基于某些明白的规则或指南。
例如:"依据现行法律,一个18岁的人可以在美国哪些州非法购置酒精饮料?"
处置这类查问的难点在于:
这种查问或许须要你成功一些规则引擎或决策树,以模拟人类的推理环节。
2.4 暗藏推理查问
这是最复杂的查问类型。答案不只须要少量的背景常识,还须要复杂的推理环节,而这些推理环节或许并不明白。
例如:"思索到环球气象变动,未来20年内北极熊的生活前景如何?"
处置这类查问的应战在于:
成功这类查问的RAG系统或许须要联合多种AI技术,如因果推理模型、情形模拟等。你或许还须要成功一种"思想链"(Chain of Thought)机制,让AI能够逐渐推理并解释其推理环节。
总结一下,这四个档次的查问分类方法让咱们能够更有针对性地设计和优化RAG系统。从便捷的理想检索到复杂的推理义务,每一层都有其共同的应战和处置打算。
在实践运行中,一个成熟的RAG系统往往须要能够处置一切这四个档次的查问。这就像是在训练一个全能静止员 - 既要能短跑,又要能马拉松,还得会游泳和举重。听起来很难?确实如此。然而,正是这种应战让AI钻研如此激动人心。
第三章:深化RAG的四个档次 - 从定义到处置打算
咱们概述了RAG义务的四个档次。如今,让咱们卷起袖子,深化每个档次的技术细节。预备好你的工程师思想,咱们要开局真正的技术探求了!
3.1 显式理想查问
定义和特色:这是最基础的查问类型,答案间接存在于外部数据中。特色是查问和答案之间存在间接的文本婚配相关。
例如:Query: "谁发明了电话?" Answer: "亚历山大·格雷厄姆·贝尔发明了电话。"
相关数据集:
这些数据集蕴含少量的问答对,十分适宜训练和评价处置显式理想查问的模型。
关键应战:
最有效的处置技术:
代码示例(经常使用Haystack框架):
from haystack import Pipelinefrom haystack.nodes import BM25Retriever, FARMReaderretriever = BM25Retriever(document_store)reader = FARMReader("deepset/roberta-base-squad2")pipe = Pipeline()pipe.add_node(compnotallow=retriever,, inputs=["Query"])pipe.add_node(compnotallow=reader,, inputs=["Retriever"])result = pipe.run(query="谁发明了电话?")print(result['answers'][0].answer)
3.2 隐式理想查问
定义和特色:这类查问的答案须要综合多个消息源。特色是须要启动便捷的推理或计算。
例如:Query: "哪个国度在2020年奥运会上取得的金牌最多?"Answer: 须要检索多个国度的金牌数据,并启动比拟。
相关数据集:
这些数据集蕴含须要多跳推理的疑问,很适宜训练处置隐式理想查问的模型。
关键应战:
最有效的处置技术:
代码示例(经常使用DeepsetAI的Haystack框架):
from haystack import Pipelinefrom haystack.nodes import BM25Retriever, FARMReader, JoinDocumentsretriever = BM25Retriever(document_store)reader = FARMReader("deepset/roberta-base-squad2")joiner = JoinDocuments(join_mode="concatenate")pipe = Pipeline()pipe.add_node(compnotallow=retriever,, inputs=["Query"])pipe.add_node(compnotallow=joiner,, inputs=["Retriever"])pipe.add_node(compnotallow=reader,, inputs=["Joiner"])result = pipe.run(query="哪个国度在2020年奥运会上取得的金牌最多?")print(result['answers'][0].answer)
3.3 可解释推理查问
定义和特色:这类查问须要基于特定规则或指南启动推理。特色是须要运行畛域常识和逻辑推理。
例如:Query: "依据现行法律,一个年支出5万美元的独身人士在加利福尼亚州须要交纳多少所得税?"Answer: 须要检索税法,了解税率表,并启动相应计算。
相关数据集:
这些数据集蕴含须要逻辑推理的疑问,适宜训练处置可解释推理查问的模型。
关键应战:
最有效的处置技术:
代码示例(经常使用GPT-3启动Chain-of-Thought推理):
import openaiopenai.api_key = "your-api-key"prompt = """Query: 依据现行法律,一个年支出5万美元的独身人士在加利福尼亚州须要交纳多少所得税?Let's approach this step-by-step:1) First, we need to know the California state income tax brackets for single filers.2) Then, we'll calculate the tax for each bracket up to $50,000.3) Finally, we'll sum up the tax amounts.Step 1: California tax brackets for single filers (2021):- 1% on the first $8,932 of taxable income- 2% on taxable income between $8,933 and $21,175- 4% on taxable income between $21,176 and $33,421- 6% on taxable income between $33,422 and $46,394- 8% on taxable income between $46,395 and $50,000Step 2: Calculate tax for each bracket:- 1% of $8,932 = $89.32- 2% of ($21,175 - $8,933) = $244.84- 4% of ($33,421 - $21,176) = $489.80- 6% of ($46,394 - $33,422) = $778.32- 8% of ($50,000 - $46,395) = $288.40Step 3: Sum up the tax amounts:$89.32 + $244.84 + $489.80 + $778.32 + $288.40 = $1,890.68Therefore, a single person with an annual income of $50,000 in California would owe approximately $1,890.68 in state income tax.Note: This is a simplified calculation and doesn't account for deductions, credits, or other factors that might affect the actual tax liability."""response = openai.Completion.create(engine="gpt4",prompt=prompt,max_tokens=500)print(response.choices[0].text.strip())
暗藏推理查问
定义和特色:这是最复杂的查问类型,须要少量背景常识和复杂的推理环节。特色是推理环节往往不是明白的,须要模型自行发现和运行隐含的常识和相关。
例如:Query: "思索到环球气象变动和人类优惠,预测未来50年内亚马逊雨林的变动。"Answer: 须要综合气象迷信、生态学、社会学等多个畛域的常识,启动复杂的因果推理和预测。
相关数据集:
这些数据集蕴含须要宽泛常识和复杂推理的疑问,适宜训练处置暗藏推理查问的模型。
关键应战:
最有效的处置技术:
代码示例(经常使用Hugging Face的Transformers库和GPT-4):
transformers pipeline openaisummarizer pipeline model# 假定咱们有多个相关文档documents "气象变动正在减速亚马逊雨林的退步...""人类优惠,如砍伐和农业扩张,正在要挟亚马逊雨林...""一些钻研标明,亚马逊雨林或许会在未来几十年内到达临界点..."summaries summarizerdoc max_length min_length do_sample doc documents# 经常使用GPT-3启动最终的综合剖析openaiapi_key prompt fresponse openaiCompletionpromptpromptmax_tokensresponsechoicesstrip
以上的例子展现了如何联合经常使用预训练模型启动文本总结,而后经常使用更弱小的言语模型(如GPT-4)启动复杂的推理和预测。经过深化了解这四个档次的查问,咱们可以看到RAG系统面临的应战是多方面的,从便捷的消息检索到复杂的常识整合和推理。每一个档次都须要特定的技术和方法来处置其共同的应战。
在实践运行中,一个成熟的RAG系统往往须要能够处置一切这四个档次的查问。这就要求咱们始终翻新和改良现有的技术,同时也为AI钻研开拓了宽广的前景。
第四章:数据与LLM的三种"联姻"形式
在前面的内容中,咱们讨论了RAG系统如何处置不同档次的查问。如今,让咱们转向一个愈加基本的疑问:假设失掉到数据后,如何将外部数据与LLM联合起来?论文提出了三种关键的方法,每种方法都有其共同的长处和应战。让咱们逐个深化讨论。
4.1 高低文方法(Context)
这种方法就像是给LLM一个即时的"记忆补丁"。每次征询LLM时,咱们都会同时提供相关的高低文消息。
上班原理:
长处:
应战:
成功示例:
transformers AutoTokenizer AutoModelForCausalLM torchtokenizer AutoTokenizerfrom_pretrainedmodel AutoModelForCausalLMfrom_pretraineddef get_contextquery:# 这里应该是你的检索逻辑 query context get_contextqueryinput_text finput_ids tokenizerencodeinput_text return_tensorsoutput modelgenerateinput_ids max_length num_return_sequences no_repeat_ngram_sizeresponse tokenizerdecodeoutput skip_special_tokensresponse
4.2 小模型方法(Small model)
这种方法就像是给LLM装备了一个专业的"助手"。咱们训练一个小型模型来处置特定义务,如消息检索或常识整合,而后将这个小模型的输入提供应LLM。
上班原理:
长处:
应战:
成功示例:
transformers AutoTokenizer AutoModel AutoModelForCausalLM torch# 假定这是咱们的小模型,用于生成查问的向量示意retriever_tokenizer AutoTokenizerfrom_pretrainedretriever_model AutoModelfrom_pretrainedlm_tokenizer AutoTokenizerfrom_pretrainedlm_model AutoModelForCausalLMfrom_pretraineddef get_query_embeddingquery:inputs retriever_tokenizerquery return_tensors padding truncatinotallow torchno_grad:outputs retriever_modelinputs outputslast_hidden_statemeandimquery query_embedding get_query_embeddingquery# 在实践运行中,咱们会用这个嵌入来检索相关文档# 这里咱们便捷地假定咱们失掉了一些相关消息retrieved_info "量子计算是应用量子力学现象启动计算的技术..."input_text f"基于以下消息:{retrieved_info}\n回答疑问:{query}"input_ids lm_tokenizerencodeinput_text return_tensorsoutput lm_modelgenerateinput_ids max_length num_return_sequences no_repeat_ngram_sizeresponse lm_tokenizerdecodeoutput skip_special_tokensresponse
4.3 微调方法(Fine-tuning)
这种方法就像是给LLM启动"专业培训"。咱们经常使用特定畛域的数据对预训练的LLM进后退一步的训练,使其能够更好地处置特定类型的义务或畛域常识。
上班原理:
长处:
应战:
成功示例:
from transformers import AutoTokenizer, AutoModelForCausalLM, TrainingArguments, Trainerimport torchfrom, truncatinotallow=True)tokenized_datasets =,num_train_epochs=3,per_device_train_batch_size=8,per_device_eval_batch_size=8,warmup_steps=500,weight_decay=0.01,logging_dir="./logs",)# 创立Trainertrainer = Trainer(model=model,args=training_args,train_dataset=tokenized_datasets["train"],eval_dataset=tokenized_datasets["test"],)# 开局微调trainer.train()# 经常使用微调后的模型query = "什么是量子纠缠?"input_ids = tokenizer.encode(query, return_tensors="pt")output = model.generate(input_ids, max_length=200, num_return_sequences=1, no_repeat_ngram_size=2)response = tokenizer.decode(output[0], skip_special_tokens=True)print(response)
每种方法都有其实用的场景:
在实践运行中,这三种方法往往是联合经常使用的。例如,咱们或许会先对LLM启动畛域微调,而后在经常使用时还配合高低文方法提供最新消息。或许,咱们或许会经常使用经过微调的小模型来启动检索,而后将检索结果作为高低文提供应关键的LLM。
选用哪种方法,或如何组合这些方法,取决于详细的运行需求、可用资源、以及对模型性能、效率和灵敏性的掂量。
第五章:RAG的艺术 - 从通常到通常的整合之道
咱们将把前面所学的一切概念串联起来,看看如何在实践中运用这些常识。系好安保带,咱们开局这段激动人心的旅程吧!
5.1 三种整合形式的利害掂量
还记得咱们讨论过的三种将外部数据整合到LLM中的形式吗?让咱们再深化讨论一下它们各自的优缺陷和实用场景。
长处:
- 灵敏性拉满:想换数据就换,LLM齐全不用动- 透明度高:咱们分明地知道模型用了哪些额外消息
局限性:
- 高低文长度有限:就像塞鸭子,塞太多LLM也消化不了- 检索品质选择生死:渣滓进渣滓出,检索不好全盘皆输
实用场景:
- 须要频繁降级常识库的运行- 对结果可解释性要求高的场景
长处:
- 专业性强:可认为特定义务定制"小助手"- 模块化设计:想换就换,主LLM不受影响
局限性:
- 训练老本高:又要预备数据又要训练,累死团体- 集成难度大:让"小助手"和LLM无缝配合不是易事
实用场景:
- 有特定复杂义务须要处置的运行- 计算资源有限,不可频繁调用大型LLM的状况
长处:
- 性能王者:在特定畛域可以到达最佳体现- 推理效率高:不须要额外的检索步骤
局限性:
- 计算老本高:微调大模型,没个几千块GPU别想了- 灵敏性降低:一旦微调,或许会影响其余畛域的体现
实用场景:
- 特定畛域的专业运行- 有少量高品质畛域数据可用的状况
5.2 四个查问档次的技术打算
如今,让咱们看看如何针对不同复杂度的查问选用适宜的技术打算。
from haystack import Pipelinefrom haystack.nodes import BM25Retriever, FARMReaderretriever = BM25Retriever(document_store)reader = FARMReader("deepset/roberta-base-squad2")pipe = Pipeline()pipe.add_node(compnotallow=retriever,, inputs=["Query"])pipe.add_node(compnotallow=reader,, inputs=["Retriever"])result = pipe.run(query="谁发明了电话?")print(result['answers'][0].answer)
代码示例(迭代RAG):
def iterative_rag(query, max_iteratinotallow=3):context = ""for i in range(max_iterations):result = pipe.run(query=query + " " + context)new_info = result['answers'][0].answercontext += new_infoif "完整回答" in new_info:breakreturn contextfinal_answer = iterative_rag("比拟太阳系中最大和最小的行星")print(final_answer)
- 迭代RAG:多轮检索,每轮基于之前的结果继续深化- 图/树RAG:构建常识图谱,启动多跳推理- RAG+SQL:联合结构化数据查问,处置复杂的数值计算
代码示例(思想链揭示):
prompt = """疑问:一个水箱可以在6小时内装满水。如今曾经装了2小时,还剩下3/4没装满。请问这个水箱实践上须要多长期间才干装满?让咱们一步步思索:1) 首先,咱们知道反常状况下,水箱须要6小古装满。2) 如今曾经装了2小时,还剩3/4没装满。3) 这象征着2小时内只装满了1/4的水箱。4) 假设2小古装满1/4,那么装满整个水箱须要的期间是:2小时 * 4 = 8小时因此,这个水箱实践上须要8小时才干装满。能否须要我进一步解释这个推理环节?"""response = openai.Completion.create(engine="gpt4", prompt=prompt, max_tokens=150)print(response.choices[0].text.strip())
- 揭示调优:设计特定的揭示模板,疏导LLM启动推理- 思想链揭示:让LLM像人类一样,一步步写出推理环节
代码示例(微调):
from transformers import AutoTokenizer, AutoModelForCausalLM, TrainingArguments, Trainermodel_name = "gpt2"tokenizer = AutoTokenizer.from_pretrained(model_name)model = AutoModelForCausalLM.from_pretrained(model_name)# 预备特定畛域的数据集train_dataset = ...# 你的训练数据eval_dataset = ...# 你的评价数据training_args = TrainingArguments(output_dir="./results", num_train_epochs=3, per_device_train_batch_size=8)trainer = Trainer(model=model, args=training_args, train_dataset=train_dataset, eval_dataset=eval_dataset)trainer.train()# 经常使用微调后的模型query = "预测未来5年的环球经济趋向"input_ids = tokenizer.encode(query, return_tensors="pt")output = model.generate(input_ids, max_length=200)print(tokenizer.decode(output[0], skip_special_tokens=True))
- 离线学习:预先学习畛域常识,构建专门的常识库- 高低文学习:灵活选用最相关的高低文启动学习- 微调:在特定畛域数据上微调LLM
5.3 知己知彼,百战不殆
在开发RAG运行之前,咱们须要做的第一件事是什么?没错,就是深化了解咱们要处置的疑问。这就像是要打仗前先要了解敌情一样关键。
只要充沛了解了这些起因,咱们才干选用最适宜的技术打算。记住,没有一种方法是万能的,关键是找到最适宜你特定需求的方法。
5.4 大杂烩才是真正的美味
在实践运行中,咱们经常会遇到各种类型的查问混同在一同的状况。这就像是要做一道大杂烩,须要各种食材和调料的完美配合。
咱们须要设计一个自动的路由系统,能够识别不同类型的查问,并将其导向最适宜的处置模块。这个系统或许看起来像这样:
def query_router(query):if is_simple_fact_query(query):return basic_rag(query)elif is_implicit_fact_query(query):return iterative_rag(query)elif is_interpretable_reasoning_query(query):return chain_of_thought_prompting(query)elif is_hidden_reasoning_query(query):return fine_tuned_model(query)else:return fallback_method(query)def process_query(query):response = query_router(query)return post_process(response)# 经常使用示例user_query = "请解释量子纠缠的原理及其在量子计算中的运行"answer = process_query(user_query)print(answer)
这个路由系统就像是一个阅历丰盛的总厨,知道每种原料应该如何处置,最终做出一道美味的大餐。
结语
构建一个低劣的RAG系统,就像是在启动一场复杂的厨艺较量。你须要了解每种原料(数据)的个性,把握各种烹饪技巧(技术方法),并且要有足够的创意来应答各种应战。
记住,通常和通常雷同关键。多尝试,多总结,你就会发现RAG的魅力所在。谁知道呢,或许兴许下一个扭转AI环球的打破,就来自于你的灵感。
论文原文:
《Retrieval Augmented Generation (RAG) and Beyond:A Comprehensive Survey on How to Make your LLMs use External>本文转载自,作者: