当前位置: 首页 > article >正文

开源模型应用落地-glm模型小试-glm-4-9b-chat-Gradio集成(三)

一、前言

    GLM-4是智谱AI团队于2024年1月16日发布的基座大模型,旨在自动理解和规划用户的复杂指令,并能调用网页浏览器。其功能包括数据分析、图表创建、PPT生成等,支持128K的上下文窗口,使其在长文本处理和精度召回方面表现优异,且在中文对齐能力上超过GPT-4。与之前的GLM系列产品相比,GLM-4在各项性能上提高了60%,并且在指令跟随和多模态功能上有显著强化,适合于多种应用场景。尽管在某些领域仍逊于国际一流模型,GLM-4的中文处理能力使其在国内大模型中占据领先地位。该模型的研发历程自2020年始,经过多次迭代和改进,最终构建出这一高性能的AI系统。

    在开源模型应用落地-glm模型小试-glm-4-9b-chat-快速体验(一)已经掌握了glm-4-9b-chat的基本入门。

    在开源模型应用落地-glm模型小试-glm-4-9b-chat-批量推理(二)已经掌握了glm-4-9b-chat的批量推理。

    本篇将介绍如何集成Gradio进行页面交互。


二、术语

2.1.GLM-4-9B

    是智谱 AI 推出的一个开源预训练模型,属于 GLM-4 系列。它于 2024 年 6 月 6 日发布,专为满足高效能语言理解和生成任务而设计,并支持最高 1M(约两百万字)的上下文输入。该模型拥有更强的基础能力,支持26种语言,并且在多模态能力上首次实现了显著进展。

GLM-4-9B的基础能力包括:

- 中英文综合性能提升 40%,在特别的中文对齐能力、指令遵从和工程代码等任务中显著增强

- 较 Llama 3 8B 的性能提升,尤其在数学问题解决和代码编写等复杂任务中表现优越

- 增强的函数调用能力,提升了 40% 的性能

- 支持多轮对话,还支持网页浏览、代码执行、自定义工具调用等高级功能,能够快速处理大量信息并给出高质量的回答

2.2.GLM-4-9B-Chat

    是智谱 AI 在 GLM-4-9B 系列中推出的对话版本模型。它设计用于处理多轮对话,并具有一些高级功能,使其在自然语言处理任务中更加高效和灵活。

2.3.Gradio

    是一个用于构建交互式界面的Python库。它使得在Python中创建快速原型、构建和共享机器学习模型变得更加容易。

    Gradio的主要功能是为机器学习模型提供一个即时的Web界面,使用户能够与模型进行交互,输入数据并查看结果,而无需编写复杂的前端代码。它提供了一个简单的API,可以将输入和输出绑定到模型的函数或方法,并自动生成用户界面。


三、前置条件

3.1.基础环境及前置条件

     1. 操作系统:centos7

     2. NVIDIA Tesla V100 32GB   CUDA Version: 12.2 

    3.最低硬件要求

3.2.下载模型

huggingface:

https://huggingface.co/THUDM/glm-4-9b-chat/tree/main

ModelScope:

魔搭社区

使用git-lfs方式下载示例:

3.3.创建虚拟环境

conda create --name glm4 python=3.10
conda activate glm4

3.4.安装依赖库

pip install torch>=2.5.0
pip install torchvision>=0.20.0
pip install transformers>=4.46.0
pip install huggingface-hub>=0.25.1
pip install sentencepiece>=0.2.0
pip install jinja2>=3.1.4
pip install pydantic>=2.9.2
pip install timm>=1.0.9
pip install tiktoken>=0.7.0
pip install numpy==1.26.4 
pip install accelerate>=1.0.1
pip install sentence_transformers>=3.1.1
pip install gradio==4.44.1
pip install openai>=1.51.0
pip install einops>=0.8.0
pip install pillow>=10.4.0
pip install sse-starlette>=2.1.3
pip install bitsandbytes>=0.43.3

四、技术实现

4.1.集成Gradio

# -*- coding: utf-8 -*-
from threading import Thread
import gradio as gr
import torch

from transformers import (
    AutoModelForCausalLM,
    AutoTokenizer,
    StoppingCriteria,
    StoppingCriteriaList,
    TextIteratorStreamer
)

modelPath = "/data/model/glm-4-9b-chat"

def loadTokenizer():
    tokenizer = AutoTokenizer.from_pretrained(modelPath, trust_remote_code=True)
    return tokenizer

def loadModel():
    model = AutoModelForCausalLM.from_pretrained(
        modelPath,
        torch_dtype=torch.float16,
        trust_remote_code=True,
        device_map="auto").eval()
    return model

class StopOnTokens(StoppingCriteria):
    def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor, **kwargs) -> bool:
        stop_ids = model.config.eos_token_id
        for stop_id in stop_ids:
            if input_ids[0][-1] == stop_id:
                return True
        return False

