一. 环境搭建
具体步骤详细参照 Datawhale
二.Demo搭建
第一步: 点击终端,输入以下命令
git lfs install
git clone https://www.modelscope.cn/datasets/Datawhale/AICamp_yuan_baseline.git
第二步: 安装streamlit
pip install streamlit==1.24.0
第三步: 启动Demo
streamlit run AICamp_yuan_baseline/Task\ 1:零基础玩转源大模型/web_demo_2b.py -server.address 127.0.0.1 --server.port 6006
第四步: 对话大模型
三. 精读baseline代码
# 导入所需的库
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch
import streamlit as st
# 创建一个标题和一个副标题
st.title("💬 Yuan2.0 智能编程助手")
# 源大模型下载
from modelscope import snapshot_download
model_dir = snapshot_download('IEITYuan/Yuan2-2B-Mars-hf', cache_dir='./')
# 定义模型路径
path = './IEITYuan/Yuan2-2B-Mars-hf'
# 定义模型数据类型
torch_dtype = torch.bfloat16 # A10
# torch_dtype = torch.float16 # P100
# 定义一个函数,用于获取模型和tokenizer
@st.cache_resource
def get_model():
print("Creat tokenizer...")
tokenizer = AutoTokenizer.from_pretrained(path, add_eos_token=False, add_bos_token=False, eos_token='<eod>')
tokenizer.add_tokens(['<sep>', '<pad>', '<mask>', '<predict>', '<FIM_SUFFIX>', '<FIM_PREFIX>', '<FIM_MIDDLE>','<commit_before>','<commit_msg>','<commit_after>','<jupyter_start>','<jupyter_text>','<jupyter_code>','<jupyter_output>','<empty_output>'], special_tokens=True)
print("Creat model...")
model = AutoModelForCausalLM.from_pretrained(path, torch_dtype=torch_dtype, trust_remote_code=True).cuda()
print("Done.")
return tokenizer, model
# 加载model和tokenizer
tokenizer, model = get_model()
# 初次运行时,session_state中没有"messages",需要创建一个空列表
if "messages" not in st.session_state:
st.session_state["messages"] = []
# 每次对话时,都需要遍历session_state中的所有消息,并显示在聊天界面上
for msg in st.session_state.messages:
st.chat_message(msg["role"]).write(msg["content"])
# 如果用户在聊天输入框中输入了内容,则执行以下操作
if prompt := st.chat_input():
# 将用户的输入添加到session_state中的messages列表中
st.session_state.messages.append({"role": "user", "content": prompt})
# 在聊天界面上显示用户的输入
st.chat_message("user").write(prompt)
# 调用模型
prompt = "<n>".join(msg["content"] for msg in st.session_state.messages) + "<sep>" # 拼接对话历史
inputs = tokenizer(prompt, return_tensors="pt")["input_ids"].cuda()
outputs = model.generate(inputs, do_sample=False, max_length=1024) # 设置解码方式和最大生成长度
output = tokenizer.decode(outputs[0])
response = output.split("<sep>")[-1].replace("<eod>", '')
# 将模型的输出添加到session_state中的messages列表中
st.session_state.messages.append({"role": "assistant", "content": response})
# 在聊天界面上显示模型的输出
st.chat_message("assistant").write(response)
基于 Streamlit 和 Yuan2-2B-Mars
的聊天应用
3.1 导入相关库
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch
import streamlit as st
使用 OpenAI 的 transformers
库加载和运行大语言模型,并通过 Streamlit 创建一个交互界面
3.2 创建标题
st.title("💬 Yuan2.0 智能编程助手")
3.3 下载模型
from modelscope import snapshot_download
model_dir = snapshot_download('IEITYuan/Yuan2-2B-Mars-hf', cache_dir='./')
snapshot_download
函数将模型文件下载到本地缓存目录。
3.4 定义模型路径和数据类型
指定模型存储路径和数据类型:
path = './IEITYuan/Yuan2-2B-Mars-hf'
torch_dtype = torch.bfloat16 # A10
# torch_dtype = torch.float16 # P100
3.5 定义获取模型和 Tokenizer 的函数
@st.cache_resource
def get_model():
print("Create tokenizer...")
tokenizer = AutoTokenizer.from_pretrained(path, add_eos_token=False, add_bos_token=False, eos_token='<eod>')
tokenizer.add_tokens(['<sep>', '<pad>', '<mask>', '<predict>', '<FIM_SUFFIX>', '<FIM_PREFIX>', '<FIM_MIDDLE>', '<commit_before>', '<commit_msg>', '<commit_after>', '<jupyter_start>', '<jupyter_text>', '<jupyter_code>', '<jupyter_output>', '<empty_output>'], special_tokens=True)
print("Create model...")
model = AutoModelForCausalLM.from_pretrained(path, torch_dtype=torch_dtype, trust_remote_code=True).cuda()
print("Done.")
return tokenizer, model
AutoTokenizer.from_pretrained: 从预训练模型中加载 tokenizer。
AutoModelForCausalLM.from_pretrained: 从预训练模型中加载因果语言模型。
cuda(): 将模型移动到 GPU 加速计算
3.6 加载模型和 Tokenizer
调用上面定义的函数来加载模型和 tokenizer:
tokenizer, model = get_model()
3.7 初始化聊天历史
第一次运行应用时,初始化聊天历史:
if "messages" not in st.session_state:
st.session_state["messages"] = []
st.session_state
用于在不同 Streamlit 组件之间共享状态。
3.8 显示聊天历史
for msg in st.session_state.messages:
st.chat_message(msg["role"]).write(msg["content"])
3.9 处理用户输入
if prompt := st.chat_input():
st.session_state.messages.append({"role": "user", "content": prompt})
st.chat_message("user").write(prompt)
# 调用模型
prompt = "<n>".join(msg["content"] for msg in st.session_state.messages) + "<sep>"
inputs = tokenizer(prompt, return_tensors="pt")["input_ids"].cuda()
outputs = model.generate(inputs, do_sample=False, max_length=1024)
output = tokenizer.decode(outputs[0])
response = output.split("<sep>")[-1].replace("<eod>", '')
st.session_state.messages.append({"role": "assistant", "content": response})
st.chat_message("assistant").write(response)
st.chat_input: 捕获用户在聊天输入框中的输入。
tokenizer.encode: 将输入转换为模型可处理的格式。
model.generate: 使用模型生成响应。
tokenizer.decode: 将模型输出解码回可读文本。