Yuan2.0

对标题的评论会显示在这里

Yuan2.0-2B FastApi 部署调用

对这一段的评论会显示在这里

环境准备

对这一段的评论会显示在这里

在 Autodl 平台中租赁一个 RTX 3090/24G 显存的显卡机器。如下图所示,镜像选择 PyTorch-->2.1.0-->3.10(ubuntu22.04)-->12.1。

对这一段的评论会显示在这里
开启机器配置选择
开启机器配置选择
对这一段的评论会显示在这里

接下来,我们打开刚刚租用服务器的 JupyterLab,如下图所示。

对这一段的评论会显示在这里
开启JupyterLab
开启JupyterLab
对这一段的评论会显示在这里

然后打开其中的终端,开始环境配置、模型下载和运行演示。

对这一段的评论会显示在这里
开启终端
开启终端
对这一段的评论会显示在这里

环境配置

对这一段的评论会显示在这里

pip 换源加速下载并安装依赖包

对这一段的评论会显示在这里
# 升级pip
python -m pip install --upgrade pip

# 更换 pypi 源加速库的安装
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

# 安装 fastapi modelscope
pip install fastapi modelscope
对这一段的评论会显示在这里

考虑到部分同学配置环境可能会遇到一些问题,我们在AutoDL平台准备了Yuan2.0的镜像,点击下方链接并直接创建Autodl示例即可。 https://www.codewithgpu.com/i/datawhalechina/self-llm/Yuan2.0

对这一段的评论会显示在这里

模型下载

对这一段的评论会显示在这里

使用 modelscope 中的 snapshot_download 函数下载模型,第一个参数为模型名称,参数 cache_dir 为模型的下载路径。

对这一段的评论会显示在这里

这里可以先进入autodl平台,初始化机器对应区域的的文件存储,文件存储路径为'/root/autodl-fs'。 该存储中的文件不会随着机器的关闭而丢失,这样可以避免模型二次下载。

对这一段的评论会显示在这里
autodl-fs
autodl-fs
对这一段的评论会显示在这里

然后运行下面代码,执行模型下载。模型大小为 4.5GB,下载大概需要 5 分钟。

对这一段的评论会显示在这里
from modelscope import snapshot_download
model_dir = snapshot_download('YuanLLM/Yuan2-2B-Mars-hf', cache_dir='/root/autodl-fs')
对这一段的评论会显示在这里

代码准备

对这一段的评论会显示在这里

点击自定义服务,开启AutoDL开放端口。

对这一段的评论会显示在这里
AutoDL开放端口配置
AutoDL开放端口配置
对这一段的评论会显示在这里

有些区域的机器需要配置AutoDL开放端口,配置方法写在本项目中General-Setting目录,首次使用请参考该文档。

对这一段的评论会显示在这里

配置方法如下图所示。

对这一段的评论会显示在这里
AutoDL开放端口配置
AutoDL开放端口配置
对这一段的评论会显示在这里

新建 api.py 文件并在其中输入以下内容,粘贴代码后请及时保存文件。

对这一段的评论会显示在这里

下面的代码有很详细的注释,大家如有不理解的地方,欢迎提出 issue。

对这一段的评论会显示在这里
from fastapi import FastAPI, Request
from transformers import LlamaTokenizer, AutoModelForCausalLM
import uvicorn
import json
import datetime
import torch

# 设置设备参数
DEVICE = "cuda"  # 使用CUDA
DEVICE_ID = "0"  # CUDA设备ID,如果未设置则为空
CUDA_DEVICE = f"{DEVICE}:{DEVICE_ID}" if DEVICE_ID else DEVICE  # 组合CUDA设备信息

# 清理GPU内存函数
def torch_gc():
    if torch.cuda.is_available():  # 检查是否可用CUDA
        with torch.cuda.device(CUDA_DEVICE):  # 指定CUDA设备
            torch.cuda.empty_cache()  # 清空CUDA缓存
            torch.cuda.ipc_collect()  # 收集CUDA内存碎片

# 创建FastAPI应用
app = FastAPI()

