大语言模型(LLM)正在改变程序员的编码方式。本文是 Redis 之父 Antirez 的个人实践分享,他从一位资深程序员的视角,深入探讨了如何在实际项目中有效利用 LLM(如 ChatGPT、本地模型),以及它们的优势、局限和最佳使用场景。无论你是新手还是专家,都能从中获得启发,学会将 AI 作为强大的编程伙伴。
一、LLM 的能力边界:全知全能还是鹦鹉学舌?
关于 LLM 的争论从未停止。一方面,有人将它们贬低为“高级马尔科夫链”,只能重复训练数据;另一方面,也有不少人过度神化,认为它们具有超自然力量。事实是:LLM 能在训练数据所代表的空间内进行插值,这种能力已经相当惊人,但它们无法真正创造新颖事物,尤其在需要细腻推理时,常常力不从心。尽管如此,它们仍是人工智能诞生至今最伟大的成就之一。
关键认知:
- LLM 并非全知全能,但也不是简单的鹦鹉学舌。
- 它们能融合不同思想的训练数据,但推理能力有限。
- 对于编程领域,LLM 就像一位“理解力有限却知识渊博”的伙伴。
小提示: 不要指望 LLM 替你解决所有复杂逻辑问题,但可以把它当作一个“博学的傻瓜”——它熟悉海量 API 和库,但需要你清晰指引方向。
二、LLM 的独特价值:无知却博学
在编程中,LLM 虽然只能进行初级推理,却拥有海量知识。它们无法引领你超越已知路径,但能帮你快速从一无所知到掌握足够知识,独立前行。尤其是当框架、库、API 大量涌现,Google 又充斥着垃圾信息时,一个“无所不知的白痴”成了宝贵盟友。
典型案例: 作者从 Keras 转向 PyTorch 时,借助 LLM 快速编写代码。他只需清楚描述需求,LLM 就能生成可用的实现,无需深究文档。
小提示: 使用 LLM 前,先明确你要构建的模型或功能。清晰的描述是成功的一半。
常见问题:LLM 能完全替代阅读文档吗?
答: 不能完全替代,但可以极大提升效率。对于复杂、晦涩的 API,LLM 能提供快速示例,但涉及底层细节时,仍需结合官方文档或源码验证。作者建议:将 LLM 当作“压缩文档”使用,节省大量查阅时间。
三、应用案例:从代码生成到数据解释
LLM 的应用远不止“类 X 的 Y 方法是什么”。以下两个真实案例展示了它的强大能力。
案例1:PyTorch 张量操作
作者需要调整张量尺寸以匹配神经网络输入。他描述需求后,GPT-4 直接生成代码。作者只需在 Python 命令行中测试即可。
案例2:macOS 蓝牙低能耗(BLE)客户端
为 ESP32 设备开发 BLE 客户端时,作者用 Objective C 和原生 API,通过 ChatGPT 逐步生成代码。尽管最终代码不美观,但 在极短时间内完成了任务,否则他根本不会尝试(因为性价比太低)。
这个过程的副作用是:作者改造了 linenoise 库,使其支持多路复用,这比原程序更有价值。
案例3:ONNX 模型逆向解析
作者遇到一个未文档化的卷积神经网络,利用 ChatGPT 分析 ONNX 元数据,推测输入格式和输出含义。最终得到可运行的 Python 脚本。ChatGPT 通过观察测试图像上的原始逻辑单元值,“理解”了网络的运作方式,这体现了 LLM 的整合能力。
四、一次性程序:LLM 的理想战场
对于用完即弃的脚本,LLM 堪称完美武器。作者举了两个例子:
- 损失曲线可视化: 向 GPT-4 展示 CSV 格式,要求比较不同实验的验证损失曲线。30 秒内生成代码。
- AirBnB 租金分析: 将 CSV 粘贴给 GPT-4,描述分组和统计需求。程序第一次尝试即成功运行。
import pandas as pd
pd.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.year
reservations['Month'] = reservations['Start Date'].dt.month
reservations['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')
a verage_nightly_rates = merged_data.groupby(['Listing', 'Year', 'Month'])['Nightly Rate'].mean().fillna(0)
这类程序需要简单的逻辑推理——LLM 并非简单重复已有模式,而是能在训练集范围内进行创新和推理。作者认为,编写这类程序是对时间的不明智使用,LLM 能显著提升效率,让他专注在更重要的事务上。
五、系统编程的挑战:LLM 的短板
在 C 语言系统编程中,LLM 的表现远不如 Python 领域。作者以布隆过滤器(Bloom Filter)为例:
- GPT-4 生成的实现并不出色,哈希函数简单重复,缺乏高级抽象。
- 当明确指示改进哈希函数后,GPT-4 能提出更合理的方案。
- 本地模型 Mixtral 的解决方案更差,仅在最后添加 hash_id。
- 而 deepseek-coder(340 亿参数) 在得到提示后,能识别问题根源,提出混合 XOR 的有效方案,展现了某种形式的推理能力。
// 6-bit quantization
// weight is represented as x = a * q
// 16 blocks of 16 elements each
// Effectively 6.5625 bits per weight
typedef struct {
uint8_t ql[QK_K/2]; // quants, lower 4 bits
uint8_t qh[QK_K/4]; // quants, upper 2 bits
int8_t scales[QK_K/16]; // scales, quantized with 8 bits
ggml_fp16_t d; // super-block scale
} block_q6_K;
void dequantize_row_q6_K(const block_q6_K * restrict x, float * restrict y, int k) {
assert(k % QK_K == 0);
const int nb = k / QK_K;
for (int i = 0; i < nb; i++) {
const float d = GGML_FP16_TO_FP32(x[i].d);
const uint8_t * restrict ql = x[i].ql;
const uint8_t * restrict qh = x[i].qh;
const int8_t * restrict sc = x[i].scales;
for (int n = 0; n < QK_K; n += 128) {
for (int l = 0; l < 32; ++l) {
int is = l/16;
const int8_t q1 = (int8_t)((ql[l + 0] & 0xF) | (((qh[l] >> 0) & 3) << 4)) - 32;
const int8_t q2 = (int8_t)((ql[l + 32] & 0xF) | (((qh[l] >> 2) & 3) << 4)) - 32;
const int8_t q3 = (int8_t)((ql[l + 0] >> 4) | (((qh[l] >> 4) & 3) << 4)) - 32;
const int8_t q4 = (int8_t)((ql[l + 32] >> 4) | (((qh[l] >> 6) & 3) << 4)) - 32;
y[l + 0] = d * sc[is + 0] * q1;
y[l + 32] = d * sc[is + 2] * q2;
y[l + 64] = d * sc[is + 4] * q3;
y[l + 96] = d * sc[is + 6] * q4;
}
y += 128;
ql += 64;
qh += 32;
sc += 8;
}
}
}
对于 llama.cpp 中的 Q6_K 量化格式,GPT-4 无法清晰解释数据布局,生成的简化函数也存在索引错误和符号扩展问题。作者最终自己逆向工程并编写了代码。
结论: 对于系统编程,如果已是资深程序员,LLM 往往无法提供满意方案。但参数越大的模型,推理能力相对越好。
小提示: 在系统编程中,将 LLM 作为“更便捷的文档工具”而非代码生成器,效果更佳。当需要复杂推理时,传统方法(纸笔、代码阅读)依然不可替代。
常见问题:为什么系统编程中 LLM 表现差?
答: 主要原因有三:1)LLM 的推理能力有限,难以处理算法和底层细节;2)系统编程领域的高质量训练数据较少,而低质量资料(如不准确的博客)可能误导模型;3)模型对上下文长度和抽象思维的要求较高,当前 LLM 尚不成熟。但随着模型规模增长,这一差距正在缩小。
六、重新审视编程工作
当今编程大多是在微调同样的内容,这类工作并不需要太高推理能力,LLM 表现出色。这提醒程序员:如果工作可被 LLM 轻松替代,未来五到十年可能不是最佳职业方向。但 LLM 是否具备真正的推理能力?作者认为,这些模型整合信息的能力远非词汇重复,它们在预训练中构建了抽象的模型,尽管脆弱且不完美,但确实存在。在专家意见分歧时,相信自己的直觉是明智的。
七、今天还有什么理由不去使用 LLM 辅助编程?
1. 正确提问是关键技能——练习越少,利用 AI 的能力越弱。
2. 清晰描述问题对于人类和 AI 同样重要,沟通不畅是严重障碍。
3. 现代 Google 变成了垃圾信息海洋,LLM 作为压缩文档使用是不错的选择。
作者将一直大量使用 LLM:他讨厌深究晦涩通讯协议的细节,或理解复杂库方法——这些“无用知识”有了 LLM 后,每天都能感受到帮助。
总结: 大语言模型不是万能银弹,但结合清晰的提问和判断力,它们能显著提升编程效率,让你把精力集中在真正重要的事情上。从今天开始,尝试将 LLM 融入你的工作流,你会发现一个全新的世界。
