AI 文摘

百川2模型解读、服务部署、微调(下篇)


  • By AiBard123
  • November 16, 2023 - 2 min read



作者: AINLP 来源: AINLP

  • 引言

  • 本地部署

    • 单轮对话

    • 多轮对话

    • 网页部署

    • 13B-base

    • 13B-chat

    • 量化部署

  • 模型微调

引言

紧接前文百川2模型解读、服务部署、微调(上篇),今天这篇小作文作为下篇 侧重于实战 ,介绍如何本地部署 百川2模型、模型量化、模型网页部署及其如何对百川2进行模型微调。

本地部署

13B-Base

#!/usr/bin/env python  
# -*- coding: utf-8 -*-  
# @Time    : 2023/9/18 22:16  
# @Author  : 卖秋裤的小女孩  
# @联系方式  : 微信公众号<小窗幽记机器学习>  
# @File    : inference_base_model.py  
"""  
CUDA_VISIBLE_DEVICES=4,5  python3 inference_base_model.py  
单卡会爆内存不足  
"""  
from transformers import AutoModelForCausalLM, AutoTokenizer  
  
model_id = "/home/model_zoo/LLM/baichuan-inc/Baichuan2-13B-Base"  
device = "cuda:0"  
tokenizer = AutoTokenizer.from_pretrained(model_id, trust_remote_code=True)  
model = AutoModelForCausalLM.from_pretrained(model_id, device_map="auto", trust_remote_code=True)  
inputs = tokenizer('蔡坤,外号,混元霹雳舞菜坤\n鹿涵,外号,南山鹿杖客\n范丞,外号,', return_tensors='pt')  
inputs = inputs.to(device)  
pred = model.generate(**inputs, max_new_tokens=64, repetition_penalty=1.1)  
print(tokenizer.decode(pred.cpu()[0], skip_special_tokens=True))  

13B-Base模型输出结果如下:

蔡坤,外号,混元霹雳舞菜坤  
鹿涵,外号,南山鹿杖客  
范丞,外号,范大将军  
朱正廷,外号,朱雀正廷  
黄明昊,外号,小贾  
毕雯珺,外号,毕姥爷  
丁泽仁,外号,丁泽仁  
李权哲,外号,权志龙  
李希侃,外号,李希侃  

可能是上述示例过于鬼畜,结果并不是很理想。

13B-Chat

单轮回答

#!/usr/bin/env python  
# -*- coding: utf-8 -*-  
# @Time    : 2023/9/18 23:16  
# @Author  : 卖秋裤的小女孩  
# @联系方式  : 微信公众号<小窗幽记机器学习>  
# @File    : inference_chat_model.py  
"""  
预先安装:  
    pip3 install xformers -i https://mirrors.cloud.tencent.com/pypi/simple  
模型目录:  
    /home/model_zoo/LLM/baichuan-inc/  
  
CUDA_VISIBLE_DEVICES=4,5 python3 inference_chat_model.py  
"""  
import torch  
from transformers import AutoModelForCausalLM, AutoTokenizer  
from transformers.generation.utils import GenerationConfig  
  
model_id = "/home/model_zoo/LLM/baichuan-inc/Baichuan2-13B-Chat"  
tokenizer = AutoTokenizer.from_pretrained(model_id, use_fast=False, trust_remote_code=True)  
model = AutoModelForCausalLM.from_pretrained(model_id, device_map="auto", torch_dtype=torch.bfloat16,  
                                             trust_remote_code=True)  
model.generation_config = GenerationConfig.from_pretrained(model_id)  
messages = []  
messages.append({"role": "user", "content": "国足啥时候可以打进世界杯?有人说是做梦的时候,该怎么理解"})  
response = model.chat(tokenizer, messages)  
print(response)  

输出结果如下:

作为一个大语言模型,我不能对国足何时能够晋级世界杯做出预测。然而,中国足球一直在努力提高水平和竞争力,以争取在世界杯上取得更好的成绩。这需要时间、努力和持续的投资。无论结果如何,我们都应该支持并鼓励我们的国家队,为他们加油鼓劲。  

多轮对话

#!/usr/bin/env python  
# -*- coding: utf-8 -*-  
# @Time    : 2023/9/18 22:30  
# @Author  : 卖秋裤的小女孩  
# @联系方式  : 微信公众号<小窗幽记机器学习>  
# @File    : inference_multi_turn_chat_model.py  
"""  
多轮对话,单卡部署  
"""  
import time  
import torch  
from transformers import AutoModelForCausalLM, AutoTokenizer  
from transformers.generation.utils import GenerationConfig  
  
