Redian新闻
>
Redis 之父自曝用 AI 写代码,锐评:LLM 有望取代 99% 的程序员!

Redis 之父自曝用 AI 写代码,锐评:LLM 有望取代 99% 的程序员!

公众号新闻

推荐关注↓

转自:CSDN(ID:CSDNnews)

【导读新年伊始,在各位大佬进行年终总结之时,Redis 之父 antirez 也发布了他今年的第一篇博文:“2024 年初,聊聊 LLM 和编程”。不同于预想之中的盘点和回顾,这篇文章 antirez 以一位独立开发者的角度,分享了他这一年来对于 AI 的使用感受,并表示:“就我个人而言,我将继续广泛使用 LLM。”


2023 年对 AI 而言是特殊的一年,这毫无疑问。首先我声明一下,本文并非是对 LLM(大型语言模型)过去一年的回顾,而是以一位独立程序员的身份聊聊我对 AI 的见证。自 ChatGPT 问世以来,以及后来使用在本地运行的 LLM,我已将这项新技术广泛应用。从个人角度来说,我使用大模型一方面是为了提升编程速度,另一方面也是希望不再浪费精力在不值得努力的编程方面。

例如,我曾花了无数个小时搜索那些奇特却无趣的技术文档、曾被迫学习过于复杂的 API、曾编写过一些几个小时后就被丢弃的程序……这些都是我不想做的事情,尤其现在谷歌搜索引擎也已沦为垃圾信息的海洋,我得费心筛选才能找到一些有用的东西。

与此同时,我在编程方面当然不是新手。我可以在没有任何辅助工具的情况下编写代码,并且也经常这么做。但随着时间的推移,我开始越来越多地用 LLM 来编写高级代码,尤其是在 Python 中,在 C 语言中则较少。在对 LLM 频繁使用的过程中,我逐渐知道了什么情况该使用它们、什么情况使用它们只会拖慢速度。

除此之外,我还了解到,LLM 其实有点像维基百科和 YouTube 上的各种视频课程:对于本身就有意愿、有能力和有纪律的人,有了 LLM 的帮助几乎如虎添翼;而对于那些本就不太上进、拖后腿的人,强大如 LLM 也帮不了他们。因此我担心,至少就现阶段而言,LLM 只会让本就优秀的人变得更优秀。

但是,让我们一步一步来。

全知全能还是鹦鹉学舌?

在这波机器学习的新潮中,最令人担忧的现象之一是 AI 专家对于 LLM 的认知也较为有限。伟人发明了神经网络,甚至还发明了自动优化神经网络参数的算法,而硬件能训练越来越大的模型,利用对要处理数据的统计知识(先验)以及大量试错来逼近最佳结果,人们发现了比其他方法更有效的架构。但总体而言,神经网络仍然相当不透明。

由于无法解释 LLM 为何会出现某些新功能,许多人推测科学家们会更加谨慎。但另一方面,还有部分人严重低估 LLM,认为它们充其量只是略为先进的马尔可夫链,最多只能重复在训练集中看到的极其有限的变化。不过后来在面对证据时,这种“鹦鹉学舌”的说法几乎被推翻。

与此同时,还有许多热心群众将现实中并不存在的超自然力量也归因于 LLM——而实际情况是,LLM 最多只能对自己在训练期间接触过的数据表示空间中进行插值,这早已不是什么新鲜事。另外值得一提的是,LLM 的插值能力也很有限,如果某个 LLM 能够在其接触过的所有代码所限定的空间内连续插值,即使它做不到真正的创新,也能够取代 99% 的程序员了。

好在实际情况并非如此。LLM 确实能编写出自己从未见过的程序,并以一定频率将训练集中出现的不同想法巧妙融合,但这种能力的局限性也很大:每当需要微妙的推理时,LLM 就会惨遭失败。不过话说回来,LLM 仍代表了 AI 诞生至今的最大成就,这没什么好否认的。

愚蠢,但无所不知

