快速掌握大語言模型+向量數據庫_RAG實現

一、前言

結合前面掌握的vLLM部署Qwen7B模型、通過Embedding模型(bdg-large-zh模型)提取高質量作文內容并預先存儲到Milvus向量數據庫中,我們很容易實現RAG方案進一步提高寫作內容的生成質量。

本篇要實現的目標是:通過FlaskAPI對上游業務系統提供一個開放接口,調用該接口將返回寫作內容(非流式)。 該接口優先通過dbg-large-zh模型生成ebedding向量,然后從Milvus向量數據庫中查詢和向量相似度最高的1條數據,若查到數據且相似度達到指定閾值(如0.75或0.9,具體數值由業務決定),則直接返回Milvus中存儲的內容,否則調用Qwen2-7B-Instruct模型生成寫作內容。

要實現的架構為

往期文章:

快速掌握大語言模型-Qwen2-7B-Instruct落地1-CSDN博客

快速掌握大語言模型-Qwen2-7B-Instruct落地2-CSDN博客

快速掌握向量數據庫-Milvus探索1-CSDN博客

快速掌握向量數據庫-Milvus探索2_集成Embedding模型-CSDN博客

二、術語

2.1 vLLM

vLLM采用連續批處理,吞吐量相比傳統框架(如Hugging Face Transformers)可提升5-10倍;

分布式推理支持允許在多GPU環境下并行處理;

通過PagedAttention技術,vLLM將注意力計算的鍵值(KV Cache)分頁存儲在顯存中,動態分配空間以減少碎片;

內置了對 OpenAI API 的兼容支持,可直接啟動符合 OpenAI 標準的 API 服務;

2.2 FastApi

基于Python的Web框架,主要用于構建高性能、易維護的API和Web應用程序,通過FastApi可以對上游業務系統暴露API,上游業務系統通過http請求即調用相關接口。

2.3 Milvus

Milvus是一個專為處理高維向量數據設計的開源向量數據庫,支持數百億級數據規模,在多數開源向量數據庫中綜合表現突出(一般是其他的2~5倍)。

提供三種部署方式:本地調試Milvus Lite、企業級小規模數據的Milvus Standalone(一億以內向量)、企業級大規模數據的Milvus Distributed (數百億向量)。

2.4 bge-large-zh

bge-large-zh模型是專為中文文本設計的,同尺寸模型中性能優異的開源Embedding模型,憑借其中文優化、高效檢索、長文本支持和低資源消耗等特性,成為中文Embedding領域的標桿模型。

2.5 Qwen2-7B-Instruct

Qwen2-7B-Instruct 是阿里云推出的開源指令微調大語言模型,屬于 Qwen2 系列中的 70 億參數版本。該模型基于 Transformer 架構,通過大規模預訓練和指令優化,展現出強大的語言理解、生成及多任務處理能力

三、代碼

3.1 代碼目錄

  • vllm.py :提供調用Qwen7B模型的方法;
  • app.py :提供通過FastAPI暴露給上游業務系統調用的API;
  • embedding.py :提供調用bge-large-zh模型生成內容的embedding向量的方法 ;
  • milvus_server.py :提供查詢Milvus向量數據庫的方法;
  • generate_text_request.py : 模擬上游業務系統通過http調用app.py提供的生成寫作內容的API

3.2 完整代碼

3.2.1 安裝依賴

# vllm需要的依賴
pip install vllm# milvus需要的依賴
python -m pip install -U pymilvus

?3.2.2?app.py