# 处理POST请求的端点
@app.post("/")
async def create_item(request: Request):
    global model, tokenizer  # 声明全局变量以便在函数内部使用模型和分词器
    json_post_raw = await request.json()  # 获取POST请求的JSON数据
    json_post = json.dumps(json_post_raw)  # 将JSON数据转换为字符串
    json_post_list = json.loads(json_post)  # 将字符串转换为Python对象
    prompt = json_post_list.get('prompt')  # 获取请求中的提示

    # 调用模型进行对话生成
    prompt += "<sep>"
    inputs = tokenizer(prompt, return_tensors="pt")["input_ids"].cuda()
    outputs = model.generate(inputs,do_sample=False,max_length=4000)
    output = tokenizer.decode(outputs[0])
    response = output.split("<sep>")[-1]

    now = datetime.datetime.now()  # 获取当前时间
    time = now.strftime("%Y-%m-%d %H:%M:%S")  # 格式化时间为字符串

    # 构建响应JSON
    answer = {
        "response": response,
        "status": 200,
        "time": time
    }
    # 构建日志信息
    log = "[" + time + "] " + '", prompt:"' + prompt + '", response:"' + repr(response) + '"'
    print(log)  # 打印日志
    torch_gc()  # 执行GPU内存清理
    return answer  # 返回响应

# 主函数入口
if __name__ == '__main__':
    # 加载预训练的分词器和模型
    path = '/root/autodl-fs/YuanLLM/Yuan2-2B-Mars-hf'

    print("Creat tokenizer...")
    tokenizer = LlamaTokenizer.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.bfloat16, trust_remote_code=True).cuda()

    # 启动FastAPI应用
    # 用6006端口可以将autodl的端口映射到本地,从而在本地使用api
    uvicorn.run(app, host='0.0.0.0', port=6006, workers=1)  # 在指定端口和主机上启动应用
对这一段的评论会显示在这里

Api 部署

对这一段的评论会显示在这里

在终端输入以下命令启动api服务:

对这一段的评论会显示在这里
python api.py
对这一段的评论会显示在这里

加载完毕后出现如下信息说明成功。

对这一段的评论会显示在这里
加载模型
加载模型
对这一段的评论会显示在这里

默认部署在 6006 端口,通过 POST 方法进行调用,可以使用 curl 调用,如下所示:

对这一段的评论会显示在这里
curl -X POST "http://127.0.0.1:6006" \
     -H 'Content-Type: application/json' \
     -d '{"prompt": "你好"}'
对这一段的评论会显示在这里
模型调用
模型调用
对这一段的评论会显示在这里

也可以使用 python 中的 requests 库进行调用,如下所示:

对这一段的评论会显示在这里
import requests
import json

def get_completion(prompt):
    headers = {'Content-Type': 'application/json'}
    data = {"prompt": prompt}
    response = requests.post(url='http://127.0.0.1:6006', headers=headers, data=json.dumps(data))
    return response.json()['response']

if __name__ == '__main__':
    print(get_completion('你好'))
对这一段的评论会显示在这里
模型调用
模型调用
对这一段的评论会显示在这里

Yuan2.0-2B 接入 LangChain 搭建知识库助手

对这一段的评论会显示在这里

环境准备

对这一段的评论会显示在这里

在 Autodl 平台中租赁一个 RTX 3090/24G 显存的显卡机器。如下图所示,镜像选择 PyTorch-->2.1.0-->3.10(ubuntu22.04)-->12.1。

对这一段的评论会显示在这里
开启机器配置选择
开启机器配置选择
对这一段的评论会显示在这里

接下来,我们打开刚刚租用服务器的 JupyterLab,如下图所示。

对这一段的评论会显示在这里
开启JupyterLab
开启JupyterLab
对这一段的评论会显示在这里

然后打开其中的终端,开始环境配置、模型下载和运行演示。

对这一段的评论会显示在这里
开启终端
开启终端
对这一段的评论会显示在这里

环境配置

对这一段的评论会显示在这里

pip 换源加速下载并安装依赖包

对这一段的评论会显示在这里
# 升级pip
python -m pip install --upgrade pip