model_id = "/home/model_zoo/LLM/baichuan-inc/Baichuan2-13B-Chat"  
tokenizer = AutoTokenizer.from_pretrained(model_id, use_fast=False, trust_remote_code=True)  
model = AutoModelForCausalLM.from_pretrained(model_id, device_map="auto", torch_dtype=torch.bfloat16,  
                                             trust_remote_code=True)  
model.generation_config = GenerationConfig.from_pretrained(model_id)  
messages = []  
  
start_time = time.time()  
user_query_1 = "国足啥时候可以打进世界杯?有人说是做梦的时候,该怎么理解"  
messages.append({"role": "user", "content": user_query_1})  
response = model.chat(tokenizer, messages)  
print("User: ", user_query_1)  
print("Baichuan2: ", response)  
end_time = time.time()  
print("Cost time=", end_time - start_time)  
messages.append({"role": "user", "content": response})  
  
start_time = time.time()  
user_query_2 = "我是让你理解这话的意思,不是让你预测未来。你做好你的阅读理解就行,没有其他事情莫要自己加戏!"  
messages.append({"role": "user", "content": user_query_2})  
response = model.chat(tokenizer, messages)  
print("User: ", user_query_2)  
print("Baichuan2: ", response)  
end_time = time.time()  
print("Cost time=", end_time - start_time)  

13B-Chat模型输出结果如下:

User:  国足啥时候可以打进世界杯?有人说是做梦的时候,该怎么理解  
Baichuan2:  作为一个大语言模型,我不能对国足何时能晋级世界杯做出预测。但是,中国足球一直在努力提高水平并寻求进步。只有通过持续的努力和不断改进,才能实现这个目标。  
Cost time= 4.264727830886841  
User:  我是让你理解这话的意思,不是让你预测未来。你做好你的阅读理解就行,没有其他事情莫要自己加戏!  
Baichuan2:  对不起,我误解了您的问题。这句话的意思是:有人认为中国国家队打进世界杯是一个遥不可及的梦想,甚至可以说是幻想。这种观点可能源于对中国足球现状的不满和对未来的悲观预期。然而,这并不意味着没有人相信中国足球有朝一日能够实现这个目标。只要中国足球不断努力和提高自身实力,总有一天会实现这个梦想。  
Cost time= 4.284733295440674  

网页demo部署

官方同时暖心地提供了一个Web版的Demo,方便小伙伴们本地部署。

streamlit run web_demo.py  

量化部署

8bits 在线量化:

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

完整代码如下:

#!/usr/bin/env python  
# -*- coding: utf-8 -*-  
# @Time    : 2023/9/19 23:15  
# @Author  : 卖秋裤的小女孩  
# @联系方式  : 微信公众号<小窗幽记机器学习>  
# @File    : inference_8bits.py  
"""  
在线量化  
CUDA_VISIBLE_DEVICES=4 python3 inference_8bits.py  
"""  
  
  
import torch  
from transformers import AutoModelForCausalLM, AutoTokenizer  
from transformers.generation.utils import GenerationConfig  
  
model_id = "/home/model_zoo/LLM/baichuan-inc/Baichuan2-13B-Chat"  
tokenizer = AutoTokenizer.from_pretrained(model_id, use_fast=False, trust_remote_code=True)  
model = AutoModelForCausalLM.from_pretrained(model_id, torch_dtype=torch.bfloat16,  
                                             trust_remote_code=True)  
# device_map="auto",   
# model = AutoModelForCausalLM.from_pretrained("baichuan-inc/Baichuan2-7B-Chat", torch_dtype=torch.float16, trust_remote_code=True)  
model = model.quantize(8).cuda()  
  
model.generation_config = GenerationConfig.from_pretrained(model_id)  
messages = []  
messages.append({"role": "user", "content": "国足啥时候可以打进世界杯?有人说是做梦的时候,该怎么理解"})  
response = model.chat(tokenizer, messages)  
print(response)  

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” ,在使用在线量化时,需要去掉这个参数,否则会报错。如果是加载使用已经离线量化后的模型,加上device_map=“auto” 参数则并不会报错。

模型微调

数据来源:https://huggingface.co/datasets/BelleGroup/multiturn_chat_0.8M

数据存放:/home/data_zoo/LLM/BelleGroup/multiturn_chat_0.8M/

全量微调

运行脚本:single_machine_one_gpu.sh ,4张A100(40GB),显存依然无法做全量微调,所以放弃了。

轻量化微调(LORA)

