Datawhale AI 夏令营 学习笔记01

# Datawhale

       背景知识:

        大模型是 为了对人类语言的内在规律进行建模,研究者们提出使用语言模型(language model)来准确预测词序列中下一个词或者缺失词的概率。

        通常来说,大模型的构建过程可以分为预训练(Pretraining)、有监督微调(Supervised Fine-tuning, SFT)、基于人类反馈的强化学习对齐(Reinforcement Learning from Human Feedback, RLHF)三个阶段。 

      目前大模型经历了四代统计语言模型(Statistical Language Model, SLM),神经语言模型(Neural Language Model, NLM),预训练语言模型(Pre-trained Language Model, PLM),大语言模型(Large Language Model, LLM)

        大模型的开发范式:

        1.prompt工程:上下文学习(In-Context Learning, ICL),思维链提示(Chain-of-Thought, CoT)

        2.Embedding辅助给LLM外接大脑:由于用的都是网络上公开的数据,具有严重的滞后性,ai可能会出现幻觉的情况,以及最重要的数据的安全性。

        3.微调(fine-tuning):通过喂给ai特定的数据进行调节

        这次学习用的是魔塔平台

        基础的baseline:

        首先导入必要的包

from transformers import AutoTokenizer, AutoModelForCausalLM
import torch
import streamlit as st
from modelscope import snapshot_download

        下载模型,这次用的是Yuan2-2B-Mars,在魔塔平台就可以下载,下载地址是IEITYuan/Yuan2-2B-Mars-hf

# 模型的下载
model_dir = snapshot_download('IEITYuan/Yuan2-2B-Mars-hf', cache_dir='./')

# 定义模型路径
path = './IEITYuan/Yuan2-2B-Mars-hf'

# 定义模型数据类型
torch_dtype = torch.bfloat16 # A10

        定义一个函数来获取模型和tokenizer

# 定义一个函数,用于获取模型和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()

        模型加载好后,到客户端部分,使用的是Streamlit,需要用chat_input()来获取用户的数据,同时将用户输入的历史数据保存下来,并且要ai的回答打印到web上面

# 创建一个标题和一个副标题
st.title("💬 Yuan2.0 智能编程助手")
# 初次运行时,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)

        其中需要注意的就是调用模型这部分,输入的prompt需要先经tokenizer切分成token,并转成对应的id,并通过 .cuda() 将输入也放置在GPU上。然后调用 model.generate() 生成输出的id,并通过 tokenizer.decode() 将id转成对应的字符串。最后从字符串中提取模型生成的内容(即 <sep> 之后的字符串),并删除末尾的 <eod> ,得到最终的回复内容。

        得到了最终的内容先放入列表messages中,角色是assistant,这样就在输入的user的后面,当再此调用的时候,又在assistant下面添加user,就变成了一个链式输入,后面以此往复。

        可以在一开始就添加一个prompt:“你是一个智能编程助手,你只需要完成用户提出的编程要求,并且提供注释。无法解决的问题,就回复目前我还无法解决这个问题“。降低出现幻觉概率。这是我现在知道的最简单的办法。

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值