浦語書生大模型實戰(zhàn)訓(xùn)練營03筆記和作業(yè)
1.1配置環(huán)境

進入命令行,安裝pytorch環(huán)境
bash
/root/share/install_conda_env_internlm_base.sh InternLM
conda activate InternLM
# 升級pip
python -m pip install --upgrade pip
pip install modelscope==1.9.5
pip install transformers==4.35.2
pip install streamlit==1.24.0
pip install sentencepiece==0.1.99
pip install accelerate==0.24.1
1.2 模型下載
在本地的 /root/share/temp/model_repos/internlm-chat-7b 目錄下已存儲有所需的模型文件參數(shù),可以直接拷貝到個人目錄的模型保存地址:
mkdir -p /root/data/model/Shanghai_AI_Laboratory
cp -r /root/share/temp/model_repos/internlm-chat-7b /root/data/model/Shanghai_AI_Laboratory/internlm-chat-7b
如果本地拷貝模型參數(shù)出現(xiàn)問題,我們也可以使用 modelscope 中的 snapshot_download 函數(shù)下載模型,第一個參數(shù)為模型名稱,參數(shù) cache_dir 為模型的下載路徑。
在 /root 路徑下新建目錄 data,在目錄下新建 download.py 文件并在其中輸入以下內(nèi)容,粘貼代碼后記得保存文件,如下圖所示。并運行 python /root/data/download.py 執(zhí)行下載,模型大小為 14 GB,下載模型大概需要 10~20 分鐘
import torch
from modelscope import snapshot_download, AutoModel, AutoTokenizer
import os
model_dir = snapshot_download('Shanghai_AI_Laboratory/internlm-chat-7b', cache_dir='/root/data/model', revision='v1.0.3')
1.3安裝依賴
pip install langchain==0.0.292
pip install gradio==4.4.0
pip install chromadb==0.4.15
pip install sentence-transformers==2.2.2
pip install unstructured==0.10.30
pip install markdown==3.3.7
1.4使用鏡像下載模型
import os
# 設(shè)置環(huán)境變量
os.environ['HF_ENDPOINT'] = 'https://hf-mirror.com'
# 下載模型
os.system('huggingface-cli download --resume-download sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2 --local-dir /root/data/model/sentence-transformer')
1.5 下載模型相關(guān) NLTK 資源庫
cd /root
git clone https://gitee.com/yzy0612/nltk_data.git --branch gh-pages
cd nltk_data
mv packages/* ./
cd tokenizers
unzip punkt.zip
cd ../taggers
unzip averaged_perceptron_tagger.zip
2.1 下載開源數(shù)據(jù)庫作為數(shù)據(jù)語料庫并搜索語料數(shù)據(jù)庫中的文本文件將文本數(shù)據(jù)轉(zhuǎn)為向量數(shù)據(jù)庫數(shù)據(jù)并保存在硬盤
# 進入到數(shù)據(jù)庫盤
cd /root/data
# clone 上述開源倉庫
git clone https://gitee.com/open-compass/opencompass.git
git clone https://gitee.com/InternLM/lmdeploy.git
git clone https://gitee.com/InternLM/xtuner.git
git clone https://gitee.com/InternLM/InternLM-XComposer.git
git clone https://gitee.com/InternLM/lagent.git
git clone https://gitee.com/InternLM/InternLM.git
# 首先導(dǎo)入所需第三方庫
from langchain.document_loaders import UnstructuredFileLoader
from langchain.document_loaders import UnstructuredMarkdownLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.vectorstores import Chroma
from langchain.embeddings.huggingface import HuggingFaceEmbeddings
from tqdm import tqdm
import os
# 獲取文件路徑函數(shù)
def get_files(dir_path):
# args:dir_path,目標(biāo)文件夾路徑
file_list = []
for filepath, dirnames, filenames in os.walk(dir_path):
# os.walk 函數(shù)將遞歸遍歷指定文件夾
for filename in filenames:
# 通過后綴名判斷文件類型是否滿足要求
if filename.endswith(".md"):
# 如果滿足要求,將其絕對路徑加入到結(jié)果列表
file_list.append(os.path.join(filepath, filename))
elif filename.endswith(".txt"):
file_list.append(os.path.join(filepath, filename))
return file_list
# 加載文件函數(shù)
def get_text(dir_path):
# args:dir_path,目標(biāo)文件夾路徑
# 首先調(diào)用上文定義的函數(shù)得到目標(biāo)文件路徑列表
file_lst = get_files(dir_path)
# docs 存放加載之后的純文本對象
docs = []
# 遍歷所有目標(biāo)文件
for one_file in tqdm(file_lst):
file_type = one_file.split('.')[-1]
if file_type == 'md':
loader = UnstructuredMarkdownLoader(one_file)
elif file_type == 'txt':
loader = UnstructuredFileLoader(one_file)
else:
# 如果是不符合條件的文件,直接跳過
continue
docs.extend(loader.load())
return docs
# 目標(biāo)文件夾
tar_dir = [
"/root/data/InternLM",
"/root/data/InternLM-XComposer",
"/root/data/lagent",
"/root/data/lmdeploy",
"/root/data/opencompass",
"/root/data/xtuner"
]
# 加載目標(biāo)文件
docs = []
for dir_path in tar_dir:
docs.extend(get_text(dir_path))
# 對文本進行分塊
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500, chunk_overlap=150)
split_docs = text_splitter.split_documents(docs)
# 加載開源詞向量模型
embeddings = HuggingFaceEmbeddings(model_name="/root/data/model/sentence-transformer")
# 構(gòu)建向量數(shù)據(jù)庫
# 定義持久化路徑
persist_directory = 'data_base/vector_db/chroma'
# 加載數(shù)據(jù)庫
vectordb = Chroma.from_documents(
documents=split_docs,
embedding=embeddings,
persist_directory=persist_directory # 允許我們將persist_directory目錄保存到磁盤上
)
# 將加載的向量數(shù)據(jù)庫持久化到磁盤上
vectordb.persist()


、
2.2創(chuàng)建本地LLM繼承子類調(diào)用向量數(shù)據(jù)庫,定義LLM模型構(gòu)建提示詞模板,部署并映射本地端口
from langchain.vectorstores import Chroma
from langchain.embeddings.huggingface import HuggingFaceEmbeddings
import os
from LLM import InternLM_LLM
from langchain.prompts import PromptTemplate
from langchain.chains import RetrievalQA
def load_chain():
# 加載問答鏈
# 定義 Embeddings
embeddings = HuggingFaceEmbeddings(model_name="/root/data/model/sentence-transformer")
# 向量數(shù)據(jù)庫持久化路徑
persist_directory = 'data_base/vector_db/chroma'
# 加載數(shù)據(jù)庫
vectordb = Chroma(
persist_directory=persist_directory, # 允許我們將persist_directory目錄保存到磁盤上
embedding_function=embeddings
)
# 加載自定義 LLM
llm = InternLM_LLM(model_path = "/root/data/model/Shanghai_AI_Laboratory/internlm-chat-7b")
# 定義一個 Prompt Template
template = """使用以下上下文來回答最后的問題。如果你不知道答案,就說你不知道,不要試圖編造答
案。盡量使答案簡明扼要??偸窃诨卮鸬淖詈笳f“謝謝你的提問!”。
{context}
問題: {question}
有用的回答:"""
QA_CHAIN_PROMPT = PromptTemplate(input_variables=["context","question"],template=template)
# 運行 chain
qa_chain = RetrievalQA.from_chain_type(llm,retriever=vectordb.as_retriever(),return_source_documents=True,chain_type_kwargs={"prompt":QA_CHAIN_PROMPT})
return qa_chain
class Model_center():
"""
存儲檢索問答鏈的對象
"""
def __init__(self):
# 構(gòu)造函數(shù),加載檢索問答鏈
self.chain = load_chain()
def qa_chain_self_answer(self, question: str, chat_history: list = []):
"""
調(diào)用問答鏈進行回答
"""
if question == None or len(question) < 1:
return "", chat_history
try:
chat_history.append(
(question, self.chain({"query": question})["result"]))
# 將問答結(jié)果直接附加到問答歷史中,Gradio 會將其展示出來
return "", chat_history
except Exception as e:
return e, chat_history
import gradio as gr
# 實例化核心功能對象
model_center = Model_center()
# 創(chuàng)建一個 Web 界面
block = gr.Blocks()
with block as demo:
with gr.Row(equal_height=True):
with gr.Column(scale=15):
# 展示的頁面標(biāo)題
gr.Markdown("""<h1><center>InternLM</center></h1>
<center>書生浦語</center>
""")
with gr.Row():
with gr.Column(scale=4):
# 創(chuàng)建一個聊天機器人對象
chatbot = gr.Chatbot(height=450, show_copy_button=True)
# 創(chuàng)建一個文本框組件,用于輸入 prompt。
msg = gr.Textbox(label="Prompt/問題")
with gr.Row():
# 創(chuàng)建提交按鈕。
db_wo_his_btn = gr.Button("Chat")
with gr.Row():
# 創(chuàng)建一個清除按鈕,用于清除聊天機器人組件的內(nèi)容。
clear = gr.ClearButton(
components=[chatbot], value="Clear console")
# 設(shè)置按鈕的點擊事件。當(dāng)點擊時,調(diào)用上面定義的 qa_chain_self_answer 函數(shù),并傳入用戶的消息和聊天歷史記錄,然后更新文本框和聊天機器人組件。
db_wo_his_btn.click(model_center.qa_chain_self_answer, inputs=[
msg, chatbot], outputs=[msg, chatbot])
gr.Markdown("""提醒:<br>
1. 初始化數(shù)據(jù)庫時間可能較長,請耐心等待。
2. 使用中如果出現(xiàn)異常,將會在文本輸入框進行展示,請不要驚慌。 <br>
""")
gr.close_all()
# 直接啟動
demo.launch()
基礎(chǔ)作業(yè):


浙公網(wǎng)安備 33010602011771號