RAG(检索增强生成)是结合检索与生成式 AI 的技术框架。核心逻辑是先从外部知识库精准检索相关信息,再将其作为上下文输入大模型生成回答。技术上依赖检索引擎(如向量数据库、BM25)、大语言模型(如 GPT、LLaMA)及数据预处理技术。通过检索增强,解决大模型知识滞后、幻觉问题,提升回答准确性。应用广泛,涵盖智能客服、医疗问答、法律检索、教育辅导等场景,能基于特定领域知识提供精准、可控的生成内容。
wow-RAG 是 Datawhale 推出的 RAG 技术实践项目,网址:datawhalechina/wow-rag: A simple and trans-platform rag framework and tutorial https://github.com/datawhalechina/wow-rag
选择文档
我们从网络上或其他途径选定一个文档,txt格式的。在jupyter notebook主目录下新建一个docs文件夹,把.txt文件放进去。
# 从指定文件读取,输入为List
from llama_index.core import SimpleDirectoryReader,Document
documents = SimpleDirectoryReader(input_files=['./docs/大模型推理.txt']).load_data()
创建 SimpleDirectoryReader 实例,通过 input_files 参数指定要读取的单个文件:./docs/大模型推理.txt;调用 load_data() 方法读取文件内容并转换为文档对象列表
可能出现的报错
这一步可能遇到的报错为:
ValueError: numpy.dtype size changed, may indicate binary incompatibility. Expected 96 from C header, got 88 from PyObject
错误根源是 NumPy 和 Pandas 版本不兼容 导致的二进制接口冲突
Pandas 依赖 NumPy 的底层二进制接口,但当前安装的 NumPy 和 Pandas 版本不匹配(可能是 NumPy 版本过旧,或 Pandas 版本过新导致不兼容)。
该错误并非 llama_index 直接引起,而是数据处理库的依赖冲突导致 llama_index 的文件读取功能无法正常加载(因为 SimpleDirectoryReader 依赖 Pandas 处理表格类文件)。
可以运行以下代码来检查版本:
import numpy as np
import pandas as pd
import scipyprint(f"NumPy 版本: {np.__version__}") # 需显示 1.26.x
print(f"Pandas 版本: {pd.__version__}") # 建议 2.0.x ~ 2.2.x
print(f"SciPy 版本: {scipy.__version__}") # 建议 1.11.x
SciPy 对 NumPy 版本有严格限制,必须将 NumPy 降级到 1.26.x
系列(既满足 SciPy 要求,又能兼容 Pandas):
# 强制卸载当前 NumPy 并安装兼容版本
pip uninstall -y numpy
pip install numpy==1.26.4 # 此版本与 SciPy、Pandas 兼容性最佳
pip安装后应该restart kernel来应用改变
显示为这样就没问题了
构建向量索引
# 构建向量索引
from llama_index.core import VectorStoreIndex
#index = VectorStoreIndex.from_documents(documents,embed_model=embedding)
# 想要看到进度条的话,加一个参数 show_progress=True
index = VectorStoreIndex.from_documents(documents,embed_model=embedding,show_progress=True)
向量索引:将文本内容转换为高维向量(嵌入向量),并建立索引结构,以便快速检索语义相似的文本片段。
from_documents() :
输入:documents:上一步加载的文档对象列表(来自 SimpleDirectoryReader)。embed_model=embedding:指定用于文本向量化的嵌入模型(需提前定义,如 embedding = OpenAIEmbedding())。
功能:将文档内容分割为更小的文本块(如段落、句子)。使用 embed_model 将每个文本块转换为向量表示。将向量存储到索引结构中,支持快速相似度检索。
输出:返回一个 VectorStoreIndex 对象(存储在 index 变量中)。
Parsing nodes(解析节点): 这是构建索引的第一步,LlamaIndex 会对输入的 documents 文档列表进行预处理,将原始文档分割为更小的文本单元(称为 “节点”,Node)。节点是向量索引的基本处理单位(通常对应段落、句子或固定长度的文本片段)
Generating embeddings(生成嵌入向量):这是构建索引的核心步骤,LlamaIndex 会调用指定的 embed_model(嵌入模型),将上一步解析出的所有节点(文本片段)转换为高维向量(嵌入向量)。这些向量是后续语义检索的基础。
问答
query_engine = index.as_query_engine(llm=llm)
# 回答提问
response = query_engine.query("大模型推理是什么?")
response
index.as_query_engine() 将之前构建的向量索引(index)转换为可执行查询的引擎。
llm=llm 参数:显式指定用于生成回答的大语言模型(LLM)。若不指定 llm,LlamaIndex 会使用默认模型(通常是 OpenAI 的 GPT 系列)。
Response(response='大模型推理指的是一种在回答问题前,将问题拆解为更小的推理步骤或思考过程的方法。这种模型不仅学习如何给出答案,还学习如何通过一系列逻辑步骤进行推理。简而言之,大模型推理是一种结合了推理过程和答案输出的方法,旨在提高模型回答问题的透明度和可解释性。', source_nodes=[NodeWithScore(node=TextNode(id_='c4b39c48-0d68-4ad4-a6b8-066d2996982d', embedding=None, metadata={'file_path': 'docs\\大模型推理.txt', 'file_name': '大模型推理.txt', 'file_type': 'text/plain', 'file_size': 22722, 'creation_date': '2025-07-21', 'last_modified_date': '2025-07-21'}, excluded_embed_metadata_keys=['file_name', 'file_type', 'file_size', 'creation_date', 'last_modified_date', 'last_accessed_date'], excluded_llm_metadata_keys=['file_name', 'file_type', 'file_size', 'creation_date', 'last_modified_date', 'last_accessed_date'], relationships={<NodeRelationship.SOURCE: '1'>: RelatedNodeInfo(node_id='b0e1d00f-4808-4606-b5ea-f38cf6522f83', node_type='4', metadata={'file_path': 'docs\\大模型推理.txt', 'file_name': '大模型推理.txt', 'file_type': 'text/plain', 'file_size': 22722, 'creation_date': '2025-07-21', 'last_modified_date': '2025-07-21'}, hash='fc891f08c5725428a6ea72c71b389cb0a718156509c4b2a4c42db880268b6595'), <NodeRelationship.NEXT: '3'>: RelatedNodeInfo(node_id='c41f7751-4d0b-4644-afa4-1336c6754a74', node_type='1', metadata={}, hash='b12dc0fd22c420bcfefb4bf02ea246dc75127380caad1c4c69d8547ff3c6a6f5')}, metadata_template='{key}: {value}', metadata_separator='\n', text='总的来说,大模型可以分为常规大模型和推理型大模型,我们大多数人口中的大模型一般都是指常规大模型,本文重点介绍推理型大模型,并尽可能将大模型的推理过程解释清楚,最后再来说说deepseek为什么能成功,用了哪些技术。\r\n\r\n什么是推理型大模型\r\n与常规 LLM 相比,推理型 LLM 在回答问题前,往往会先将问题拆解为更小的步骤(通常称为推理步骤或思考过程),也可以说是思维链COT。\r\n\r\n\r\n普通大模型直接给出答案,没有给出求解过程。推理型大模型会将推理过程和答案一起输出。那么,“思考过程”、“推理步骤”或“思维链”(CoT, Chain-of-Thought)究竟意味着什么?\r\n\r\n\r\n我在之前的复旦大学文章中也提到过过思维链,可以说某种程度上,思维链直接决定了大模型的推理规划能力:\r\n\r\n\r\n爱吃牛油果的璐璐:细说复旦大学,斯坦福大学智能代理AI-Agent(二更)\r\n280 赞同 · 16 评论文章\r\n\r\n爱吃牛油果的璐璐:大模型中的思维链、思维树、思维图\r\n19 赞同 · 2 评论文章\r\n虽然我们可以探讨大模型是否真的能像人类那样思考,但这些步骤将整个过程拆解为更小,且结构化的推理。推理型大模型不仅学习“回答什么”,更学习“如何回答”。\r\n\r\n\r\n为了理解推理型大模型的构建过程,我们首先需要探讨一个范式转变。\r\n\r\nTrain-time compute 到 Test-time compute\r\n大模型从关注训练阶段的扩展(训练时计算)转向关注推理阶段(测试时计算),下面对两者分别进行介绍。\r\n\r\n训练时计算:Train-time compute\r\n在 2024 年上半年之前,为了提升大模型在预训练阶段的性能,开发者通常会增加以下几个方面的规模:\r\n\r\n• 模型参数(parameters)\r\n\r\n• 数据集(tokens )\r\n\r\n• 计算量(FLOPs )\r\n\r\n这三者合称为训练时计算(train-time compute),它体现了预训练数据作为“ AI 之燃料”的理念。基本上,预训练投入越大,最终得到的模型就会越出色。\r\n\r\n\r\n训练时计算不仅包括训练期间所需的计算量,还涵盖了微调时所需的计算量。\r\n\r\n\r\n长期以来,这些因素一直是提升 LLMs 性能的关键。研究人员通过各种 Scaling Law 探讨模型规模(包括计算量、数据集大小和模型参数数量)与模型性能之间的关系。这些定律属于所谓的“幂律”:某一变量(例如计算量)的增加会导致另一变量(例如性能)按比例发生变化。\r\n\r\n\r\n通常,这些关系会在对数-对数坐标系下展示(呈现直线),以突出计算量的大幅增加。', mimetype='text/plain', start_char_idx=0, end_char_idx=1103, metadata_seperator='\n', text_template='{metadata_str}\n\n{content}'), score=0.6528139357784619), NodeWithScore(node=TextNode(id_='82ac4f70-ec78-499f-9d5e-04cbec54208c', embedding=None, metadata={'file_path': 'docs\\大模型推理.txt', 'file_name': '大模型推理.txt', 'file_type': 'text/plain', 'file_size': 22722, 'creation_date': '2025-07-21', 'last_modified_date': '2025-07-21'}, excluded_embed_metadata_keys=['file_name', 'file_type', 'file_size', 'creation_date', 'last_modified_date', 'last_accessed_date'], excluded_llm_metadata_keys=['file_name', 'file_type', 'file_size', 'creation_date', 'last_modified_date', 'last_accessed_date'], relationships={<NodeRelationship.SOURCE: '1'>: RelatedNodeInfo(node_id='b0e1d00f-4808-4606-b5ea-f38cf6522f83', node_type='4', metadata={'file_path': 'docs\\大模型推理.txt', 'file_name': '大模型推理.txt', 'file_type': 'text/plain', 'file_size': 22722, 'creation_date': '2025-07-21', 'last_modified_date': '2025-07-21'}, hash='fc891f08c5725428a6ea72c71b389cb0a718156509c4b2a4c42db880268b6595'), <NodeRelationship.PREVIOUS: '2'>: RelatedNodeInfo(node_id='87986d57-a6cc-4617-8958-00d597301f3e', node_type='1', metadata={'file_path': 'docs\\大模型推理.txt', 'file_name': '大模型推理.txt', 'file_type': 'text/plain', 'file_size': 22722, 'creation_date': '2025-07-21', 'last_modified_date': '2025-07-21'}, hash='63a1927e6be275695f51cfcc2e469dfbe8aec9a18bdd496632b388b953b6ef75')}, metadata_template='{key}: {value}', metadata_separator='\n', text='使用之前提到的 80 万高质量数据样本(其中 60 万条推理示例 + 20 万条非推理示例)进行训练。\r\n\r\n\r\n2. 学生模型通过不断对比自己的输出分布和教师模型的输出分布,来学习 DeepSeek-R1 的推理方式。\r\n\r\n这样“蒸馏”出来的小模型性能依旧出色,因为它不仅学到了 80 万条数据中的知识,还学到了 DeepSeek-R1 如何作答的思路。\r\n\r\nDeepSeek不太成功的尝试\r\n还记得我们之前提到的 过程奖励模型(PRMs) 和 蒙特卡洛树搜索(MCTS) 吗?DeepSeek 团队也曾试图用这些方法来培养模型的推理能力,但并未取得理想成果。\r\n\r\n在 MCTS 中,由于搜索空间极其庞大,研究人员不得不大幅限制节点扩展。此外,训练一个能够细化评估推理过程的奖励模型本身就是一项困难的任务。\r\n\r\n在结合 PRMs 的 Best-of-N 技术中,他们遇到的主要问题是计算开销过高,需要频繁地对奖励模型进行再训练,以防止出现所谓的 “reward-hacking”(对奖励函数的漏洞进行投机利用)。\r\n\r\n这并不代表这些技术就完全不适用,但至少说明了它们在实际应用中面临着一些挑战。\r\n\r\n结语\r\n以上就是关于推理型大模型的概念与 DeepSeek-R1 的有关介绍。希望这篇内容能帮助你更好地理解 “测试时计算扩展” 的潜力所在。也再次感谢为大模型探索道路上做出贡献和努力的研究者们,像你们致敬!', mimetype='text/plain', start_char_idx=9003, end_char_idx=9614, metadata_seperator='\n', text_template='{metadata_str}\n\n{content}'), score=0.5625440768569911)], metadata={'c4b39c48-0d68-4ad4-a6b8-066d2996982d': {'file_path': 'docs\\大模型推理.txt', 'file_name': '大模型推理.txt', 'file_type': 'text/plain', 'file_size': 22722, 'creation_date': '2025-07-21', 'last_modified_date': '2025-07-21'}, '82ac4f70-ec78-499f-9d5e-04cbec54208c': {'file_path': 'docs\\大模型推理.txt', 'file_name': '大模型推理.txt', 'file_type': 'text/plain', 'file_size': 22722, 'creation_date': '2025-07-21', 'last_modified_date': '2025-07-21'}})
Response 对象由三个关键部分组成:
response:生成的自然语言回答内容。
source_nodes:LLM 生成回答时参考的文档节点(文本片段)。
metadata:源文档的元数据信息(如文件路径、大小等)。
source_nodes 表示引用的文档节点,这是一个包含 NodeWithScore 对象的列表,每个对象代表一个被检索到的相关文本片段,包含 文本内容 和 匹配分数。
NodeWithScore(node=TextNode(id_='c4b39c48-0d68-4ad4-a6b8-066d2996982d', # 节点唯一标识text='总的来说,大模型可以分为常规大模型和推理型大模型...推理型大模型不仅学习“回答什么”,更学习“如何回答”。', # 核心文本内容metadata={'file_path': 'docs\\大模型推理.txt', ...}, # 源文件信息relationships={...}, # 节点间关系(如前序/后序节点)),score=0.6528139357784619 # 语义相似度分数(0-1,越高越相关)
)
0.65 的相似度分数表明该片段与问题 “大模型推理是什么?” 高度相关,是生成回答的主要依据。
NodeWithScore(node=TextNode(id_='82ac4f70-ec78-499f-9d5e-04cbec54208c',text='使用之前提到的 80 万高质量数据样本...但至少说明了它们在实际应用中面临着一些挑战。',metadata={...},),score=0.5625440768569911 # 相似度略低
)
metadata={'c4b39c48-0d68-4ad4-a6b8-066d2996982d': {'file_path': 'docs\\大模型推理.txt', ...},'82ac4f70-ec78-499f-9d5e-04cbec54208c': {'file_path': 'docs\\大模型推理.txt', ...}
}
记录所有引用节点的源文件信息,包括文件路径、名称、大小、修改日期等,确保回答可追溯到原始文档,增强可信度。
这个 Response
对象完整呈现了从 “问题输入” 到 “答案输出” 的闭环:基于向量索引的精准检索 → 上下文构建 → LLM 生成可靠回答,同时通过 source_nodes
和 metadata
保证了回答的可追溯性和可信度,是 LlamaIndex 知识增强问答能力的典型体现。
参考文章
https://github.com/datawhalechina/wow-raghttps://github.com/datawhalechina/wow-rag