# 更换 pypi 源加速库的安装
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

# 安装 langchain modelscope
pip install langchain modelscope
对这一段的评论会显示在这里

考虑到部分同学配置环境可能会遇到一些问题,我们在AutoDL平台准备了Yuan2.0的镜像,点击下方链接并直接创建Autodl示例即可。 https://www.codewithgpu.com/i/datawhalechina/self-llm/Yuan2.0

对这一段的评论会显示在这里

模型下载

对这一段的评论会显示在这里

使用 modelscope 中的 snapshot_download 函数下载模型,第一个参数为模型名称,参数 cache_dir 为模型的下载路径。

对这一段的评论会显示在这里

这里可以先进入autodl平台,初始化机器对应区域的的文件存储,文件存储路径为'/root/autodl-fs'。 该存储中的文件不会随着机器的关闭而丢失,这样可以避免模型二次下载。

对这一段的评论会显示在这里
autodl-fs
autodl-fs
对这一段的评论会显示在这里

然后运行下面代码,执行模型下载。模型大小为 4.5GB,下载大概需要 5 分钟。

对这一段的评论会显示在这里
from modelscope import snapshot_download
model_dir = snapshot_download('YuanLLM/Yuan2-2B-Mars-hf', cache_dir='/root/autodl-fs')
对这一段的评论会显示在这里

代码准备

对这一段的评论会显示在这里

为便捷构建 LLM 应用,我们需要基于本地部署的 Yuan2,自定义一个 LLM 类,将 Yuan2 接入到 LangChain 框架中。

对这一段的评论会显示在这里

完成自定义 LLM 类之后,可以以完全一致的方式调用 LangChain 的接口,而无需考虑底层模型调用的不一致。

对这一段的评论会显示在这里

基于本地部署的 Yuan2 自定义 LLM 类并不复杂,我们只需从 LangChain.llms.base.LLM 类继承一个子类,并重写构造函数与 _call 函数即可:

对这一段的评论会显示在这里
from langchain.llms.base import LLM
from typing import Any, List, Optional
from langchain.callbacks.manager import CallbackManagerForLLMRun
from transformers import LlamaTokenizer, AutoModelForCausalLM
import torch

class Yuan2_LLM(LLM):
    # 基于本地 Yuan2 自定义 LLM 类
    tokenizer: LlamaTokenizer = None
    model: AutoModelForCausalLM = None

    def __init__(self, mode_name_or_path :str):
        super().__init__()

        # 加载预训练的分词器和模型
        print("Creat tokenizer...")
        self.tokenizer = LlamaTokenizer.from_pretrained(mode_name_or_path, add_eos_token=False, add_bos_token=False, eos_token='<eod>')
        self.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...")
        self.model = AutoModelForCausalLM.from_pretrained(mode_name_or_path, torch_dtype=torch.bfloat16, trust_remote_code=True).cuda()

    def _call(self, prompt : str, stop: Optional[List[str]] = None,
                run_manager: Optional[CallbackManagerForLLMRun] = None,
                **kwargs: Any):

        prompt += "<sep>"
        inputs = self.tokenizer(prompt, return_tensors="pt")["input_ids"].cuda()
        outputs = self.model.generate(inputs,do_sample=False,max_length=4000)
        output = self.tokenizer.decode(outputs[0])
        response = output.split("<sep>")[-1]

        return response

    @property
    def _llm_type(self) -> str:
        return "Yuan2_LLM"
对这一段的评论会显示在这里

在上述类定义中,我们分别重写了构造函数和 _call 函数:对于构造函数,我们在对象实例化的一开始加载本地部署的 Yuan2 模型,从而避免每一次调用都需要重新加载模型带来的时间过长;_call 函数是 LLM 类的核心函数,LangChain 会调用该函数来调用 LLM,在该函数中,我们调用已实例化模型的 generate 方法,从而实现对模型的调用并返回调用结果。

对这一段的评论会显示在这里

在整体项目中,我们将上述代码封装为 LLM.py,后续将直接从该文件中引入自定义的 LLM 类。

对这一段的评论会显示在这里

