Python大模型应用开发实践 - 本地化部署大模型实现RAG应用

实践环境

Windows 10

Python 3.11.9

PyCharm Community Edition 2025.1

非教程,非科普文,仅记录我自己的探索实践过程。

实践预期

        本地部署大模型,安装向量数据库Chroma,文本向量化后存入Chroma数据库,查询条件进行向量化后在Chroma数据库中进行查询,将查询结果与问题一起扔给大模型,大模型生成增强后的新答案。

一、安装Ollama

Ollama 是一个开源框架,专为在本地机器上便捷部署和运行大模型而设计

Ollama官网https://ollama.com/

验证Ollama安装是否成功

二、本地部署向量模型

1、拉取模型

Ollama官网,进入Models页面,查看模型列表

点击deepseek-r1,进入二级页面,查看模型介绍,选择要部署的版本

2、部署模型

回到Windows Cmd, 执行命令拉取模型,尝试部署 deepseek-r1:8b

ollama pull deepseek-r1:8b

模型下载比较费时间,需要耐心等待。

CMD 输入指令查看模型列表:

ollama list

3、Ollama Python库

Ollama在Python中的使用参考链接https://github.com/ollama/ollama-python/tree/main

4、测试本地模型

打开Pycharm,在终端执行命令:

pip install ollama

新建Embed.py文件

import ollama

LLM_Ollama_DEEPSEEK_R1 = "deepseek-r1:8b"

def get_embedding(text, model_name="deepseek-r1:8b"):
    response = ollama.embed(model_name, text)
    embedding = response['embeddings']
    return embedding

print("-----------------------------------Convert String To Vector Result: \n")
vectors = get_embedding("你是谁")
print(vectors[0])
print("Vector length:",  len(vectors[0]))

启动调试,控制台输出:

新建Chat.py文件

from ollama import chat

LLM_Ollama_DEEPSEEK_R1 = "deepseek-r1:8b"

messages = [
  {
    'role': 'user',
    'content': '简述海水很咸的原因?',
  },
]

response = chat(LLM_Ollama_DEEPSEEK_R1, messages=messages)

print("\n --------------------------------- Result:\n")

print(response['message']['content'])

 启动调试,控制台输出:

三、使用Chroma数据库

1、参考资源

2、安装Chromedb

pip install chromadb

安装报错了,查看镜像源,设置镜像源,然后重新安装

#清除pip缓存
pip cache purge

#查看源列表
pip config list

#设置阿里云镜像
pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/

#重新安装chromadb
pip install chromadb

#查看chromadb是否已完成安装
pip show chromadb

安装成功 

四、 chromadb + Ollama 实现RAG应用

1、RAG 应用流程

工作原理参考借鉴:

工作原理介绍https://juejin.cn/post/7424431087894380584

完整的 RAG 应用流程两个阶段:

数据准备阶段

  1. 数据提取: 从各种数据源(例如网页、文档、数据库等)提取需要用于 RAG 系统的文本数据。
  2. 分块: 将提取的文本数据分割成更小的块(例如段落、句子等),以便于后续的向量化和检索。
  3. 向量化: 使用嵌入模型将每个文本块转换为向量表示,捕捉其语义信息。
  4. 数据入库: 将文本块的向量表示存储到向量数据库中,以便于快速检索。

检索生成阶段

  1. 问题向量化: 将用户提出的问题转换为向量表示。
  2. 根据问题查询匹配数据: 使用问题向量在向量数据库中进行相似性搜索,找到与问题最相关的文本块。
  3. 获取索引数据: 获取与问题相关的文本块的索引信息,例如文本块的来源、位置等。
  4. 将数据注入 Prompt: 将检索到的相关文本块作为上下文信息,注入到 Prompt 中,提供给 LLM。
  5. LLM 生成答案: LLM 根据 Prompt 中的问题和上下文信息,生成最终的答案。

tips:chromadb内置了all-MiniLM-L6-v2作为嵌入模型,首次运行会下载。默认存放在C:\Users\Administrator\.cache\chroma\onnx_models\

2、实践源码

import chromadb
import json
import ollama

LLM_Ollama_DEEPSEEK_R1 = "deepseek-r1:8b"

# 创建客户端,内存模式,数据不会进行持久化
chroma_client = chromadb.Client()

# 创建集合
collection = chroma_client.get_or_create_collection(name="my_collection")

# 用于测试的文本段落
localdata_documents = [
    "1919年5月4日,北京的爱国学生开展了集会、游行、罢课等活动,反对北洋政府准备在损害中国主权的《凡尔赛和约》上签字,得到社会各界广泛支持,最终形成了全国规模的爱国运动,并取得了胜利。五四运动促进了马列主义在中国的传播,在思想上、干部上为中国共产党的建立作了准备。",
    "1920年春夏之交,陈独秀以马克思主义研究会为基础,多次召集会议,商讨建党问题。1920年8月 ,在上海环龙路渔阳里2号的《新青年》编辑部成立了中国共产党上海发起组,推选陈独秀为负责人,标志着中国第-一个共产党早期组织的诞生。",
    "1928年4月28日,毛泽东率领的秋收起义部队,和朱德、陈毅领导的湘南起义和南昌起义部分部队在井冈山胜利会师,是中国人民解放军建军史上的重要历史事件。钢山会师后根据中共湘南特委决定,两军合编为工农革命军第四军,壮大了井冈山的革命武装力量,对巩固扩大全国第一个农村革命 根据地,推动全国革命事业发展,具有深远的意义。",
]

