0.前言
这篇笔记主要记录task1的教程相关内容,以及团队项目的相关思考
1. 关于大语言模型:
为了对人类语言的内在规律进行建模,研究者们提出使用语言模型(language model)来准确预测词序列中 下一个词 或者 缺失的词 的概率。
如下图所示,截止到目前,语言模型已经演化了四代,分别是:
- 统计语言模型(Statistical Language Model, SLM):使用马尔可夫假设(Markov Assumption)来建模语言序列的 𝑛 元(𝑛-gram)语言模型
- 神经语言模型(Neural Language Model, NLM):基于神经网络构建语言模型,如循环神经网络(Recurrent Neural Networks, RNN),并学习上下文相关的词表示(即分布式词向量),也被称为词嵌入(Word Embedding)。代表性工作:word2vec
- 预训练语言模型(Pre-trained Language Model, PLM):使用大量的无标注数据预训练双向 LSTM(Bidirectional LSTM, biLSTM)或者Transformer,然后在下游任务上进行微调(Fine-Tuning)。代表性工作:ELMo、BERT、GPT-1/2
- 大语言模型(Large Language Model, LLM):基于“扩展法则”(Scaling Law),即通过增加模型参数或训练数据,可以提升下游任务的性能,同时具有小模型不具有的“涌现能力”(Emergent Abilities)。代表性工作:GPT-3、ChatGPT、Claude、Llama
2. BaseLine运行与代码分析:
2.1 速通大语言模型:
这次的baseline主要是一个基于浪潮信息源2.0的辅助编程聊天bot,这里我们先尝试将其部署到云端并且运行
这里我们选取的是魔搭平台
这里我们拉取一下仓库,使用的指令如下
git lfs install
git clone https://www.modelscope.cn/datasets/Datawhale/AICamp_yuan_baseline.git
我们需要安装一下库依赖,这里的使用的库是streamlit
这里我们简单介绍一下steamlit
Streamlit是一个用于快速创建数据应用程序的Python库。 它提供了一种简单而直观的方式来构建交互式Web应用,这些应用可以展示数据可视化、接受用户输入,并实时更新显示结果。
简单来说streamlit是一个web版本的python数据可视化工具。在本次的应用中,streamlit提供了接受用户输入,并且输出大模型给出结果的作用
这里运行一下baseline代码,使用的bash指令为:
streamlit run AICamp_yuan_baseline/Task\ 1:零基础玩转源大模型/web_demo_2b.py --server.address 127.0.0.1 --server.port 6006
根据链接访问一下大模型,尝试一下效果。
2.2 代码解析
接下来我们查看一下应用的主要代码,实际上程序的代码主要分成四个个部分
- 初始化模型
- 生成消息列表
- 获取用户输入
- 显示模型输出
# 导入所需的库
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()
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)
这里重点需要留意的是第52行中对于prompt的处理,这里主要是为了保证大模型可以根据用户对话的上下文来给出确定的答案。
整体上程序的架构如下图所示:
这个程序本质上是通过streamlit来获取用户输入、拼接交互历史,并通过API将这一部分的信息传输给源大模型,最后源大模型输出结果,并且通过streamlit将输出再次传送给用户(也就是用户所见到的回复)
程序在架构上采用了经典的B/S架构
B/S架构的主要好处有以下几个
1、无需客户端,用户可以通过浏览器访问。
2、B/S架构可以部署在广域网上,从而保证用户只要有联网设备
3、B/S架构在更新的时候只需要更新服务器即可,不需要更新用户端
4. 小组项目时刻:
4.1 Idea:游戏小助手
此处我们考虑的是制作一个比较好的游戏攻略助手,其可以提供给玩家比较有意思的游戏攻略体验。这里我们考虑到的两个主要使用场景
- 基于游戏体验的攻略:传统的游戏攻略站主要还是提供数值上的一些计算,但是缺乏对于一些相对较为感性的话题建议,比如开荒体验、游戏终局体验等。这一点是大模型较为擅长的。
2 . 面向开发者的游戏小助手:传统的游戏小助手主要是面向游戏玩家,而较少面向游戏开发者,我们希望在第一点的基础上,通过大模型来帮助游戏开发者进一步来优化游戏体验。
目前这个Idea还有一部分细节需要确定
- 游戏类型:游戏发展到如今已经有很多种类了,比如ACT、RPG、MOBA,这一些游戏在游戏的数值计算以及体验上有很多的不同,故此我们需要确定一款特定的游戏来对模型进行优化。
- 在面向开发者的小助手中,我们需要保证提供的信息是开发者所需要的,如何确保这些信息的正确性。
这个Idea的优点也相对明显:
- 高可扩展性:除了模型的调优外,web前后端可以进行的拓展还有很多
- 相对成熟的技术路线:模型调优技术已经有很多相对成熟的方案,web方面主流的框架如django、vue、react、springboot也可以为后期网站开发提供支持
4.2 开发模型选取
本次的项目中,由于团队的规模较小,故此我们采用敏捷开发模型,保证能够在较短的开发时间内对项目进行多次迭代,优化用户体验。通过这种方式来尽可能的使得产品变得更好,敏捷开发一般分为以下5个阶段
项目启动与规划:明确愿景、目标、范围,设定里程碑,建立产品路线图及待办事项列表。
需求分析与迭代计划:从待办事项中挑选需求,通过冲刺计划会议确定迭代任务清单。
迭代开发与实现:设计、编码、测试并行,通过日常站立会议确保进度,目标为迭代末交付可工作软件。
测试与质量保证:迭代末集中测试,自动化测试加速反馈,确保功能质量。
交付与回顾:交付软件,举行回顾会议总结教训,为下一迭代提供改进方向。