北京常用网站,wordpress 模板 破解版,网站开发需要用哪些东西,网站开发技术职责文章目录 \1. RAG\2. 构建流程 2.1 文档加载与切分2.2 传统检索引擎2.3 LLM接口封装2.4 构建prompt \3. 向量检索\4. 向量数据库\5. 基于向量检索的RAG\6. 进阶知识 6.1 文本分割粒度6.2 检索后再排序6.3 测试
1. RAG
RAG#xff08;Retrieval Augmented Generation#…文章目录 \1. RAG\2. 构建流程 2.1 文档加载与切分2.2 传统检索引擎2.3 LLM接口封装2.4 构建prompt \3. 向量检索\4. 向量数据库\5. 基于向量检索的RAG\6. 进阶知识 6.1 文本分割粒度6.2 检索后再排序6.3 测试
1. RAG
RAGRetrieval Augmented Generation通过检索获取一些信息传给大模型提高回复的准确性。
一般流程
离线步骤文档加载切片 - 向量化 - 存入向量数据库在线步骤用户提问 - 向量化 -检索 - 组装提示词 - LLM - 输出回复
2. 构建流程
相关环境
代码语言javascript
复制
pip install pdfminer.six # pdf解析
pip install openai -U # openai-1.3.72.1 文档加载与切分
代码语言javascript
复制
import pathlib
def extract_text_from_pdf(filename, page_numbersNone, min_line_length1):从 PDF 文件中按指定页码提取文字paragraphs []buffer full_text # 提取全部文本for i, page_layout in enumerate(extract_pages(filename)):# 如果指定了页码范围跳过范围外的页if page_numbers is not None and i not in page_numbers:continuefor element in page_layout:if isinstance(element, LTTextContainer):full_text element.get_text() \n# 按空行分隔将文本重新组织成段落lines full_text.split(\n)for text in lines:if len(text) min_line_length:buffer ( text) if not text.endswith(-) else text.strip(-)elif buffer:paragraphs.append(buffer)buffer if buffer:paragraphs.append(buffer)return paragraphs代码语言javascript
复制
paragraphs extract_text_from_pdf(pathlib.Path(__file__).parent.absolute() / llama2.pdf, min_line_length10)2.2 传统检索引擎
安装 ElasticSearch
代码语言javascript
复制
pip install elasticsearch8
pip install nltk代码语言javascript
复制
from elasticsearch8 import Elasticsearch, helpers
from nltk.stem import PorterStemmer
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords
import nltk
import reimport warnings
warnings.simplefilter(ignore) #屏蔽 ES 的一些Warningsnltk.download(punkt) # 英文切词、词根、切句等方法
nltk.download(stopwords) # 英文停用词库def to_keywords(input_string):英文文本只保留关键字# 使用正则表达式替换所有非字母数字的字符为空格no_symbols re.sub(r[^a-zA-Z0-9\s], , input_string)word_tokens word_tokenize(no_symbols)stop_words set(stopwords.words(english))ps PorterStemmer()# 去停用词取词根filtered_sentence [ps.stem(w) for w in word_tokens if not w.lower() in stop_words]return .join(filtered_sentence)切分文档存入 Es
代码语言javascript
复制
# 1. 创建Elasticsearch连接
es Elasticsearch(hosts[http://localhost:9200], # 服务地址与端口# http_auth(elastic, *****), # 用户名密码
)# 2. 定义索引名称
index_name string_index# 3. 如果索引已存在删除它仅供演示实际应用时不需要这步
if es.indices.exists(indexindex_name):es.indices.delete(indexindex_name)# 4. 创建索引
es.indices.create(indexindex_name)# 5. 灌库数据
actions [{_index: index_name,_source: {keywords: to_keywords(para),text: para}}for para in paragraphs
]# 6. 批量存储Es
helpers.bulk(es, actions)关键字检索
代码语言javascript
复制
def search(es, index_name, query_string, top_n3):# ES 的查询语言search_query {match: {keywords: to_keywords(query_string)}}res es.search(indexindex_name, querysearch_query, sizetop_n)return [hit[_source][text] for hit in res[hits][hits]]results search(es, string_index, how many parameters does llama 2 have?, 2)
for r in results:print(r \n)搜索llama2有多少参数找到了相关的文档输出
代码语言javascript
复制
Llama 2 comes in a range of parameter sizes—7B, 13B,
and 70B—as well as pretrained and fine-tuned variations.1. Llama 2, an updated version of Llama 1, trained on a new mix of publicly available data.
We also increased the size of the pretraining corpus by 40%, doubled the context length of the model, and adopted grouped-query attention (Ainslie et al., 2023).
We are releasing variants of Llama 2 with 7B, 13B, and 70B parameters. We have also trained 34B variants, which we report on in this paper but are not releasing.§2.3 LLM接口封装
代码语言javascript
复制
from openai import OpenAI
import os
# 加载环境变量
from dotenv import load_dotenv, find_dotenv
_ load_dotenv(find_dotenv(../utils/.env)) # 读取本地 .env 文件里面定义了 OPENAI_API_KEYclient OpenAI(api_keyos.getenv(OPENAI_API_KEY),base_urlos.getenv(OPENAI_API_BASE)
)def get_completion(prompt, modelgpt-3.5-turbo):封装 openai 接口messages [{role: user, content: prompt}]response client.chat.completions.create(modelmodel,messagesmessages,temperature0, # 模型输出的随机性0 表示随机性最小)return response.choices[0].message.content2.4 构建prompt
代码语言javascript
复制
def build_prompt(prompt_template, **kwargs):将 Prompt 模板赋值prompt prompt_templatefor k, v in kwargs.items():if isinstance(v,str):val velif isinstance(v, list) and all(isinstance(elem, str) for elem in v):val \n.join(v)else:val str(v)prompt prompt.replace(f__{k.upper()}__,val)return prompt代码语言javascript
复制
prompt_template 你是一个问答机器人。你的任务是根据下述给定的已知信息回答用户问题。确保你的回复完全依据下述已知信息。不要编造答案。如果下述已知信息不足以回答用户的问题请直接回复我无法回答您的问题。已知信息:__INFO__用户问__QUERY__请用中文回答用户问题。user_query how many parameters does llama 2 have?# 1. 检索
search_results search(es, string_index, user_query, 2)# 2. 构建 Prompt
prompt build_prompt(prompt_template, infosearch_results, queryuser_query)
print(Prompt)
print(prompt)# 3. 调用 LLM
response get_completion(prompt)
print(回复)
print(response)提示词如下 在这里插入图片描述
GPT输出
代码语言javascript
复制
Llama 2有7B、13B和70B三种参数大小的变体。传统的关键字检索对同一个语义的不同描述可能检索不到结果
3. 向量检索
把一个词句映射到 n 维空间的一个向量构建句对相似和不相似训练双塔式模型 https://www.sbert.net向量相似度 余弦距离dot(a, b)/(norm(a)*norm(b)) 欧式距离 norm(np.asarray(a)-np.asarray(b))
向量化
代码语言javascript
复制
def get_embeddings(texts, modeltext-embedding-ada-002):封装 OpenAI 的 Embedding 模型接口data client.embeddings.create(input texts, modelmodel).datareturn [x.embedding for x in data]
test_query [测试文本]
vec get_embeddings(test_query)
print(vec[0][:10]) # 1536 维向量 [-0.0072620222344994545, -0.006227712146937847, -0.010517913848161697, 0.001511403825134039, -0.010678159072995186, 0.029252037405967712, -0.019783001393079758, 0.0053937085904181, -0.017029697075486183, -0.01215678546577692]4. 向量数据库
代码语言javascript
复制
# pip install chromadbimport chromadb
from chromadb.config import Settingsclass MyVectorDBConnector:def __init__(self, collection_name, embedding_fn):chroma_client chromadb.Client(Settings(allow_resetTrue))# 为了演示实际不需要每次 reset()chroma_client.reset()# 创建一个 collectionself.collection chroma_client.get_or_create_collection(namedemo)self.embedding_fn embedding_fndef add_documents(self, documents, metadata{}):向 collection 中添加文档与向量self.collection.add(embeddingsself.embedding_fn(documents), # 每个文档的向量documentsdocuments, # 文档的原文ids[fid{i} for i in range(len(documents))] # 每个文档的 id)def search(self, query, top_n):检索向量数据库results self.collection.query(query_embeddingsself.embedding_fn([query]),n_resultstop_n)return resultsparagraphs extract_text_from_pdf(pathlib.Path(__file__).parent.absolute() / llama2.pdf, page_numbers[2, 3], min_line_length10)# 创建一个向量数据库对象
vector_db MyVectorDBConnector(demo, get_embeddings)
# 向向量数据库中添加文档
vector_db.add_documents(paragraphs)user_query Llama 2有多少参数
results vector_db.search(user_query, 2) # 查询最相似的2个for para in results[documents][0]:print(para\n)FAISS: Meta开源的向量检索引擎 https://github.com/facebookresearch/faissPinecone: 商用向量数据库只有云服务 https://www.pinecone.io/Milvus: 开源向量数据库同时有云服务 https://milvus.io/ 选项全都是YWeaviate: 开源向量数据库同时有云服务 https://weaviate.io/Qdrant: 开源向量数据库同时有云服务 https://qdrant.tech/PGVector: Postgres的开源向量检索引擎 https://github.com/pgvector/pgvectorRediSearch: Redis的开源向量检索引擎 https://github.com/RediSearch/RediSearchElasticSearch 也支持向量检索 https://www.elastic.co/enterprise-search/vector-search
5. 基于向量检索的RAG
代码语言javascript
复制
class RAG_Bot:def __init__(self, vector_db, llm_api, n_results2):self.vector_db vector_dbself.llm_api llm_apiself.n_results n_resultsdef chat(self, user_query):# 1. 检索search_results self.vector_db.search(user_query,self.n_results)# 2. 构建 Promptprompt build_prompt(prompt_template, infosearch_results[documents][0], queryuser_query)# 3. 调用 LLMresponse self.llm_api(prompt)return response# 创建一个RAG机器人
bot RAG_Bot(vector_db,llm_apiget_completion
)user_queryllama 2有多少参数
response bot.chat(user_query)
print(response) # Llama 2有7B、13B和70B参数的变体。可以替换其他的 embedding、LLM
代码语言javascript
复制
# pip install sentence_transformers
from sentence_transformers import SentenceTransformer
model SentenceTransformer(BAAI/bge-large-zh-v1.5)
query_vec model.encode(query, normalize_embeddingsTrue)不是每个 Embedding 模型都对 余弦距离 和 欧氏距离 同时有效 哪种相似度计算有效要阅读模型的说明通常都支持余弦距离计算
6. 进阶知识
6.1 文本分割粒度
太大检索不精准太小信息不全问题的答案跨越两个片段
改进方法
按一定粒度部分重叠式的切割文本使上下文更完整
6.2 检索后再排序
最合适的答案有时候不一定排在检索结果的最前面
检索的时候多召回一些文本再用排序模型对 query 和 召回的 doc 进行打分排序
代码语言javascript
复制
user_queryhow safe is llama 2
search_results semantic_search(user_query,5) # 召回文档model CrossEncoder(cross-encoder/ms-marco-MiniLM-L-6-v2, max_length512)
scores model.predict([(user_query, doc) for doc in search_results[documents][0]])
# 按得分排序
sorted_list sorted(zip(scores,search_results[documents][0]), keylambda x: x[0], reverseTrue)
for score, doc in sorted_list:print(f{score}\t{doc}\n)6.3 测试
检查预处理文档是否切分合理问题检索是否能召回正确答案文档大模型根据包含正确答案的信息能否正确回答 大模型知识脑图
为了成为更好的 AI大模型 开发者这里为大家提供了总的路线图。它的用处就在于你可以按照上面的知识点去找对应的学习资源保证自己学得较为全面。 经典书籍阅读
阅读AI大模型经典书籍可以帮助读者提高技术水平开拓视野掌握核心技术提高解决问题的能力同时也可以借鉴他人的经验。对于想要深入学习AI大模型开发的读者来说阅读经典书籍是非常有必要的。 实战案例
光学理论是没用的要学会跟着一起敲要动手实操才能将自己的所学运用到实际当中去这时候可以搞点实战案例来学习。 面试资料
我们学习AI大模型必然是想找到高薪的工作下面这些面试题都是总结当前最新、最热、最高频的面试题并且每道题都有详细的答案面试前刷完这套面试题资料小小offer不在话下 这份完整版的大模型 AI 学习资料已经上传CSDN朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】