AI大模型持续火爆,我作为IT人员从业者也想参与一下,但是奈何大模型的参数太大,动辄上亿的参数需要很大的算力,GPU卡必不可少,对于手头羞涩的小白,不想投几千大洋只为了满足自己的好奇心。这真是个难题。
现在好了,微软推出了PHI模型,它是一系列小型语言模型(small language models,SLMs),代表了微软研究院在小规模语言模型领域的探索和成果。微软的 PHI 系列模型的发展不仅证明了小模型在特定领域内的强大潜力,也为如何通过精心设计的训练策略和数据选择来提升模型性能提供了宝贵的经验。对AI大模型的小白,它也是一个用家用PC来学习和调试AI模型的利器。
现在开始。
- RAG 检索增强生成工作流程
1. 数据预处理
对大量的原始文本数据进行收集和整理。
将这些文本数据分割成适当的块,例如段落或句子。
对每个数据块进行向量化处理,将其转换为可以进行相似性计算的向量表示。
2. 构建索引
使用预处理后的数据向量创建向量索引。这个索引类似于一个数据库的目录,能够快速找到与给定查询相似的数据块。
3. 接收用户查询
用户向系统输入问题或查询请求。
4. 查询向量化
系统将用户的查询转换为向量形式,以便与之前创建的索引中的向量进行比较和匹配。
5. 检索相关数据
在向量索引中进行搜索,找到与查询向量最相似的前 k 个数据块。
6. 提取相关文本
从数据库中提取检索到的相关数据块的实际文本内容。
7. 整合输入给模型
将提取的相关文本与用户的原始查询整合在一起,形成一个完整的输入提示,提供给语言模型。
8. 生成回答
语言模型基于整合后的输入提示生成最终的回答
2、这里直接使用NVIDIA网站的 phi-3-small-128k-instruct
llm = ChatNVIDIA(model="ai-phi-3-small-128k-instruct", nvidia_api_key=nvapi_key, max_tokens=512)
result = llm.invoke("泰坦尼克号的导演是谁?")
print(result.content)
《泰坦尼克号》的导演是乔治·哈维(George Lucas)。这部电影于1977年上映,由乔治·哈维执导,且由雷·格林斯特里克、汤姆·布莱恩斯和罗伯特·杰克逊等著名演员主演。这部电影不仅在票房上取得了巨大成功,而且还对后来的科幻电影产生了深远的影响。
直接使用该模型产生了AI幻觉,它在一本正经的胡说八道。
3、初始化向量库
from langchain_nvidia_ai_endpoints import NVIDIAEmbeddings
embedder = NVIDIAEmbeddings(model="ai-embed-qa-4")
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("./zh_data/")
data = []
sources = []
for p in ps:
if p.endswith('.txt'):
path2file="./zh_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']
len(data), len(documents), data[0]
(1, 1, '泰坦尼克号是一部 1997 年美国史诗爱情灾难片,由詹姆斯·卡梅隆执导、编剧、制作和联合剪辑。该片以 1912 年泰坦尼克号沉没事件为基础,融合了历史和虚构的元素。凯特·温斯莱特和莱昂纳多·迪卡普里奥饰演不同社会阶层的成员,他们在泰坦尼克号的处女航中坠入爱河。比利·赞恩、凯西·贝茨、弗朗西斯·费舍尔、格洛丽亚·斯图尔特、伯纳德·希尔、乔纳森·海德、维克多·加伯和比尔·帕克斯顿也参演了这部电影。\\n卡梅隆的这部电影的灵感来自于他对沉船的迷恋。他认为,一个夹杂着人员伤亡的爱情故事对于传达灾难的情感影响至关重要。该片于 1995 年 9 月 1 日开始拍摄,当时卡梅隆拍摄了泰坦尼克号沉船的实际镜头。研究船上的现代场景是在卡梅伦拍摄沉船时使用的 Akademik Mstislav Keldysh 号上拍摄的。使用比例模型、计算机生成的图像以及巴哈工作室建造的泰坦尼克号重建模型来重现沉没过程。该片由派拉蒙影业和二十世纪福克斯公司共同资助;前者负责在北美发行,而后者则在国际上发行影片。这是当时制作成本最高的电影,制作预算为 2 亿美元。拍摄时间为1996年7月至1997年3月。\\n《泰坦尼克号》于 1997 年 12 月 19 日上映。它因其视觉效果、表演(尤其是迪卡普里奥、温斯莱特和斯图尔特的表演)、制作价值、导演、配乐、摄影、故事和情感深度而受到好评。除其他奖项外,它获得了14项奥斯卡金像奖提名,并赢得了11项奖项,其中包括最佳影片和最佳导演,追平了《宾虚》(1959 年),成为获得奥斯卡奖最多的电影。 《泰坦尼克号》的全球首映票房超过 18.4 亿美元,是第一部突破 10 亿美元大关的电影。它是有史以来票房最高的电影,直到卡梅隆的下一部电影《阿凡达》(2009 年) 在 2010 年超越了它。经过多次重新上映,该电影的全球总票房达到 22.57 亿美元,成为第二部票房收入超过 100 万美元的电影。 《阿凡达》之后全球票房达到 20 亿美元。它于2017年被选入美国国家电影登记处保存。')
5、将文档处理到向量库并将其保存到磁盘
# Here we create a vector store from the documents and save it to disk.
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('./zh_data/nv_embedding')
6、进行验证
# Load the vectorestore back.
store = FAISS.load_local("./zh_data/nv_embedding", embedder,allow_dangerous_deserialization=True)
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("泰坦尼克号的导演是谁?")
' 泰坦尼克号的导演是詹姆斯·卡梅隆。