from fastapi import FastAPI
from fastapi.responses import StreamingResponse
import logging
from vllm import Model
from embedding import search_writing_embeddings# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
app = FastAPI()
model = Model()# 流式響應
@app.get("/chat")
async def chat(prompt: str):return StreamingResponse(model.generate_stream(prompt), media_type="text/plain")# 非流式響應(RAG增強檢索)
@app.get("/generate")
async def generate(prompt: str):# 優先通過embedding向量從milvus中搜索相似度最高的1條數據,如果相似度達到90%以上,則直接返回該數據的content_full字段作為結果,否則調用llm模型生成# 這里的90%是一個閾值,可以根據實際情況調整res = search_writing_embeddings(prompt)print(f"search_writing_embeddings:{res}")threshold = 0.75if res and res[0] and res[0][0]['distance'] >= threshold:print("使用milvus中的數據")result = res[0][0]['entity']['content_full']else:print("使用llm模型生成")result = await model.generate_text(prompt)return resultif __name__ == "__main__":import uvicornuvicorn.run(app, host="0.0.0.0", port=8000)

3.2.3?vllm.py

# 大語言模型LLM文件import logging
from openai import OpenAI
from pydantic_core import Url# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
model_path = "/mnt/workspace/models/Qwen2-7B-Instruct"  
base_url = "http://localhost:9000/v1"class Model:def __init__(self):# 創建 OpenAI 客戶端實例,這里的密鑰可以隨意填寫,vLLM 不需要驗證self.client = OpenAI(api_key="EMPTY", base_url= base_url)   # 流式處理async def generate_stream(self, prompt: str):try:logging.info(f"開始處理提示: {prompt}")# 使用新客戶端調用 API# 確保使用類的實例屬性 self.clientchat_response = self.client.chat.completions.create(model= model_path,messages=[{"role": "user", "content": prompt}],stream=True,max_tokens=512,temperature=0.7,top_p=0.9)for chunk in chat_response:msg = chunk.choices[0].delta.contentif msg is not None:logging.info(f"生成文本塊: {msg}")yield msglogging.info("流式輸出結束")except Exception as e:logging.error(f"處理提示時出錯: {e}", exc_info=True)# 非流式處理async def generate_text(self, prompt: str):try:logging.info(f"開始處理提示: {prompt}")# 使用新客戶端調用 APIresponse = self.client.chat.completions.create(model= model_path,messages=[{"role": "user", "content": prompt}],stream=False,max_tokens=512,temperature=0.7,top_p=0.9)# 獲取完整響應content = response.choices[0].message.contentlogging.info(f"文本生成完成:{content}")return contentexcept Exception as e:logging.error(f"處理提示時出錯: {e}", exc_info=True)return ""

3.2.4?embedding.py

from transformers import AutoTokenizer, AutoModel
import torch
import random
from milvus_server import WritingDTO, insert_data_to_milvus,search_data_from_milvus# 加載模型和分詞器
model_path = "/mnt/workspace/models/bge-large-zh"  # 根據實際情況修改
model = AutoModel.from_pretrained(model_path)
tokenizer = AutoTokenizer.from_pretrained(model_path)
# 推理模式
model.eval()  # 寫作生成合集名稱
writing_collection_name = "writing"def get_embedding_list(text_list):"""輸入文本列表,返回文本的embedding向量:param text_list: 待獲取embedding的文本集合:return: ebedding向量集合"""# 編碼輸入(自動截斷和填充)encoded_input = tokenizer(text_list, padding=True, truncation=True, return_tensors='pt')# 調用大模型得到文本的embeddingwith torch.no_grad():model_output = model(**encoded_input)sentence_embeddings = model_output[0][:, 0] # bdge-large-zh 模型的輸出是一個元組,第一個元素是句子的嵌入向量,1024維print(f"sentence_embeddings:{ len(sentence_embeddings[0])}")# 歸一化處理:可以提高模型的穩定性和收斂速度,尤其在處理向量相似度計算時非常有用sentence_embeddings = torch.nn.functional.normalize(sentence_embeddings, p=2, dim=1)# 轉換嵌入向量為列表embeddings_list = sentence_embeddings.tolist()return embeddings_listdef insert_writing_embeddings(text_list):"""獲取寫作生成內容的文本的embedding向量,并寫入到milvus中:param text_list: 待獲取embedding的寫作生成內容集合:return: 寫入到到milvus結果,ebedding向量集合"""# 獲取embedding embeddings_list = get_embedding_list(text_list)print(f"embeddings_list:{len(embeddings_list)}")# 寫作記錄合集writing_list = []for i, embedding in enumerate(embeddings_list):writingDTO = WritingDTO(embedding, text_list[i], random.randint(500,9999))  #組裝對象數據,其中biz_id是業務ID,這里這里方便說明暫設為隨機數字writing_list.append(writingDTO.to_dict()) # 將對象轉換為字典,并添加到集合中# 插入數據到 Milvusres = insert_data_to_milvus(writing_collection_name,writing_list)return res,embeddings_listdef search_writing_embeddings(text):"""獲取寫作內容的embedding向量,并從milvus中搜索"""# 獲取embeddingembeddings_list = get_embedding_list([text])# 搜索數據res = search_data_from_milvus(writing_collection_name,embeddings_list,["id","content_full","biz_id"],1)return resif __name__ == "__main__":# 輸入文本content = "推薦廣州有哪些好玩的地方"# 將文本轉eembedding向量并寫入到milvus中res = search_writing_embeddings(content)print("Search result:", res)

