王路在隐身

炼丹十日

我是最近才知道 “ 炼丹 ” 这个词 —— 用 GPU 训练文本深度学习。我本科学的是地理,研究生学经济,对计算机一窍不通,就在大一基础课上学过半学期 JavaScript ,之后再也没摸过编程相关的东西(作为自媒体倒是卖过 Python 的课)。不久前,我还在问朋友什么叫 “ 运行( run ) ” ,还去 GPT 上问 “GPU 和 CPU 的区别是什么 ”“ 我怎么知道我的电脑有没有 GPU”—— 这都是一个月内发生的。而今天,我也练上丹了,用 GPT2 模型训练了《大正藏》毗昙部类 13851113 字的文本。 这一切,在过去是不能想象的 —— 如果没有人工智能,我一年也做不了这件事,我是一行代码都看不懂。但是,有了人工智能(我甚至都没用 GPT4 ,只是用 ChatGPT 和 Claude ),一个一行代码都看不懂的人,在 10 天内,也可以炼上丹了。中间碰到的困难,我请教过祁勋几次,他训练过 “ 击攘 ” ,是个生成古诗的大模型。除了请教祁勋的几次,剩下的问题,我都是问 AI ,大概问过上千个问题,也就比葫芦画瓢弄出来一个最基本的毗昙文本生成器。我就简单说说我碰到的困难,和解决的思路,来演示一下,完全零基础的小白怎样利用人工智能去学习。 去年年底, ChatGPT 刚出圈的时候,我就对用大语言模型训练毗昙文献有很高的期待,但那时候我从没想过自己去做这件事,而且是一个人做 —— 我总觉得得懂计算机的人才能做。但实际上,懂计算机和深度学习的人,如果不是对毗昙感兴趣,没有人会专门去做这个东西 —— 他们有自己觉得更重要的事情去做,多得很。最近,闲得无聊,我也就自己尝试了。 第一步是什么呢? —— 我这里说的第一步不是思想建设上的,是实操上的。第一步是给电脑装个编程语言。对我来说,是装个 Python 。我的电脑是 2015 年买的 Macbook Air ,那一款在当时都不是最新的,现在已经基本要弃用了,我都不知道它自带的有 Python 。当然,自带的也不能用,要用 Python3——Python 分 2 、 3 我也是最近刚知道。我动手炼丹到目前最大的障碍,还不是代码有错误,而是什么东西不兼容,或者缺少什么包,导致运行不了。 很多人低估了小白学习一样东西的难度。在某方面有一定基础的人,借助 AI 去减少工作量,是非常容易的;但是,毫无基础的人,上手实现一个最简单的操作,也非常困难。 —— 你压根儿不知道该问 AI 什么。比方说,我就问过 AI 这些问题: “ 什么是终端? ”“ 怎样在电脑上找到终端? ”“ 不,我用的 Mac ,怎样在上面找到终端? ”—— 一个人如果已经知道什么是 “ 终端 ” ,而且能够在电脑上找到 “ 终端 ” 在哪儿,我就认为他不配自称 “ 零基础 ” 或者 “ 小白 ” 。他如果还好意思自称零基础,那就等于把真正零基础的人打成负基础了。 很多时候,固然,你问了, AI 就能告诉你答案(虽然答案也会错),但问题是,你根本不知道该怎么问、以及问什么,也听不懂 AI 的回答。 ——AI 告诉你在终端输入命令,你起码得知道什么叫 “ 终端 ” 什么叫 “ 命令 ” 吧, AI 告诉你运行程序,你起码得知道什么叫 “ 运行 ” ,以及怎样 “ 运行 ” 吧? “ 怎样在 Mac 上找到终端 ” 的问题,我就问过 AI 好几次,因为会忘。如果你符合这个标准,我觉得你在炼丹方面基础可能跟我是一样的。 不久前,有个 985 院校毕业的研究生,接受采访,想说自己工作中经常被 PUA ,说成了经常被 GPU ,我觉得他可能在计算机方面跟我差不多,我比他强的是,没有经常被 GPU ,顶多是被 CPU 。现实中,家长辅导小孩,要是怎么教小孩都不会,有些家长能气炸,经常拍着桌子 PUA 小孩:你怎么就这么笨!这么简单的问题,讲了这么多遍,你怎么还不会! —— 而 AI 最好的就是,你问它问题,完全不用担心被 PUA ,甚至,你 PUA 它都没问题:你怎么就不能用我听得懂的语言来解释!你以为你说这些我就能听懂吗?你知道一个小白在听你讲术语时候的感受吗! —— 我把这称为 PUAI 。 为什么你碰到问题不能去请教周围懂的朋友?因为有些问题,像 “ 什么是环境 ” , “ 为什么终端显示的内容有时候一行一行往上跳,有时候又保持一行不动 ” ,这种问题你是绝对不好意思去问周围懂计算机的人的,我有个高中同学现在就是计算机学院的教授,跟我关系也很好,但我绝对不会去问他这种问题 —— 太小儿科了,问不出口。但是你去问 AI ,就完全没有心理障碍。随便你怎么问,问得再低幼, AI 都不会笑话你,你听不懂还可以反复问,问十遍都没事;但是你问活人,人家解释了三遍你都听不懂,你还好意思问吗? 接着说实操。我装了 Python3 之后,让 AI 先 “ 给我写一个最简单的大语言模型生成内容的程序,训练的文本是只有 0 和 1 的 100 位数,要生成的文本也只有 0 或者 1”—— 这就是我炼丹的开始。是上星期三。 这个不算难,我折腾了几十次吧,也就是一下午加一晚上的时间,实现了。 —— 把 AI 生成的代码拷贝到文本编辑器里,保存,运行。 —— 可不要觉得对小白来说这很简单,因为,什么叫 “ 文本编辑器 ” ,怎么 “ 保存 ” ,怎么 “ 运行 ” ,每一步都是很大的障碍。我稀里糊涂下载了好几个文本编辑器,怎么运行都会出错 —— 你搞不清楚到底是 AI 给的代码有问题,还是代码里你该动手改的地方没改,还是别的问题。 一下午障碍我的,可能是 conda 环境的问题,到现在我都没搞懂什么叫 conda ,什么叫 “ 环境 ” ,当时只是来来回回把报错的信息发给 AI ,问它什么意思,在几十次无果之后,我尝试从终端运行,发现可以了。之前它老是告诉我 numpy 没有装,我也不知道 numpy 是什么,也不知道怎么装,按照 AI 给出的方法去装,感觉装上了,再运行,还是告诉我 numpy 没有装,我就问 AI“ 怎么知道我的 Mac 上有没有装 numpy” ,甚至卸载重装了几次,一度把破笔记本搞得没有空间,它仍然告诉我 numpy 没有装 —— 整个过程中最让人烦躁挫败的就是这些,这些问题,如果你旁边有个懂的人,比方说你在机房里,身边就有老师同学,两分钟就解决了,但是你一个人碰到这种问题,真的是一筹莫展。最后发现并不是 numpy 没装,只是通过文本编辑器没法运行。 —— 我就通过这个挫败,学会了在终端用命令运行程序。之前我只会问 AI : “sublime text 的运行在哪里 ” , “visual studio code 运行 Python 怎么总是说没装 numpy” , “IDLE 的运行怎么没有结果 ” ,包括这些文本编辑器的名称,我都是问了 AI 才听说的。 有编程基础的人可能会觉得小白的最大障碍是代码错了看不出来,其实根本不是。最大的障碍是,为什么同样的代码,别人能运行,我这儿就是运行不了。为了定位问题,我经常会让 AI 写个最简单的程序给我,比如让它写个 print 的程序,我好看看到底是程序本身有问题,还是别的问题。 —— 有时候发现是文件所在路径的问题。曾经卡住我很久的一个问题,最终的解决办法是,把程序里提到的一个文件,拖到它旁边的文件夹里。 总之,经过一下午和一晚上,我得到了一个可以生成 0 或 1 的代码。我想,既然可以生成数字,就应该可以生成汉字。我就让 AI 给我写生成汉字的代码,要求它写最简单的。我的训练文本,是从《大毗婆沙论》里复制的几十个字。我按照 AI 的提示,把每一个字打上引号,用逗号分开 —— 我也不知道这是为什么。一个人如果知道这是为什么,他就根本不配自称小白,根本没资格说自己 “ 也不懂 ” 。 “ 不懂 ” 和 “ 也不懂 ” 之间,那是差了十万八千里。 很多人给别人讲东西,别人听不懂,不是因为别人笨,而是因为讲的人不知道什么叫零基础。有些人,甚至是非常多的人,在自己不是零基础之后,就彻底忘掉了什么是 “ 零基础 ” ,以至于觉得别人应该理所当然地知道一些别人根本不可能知道的事情 —— 而他觉得别人 “ 显然应该知道 ” 。有时候看教材,最痛恨的一个表述就是 “ 显然有 ”——“ 显然你个头啊! ” 对完全不显然的事情说显然的人,显然是没有办法当一个好老师的。因为他只能理解自己的困境,永远理解不了别人的困境,哪怕别人的困境是他曾经经历的,而一旦自己越过去,他就再也不把那当成一个别人也会遭遇的困境来看待。 我在用《婆沙》的几十字训练后,能够做到让程序生成几个字的文本。于是我就尝试用更长的文本作为训练材料,选了《婆沙》里的三五千字。首先碰到的问题是,我不能再把想要训练的文本直接放到程序里,而是要另外保存。至于该保存成 TXT 还是别的格式,我也得问 AI 。问了,保存成 TXT 。照葫芦画瓢地运行,总是出错。 出错的原因也简单,有些字不能识别。但到底是哪些字不能识别,我也不知道。问了 GPT 和 BING ,都无果之后,我想了想,决定问祁勋。他先问我,哪些字不能识别;我说我不知道。他说,这样,你加一行代码,给了我一句 “fo” 开头的代码,说把不能识别的忽略掉就行了。我没见过 fo 开头的代码,还在想,他是不是想写 for ?我就把这句代码抛给 AI ,问什么意思, AI 告诉我之后,我明白确实是 fo ,不是 for ;但我也不知道这一句应该加在哪个地方,就复制了全部的代码,告诉 AI ,把 “fo” 这句加进去,加在合适的地方。然后,我就能够根据三五千字的内容,生成文本了。那是上周三晚上 11 点多。我很高兴。我想,既然能够训练三五千字,就能训练三五十万字,乃至几百万字。 上周四一早,我就从 CBETA 上,把《俱舍论》用 TXT 格式下下来,让 AI 给我写个程序,去掉开头的资讯,也就是光盘由谁提供这些,我怕对训练造成干扰(实际上会不会干扰我也不知道)。然后照猫画虎,替换掉昨天的三五千字,在终端运行。程序里设置的 epoch 是 100 ,但我当时还不知道什么叫 epoch ,也不知道代码里有 epoch 这一行。我甚至都不知道终端会显示剩余时间(终端显示的所有数字和英文,我如果想知道什么意思,就会直接扔给 AI )。 不过,进度条我是能看懂的, 1% 我也能理解,我就看着进度条从 1% 走到 2% ,花了两分多钟,我就知道完成需要 250 分钟,要四五个小时才运行完。 —— 我很高兴,知道自己已经在训练了,而且没想到这么个小破电脑就能训练 —— 以后不能再叫它小破电脑了,它这些年真是没少帮助我,不能说人家小、人家破。 我的 Mac 只要一分钟不碰,就会自动待机,我怕待机的时候程序停了,就问 AI ,在 AI 指导下改了设置,还不放心,盯了好几分钟,才去吃早饭、下楼散步。走之前把卧室门关好 —— 以免猫蹦到键盘上。在等待训练的 4 个小时里,我才仔细去看运行的每一行代码,虽然仍然完全看不懂,但我会扔给 AI ,让它给我 “ 逐行解释 ” 。然后知道了 epoch ,也发现了终端会显示剩余时间。 到中午 11 点多,训练 4 个多小时的程序停下来了。我满怀期待地看看能生成什么,结果很堪忧:连着生成 20 个逗号。我又尝试改变输入的词,结果还是连着 20 个逗号。我猜,应该是训练文本中,逗号出现的频率最高导致的。我让 AI 给我写代码,不让它生成逗号和句号,再运行,就根本出不来结果。 睡了午觉,我让 AI 给我写代码,把文本里的所有非汉字的字符全去掉。结果,它生成了 20 个 “ 望 ” 字。换输入,仍然如此。效果比训练三五千字还差。而且, LOSS 值一直在 5.8 左右。后来,我仔细看上午运行的记录,才明白,那四个多小时都是瞎跑,程序运行 5 轮之后, LOSS 值基本就不下降了,也就是说,我在早上跑了 20 分钟的时候就可以停了,后面 4 个小时毫无必要。我又问 AI 怎样能把 LOSS 值降下来,等等。 一个下午,没有结果。 晚上,我又请教祁勋。祁勋说,你用的什么模型?我问他:什么是模型?他说,比方说,你用的是 GPT ,还是 LSTM ?我说,我也不知道,可能没用模型,我让 AI 生成的代码。他说,把你代码给我看看。我发给他,他说,你这是 LSTM 。我就赶紧问 AI , “ 什么是 LSTM 模型?和 GPT 模型有什么差别? ” 我说,用 30 万字训练,生成的内容总是同一个字符。他圈出两行代码说,你这里,一个汉字对应一个数字,太简单了,完全不能表达不同汉字之间的关系,你可以让汉字映射向量,比方说,一个汉字映射 300 维的向量。我又问他击攘的 LOSS 值,他说没有可比性。因为这一天我在跟 AI 聊的一堆问题中, AI 提到了可以网上买算力,我就问祁勋,他告诉了我几个平台和价格。这是上周四晚上。 夜里,我找到一个租用 GPU 的平台,充了 50 块钱。我把所有程序都粘贴到 Jupiter notebook 的一行里面,很不美观,然后点运行,等了半天,都没反应。我以为是 GPU 运行太快,已经默然出结果了,就想找找生成的文件保存在哪儿。还问 AI : “ 网上买算力生成的文件保存在哪儿? ” 一直搞到凌晨一点多,还是没找到。后来下机,发现只花了一块钱。心想:早知道才花一块钱, 12 点就睡了,还干嘛找这半天。 第二天周五,又找,找了一上午,还问 AI 怎样用 SSR 下载,后来才知道,程序压根儿没运行。周五一天,基本上等于是在熟悉算力平台是怎么操作的,怎么上传和下载东西。 上周六仍然卡了很久,想运行的程序,基本上没有成功过。每次出错,丢给 GPT , GPT 改了之后,运行,又出错,再丢给 GPT ,再改。要改几十次、上百次。因为我是一行代码都看不懂, GPT 解释了,我也不明白 GPT 解释的对不对。之所以不怎么问 BING ,是因为现在的 BING 越来越讨厌了,基本上会拒绝回答代码问题。后来,我开始 Claude 和 GPT 并用, Claude 回复很有礼貌,每次都会加上几段废话,好比客服电话结尾的 “ 祝您生活愉快 ” 。我用的比较多的是 GPT 代理,不是直接从 openai 网站上用,在它的网站上,只要 30 秒不操作,就必须重新刷新页面才能问,很浪费时间。但 GPT 代理似乎没有 ChatGPT 智能,有时候它的改动本身就会造成错误。所以我不同的 AI 一起问,三个臭皮匠(裨将),顶个诸葛亮。周六下午,我疲劳了,周日就去搞别的了。 周一又试,先把之前我的 Mac 上能运行的 LSTM 程序扔给算力平台,结果发现算力平台运行不了。我很惊讶,为什么 CPU 可以搞的活, GPU 反而不能搞。又问 AI ,又让它改代码。最终, GPU 可以运行 LSTM 程序了。 然后我就想试 GPT 模型,从头开始,让 AI 给我生成一个用 GPT2 模型训练纯中文文本的代码。 AI 生成的代码都是有长度限制的,我让它给我生成最简单的,也要大几十行,一次生成不完,只能命令它继续。而我把两次生成的粘在一起,就会出现问题。有时候是缩进的问题。有时候它自己错乱了。周一搞了一上午,没结果。 中午我想,大概不应该那样问,不应该直接让它给我生成代码,应该问它想用 GPT2 模型训练纯中文文本,需要哪些步骤。它告诉我一二三四五,第一步是数据预处理,去掉标点符号之类的,我已经做了,第二步是分词。我就问它具体怎样分词。它就给我生成了用 jieba 分词的代码。试了十来次,分词成功了。 接着,让 AI 写训练的代码。写了,还是屡屡出错。最后,似乎成功了,又是只能用 CPU 运行。又花了些时间让 AI 帮我改成可以用 GPU 运行的代码,到周二凌晨,可以了。 周二上午,我让 AI 给我写生成文本的代码,仍然屡次不成功。后来觉得可能是 jieba 的分词和训练程序不匹配,因为训练用的是 GPT2 的分词方法,问了不同的 AI ,到现在仍然没有明确的结论(因为 AI 经常说得不对,我也不会轻易信),保险起见,我重新用 GPT2 分词,再训练,最后,可以生成文本了。 但生成的文本其实不能叫文本,因为并不是有意义的句子。毗昙的句子和我们平常读的句子还是不大一样的。我有时候直接拿毗昙文献中的一句话,抛给 ChatGPT 和 BING ,它们也不知所云。这也是我想专门训练毗昙文献的原因之一。我想,初步的目的,应该是让生成的文本是有意义的,起码是语法正确有含义的,含义的正确就不要求了 ——GPT4 都做不到。 我能想到的方法,就是扩大数据。于是把《顺正理论》加进去,统计了字数,共 131 万。生成的内容还是没有太大起色,但稍微好一点。我又更改参数。中间因为别的事情,也不是每天都弄,反正闲了就想想。 在能够用 GPT2 模型训练《俱舍》和《正理》之后,我主要考虑的问题是:我怎么知道训练应该到什么时候结束?而且我不清楚:每次训练一轮,训练六次,和一次训练六轮效果有多大差别?这是汲取了之前的教训,之前上来就训练 100 轮,结果发现后面的 90 轮都没有意义。我现在不敢一下子训练太多轮,想一轮一轮训练。就问 AI ,后面的训练是在原来基础上训练还是等于从头训练? AI 告诉我,只要不改参数,就是在原来基础上训练。我挺高兴,就训练一轮,看看结果,再训练一轮,但我发现,两次训练的 LOSS 值是一样的,就怀疑,后面的训练等于白练,但我也没有证据。 我想,要先搞清楚,训练的天花板在哪儿,也就是说,得先知道训练到什么时候可以停止。又问 AI ,了解到 “ 早停法 ” 以及用困惑度来确定何时停止训练。又找它要代码,又试。还问它早停法的代码是应该放在另外的文件里,还是和训练文件放一起,等等,各种细节。 最后,加了困惑度,在 LOSS 值连着几个回合降低不超过 0.02 的时候,让它停下来。这才发现,其实 130 万汉字的训练,在现有的参数下, 1 个小时左右也就停了。根本用不着更长时间。当然,如果增加隐藏层的数量应该可以改进效果,但那些对我来说还比较复杂,也要花更多精力,就暂时没试。 在停下来之前,我还想把数据堆大一点,就又把《大毗婆沙论》整个放进去,《俱舍》《正理》《婆沙》,加起来是 3498562 字。训练了两次,第一次是 55 分钟自动停,第二次把条件改得苛刻一点,训练了两个多小时,试了效果,勉强有一点起色,但不大。甚至有时候,你的 prompt 是 “ 問幾地有無漏法 ” ,它生成的内容里有 “ 三藏法師玄奘奉詔譯 ” 。 后来我想,干脆把毗昙部都堆给它算了,又去下载,整个毗昙部,除了最后的《三界图》,都堆上去了,共 13851113 字。这次,我没有再删开头的 ” 经文资讯 “ ,因为文件太多了,每个又有差别,程序也不好写,关键是,不知道删了是不是真的会有帮助。我想,先训练了试试,如果问它一个毗昙问题,它生成的内容有 “ 光盘由某某大德提供 ” ,我可能就考虑从原始数据中删掉那些。最终,运行了 4 个小时多一点,还没有第一次运行的时间长。生成的内容,没有超出预期,也没有低于预期。大致是这样子的 —— 尽管句子是完全不通的,但毗昙的味道和气息基本具备,也就是说,让一个外行看,他不一定能看出来哪些是毗昙文本,哪些是 AI 生成。 以下四个例子,有 AI 生成的,也有毗昙经典文献: 例一:色無色繫及與無漏道諦得唯無漏故無繫法得有四種又有學法得唯有學若無學法得唯無學非學非無學得有差別謂此法得總說有三別分別者一切有漏及三無為皆名非學非無學法 例二:幾地有無漏樂根幾地有無漏喜根幾地有漏捨根幾地無復有異者二種有為法為捨根耶少分皆如此應知雜者生欣樂故捨根三種有生欣樂故生身根少分亦有生欣樂五識除樂根定在下地五識一逆與識不在上地中 例三:說名頂墮非已得退有作是說世尊如頂於佛作惡而墮惡趣故名頂墮有餘師說佛法如頂彼壞佛法便自退落故名頂墮忍亦得亦捨得者由加行故捨者或由越界地故或由捨眾同分故不由退故 例四:生幾地容起滅盡定答涅槃此中說緣現在亦說緣無過復次若此定中於未來定無體可立二定名此定不定中無體何得說名為所緣或說一過謂於未來定不定住安住由此唯於地未來定發悉依於地天眼天清清故地一切眼 AI 生成的,是完全不通的。这应该有一部分是我的参数调得不够好的原因,更重要的一部分是,模型确实还不够智能。我目前能做的,也就这样了。这 10 天的炼丹体验,到此也告一段落。记下来是想表示:如果没有 AI ,我这种尝试和体验,是完全不可能的 —— 你势必需要周围有人手把手教你,你要亲自写代码,而现在,你甚至连看懂代码都不需要,就可以有这样的体验。