调用

对这一段的评论会显示在这里

然后就可以像使用任何其他的langchain大模型功能一样使用了。

对这一段的评论会显示在这里
from LLM import Yuan2_LLM
llm = Yuan2_LLM('/root/autodl-fs/YuanLLM/Yuan2-2B-Mars-hf')
print(llm("你是谁"))
对这一段的评论会显示在这里
alt text
alt text
对这一段的评论会显示在这里

Yuan2.0-2B WebDemo部署

对这一段的评论会显示在这里

环境准备

对这一段的评论会显示在这里

在 Autodl 平台中租赁一个 RTX 3090/24G 显存的显卡机器。如下图所示,镜像选择 PyTorch-->2.1.0-->3.10(ubuntu22.04)-->12.1。

对这一段的评论会显示在这里
开启机器配置选择
开启机器配置选择
对这一段的评论会显示在这里

接下来,我们打开刚刚租用服务器的 JupyterLab,如下图所示。

对这一段的评论会显示在这里
开启JupyterLab
开启JupyterLab
对这一段的评论会显示在这里

然后打开其中的终端,开始环境配置、模型下载和运行演示。

对这一段的评论会显示在这里
开启终端
开启终端
对这一段的评论会显示在这里

环境配置

对这一段的评论会显示在这里

pip 换源加速下载并安装依赖包

对这一段的评论会显示在这里
# 升级pip
python -m pip install --upgrade pip

# 更换 pypi 源加速库的安装
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

# 安装 einops modelscope streamlit
pip install einops modelscope streamlit==1.24.0
对这一段的评论会显示在这里

考虑到部分同学配置环境可能会遇到一些问题,我们在AutoDL平台准备了Yuan2.0的镜像,点击下方链接并直接创建Autodl示例即可。 https://www.codewithgpu.com/i/datawhalechina/self-llm/Yuan2.0

对这一段的评论会显示在这里

模型下载

对这一段的评论会显示在这里

使用 modelscope 中的 snapshot_download 函数下载模型,第一个参数为模型名称,参数 cache_dir 为模型的下载路径。

对这一段的评论会显示在这里

这里可以先进入autodl平台,初始化机器对应区域的的文件存储,文件存储路径为'/root/autodl-fs'。 该存储中的文件不会随着机器的关闭而丢失,这样可以避免模型二次下载。

对这一段的评论会显示在这里
autodl-fs
autodl-fs
对这一段的评论会显示在这里

然后运行下面代码,执行模型下载。模型大小为 4.5GB,下载大概需要 5 分钟。

对这一段的评论会显示在这里
from modelscope import snapshot_download
model_dir = snapshot_download('YuanLLM/Yuan2-2B-Mars-hf', cache_dir='/root/autodl-fs')
对这一段的评论会显示在这里

代码准备

对这一段的评论会显示在这里

/root/autodl-tmp路径下新建 chatBot.py 文件并在其中输入以下内容,粘贴代码后记得保存文件。下面的代码有很详细的注释,大家如有不理解的地方,欢迎提出issue。

对这一段的评论会显示在这里

chatBot.py代码如下

对这一段的评论会显示在这里
# 导入所需的库
from transformers import LlamaTokenizer, AutoModelForCausalLM
import torch
import streamlit as st

# 在侧边栏中创建一个标题和一个链接
with st.sidebar:
    st.markdown("## Yuan2.0 LLM")
    "[开源大模型食用指南 self-llm](https://github.com/datawhalechina/self-llm.git)"
    # 创建一个滑块,用于选择最大长度,范围在0到1024之间,默认值为512
    max_length = st.slider("max_length", 0, 1024, 512, step=1)

# 创建一个标题和一个副标题
st.title("💬 Yuan2.0 Chatbot")
st.caption("🚀 A streamlit chatbot powered by Self-LLM")

# 定义模型路径
path = '/root/autodl-fs/YuanLLM/Yuan2-2B-Mars-hf'

