在该视频中,UP用赛扬G5905+32GB内存尝试部署ChatGLM并成功运行,但是时间有限,所以没有尝试此模型多轮对话等能力:
有用显卡运行的小伙伴反映,多轮对话会爆显存,于是就粗略做了一些不太严谨的测试。本文末尾也会提供一种临时的解决办法,通过抛弃部分对话历史记录的方法来缓解显存问题。
测试内容包括:多轮短对话,代码相关对话,多轮长对话,对话的另一端是ChatGPT,事先对内容和输出长度做了约束。
CPU这边的话,目前没有发现爆内存的问题,使用单精度方式运行时,Python进程的内存占用稳定在23.5GB,波动不超过正负1GB。有可能是垃圾回收机制比较激进,而CUDA那边对应的策略比较保守?
首先对web_demo.py做了简单改造,使得它能够在终端打印对话轮次、输入字符数、输出字符数、消耗时间,基本逻辑如下:
在展示结果之前,贴一下CPU和内存的参数与跑分,供参考:
如果有打算使用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杯糖
适量冰块
适量肉桂或可可粉(可选)
步骤:
预热杯子,并在杯底倒入一些牛奶,加入糖和冰块。
把浓缩咖啡放入杯子中,用吸管搅拌均匀。
根据个人口味,加入适量的肉桂或可可粉。
继续搅拌均匀,直到咖啡和牛奶充分混合。
如果喜欢,可以在咖啡上撒上一些肉桂粉或可可粉作为装饰。
拿铁咖啡的特色在于牛奶和咖啡的混合,以及肉桂或可可粉的味道。可以根据自己的口味和喜好进行调整,制作出自己喜欢的拿铁咖啡。
用户:非常感谢你提供的详细步骤,我会尝试按照你的建议制作一杯美味的拿铁咖啡。
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函数可以用于许多场景,例如:
匿名函数:在函数内部定义一个Lambda函数,可以简化代码的可读性和逻辑性。
生成器表达式:生成器表达式是一个Lambda函数,用于返回一个序列或集合。
条件表达式:条件表达式可以使用Lambda函数作为内部函数,实现递归条件判断。
以下是一个简单的例子,展示了如何使用Lambda函数:
在这个例子中,my_function是一个生成器表达式,它使用条件表达式判断x是否大于10,如果大于10,返回一个字符串,否则返回另一个字符串。Lambda函数被定义在生成器表达式内部,这样外部就可以使用生成的字符串,而不需要知道具体的生成器表达式。
用户:Lambda函数是Python中的匿名函数,通常用于简化代码或实现逻辑。它们可以作为函数对象返回,但不需要定义外部或外部的函数对象。
ChatGLM-6B:Lambda函数是Python中的匿名函数,也称为匿名内部函数。它们可以作为函数对象返回,但不需要定义外部或外部的函数对象。Lambda函数通常用于简化代码或实现逻辑,其语法如下:
其中,表达式是一个可选的参数,表示Lambda函数要返回的值。Lambda函数可以用于许多场景,例如:
匿名函数:在函数内部定义一个Lambda函数,可以简化代码的可读性和逻辑性。
生成器表达式:生成器表达式是一个Lambda函数,用于返回一个序列或集合。
条件表达式:条件表达式可以使用Lambda函数作为内部函数,实现递归条件判断。
以下是一个简单的例子,展示了如何使用Lambda函数:
在这个例子中,my_function是一个生成器表达式,它使用条件表达式判断x是否大于10,如果大于10,返回一个字符串,否则返回另一个字符串。Lambda函数被定义在生成器表达式内部,这样外部就可以使用生成的字符串,而不需要知道具体的生成器表达式。
用户:Lambda函数是Python中的匿名函数,通常用于简化代码或实现逻辑。它们可以作为函数对象返回,但不需要定义外部或外部的函数对象。
ChatGLM-6B:Lambda函数是Python中的匿名函数,也称为匿名内部函数。它们可以作为函数对象返回,但不需要定义外部或外部的函数对象。Lambda函数通常用于简化代码或实现逻辑,其语法如下:
其中,表达式是一个可选的参数,表示Lambda函数要返回的值。Lambda函数可以用于许多场景,例如:
匿名函数:在函数内部定义一个Lambda函数,可以简化代码的可读性和逻辑性。
生成器表达式:生成器表达式是一个Lambda函数,用于返回一个序列或集合。
条件表达式:条件表达式可以使用Lambda函数作为内部函数,实现递归条件判断。
以下是一个简单的例子,展示了如何使用Lambda函数:
在这个例子中,my_function是一个生成器表达式,它使用条件表达式判断x是否大于10,如果大于10,返回一个字符串,否则返回另一个字符串。my_generator是一个生成器表达式,它使用for循环生成1到11的整数。my_condition是一个条件表达式,它使用条件表达式判断x是否大于10,如果大于10,返回True,否则返回False。result是my_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、智能音响、物联网设备等,而第一句话通常用于树立人设(猫设?),有其重要性,需要保留。
修改位置如图:
对应代码如下: