Centos7本地部署阿里Qwen2-7B模型

1.從hagging face下載模型

2.把下載的模型文件,放到/usr/local/Qwen2-7B目錄下

3.創建虛擬環境,安裝依賴

1.環境安裝
sudo yum update -y
sudo yum install -y python3 python3-pip git

2.創建虛擬環境并激活
python3 -m venv qwen2_env
source qwen2_env/bin/activate

conda activate??qwen2_env

conda install numpy transformers torch langchain sentence-transformers jieba requests streamlit

3.將diet_ui.py文件放到根目錄下

import streamlit as st
import requests
import re
import logging
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch
from langchain.memory import ConversationBufferMemory
from langchain.chains import LLMChain
from langchain.llms import HuggingFacePipeline
from langchain.prompts import PromptTemplate
from transformers import pipeline
from sentence_transformers import SentenceTransformer, models
import numpy as np
import jieba# 配置日志記錄
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')# 加載 Qwen2 模型和分詞器
try:tokenizer = AutoTokenizer.from_pretrained("/usr/local/Qwen2-7B", trust_remote_code=True)model = AutoModelForCausalLM.from_pretrained("/usr/local/Qwen2-7B", device_map="auto", trust_remote_code=True).eval()logging.info("分詞器和模型加載成功")
except Exception as e:logging.error(f"加載分詞器或模型時發生錯誤: {e}")raise# 公司業務接口地址
PORTFOLIO_API_URL = "https://xxxxx/plugin/portfolio"# 擴充關鍵詞列表
KEYWORDS = ["方案", "配餐", "計劃", "飲食安排", "食譜", "卡路里", "餐單", "膳食"]
# 允許的話題列表,添加配餐相關關鍵詞
ALLOWED_TOPICS = ["健康", "營養", "飲食", "訂單", "優惠券", "吃飯", "運動", "養生", "客服"] + KEYWORDS# 初始化會話記憶,最多存儲 10 輪對話
memory = ConversationBufferMemory(k=10)# 創建 HuggingFacePipeline
pipe = pipeline("text-generation",model=model,tokenizer=tokenizer,max_new_tokens=500,do_sample=True,top_p=0.85,temperature=0.35
)
llm = HuggingFacePipeline(pipeline=pipe)# 創建一個簡單的提示模板
prompt_template = PromptTemplate(input_variables=["input"],template="{input}"
)# 創建 LLMChain
chain = LLMChain(llm=llm, memory=memory, prompt=prompt_template)# 加載知識庫
def load_knowledge_base(file_path):with open(file_path, 'r', encoding='utf-8') as file:lines = file.readlines()knowledge_base = []question = Noneanswer = ""for line in lines:line = line.strip()if line.startswith("Q:"):if question is not None:knowledge_base.append((question, answer))question = line[2:]answer = ""elif line.startswith("A:"):answer = line[2:]else:answer += line + " "if question is not None:knowledge_base.append((question, answer))return knowledge_base# 加載知識庫
knowledge_base = load_knowledge_base("/root/knowledge_base.txt")# 手動加載模型組件
word_embedding_model = models.Transformer('/root/all-MiniLM-L6-v2')
pooling_model = models.Pooling(word_embedding_model.get_word_embedding_dimension())
encoder = SentenceTransformer(modules=[word_embedding_model, pooling_model])# 編碼知識庫中的問題
question_embeddings = [encoder.encode(question) for question, _ in knowledge_base]# 提取關鍵詞
def extract_keywords(text):return list(jieba.cut(text))# 從知識庫查找答案(結合關鍵詞匹配和向量相似度)
def find_answer_from_knowledge_base(question, threshold=0.5):question_keywords = extract_keywords(question)question_embedding = encoder.encode(question)best_match_index = -1best_similarity = -1for i, (kb_question, _) in enumerate(knowledge_base):kb_keywords = extract_keywords(kb_question)# 檢查關鍵詞是否匹配if any(keyword in kb_keywords for keyword in question_keywords):similarity = np.dot(question_embedding, question_embeddings[i]) / (np.linalg.norm(question_embedding) * np.linalg.norm(question_embeddings[i]))if similarity > best_similarity and similarity >= threshold:best_similarity = similaritybest_match_index = iif best_match_index != -1:return knowledge_base[best_match_index][1]return None# 提取配餐參數
def extract_params(text):calory = Noneday = None# 優化后的卡路里提取正則表達式calory_pattern = re.compile(r'(?:每天|每日|每餐)?\s*(?:卡路里|熱量|千卡|大卡)\s*(?:是|約|大概|為)?\s*(\d+)', re.IGNORECASE)# 優化后的天數提取正則表達式day_pattern = re.compile(r'(?:配|安排|制定)?\s*(\d+)\s*(?:天|日|天的餐|日的餐)', re.IGNORECASE)calory_match = calory_pattern.search(text)if calory_match:try:calory = int(calory_match.group(1))except ValueError:passday_match = day_pattern.search(text)if day_match:try:day = int(day_match.group(1))except ValueError:passreturn calory, day# 調用配餐接口
def get_meal_plan(calory, day):logging.debug(f"準備調用配餐接口,calory: {calory}, day: {day}")try:response = requests.get(PORTFOLIO_API_URL, params={"calory": calory, "day": day})logging.debug(f"接口響應狀態碼: {response.status_code}")logging.debug(f"接口響應內容: {response.text}")if response.status_code == 200:logging.debug("配餐接口調用成功")try:response_data = response.json()# 打印完整的響應數據,用于調試logging.debug(f"完整的接口響應數據: {response_data}")# 提取配餐方案信息sku_list = response_data.get("skuList", [])if sku_list:output_text = "以下是為您生成的配餐方案:\n"output_text += "=" * 50 + "\n"current_day = 0for sku in sku_list:sequential_days = sku.get("sequentialDays")if sequential_days is None:logging.warning("配餐數據中缺少 sequentialDays 字段")continueif sequential_days != current_day:current_day = sequential_daysoutput_text += f"\n第 {current_day} 天:\n"output_text += "-" * 50 + "\n"category_type = sku.get("categoryType", "未知餐別")total_kcal = sku.get("totalKcal", "未知熱量")output_text += f"  {category_type}({total_kcal} 千卡):\n"meal_list = sku.get("list", [])for meal in meal_list:meal_name = meal.get("name", "未知套餐")output_text += f"    套餐名稱:{meal_name}\n"output_text += "    包含菜品:\n"category_list = meal.get("getCategoryList", [])for item in category_list:skuname = item.get("skuname", "未知菜品")price = item.get("price", "未知價格")energy = item.get("energy", "未知能量")output_text += f"      - {skuname}(價格:{price} 元,能量:{energy} 千卡)\n"output_text += "=" * 50 + "\n"else:output_text = "獲取配餐方案成功,但無具體信息"return output_textexcept ValueError:logging.error("無法將接口響應內容解析為 JSON 格式")return "調用接口成功,但無法解析響應內容"else:logging.error(f"配餐接口調用失敗,狀態碼: {response.status_code}")return f"調用接口失敗,狀態碼: {response.status_code}"except requests.RequestException as e:logging.error(f"調用配餐接口時發生網絡錯誤: {e}")return f"調用接口時發生網絡錯誤: {e}"# Streamlit UI
st.title("Nutribite 智能營養師聊天機器人")# 初始化聊天歷史
if 'chat_history' not in st.session_state:st.session_state.chat_history = []# 初始化輸入框值
if 'input_value' not in st.session_state:st.session_state.input_value = ""# 獲取用戶輸入
user_input = st.text_input("請輸入你的問題", value=st.session_state.input_value, key="input_key")if user_input:# 拼接歷史對話和當前輸入history_text = "\n".join([f"用戶: {msg['user']}\n機器人: {msg['bot']}" for msg in st.session_state.chat_history]) + "\n" + user_inputlogging.debug(f"拼接后的文本: {history_text}")# 檢查是否處于配餐流程中is_in_meal_process = "配餐" in history_text and ("請問,要配幾天的餐?" in history_text or "請問每天的卡路里大概是多少?" in history_text)# 檢查是否是允許的話題if not any(topic in history_text for topic in ALLOWED_TOPICS) and not is_in_meal_process:bot_response = "我是Nutribite智能營養師,請問我相關問題"else:# 從知識庫查找答案answer = find_answer_from_knowledge_base(user_input)if answer:logging.debug("從知識庫找到答案")bot_response = answerelse:# 檢測用戶問題是否與配餐相關,僅依據當前輸入文本is_meal_related = any(keyword in user_input for keyword in KEYWORDS)# 嘗試從拼接后的文本中提取 calory 和 daycalory, day = extract_params(history_text)if is_meal_related or is_in_meal_process:if day is None:if "請問,要配幾天的餐?" in history_text:# 重新提取當前用戶輸入中的 day_, day = extract_params(user_input)if day is None:logging.debug("仍未提取到 day 參數,再次詢問用戶")bot_response = "抱歉,我沒獲取到配餐天數,請明確告知要配幾天的餐。"else:if calory is None:logging.debug("提取到 day 參數,未提取到 calory 參數,詢問用戶")bot_response = "請問每天的卡路里大概是多少?"else:# 調用配餐接口bot_response = get_meal_plan(calory, day)else:logging.debug("未提取到 day 參數,詢問用戶")bot_response = "請問,要配幾天的餐?"elif calory is None:logging.debug("未提取到 calory 參數,詢問用戶")bot_response = "請問每天的卡路里大概是多少?"else:# 調用配餐接口bot_response = get_meal_plan(calory, day)else:logging.debug("用戶問題與配餐無關,使用 Qwen2 模型生成回復")bot_response = chain.run(user_input)# 更新聊天歷史st.session_state.chat_history.append({"user": user_input, "bot": bot_response})# 清空輸入框st.session_state.input_value = ""# 顯示聊天歷史
for msg in st.session_state.chat_history:st.markdown(f"**用戶**:{msg['user']}")st.markdown(f"**機器人**:{msg['bot']}")

4.執行streamlit run diet_ui.py

這個智能體實現了知識庫、調公司業務接口功能,具體效果圖

然后訪問公網xxxxx:8501

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

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

相關文章

群暉監控套件通過ONVIF協議添加海康攝像頭

1. 首先登錄錄像機 通道管理 找到每個攝像頭的IP地址 2. 登錄某個攝像頭 配置 3. 添加用戶名(注意不能是admin) 設置賬戶密碼 用戶類型選管理員 4. 群暉里面添加攝像頭,自動搜索,添加剛剛那個IP的攝像頭 5. 驗證…

【C++】 —— 筆試刷題day_8

一、求最小公倍數 題目解析 題目很簡單,給定兩個數a和b求它們的最小公倍數。 算法思路 對于求兩個數的最小公倍數問題,想必已經非常熟悉了; 在之前學校上課時,記得老師提起過,最小公倍數 兩個數的乘積 除以最大公約數…

MTK Android12-Android13 設置系統默認語言

Android 系統,默認語言 文章目錄 需求:場景 參考資料實現方案實現思路編譯腳本熟悉-平臺熟悉mssi_64_cnkernel-4.19 解決方案修改文件-實現方案 源碼分析PRODUCT_LOCALES 引用PRODUCT_DEFAULT_LOCALE 定義get-default-product-locale 方法定義PRODUCT_DE…

系統如何查找文件?inode號又是什么?

下面分別詳細解釋您提到的三個問題: “文件系統怎么定位文件”、“inode 是什么”、“為什么刪除后還可能被占用”。 一、文件系統怎么定位文件 1.1 目錄與文件名并不直接存儲文件數據 在常見的 Unix/Linux 文件系統(如 ext4、xfs)或類似的…

05-SpringBoot3入門-整合SpringMVC(配置靜態資源、攔截器)

1、說明 在01-SpringBoot3入門-第一個項目-CSDN博客中,其實就已經整合了SpringMVC。下面講解怎么配置靜態資源和攔截器 2、配置靜態資源 命名:static(文件夾) 位置:src/main/resources 編寫一個html文件 訪問 http:/…

Transformer-LSTM、Transformer、CNN-LSTM、LSTM、CNN五模型多變量回歸預測

聚劃算!Transformer-LSTM、Transformer、CNN-LSTM、LSTM、CNN五模型多變量回歸預測 目錄 聚劃算!Transformer-LSTM、Transformer、CNN-LSTM、LSTM、CNN五模型多變量回歸預測預測效果基本介紹程序設計參考資料 預測效果 基本介紹 聚劃算!Tran…

樹莓派瀏覽器配置全解析:從輕量系統到網頁應用平臺

樹莓派(Raspberry Pi)不僅是嵌入式開發的入門利器,也因其低成本和強大的社區支持而成為物聯網、數字標牌、教育培訓等領域的熱門平臺。在很多應用中,運行一個瀏覽器并作為 Web 前端展示、操作或交互的能力顯得尤為關鍵。 但在資源…

初識Qt(一)

本文部分ppt、視頻截圖原鏈接:萌馬工作室的個人空間-萌馬工作室個人主頁-嗶哩嗶哩視頻 1. Qt是什么? Qt是一個跨平臺的C應用程序開發框架,它既為圖形用戶界面(GUI)程序開發提供了強大支持,也能用于開發非GUI的控制臺程序、服務端…

六十天前端強化訓練之第三十二天之Babel 轉譯配置大師級深度講解

歡迎來到編程星辰海的博客講解 看完可以給一個免費的三連嗎,謝謝大佬! 目錄 一、核心概念與知識體系詳解 1. Babel 工作原理全景解析 二、完整配置方案(帶詳細注釋) 1. 進階版 .babelrc 配置 2. Webpack 集成配置&#xff08…

智能提示詞生成器:助力測試工程師快速設計高質量測試用例

在軟件測試中,測試用例設計方法的選擇和實施是確保軟件質量的重要步驟。測試工程師經常需要根據不同的測試場景、參數維度和業務需求,設計出覆蓋率高且有效的測試用例。然而,設計測試用例并非易事,特別是在面對復雜的業務邏輯時。 為了幫助測試工程師高效生成測試用例提示…

beanie.exceptions.CollectionWasNotInitialized

遇到這樣的情況不要慌,不要慌 1:檢查模型是否已經初始化: class TaskModel(Document):"""定時任務模型"""task_id: str Field(default_factorylambda: str(uuid.uuid4()), # 新增默認值description"任…

【CVE-2025-30208】| Vite-漏洞分析與復現

漏洞簡介 CVE-2025-30208 是 Vite 開發服務器中的一個任意文件讀取漏洞。該漏洞允許攻擊者通過特定的 URL 參數繞過訪問控制,從而讀取服務器上的敏感文件(如 /etc/passwd 或 C:\windows\win.ini)。 該漏洞主要影響以下版本的 Vite&#xff…

將 Markdown 表格結構轉換為Excel 文件

在數據管理和文檔編寫過程中,我們經常使用 Markdown 來記錄表格數據。然而,Markdown 格式的表格在實際應用中不如 Excel 方便,特別是需要進一步處理數據時。因此,我們開發了一個使用 wxPython 的 GUI 工具,將 Markdown…

Golang使用 ip2region 查詢IP的地區信息

利用 ip2region 進行 IP 地址定位 import ("fmt""log""github.com/lionsoul2014/ip2region/binding/golang/xdb" )func main() {ip : "213.118.179.98"dbPath : ".\\cmd\\ip\\ip2region.xdb"// 1、初始化查詢器//searcher,…

對匿名認證的理解

概述:在 Spring Security 中,** 匿名認證(Anonymous Authentication)** 是一種特殊的認證機制,用于處理未提供有效憑證的請求。 匿名認證的本質 目的:允許未認證用戶訪問特定資源。原理: 當請求…

C++調用Python

Python安裝 地址: python官網 可以根據需要下載對應的版本。 調用python python測試腳本 # my_script.py import sys import jsondef calculate(a, b):return a * b 10 # 示例計算邏輯if __name__ "__main__":# 從命令行參數讀取 JSON 字符串try…

工程數字建造管理系統平臺有哪些?好的數字建造管理系統推薦

一、什么是工程數字建造管理系統平臺? 工程數字建造管理系統平臺是一種集成了先進信息技術(如云計算、大數據、物聯網等)的綜合性管理工具,它旨在通過數字化手段提升工程建造全過程的管理效率和決策水平。這一平臺不僅覆蓋了工程…

Android開發EmojiCompat 初始化

Android開發EmojiCompat 初始化 報錯信息: ensure spannable:java.lang.IllegalStateException: EmojiCompat is not initialized 在Application上寫上下面代碼即可: EmojiCompat.Config config new BundledEmojiCompatConfig(this);EmojiCompat.in…

【Go】數組

數組Array 重點: 數組是值類型 注意點: 1. 數組:是同一種數據類型的固定長度的序列。2. 數組定義:var a [len]int,比如:var a [5]int,數組長度必須是常量,且是類型的組成部分。一旦定義&…

CORDIC算法:三角函數的硬件加速革命——從數學原理到FPGA實現的超高效計算方案

計算機該如何求解三角函數?或許你的第一印象是采用泰勒展開,或者采用多項式進行逼近。對于前者,來回的迭代計算開銷成本很大;對于后者,多項式式逼近在較窄的范圍內比較接近,超過一定范圍后,就變…