3.2.5?milvus_server.py

from pymilvus import MilvusClient, db
import numpy as np
from pymilvus.orm import collection
from typing import Iterable# 定義 Milvus 服務的主機地址
host = "阿里云公網IP"# 創建一個 Milvus 客戶端實例,連接到指定的 Milvus 服務
client = MilvusClient(uri=f"http://{host}:19530",db_name="db001") # 連接到 Milvus 服務并選擇數據庫 "db001"
# collection_name = "writing" # 指定要連接的集合名稱 "writing"# 寫作生成對象
class WritingDTO:def __init__(self, content_vector, content_full, biz_id):self.content_vector = content_vectorself.content_full = content_fullself.biz_id = biz_iddef to_dict(self):"""將 WritingDTO 對象轉換為字典。:return: 包含 WritingDTO 對象屬性的字典"""return {"content_vector": self.content_vector,"content_full": self.content_full,"biz_id": self.biz_id}def insert_data_to_milvus(collection_name,data):"""將對象集合中的數據插入到 Milvus 集合中。:param data: 字典對象集合:return: 插入操作的結果"""print(f"insert_data_to_milvus:{collection_name}")print(f"insert_data_to_milvus:{len(data)}")res = client.insert(collection_name=collection_name,data=data)return resdef search_data_from_milvus(collection_name,query_vector,output_fields, top_k=10):"""從 Milvus 集合中搜索與查詢向量最相似的向量。:param query_vector: 查詢向量:param top_k: 返回的最相似向量的數量:return: 搜索結果"""res = client.search(collection_name= collection_name, # 合集名稱data=query_vector, # 查詢向量search_params={"metric_type": "COSINE", # 向量相似性度量方式,COSINE 表示余弦相似度(適用于文本/語義相似性場景); 可選 IP/COSINE/L2 "params": {"level":1}, }, # 搜索參數limit=top_k, # 查詢結果數量output_fields= output_fields, # 查詢結果需要返回的字段consistency_level="Bounded" # 數據一致性級別,Bounded允許在有限時間窗口內讀取舊數據,相比強一致性(STRONG)提升 20 倍查詢性能,適合高吞吐場景; )return res

3.2.6?generate_text_request.py

import requestsurl = "http://0.0.0.0:8000/generate?prompt=廣州有什么好玩的"
response = requests.get(url, stream=True)
print(response.text)

四、調用結果

4.1 啟動vllm

python -m vllm.entrypoints.openai.api_server  --model  /mnt/workspace/models/Qwen2-7B-Instruct  --swap-space 10 --disable-log-requests --max-num-seqs 256 --host 0.0.0.0 --port 9000  --dtype float16 --max-parallel-loading-workers 1  --max-model-len 10240 --enforce-eager

4.2 啟動FastAPI

4.3 上游業務系統調用

情況1:向量查詢結果相似度低于閾值(90%相似度)的情況 ==> 通過Qwen7B模型生成內容

情況2:向量查詢結果相似度高于于閾值(75%相似度)的情況 ==> 直接返回向量查詢結果的內容

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/79071.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/79071.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/79071.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【FreeRTOS-列表和列表項】

參照正點原子以及以下gitee筆記整理本博客,并將實驗結果附在文末。 https://gitee.com/xrbin/FreeRTOS_learning/tree/master 一、列表和列表項的簡介(熟悉) 1、什么是列表 答:列表是FreeRTOS中的一個數據結構,概念上和鏈表有點類似&#…

【c++】【STL】queue詳解

目錄 queue的作用什么是容器適配器queue的接口構造函數emptysizefrontback queue類的實現 queue的作用 queue是stl庫提供的一種容器適配器,也就是我們數據結構中學到的隊列,是非常常用的數據結構,特點是遵循LILO(last in last ou…

【一】 基本概念與應用領域【數字圖像處理】

考綱 文章目錄 1 概念2005甄題【名詞解釋】2008、2012甄題【名詞解釋】可考題【簡答題】可考題【簡答題】 2 應用領域【了解】2.1 伽馬射線成像【核醫學影像】☆2.2 X射線成像2.3 紫外波段成像2.4 可見光和紅外波段成像2.5 微波波段成像2.6 無線電波段成像2.7 電子顯微鏡成像2…

RAG技術完全指南(一):檢索增強生成原理與LLM對比分析

RAG技術完全指南(一):檢索增強生成原理與LLM對比分析 文章目錄 RAG技術完全指南(一):檢索增強生成原理與LLM對比分析1. RAG 簡介2. 核心思想3. 工作流程3.1 數據預處理(索引構建)3.2…

對計網考研中的信道、傳輸時延、傳播時延的理解

對計網考研中的信道、傳輸時延、傳播時延的理解 在學習數據鏈路層流量控制和可靠傳輸那一節的三個協議的最大信道利用率時產生的疑惑 情景: 假如A主機和B主機通過集線器連接,A和集線器是光纖連接,B和集線器也是光纖連接,A給B發…

【2025五一數學建模競賽C題】社交媒體平臺用戶分析問題|建模過程+完整代碼論文全解全析

你是否在尋找數學建模比賽的突破點?數學建模進階思路! 作為經驗豐富的美賽O獎、國賽國一的數學建模團隊,我們將為你帶來本次數學建模競賽的全面解析。這個解決方案包不僅包括完整的代碼實現,還有詳盡的建模過程和解析&#xff0c…

使用 Spring Boot Actuator 實現應用實時監控

1. 引言 1.1 什么是 Spring Boot Actuator Spring Boot Actuator 是 Spring Boot 提供的一組生產級功能模塊,用于幫助開發者對 Spring Boot 應用進行監控和管理。它提供了一系列 REST API 端點(Endpoints),可以獲取應用程序的運行狀態、健康檢查、度量指標等信息。 這些…

2025MathorCup數學應用挑戰賽B題

目錄 模型建立與求解 1.問題一的模型建立與求解 1.1 搬遷補償模型設計 1.2 住戶是否搬遷的應對策略與分析 1.3 定量討論 2.問題二的模型建立與求解 2.1 搬遷方案模型的優化介紹 2.2 模型的評估 2.3 模型結果 3.問題三的模型建立與求解 3.1 拐點存在性分析模型的建立 3.2 模型的…

西門子數字化研發設計制造一體化規劃案例P87(87頁PPT)(文末有下載方式)

資料解讀:《西門子數字化研發設計制造一體化規劃案例》 詳細資料請看本解讀文章的最后內容。 該文檔圍繞西門子為企業打造的智能化制造研發工藝生產一體化平臺規劃方案展開,全面闡述了從業務現狀分析到項目實施及案例分享的整個過程。 業務現狀與需求分析…

stm32基礎001(串口)

文章目錄 通信的基本概念串行通信和并行通信單工,半雙工和全雙工串口的硬件連接 stm32的串口原理圖CPU的芯片手冊stm32串口的庫函數實現通過串口實現printf函數使用中斷實現串口的接收 通信的基本概念 串行通信和并行通信 串行通信一個方向只有一個數據通道&#x…

【驗證技能】文檔要求和好文檔注意點

項目文檔 產品場景分析; 產品規格需求:OR; 項目設計需求:DR; 業務文檔:學發材料; 計劃 項目執行計劃,設計計劃,驗證計劃,一~四級計劃; 一級計…

使用 CarrierWave 通過 AWS S3上傳文件到阿里云 OSS

雖然阿里云 OSS 與 AWS S3 兼容,但需要使用阿里云的特定端點進行配置。CarrierWave 是一個流行的 Ruby 文件上傳庫,可以方便地與 AWS S3 集成。以下是配置和使用方法: 1. 安裝必要的 gem 首先,在 Gemfile 中添加以下 gem&#x…

上位機知識篇---流水線執行

文章目錄 前言前言 本文簡單介紹了流水線. 基本概念 流水線(Pipeline) 是一種通過將任務分解為多個子任務(階段),并讓不同子任務并行執行以提高效率的技術。其靈感來源于工業流水線,每個階段專注于特定操作,多任務在不同階段重疊執行,從而提升整體吞吐率(Throughput)…

第三部分:賦予網頁靈魂 —— JavaScript(下)

目錄 7 DOM 操作:控制網頁的"智能面板7.1 小例子:點擊按鈕時改變段落文字,根據用戶輸入改變圖片7.2 練習:實現一個簡單的 Tab 切換效果 8 事件處理:響應用戶的"指令"8.1 小例子:實現點擊按鈕…

芯片軟錯誤概率探究:基于汽車芯片安全設計視角

摘要: 本文深入剖析了芯片軟錯誤概率問題,結合 AEC-Q100 與 IEC61508 標準,以 130 納米工藝 1Mbit RAM 芯片為例闡述其軟錯誤概率,探討汽車芯片安全等級劃分及軟錯誤對汽車關鍵系統的影響,分析先進工藝下軟錯誤變化趨勢…

嵌入式AI還是一片藍海

發現其實還是挺多人關注嵌入式和人工智能交叉領域的,隨便一個問題,瀏覽量就27萬了,但是這方面的內容確實少得可憐……所以干脆我自己來補點干貨。 推薦一本最近很熱門的新書——《邊緣人工智能:用嵌入式機器學習解決現實問題》。 …

Linux 怎么安裝 Oracle Java 8

在 Linux 系統上安裝 Oracle Java 8 的步驟如下: 1. 下載 Oracle Java 8 訪問 Oracle 官方網站的 Java 下載頁面: 下載鏈接:Oracle Java 8 下載頁面選擇適合 Linux x64 的安裝包(通常是 .tar.gz 格式)。需要登錄 Or…

nginx配置集群服務器中的tcp負載均衡器

文章目錄 前言1. Ubuntu下nginx安裝2. nginx的tcp負載配置 前言 假設一臺機器支持兩萬的并發量,現在我們需要保證八萬的并發量。首先想到的是升級服務器的配置,比如提高 CPU 執行頻率,加大內存等提高機器的物理性能來解決此問題。但是單臺機…

【音視頻】RTMP流媒體服務器搭建、推流拉流

服務器:SRS(Simple RTMP Server,?持RTMP、HTTP-FLV,HLS) 推流端:ffmpeg OBS 拉流端:ffplay VLC srs播放器 1 安裝和測試srs流媒體服務器 1.1 安裝srs流媒體服務器 srs官?:https://github.com/ossrs/…

數據治理與數據管理:定義之辯和責任外包的邊界

數據治理與數據管理:定義之辯和責任外包的邊界 最近,在數據領域的技術交流中,一位朋友探討了兩個很有意思的問題。這兩個問題非常典型,也反映了大家在實際工作和學習中常會遇到的困惑:一是關于“數據管理”和“數據治…