def predict(history, prompt, max_length, top_p, temperature):
    stop = StopOnTokens()
    messages = []
    if prompt:
        messages.append({"role": "system", "content": prompt})
    for idx, (user_msg, model_msg) in enumerate(history):
        if prompt and idx == 0:
            continue
        if idx == len(history) - 1 and not model_msg:
            messages.append({"role": "user", "content": user_msg})
            break
        if user_msg:
            messages.append({"role": "user", "content": user_msg})
        if model_msg:
            messages.append({"role": "assistant", "content": model_msg})

    model_inputs = tokenizer.apply_chat_template(messages,
                                                 add_generation_prompt=True,
                                                 tokenize=True,
                                                 return_tensors="pt").to(next(model.parameters()).device)
    streamer = TextIteratorStreamer(tokenizer, timeout=60, skip_prompt=True, skip_special_tokens=True)
    generate_kwargs = {
        "input_ids": model_inputs,
        "streamer": streamer,
        "max_new_tokens": max_length,
        "do_sample": True,
        "top_p": top_p,
        "temperature": temperature,
        "stopping_criteria": StoppingCriteriaList([stop]),
        "repetition_penalty": 1.2,
        "eos_token_id": model.config.eos_token_id,
    }
    t = Thread(target=model.generate, kwargs=generate_kwargs)
    t.start()
    for new_token in streamer:
        if new_token:
            history[-1][1] += new_token
        yield history


with gr.Blocks() as demo:
    gr.HTML("""<h1 align="center">GLM-4-9B-CHAT DEMO</h1>""")
    chatbot = gr.Chatbot()

    with gr.Row():
        with gr.Column(scale=3):
            with gr.Column(scale=12):
                user_input = gr.Textbox(show_label=False, placeholder="Input...", lines=10, container=False)
            with gr.Column(min_width=32, scale=1):
                submitBtn = gr.Button("Submit")
        with gr.Column(scale=1):
            prompt_input = gr.Textbox(show_label=False, placeholder="Prompt", lines=10, container=False)
            pBtn = gr.Button("Set Prompt")
        with gr.Column(scale=1):
            emptyBtn = gr.Button("Clear History")
            max_length = gr.Slider(0, 32768, value=8192, step=1.0, label="Maximum length", interactive=True)
            top_p = gr.Slider(0, 1, value=0.8, step=0.01, label="Top P", interactive=True)
            temperature = gr.Slider(0.01, 1, value=0.6, step=0.01, label="Temperature", interactive=True)


    def user(query, history):
        return "", history + [[query, ""]]


    def set_prompt(prompt_text):
        return [[prompt_text, "成功设置prompt"]]


    pBtn.click(set_prompt, inputs=[prompt_input], outputs=chatbot)

    submitBtn.click(user, [user_input, chatbot], [user_input, chatbot], queue=False).then(
        predict, [chatbot, prompt_input, max_length, top_p, temperature], chatbot
    )
    emptyBtn.click(lambda: (None, None), None, [chatbot, prompt_input], queue=False)

if __name__ == '__main__':
    model = loadModel()
    tokenizer = loadTokenizer()
    
    demo.queue()
    demo.launch(server_name="0.0.0.0", server_port=7860, auth=("zhangsan", '123456'), width='70%')

启动结果:

调用结果:

一. 访问页面,账/密为上述代码示例中的zhangsan/123456

二.测试推理效果


五、附带说明

5.1.问题一: undefined symbol: __nvJitLinkComplete_12_4, version libnvJitLink.so.12

解决:

export LD_LIBRARY_PATH=/usr/local/miniconda3/envs/glm4/lib/python3.10/site-packages/nvidia/nvjitlink/lib:$LD_LIBRARY_PATH

5.2.问题二:Gradio界面无法打开

 1. 服务监听地址不能是127.0.0.1

2. 检查服务器的安全策略或防火墙配置

 服务端:lsof -i:8989 查看端口是否正常监听

 客户端:telnet ip 8989 查看是否可以正常连接


http://www.kler.cn/a/385844.html

相关文章:

  • 英伟达基于Mistral 7B开发新一代Embedding模型——NV-Embed-v2
  • 从电动汽车到车载充电器:LM317LBDR2G 线性稳压器在汽车中的多场景应用
  • 算法魅力-二分查找实战
  • unity小:shaderGraph不规则涟漪、波纹效果
  • 基于VUE实现语音通话:边录边转发送语言消息、 播放pcm 音频
  • nacos-operator在k8s集群上部署nacos-server2.4.3版本踩坑实录
  • 什么是jQuery
  • 光耦合器在现代电子学中的关键应用
  • H5播放器EasyPlayer.js 流媒体播放器是否支持npm(yarn) install 安装?
  • 设置agetty启动参数登录Linux
  • 大模型自动构建知识图谱/GraphRAG/neo4j可视化/问答系统探索
  • HTB:Perfection[WriteUP]
  • 【Ant Design Pro】框架入门的起手式及架构的分析
  • MongoDB 基础与应用
  • 如何管理PHP的API部署环境
  • iPhone 17版本的开发者权限如何开启?
  • Oracle 第29章:Oracle数据库未来展望
  • 15分钟学 Go 第 43 天:前端与Go的结合
  • qt QClipboard详解
  • # 使用VMwarWorkstation虚拟机安装Ubuntu系统
  • Obsidian之与Typora图片格式相互兼容
  • 【缓存与加速技术实践】Web缓存代理与CDN内容分发网络
  • 图像分割1
  • FTP替代方案:FileLink内外网文件摆渡,助力企业安全高效文件传输
  • 【Hadoop实训】Flume系统负载均衡测试
  • Java项目实战II基于Spring Boot的高校教师电子名片系统的设计与实现(开发文档+数据库+源码)