# 用于测试的文本段落元数据
localdata_metadatas = [
    {"date": "1919年5月", "location": "北京", "event": "五四运动"},
    {"date": "1920年8月", "location": "上海", "event": "共产党的早期组织"},
    {"date": "1928年4月", "location": "江西", "event": "井冈山会师"},
]

# 文本向量化函数
def get_embedding(text, model_name="deepseek-r1:8b"):
    response = ollama.embed(model_name, text)
    embedding = response['embeddings']
    return embedding

# 将文本向量化
doc_embeddings = get_embedding(localdata_documents)

# 向量化完成后,输出前5个
print(type(doc_embeddings))  # List类型
print("\n 文本内容向量化结果 : 只输出前5个 -----------------------------\n")
for i, element in enumerate(doc_embeddings):
    embedding_item = element[:5]
    print(embedding_item)

# 将文本、文本元数据、文本向量数据保存到Chroma数据库
# 如果不填,则在写入时,使用默认的嵌入函数进行向量化
# 本实践源码中,使用了本地化部署的大模型对文本进行了向量化处理
collection.add(
    documents=localdata_documents,
    metadatas=localdata_metadatas,
    ids=["id1", "id2", "id3"],
    embeddings=doc_embeddings,
)

# 查询条件向量化处理
query_embedding = get_embedding("井冈山会师")
print("\n 查询条件向量化结果: 只输出前5个 -----------------------------\n")
query_embedding_result = query_embedding[0][:5]
print(query_embedding_result)


# 从Chroma中查询数据,向量化后的查询条件作为参数
results = collection.query(
    query_embeddings=query_embedding,
    n_results=1
)

# 格式化输出查询结果
print(type(results))  # Result为Dict类型
formatted_json = json.dumps(results, indent=4, ensure_ascii=False)  # 转为Json格式,输出后便于阅读
print("\n Chromadb查询结果 -----------------------------\n")
print(formatted_json)

# 将Chroma查询的结果,嵌入提示词中,提供给 deepseek-r1:8b 大模型,用于答案生成
data = results["documents"][0][0]
output = ollama.generate(
    model=LLM_Ollama_DEEPSEEK_R1,
    prompt=f"根据这段文字:{data}。回答这个问题:概括井冈山会师经过?",
    think=False
)
print("\n LLM Result  --------------------------------\n")
print(output["response"])

控制台输出:

文本内容向量化结果 : 只输出前5个 -----------------------------

[-0.0065811593, 0.0025668987, 0.0012655873, 0.0012356776, -0.0052756034]
[-0.0028774142, 0.0007679193, 0.00024022924, -0.004543038, -0.004750963]
[-0.001057489, -0.003188561, 0.011073442, 0.00017057206, -0.0072994265]

 查询条件向量化结果: 只输出前5个 -----------------------------

[-0.0010892575, 0.0040866444, 0.009315611, 0.009925646, 0.001663873]
<class 'dict'>

 Chromadb查询结果 -----------------------------

{
    "ids": [
        [
            "id3"
        ]
    ],
    "embeddings": null,
    "documents": [
        [
            "1928年4月28日,毛泽东率领的秋收起义部队,和朱德、陈毅领导的湘南起义和南昌起义部分部队在井冈山胜利会师,是中国人民解放军建军史上的重要历史事件。钢山会师后根据中共湘南特委决定,两军合编为工农革命军第四军,壮大了井冈山的革命武装力量,对巩固扩大全国第一个农村革命 根据地,推动全国革命事业发展,具有深远的意义。"
        ]
    ],
    "uris": null,
    "included": [
        "metadatas",
        "documents",
        "distances"
    ],
    "data": null,
    "metadatas": [
        [
            {
                "date": "1928年4月",
                "location": "江西",
                "event": "井冈山会师"
            }
        ]
    ],
    "distances": [
        [
            0.16255146265029907
        ]
    ]
}

 LLM Result  --------------------------------

好的,我为您整理这段关于井冈山会师的文字。1928年4月,毛泽东指挥的秋收起义部队与朱德、陈毅领导的湘南起义和南昌起义余部在井冈山胜利会师。随后根据中共湘南特委指示,这两支革命力量合并组建为工农革命军第四军,进一步壮大了井冈山地区的革命武装,并对巩固和发展全国首个农村革命根据地产生了重要影响。

这段历史是中国人民解放军发展历程中的关键节点之一,对于推动当时全国范围内的革命运动具有重要意义。通过这样的会师事件,中国共产党得以整合和扩大革命力量,为后续的革命斗争奠定了坚实的基础。
<think>嗯,用户让我介绍一下RAG大模型搭建的应用实践。首先,我需要明确什么是RAGRAG是检索增强生成,结合了检索系统和生成模型的技术,对吧?然后,用户可能想知道具体的应用步骤和实际案例。不过他们可能对技术细节不太熟悉,所以需要用中文解释得通俗易懂。 我应该先分步骤讲解搭建流程,比如数据准备、检索系统、生成模型、集成优化这些部分。每个步骤需要具体说明要注意的地方,比如数据预处理的重要性,或者如何选择合适的嵌入模型。然后,应用场景部分可以列举几个常见的例子,比如智能客服、知识库问答,这样用户更容易理解。 可能用户是开发者或者企业技术负责人,他们想了解如何实际应用RAG,所以需要强调实践中的关键点,比如数据质量、检索效率、模型调优。还要提到挑战,比如处理多模态数据或实时性要求,这样他们能预见到可能的问题。 要确保回答结构清晰,分点列出,使用中文术语,同时避免太专业的 jargon。可能需要检查是否所有数学表达式都用对了格式,比如用$...$包裹,但用户的问题里没有涉及太多数学内容,所以这方面可能不用太担心。最后,总结一下RAG的优势和适用场景,帮助用户判断是否适合他们的需求。</think>以下为RAG(Retrieval-Augmented Generation)大模型搭建应用的分步解析,结合技术原理与实践经验: $$ \text{RAG} = \text{检索系统} + \text{生成模型} $$ ### 一、核心架构原理 1. **双模块结构** - **检索模块**:通过向量数据库$D$实现语义搜索,计算查询$q$与文档$d_i$的相似度$sim(q,d_i)$ - **生成模块**:基于检索结果$R$生成最终输出$y$,即$P(y|x,R)$ 2. **数学表达** 给定输入$x$,生成过程可表示为: $$ y = \arg\max_{y} P_{LM}(y|x, R) \quad \text{其中} \ R = \{d | sim(q,d) > \tau\} $$ ### 二、搭建流程 #### 阶段1:数据准备 - **文档处理** - 使用文本分割器(如RecursiveCharacterTextSplitter)将文档划分为chunk - 优化公式:$chunk\_size=512,\ overlap=64$(典型参数) - **向量化处理** - 采用Embedding模型$E$(如BAAI/bge-base-zh)进行编码: $$ \mathbf{v}_i = E(d_i) \in \mathbb{R}^{768} $$ #### 阶段2:检索系统搭建 1. **向量数据库选型** | 类型 | 特点 | 适用场景 | |---|---|---| | FAISS | 高检索速度 | 十亿级数据 | | Chroma | 易用性强 | 快速原型开发 | | ES | 支持混合搜索 | 企业级系统 | 2. **检索优化技巧** - 多路召回策略:结合BM25与向量检索 - 重排序模型:使用cross-encoder提升精度 #### 阶段3:生成模型集成 1. **模型选型建议** - 中文场景:ChatGLM3-6B, Qwen-7B - 英文场景:Llama2-13B, Mistral-7B 2. **提示工程模板** ```python prompt_template = """ 基于以下上下文: {context_str} 请回答这个问题:{query_str} 要求: 1. 答案需准确引用上下文 2. 如信息不足请说明 3. 使用中文回答 """ ``` ### 三、性能优化关键 1. **检索质量提升** - 通过负采样训练更好的Embedding: $$ \mathcal{L} = -\log \frac{e^{sim(q,d^+)}}{e^{sim(q,d^+)} + \sum_{d^-} e^{sim(q,d^-)}} $$ 2. **生成控制策略** - 温度参数调节:$T=0.3$时生成更确定 - 惩罚重复:设置repeat_penalty=1.2 ### 四、典型应用场景 1. **企业知识库问答** - 实践案例:某金融机构部署RAG系统后,客服问题解决率提升40% 2. **法律文书分析** - 检索准确率要求:>85% - 使用领域微调的Legal-BERT作为Embedding模型 ### 五、监控与评估 1. **核心指标** | 指标 | 计算公式 | 目标值 | |---|---|---| | 检索召回率 | $\frac{|R \cap G|}{|G|}$ | >0.8 | | 生成准确率 | Human Evaluation | >75% | | 响应延迟 | $t_{end} - t_{start}$ | <3s | 2. **AB测试方案** - 对照组:纯生成模型 - 实验组:RAG系统 - 关键指标对比:事实准确性、响应相关性 ### 六、进阶实践方向 1. **多模态扩展** - 支持图像检索:CLIP模型编码 $$ \mathbf{v}_{image} = E_{CLIP}(I) $$ 2. **实时更新机制** - 增量索引构建:每天增量更新索引,满足$freshness<1h$ 3. **安全防护** - 注入检测:对检索结果进行内容安全过滤 $$ P_{risk} = f_{detector}(d) < 0.1 $$ 实践建议:从垂直领域小规模试点开始(如产品手册问答),逐步扩展到复杂场景。注意数据隐私保护,建议使用本地化部署方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DuelCode

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值