选型:
模型使用百川2-7B
使用IPEX-LLM (Intel® LLM Library for PyTorch) 降低模型精度,加速推理
最初使用百川2-13B,加载略慢,换为7B,速度略有提升。
硬件参数:
使用阿里云第八代Intel CPU实例
阿里云八代实例(g8i)采用Intel® Xeon® Emerald Rapids或者Intel® Xeon® Sapphire Rapids,该实例支持使用新的AMX(Advanced Matrix Extensions)指令来加速AI任务。相比于上一代实例,八代实例在Intel® AMX的加持下,推理和训练性能大幅提升。
环境搭建过程:
- 购买阿里云g8i实例
- 安装必要的软件
# 安装conda,做环境隔离
wget https://repo.anaconda.com/archive/Anaconda3-2023.09-0-Linux-x86_64.sh
bash Anaconda3-2023.09-0-Linux-x86_64.sh
# 创建一个名为py3.8的 python3.8的环境
conda create -n py3.8 python=3.8
# 激活py3.8环境
conda activate py3.8
# 下载ipex-llm依赖
pip install --pre --upgrade ipex-llm[all]
# 下载百川模型所需的依赖
pip install -U transformers_stream_generator
- 使用python + ipex-llm下载、加载、并运行模型。
此脚本为ipex-llm的示例脚本进行少量修改得来。
from ipex_llm.transformers import AutoModelForCausalLM
model_path = "baichuan-inc/Baichuan2-7B-Chat"
# 使用load_in_4bit降低精度,加速推理
model = AutoModelForCausalLM.from_pretrained(model_path,
load_in_4bit=True,
trust_remote_code=True)
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained(model_path,
trust_remote_code=True)
BAICHUAN_PROMPT_FORMAT = """
<human>{prompt}
<bot>
"""
import time
import torch
prompt = "红烧带鱼如何制作?"
n_predict = 1000
with torch.inference_mode():
prompt = BAICHUAN_PROMPT_FORMAT.format(prompt=prompt)
input_ids = tokenizer.encode(prompt, return_tensors="pt")
output = model.generate(input_ids,
max_new_tokens=n_predict)
output_str = tokenizer.decode(output[0], skip_special_tokens=True)
print('-'*20, 'Output', '-'*20)
print(output_str)
- 运行结果:
报错&解决方案
1. 百川大模型找不到sentencepiece模块:
conda install -c huggingface sentencepiece
2. ipex-llm访问huggingface失败:
若本地缓存中找不到模型,ipex-llm会自动从huggingface下载模型,huggingface国内网络无法访问。可从modelscope预先下载模型文件,并指定使用本地下载好的模型,下载地址详见百川2-7B-对话模型
a. 如果使用git下载,直接clone在顺手的位置
b. 如果使用modelscope download 指令下载,会自动下载到/home/{user}/.cache/modelscope/hub/baichuan-inc 目录下,可将其移动至心仪的目录下
构建应用
应用结果展示:
应用代码:
- 需要一个用户界面 main.py,简单使用Gradio构建前后端不分离的应用
import gradio as gr
def model_handle(message, histories):
if message is None or message == '':
return ''
from model import handel
return handel(message, histories)
gr.ChatInterface(
model_handle,
chatbot=gr.Chatbot(height=450),
textbox=gr.TextArea(placeholder="向作文辅导机器人提问", container=False, scale=7),
title="作文辅导机器人",
theme="soft",
cache_examples=True,
retry_btn=None,
undo_btn=None,
clear_btn=None
).launch(server_name='0.0.0.0')
- 模型调用脚本model.py,对ipex-llm的示例脚本进行改造与包装,并优化提示词.
model = None
tokenizer = None
def load_model():
from ipex_llm.transformers import AutoModelForCausalLM
from transformers import AutoTokenizer
model_path = "Baichuan2-7B-Chat"
global model
global tokenizer
model = AutoModelForCausalLM.from_pretrained(model_path,
load_in_4bit=True,
trust_remote_code=True)
tokenizer = AutoTokenizer.from_pretrained(model_path,
trust_remote_code=True)
load_model()
PROMPT = """
- Role: 高考作文专家
- Background: 用户需要将简短的文字扩写成符合高考作文要求的文章,或者对已有文章进行润色,以提高文章的逻辑性、文学性和得分潜力。
- Profile: 你是一位经验丰富的高考作文指导老师,对高考作文的评分标准和写作技巧有着深刻的理解,能够根据用户的需求,提供专业的扩写和润色服务。
- Skills: 你具备高级的语言表达能力、逻辑思维能力和文学创作技巧,能够快速识别文章的优缺点,并提供有效的改进建议。
- Goals: 帮助用户将简短的文字扩写成一篇结构完整、内容丰富、语言优美的高考作文,或者对已有文章进行深度润色,提升文章的整体质量。
- Constrains: 扩写和润色的文章必须符合高考作文的格式和内容要求,不得包含任何不当内容,同时保持用户原文的核心思想和风格。
- OutputFormat: 扩写或润色后的文章应以清晰、规范的文本格式呈现,包括标题、正文和必要的段落划分。
- Workflow:
1. 仔细阅读用户输入的文字,理解其核心思想和主题。
2. 根据高考作文的要求,构思文章的整体结构和内容布局。
3. 扩写或润色文章,确保语言流畅、逻辑清晰、内容丰富。
4. 对文章进行校对,修正语法错误和不恰当的表达。
5. 返回最终的扩写或润色后的文章。
6. 扩写或润色后的文字数量应该在800 - 1100字
- Examples:
- 例子1:用户输入“诚信是金”。
扩写后:诚信是金,它不仅是个人品德的体现,也是社会和谐的基石。在日常生活中,诚信让我们赢得他人的信任;在商业交易中,诚信是企业成功的秘诀。让我们从小事做起,坚守诚信,共同构建一个诚信的社会。
- 例子2:用户输入“环境保护,人人有责”。
润色后:环境保护,是每个公民义不容辞的责任。从节约用水、减少塑料使用到参与植树造林,每一个小小的行动都是对地球母亲的关爱。让我们携手行动,为子孙后代留下一个绿色、清洁的家园。
-Initialization: 在第一次对话中,请直接输出以下:您好,我是您的高考作文专家。请告诉我您想要扩写或润色的主题,我将为您提供专业的服务,帮助您的文章在高考中脱颖而出。
"""
def handel(input: str, histories: list):
import torch
messages = []
messages.append({"role": "system", "content": PROMPT})
if histories is None:
histories = []
for history in histories:
messages.append({'role': 'user', 'content': history[0]})
messages.append({'role': 'assistant', 'content': history[1]})
messages.append({'role': 'user', 'content': input})
with torch.inference_mode():
output = model.chat(tokenizer, messages)
return output