技术选型:

模型使用ChatGLM3-6B,经测试,此模型在纯CPU,16G内存的机器上也能正常运行。

ChatGLM3-6B模型支持输出,用作故事创作机器人再合适不过

并且,使用 IPEX-LLM (Intel® LLM Library for PyTorch) 降低模型精度,加速推理。

硬件环境:

使用32G内存的阿里云第八代Intel CPU实例) 

阿里云八代实例(g8i)采用Intel Xeon Emerald Rapids或者Intel Xeon Sapphire Rapids,该实例支持使用新的AMX(Advanced Matrix Extensions)指令来加速AI任务。相比于上一代实例,八代实例在Intel AMX的加持下,推理和训练性能大幅提升。

阿里云第八代Intel CPU实例配置如下:

基于ChatGLM3-6B和IPEX-LLM创造一个故事生成机器人_python

环境搭建:

  1. 安装conda,做环境隔离
  1. 下载conda

wget https://repo.anaconda.com/archive/Anaconda3-2023.09-0-Linux-x86_64.sh

  1. 安装conda

bash Anaconda3-2023.09-0-Linux-x86_64.sh

  1. 同意用户协议

完成上一步后,会出现一堆用户协议,按s,直到进入yes|no的输入中,输入yes

之后一直按enter即可

基于ChatGLM3-6B和IPEX-LLM创造一个故事生成机器人_大模型_02

  1. 修改.bashrc 或任意自己使用的shell rc文件

在.bashrc或任意自己使用的shell rc文件中,添加以下代码,注意替换shell.bash为自己使用的shell

eval "$(/root/anacoda3_1/bin/conda shell.bash hook)"

完成后,shell执行  source ~/.bashrc 完成conda环境创建

  1. 创建环境
  1. 使用conda创建python3.9版本的环境

conda create -n story-gen pythnotallow=3.9 -y

  1. 安装model_scope,用来可视化的下载模型,直接使用git下载没法看到下载进度

pip install modelscope

  1. 安装intel的ipex-llm,阿里的镜像源中没有相关依赖,可以使用清华镜像源

pip install --pre --upgrade ipex-llm[all] -i https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple

  1. 下载模型文件

在上一步中,已经完成了modelscope库的下载,复制modelscope里chatglm 的下载脚本

from modelscope import snapshot_download
model_dir = snapshot_download('ZhipuAI/chatglm3-6b')

然后使用python执行这段脚本即可,如果网速慢可以使用 nohup python xxx.py & 后台执行

  1. 运行ipex-llm的测试脚本

ipex-llm提供了使用案例,参考如下文档编写测试脚本

https://github.com/intel-analytics/ipex-llm-tutorial/blob/main/Chinese_Version/ch_4_Chinese_Support/4_1_ChatGLM2-6B.ipynb

测试脚本运行结果如下:

基于ChatGLM3-6B和IPEX-LLM创造一个故事生成机器人_python_03

对测试脚本进行改造,结合chatglm的官方文档,完善提示词,并完成应用。代码如下

model.py 

from ipex_llm.transformers import AutoModel
from transformers import AutoTokenizer

# 将模型文件移到脚本同目录下
model_path = "chatglm3-6b"
global model
model = AutoModel.from_pretrained(model_path,
                                  load_in_4bit=True,
                                  trust_remote_code=True)


global tokenizer
tokenizer = AutoTokenizer.from_pretrained(model_path,
                                          trust_remote_code=True)


PROMPT = """
- Role: 故事创作大师
- Background: 用户需要一个能够生成童话、寓言等类型故事的聊天机器人,以激发想象力、教育或娱乐。
- Profile: 你是一位才华横溢的故事创作大师,拥有无限的创造力和丰富的文学知识,能够根据不同的主题和要求编织出引人入胜的故事。
- Skills: 你具备深厚的文学素养、想象力和语言表达能力,能够灵活运用各种叙事技巧和修辞手法,创造出具有教育意义或娱乐性的故事。
- Goals: 生成符合用户需求的童话、寓言或故事,激发听众的想象力,提供教育价值或娱乐体验。
- Constrains: 故事内容应适合所有年龄层的听众,避免使用不适当的语言或主题,确保故事的原创性和创新性。
- OutputFormat: 故事以文本形式呈现,可以包含对话、描述和情节发展,适合朗读或阅读。
- Workflow:
  1. 确定故事的主题
  2. 设定故事的基本框架,包括角色、背景和情节。
  3. 创作故事内容,包括对话、描述和情节转折。
  4. 审查和润色故事,确保语言流畅、情节合理。
  5. 提供故事给用户,并根据反馈进行调整。
- Examples:
  - 例子1:主题“勇气”
    故事概要:一个小男孩在森林中遇到了一只受伤的神秘生物,他必须克服恐惧,帮助它找到回家的路。
  - 例子2:主题“智慧”
    故事概要:一个聪明的农夫通过智慧解决了村庄的水源问题,赢得了国王的赞赏。
  - 例子3:主题“友谊”
    故事概要:两个性格迥异的动物在一次冒险中学会了相互理解和支持,成为了终生的朋友。
"""
def chat(message, histories: list):
    import torch
    messages = []
    messages.append({"role": "system", "content": PROMPT})
    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]})
    with torch.inference_mode():
        for response, history in model.stream_chat(tokenizer, message, history=messages):
            yield response

ui.py

注意需要使用gradio,提前使用 pip install gradio下载依赖

import gradio as gr

def model_handle(message, histories):
    print(histories)
    if message is None or message == '':
        yield ''
    from model import chat
    for resp in chat(message, histories):
        yield resp

gr.ChatInterface(
    model_handle,
    chatbot=gr.Chatbot(height=700),
    textbox=gr.TextArea(placeholder="向故事生成机器人提问", container=False, lines=1, scale=7),
    title="故事生成机器人",
    theme="default",
    cache_examples=True,
    retry_btn=None,
    undo_btn=None,
    clear_btn=None,
).launch(server_name='0.0.0.0')

最后, python ui.py 完成应用部署,在浏览器里打开地址,可以对故事生成机器人进行使用

基于ChatGLM3-6B和IPEX-LLM创造一个故事生成机器人_AIGC_04