当前位置:首页|资讯|清华|编程|ChatGPT|ChatGLM

清华开源中文对话模型ChatGLM-6B简略试验及迫真优化解决爆显存

作者:蒙舌上単发布时间:2023-03-17

在该视频中,UP用赛扬G5905+32GB内存尝试部署ChatGLM并成功运行,但是时间有限,所以没有尝试此模型多轮对话等能力:

有用显卡运行的小伙伴反映,多轮对话会爆显存,于是就粗略做了一些不太严谨的测试。本文末尾也会提供一种临时的解决办法,通过抛弃部分对话历史记录的方法来缓解显存问题。

测试内容包括:多轮短对话,代码相关对话,多轮长对话,对话的另一端是ChatGPT,事先对内容和输出长度做了约束。

CPU这边的话,目前没有发现爆内存的问题,使用单精度方式运行时,Python进程的内存占用稳定在23.5GB,波动不超过正负1GB。有可能是垃圾回收机制比较激进,而CUDA那边对应的策略比较保守?

首先对web_demo.py做了简单改造,使得它能够在终端打印对话轮次输入字符数输出字符数消耗时间,基本逻辑如下:

在展示结果之前,贴一下CPU和内存的参数与跑分,供参考:

CPU参数
CPU-Z跑分,用初代县城撕裂者作比较。有没有正在用线程撕裂者跑的现身说法下,多核利用效率如何

如果有打算使用CPU跑的小伙伴,可以根据跑分换算速度。但只能粗估,因为不是严格的正比关系:

比如i3/5/7,锐龙等CPU有AVX指令集(赛扬没有),一些服务器CPU甚至有AVX512,对这些CPU有优化的话,速度会更快;

对于多核CPU,需要看对多核优化的程度如何,如果利用率不高,且单核性能不佳的话,也许效果反而不如这破赛扬;

推理很吃浮点性能,像推土机这样阉割一半FPU的设计,效果不会太理想。

另外有内存带宽,总线带宽等制约性能的要素。

内存读取性能
内存写入性能
内存复制性能
内存潜伏性能,条子时序导致数据一般

对话内容,以及用Excel做了点简单的分析,贴在下面供参考。

1.简单短对话

用户:你好,开始对话。

ChatGLM-6B:你好,有什么我可以为你效劳的吗?

用户:请问你能告诉我现在是几点吗?

ChatGLM-6B:很抱歉,我无法提供当前时间,因为我只是一个计算机程序,没有直接访问实时时间的能力。不过,你可以使用任何时间戳或当前日期来查询当前时间。

用户:好的,谢谢你的回答。那请告诉我如何制作一杯美味的拿铁咖啡?

ChatGLM-6B:制作一杯美味的拿铁咖啡,可以参考下述步骤:

材料:

  • 1个杯子

  • 1包(约4克)浓缩咖啡

  • 1/2杯牛奶

  • 1/4杯糖

  • 适量冰块

  • 适量肉桂或可可粉(可选)

步骤:

  1. 预热杯子,并在杯底倒入一些牛奶,加入糖和冰块。

  2. 把浓缩咖啡放入杯子中,用吸管搅拌均匀。

  3. 根据个人口味,加入适量的肉桂或可可粉。

  4. 继续搅拌均匀,直到咖啡和牛奶充分混合。

  5. 如果喜欢,可以在咖啡上撒上一些肉桂粉或可可粉作为装饰。

拿铁咖啡的特色在于牛奶和咖啡的混合,以及肉桂或可可粉的味道。可以根据自己的口味和喜好进行调整,制作出自己喜欢的拿铁咖啡。

用户:非常感谢你提供的详细步骤,我会尝试按照你的建议制作一杯美味的拿铁咖啡。

ChatGLM-6B:不客气,很高兴能帮助制作出一杯美味的拿铁咖啡。如果有任何其他问题或需要进一步的帮助,请随时告诉我。

用户:好的,谢谢你的热心帮助。请问你有什么推荐的书籍或电影吗?

ChatGLM-6B:当然,我很乐意为您提供推荐。以下是一些我个人喜欢的的书籍和电影:

书籍:

  • 《1984》乔治·奥威尔

  • 《追风筝的人》卡勒德·胡赛尼

  • 《人类群星闪耀时》刘慈欣

  • 《小王子》安托万·德·圣埃克苏佩里

电影:

  • 《教父》弗朗西斯·福特·科波拉

  • 《辛德勒的名单》史蒂文·斯皮尔伯格

  • 《肖申克的救赎》弗兰克·德拉邦特

  • 《阿甘正传》罗伯特·泽米吉斯

  • 《星际穿越》克里斯托弗·诺兰

这些都是我非常推荐的书籍和电影,它们都有自己独特的风格和主题,可以带给您不同的阅读和观影体验。希望这些推荐能够对您有所帮助!

用户:非常感谢您提供的这些推荐,我会尽快去阅读和观看。如果我有任何其他问题或需要进一步的建议,我会再次与你联系。

ChatGLM-6B:不客气,很高兴能够为您提供帮助。如果有任何其他问题或需要进一步的建议,随时都可以联系我。祝您阅读愉快!

用户:谢谢,祝您也有愉快的一天!

ChatGLM-6B:不客气,祝您也度过愉快的一天!如果有任何其他问题,随时都可以联系我。

时间有限,没有去一一检验模型生成的内容中是否存在常识性错误,若有请在评论区指出,谢谢。

2.代码相关对话

一开始问了一些Python相关的问题,结果ChatGLM的表现不尽人意,而且最后收敛(复读)了,就只测了四轮:

用户:会Python吗?

ChatGLM-6B:是的,我可以使用Python编程语言。Python是一种高级、通用、解释型编程语言,易于学习和使用,并且广泛应用于各种领域,包括数据科学、机器学习、人工智能、Web开发等。如果您需要使用Python,我可以提供一些帮助或建议。

用户:那您能否介绍一下Python中的Lambda函数是什么?何时使用它们?

ChatGLM-6B:Lambda函数是Python中的匿名函数,也称为匿名内部函数。它们可以作为函数对象返回,但不需要定义外部或外部的函数对象。Lambda函数通常用于简化代码或实现逻辑,其语法如下:

其中,表达式是一个可选的参数,表示Lambda函数要返回的值。Lambda函数可以用于许多场景,例如:

  1. 匿名函数:在函数内部定义一个Lambda函数,可以简化代码的可读性和逻辑性。

  2. 生成器表达式:生成器表达式是一个Lambda函数,用于返回一个序列或集合。

  3. 条件表达式:条件表达式可以使用Lambda函数作为内部函数,实现递归条件判断。

以下是一个简单的例子,展示了如何使用Lambda函数:

在这个例子中,my_function是一个生成器表达式,它使用条件表达式判断x是否大于10,如果大于10,返回一个字符串,否则返回另一个字符串。Lambda函数被定义在生成器表达式内部,这样外部就可以使用生成的字符串,而不需要知道具体的生成器表达式。

用户:Lambda函数是Python中的匿名函数,通常用于简化代码或实现逻辑。它们可以作为函数对象返回,但不需要定义外部或外部的函数对象。

ChatGLM-6B:Lambda函数是Python中的匿名函数,也称为匿名内部函数。它们可以作为函数对象返回,但不需要定义外部或外部的函数对象。Lambda函数通常用于简化代码或实现逻辑,其语法如下:

其中,表达式是一个可选的参数,表示Lambda函数要返回的值。Lambda函数可以用于许多场景,例如:

  1. 匿名函数:在函数内部定义一个Lambda函数,可以简化代码的可读性和逻辑性。

  2. 生成器表达式:生成器表达式是一个Lambda函数,用于返回一个序列或集合。

  3. 条件表达式:条件表达式可以使用Lambda函数作为内部函数,实现递归条件判断。

以下是一个简单的例子,展示了如何使用Lambda函数:

在这个例子中,my_function是一个生成器表达式,它使用条件表达式判断x是否大于10,如果大于10,返回一个字符串,否则返回另一个字符串。Lambda函数被定义在生成器表达式内部,这样外部就可以使用生成的字符串,而不需要知道具体的生成器表达式。

用户:Lambda函数是Python中的匿名函数,通常用于简化代码或实现逻辑。它们可以作为函数对象返回,但不需要定义外部或外部的函数对象。