# 定义一个函数,用于获取模型和tokenizer
@st.cache_resource
def get_model():
    print("Creat tokenizer...")
    tokenizer = LlamaTokenizer.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.bfloat16, 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"] = [{"role": "assistant", "content": "有什么可以帮您的?"}]

# 遍历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)

    # 调用模型
    input_str = "<n>".join(msg["content"] for msg in st.session_state.messages) + "<sep>"
    inputs = tokenizer(input_str, return_tensors="pt")["input_ids"].cuda()
    outputs = model.generate(inputs,do_sample=False,max_length=4000)
    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)

    # print(st.session_state)
对这一段的评论会显示在这里

复制机器ssh登录指令

对这一段的评论会显示在这里
对这一段的评论会显示在这里

粘贴到本地电脑的.ssh/config,并修改成如下格式

对这一段的评论会显示在这里
对这一段的评论会显示在这里

然后连接到此ssh,选择linx

对这一段的评论会显示在这里
对这一段的评论会显示在这里

复制密码并输入,按下回车即可登录到机器

对这一段的评论会显示在这里

运行demo

对这一段的评论会显示在这里

在终端中运行以下命令,启动streamlit服务

对这一段的评论会显示在这里
streamlit run chatBot.py --server.address 127.0.0.1 --server.port 6006
对这一段的评论会显示在这里
对这一段的评论会显示在这里

点击在浏览器中打开,即可看到聊天界面。

对这一段的评论会显示在这里

运行效果如下:

对这一段的评论会显示在这里
对这一段的评论会显示在这里

基于vLLM的Yuan 2.0推理服务部署

对这一段的评论会显示在这里

  1. 配置vLLM环境

对这一段的评论会显示在这里

环境要求:torch2.1.2 cuda12.1

对这一段的评论会显示在这里

vLLM环境配置主要分为以下两步,拉取Yuan-2.0项目,以及安装vllm运行环境

对这一段的评论会显示在这里

注:由于pip版本 vllm目前还不支持Yuan 2.0,因此需要编译安装

对这一段的评论会显示在这里

Step 1. 拉取Yuan-2.0项目

对这一段的评论会显示在这里
# 拉取项目
git clone https://github.com/IEIT-Yuan/Yuan-2.0.git
对这一段的评论会显示在这里

Step 2. 安装vLLM运行环境

对这一段的评论会显示在这里
# 进入vLLM项目
cd Yuan-2.0/3rdparty/vllm

# 安装依赖
pip install -r requirements.txt

# 安装setuptools
# vllm对setuptools的版本有要求, 参考 https://github.com/vllm-project/vllm/issues/4961
vim pyproject.toml # 修改为setuptools == 69.5.1
pip install setuptools == 69.5.1

# 安装vllm
pip install -e .
对这一段的评论会显示在这里

  1. Yuan2.0-2B模型基于vLLM的推理和部署

对这一段的评论会显示在这里

以下是如何使用vLLM推理框架对Yuan2.0-2B模型进行推理和部署的示例

对这一段的评论会显示在这里

Step 1. 模型下载

对这一段的评论会显示在这里

使用 modelscope 中的 snapshot_download 函数下载模型,第一个参数为模型名称,参数 cache_dir 为模型的下载路径。

对这一段的评论会显示在这里

这里可以先进入autodl平台,初始化机器对应区域的的文件存储,文件存储路径为'/root/autodl-fs'。 该存储中的文件不会随着机器的关闭而丢失,这样可以避免模型二次下载。

对这一段的评论会显示在这里
autodl-fs
autodl-fs
对这一段的评论会显示在这里

然后运行下面代码,执行模型下载。模型大小为 4.5GB,下载大概需要 5 分钟。

对这一段的评论会显示在这里
from modelscope import snapshot_download
model_dir = snapshot_download('YuanLLM/Yuan2-2B-Mars-hf', cache_dir='/root/autodl-fs')
对这一段的评论会显示在这里

Step 2. 基于vllm推理Yuan2.0-2B

对这一段的评论会显示在这里

基于vllm推理Yuan2.0-2B首先需要加载模型,然后进行推理

对这一段的评论会显示在这里

  1. 加载模型

对这一段的评论会显示在这里
from vllm import LLM, SamplingParams
import time

# 配置参数
sampling_params = SamplingParams(max_tokens=300, temperature=1, top_p=0, top_k=1, min_p=0.0, length_penalty=1.0, repetition_penalty=1.0, stop="<eod>", )

# 加载模型
llm = LLM(model="/root/autodl-fs/YuanLLM/Yuan2-2B-Mars-hf", trust_remote_code=True)
对这一段的评论会显示在这里

  1. 推理

对这一段的评论会显示在这里

推理支持单个prompt和多个prompt

对这一段的评论会显示在这里
Option 1. 单个prompt推理
对这一段的评论会显示在这里
prompts = ["给我一个python打印helloword的代码<sep>"]

start_time = time.time()
outputs = llm.generate(prompts, sampling_params)
end_time = time.time()

for output in outputs:
    prompt = output.prompt
    generated_text = output.outputs[0].text
    print("Prompt:", prompt)
    print("Generated text:", generated_text)
    print()

print("inference_time:", (end_time - start_time))
对这一段的评论会显示在这里
Option 2. 多个prompt推理
对这一段的评论会显示在这里
prompts = ["给我一个python打印helloword的代码<sep>", "给我一个c++打印helloword的代码<sep>"]

start_time = time.time()
outputs = llm.generate(prompts, sampling_params)
end_time = time.time()

for output in outputs:
    prompt = output.prompt
    generated_text = output.outputs[0].text
    print("Prompt:", prompt)
    print("Generated text:", generated_text)
    print()

print("inference_time:", (end_time - start_time))
对这一段的评论会显示在这里

Step 3. 基于vllm.entrypoints.api_server部署Yuan2.0-2B

对这一段的评论会显示在这里

基于api_server部署Yuan2.0-2B的步骤包括推理服务的发起和调用

对这一段的评论会显示在这里

  1. 服务发起

对这一段的评论会显示在这里
# 请在命令行运行以下命令,不用直接在jupyter中使用!python运行
python -m vllm.entrypoints.api_server --model=/root/autodl-fs/YuanLLM/Yuan2-2B-Mars-hf --trust-remote-code
对这一段的评论会显示在这里

(该图片在源文档中已缺失或失效)

对这一段的评论会显示在这里

  1. 服务调用

对这一段的评论会显示在这里

服务调用有以下两种方式:第一种是通过命令行直接调用;第二种方式是通过运行脚本批量调用。

对这一段的评论会显示在这里
Option 1. 基于命令行调用服务
对这一段的评论会显示在这里
!curl http://localhost:8000/generate -d '{"prompt": "给我一个python打印helloword的代码<sep>", "use_beam_search": false,  "n": 1, "temperature": 1, "top_p": 0, "top_k": 1,  "max_tokens":256, "stop": "<eod>"}'
对这一段的评论会显示在这里
Option 2. 基于命令脚本调用服务
对这一段的评论会显示在这里
import requests
import json

prompt = "给我一个python打印helloword的代码<sep>"
raw_json_data = {
        "prompt": prompt,
        "logprobs": 1,
        "max_tokens": 256,
        "temperature": 1,
        "use_beam_search": False,
        "top_p": 0,
        "top_k": 1,
        "stop": "<eod>",
        }
json_data = json.dumps(raw_json_data)
headers = {
        "Content-Type": "application/json",
        }
response = requests.post(f'http://localhost:8000/generate',
                     data=json_data,
                     headers=headers)
output = response.text
output = json.loads(output)
print(output)
对这一段的评论会显示在这里

Step 4. 基于vllm.entrypoints.openai.api_server部署Yuan2.0-2B

对这一段的评论会显示在这里

基于openai的api_server部署Yuan2.0-2B的步骤和step 3的步骤类似,发起服务和调用服务的方式如下:

对这一段的评论会显示在这里

  1. 服务发起

对这一段的评论会显示在这里
# 请在命令行运行以下命令,不用直接在jupyter中使用!python运行
python -m vllm.entrypoints.openai.api_server --model=/root/autodl-fs/YuanLLM/Yuan2-2B-Mars-hf --trust-remote-code
对这一段的评论会显示在这里

