如果一个简单的游戏成为通往计算突破的途径呢?David Freiberg和Felipe踏上了征服Hatetris(一款臭名昭著的困难的JavaScript游戏)的旅程。当一个新的世界纪录被创造出来时,他们的兴趣被点燃了,这表明超越游戏的高分是可能的。他们的旅程充满了挑战,从用不同的编程语言构建模拟器到解决复杂的算法。他们突破了可能的界限,但故事并没有就此结束。与其他爱好者(包括一位日本俄罗斯方块专家)合作,带来了进一步的突破。通过分享见解和建立在彼此工作的基础上,他们创造了一个又一个纪录。他们的故事突出了好奇心、合作和发现的乐趣。剧集页面支持节目订阅播客加入通讯</context> <raw_text>0 - 你好,这里是Co-Recursive,我是Adam Gordon Bell。今天,和往常一样,我们将深入探讨软件背后的人们。
因为有时看起来像一个简单的谜题的东西可能会解开成一个复杂的网络。今天,我们将探索两个在2010年一款JavaScript游戏中迷失自我的人的故事。它看起来只是另一个俄罗斯方块的克隆,但它很快成为一种痴迷,这将挑战他们的技能、钱包,甚至他们的关系。我的名字是David Freiberg。我是一位材料科学博士。
而我非常非常痴迷于2010年发布的一款JavaScript游戏。我是Felipe。我是HubSpot的一名软件工程师。我对这个问题不像Dave那样充满热情,但我已经被拖着踢踢叫叫地卷入其中了,所以我想我现在是这方面的专家了。这款游戏叫做Hatress。如果你玩过俄罗斯方块,你会知道你需要恰好合适的方块的那一刻。♪
就像我已经把一切都排好了,如果我能得到那四个一排,那个眼睛,我可以清除四行。
现在想象一下俄罗斯方块的一个版本,你永远不会得到你想要的方块。游戏似乎对你怀恨在心。那就是Hatetris。这是一个很难很难的游戏。多年来,它有一个看似无法战胜的、非常非常低的高分。然后这两个朋友,Dave和Felipe,沉迷其中了。他们花费了数月甚至更多的时间和金钱来打破这个纪录。
根据你收听这集节目的时间而定,因为这场游戏的竞争实际上非常激烈。但截至目前,Dave和Felipe是目前的纪录保持者,世界纪录保持者。但在我们深入探讨这一切之前,让我们回到2010年,回到伟大的科幻作家Sam Hughes。2010年,Sam Hughes创作了Hatress,只是在他的博客上将其作为一种新奇事物发布。大约一个月后,
游戏发布后,一位名叫Diasuke的日本Slashdot评论员获得了30分。它在那里停留了数年之久。2015年,我在MIT OpenCourseWare上学习了一门关于通用游戏玩法的课程。
这是一门有趣的课程。你编写的程序不是为了下国际象棋或跳棋或玩四子棋,而是为了在给定规则的情况下玩任何游戏。你不仅得到了一个位置,还得到了与之相关的全部规则。我开始阅读QNTM,我开始关注Hatress,我给Felipe发了几条消息问他,我们能应用它吗?
到Hatress上,我们能否应用这个游戏玩家?Felipe非常明智地指出,我的通用游戏玩家几乎无法在四子棋中击败我,也无法在跳棋中击败我,而Hatress比几乎任何人类游戏都要难得多,是的,Felipe是对的,所以我们搁置了它。接下来发生的事情是,在2021年6月
一位日本计算俄罗斯方块专家,是的,有这样一个人,名叫New Jade,创造了一个新的世界纪录。我们认为超过30分可能真的不可能。
我相信这个最高分是基于他们运行的模拟。与俄罗斯方块不同,Hatress是完全确定性的。根据你的井,你总是得到最糟糕的方块。“井”是俄罗斯方块中方块掉落的地方的术语,即使在狭窄的井中,游戏状态也会比你想象的更快地膨胀。所以30分,清除了30行,感觉就像绝对的天花板。但随后New Jade达到了32分,所以显然他们错过了一些东西。Dave开始制作模拟器,我说,好吧。
我们正在做这个,我想,因为Dave已经开始制作模拟器了,我将无法轻轻地引导他放弃这个想法。这就是在我脑海中启动这个项目的原因。这就是它从我们讨论的不可行的想法(这是我们90%的对话,80%的对话)转变为我们正在做的想法的地方。
这对他们来说很正常,但在我们更深入地探讨他们如何应对这一挑战之前,你需要了解他们的一些情况。Dave和Felipe,他们是高中时代的朋友,但他们对这些挑战的态度并不随意。Dave是项目的发起者。Felipe是那个用实际问题来控制他们的人。但无论他们在做什么,他们总是在讨论想法。
Dave会给我发一些想法,比如,“我在考虑如何使用机器学习算法来解决游戏问题”。我会说,“Dave,这很不切实际。我们如何使你的想法更实际?因为我喜欢它的核心,对吧?我真的很想,
也许我们无法解决每一个游戏。也许我们可以专注于一个游戏。我们将缩小范围。我们将改进它。我们将讨论它。我们将想出一个实际的方法。这通常是谈话结束的地方,对吧?我会说,“是的,我们可以永远预测所有股票市场。但是,你知道,你也许可以专注于预测一只股票,你可以使用所有这些其他方差因素来计算出来。我读了一篇好论文。也许你可以看看。”
然后如果Dave真的喜欢这个想法,两天后到一周后,他会出现并说,“我为此写了一个Mathematica脚本。这是我从中得到的数据。这是不起作用的部分。我没有使用数据库,因为我不相信那些。所有数据现在都存储在我的硬盘上的文本文件中。它充满了这些。”我会说,“Dave,我在这里给了你四个实际的想法。你为什么这样做?”所以老实说,大部分这些东西都是通过Discord进行的对话片段,对吧?就像Dave给我发了一条消息,说类似于,
我刚刚测试了算法排序器,我得到了这些结果。我说了一些尖锐的话,比如,“好吧,Dave,这些结果并没有什么意义。我们能从中学到什么?”他说,“好吧,让我打开Mathematica。我做一个图表。”我会看看图表并对其进行更多评论。我们会就此进行讨论,对吧?随着我们的时间安排,谈话会在一天中断断续续地进行。我会说,“好吧,我得去做饭了”,然后我去做饭。我会回来,Dave会在我的Discord上发布了。
在我的Discord上发布了五段话,我去读它们,我做了一些评论,Dave去游泳了,因为他正在为铁人三项做准备,我想你当时正在为铁人三项做准备,所以他说,“我刚从游泳8000米回来,让我发表一些想法。”“8000米?来吧,Dave,你神奇的运动数字对我来说毫无意义。”我做了很多骑自行车和游泳,所以很多时候我会在离开之前查看大量数据
然后当我骑自行车去河边或在河里的时候,我没有其他事情可想可做。所以我只是在脑子里反复思考这些数据。当我回来的时候,我会像大炮发射炮弹一样给Felipe发消息。所以他会受到几千字的弹幕的冲击,这些弹幕基于我当时正在思考的内容。任何关于VS Code的实际内容的参考都将是Felipe。
他强迫我使用Git和版本控制以及备份副本。我仍然没有完全原谅他。我的意思是,我们只因为没有保留任何备份和没有使用版本控制而丢失了大部分项目,所以你没有。直到我们这样做,我才设法让你到达那里。是的,这是非常真实的。
所以这是Dave和Felipe做的事情。他们一起参与项目。他们互相发送消息。然后在晚上,根据他们是否忙碌,他们可能会进行Discord语音通话。他们可能会运行VS Code Live Share。他们可能会进行一些编码。有时项目会取得进展。有时不会。有时最后,他们会写下他们的工作,在博客上分享。大多数时候,他们不会这样做。
但是,是的,Hatress一直是这些搁置话题之一。它会时不时地出现。Dave想解决它。Felipe指出它似乎遥不可及。因此,其他项目将获得优先级。但与许多搁置的想法一样,Hatress正悄悄地准备占据中心位置。因为他们不知道,一旦他们真正致力于击败这个非常讨厌的游戏,就再也回不去了。
因为当一个项目吸引你的兴趣时,尤其是在你们一群人的情况下,你们在无数个晚上和周末投入的努力可能会令人惊讶。它可以累积起来。所以,是的,New Jade创造了一个新的纪录,32分。Dave认为也许他们可以击败它。但首先他们需要构建一个模拟器。所以……
我们没有构建一个模拟器,我们总共构建了六个。从Mathematica开始,只是为了得到一些有效的东西,并了解事情有多慢。在Mathematica中,计算单个移动大约需要十分之一秒。Hatris中有很多计算,因为Hatris算法不会随机给你一个方块。它会查看井并计算根据极小极大算法哪个方块将是最糟糕的。
它需要一点时间是有道理的。我们当前的运行速度大约快200,000倍。因此,目前我们每个移动每个核心大约运行5微秒。所以即使在单线程上,这仍然是成千上万倍的改进。最基本的模拟器包括尝试方块可以去的每个可能位置,并从那里进行极小极大算法。在Mathematica中它并不快。所以
Felipe最终说服我做的是将其从Mathematica重写到Python,这几乎没有快多少,然后从Python重写到Rust。我会把这归咎于Felipe。我会把这归咎于你,因为我认为如果你没有把我拖进去,我不会接触Rust的。我确实为此方法负责。作为背景,我们之前没有使用过这种语言的经验。
我们做了六个AOC问题,我们的第七件事是重新实现谷歌的AlphaZero算法,包括从头开始的GPU神经网络。这是一个不小的飞跃。是的,AlphaZero,谷歌的DeepMind项目,这是他们的灵感来源。我的意思是,有一篇发表的论文包含公式等内容,所以对他们两人来说,重新实现所有这些内容有多难?
当他提到AlphaZero时,我玩了很多围棋,我看到了AlphaGo能做什么。所以我当时想,“哦,实际上,我认为这很有潜力。让我们讨论一下这样做的实际意义。”在那时,我知道这是我们将要做的想法,对吧?我们采用了我们理解的部分并实现了它们。关键要素是我们理解的部分。因为在某些时候,我记得我们正在讨论这个问题,然后出现了狄利克雷噪声的话题。我说,“Dave,我不知道那是什么。”Dave看着我说,“我也不知道那是什么。”
我说,“那么我们使用它吗?”我说,“我认为我们实际上并没有在任何地方实现它。它重要吗?”然后我们看看,我们说,“看起来它可能很重要。是的,但问题是,当我们实际实现它时,我们的结果变得更糟了,因为它们是在没有狄利克雷噪声的情况下训练的。”是的,因为我们不太了解循环器。我们这样做是因为我们没有理解论文。
即使他们没有完全掌握所有细节,他们也让AlphaZero方法运行起来。然后他们可以运行它,他们可以查看日志,他们可以查看它是否真的在学习任何东西并变得更好。所以你会看到一个文本文件。这是一个文本文件,因为Felipe从不觉得要写一个合适的日志。所以我做了。当你处于AlphaZero阶段时,你会看到游戏打印输出。
并且每次玩新游戏时,你都会得到一个数字列表,其中每个数字列表都表示以二进制形式编写的井。你会得到这些日志,每个井都会有一个分数(如果它得到任何行的话)。它将包含网络的启发式估计。它将包含一些其他元数据,例如它有多少子节点等等。
你会看到成千上万个这样的日志。我们每隔几秒钟就会得到一个,我们会使用Ctrl+F手动查找高分日志。当然,大多数日志的分数并不高。我非常喜欢与Dave进行语音通话的记忆,实际上,只是查看已经玩过的游戏,并试图找出是否存在共性或特征以及网络在尝试思考什么。
如果我记得没错的话,你制作了一个小程序,让我们在数学中查看游戏,它会点击查看,好吧,这里发生了什么?它为什么这样做?然后查看一个动作,就像,“这个动作很糟糕。它为什么这样做?为什么网络无法弄清楚它不应该这样做?”我们这样做的时候可能凌晨一点左右。但是,是的,这种AlphaZero方法存在一个问题。我们需要的是一个数据中心数量的TPU连接到一堆硬盘和全天候运行的计算机,以便我们可以更改元参数并测试事物。
所以这是一个很大的因素。我们的实现是两个阅读并半理解了一篇论文然后跳过了显然无关紧要的模糊细节的人的实现,结果这些细节可能有点重要。它们可能很重要。我认为我们只是完全没有掌握为了使这个项目有效需要发生的事情的范围。
解决方案。所以我们有点像卡在这个循环中:调整一个东西,它变得更糟了,但它变得更糟是因为我们调整了这个东西,还是因为它处于局部最小值而我们不知道如何修复它?然后我们无法迭代它,因为我们没有硬件来正确地迭代它。所以这就像你有一种感觉,你知道你正在朝着错误的方向解决问题,是的,你可以继续调整事情,但没有什么能让你摆脱这个困境。我认为这是这种情绪。
想象一下爬山,然后意识到你一直在努力攀登的面前的山峰不是山顶,而只是一个假山峰。真正的山峰在它后面。那就是他们所在的地方。资源越来越少,每一天都感觉像是一个警告。这个问题比他们想象的要大得多。你会遇到一些模糊的错误,比如一些Rust回溯错误,这是一个段错误。你在某个地方遇到了溢出。你会想,“这甚至是什么意思?为什么会出现段错误?”
我们只是看看它,要么修复它,要么说,“实际上,我们不再使用这个库了。没关系。我们不需要使用稀疏矩阵。这无论如何都不会有帮助。”但是,是的,也有希望的时刻。我自己玩Hatress的个人最高纪录是10分。所以当它第一次击败我的那一刻,那是令人兴奋的。有一段时间,它从个位数分数缓慢上升到22分。这确实感觉它正在变得更好。
然后它就停滞了。无论我们做什么,我们都无法改进它。但在那里有一些我们非常开心的时刻。在那里有一些我们找到加速模拟器并获得每秒更多游戏的方法的时刻。我并不是说一切都糟。只是糟糕的部分是我们记得的部分,因为从时间上来说,糟糕的部分是那段时间的大部分。
几个月来,他们一直在努力解决这个问题,工作到深夜,交换代码。但是现在,在突破的边缘,他们只是感到非常怀疑。这是一种在任何给定项目中都会发生的时刻。你到达了重定向点,对吧?你就像,“我仍然对这个背后的核心思想感兴趣。我仍然想解决这个问题。但无论是什么,我正在做的事情都没有奏效,无论出于什么原因。”而且……
老实说,我可以假装这是一个经过衡量的决定,你坐下来列出利弊,但实际上是“我对这个有多恼火?”以及“我还想继续与这组特定问题作斗争吗?”我认为我们进行了一次谈话,我基本上说,“我认为按照我们目前的规模,除非我们要向谷歌支付大量资金,否则我们无法做到这一点。我们申请TPU赠款是在什么时候?因为我们查看了这一点,我们查看了,如果我们想正确地做到这一点,它会在云端花费我们多少成本?答案是它将需要大约一个月的时间,一千个TPU全天候运行。”
所以我们申请了一笔赠款,以获得一个月的时间,一千个TPU全天候运行,我们获得了赠款。我们从未使用过它。想想《威尼斯商人》,一磅肉不包括任何血。这或多或少是我们在这里遇到的情况,我们可以免费使用数千个TPU大约一个月。我们无法免费使用协调这些TPU所需的任何CPU。
或者硬盘。当然,TPU仍然在进行大部分计算,绝大部分。但是,即使是辅助控制和日志记录等等的成本也远远超出了我们的预算。我们的预算为0美元,很明显。
所以他们感到沮丧,意识到他们一直在努力的神经网络方法超出了他们能够承受的计算资源,他们准备放弃了。但随后NewJade出现在GitHub上,并开始改变局面。他发布了一个gist,其中包含他用日语写的整个方法。谷歌翻译和图片足以弄清楚发生了什么。
我们在这时已经研究Hatress相当长一段时间了。所以解释中没有任何东西需要向我们解释,例如,“游戏是如何运作的?我正在使用什么机制?”我们主要对总体情况感兴趣,例如,“你在看什么?”他实际上制作了一些非常好的图形,这些图形真正捕捉了他正在查看的事物的形状的概念。这非常有帮助。这是一个非常简洁的解释。它没有深入到许多技术实现细节中,这正是我们所需要的。
所以这是他做得非常好的工作,即使是用我们不懂的日语。我们想,“与我们正在尝试做的事情相比,这些都不难。我敢打赌我们可以想出一个更好的启发式方法。我们擅长寻找问题。”
我认为这个想法超越了其他所有想法。我们想,“如果我们开始考虑这个问题,启发式方法是什么样的?我们应该考虑New Jade没有考虑过的事情,因为当然,他是一位计算俄罗斯方块专家,他研究这个问题的时间比我们长,并提出了一个更好的解决方案。但显然,我们可以做到。我们可以做得更好。我们可以想出一个更好的主意。我认为这就是事情的开始。对吧,Dave?是的。我们决定好艺术家借鉴,伟大的艺术家窃取。这正是我们所做的。”
然后,当他们重新实现、窃取或无论你想称之为什么是,New Jade开始发布新的高分。我认为Dave给我发了一条消息,说类似于,“新的纪录是多少,66分?”我说,“来吧,不可能,Dave。”
最后的纪录是45分,我们推测上限大约是50分,也许是60分。因为当然,每次有新的纪录时,对吧,我们会将上限提高大约10分。我说,“不可能人为地做到这一点。”这时,我说了一些类似于“名言最后一句话”的话。“那么最高分可能在100分左右。我认为这是有道理的。”
所以我们说,“好吧,让我们首先尝试重现这项工作,看看我们能否获得类似的结果,然后我们可以开始调整启发式方法,使其更适合我们的理解。我们将带来的东西是,我们将进行更多的数据分析,我们将更好地了解启发式方法或我们可以添加到其中的内容。”从那时起,我们花了大约五个月的时间,因为我们在重新实现中犯了两个关键性错误,每个错误都让我们损失了数月的运行时间。
重新实现New Jade的解决方案并不容易,特别是如果你没有计算俄罗斯方块博士学位或不熟悉计算游戏搜索。想象一下同时探索迷宫的多个路径。你通过迷宫走10条不同的路,当其中一些路走到尽头或看起来没有希望时,你可以从那些看起来有希望的路中分叉出来,这样你总是有你最好的10条,你最好的N条路径并行向前穿过游戏空间。
你放弃其余的路径,你专注于这些获胜的路径,但你总是同时穿过多条路径。你一次穿过多少条路径,这就是你的光束宽度。这就是光束搜索的原理。但是模拟所有这些都需要大量的计算能力。与这些事情的对话总是这样的。“这需要多长时间?”“我不知道,一天?”“当然,一天似乎很合理。”然后一天过去了。我说,“它进行到哪里了?”“好吧,它完成了第一束。”“好的”,所以两周后,
我们非常希望它能在不到一个月的时间内运行,然后它比我们预期的要慢得多。所以每次运行都需要一个月的时间,这是一个月的时间来查看日志,查看分数略有增加,并说,“哦,上帝,我希望我们在这部分代码中没有错误,因为如果我们有错误,我们将进行两周的时间,然后必须重新开始。”我们正在查看日志文件,我们正在讨论正在发生的事情。显然,这只是刷新日志文件和来回交谈,并说,“好吧,最新的高分是这个。”
我记得我会在Discord上签署一个警察。我会看到Dave发来的消息,内容类似于,“当前分数是30分。”然后一小时后发来的消息,“当前分数是32分。”我们会结束工作会议,对吧?我会重新连接到控制台查看日志。我会向服务器上的其他人发送回显消息,说,“Dave,你还在查看日志吗?”我会收到一条回复消息,说,“是的,好的。”
所以你确实爬到了32分。那么在那时纪录是多少?此时的纪录是多少?此时的纪录是66分。我们最终通过这些搜索中最好的一次搜索达到了53分,这仍然非常好。它是世界第二好的。它比除New Jade之外的任何人都好,但还不够好。
所以Felipe想到了一个主意,而不是使用此时已经使用了五六年之久的单台台式电脑,让我们实际购买一些计算机时间,并在一天内完成它。
事情变得严重了。他们不是在家运行这个程序,这只是一件有趣的事情,他们即将在云端租用一台72核的机器,而且时间在流逝。这是在AWS上,如果出现任何问题,这笔钱将永远消失,只留下一个未完成的光束搜索。现在这个谜题不仅仅关乎自豪感,也不仅仅关乎探索,他们的钱包现在也岌岌可危了。
是的,所以我做了一些DevOps工作,但AWS是我最熟悉的云提供商。所以我当时想,“AWS似乎是合理的选择。”所以我出去定价并查看了各种解决方案。我说,“好吧,我们正在寻找的是大量线程。我忘记了实例类型。这个有很多线程。如果我们要运行24小时,这似乎是完成这个项目需要支付的合理价格。”
此时我们有一个闪亮的新启发式方法。我们已经向其中添加了我们自己的新的神奇字段,这将使一切变得更好。我们已经获得了53分,所以我们知道这是可以做到的。所以我认为我们所做的数学计算是:四个核心需要一个月的时间,将一个月的时间除以,我们需要这么多核心。它就像,我忘了有多少个,几百个。你还记得吗,Dave?我认为是72个左右。我认为是72个。是的。所以我们说72个核心,更多的RAM。我们可以让它快速运行。
What if a simple game became a gateway to computational breakthroughs? David Freiberg and Felipe set out on a journey to conquer Hatetris, a notoriously difficult JavaScript game. Their interest ignited when a new world record was set, showing that surpassing the game's high score was possible. Their journey was full of challenges, from building an emulator in different programming languages to tackling complex algorithms. They pushed the boundaries of what's possible but the story didn't end there. Collaborating with fellow enthusiasts, including a Japanese Tetris expert, led to further breakthroughs. By sharing insights and building on each other's work, they set a records after records. Their story highlights the power of curiosity, collaboration, and the joy of discovery. Episode Page Support The Show Subscribe To The Podcast Join The Newsletter </context> <raw_text>0 我们做了一些草图计算,得出了一个预算。然后我说,戴夫,这就是它要花多少钱。戴夫说,好吧,我们可以这么做。这感觉很合理。永远不要相信我的预算决定。我总是,每一次都严重低估了做这件事的成本。所以我们把它设置好了。我设置了AWS账户。这些都不是什么挑战,因为它们都是一键式设置,设置实例。我们通过SSH进入实例,复制你的代码,因为我们现在使用版本控制,所以我们可以克隆这些东西。戴夫,不用谢。
安装依赖项,让一切运行起来,然后启动它,对吧?老实说,它速度飞快。你会想,哇,这速度很快。正如我们预测的那样。
到午夜时分,他们都盯着日志文件,希望每个新条目都能让他们超过66分,每一束光都能取得进展,并且有人会打破世界纪录。然后问题开始出现。我们实际上超过了66分。然后我们开始意识到,等等,如果游戏持续时间比我们预测的更长,我们将不得不支付比我们预测的更多的费用。这是在48小时标记处。这是预期运行时间的两倍,但他们的代码仍然必须完成。
他们必须让它运行,因为它已经清除了66行。但是,直到他们输掉游戏,直到他们完成搜索,程序才不会最终完成。它不会打印分数。所以你会打破新的世界纪录,但你却看不到。你无法将其记录为世界纪录。你只知道如果你的程序没有错误,它就存在。所以你的程序做得越好,你坐在那里看着它,你的账单就越糟糕。
然后就是阿姆达尔定律。因为我们忘记了多线程只适用于实际的光束。当你保存所有内容时,当你将一个时间步长的进度保存到另一个时间步长时,文件读取和写入是单线程的。这根本没有加速。当我们只有四个核心时,这是一小部分时间。但是当我们有70个核心时,这现在是大部分时间。
因此,我们的云计算预算追溯性地增加了,直到游戏在午夜前结束。我们得到了86分。比纪录提高了20分。巨大的,巨大的,巨大的里程碑。
这是一个星期五晚上,对吧?我妻子说:“我们要做些什么吗?”我说:“我必须盯着这个屏幕看,看看我们是否能打破纪录。”她说:“好吧,我们明天有计划。你还记得吗?”我说:“是的,这很好。戴夫和我最晚会在凌晨2点之前完成,对吧?”所以现在是午夜。我们打破了世界纪录。我们可以看到世界纪录,对吧?我们非常有信心没有错误。是的。所以问题是,在游戏结束时,我们现在有一个位置。
而这个位置是获胜游戏的最终位置。这不是整个游戏。我们需要整个游戏过程中每一块所经过的每一个位置。为此,我们参考了前面做的所有保存时间步长,这也是一个单线程过程,这也是我们没有预料到的。这甚至比向前走更慢。我们认为最多需要一个小时,
一个小时后,它才刚刚开始。我们做了一些粗略的计算,我们预测它会在我们早上醒来之前完成。它没有。当我们早上醒来时,事实证明我们的粗略计算是基于最后较小的时间步长,因为光束正在耗尽选项。每个时间步长存储的井的数量较少。当我们醒来时,它还需要12个小时才能完成。它可能会这样做。我们看着我们的预算,就像……
我想我们现在不能停止它,对吧?因为它都消失了,对吧?如果你无法在停止时把它组合起来?正确。如果我们在它完成之前停止,那么整个运行就没有意义。我们需要每个井的每个位置,否则我们就无法到达那里。顺便说一句,这是软件设计的巅峰之作,对吧?你应该始终设计你的流程,以便如果在任何时候停止它们都会破坏你所有的工作,这就是你应该设计软件的方式。没有备份。我认为这会让你保持警惕。
但最终我们得到了纪录。是86分。我们立即下载了它。我们将文件从AWS转移出去。我们停止了流向AWS的资金。但他们还没完成。他们的钱包正在休息,但模拟器会为每个移动输出其内部状态,这与高分排行榜所需的格式不匹配。这需要逐个移动的重播。我们拿到了我们的数字列表……
有一个Mathematica脚本可以将其转换为图片列表。每张图片都代表了棋子将要移动到哪里。然后我们在屏幕共享上坐了一个小时,手动按下箭头键将棋子移动到适当的位置。
我们发誓要在下一个纪录之前自动化它,但我们没有,下一个纪录花了更长时间。幸运的是,Hatress有一个撤销按钮,所以可以修复错误。它还有一个重播代码按钮,你可以在其中输入游戏的重播代码。这比手动操作要好得多。因为它是一个确定性的重播代码,所以你只需要知道移动是什么就可以生成它。我们只是从未编写过它的脚本,所以我们想,这需要多长时间?最后,虽然……
我们得到了它。此时,我们找到了New Jade。我们在一个计算四叠方Discord服务器上找到了他,我们能够通过这种方式与他取得联系。他向我们表示祝贺。他顺便提到了他把目光放在了一种新的方法上,但这种方法现在将暂时搁置。
他们在Hatress网站上发布了他们86分的全球纪录。这是一个巨大的飞跃,他们终于获得了世界纪录。他们还在推特上@Sam Hughes分享了这个消息。是的,他表示祝贺。他证实了这个纪录是合法的。他对我们显然付出的努力印象非常深刻,因为我们当时提到我们花了11个月才做到这一点。是的,从那时起,我们写了一篇博客文章
在这个时候,任何理性的人都会停止思考这个问题,你已经解决了这个问题,并且获得了世界纪录。当然,当你谈论将小型工程团队的资源基本上投入到2010年代排行榜上的一个不知名游戏中时,“理性”是一个有趣的词。
理性并不是重点。因此,他们实际上并没有继续前进。事实上,他们计划就他们所做的所有工作做一个演讲。所以我们被邀请去做DC Russ的演讲。我们花了大约三周时间来计划这次演讲并制作幻灯片。我们的演讲一开始太长了。我们把它剪短了。并且有一整段对话是,我们的观众是否想看我制作的这个漂亮的图表?也许不是。也许我们只是把它剪掉。
所有这段时间,我们都在谈论这次演讲和我们的项目。你回顾这个项目,看看你的代码库,你会想,好吧,我们可以做得更好一点。好吧,我们可以进行调整。现在我们正在查看它,因为戴夫说,如果我们要做这个演讲,那么开源我们的代码以便人们可以查看我们的错误是有意义的。我说,好吧,我不希望在没有自述文件的情况下这样做,戴夫说,我们可能应该清理一下这里可怕的意大利面条式代码,我们有一个巨大的方法来做所有事情。我们可以添加一些单元测试,也许,只是为了让人们不认为我们从不编写单元测试。我们从不编写单元测试。
在思考这一切的同时,沉浸在他们的Hatetris工作中,戴夫想到了一个新的启发式方法,你只需要多向前看一点。看看你是否可以在接下来的几步中清除一行。
这为你关于你是否处于良好状态的启发式方法提供了更多依据。我相信他当时称之为“手中之鸟”启发式方法。我们进行了长时间的讨论,如果这被发表,我们可以用他的名字命名它,因为这很有意义。然后两个小时后我收到一条消息说,我把这个想法解释给了我父亲。他说,哦,这是一个静态超前搜索。是的,这在国际象棋引擎中一直被使用。我说,好吧,这很合适。
你父亲是国际象棋引擎专家吗?那是……他是一个程序员、业余数学家和世界上最著名的PetriNet爱好者。我没有说世界上最著名的PetriNet专家。有一些人比他更了解。但是,没有人比他更热爱PetriNet了。我从小就听着关于如果你正在训练遗传算法,你必须记住要包含突变,否则你会陷入局部最大值之类的警示故事。即使你没有尝试,你也会通过渗透学习很多东西。
所以我仍然经常打电话给他,谈论这类事情。他还参加了我们的Rusty C演讲。他对新的持续编程项目总是很感兴趣。
太疯狂了。我觉得很有趣,你可以说,哦,是的,然后我想起了我12岁时我父亲告诉我的话,比如在你开始之前考虑一下光束搜索。是的,但这实际上是他12岁时会给我的建议。多年来,我们一起完成了项目欧拉的问题。我们都在项目欧拉求解者的前0.1%之列。菲利普也可以证明这一点。事实上,我和他一起解决了整个网站上最难的问题。我们断断续续地花了大约一年的时间。
但接下来发生的事情可能和解决一个难题一样令人兴奋,或者至少一样令人惊讶。这基本上是第一个,也许也是唯一一个真正举起拳头庆祝的时刻,你简直不敢相信事情进展得如此顺利。我们巨大的光束搜索,运行需要几天时间,宽度为2500万。所以我们正在并行查看2500万个位置。
所以他们测试了他们的新启发式方法。他们尝试使用10万的宽度。这比他们大型AWS运行并行游戏少250倍。但他们有这个更好的启发式方法,对吧?所以他们正在搜索这个可能的博弈树,但他们正在朝这些更长的运行方向前进。他们正在模拟更好的游戏。所以即使游戏少250倍,他们也得到了82分,几乎是他们的世界纪录。
需要明确的是,我不相信这个数字。戴夫告诉我这个数字。我说,戴夫,我们某个地方有错误。不可能是对的。不可能这个启发式方法这么快就变得这么好。我不同意,直到我们运行了一百万次。对于一百万次,它给了我们148分。现在,我也相信模拟器中某个地方有错误。因为在Rust DC之后,我们进行了一系列优化以使其更快。我相信我们所做的一些优化
导致出现错误,而该错误导致游戏更容易。我们早期实现中确实存在一个错误,我们有一段时间没有发现它,而且它一直在给我们提供错误的游戏,这并没有帮助。
所以,再一次,他们需要把游戏玩法组合起来。他们需要验证纪录。我们接通了电话。我们说,我们真的应该上次就写那个脚本。我们为什么没有这样做?戴夫非常明智地说,因为我们认为我们完成了,我们不会做任何额外的工作,并且永远不会再访问这个项目。我说,是的,好吧,让我们确保下次编写它。所以你只是得到了一个屏幕截图。你只是得到了一张图片,显示了棋子必须移动到哪里,也就是井的形状。
但它没有显示如何将棋子移动到那里。有很多需要复杂的旋转才能通过狭窄的角落等等。R脚本没有包含任何这些内容,因为如果我们这样做,我们将编写一个自动重播代码生成器,在这之后,我们实际上坐下来做了,因为这太多了。我们花了大约两个小时才真正输入了整个内容。
请注意,每次我们移动时,我都想,这显然是我们会发现错误的地方,对吧?就像,我们每隔几分钟就会开玩笑。就像,很明显,这个移动是非法的,这不会奏效。所以旧纪录是86分,这个是148分,这是四叠方历史上最大的增幅,无论是绝对值还是比例。没有人会超过这个。这超出了我们对这个游戏最大可能分数的任何预测。
结束了。不可能。菲利普,一周后发生了什么?有人得到了更高的分数。而这个责任在我们身上。戴夫有一个朋友,他有时会和他一起参加Advent of Code。戴夫没有这么说,但他经常出现在Advent of Code排行榜上,因为他非常擅长这种类型的编程。我责怪他的Mathematica技能和他在午夜解决问题的愿望。戴夫正在和他的朋友聊天。
你给他看了Rusty C的演讲了吗?对吗?是的。他独立地看到了Rusty C的演讲,然后给我发了消息。是的。所以这是Tim。
他们正在谈话,他说,嘿,我看到了你们的Rusty C演讲,我实际上知道如何很好地编写Rust。所以我制作了自己的模拟器版本。然后在戴夫告诉他“手中之鸟”启发式方法后,他得到了157分,因为我们就是这样的人。感觉你父亲应该为此提出建议。如果你参加的是编程竞赛,不要告诉排行榜上的其他人你的技巧。我
我不能认可这一点,因为每次我们一起工作在一个项目上,并且我们正在做一些非常困难的事情,并且我们与同一领域的某人交谈时,他们都非常乐意分享他们正在使用的任何东西,其细节程度我认为是实际的工作。就像,这是我正在做的。这就是我正在做的事情。这就是我在想什么。如果你想让我看看你的代码,请告诉我。所以我们采取同样的态度。如果有人问我们在做什么,我们会尽可能详细地告诉他们,因为我们是
是的,这是一场竞争,但目标不是获胜。目标是在其核心上击败Hatetris,对吧?就像,打破游戏的意志,因为这就是我们都在追求的。戴夫和我现在花了一周时间坐在各种Discord聊天室里,因为170分被发布了。
然后232分被发布了。我们想,我们真的需要想出一个更好的方法来做这件事。这些都是你的朋友吗?都是Tim。是的。Tim比我们有更好的电脑。我会给他那部分。他的Rust也比我们好。他问戴夫,嘿,我看到你们做了什么?使用了优先级队列,但你不需要这样做。你可以这样做。我们说,哦。
是的,我想我们可以那样做。那会快得多。是的。谢谢你,Tim。所以他正在调整他的启发式方法。他正在改变它。他正在发布更多分数。戴夫和我正在生气,这不是正确的词,但我们肯定坐在Zoom聊天室里。我们想,好吧,我们怎么做才能……我们不能在技术技能或硬件方面击败他们。我们需要做一些事情来改变局面。我们什么也没有。我们的谈话就像也许我们可以做一个分析并做一件事。
那么,你还记得是星期几吗?Tin发布了232分,我们想,哦,天哪,好吧,我不知道我们能否突破200分大关。12小时后,New Jade出现在Twitter上,发布了289分。我们和他谈过话,我们分享了我们的启发式方法,并且……
他做了一些全新的事情,对吧?他使用了一套全新的技术。但基本上他发布了,好吧,伙计们,就是这样。这是最终的分数。我们说,是的,好吧,我想我们完成了Hatetris的工作。所以我们从神经网络开始,然后为了New Jade的启发式方法而放弃了它。Tim也使用了启发式方法。他只是比我们更擅长它。在我们这样做的时候,New Jade正忙着放弃他的启发式方法,转而采用神经网络方法。但神经网络方法非常不同。
所以AlphaZero是由谷歌设计的。它是由拥有数百万美元硬件的人设计的。还有一种客观上更好的国际象棋神经网络学习算法,它是由一位日本将棋爱好者开发的,因为将棋的资源远不及国际象棋和围棋。
所以这叫做NNUE。它使用稀疏神经网络来显著加快你的有效计算量。如果你有一个巨大的神经网络,但该神经网络的99%输入为零,那么你的网络的运行速度实际上比其他情况快100倍。他用它制作了一个创纪录的将棋程序。
而将棋程序的名字直接来自动漫。它被称为创世纪终结TNK进化涡轮型D。这是程序的实际名称。我们从未听说过它。这出现在2018年。我们从未听说过这是一种可能性。所以是的,NewJ为该纪录记录了这种方法,这就是戴夫和菲利普了解它的方式。他将戴维的“手中之鸟”策略与他的新神经网络方法结合起来。
所有这些都导致了第一个循环的发现。我们很快就会探索循环,但是通过将Nujak的见解重新整合到他们的代码中,戴维和菲利普很快就获得了更高的纪录,366分,从他手中夺回了纪录。大约在这个时候,我给他们发消息,询问他们是否可以做一个播客节目。所以,就像准备Rusty C演讲让我们再次谈论这个问题一样,
当你给我发消息时,这也让我们再次谈论这个问题。所以我们开始寻找,不一定是新的方法,而是一种分析我们已经拥有数据的新的方法。我们实际上有一个所谓的循环图。现在,理论上,如果你可以在Hatetris中拥有一个位置,然后回到同一个位置,你可以永远运行下去。为了防止这种情况,
Hatetris算法有一个内置的循环防止规则,如果它看到你将要到达你之前见过的井,它会给你一些其他的棋子,这样你就无法到达那里。New Jade的289分纪录也是第一个发现循环的纪录。不久之后,Tim发现了自己的循环,不久之后我们也发现了一些循环。这些是移动……
如果那个循环防止规则不存在,将会获得无限的分数。你可以永远玩下去。所以我们过去几周一直在问自己,并且一直在调查的问题是,有多少个循环?这些循环的结构是什么?什么样的井会让你进入循环?因为显然,如果你能弄清楚这一点,你就能很好地理解整个游戏。
这将Hatetris从仅仅是一个机器学习、游戏搜索问题转变为戴维和菲利普非常擅长的事情:模式分析。你只能走每个循环一次,但如果多个循环从同一个点开始,如果你能强迫Hatetris让你进入第二个循环,游戏就会改变。
看到这些想法相互激发,真是令人兴奋。分享会导致学习,每个人都在从彼此的见解中成长。每个发表的想法都建立在最后一个想法之上。我们目前的方法,保持世界纪录,是基于New Jade的方法。New Jade的方法是基于Tim的方法。Tim的方法又是基于我们的方法。我们的方法又是基于New Jade的方法。New Jade在我们的参与之初就获得了32分的方法
他实际上并没有提出为Hatetris使用光束搜索的想法。那是另一位名叫3Pipes的程序员。3Pipes在2019年,为了一个课堂项目,决定编写一个Hatetris求解器。他尝试了一下。他从原始JavaScript中提取了Hatetris模拟器,而不是自己编写,这是一种非常有趣的方法。他制作了一个光束搜索实现。它并没有走得很远。他得到了16分或17分。
他为他的课程完成了它。他再也没有碰过它。他继续他的生活。但他写下了他所做的事情,并将其发布到网上。New Jade在2021年找到了它。这就是给他这个想法的原因
开始光束搜索,这导致了他的世界纪录,并且让这一切都开始了。这并不是关于华丽的千字博客文章。这只是关于提出一些想法,实现这个想法,然后告诉人们它是否有效。Hatetris在某种意义上并不重要。这个纪录完全无关紧要。除了我们之外,没有人关心。
保持知识的持续链条的概念,阅读其他人所做的事情,然后写下你所做的不同之处和相同之处以及它是否有效,并将它传递给下一个人,我认为这是普遍存在的。
戴维和菲利普令人印象深刻。他们如何解决一个特定的游戏问题,突破界限,并做出独特的发现,这令人惊叹。然而,他们想要明确的是,他们实际上并没有特别资格承担这样的任务。归根结底,如果你正在从事一个项目,而你不是该项目的专家……
某个地方有一个庞大的社区,或者某个地方有一个小型社区,他们可能之前就考虑过这个问题。他们可能之前在这个问题上投入了时间和精力。他们很高兴有人关心。所以,如果你出现并给他们发一条友好的消息,你说,嘿,我看到了你关于……比如说Trackmania的帖子。我看到你在Trackmania上尝试过这个。我们正在尝试类似的事情。我对你的方法很感兴趣。他们会回复你,即使他们三年没有接触过这个项目,也会尽可能多地告诉你关于它的信息。
这些类型的跨社区的人际关系与戴夫刚刚提出的想法有关。但我认为它更基本,事实上,关心项目的人乐于分享他们的知识。如果你只是去寻找他们,他们会毫无怨言地自由而快乐地与你分享。
所以,是的,这就是故事。这就是两个无法理解AlphaZero论文但认为,嘿,我们将无论如何实现它,到达前沿,到达游戏搜索树的煤矿,或者这个领域被称为什么的两个朋友的故事。他们一直在努力,即使菲利普偶尔不得不向他的妻子报到。
哦,她纵容我,我正在和戴夫一起做一个项目,因为她不想在餐桌上再听到关于Hatetris的任何事情。所以往往是很多,你在和戴夫一起做事情吗?是的。好的。我会让你去做。我不需要细节。戴夫,在你那边,我不知道你的情况如何。这些项目是否曾经导致任何关系冲突?不,我不能说有。我没有。
我希望它会在某个时候发生,因为我看不到自己很快会在凌晨三点放弃这些项目。但我会在遇到它的时候再过那座桥。戴维,你在哪里工作?我错过了。哦,目前没有。我正在找工作。是的,我最近面试的公司,我在两个月内进行了五次面试。如果你进行了五次面试,包括一次你进行完整场地参观,这是一个三小时的过程,以及所有的一切,
你真的会燃起希望,即使你告诉自己不要燃起希望。他们说,基本上,在一周内,我们会以某种方式回复你最终的报价。那是三周前的事了。我已经给他们回邮件了,但从未收到任何回复。这就是为什么我们做这种事情来分散我们的注意力。至少这就是我这么做的原因。我不能代表菲利普说话。在超过366分之后,Hatetris为戴维和菲利普提供了一个难得的逃脱机会。
这是一个可以建立联系、进行实验和在深夜交换故事的地方。我觉得这里面还有更深层次的东西。我们追逐这些看似微不足道的难题的原因,我曾经这样做过,也许没有那么远。但我们能够将数月的时间投入到副项目中,投入到2010年的JavaScript游戏中,
如果一个简单的游戏成为通往计算突破的途径呢?David Freiberg和Felipe踏上了征服Hatetris(一款臭名昭著的困难的JavaScript游戏)的旅程。当新的世界纪录诞生时,他们的兴趣被点燃了,这表明超越游戏的高分是可能的。他们的旅程充满了挑战,从用不同的编程语言构建模拟器到解决复杂的算法。他们突破了可能的界限,但故事并没有就此结束。与其他爱好者(包括一位日本俄罗斯方块专家)合作,带来了进一步的突破。通过分享见解并在彼此的工作基础上,他们一次又一次地创造了纪录。他们的故事突出了好奇心、合作和发现的乐趣。剧集页面支持节目订阅播客加入通讯 </context> <raw_text>0 之所以如此,是因为在这个努力的过程中,存在着一些根本上的人性。这关乎好奇心和发现的乐趣,以及突破看似可能界限的刺激。有时,这仅仅是找个好借口在深夜打开Discord,与非常要好的朋友并肩攻克一些不可能完成的任务。
这就是节目内容。感谢Felipe和David。我希望你们的探索能够继续。采访结束后,我和他们一起待了一会儿,他们向我展示了他们一些关于循环的未发表作品。你知道,David向我展示了这些循环的Mathematica地图,它看起来像某种疯狂的地铁线路图,但是……
他们正在研究利用它的一些东西。一种开创性的新方法。我相信如果他们成功了,他们会把结果发布在他们的博客上。当你听到的时候,它可能已经上线了。所以请查看hallofimpossibledreams.org,看看他们最新的项目。有时是仇恨。有时是死去的互联网理论。有时是超人同人小说。他们总是有东西分享,总是有东西在做。在我与他们短暂相处的时间里,
我看到了他们的与众不同之处。他们两个人性格迥异,但却以一种让他们强于部分之和的方式结合在一起。如果你能听到这里,我不说让你成为这个播客的支持者就显得失职了。我知道外面有人正在做一个副项目,需要听到这两个人的故事。也许就是你。但故事可以很强大。
故事可以成为一些让你铭记于心并让你从别人的经验中学习的东西。这就是我在这里试图做的。如果你喜欢,就支持我,或者只是收听。这就是为什么我总是以这样一句话结尾:直到下次,非常感谢您的收听。 </raw_text>