fastllm icon indicating copy to clipboard operation
fastllm copied to clipboard

chatglm模型转化为flm格式后,推理结果质量暴降(主要表现在总结能力),在其他issue也看到类似的问题

Open ColorfulDick opened this issue 1 year ago • 3 comments

转化脚本如下,模型和lora都可以在huggingface找到:

from transformers import AutoTokenizer, AutoModel
from peft import PeftModel

tokenizer = AutoTokenizer.from_pretrained("./chatglm-fitness-RLHF", trust_remote_code=True)
model = AutoModel.from_pretrained("./chatglm-fitness-RLHF", trust_remote_code=True, device_map='auto')
model = PeftModel.from_pretrained(model, "./Bofan-chatglm-Best-lora")
model = model.half().cuda().eval()

# 加入下面这两行,将huggingface模型转换成fastllm模型
# 目前from_hf接口只能接受原始模型,或者ChatGLM的int4, int8量化模型,暂时不能转换其它量化模型
from fastllm_pytools import llm
model = llm.from_hf(model, tokenizer) # dtype支持 "float16", "int8", "int4"
model.save("./chatglm2-6b.flm")

使用transformers库运行的gradio界面代码如下:

from transformers import AutoModel, AutoTokenizer
from peft import PeftModel
import gradio as gr
import mdtex2html
"""
tokenizer = AutoTokenizer.from_pretrained("../chatglm2-6b-32k", trust_remote_code=True)
model = AutoModel.from_pretrained("../chatglm2-6b-32k", trust_remote_code=True).half().cuda()
model = model.eval()
"""

"""Override Chatbot.postprocess"""


tokenizer = AutoTokenizer.from_pretrained("../chatglm-fitness-RLHF", trust_remote_code=True)
model = AutoModel.from_pretrained("../chatglm-fitness-RLHF", trust_remote_code=True, device_map='auto')
model = PeftModel.from_pretrained(model, "../Bofan-chatglm-Best-lora")
model = model.half().cuda().eval()


def postprocess(self, y):
    if y is None:
        return []
    for i, (message, response) in enumerate(y):
        y[i] = (
            None if message is None else mdtex2html.convert((message)),
            None if response is None else mdtex2html.convert(response),
        )
    return y


gr.Chatbot.postprocess = postprocess


def parse_text(text):
    """copy from https://github.com/GaiZhenbiao/ChuanhuChatGPT/"""
    lines = text.split("\n")
    lines = [line for line in lines if line != ""]
    count = 0
    for i, line in enumerate(lines):
        if "```" in line:
            count += 1
            items = line.split('`')
            if count % 2 == 1:
                lines[i] = f'<pre><code class="language-{items[-1]}">'
            else:
                lines[i] = f'<br></code></pre>'
        else:
            if i > 0:
                if count % 2 == 1:
                    line = line.replace("`", "\`")
                    line = line.replace("<", "&lt;")
                    line = line.replace(">", "&gt;")
                    line = line.replace(" ", "&nbsp;")
                    line = line.replace("*", "&ast;")
                    line = line.replace("_", "&lowbar;")
                    line = line.replace("-", "&#45;")
                    line = line.replace(".", "&#46;")
                    line = line.replace("!", "&#33;")
                    line = line.replace("(", "&#40;")
                    line = line.replace(")", "&#41;")
                    line = line.replace("$", "&#36;")
                lines[i] = "<br>"+line
    text = "".join(lines)
    return text


def predict(input, chatbot, max_length, top_p, temperature, history):
    chatbot.append((parse_text(input), ""))
    for response, history in model.stream_chat(tokenizer, input, history, do_sample=False,max_length=max_length, top_p=top_p,
                                               temperature=temperature,repeat_penalty = 1.02):
        chatbot[-1] = (parse_text(input), parse_text(response))       

        yield chatbot, history


def reset_user_input():
    return gr.update(value='')


def reset_state():
    return [], []


with gr.Blocks() as demo:
    gr.HTML("""<h1 align="center">ChatGLM</h1>""")

    chatbot = gr.Chatbot()
    with gr.Row():
        with gr.Column(scale=4):
            with gr.Column(scale=12):
                user_input = gr.Textbox(show_label=False, placeholder="Input...", lines=10).style(
                    container=False)
            with gr.Column(min_width=32, scale=1):
                submitBtn = gr.Button("Submit", variant="primary")
        with gr.Column(scale=1):
            emptyBtn = gr.Button("Clear History")
            max_length = gr.Slider(0, 8192, value=4096, step=1.0, label="Maximum length", interactive=True)
            top_p = gr.Slider(0, 1, value=0.85, step=0.01, label="Top P", interactive=True)
            temperature = gr.Slider(0, 1, value=0.85, step=0.01, label="Temperature", interactive=True)

    history = gr.State([])

    submitBtn.click(predict, [user_input, chatbot, max_length, top_p, temperature, history], [chatbot, history],
                    show_progress=True)
    submitBtn.click(reset_user_input, [], [user_input])

    emptyBtn.click(reset_state, outputs=[chatbot, history], show_progress=True)

demo.queue().launch(share=False, inbrowser=True,server_name="0.0.0.0")

使用转化后的flm格式代码如下,可以看到两边的top_p等系数都是一样的:

import gradio as gr
from fastllm_pytools import llm

meta_instruction = ""
model = llm.model("./chatglm-fitness-RLHF.flm")

def respond(message, chat_history,max_length, top_p, temperature):
        prompt = meta_instruction
        for i, (old_query, response) in enumerate(chat_history):
            prompt += "[Round {}]\n\n问:{}\n\n答:{}\n\n".format(i + 1, old_query, response)
        prompt += "[Round {}]\n\n问:{}\n\n答:".format(len(chat_history) + 1, message)  
        bot_message = ""
        chat_history.append([message,bot_message])
        for new_text in model.stream_response(prompt,max_length=max_length,do_sample=False,top_p=top_p,temperature=temperature,repeat_penalty = 1.02):
            bot_message += new_text
            chat_history[-1][1] = bot_message
            if len(bot_message) > 2560000:
                raise StopIteration()
            yield chat_history
        return

def reset_user_input():
    return gr.update(value='')

def reset_state():
    return [], []

with gr.Blocks() as demo:
    gr.HTML("""<h1 align="center">ChatGLM</h1>""")

    chatbot = gr.Chatbot()
    with gr.Row():
        with gr.Column(scale=4):
            with gr.Column(scale=12):
                user_input = gr.Textbox(show_label=False, placeholder="Input...", lines=10).style(
                    container=False)
            with gr.Column(min_width=32, scale=1):
                submitBtn = gr.Button("Submit", variant="primary")
        with gr.Column(scale=1):
            emptyBtn = gr.Button("Clear History")
            max_length = gr.Slider(0, 8192, value=4096, step=1.0, label="Maximum length", interactive=True)
            top_p = gr.Slider(0, 1, value=0.85, step=0.01, label="Top P", interactive=True)
            temperature = gr.Slider(0, 1, value=0.85, step=0.01, label="Temperature", interactive=True)

    history = gr.State([])

    submitBtn.click(respond, [user_input, chatbot, max_length, top_p, temperature], chatbot, queue=True,
                    show_progress=True)
    submitBtn.click(reset_user_input, [], [user_input])

    emptyBtn.click(reset_state, outputs=[chatbot, history], show_progress=True)

demo.queue().launch(share=False, inbrowser=True,server_name="0.0.0.0")

输入的prompt如下:

请将下列文本输出成简历:“适合职位:Python开发前程无忧更新时间:2021-03-09ID:854068334目前正在找工作****[email protected]男|24岁(1996年9月24日)|现居住广州-天河区丨2年工作经验ID:854068334最近工作(9个月)职位:数据分析师专业:交通工程公司:达怡科技有限公司学校:五邑大学行业:互联网/电子商务学历/学位:森求职意向数据分析师广州10000-14999元/月全职|互联网/电子商务网络游戏计算机服务(系统、数据服务、维修)到岗时间:1个月内自我评价:1.熟悉Python语言、SQL语句、Linux操作系统(Ubuntu、CentOS)、Shell,了解C语言2.熟悉Mysql、Redis数据库、MongoDB3.熟练使用Jupyter、Matplotlib、Numpy、Pandas、Sklearn等4.熟悉机器学习基本算法,如KNN、线性回归、岭回归、LaSSo回归、逻辑回归、决策树、随机森林、GBDT、XGBoost、聚类算法、朴素贝叶斯、LightGBM等算法。5.熟悉Hadoop、Hive、Hbase6.熟悉协同过滤算法,了解推荐系统7.熟悉基本的爬虫技术8.熟练使用Django/Flask等主流WEB框架,善于使用Django的DRF框架以及Flask-Restful风格进行9.熟练使用MySQL,Redis数据库,熟悉MySQL,Redis分布式设计以及Redis缓存优化,熟练使用SQL语句10.了解html、js、css11.数学功底扎实,兴趣浓厚,具有一定线性代数、统计学、概率论、微积分、高数、等数学知识储备。12.熟悉使用tableau等BI工具13.熟练使用excel、PPT工作经验2020/6-至今达怡科技有限公司(9个月)互联网/电子商务丨民营公司业务部数据分析师工作描述:1.对海量数据进整理分析,为公司运营决策提供可靠依据2.依据公司产品特性,开发、评估并维护各种数据预测模型及模型优化更新3.快速响应各种突发事件的相应开发需求4.收集、整理用户反馈信息,进行模型持续优化2019/7-2020/5江门市工蚁网络科技有限公司(10个月)互联网/电子商务丨50-150人丨民营公司研发部Python开发工程师工作描述:负责所分配功能模块的详细设计、功能开发、代码优化工作,系统维护及Bug修复。项目经验2020/9-至今产品销量预测所属公司:达怡科技有限公司项目描述:举行的活动期间销售情况,从而可以提前调整物流、完善备货渠道、根据不同情况调整活动力度、销售策略、成本投入。以较高的效率、较好方案完成销售流程,追求更小成本达到更大销量。个人工作流程及描述:一.明确问题,抽象成数学问题:明确我取得什么样的数据,可以抽象出一个分类还是回归或是聚类等的问题二.获取数据并进行相关处理三.数据基本处理:1.将训练集和测试集合并,在统一执行完处理后再分开,节省处理时间。2.数据清洗:对数据进行去重、缺失值处理、异常值处理、衍生字段、类型变量数值化和独热编码化四.特征工程:1.进行标准化处理。2.特征降维:根据经验删除冗余或无关特征;删除低方差的特征;五.机器学习(模型训练)使用岭回归、随机森林回归、决策树回归、梯度提升决策树回归等算法完成销量预测。并加入交叉验证的方法,并针对每个训练模型选择不同的超参数进行实验。六.模型评估根据情况使用平均绝对误差(MAE)、均方差(MSE)、均方根差(RMSE)、R^2(决定系数)一种或多种评价指标进行模型评估。七.对各算法模型分析对比得到最佳的两个算法模型重点分析并调参优化。八.达到预期进行部署上线责任描述:建立销售预测模型,使得公司可以预测每个产品在特定门店的销售情况、每个产品在营销部的销售情况、各个举行的活动期间销售情况,从而可以提前调整物流、完善备货渠道、根据不同情况调整活动力度、销售策略、成本投入。以较高的效率、较好方案完成销售流程,追求更小成本达到更大销量。2020/6-2020/9推广评估分析所属公司:达怡科技有限公司项目描述:个人工作流程及描述:一.使用pandas根据用户数据表和用户行为日志等进行数据提取,转化和清理,将原始数据转化为可用的模型的格式二.运用相关性分析和卡方检验实现特征选取三.根据不同特征在其他部门协助下确定分配权重,建立模型函数四.依据推广持续数据依靠模型建立各渠道推广效果对比图责任描述:研究不同渠道的广告推广投入,通过分析用户新增,日月活,平均使用时长,转化率,留存率等分析不同渠道推广效率,根据已有数据评估权重建立评估模型预测其他渠道分数,以便协助高层合理选择配比推广渠投入以及布局。2017-2020近地的无优限公司所属公司:江门市工蚁网络科技有限公司1.注册登录使用cookie,session以及redis缓存技术,注册时对用户名和手机号等信息进行唯一性校验,短信验证使用容联云,使用celery异步处理io耗时2.商品信息使用Django-haystack对接Elasticsearch实行商品关键词检索功能,图片管理使用FastDFS分布式存储系统3.后台管理商品使用Django RESTframework框架,序列化器优化商品增删改查4.后期使用MySQL的读写分离代码优化以及部分首页热搜商品使用redis一级缓存优化5.生成模板文件将商品首页作静态化处理,并使用django-crontab进行定时更新首页责任描述:用户的注册登录,首页&列表页&详情页&商品搜索页,后台商品的增删改查操作教育经历2015/9-2019/6五邑大学本科丨交通工程”

使用transformers库进行推理的结果如下,整体较好:

简历
姓名:XXX
性别:男
出生年月:1996年9月24日
联系方式:XXX
所在地:广州-天河区
职位:Python开发
期望薪资:10000-14999元/月
自我评价:
1.熟悉Python语言、SQL语句、Linux操作系统(Ubuntu、CentOS)、Shell,了解C语言。
2.熟悉Mysql、Redis数据库、MongoDB。
3.熟练使用Jupyter、Matplotlib、Numpy、Pandas、Sklearn等。
4.熟悉机器学习基本算法,如KNN、线性回归、岭回归、LaSSo回归、逻辑回归、决策树、随机森林、GBDT、XGBoost、聚类算法、朴素贝叶斯、LightGBM等算法。
5.熟悉Hadoop、Hive、Hbase。
6.熟悉协同过滤算法,了解推荐系统。
7.熟悉基本的爬虫技术。
8.熟练使用Django/Flask等主流WEB框架,善于使用Django的DRF框架以及Flask-Restful风格进行。
9.熟练使用MySQL,Redis数据库,熟悉MySQL,Redis分布式设计以及Redis缓存优化,熟练使用SQL语句。
10.了解html、js、css。
11.数学功底扎实,兴趣浓厚,具有一定线性代数、统计学、概率论、微积分、高数、等数学知识储备。
12.熟悉使用tableau等BI工具。
13.熟练使用Excel、PPT。
工作经历:
2020/6-至今:达怡科技有限公司(9个月)
职位:数据分析师
工作内容:
1.对海量数据进整理分析,为公司运营决策提供可靠依据。
2.依据公司产品特性,开发、评估并维护各种数据预测模型及模型优化更新。
3.快速响应各种突发事件的相应开发需求。
4.收集、整理用户反馈信息,进行模型持续优化。
2019/7-2020/5:江门工蚁网络科技有限公司(10个月)
职位:Python开发工程师
工作内容:
1.负责所分配功能模块的详细设计、功能开发、代码优化工作,系统维护及Bug修复。
2.负责所分配功能模块的详细设计、功能开发、代码优化工作,系统维护及Bug修复。
项目经验:
2020/9-至今:产品销量预测
项目描述:
1.根据公司的产品特性,开发、评估并维护各种数据预测模型及模型优化更新。
2.快速响应各种突发事件的相应开发需求。
3.收集、整理用户反馈信息,进行模型持续优化。
2020/6-2020/9:推广评估分析
项目描述:
1.使用pandas根据用户数据表和用户行为日志等进行数据提取,转化和清理,将原始数据转化为可用的模型的格式。
2.运用相关性分析和卡方检验实现特征选取。
3.根据不同特征在其他部门协助下确定分配权重,建立模型函数。
4.依据推广持续数据依靠模型建立各渠道推广效果对比图。
教育经历:
2015/9-2019/6:五邑大学本科丨交通工程

使用flm格式进行推理的结果如下,不完整,且有大量不存在于原文中的信息(比如文末声称求职者有硕士学位):

适合职位:Python开发工程师

姓名:男|24岁|1996年9月24日|现居住广州-天河区

职位描述:

负责Python开发工程师,根据项目需求开发、维护和优化Web应用程序;
熟悉MySQL数据库和Redis数据库,能够设计和实现高效的数据存储和管理方案;
熟悉HTML、CSS、JavaScript等Web前端技术,能够设计和实现用户友好的界面;
熟悉Linux操作系统,能够编写和配置Web服务器和容器;
具有良好的团队协作能力和沟通能力,能够与团队成员和客户进行有效的沟通和协作。
自我评价:

熟悉Python语言、SQL语句、Linux操作系统、MySQL数据库和Redis数据库等;
熟练使用Jupyter、Matplotlib、Numpy、Pandas、Sklearn等Python工具;
熟悉机器学习基本算法,如KNN、线性回归、岭回归、LaSSo回归、逻辑回归、决策树、随机森林回归、GBDT、XGBoost等算法;
熟悉协同过滤算法,了解推荐系统;
熟悉基本的爬虫技术,能够使用Django/Flask等主流WEB框架进行Web爬虫;
熟悉HTML、CSS和JavaScript等Web前端技术;
具有良好的数学基础和逻辑思维能力,具有一定的线性代数、统计学、概率论、微积分、高数、等数学知识储备。
教育经历:

2015年9月至2019年6月,五邑大学本科,交通工程专业,获得学士学位;
2019年7月至2020年5月,达怡科技有限公司,数据分析师,获得硕士学位。

ColorfulDick avatar Sep 21 '23 09:09 ColorfulDick

应该是还不支持设置生成参数导致的吧。我看了下源码,chat和stream_chat接口中的生成参数好像都没使用,有大佬帮忙确认下吗 image

louiss007 avatar Oct 17 '23 08:10 louiss007

应该是还不支持设置生成参数导致的吧。我看了下源码,chat和stream_chat接口中的生成参数好像都没使用,有大佬帮忙确认下吗 image

查看近期代码,这部分参数都是用上的。您需要更新代码。

TylunasLi avatar Oct 30 '23 11:10 TylunasLi

fp16勉强能用,int8、int4质量指数式下降

failable avatar Oct 31 '23 05:10 failable