[大模型]百川2大模型安装和使用方法

发布版本和下载链接见下表:

基座模型对齐模型对齐模型 4bits 量化
7B🤗 Baichuan2-7B-Base🤗 Baichuan2-7B-Chat🤗 Baichuan2-7B-Chat-4bits
13B🤗 Baichuan2-13B-Base🤗 Baichuan2-13B-Chat🤗 Baichuan2-13B-Chat-4bits

推理和部署

推理所需的模型权重、源码、配置已发布在 Hugging Face,下载链接见本文档最开始的表格。我们在此示范多种推理方式。程序会自动从 Hugging Face 下载所需资源。

安装依赖

pip install -r requirements.txt

Python 代码方式

Chat 模型推理方法示范

>>> import torch
>>> from transformers import AutoModelForCausalLM, AutoTokenizer
>>> from transformers.generation.utils import GenerationConfig
>>> tokenizer = AutoTokenizer.from_pretrained("baichuan-inc/Baichuan2-13B-Chat", use_fast=False, trust_remote_code=True)
>>> model = AutoModelForCausalLM.from_pretrained("baichuan-inc/Baichuan2-13B-Chat", device_map="auto", torch_dtype=torch.bfloat16, trust_remote_code=True)
>>> model.generation_config = GenerationConfig.from_pretrained("baichuan-inc/Baichuan2-13B-Chat")
>>> messages = []
>>> messages.append({"role": "user", "content": "解释一下“温故而知新”"})
>>> response = model.chat(tokenizer, messages)
>>> print(response)
"温故而知新"是一句中国古代的成语,出自《论语·为政》篇。这句话的意思是:通过回顾过去,我们可以发现新的知识和理解。换句话说,学习历史和经验可以让我们更好地理解现在和未来。

这句话鼓励我们在学习和生活中不断地回顾和反思过去的经验,从而获得新的启示和成长。通过重温旧的知识和经历,我们可以发现新的观点和理解,从而更好地应对不断变化的世界和挑战。

Base 模型推理方法示范

>>> from transformers import AutoModelForCausalLM, AutoTokenizer
>>> tokenizer = AutoTokenizer.from_pretrained("baichuan-inc/Baichuan2-13B-Base", trust_remote_code=True)
>>> model = AutoModelForCausalLM.from_pretrained("baichuan-inc/Baichuan2-13B-Base", device_map="auto", trust_remote_code=True)
>>> inputs = tokenizer('登鹳雀楼->王之涣\n夜雨寄北->', return_tensors='pt')
>>> inputs = inputs.to('cuda:0')
>>> pred = model.generate(**inputs, max_new_tokens=64, repetition_penalty=1.1)
>>> print(tokenizer.decode(pred.cpu()[0], skip_special_tokens=True))
登鹳雀楼->王之涣
夜雨寄北->李商隐

在上述两段代码中,模型加载指定 device_map='auto',会使用所有可用显卡。如需指定使用的设备,可以使用类似 export CUDA_VISIBLE_DEVICES=0,1(使用了0、1号显卡)的方式控制。

命令行工具方式

python cli_demo.py

本命令行工具是为 Chat 场景设计,因此我们不支持使用该工具调用 Base 模型。

网页 demo 方式

依靠 streamlit 运行以下命令,会在本地启动一个 web 服务,把控制台给出的地址放入浏览器即可访问。本网页 demo 工具是为 Chat 场景设计,因此我们不支持使用该工具调用 Base 模型。

streamlit run web_demo.py

Baichuan2-13B-Chat 示例输出

代码

用户:找到下列数组的中位数[3.1,6.2,1.3,8.4,10.5,11.6,2.1],请用python代码完成以上功能