有个事实我们需要明确:LLM 最多只能进行最基本的推理,且往往不准确,还经常夹杂着一些不存在事实的幻觉,但它们确实知识渊博。在编程领域以及其他有高质量数据的领域,LLM 就像愚蠢的天才,知道很多事情。

与这样的搭档进行结对编程非常麻烦(对我而言,结对编程这件事本身就很麻烦):它们会有一些荒谬的想法,我们则必须不断地将自己的想法强加于它。当然,如果这个博学的“傻瓜”可以为我们所用,回答我们向它提出的所有问题,那情况就大不相同了。现有的 LLM 可能还无法跨越知识的鸿沟,但如果我们想处理一个不太了解的主题,那 LLM 可以让我们从绝对无知的状态中解脱出来,让我们了解到足够的知识从而独立前行。

在编程领域,也许是二三十年前,人们对 LLM 的能力兴趣并不大。那时,你必须掌握几种编程语言、经典算法和十个基本库。剩下的就得靠自己了,靠自己的智慧、专业知识和设计技能。如果你具备了这些要素,你就是一个熟练的程序员,几乎能做所有的事情。随着时间的推移,我们目睹了框架、编程语言和各类库的爆炸式增长,虽然这种复杂性的爆炸增长往往是完全不必要和不合理的,但事实就是事实。在这种情况下,一个博学的“傻瓜”就是一位宝贵盟友。

我举个例子:我对机器学习的实验至少进行了一年,一直在使用 Keras,后来出于各种原因,我转到了 PyTorch。我已经知道嵌入或残差网络是什么,但我不想一步一步地学习 PyTorch 文档(就像我学习 Keras 时那样,当时还没有 ChatGPT)。而有了 LLM 后,编写使用 Torch 的 Python 代码就变得非常容易了,我只需对我想要组合的模型有清晰的想法,并提出正确的问题即可。

举例说明

我不是在谈论像“嘿,X 类中执行 Y 的方法是什么?”这样的简单问题,这样我可能会同意那些对 LLM 持怀疑态度的人的观点。事实证明,更复杂的模型所能做的事情要精细得多。我可以告诉 GPT4:看,这是我在 PyTorch 中实现的神经网络模型,这是我的批处理数据,我想调整张量的大小,使输出批次的函数与神经网络的输入相匹配,我想用这种特殊的方式来表示事物。你能给我展示进行重塑所需的代码吗?然后,GPT4 编写了代码,而我只需要在 Python CLI 中测试张量是否真的具有我需要的维度,以及数据布局是否正确。

还有一个例子。前段时间,我不得不为某些基于 ESP32 的设备实现一个 BLE 客户端。经过研究后,我发现多平台蓝牙编程绑定或多或少都无法使用。解决方案很简单,使用 MacOS 的本地 API 用 Objective C 编写代码。于是,我不得不同时处理两个问题:学习 Objective C 繁琐的 BLE API,同时还要记起如何在 Objective C 中编程——我上一次用 Objective C 写程序是十年前,根本不记得事件循环、内存管理等许多细节。

然而在 LLM 的帮助下,我用极短的时间就写完了代码。最终的代码是这样的,虽然不算美观,但至少能完成任务:

https://github.com/antirez/freakwan/blob/main/osx-bte-cli/SerialBTE.m

代码主要是通过在 ChatGPT 上剪切粘贴我想要做的事情来编写的,由于刚开始我不太了解如何做,最初生成的代码没法正常运行,但我可以让 LLM 向我解释问题所在以及如何解决它。如果没有 ChatGPT,我能做得到吗?当然可以,但这不仅浪费了我的时间,我可能根本也不会去尝试,因为这不值得:编写这样一个对我的项目来说次要的程序,其付出和收益之间的比例并不可观。

最后还有一个例子,与代码编写无关,而是与数据解释有关。当时,我想建立一个用我在网上找到的卷积神经网络的 Python 脚本,但文档相当缺乏。这个网络的优势在于它采用 ONNX 格式,因此我可以轻松提取输入和输出列表以及它们分配名称的列表。我只知道这个卷积神经网络能检测图像中的某些特征,但输入图像的格式和大小及输出的复杂度我都不太了解。

