InfoQ 推荐 ( ) • 2024-04-28 17:33

在过去的六个月里,我的创业公司Truss(gettruss.io")发布了多项倚重LLM的功能,而我在Hacker News上读到的关于LLM的故事现在已经和我的实际情况脱节了,所以我想在处理过5亿多(我估计)tokens之后,分享一些更“令人惊讶”的经验教训。

 

本文要点:

 

我们正在使用OpenAI模型,如果你想知道我对其他模型的看法,请阅读底部的问答部分。在我们的用例中,GPT-4占85%,GPT-3.5占15%。我们专门处理文本,因此不涉及GPT-4-vision、Sora、whisper等。我们有一个B2B用例——重点是汇总/分析-提取,你的情况可能有所不同。5亿tokens其实并不像想象的那多,也就大概75万页文本,要正确看待。

 

对于提示,少即是多

我们发现,不要在提示中给出确切的列表或指令——如果这些东西已经是常识的话,这样可以获得更好的结果。GPT并不愚蠢,你提供的细节过多,反而会让它混乱。

 

这和编写代码不一样,代码必须明确。

 

下面是我们遇到的一个例子。

 

我们的一部分管道读取了一些文本块,并要求GPT根据它们与美国50个州或联邦政府的相关性进行归类。这不是什么很难的任务——或许用string/regex就可以搞定,但会有许多奇怪的边缘情况,花费的时间会更长。因此,我们首先做了(大致)这样的尝试:

Here's a block of text. One field should be "locality_id", and it should be the ID of one of the 50 states, or federal, using this list: [{"locality: "Alabama", "locality_id": 1}, {"locality: "Alaska", "locality_id": 2} ... ]

这样做有时候是可以的(我估计98%以上的情况都可以),但如果需要深入挖掘的话经常会失败。

 

经过研究,我们注意到字段name始终返回州的全名——即使我们没有明确要求它这样做。因此,我们改为对name做简单的字符串搜索来找出相应的州。从那以后,它就工作得很好了。

 

我认为,更好的方法应该是:

 

“You obviously know the 50 states, GPT, so just give me the full name of the state this pertains to, or Federal if this pertains to the US government.”(GPT,你显然知道50个州,文本和哪个州相关,你就告诉我这个州的全名,如果和美国政府相关,你就告诉我联邦政府。)

 

就是这么不可思议!你的提示模糊一点,GPT概括的反而更好,反馈的质量反而更高——这是高阶委托/思维的典型标志。

 

(注1:你可能会想GPT从根本上讲是一个随机模型,但它面对M开头的州失败次数最多。)

 

(注2:当我们要求GPT从列表中选择一个ID时,如果我们以格式化的JSON发送,每个州一行,那么它就不会那么困惑了。我认为,\n是一个比逗号更强大的分隔符。)

 

你不需要langchain,甚至不需要OpenAI去年在API中发布的任何东西,只需聊天API就够了

 

Langchain是过早抽象的一个典型例子。

 

我们一开始以为必须得用它,因为网上是这么说的。而实际上,在tokens数量达到成百上千万、生产环境具备大概3~4个完全不同的LLM特性之后,我们的openai_service文件中仍然只有一个40行的函数:

def extract_json(prompt, variable_length_input, number_retries)

 

我们唯一使用的API是chat。我们总是提取JSON。我们不需要JSON mode、函数调用和助手(虽然我们都做了),我们甚至没有使用系统提示(或许我们应该)。当gpt-4-turbo发布的时候,我们只更新了代码库中的一个字符串。

 

这就是功能强大的通用模型的美妙之处——少即是多。

 

在这个函数的40行代码中,大部分代码都是用来处理普通的500错误或套接字关闭错误(尽管OpenAI API变得越来越好,但考虑到它们的负载,出现这样的问题也并不奇怪)。

 

我们内置了一些自动截断代码,因为我们不必担心上下文长度限制。我们有自己的tokens长度估计器,如下所示:

if s.length > model_context_size * 3 # truncate it! end

在一些极端情况下,如句号或数字过多时,上述代码会不起作用。因此,我们还有下面这个特有的try/catch重试逻辑:

if response_error_code == "context_length_exceeded" s.truncate(model_context_size * 3 / 1.3)

我们使用这种方法取得了不错的效果,而且也有足够的灵活性来满足我们的需求。

 

使用流式API改善延迟,向用户提供速度可变的输出,这实是ChatGPT一个重大的用户体验创新

我们可能认为这就是一个噱头,但用户对于这个特性的反响很是积极。

 

GPT特别不擅长零假设

“Return an empty output if you don’t find anything(如果没有找到任何内容,则返回空)”——这可能是我们遇到的最容易导致GPT出错的提示语。

 

GPT经常会产生幻觉,提供不那么真实的答案,而不是什么都不返回。但这样的问题会导致它缺乏信心,什么都不返回的次数会比正常情况下多。

 

我们大部分提示都是类似下面这样:

 

“Here’s a block of text that’s making a statement about a company, I want you to output JSON that extracts these companies. If there’s nothing relevant, return a blank. Here’s the text: [block of text]”(这里有一段文字描述了一家公司,我们希望你提取这家公司并输出JSON。如果未找到任何相关内容,则返回空。文本如下:[文本内容])

 

有一段时间,我们有一个Bug,就是[文本块]可以为空。GPT会出现糟糕的幻觉。顺便说一下,GPT喜欢幻想面包店,下面这些都很棒:

 

Sunshine BakeryGolden Grain BakeryBliss Bakery

 

我们的解决方案是修复这个Bug,如果没有文本就不发送提示。但难点在于,通过编程判断“它是空”比较困难,其实这时需要GPT参与进来了。

 

“上下文窗口”一词不是很妥当,只有输入窗口变大了,而输出窗口并没有

 

很少有人知道:GPT-4允许的最大输入窗口为128K,而输出窗口仍然只有4K。显然,“上下文窗口”一词是有迷惑性"的。但问题的糟糕之处在于,我们经常要求GPT返回一个JSON对象的列表。想象一下,一个JSON任务的数组列表,每个任务都有一个名称和标签。

 

GPT实在没法返回10项以上。硬要让它返回15项的话,或许只有15%的情况下可以做到。

 

一开始,我们以为这是因为4K大小的上下文窗口限制,但我们发现,10项的时候只有700~800个tokens,GPT就停下了。

 

现在,你当然可以把输出变成输入。你给它一个提示,要求它返回一个任务,然后把提示和任务一起提供给它,再要求下一个任务,以此类推。但现在,你在和GPT玩电话游戏,并且必须处理类似Langchain这样的事情。

 

向量数据库和RAG/embeddings,对我们这些普通人来说几乎毫无用处

我累了,我真得累了。每次我想到一个杀手级的RAG / embeddings用例时,我都会狼狈不堪。

 

我认为,数据库/RAG事实上是为搜索而存在的,仅限于搜索,而且是像谷歌或必应那样的真正的搜索。下面是一些原因:

 

缺少相关性界限。这里有一些解决方案",比如你可以创建自己的相关性界限启发式,但那并不可靠。在我看来,这会扼杀RAG——总是会检索出不相关的结果,或者过于保守,错过重要的结果。为什么要把向量存入一个专有数据库里而远离其他数据呢?除非你的规模达到了谷歌/必应的水平,否则是不值得丢失上下文的。除非你做的是一个非常开放的搜索,比如整个互联网——用户通常不喜欢语义搜索,因为它会返回一些不相关的东西。对于大多数商业应用中的搜索,用户都是领域专家——他们不需要你去猜测他们的意思,他们会直接告诉你!

 

在我看来(没测试过),对于大多数的搜索场景,LLM更好的用法是使用正常的提示补全将用户的搜索转换为面搜索,甚至是更复杂的查询(甚至是SQL)。但这根本不是RAG。

 

幻觉基本不会出现

从根本上讲,我们的用例都是“这里有一个文本块,从中提取一些东西。”

 

一般来说,如果你让GPT给出一段文本中提到的公司名,它不会随机给出一个公司(除非文本中没提及任何公司——这是零假设问题!)。

 

如果你是一名工程师,那你肯定已经注意到了:GPT并没有真正地生成幻觉代码,它不会创建变量,或者在重写你发送给它的代码块过程中随机引入错别字。

 

当你要求它给你一些东西时,它确实会产生存在标准库函数的幻觉,但我还是把那看作零假设。它不知道怎么说“我不知道”。

 

但如果你的用例完全是这样的:“这是全部的上下文信息,分析/总结/提取”,那么它会非常可靠。最近发布的很多产品都强调了这个严谨的用例。

 

因此总的来说,输入的数据好,GPT就会给出好的响应。

 

小结:路在何方?

 

对于一些问题,我在下面直接做了回答。

 

Q:我们会实现AGI吗?

A:不。用这种转换器+互联网数据+$XB基础设施的方法是不行的。

 

Q:GPT-4真得有用吗?还是说一切都是营销?

A:它百分之百有用。现在仍然是互联网的早期阶段。

 

Q:它会让所有人失业吗?

A:不。从根本上讲,它降低了人们进入ML/AI领域的门槛,而之前这是谷歌才有的能力。

 

Q:你试过Claude、Gemini等模型吗?

A:实际上,我们并没有做任何严谨的A/B测试,但我在日常编码过程中测试过,感觉它们还差得比较远。主要体现在一些比较微妙的事情上,比如感知你的意图。

 

Q:我怎么才能跟上LLMs/AI领域的最新发展动态?

A:不需要这么做。关于The Bitter Lesson",我想过很多,模型性能的总体改进会远超小幅优化。如果真是这样,你所需要担心的就只有GPT-5何时问世,其他的都不重要。OpenAI在此期间发布的其他所有东西(不包括Sora等,那是完全不同的东西)基本上都是干扰。

 

Q:那么当GPT-5出现时,它会有多好?

A:和其他人一样,我一直在试图从OpenAI那里寻找相关的蛛丝马迹。遗憾的是,我认为我们接下来只会看到渐进式的改进。我对“GPT-5会改变一切”不抱多少希望。

 

这其中的根本原因是经济方面的。我之前以为,从GPT-3到GPT-3.5可能是模型通过训练获得超线性改进:训练难度提高2倍,而性能提升2.2倍。但显然,情况并非如此。我们看到的是对数关系。事实上,为实现增量改进,token 速度是呈指数级下降而单token成本是呈指数级增长的。

 

如果是这样的话,我们就处于某种帕累托最优曲线上,而GPT-4可能就是最优的:尽管与GPT-3.5相比,我愿意为GPT-4支付20倍的价格。但老实说,从GPT-4到GPT-5,我不认为我会为每个token,而不是为GPT-4所使用的任务集,支付20倍的价格。

 

GPT-5可能会打破这一局面。或者,只是iPhone 5与iPhone 4的差别。我并不会为此感到失落!

 

 

声明:本文为InfoQ翻译,未经许可禁止转载。

 

原文链接:https://kenkantzer.com/lessons-after-a-half-billion-gpt-tokens/"