ChatGLM-6B:Lambda函数是Python中的匿名函数,也称为匿名内部函数。它们可以作为函数对象返回,但不需要定义外部或外部的函数对象。Lambda函数通常用于简化代码或实现逻辑,其语法如下:

其中,表达式是一个可选的参数,表示Lambda函数要返回的值。Lambda函数可以用于许多场景,例如:

  1. 匿名函数:在函数内部定义一个Lambda函数,可以简化代码的可读性和逻辑性。

  2. 生成器表达式:生成器表达式是一个Lambda函数,用于返回一个序列或集合。

  3. 条件表达式:条件表达式可以使用Lambda函数作为内部函数,实现递归条件判断。

以下是一个简单的例子,展示了如何使用Lambda函数:

在这个例子中,my_function是一个生成器表达式,它使用条件表达式判断x是否大于10,如果大于10,返回一个字符串,否则返回另一个字符串。my_generator是一个生成器表达式,它使用for循环生成1到11的整数。my_condition是一个条件表达式,它使用条件表达式判断x是否大于10,如果大于10,返回True,否则返回False。resultmy_condition的返回值,如果my_condition返回True,则result为"x is greater than 10",否则为"x is less than or equal to 10"。

本想看看ChatGPT怎么吐槽的:


后来问了一些关于C语言的问题,ChatGLM表现好一些(国内大学多以C语言作为计算机入门课程之一,所以语料较为丰富?),但也有瑕疵。然而这段回答已经让ChatGPT折服了,我刷新了十多遍都是回一句谢谢,于是没有再往下试、或者重开了,不然各位今天就看不到这篇专栏了:

就两轮,因此没有做拟合曲线

用户:C语言的变量可以在哪些地方定义?

ChatGLM-6B:变量定义语句:在C语言中,变量定义语句是用来声明变量的语句,通常放在程序的开头。例如:

int a;  // 声明一个整型变量a

double b;  // 声明一个双精度浮点型变量b

char c;  // 声明一个字符型变量c

变量声明:在变量定义语句之前,可以使用变量声明语句来声明一个变量,声明时需要指定变量的类型和名称。例如:

int a = 10;  // 声明一个整型变量a,并将其初始化为10

double b = 0.1;  // 声明一个双精度浮点型变量b,并将其初始化为0.1

char c = 'X';  // 声明一个字符型变量c,并将其初始化为X

变量定义后:在变量定义语句之后,可以使用变量来访问和修改它的值。例如:

int a = 10;

printf("%d\n", a);  // 输出a的值是10

a = 20;

printf("%d\n", a);  // 输出a的值是20

上面的代码中,变量a的值在定义后可以被修改。需要注意的是,在程序中只能有一个变量定义语句,定义语句之后不能再进行变量声明或变量赋值。

用户:明白了,谢谢你的解释。

3.多轮长对话

内容是两个AI在聊人生经验,由于聊天内容篇幅极长,就不在这里发,只贴数据,另投一篇专栏如下:

内容没有明显的问题,而且可以直接拿来水各种鸡汤文,只是ChatGLM复读现象严重,就像在附和ChatGPT;但也可能因为用了现成语料,输出速度有提升。

这个其实用幂函数能够拟合得更完美

简单改造代码,通过抛弃部分对话历史记录的方法来缓解显存问题

目前在CPU上没有遇到OOM,但是爆显存的现象是客观存在的,在清华项目组迭代之前,可以用这种方式来应急。

甲.直接挤掉前面的记忆,只保留最近3轮对话的内容

简单粗暴,逻辑清晰。

以下是web_demo.py修改的位置:

将原版代码第15行修改如下:

若要修改保留对话的轮数,可自行修改小于等于号、负号后的数字。

乙.保留第一轮对话以及最近2轮对话

大多数用户本地部署都有将AI调教为猫娘等需求,进而接入vits、智能音响、物联网设备等,而第一句话通常用于树立人设(猫设?),有其重要性,需要保留。

修改位置如图:

对应代码如下:



Copyright © 2024 aigcdaily.cn  北京智识时代科技有限公司  版权所有  京ICP备2023006237号-1