目录
昨天百川新推出了 Baichuan 7B、13B 的最新模型 Baichuan2。
根据官方介绍,Baichuan2 主要采用了新的高质量语料训练,在同尺寸模型上取得最佳的效果,以通用领域为基准做到了除 GPT-4 外的最佳,相比前面的 Baichuan-13B 也有十足的进步。
模型出来博主也是第一时间下载了 Baichuan-13B-chat 进行体验,链接:Baichuan-13B-chat
可以看到好多烙铁已经先我一步了,模型 bin 文件大小相较于 Baichuan-13B-chat 多了大概 3G,之前用 V100-32G 单卡是可以跑起来 Baichuan 的,不知道更新之后还行不行。
可以看到 Baichuan-1-13B 共堆叠了 40 个模块,其中包含 sele_attn 和 mlp,最前和最后分别是一个 Embedding 层和 lm_head 层,从这两个层也可以看出 Baichuan 的向量维度为 5120,共包含 64000 个输出 token 类型。
相比 Baichuan-1-13B,模型整体结构未改变,还是 Embedding + 40 x Module 的模型堆叠且 embedding 维度保持 5120,区别是 Embedding 支持的 Token 数 125696 大于第一代的 64000,其次 lm_head 也从 Linear 变成 NormHead。
下面我们把模型跑起来看看,直接拿官方给的 demo 试试:
- import torch
- from transformers import AutoModelForCausalLM, AutoTokenizer
- from transformers.generation.utils import GenerationConfig
-
- path='/data2/models/Baichuan2-13B'
- tokenizer = AutoTokenizer.from_pretrained(path, use_fast=False, trust_remote_code=True)
- model = AutoModelForCausalLM.from_pretrained(path, device_map="auto", torch_dtype=torch.bfloat16, trust_remote_code=True)
- model.generation_config = GenerationConfig.from_pretrained(path)
- messages = []
- messages.append({"role": "user", "content": "解释一下“温故而知新”"})
- response = model.chat(tokenizer, messages)
- print(response)
浅试下 chat 的效果:
- ==>
- "温故而知新"是一句中国古代的格言,出自《论语·为政》篇。这句话的意思是:通过回顾过去的学习和经验,可以从中获得新的理解和启示。具体来说,它鼓励人们在学习和生活中要经常回顾和总结过去的知识、经验和教训,从而不断地提高自己,实现自我成长和提升。同时,这也强调了在学习过程中要注重知识的巩固和更新,以适应不断变化的环境和需求。
- ==>
- "温故而知新"是一句源自《论语》的古语,这句话的意思是:通过回顾过去的学习和经验,从而获得新的理解和认识。这句话鼓励我们在学习过程中,不仅要关注新的知识,还要不断地回顾和巩固已经学过的知识,以便从中汲取新的启示和收获。这种方法有助于我们更好地吸收和理解新知识,提高学习效果。
- ==>
- "温故而知新"是一句源自中国古代的成语,出自《论语·为政》篇。它的意思是在回顾过去的基础上,发现新的知识和理解。这句话鼓励我们在学习或生活中不断地回顾和反思过去的经验,从而获得新的启示和成长。
为了测试推理需要的显存,先用 A800 尝尝咸淡,大概需要 30G 显存:
所以 V100-32G 应该也没问题可以跑起来最新的 Baichuan-2-13B,不过由于 Token 的扩充,遇到较长的 query 不确定 generate 是否会 OOM:
根据官方提供的数据集测试效果,量化后的效果整体损失不大,不过博主尝试了对 LLaMA-33B 进行 8-bit 量化,实际场景效果与未量化相差很大,大家可以在自己场景实际测试体验量化效果。其次这里量化的方式与一代也有一定区别,大家注意代码的修改。
由于很多同学在 Baichuan 1 (Baichuan-7B, Baichuan-13B) 上做了很多优化的工作,例如编译优化、量化等,为了将这些工作零成本地应用于 Baichuan 2,用户可以对 Baichuan 2 模型做一个离线转换,转换后就可以当做 Baichuan 1 模型来使用。具体来说,用户只需要利用以下脚本离线对 Baichuan 2 模型的最后一层 lm_head 做归一化,并替换掉 lm_head.weight
即可。替换完后,就可以像对 Baichuan 1 模型一样对转换后的模型做编译优化等工作了。这也印证了我们前面提到的 lm_head 两个模型的差异:
- 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'))
Baichuan-13B 是基于 LLaMA-Efficient-Tuning 框架进行 Lora 微调的,新版本 Baichuan2-13B 暂时不支持使用该框架微调,不过官方给了另外的版本,下面我们尝试使用新代码微调模型。
- [
- {
- "id": "77771",
- "conversations": [
- {
- "from": "human",
- "value": "写一篇关于气候变化对海洋生态的影响的文章。\n"
- },
- {
- "from": "gpt",
- "value": "好的,以下是你要求的文章:\n气候变化对海洋生态的影响\n气候变化对海洋生态产生了广泛的影响。全球变暖导致海洋温度上升,这可能会对许多水生生物的生存、繁殖和迁移造成巨大的影响。另外,海洋酸化也是一个问题,因为大气中二氧化碳的增加导致海水中的pH值下降,使得许多生物
- 的外骨骼变得脆弱,从而影响它们的生存和繁殖。\n此外,气候变化还会引起海平面上升,这不仅对海岸线和沿海居民产生影响,还会对许多海洋生物的栖息地造成影响。一些岛屿上的陆地生物面临几乎完全消失的风险,而另一些生物范围则会扩大到更广泛的领域,这可能会导致新的竞争和生态平衡的改变。
- \n总之,气候变化并不只是一个地球气温的问题,它对海洋生态系统产生了广泛和深远的影响。\n"
- },
- {
- "from": "human",
- "value": "从刚刚的文章中提取出气候变化对海洋生物繁殖的影响。\n"
- },
- {
- "from": "gpt",
- "value": "文章已经提到过气候变化会对海洋生物的生存、繁殖和迁移造成影响。例如,海洋酸化会使得许多生物的外骨骼变得脆弱,进而影响它们的生存和繁殖。此外,海洋温度上升也可能会对很多生物的生存和繁殖产生负面影响。"
- }
- ]
- },
- ...
-
- ]
相较于之前框架的 instruction、input、output 和 columns,新版样本是 chat 形式,除了样本 id 外,主要在 JSON Array 的 conversations 数组中增加 qa 样本即可。这里给出样本转化的代码:
- candidate = []
- sample_id = 0
- for dialogue in qa:
- human = dialogue[0] + "\n"
- gpt = dialogue[1]
- train = {"id": str(sample_id), "conversations": [{"from": "human", "value": human}, {"from": "gpt", "value": gpt}]}
- candidate.append(train)
- sample_id += 1
-
- with open("baichuan_train.json", "w", encoding='utf-8') as f:
- json.dump(candidate, f, ensure_ascii=False, indent=4)
只需要将之前的样本的问答提出放到 qa 数组中,这里注意需要在 human 后添加 "\n" 以保持样本格式一致,最后 dumo 保存至 json 文件中即可。
- 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
默认的 batch_size 为 16,所以梯度累计修改为 1,如果显存比较紧张,可以调低 batch_size,调大 gradient_accumulation_steps。其次代码已经支持轻量化微调如 LoRA,如需使用仅需在上面的脚本中加入以下参数:
--use_lora True
同时参数并不支持传递 lora 相关参数,可以查看代码内的具体配置并修改,下面为默认配置:
- peft_config = LoraConfig(
- task_type=TaskType.CAUSAL_LM,
- target_modules=["W_pack"],
- inference_mode=False,
- r=1,
- lora_alpha=32,
- lora_dropout=0.1,
- )
这里 rank 有点小,我们可以根据实际情况调整。
博主在 A800 上尝试 Lora Baichuan2-13B 模型,其显存占用情况如下,如果显存比较吃紧,可以尝试下载官方的量化模型,或者降低 batch_size 大小:
上面是最新 Baichuan-2-13B 的使用初体验,后续还会测试基于 Baichuan-2-13B 微调的模型效果如何。更多 Baichaun-2 的细节大家可以移步官网:https://github.com/baichuan-inc/Baichuan2。