我首先将 ONNX 网络元数据的输出复制粘贴到 ChatGPT 中,并同步了我对该网络的一点了解。然后,ChatGPT 假设输入的组织方式,输出可能是表示图像中与潜在缺陷相对应部分的归一化方框等。经过几分钟的来回讨论后,我得到了一个能进行网络推理的 Python 脚本以及将起始图像转换为适合输入的张量所需的代码等等。

一次性程序

上述类似的例子还有很多,我在这里就不一一赘述了,基本上都是同样的情况和结果。除此之外,我还经常遇到另一类情况:想迅速了解某些可以快速验证的东西。在这种情况下,我就会用 LLM 来加快我对知识的需求。

不过,在不同的情况下,我也会让 LLM 编写所有代码。例如,当我需要编写一个一次性的程序时,比如这个:

https://github.com/antirez/simple-language-model/blob/main/plot.py

我需要可视化一个小型神经网络学习过程中的损失曲线。我向 GPT4 展示了 PyTorch 程序在学习过程中生成的 CSV 文件格式,然后我要求,如果我在命令行中指定了多个 CSV 文件,我就不再需要相同实验的训练和验证损失曲线,而是要比较不同实验的验证损失曲线。以上结果就是 GPT4 生成的结果,总共耗时 30 秒。

同样,我需要一个程序来读取 AirBnB 的 CSV 报告,并按月份和年份进行分组。然后,考虑清洁费用和每次预订的住宿天数,它将统计出一年中不同月份的平均租金价格。这个程序对我来说非常有用,但编写它也非常无聊:没有任何有趣的东西。因此,我从 CSV 文件中截取了一小部分,并在 GPT4 上进行了剪切粘贴,然后给 LLM 写了要解决的问题,其生成的程序一次就成功了,以下,我将展示完整代码:

pythonimport pandas as pdpd.set_option('display.max_rows', None)df = pd.read_csv('listings.csv')reservations = df[df['Type'] == 'Reservation']reservations['Start Date'] = pd.to_datetime(reservations['Start Date'])reservations['Year'] = reservations['Start Date'].dt.yearreservations['Month'] = reservations['Start Date'].dt.monthreservations['Nightly Rate'] = (reservations['Amount'] - reservations['Cleaning Fee']) / reservations['Nights']all_listings = reservations['Listing'].unique()all_years = reservations['Year'].unique()all_months = range(1, 13)index = pd.MultiIndex.from_product([all_listings, all_years, all_months], names=['Listing', 'Year', 'Month'])all_data = pd.DataFrame(index=index).reset_index()merged_data = pd.merge(all_data, reservations, on=['Listing', 'Year', 'Month'], how='left')average_nightly_rates = merged_data.groupby(['Listing', 'Year', 'Month'])['Nightly Rate'].mean().fillna(0)print(average_nightly_rates)

要准确理解如何对数据进行分组,且这些数据本来就相当分散和无序,需要一些简单的推理:这不是一个 LLM 简单地重复一些它所见过的语言可以解决的问题。GPT4 在训练过程中可能接触过类似程序,但与我所要求的提示条件必定有所不同,但它依旧能写出符合的程序代码。在我看来,这表明 LLM  能在一定程度上对训练集中各种程序描绘的空间内进行插值。

在我看来,编写这种程序只会浪费我的时间,而 LLM 可以为我代劳,这无疑直接加速了我编写代码的能力:我可以专注于真正重要的事情。

当 LLM 不尽如人意时:系统编程

尽管我在使用 LLM 和编程方面取得了成功,但当我编写 C 语言程序时,我几乎总是把 LLM 仅用作一种更方便的文档形式。我是系统编程专家,在这种情况下,只有当 LLM 能够进行复杂推理时才会对我有用:然而在这种场景中,它们几乎总是失败的。