(该图片在源文档中已缺失或失效)

对这一段的评论会显示在这里

  1. 服务调用

对这一段的评论会显示在这里

服务调用有以下两种方式:第一种是通过命令行直接调用;第二种方式是通过运行脚本批量调用。

对这一段的评论会显示在这里
Option 1. 基于命令行调用服务
对这一段的评论会显示在这里
!curl http://localhost:8000/v1/completions -H "Content-Type: application/json" -d '{"model": "/root/autodl-fs/YuanLLM/Yuan2-2B-Mars-hf", "prompt": "给我一个python打印helloword的代码<sep>", "max_tokens": 300, "temperature": 1, "top_p": 0, "top_k": 1, "stop": "<eod>"}'
对这一段的评论会显示在这里
Option 2. 基于命令脚本调用服务
对这一段的评论会显示在这里
import requests
import json

prompt = "给我一个python打印helloword的代码<sep>"
raw_json_data = {
        "model": "/root/autodl-fs/YuanLLM/Yuan2-2B-Mars-hf",
        "prompt": prompt,
        "max_tokens": 256,
        "temperature": 1,
        "use_beam_search": False,
        "top_p": 0,
        "top_k": 1,
        "stop": "<eod>",
        }
json_data = json.dumps(raw_json_data, ensure_ascii=True)
headers = {
        "Content-Type": "application/json",
        }
response = requests.post(f'http://localhost:8000/v1/completions',
                     data=json_data,
                     headers=headers)
output = response.text
output = json.loads(output)
print(output)
对这一段的评论会显示在这里

Yuan2.0-2B Lora微调

对这一段的评论会显示在这里

Lora微调

对这一段的评论会显示在这里

本节我们简要介绍如何基于 transformers、peft 等框架,对 Yuan2.0-2B 模型进行 Lora 微调。

对这一段的评论会显示在这里

Lora 是一种高效微调方法,深入了解其原理可参见博客:知乎|深入浅出Lora

对这一段的评论会显示在这里

环境要求

对这一段的评论会显示在这里

相比7B、14B甚至更大的模型,Yuan2.0-2B的参数量较小,因此对显存要求的门槛较低。

对这一段的评论会显示在这里

以本教程为例,在设置好的batch size和sequence length下,大约6G显存即可运行。

对这一段的评论会显示在这里

而由于Yuan2.0-2B原始模型是bf16的,需要使用英伟达安培架构的显卡,比如A100、A800或者3090等30系显卡。

对这一段的评论会显示在这里
对这一段的评论会显示在这里

实际上,如果使用fp16混合精度训练,T4、2080 Ti、1080 Ti等显卡也可以轻松运行。

对这一段的评论会显示在这里
对这一段的评论会显示在这里

因此,本教程提供了以下两个nodebook文件,来让大家更好的学习:

对这一段的评论会显示在这里

bf16 nodebook 需要英伟达安培架构的显卡
fp16 nodebook 不需要英伟达安培架构的显卡

对这一段的评论会显示在这里

注意事项

对这一段的评论会显示在这里

使用fp16混合精度训练时,需要进行如下修改:

对这一段的评论会显示在这里

模型加载为float16

对这一段的评论会显示在这里
model = AutoModelForCausalLM.from_pretrained(path, device_map="auto", torch_dtype=torch.float16, trust_remote_code=True)
对这一段的评论会显示在这里

添加训练参数fp16=Ture

对这一段的评论会显示在这里
args = TrainingArguments(
    output_dir="./output/Yuan2.0-2B_lora_fp16",
    per_device_train_batch_size=4,
    gradient_accumulation_steps=1,
    logging_steps=10,
    num_train_epochs=3,
    save_steps=10, # 为了快速演示,这里设置10,建议你设置成100
    learning_rate=5e-5,
    save_on_each_node=True,
    gradient_checkpointing=True,
    fp16=True # 使用fp16训练
)
对这一段的评论会显示在这里

将可训练的lora参数设置为fp32

对这一段的评论会显示在这里
# 待训练的lora参数需转成fp32
print_flag = True
for param in filter(lambda p: p.requires_grad, model.parameters()):
    if print_flag:
        print(param.data.dtype)
        print_flag = False
    param.data = param.data.to(torch.float32)
对这一段的评论会显示在这里

否则会遇到如下错误:

对这一段的评论会显示在这里

无法正常混合精度训练

对这一段的评论会显示在这里
ValueError: Attempting to unscale FP16 gradients.
对这一段的评论会显示在这里

loss为nan,模型生成连续unk。

对这一段的评论会显示在这里
对这一段的评论会显示在这里
对这一段的评论会显示在这里

修改后,正常训练的loss和预测结果如下:

对这一段的评论会显示在这里
对这一段的评论会显示在这里
对这一段的评论会显示在这里

README

对这一段的评论会显示在这里

  1. 模型简介

对这一段的评论会显示在这里

源2.0 是浪潮信息发布的新一代基础语言大模型,包括源2.0-102B,源2.0-51B和源2.0-2B。源2.0是在源1.0的基础上,利用更多样的高质量预训练数据和指令微调数据集,令模型在语义、数学、推理、代码、知识等不同方面具备更强的理解能力。

对这一段的评论会显示在这里

算法方面,源2.0提出并采用了一种新型的注意力算法结构:局部注意力过滤增强机制(LFA:Localized Filtering-based Attention)。LFA通过先学习相邻词之间的关联性,然后再计算全局关联性的方法,能够更好地学习到自然语言的局部和全局的语言特征,对于自然语言的关联语义理解更准确、更人性,提升了模型的自然语言表达能力,进而提升了模型精度。

对这一段的评论会显示在这里

项目地址:https://github.com/IEIT-Yuan/Yuan-2.0

对这一段的评论会显示在这里

官方报道:https://mp.weixin.qq.com/s/rjnsUS83TT7aEN3r2i0IPQ

对这一段的评论会显示在这里

论文链接:https://github.com/IEIT-Yuan/Yuan-2.0/blob/main/docs/Yuan2.0_paper.pdf

对这一段的评论会显示在这里

  1. 模型下载

对这一段的评论会显示在这里

Yuan2.0提供了多种模型格式,下载链接如下表所示:

对这一段的评论会显示在这里

| 模型 | 序列长度 | 下载链接 |
| 源2.0-102B-hf | 4K | ModelScope | HuggingFace | OpenXlab | 百度网盘 | WiseModel |
| 源2.0-51B-hf | 4K | ModelScope | HuggingFace | OpenXlab | 百度网盘 | WiseModel |
| 源2.0-2B-hf | 8K | ModelScope | HuggingFace | OpenXlab | 百度网盘 | WiseModel |
| 源2.0-2B-Janus-hf | 8K | ModelScope | HuggingFace | OpenXlab | 百度网盘 | WiseModel |
| 源2.0-2B-Februa-hf | 8K | ModelScope | HuggingFace | OpenXlab | 百度网盘 | WiseModel |
| 源2.0-2B-Mars-hf New | 8K | ModelScope | HuggingFace | OpenXlab | 百度网盘 | WiseModel |

对这一段的评论会显示在这里

注:源2.0-2B-Mars-hf、源2.0-2B-Februa-hf、源2.0-2B-Janus-hf均为源2.0-2B-hf的迭代版本。

对这一段的评论会显示在这里

  1. 教程简介

对这一段的评论会显示在这里

在上一节介绍的多个模型中,源2.0-2B-Mars-hf是最新版本的2B参数模型,微调和部署源2.0-2B-Mars-hf对显存和硬盘的要求都相对较低。

对这一段的评论会显示在这里

因此,本教程以源2.0-2B-Mars-hf为基础,介绍以下内容:

对这一段的评论会显示在这里

01-Yuan2.0-2B FastApi 部署调用
02-Yuan2.0-2B Langchain 接入
03-Yuan2.0-2B WebDemo部署
04-Yuan2.0-2B vLLM部署调用
05-Yuan2.0-2B Lora微调

对这一段的评论会显示在这里