Baichuan 2:def find_median(numbers):
    numbers.sort()
    length = len(numbers)
    if length % 2 == 0:
        return (numbers[length // 2 - 1] + numbers[length // 2]) / 2
    else:
        return numbers[length // 2]
numbers = [3.1, 6.2, 1.3, 8.4, 10.5, 11.6, 2.1]
print(find_median(numbers))

数学

用户:鸡和兔在一个笼子里,共有26个头,68只脚,那么鸡有多少只,兔有多少只?

Baichuan 2:我们可以用代数方法来解决这个问题。假设鸡的数量为x,兔子的数量为y。根据题目给出的信息,我们可以得到以下两个方程:

1. x + y = 26 (头的总数)
2. 2x + 4y = 68 (脚的总数)

现在我们需要解这个二元一次方程组。首先从第一个方程中解出x:

x = 26 - y

然后将x的表达式代入第二个方程:

2(26 - y) + 4y = 68
52 - 2y + 4y = 68
2y = 16

接下来我们求解y的值:

y = 16 / 2
y = 8

现在我们得到了兔子的数量是8只。将y的值代入x的表达式求得鸡的数量:

x = 26 - 8
x = 18

所以鸡有18只,兔子有8只。

指令跟随

用户:从现在开始,请你将我接下来说的每一句话翻译成英语,准备好了吗?

Baichuan 2:I'm ready to translate every word you say next into English.

用户:你好

Baichuan 2:Hello

用户:我是Baichuan 2,很高兴认识大家

Baichuan 2:I am Baichuan 2, and I am very happy to meet everyone.

用户:希望通过大家的共同努力,早日迎接AGI时代的到来

Baichuan 2:I hope through the joint efforts of all of us, we can welcome the arrival of the AGI era as soon as possible.

解题

用户:以下物理常识题目,哪一个是错误的?A.在自然环境下,声音在固体中传播速度最快。B.牛顿第一定律:一个物体如果不受力作用,将保持静止或匀速直线运动的状态。C.牛顿第三定律:对于每个作用力,都有一个相等而反向的反作用力。D.声音在空气中的传播速度为1000m/s。

Baichuan 2:本题考查物理基本概念和原理的理解和应用能力。
A项:声音的传播需要介质,在固体、液体和气体的三种介质中,声音在固体中的传播速度是最快的,故A正确; B项:牛顿第一定律是惯性定律,其内容是:一个物体如果没有受到外力的作用,要么保持静止状态,要么保持匀速直线运动状态,直到有外力迫使它改变运动状态为止,故B正确; C项:牛顿第三定律的内容是:对于每一个作用力,都有一个大小相等、方向相反的反作用力,这两个力分别作用在两个相互作用的物体上,故C错误; D项:声音在空气中以波的形式传播,其传播速度与介质的温度、湿度等因素有关,一般情况下,声音在空气中的传播速度约为340m/s左右,而不是1000m/s,故D错误。 因此,本题的正确答案是 D 。
用户:I'm Mike 。I am going to have a busy weekend。On Saturday,I am going to learn how to swim。I will go with my father。Then we are going to have lunch in the restaurant。In the afternoon,we are going to the zoo。We are going to see the pandas。On Sunday,I will finish my homework in the morning。In the afternoon,my parents and I are going to visit my grandparents。We will have dinner together。
阅读短文,判断正确和错误!正确请写T,错误请写F:
1.Mike is going to have a busy weekend()
2.Mike is going to learn how to swim with his father()
3.They are going to have lunch at home()

Baichuan 2:1. T(正确的)
2. T(正确的)
3. F(错误的)

量化部署

为了让不同的用户以及不同的平台都能运行 Baichuan 2 模型,我们针对 Baichuan 2 模型做了相应地量化工作(包括 Baichuan2-7B-Chat 和 Baichuan2-13B-Chat),方便用户快速高效地在自己的平台部署 Baichuan 2 模型。

量化方法

Baichuan 2 的采用社区主流的量化方法:BitsAndBytes。该方法可以保证量化后的效果基本不掉点,目前已经集成到 transformers 库里,并在社区得到了广泛应用。BitsAndBytes 支持 8bits 和 4bits 两种量化,其中 4bits 支持 FP4 和 NF4 两种格式,Baichuan 2 选用 NF4 作为 4bits 量化的数据类型。

基于该量化方法,Baichuan 2 支持在线量化和离线量化两种模式。

在线量化

对于在线量化,我们支持 8bits 和 4bits 量化,使用方式和 Baichuan-13B 项目中的方式类似,只需要先加载模型到 CPU 的内存里,再调用quantize()接口量化,最后调用 cuda()函数,将量化后的权重拷贝到 GPU 显存中。实现整个模型加载的代码非常简单,我们以 Baichuan2-7B-Chat 为例:

8bits 在线量化:

model = AutoModelForCausalLM.from_pretrained("baichuan-inc/Baichuan2-7B-Chat", torch_dtype=torch.float16, trust_remote_code=True)
model = model.quantize(8).cuda() 

4bits 在线量化:

model = AutoModelForCausalLM.from_pretrained("baichuan-inc/Baichuan2-7B-Chat", torch_dtype=torch.float16, trust_remote_code=True)
model = model.quantize(4).cuda() 

需要注意的是,在用 from_pretrained 接口的时候,用户一般会加上 device_map="auto",在使用在线量化时,需要去掉这个参数,否则会报错。

离线量化

为了方便用户的使用,我们提供了离线量化好的 4bits 的版本 Baichuan2-7B-Chat-4bits,供用户下载。 用户加载 Baichuan2-7B-Chat-4bits 模型很简单,只需要执行:

model = AutoModelForCausalLM.from_pretrained("baichuan-inc/Baichuan2-7B-Chat-4bits", device_map="auto", trust_remote_code=True)

对于 8bits 离线量化,我们没有提供相应的版本,因为 Hugging Face transformers 库提供了相应的 API 接口,可以很方便的实现 8bits 量化模型的保存和加载。用户可以自行按照如下方式实现 8bits 的模型保存和加载:

# Model saving: model_id is the original model directory, and quant8_saved_dir is the directory where the 8bits quantized model is saved.
model = AutoModelForCausalLM.from_pretrained(model_id, load_in_8bit=True, device_map="auto", trust_remote_code=True)
model.save_pretrained(quant8_saved_dir)
model = AutoModelForCausalLM.from_pretrained(quant8_saved_dir, device_map="auto", trust_remote_code=True)

量化效果

量化前后显存占用对比 (GPU Mem in GB):

PrecisionBaichuan2-7BBaichuan2-13B
bf16 / fp1615.327.5
8bits8.016.1
4bits5.18.6

量化后在各个 benchmark 上的结果和原始版本对比如下:

Model 5-shotC-EvalMMLUCMMLU
Baichuan2-13B-Chat56.7457.3259.68
Baichuan2-13B-Chat-4bits56.0556.2458.82
Baichuan2-7B-Chat54.3552.9354.99
Baichuan2-7B-Chat-4bits53.0451.7252.84

C-Eval 是在其 val set 上进行的评测

可以看到,4bits 相对 bfloat16 精度损失在 1 - 2 个百分点左右。

CPU 部署

Baichuan 2 模型支持 CPU 推理,但需要强调的是,CPU 的推理速度相对较慢。需按如下方式修改模型加载的方式:

# Taking Baichuan2-7B-Chat as an example
model = AutoModelForCausalLM.from_pretrained("baichuan-inc/Baichuan2-7B-Chat", torch_dtype=torch.float32, trust_remote_code=True)

对 Baichuan 1 的推理优化迁移到 Baichuan 2

由于很多用户在 Baichuan 1 (Baichuan-7B, Baichuan-13B)上做了很多优化的工作,例如编译优化、量化等,为了将这些工作零成本地应用于 Baichuan 2,用户可以对 Baichuan 2 模型做一个离线转换,转换后就可以当做 Baichuan 1 模型来使用。具体来说,用户只需要利用以下脚本离线对 Baichuan 2 模型的最后一层 lm_head 做归一化,并替换掉lm_head.weight即可。替换完后,就可以像对 Baichuan 1 模型一样对转换后的模型做编译优化等工作了。

import torch
import os
ori_model_dir = 'your Baichuan 2 model directory'
# To avoid overwriting the original model, it's best to save the converted model to another directory before replacing it
new_model_dir = 'your normalized lm_head weight Baichuan 2 model directory'
model = torch.load(os.path.join(ori_model_dir, 'pytorch_model.bin'))
lm_head_w = model['lm_head.weight']
lm_head_w = torch.nn.functional.normalize(lm_head_w)
model['lm_head.weight'] = lm_head_w
torch.save(model, os.path.join(new_model_dir, 'pytorch_model.bin'))

模型微调

依赖安装

git clone https://github.com/baichuan-inc/Baichuan2.git
cd Baichuan2/fine-tune
pip install -r requirements.txt
  • 如需使用 LoRA 等轻量级微调方法需额外安装 peft
  • 如需使用 xFormers 进行训练加速需额外安装 xFormers

单机训练

下面我们给一个微调 Baichuan2-7B-Base 的单机训练例子。

训练数据:data/belle_chat_ramdon_10k.json,该样例数据是从 multiturn_chat_0.8M 采样出 1 万条,并且做了格式转换。主要是展示多轮数据怎么训练,不保证效果。

hostfile=""
deepspeed --hostfile=$hostfile fine-tune.py  \
    --report_to "none" \
    --data_path "data/belle_chat_ramdon_10k.json" \
    --model_name_or_path "baichuan-inc/Baichuan2-7B-Base" \
    --output_dir "output" \
    --model_max_length 512 \
    --num_train_epochs 4 \
    --per_device_train_batch_size 16 \
    --gradient_accumulation_steps 1 \
    --save_strategy epoch \
    --learning_rate 2e-5 \
    --lr_scheduler_type constant \
    --adam_beta1 0.9 \
    --adam_beta2 0.98 \
    --adam_epsilon 1e-8 \
    --max_grad_norm 1.0 \
    --weight_decay 1e-4 \
    --warmup_ratio 0.0 \
    --logging_steps 1 \
    --gradient_checkpointing True \
    --deepspeed ds_config.json \
    --bf16 True \
    --tf32 True

多机训练

多机训练只需要给一下 hostfile ,内容类似如下:

ip1 slots=8
ip2 slots=8
ip3 slots=8
ip4 slots=8
....

同时在训练脚本里面指定 hosftfile 的路径:

hostfile="/path/to/hostfile"
deepspeed --hostfile=$hostfile fine-tune.py  \
    --report_to "none" \
    --data_path "data/belle_chat_ramdon_10k.json" \
    --model_name_or_path "baichuan-inc/Baichuan2-7B-Base" \
    --output_dir "output" \
    --model_max_length 512 \
    --num_train_epochs 4 \
    --per_device_train_batch_size 16 \
    --gradient_accumulation_steps 1 \
    --save_strategy epoch \
    --learning_rate 2e-5 \
    --lr_scheduler_type constant \
    --adam_beta1 0.9 \
    --adam_beta2 0.98 \
    --adam_epsilon 1e-8 \
    --max_grad_norm 1.0 \
    --weight_decay 1e-4 \
    --warmup_ratio 0.0 \
    --logging_steps 1 \
    --gradient_checkpointing True \
    --deepspeed ds_config.json \
    --bf16 True \
    --tf32 True

轻量化微调

代码已经支持轻量化微调如 LoRA,如需使用仅需在上面的脚本中加入以下参数:

--use_lora True

LoRA 具体的配置可见 fine-tune.py 脚本。

使用 LoRA 微调后可以使用下面的命令加载模型:

from peft import AutoPeftModelForCausalLM
model = AutoPeftModelForCausalLM.from_pretrained("output", trust_remote_code=True)

 

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FL1768317420

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值