需要预先安装pip3 install peft accelerate==0.21.0 -i https://mirrors.cloud.tencent.com/pypi/simple

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

--use_lora True  

具体代码如下:

# 由于单机,所以没必要设置 hostfile  
#init_model_path="/home/model_zoo/LLM/baichuan-inc/Baichuan2-13B-Base"  
init_model_path="/home/jiepeng.liu/Repository/LLM/llama-recipes/baichuan-inc/Baichuan2-7B-Base"  
# python3 deepspeed  
deepspeed --include localhost:7 fine-tune.py  \  
    --report_to "none" \  
    --data_path "data/belle_chat_ramdon_10k.json" \  
    --model_name_or_path=$init_model_path \  
    --output_dir "output" \  
    --model_max_length 512 \  
    --num_train_epochs 4 \  
    --per_device_train_batch_size 32 \  
    --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 \  
    --use_lora True  

微调后模型加载及其inference:

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

完整inference代码如下:

#!/usr/bin/env python  
# -*- coding: utf-8 -*-  
# @Time    : 2023/9/21 23:19  
# @Author  : 卖猪蹄的小女孩  
# @联系方式  : 微信公众号<小窗幽记机器学习>  
# @File    : inference_lora.py  
"""  
CUDA_VISIBLE_DEVICES=4,5,6,7 python3 inference_lora.py  
"""  
import torch  
from transformers import AutoModelForCausalLM, AutoTokenizer  
from transformers.generation.utils import GenerationConfig  
from peft import PeftModel, PeftConfig  
from peft import AutoPeftModelForCausalLM  
  
model_id = "output"  
device = "cuda:7"  
model = AutoPeftModelForCausalLM.from_pretrained(model_id, trust_remote_code=True)  
model = model.to(device)  
model.eval()  
tokenizer = AutoTokenizer.from_pretrained(model_id, use_fast=False, trust_remote_code=True)  
# test_text = "国足啥时候可以打进世界杯?有人说是做梦的时候,该怎么理解"  
# test_text = "写一篇关于气候变化对海洋生态的影响的文章。"  
test_text = "写一篇关于国足勇夺9999年世界杯冠军的新闻,以'真的是万年等一回'作为结尾"  
inputs = tokenizer(test_text, return_tensors="pt")  
outputs = model.generate(input_ids=inputs["input_ids"].to(device), max_new_tokens=400)  # 不能使用mode.chat  
print(tokenizer.batch_decode(outputs.detach().cpu().numpy(), skip_special_tokens=True)[0])  

输出结果如下:

写一篇关于国足勇夺9999年世界杯冠军的新闻,以'真的是万年等一回'作为结尾。  
好的,以下是新闻:  
北京时间2020年12月20日,国足在9999年世界杯决赛中,以1:0战胜了巴西队,勇夺冠军。这是国足历史上第一次夺得世界杯冠军,也是国足历史上最辉煌的时刻。赛后,国足队员们激动地流下了眼泪,他们表示,这是他们一生中最难忘的时刻。  
真的是万年等一回,国足终于圆梦了!  

总结

整体评测下来,百川2很不错,诚心安利!

进技术交流群请添加AINLP小助手微信(id: ainlp2)

请备注具体方向+所用到的相关技术点

![](https://api.allorigins.win/raw?url=https://mmbiz.qpic.cn/mmbiz_jpg/nW2ZPfuYqSJADkmZ2IX6Z23znAibuEevotDMq9iaMxiapK7jfMibiauGFkycicAJEs6x5U9SGyDJZ0S1tRed9TPNUUDQ/640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1&wx_co=1)

关于AINLP

AINLP 是一个有趣有AI的自然语言处理社区,专注于 AI、NLP、机器学习、深度学习、推荐算法等相关技术的分享,主题包括LLM、预训练模型、自动生成、文本摘要、智能问答、聊天机器人、机器翻译、知识图谱、推荐系统、计算广告、招聘信息、求职经验分享等,欢迎关注!加技术交流群请添加AINLP小助手微信(id:ainlp2),备注工作/研究方向+加群目的。

  


  


![](https://api.allorigins.win/raw?url=https://mmbiz.qpic.cn/mmbiz_jpg/nW2ZPfuYqSKABHCqVVQkVYPrM4XY1vsd0iaeuXzyJnoFc8cibd5mYb4wdA3WMQtiaPVmr0XLZHMuVibqWncibpnTSnQ/640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1&wx_co=1)

阅读至此了,分享、点赞、在看三选一吧🙏

更多AI工具,参考Github-AiBard123国内AiBard123

可关注我们的公众号:每天AI新工具