让我们从这个实验的提示开始:

概述一个漂亮、小巧但可行的 C 语言实现的 Bloom 过滤器的要求。重点考虑哈希函数的重要方面,然后用高质量的 C 语言编写出来。同时考虑到你的示例实现应能存储 100,000 个元素,误报率不超过 5%,添加的元素是以空字符结尾的字符串。

以下是输出:

c#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>

#define N 100000 // Number of elements#define P 0.05 // False positive probability#define M (int)(-(N * log(P)) / (log(2) * log(2))) // Size of bit array#define K (int)(M / N * log(2)) // Number of hash functions

unsigned char bitArray[M / 8 + 1];

void setBit(int n) { bitArray[n / 8] |= 1 << (n % 8);}

int getBit(int n) { return bitArray[n / 8] & (1 << (n % 8));}

// Basic hash functions (for demonstration purposes)int hash1(char *str) { int hash = 5381; int c; while ((c = *str++)) hash = ((hash << 5) + hash) + c; return abs(hash % M);}

int hash2(char *str) { unsigned long hash = 0; int c; while ((c = *str++)) hash = c + (hash << 6) + (hash << 16) - hash; return abs(hash % M);}

void add(char *str) { setBit(hash1(str)); setBit(hash2(str)); // Add more hash functions if needed}

int is_in(char *str) { return getBit(hash1(str)) && getBit(hash2(str)); // Check more hash functions if used}

int main() { char *testStr = "testString"; add(testStr);

if (is_in(testStr)) { printf("%s is probably in the set.\n", testStr); } else { printf("%s is definitely not in the set.\n", testStr); }

return 0;}

从生成代码来看,GPT4 的表现不太出色。Bloom 过滤器的应用相当广泛,不是一种太过奇异的数据结构。不过要编写一个像样的 Bloom 过滤器,显然需要更强的抽象能力,例如找到一种有效方法,对同一字符串进行 N 次哈希处理,并确保各哈希值充分不相关。

然而,如果你明确要求 GPT4 修改哈希函数,使其产生 N 个不相关的输出,它提出的解决方案要好得多:

cunsigned int hash(const char* str, unsigned int hash_id) {    unsigned int hash = 5381;    int c;    while ((c = *str++)) {        hash = ((hash << 5) + hash) + c + hash_id;    }    return hash % BF_SIZE;}

如果是 GPT4 自己提出了这个想法,它可能会以不同的方式编写 Bloom 过滤器,使用单个哈希函数一次设置 K 个 bits。

也就是说,GPT4 能独立完成编写一个合适且更通用的哈希函数的任务,但在编写 Bloom 过滤器这一更大的项目中,它却未能表现出足够的推理能力,而是输出了两个不同但相似的哈希函数——这与网络上一篇关于 Bloom 过滤器实现不佳的示例文章相符。

目前,LLM 的推理能力较弱,如果关于提问的信息来源稀缺,加上还掺杂着许多质量低劣的信息来源,输出结果就很容易不尽如人意。然而,这并非个案,我曾多次尝试在算法或系统编程领域使用 LLM,结果都非常糟糕

与此同时,GPT4 能够反汇编它生成的函数(在单独的会话中),并准确理解其目的:

https://chat.openai.com/share/f54b64d7-d19a-4be4-8f10-08553aa812f1

因此,断言 LLM 在系统编程上没有用途肯定是不准确的。

一个有趣且基本在意料之中的现象是,在这些情况下,较小模型和较大模型之间的差异确实很大。下面让我们看看两个本地模型的表现。

例如,Mistral 的 MoE 模型 Mixtral 对同样的问题的回答如下:

cunsigned int hash(const char* str, unsigned int hash_id) {    unsigned int hash = 5381;    int c;    while ((c = *str++)) {        hash = ((hash << 5) + hash) + c;    }    return hash + hash_id;}

显然,仅在最后添加 hash_id 是一个极其糟糕的解决方案。Mixtral 在很多方面都是一个很好的模型,但对于推理能力本就薄弱的 LLM 而言,目前的规则无疑是:越大越好。

这是我与本地 LLM deepseek 编码器的聊天,由于我没有足够的 RAM 以更高的精度使用该模型,所以量化到了 4 位。然而,由于它有 340 亿个参数,因此在这个问题上的推理能力似乎相当先进:直说将 hash_id 添加到末尾可能会导致分布不均,尤其是当 hash_id 过大或分布不均时,同时建议用位运算将 hash_id 混合进去。

cunsigned int hash(const char* str, unsigned int hash_id) {    unsigned int hash = 5381;    int c;    while ((c = *str++)) {        hash = ((hash << 5) + hash) ^ c + hash_id; // Using XOR to mix in the hash_id     }    return (hash ^ hash_id); // Mixing the hash_id one more time at the end}

这个结果,至少在我的 MacBook M1 Max 上运行得还不错,它还使用了异或来混合求和结果。在这种情况下,我提供了解决问题的线索肯定对模型有所帮助,但是模型确定了问题的真正源头,并提出有效的解决方案——上述情况,是任何书籍、文档或谷歌搜索都无法实现的。

不论这是一种插值的原始结果,还是从其他角度来看,不可否认模型确实进行了某种形式的推理,我们找到问题起源和解决方案也正得益于此。所以,无论人们如何看待 LLM,断言它们对程序员没有帮助是一种极为草率的行为。

但与此同时,凭我在过去几个月的经验表明,对于系统编程而言,如果你已经是一名经验丰富的程序员,LLM 几乎永远也提供不了有效的解决方案。举个例子,我目前的项目是 ggufflib,涉及编写一个读写 GGUF 格式文件的库,这是 llama.cpp 加载量化模型的格式。最初,为了了解量化编码是如何工作的,我尝试用 ChatGPT,但后来我决定对 llama.cpp 的代码进行逆向工程:这样更快。

如果 LLM 能为系统程序员提供适当的帮助,那么看到数据编码“struct”声明和解码函数时,就应该能重建数据格式文档。llama.cpp的函数很小,完全符合 GPT4 的要求,但输出结果却完全没用。在这种情况下,我们就只能像过去一样:掏出纸和笔,阅读代码,看看解码器提取的 bits 在哪里注册。

透过外在看本质

我这么说可能很直接,但事实确实如此:当今的大多数编程工作,都是以略有不同的形式重复同样的内容——而这,并不需要高水平的推理能力。尽管 LLM 会受到上下文的严重限制,但它们在做这方面确实相当擅长。 

这应该引起程序员的思考:编写这类程序是否值得?当然,你会得到报酬,还可能是相当丰厚的报酬,但如果用一个 LLM 就可以完成其中一部分,那么也许五年或十年后,这份工作并不是你的最好归宿。

其次,LLM 到底是真的具备某种推理能力,还只是“鹦鹉学舌”?也许有时候它们看起来会推理,符合符号学家所说的“能指”概念,但实际上这是一种并不存在的意义。那些长期与 LLM 打交道、并深知其限制的人们,对此应该深有感触:它们对以往接触过的内容的融合能力,远远超出了其随机输出单词的能力。尽管 LLM 的大部分训练主要是在预训练期间进行的,但在预测下一个 token 时,大模型还是会根据目标创建某种形式的抽象模型。这个模型可能很脆弱、零散且不完美,但通过实际观察,我们会发现这种能力一定存在。如果我们的数学定理令人怀疑,而最伟大的专家们经常持相反意见,那么对我们来说,“眼见为实”似乎是一种明智的做法。

最后,我想说:事已至此,不使用 LLM 进行编程还有什么意义呢?向 LLM 提出正确的问题已是一项基本技能,这种技能练得越少,AI 对工作的帮助就越小。此外,培养对问题的描述能力在与其他人交谈时也很有用,有时并非只有 LLM 不理解我们想说什么。沟通不畅是一个很大的局限,很多程序员尽管在自己的特定领域能力很强,但沟通能力却很差。

目前,谷歌搜索已经乱得不能用了:使用 LLM,哪怕只是把它作为一种压缩的文档形式,也是一个不错的选择。就我个人而言,我将继续广泛使用 LLM,我从来都不喜欢学习晦涩难懂的通信协议细节,也很讨厌那些想展示自己有多么优秀的人编写的库的复杂方法——对我来说,这些似乎都是“知识垃圾”,感谢 LLM 每天都在把我从这一切中解救出来。

原文链接:http://antirez.com/news/140


- EOF -

推荐阅读  点击标题可跳转

1、改几行代码,for 循环耗时从 3.2 秒降到 0.3 秒!

2、改一行代码,数组遍历耗时从 10.3 秒降到了 0.5 秒

3、有这个迹象,公司就要凉了

4、大厂程序员提倡“防御性编程”:故意把代码写得很烂

5、雷军 30 年前的病毒论文,结语最后一句是亮点


关注「程序员的那些事」加星标,不错过圈内事

点赞和在看就是最大的支持❤️

微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
详解多模态大模型:LLaVA+LLaVA1.5+LLaVA-MedAI也造代码屎山!研究发现GitHub Copilot代码可维护性差,偏爱“无脑重写”而非重构复用已有代码Redis之父“锐评”LLM编程:全知全能 && Stupid中国程序员 VS 美国程序员,太形象了...明朝有钱今日花(二)9999999999999999.0 - 9999999999999998.0今日Arxiv最热NLP大模型论文:LLM化身符号逻辑大师,智能体文本游戏新纪元某公司高级程序员敲的代码劲爆!Open AI CEO和他的男伴侣结婚了!也是程序员!Stability AI开年首个大模型:专写代码,支持18种编程语言,上下文100K,苹果笔记本离线就能跑Redis 之父亲自上手用大模型撸代码:通晓古今的白痴队友,将来可以取代 99% 程序员“精气神”是什么?隐退三年重出山!身价4800亿的谷歌创始人亲自给Gemini写代码,经常加班到凌晨侃爷整新活!花了600多w!换了一副钢牙!网友锐评:钱比脑子多趣图:自己单独写代码 vs 有人看着写代码欧阳娜娜最新留学生活曝光,网友锐评:咋还没从野鸡大学毕业???英国有望取消旅游税!抵押贷款市场反弹!伦敦批准新的摩天大楼,媲美碎片大厦!这样写代码,同事乐开花机械革命 2024 版蛟龙 16S 游戏本预售,锐龙 7 8845H+RTX 4060 定价 5999 元2023 LLM技术报告—— LLM的工具和平台字节想买饿了么,只要外卖员,不留程序员!公民努力决不会注定失败 - 乌克兰公民70年后把撒谎的普利策奖得主Duranty拉下马提示词专场:从调整提示改善与LLMs的沟通,到利用LLMs优化提示效果LLM巫师,代码预训练是魔杖!UIUC华人团队揭秘代码数据三大好处有望取消47号法案部分条款,南加橙县地区检察官刊出巨幅广告:“我们要严惩罪犯!”专访VideoPoet作者:LLM能带来真正的视觉智能大厂程序员提倡“防御性编程”:故意把代码写得很烂,万一被裁,要确保留下的代码不可维护!100元起拍的“18611999999”,2893次出价,以2614万元成交!评论区炸了…Redis之父亲自上手用大模型撸代码:通晓古今的白痴队友,将来可以取代99%程序员只会写代码的程序员要不存在了?大模型浪潮下开发者概念泛化 | InfoQ 研究中心给母亲寄鱼油一个丑陋的“中国”人LLM会写代码≠推理+规划!AAAI主席揭秘:代码数据质量太高|LeCun力赞“结婚后,老公问我叫啥名字……”网友锐评:你俩好像不太熟哈哈哈哈哈谷歌:LLM找不到推理错误,但能纠正它
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。